]> git.saurik.com Git - apple/javascriptcore.git/blobdiff - runtime/StringObject.cpp
JavaScriptCore-1097.3.3.tar.gz
[apple/javascriptcore.git] / runtime / StringObject.cpp
index f8e0e872b40c549006080e50f3228bedf98b91b3..d7e1c8a17b89dd134188b96492524e475e0818ef 100644 (file)
 #include "config.h"
 #include "StringObject.h"
 
+#include "Error.h"
 #include "PropertyNameArray.h"
 
 namespace JSC {
 
 ASSERT_CLASS_FITS_IN_CELL(StringObject);
+ASSERT_HAS_TRIVIAL_DESTRUCTOR(StringObject);
 
-const ClassInfo StringObject::info = { "String", 0, 0, 0 };
+const ClassInfo StringObject::s_info = { "String", &JSWrapperObject::s_info, 0, 0, CREATE_METHOD_TABLE(StringObject) };
 
-StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure)
-    : JSWrapperObject(structure)
+StringObject::StringObject(JSGlobalData& globalData, Structure* structure)
+    : JSWrapperObject(globalData, structure)
 {
-    setInternalValue(jsEmptyString(exec));
 }
 
-StringObject::StringObject(NonNullPassRefPtr<Structure> structure, JSString* string)
-    : JSWrapperObject(structure)
+void StringObject::finishCreation(JSGlobalData& globalData, JSString* string)
 {
-    setInternalValue(string);
+    Base::finishCreation(globalData);
+    ASSERT(inherits(&s_info));
+    setInternalValue(globalData, string);
 }
 
-StringObject::StringObject(ExecState* exec, NonNullPassRefPtr<Structure> structure, const UString& string)
-    : JSWrapperObject(structure)
+bool StringObject::getOwnPropertySlot(JSCell* cell, ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
 {
-    setInternalValue(jsString(exec, string));
-}
-
-bool StringObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
-{
-    if (internalValue()->getStringPropertySlot(exec, propertyName, slot))
+    StringObject* thisObject = jsCast<StringObject*>(cell);
+    if (thisObject->internalValue()->getStringPropertySlot(exec, propertyName, slot))
         return true;
-    return JSObject::getOwnPropertySlot(exec, propertyName, slot);
+    return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
 }
     
-bool StringObject::getOwnPropertySlot(ExecState* exec, unsigned propertyName, PropertySlot& slot)
+bool StringObject::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned propertyName, PropertySlot& slot)
 {
-    if (internalValue()->getStringPropertySlot(exec, propertyName, slot))
+    StringObject* thisObject = jsCast<StringObject*>(cell);
+    if (thisObject->internalValue()->getStringPropertySlot(exec, propertyName, slot))
         return true;    
-    return JSObject::getOwnPropertySlot(exec, Identifier::from(exec, propertyName), slot);
+    return JSObject::getOwnPropertySlot(thisObject, exec, Identifier::from(exec, propertyName), slot);
 }
 
-bool StringObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
+bool StringObject::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
 {
-    if (internalValue()->getStringPropertyDescriptor(exec, propertyName, descriptor))
+    StringObject* thisObject = jsCast<StringObject*>(object);
+    if (thisObject->internalValue()->getStringPropertyDescriptor(exec, propertyName, descriptor))
         return true;    
-    return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
+    return JSObject::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
 }
 
-void StringObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
+void StringObject::put(JSCell* cell, ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
 {
-    if (propertyName == exec->propertyNames().length)
+    if (propertyName == exec->propertyNames().length) {
+        if (slot.isStrictMode())
+            throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
         return;
-    JSObject::put(exec, propertyName, value, slot);
+    }
+    JSObject::put(cell, exec, propertyName, value, slot);
+}
+
+bool StringObject::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException)
+{
+    StringObject* thisObject = jsCast<StringObject*>(object);
+
+    if (propertyName == exec->propertyNames().length) {
+        if (!object->isExtensible()) {
+            if (throwException)
+                throwError(exec, createTypeError(exec, "Attempting to define property on object that is not extensible."));
+            return false;
+        }
+        if (descriptor.configurablePresent() && descriptor.configurable()) {
+            if (throwException)
+                throwError(exec, createTypeError(exec, "Attempting to configurable attribute of unconfigurable property."));
+            return false;
+        }
+        if (descriptor.enumerablePresent() && descriptor.enumerable()) {
+            if (throwException)
+                throwError(exec, createTypeError(exec, "Attempting to change enumerable attribute of unconfigurable property."));
+            return false;
+        }
+        if (descriptor.isAccessorDescriptor()) {
+            if (throwException)
+                throwError(exec, createTypeError(exec, "Attempting to change access mechanism for an unconfigurable property."));
+            return false;
+        }
+        if (descriptor.writablePresent() && descriptor.writable()) {
+            if (throwException)
+                throwError(exec, createTypeError(exec, "Attempting to change writable attribute of unconfigurable property."));
+            return false;
+        }
+        if (!descriptor.value())
+            return true;
+        if (propertyName == exec->propertyNames().length && sameValue(exec, descriptor.value(), jsNumber(thisObject->internalValue()->length())))
+            return true;
+        if (throwException)
+            throwError(exec, createTypeError(exec, "Attempting to change value of a readonly property."));
+        return false;
+    }
+
+    return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
 }
 
-bool StringObject::deleteProperty(ExecState* exec, const Identifier& propertyName)
+bool StringObject::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
 {
+    StringObject* thisObject = jsCast<StringObject*>(cell);
     if (propertyName == exec->propertyNames().length)
         return false;
     bool isStrictUInt32;
-    unsigned i = propertyName.toStrictUInt32(&isStrictUInt32);
-    if (isStrictUInt32 && internalValue()->canGetIndex(i))
+    unsigned i = propertyName.toUInt32(isStrictUInt32);
+    if (isStrictUInt32 && thisObject->internalValue()->canGetIndex(i))
         return false;
-    return JSObject::deleteProperty(exec, propertyName);
+    return JSObject::deleteProperty(thisObject, exec, propertyName);
 }
 
-void StringObject::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
+void StringObject::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
 {
-    int size = internalValue()->length();
+    StringObject* thisObject = jsCast<StringObject*>(object);
+    int size = thisObject->internalValue()->length();
     for (int i = 0; i < size; ++i)
-        propertyNames.add(Identifier(exec, UString::from(i)));
+        propertyNames.add(Identifier(exec, UString::number(i)));
     if (mode == IncludeDontEnumProperties)
         propertyNames.add(exec->propertyNames().length);
-    return JSObject::getOwnPropertyNames(exec, propertyNames, mode);
+    return JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
 }
 
 } // namespace JSC