summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSValue.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-03-12 14:11:15 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-03-12 14:11:15 +0100
commitdd91e772430dc294e3bf478c119ef8d43c0a3358 (patch)
tree6f33ce4d5872a5691e0291eb45bf6ab373a5f567 /Source/JavaScriptCore/runtime/JSValue.cpp
parentad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (diff)
downloadqtwebkit-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.cpp82
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()