Cannot Object.seal() or Object.freeze() global "this"
authormsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 7 Apr 2017 00:16:18 +0000 (00:16 +0000)
committermsaboff@apple.com <msaboff@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 7 Apr 2017 00:16:18 +0000 (00:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=170549

Reviewed by Mark Lam.

JSTests:

Enabled failing tests fixed by the corresponding code change:
    ChakraCore/test/LetConst/delete.js
    ChakraCore/test/LetConst/dop.js
    ChakraCore/test/LetConst/dop1.js

* ChakraCore.yaml:
* ChakraCore/test/LetConst/dop.baseline-jsc: Added JSC specific expected output.
* ChakraCore/test/LetConst/dop1.baseline-jsc: Added JSC specific expected output.

Source/JavaScriptCore:

Needed to implement JSProxy::isExtensible() which returns the results of calling
the same on wrapped object.

Implemented step 11 of Runtime Semantics: EvalDeclarationInstantiation from the ECMAScript
spec to properly return a TypeError object when attempting to add properties to a
non-extensible global object.

* interpreter/Interpreter.cpp:
(JSC::Interpreter::execute):
* runtime/JSProxy.cpp:
(JSC::JSProxy::isExtensible):
* runtime/JSProxy.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@215072 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JSTests/ChakraCore.yaml
JSTests/ChakraCore/test/LetConst/dop.baseline-jsc [new file with mode: 0644]
JSTests/ChakraCore/test/LetConst/dop1.baseline-jsc [new file with mode: 0644]
JSTests/ChangeLog
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/interpreter/Interpreter.cpp
Source/JavaScriptCore/runtime/JSProxy.cpp
Source/JavaScriptCore/runtime/JSProxy.h

index b3efe94..f34ad80 100644 (file)
 - path: ChakraCore/test/LetConst/defer5.js
   cmd: runChakra :baseline, "ReferenceError", "defer5.baseline-jsc", []
 - path: ChakraCore/test/LetConst/delete.js
-  # Differences in Object.seal().
-  cmd: runChakra :skip, "NoException", "delete.baseline", []
+  cmd: runChakra :baseline, "NoException", "delete.baseline", []
 - path: ChakraCore/test/LetConst/dop.js
-  # Differences in Object.seal().
-  cmd: runChakra :skip, "NoException", "dop.baseline", []
+  cmd: runChakra :baseline, "NoException", "dop.baseline-jsc", []
 - path: ChakraCore/test/LetConst/dop1.js
-  # Differences in Object.seal().
-  cmd: runChakra :skip, "NoException", "dop1.baseline", []
+  cmd: runChakra :baseline, "NoException", "dop1.baseline-jsc", []
 - path: ChakraCore/test/LetConst/eval_fncdecl.js
   # Seems like a bug.  We try to define a function in a false "then" block.
   cmd: runChakra :skip, "NoException", "eval_fncdecl.baseline", []
diff --git a/JSTests/ChakraCore/test/LetConst/dop.baseline-jsc b/JSTests/ChakraCore/test/LetConst/dop.baseline-jsc
new file mode 100644 (file)
index 0000000..a6e95c7
--- /dev/null
@@ -0,0 +1,4 @@
+exception: TypeError: Attempting to define property on object that is not extensible.
+let x
+undefined
+true
diff --git a/JSTests/ChakraCore/test/LetConst/dop1.baseline-jsc b/JSTests/ChakraCore/test/LetConst/dop1.baseline-jsc
new file mode 100644 (file)
index 0000000..a6e95c7
--- /dev/null
@@ -0,0 +1,4 @@
+exception: TypeError: Attempting to define property on object that is not extensible.
+let x
+undefined
+true
index 81d920d..eef9fc0 100644 (file)
@@ -1,3 +1,19 @@
+2017-04-06  Michael Saboff  <msaboff@apple.com>
+
+        Cannot Object.seal() or Object.freeze() global "this"
+        https://bugs.webkit.org/show_bug.cgi?id=170549
+
+        Reviewed by Mark Lam.
+
+        Enabled failing tests fixed by the corresponding code change:
+            ChakraCore/test/LetConst/delete.js
+            ChakraCore/test/LetConst/dop.js
+            ChakraCore/test/LetConst/dop1.js
+
+        * ChakraCore.yaml:
+        * ChakraCore/test/LetConst/dop.baseline-jsc: Added JSC specific expected output.
+        * ChakraCore/test/LetConst/dop1.baseline-jsc: Added JSC specific expected output.
+
 2017-04-05  Joseph Pecoraro  <pecoraro@apple.com>
 
         test262: ES2017 test progressions need updated expectations (arguments.caller removed)
index 6ecbfb8..a44a44e 100644 (file)
@@ -1,3 +1,23 @@
+2017-04-06  Michael Saboff  <msaboff@apple.com>
+
+        Cannot Object.seal() or Object.freeze() global "this"
+        https://bugs.webkit.org/show_bug.cgi?id=170549
+
+        Reviewed by Mark Lam.
+
+        Needed to implement JSProxy::isExtensible() which returns the results of calling
+        the same on wrapped object.
+
+        Implemented step 11 of Runtime Semantics: EvalDeclarationInstantiation from the ECMAScript
+        spec to properly return a TypeError object when attempting to add properties to a
+        non-extensible global object.
+
+        * interpreter/Interpreter.cpp:
+        (JSC::Interpreter::execute):
+        * runtime/JSProxy.cpp:
+        (JSC::JSProxy::isExtensible):
+        * runtime/JSProxy.h:
+
 2017-04-06  Filip Pizlo  <fpizlo@apple.com>
 
         Linear scan should run liveness only once
index 99fadd6..de2f88b 100644 (file)
@@ -1158,6 +1158,8 @@ JSValue Interpreter::execute(EvalExecutable* eval, CallFrame* callFrame, JSValue
             RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception()));
             if (!hasProperty) {
                 PutPropertySlot slot(variableObject);
+                if (!variableObject->isExtensible(callFrame))
+                    return checkedReturn(throwTypeError(callFrame, throwScope, ASCIILiteral(NonExtensibleObjectPropertyDefineError)));
                 variableObject->methodTable()->put(variableObject, callFrame, ident, jsUndefined(), slot);
                 RETURN_IF_EXCEPTION(throwScope, checkedReturn(throwScope.exception()));
             }
