diff options
author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-03-12 14:11:15 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-03-12 14:11:15 +0100 |
commit | dd91e772430dc294e3bf478c119ef8d43c0a3358 (patch) | |
tree | 6f33ce4d5872a5691e0291eb45bf6ab373a5f567 /Source/JavaScriptCore/runtime/JSValue.cpp | |
parent | ad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (diff) | |
download | qtwebkit-dd91e772430dc294e3bf478c119ef8d43c0a3358.tar.gz |
Imported WebKit commit 3db4eb1820ac8fb03065d7ea73a4d9db1e8fea1a (http://svn.webkit.org/repository/webkit/trunk@110422)
This includes build fixes for the latest qtbase/qtdeclarative as well as the final QML2 API.
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSValue.cpp')
-rw-r--r-- | Source/JavaScriptCore/runtime/JSValue.cpp | 82 |
1 files changed, 69 insertions, 13 deletions
diff --git a/Source/JavaScriptCore/runtime/JSValue.cpp b/Source/JavaScriptCore/runtime/JSValue.cpp index e3843f02b..36697c60c 100644 --- a/Source/JavaScriptCore/runtime/JSValue.cpp +++ b/Source/JavaScriptCore/runtime/JSValue.cpp @@ -27,6 +27,7 @@ #include "BooleanPrototype.h" #include "Error.h" #include "ExceptionHelpers.h" +#include "GetterSetter.h" #include "JSGlobalObject.h" #include "JSFunction.h" #include "JSNotAnObject.h" @@ -90,30 +91,85 @@ JSObject* JSValue::toThisObjectSlowCase(ExecState* exec) const return exec->globalThisValue(); } -JSObject* JSValue::synthesizeObject(ExecState* exec) const +JSObject* JSValue::synthesizePrototype(ExecState* exec) const { - ASSERT(!isCell()); + if (isCell()) { + ASSERT(isString()); + return exec->lexicalGlobalObject()->stringPrototype(); + } + if (isNumber()) - return constructNumber(exec, exec->lexicalGlobalObject(), asValue()); + return exec->lexicalGlobalObject()->numberPrototype(); if (isBoolean()) - return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue()); + return exec->lexicalGlobalObject()->booleanPrototype(); ASSERT(isUndefinedOrNull()); throwError(exec, createNotAnObjectError(exec, *this)); return JSNotAnObject::create(exec); } -JSObject* JSValue::synthesizePrototype(ExecState* exec) const +// ECMA 8.7.2 +void JSValue::putToPrimitive(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { - ASSERT(!isCell()); - if (isNumber()) - return exec->lexicalGlobalObject()->numberPrototype(); - if (isBoolean()) - return exec->lexicalGlobalObject()->booleanPrototype(); + JSGlobalData& globalData = exec->globalData(); - ASSERT(isUndefinedOrNull()); - throwError(exec, createNotAnObjectError(exec, *this)); - return JSNotAnObject::create(exec); + // Check if there are any setters or getters in the prototype chain + JSObject* obj = synthesizePrototype(exec); + JSValue prototype; + if (propertyName != exec->propertyNames().underscoreProto) { + for (; !obj->structure()->hasReadOnlyOrGetterSetterPropertiesExcludingProto(); obj = asObject(prototype)) { + prototype = obj->prototype(); + if (prototype.isNull()) { + if (slot.isStrictMode()) + throwTypeError(exec, StrictModeReadonlyPropertyWriteError); + return; + } + } + } + + for (; ; obj = asObject(prototype)) { + unsigned attributes; + JSCell* specificValue; + size_t offset = obj->structure()->get(globalData, propertyName, attributes, specificValue); + if (offset != WTF::notFound) { + if (attributes & ReadOnly) { + if (slot.isStrictMode()) + throwError(exec, createTypeError(exec, StrictModeReadonlyPropertyWriteError)); + return; + } + + JSValue gs = obj->getDirectOffset(offset); + if (gs.isGetterSetter()) { + JSObject* setterFunc = asGetterSetter(gs)->setter(); + if (!setterFunc) { + if (slot.isStrictMode()) + throwError(exec, createTypeError(exec, "setting a property that has only a getter")); + return; + } + + CallData callData; + CallType callType = setterFunc->methodTable()->getCallData(setterFunc, callData); + MarkedArgumentBuffer args; + args.append(value); + + // If this is WebCore's global object then we need to substitute the shell. + call(exec, setterFunc, callType, callData, *this, args); + return; + } + + // If there's an existing property on the object or one of its + // prototypes it should be replaced, so break here. + break; + } + + prototype = obj->prototype(); + if (prototype.isNull()) + break; + } + + if (slot.isStrictMode()) + throwTypeError(exec, StrictModeReadonlyPropertyWriteError); + return; } char* JSValue::description() |