StringObject.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. * Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
  3. * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. *
  19. */
  20. #include "config.h"
  21. #include "StringObject.h"
  22. #include "Error.h"
  23. #include "JSGlobalObject.h"
  24. #include "Operations.h"
  25. #include "PropertyNameArray.h"
  26. namespace JSC {
  27. ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringObject);
  28. const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(StringObject) };
  29. StringObject::StringObject(VM& vm, Structure* structure)
  30. : JSWrapperObject(vm, structure)
  31. {
  32. }
  33. void StringObject::finishCreation(VM& vm, JSString* string)
  34. {
  35. Base::finishCreation(vm);
  36. ASSERT(inherits(&s_info));
  37. setInternalValue(vm, string);
  38. }
  39. bool StringObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
  40. {
  41. StringObject* thisObject = jsCast<StringObject*>(cell);
  42. if (thisObject->internalValue()->getStringPropertySlot(exec, propertyName, slot))
  43. return true;
  44. return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
  45. }
  46. bool StringObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, PropertySlot& slot)
  47. {
  48. StringObject* thisObject = jsCast<StringObject*>(cell);
  49. if (thisObject->internalValue()->getStringPropertySlot(exec, propertyName, slot))
  50. return true;
  51. return JSObject::getOwnPropertySlot(thisObject, exec, Identifier::from(exec, propertyName), slot);
  52. }
  53. bool StringObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
  54. {
  55. StringObject* thisObject = jsCast<StringObject*>(object);
  56. if (thisObject->internalValue()->getStringPropertyDescriptor(exec, propertyName, descriptor))
  57. return true;
  58. return JSObject::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
  59. }
  60. void StringObject::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
  61. {
  62. if (propertyName == exec->propertyNames().length) {
  63. if (slot.isStrictMode())
  64. throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
  65. return;
  66. }
  67. JSObject::put(cell, exec, propertyName, value, slot);
  68. }
  69. void StringObject::putByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, JSValue value, bool shouldThrow)
  70. {
  71. StringObject* thisObject = jsCast<StringObject*>(cell);
  72. if (thisObject->internalValue()->canGetIndex(propertyName)) {
  73. if (shouldThrow)
  74. throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
  75. return;
  76. }
  77. JSObject::putByIndex(cell, exec, propertyName, value, shouldThrow);
  78. }
  79. bool StringObject::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor, bool throwException)
  80. {
  81. StringObject* thisObject = jsCast<StringObject*>(object);
  82. if (propertyName == exec->propertyNames().length) {
  83. if (!object->isExtensible()) {
  84. if (throwException)
  85. throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to define property on object that is not extensible.")));
  86. return false;
  87. }
  88. if (descriptor.configurablePresent() && descriptor.configurable()) {
  89. if (throwException)
  90. throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to configurable attribute of unconfigurable property.")));
  91. return false;
  92. }
  93. if (descriptor.enumerablePresent() && descriptor.enumerable()) {
  94. if (throwException)
  95. throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change enumerable attribute of unconfigurable property.")));
  96. return false;
  97. }
  98. if (descriptor.isAccessorDescriptor()) {
  99. if (throwException)
  100. throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change access mechanism for an unconfigurable property.")));
  101. return false;
  102. }
  103. if (descriptor.writablePresent() && descriptor.writable()) {
  104. if (throwException)
  105. throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change writable attribute of unconfigurable property.")));
  106. return false;
  107. }
  108. if (!descriptor.value())
  109. return true;
  110. if (propertyName == exec->propertyNames().length && sameValue(exec, descriptor.value(), jsNumber(thisObject->internalValue()->length())))
  111. return true;
  112. if (throwException)
  113. throwError(exec, createTypeError(exec, ASCIILiteral("Attempting to change value of a readonly property.")));
  114. return false;
  115. }
  116. return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
  117. }
  118. bool StringObject::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
  119. {
  120. StringObject* thisObject = jsCast<StringObject*>(cell);
  121. if (propertyName == exec->propertyNames().length)
  122. return false;
  123. unsigned i = propertyName.asIndex();
  124. if (thisObject->internalValue()->canGetIndex(i)) {
  125. ASSERT(i != PropertyName::NotAnIndex); // No need for an explicit check, the above test would always fail!
  126. return false;
  127. }
  128. return JSObject::deleteProperty(thisObject, exec, propertyName);
  129. }
  130. bool StringObject::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
  131. {
  132. StringObject* thisObject = jsCast<StringObject*>(cell);
  133. if (thisObject->internalValue()->canGetIndex(i))
  134. return false;
  135. return JSObject::deletePropertyByIndex(thisObject, exec, i);
  136. }
  137. void StringObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
  138. {
  139. StringObject* thisObject = jsCast<StringObject*>(object);
  140. int size = thisObject->internalValue()->length();
  141. for (int i = 0; i < size; ++i)
  142. propertyNames.add(Identifier(exec, String::number(i)));
  143. if (mode == IncludeDontEnumProperties)
  144. propertyNames.add(exec->propertyNames().length);
  145. return JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
  146. }
  147. StringObject* constructString(ExecState* exec, JSGlobalObject* globalObject, JSValue string)
  148. {
  149. StringObject* object = StringObject::create(exec, globalObject->stringObjectStructure());
  150. object->setInternalValue(exec->vm(), string);
  151. return object;
  152. }
  153. } // namespace JSC