index 214ce16..a295d89 100644 (file)
@@ -115,6 +115,12 @@ bool JSProxy::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propert
     return thisObject->target()->methodTable(exec->vm())->deleteProperty(thisObject->target(), exec, propertyName);
 }
 
+bool JSProxy::isExtensible(JSObject* object, ExecState* exec)
+{
+    JSProxy* thisObject = jsCast<JSProxy*>(object);
+    return thisObject->target()->methodTable(exec->vm())->isExtensible(thisObject->target(), exec);
+}
+
 bool JSProxy::preventExtensions(JSObject* object, ExecState* exec)
 {
     JSProxy* thisObject = jsCast<JSProxy*>(object);
index ade13c4..b407af7 100644 (file)
@@ -96,6 +96,7 @@ protected:
     JS_EXPORT_PRIVATE static bool defineOwnProperty(JSObject*, ExecState*, PropertyName, const PropertyDescriptor&, bool shouldThrow);
     JS_EXPORT_PRIVATE static bool setPrototype(JSObject*, ExecState*, JSValue, bool shouldThrowIfCantSet);
     JS_EXPORT_PRIVATE static JSValue getPrototype(JSObject*, ExecState*);
+    JS_EXPORT_PRIVATE static bool isExtensible(JSObject*, ExecState*);
     JS_EXPORT_PRIVATE static bool preventExtensions(JSObject*, ExecState*);
 
 private: