Title: [211938] releases/WebKitGTK/webkit-2.14
Revision
211938
Author
[email protected]
Date
2017-02-09 00:55:28 -0800 (Thu, 09 Feb 2017)

Log Message

Merge r209424 - Introduce the concept of Immutable Prototype Exotic Objects to comply with the spec.
https://bugs.webkit.org/show_bug.cgi?id=165227
<rdar://problem/29442665>

Reviewed by Saam Barati.

JSTests:

* stress/get-from-scope-dynamic-onto-proxy.js:
- Updated error message.

* stress/proxy-dont-infinite-loop.js: Removed.
* stress/proxy-json-path.js: Removed.
* stress/rest-parameter-allocation-elimination-watchpoints-6.js: Removed.
- Removed these tests because the issue they are testing relies on being able to
  set Object.prototype.__proto__ to something else (which is now not possible).

Source/_javascript_Core:

* runtime/JSObject.cpp:
(JSC::JSObject::setPrototypeWithCycleCheck):
- This is where we check for immutable prototype exotic objects and refuse to set
  the prototype if needed.
  See https://tc39.github.io/ecma262/#sec-immutable-prototype-exotic-objects.

* runtime/JSTypeInfo.h:
(JSC::TypeInfo::isImmutablePrototypeExoticObject):
* runtime/Structure.h:
- Add flag for declaring immutable prototype exotic objects.

* runtime/ObjectPrototype.h:
- Declare that Object.prototype is an immutable prototype exotic object.
  See https://tc39.github.io/ecma262/#sec-properties-of-the-object-prototype-object.

* runtime/ObjectConstructor.cpp:
(JSC::objectConstructorSetPrototypeOf):
- Use better error messages.

Source/WebCore:

Make all objects in window.__proto__'s prototype chain immutable prototype exotic
objects.  This gives us roughly equivalent behavior to other browsers.

Firefox's behavior differ slightly in that Firefox will fail any attempted
assignment their __proto__, while the immutable prototype exotic objects will
only fail if the assignment is of a different value.  See
https://tc39.github.io/ecma262/#sec-immutable-prototype-exotic-objects.

Chrome differs in that assignment to window.__proto__ is also handled like an
immutable prototype exotic object.  Instead we adhere to the current HTML spec
that says that the assignment should fail unconditionally.  See
https://html.spec.whatwg.org/#the-windowproxy-exotic-object and
https://html.spec.whatwg.org/#windowproxy-setprototypeof.

If the HTML spec is changed to make the WindowProxy and Location objects into
immutable prototype exotic objects later, we can update to match the spec then.

Test: js/prototype-assignment.html

* bindings/js/JSDOMWindowProperties.h:
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader):
(GeneratePrototypeDeclaration):
* bindings/scripts/IDLAttributes.txt:
* dom/EventTarget.idl:
* page/DOMWindow.idl:

LayoutTests:

The new prototype-assignment.js test is currently only enabled for LLInt only
run in the JSC tests until webkit.org/b/165401 is fixed.

* TestExpectations:
- Skip js/prototype-assignment.html for now until webkit.org/b/165401 is fixed.

* http/tests/security/window-named-valueOf-expected.txt:
* js/dom/proxy-is-not-allowed-in-global-prototype-chain-expected.txt:
* js/dom/proxy-is-not-allowed-in-global-prototype-chain.html:
- Updated error messages.

* js/prototype-assignment-expected.txt: Added.
* js/prototype-assignment.html: Added.
* js/script-tests/prototype-assignment.js: Added.
(else):
(reportError):
(shouldEqual):
(shouldThrow):
(stringify):
(makeTestID):
(doInternalSetPrototypeOf):
(ordinarySetPrototypeOf):
(setImmutablePrototype):
(windowProxySetPrototypeOf):
(initSetterExpectation):
(throwIfNoExceptionPending):
(objectSetPrototypeOf):
(setUnderscoreProto):
(reflectSetPrototypeOf):
(newObjectProto.toString):
(this.testObject.targets.push.value):
(this.testProxy.targets.push.setPrototypeOf):
(Symbol):
(test):
(runTests):
* js/setPrototypeOf-expected.txt:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: releases/WebKitGTK/webkit-2.14/JSTests/ChangeLog (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/JSTests/ChangeLog	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/JSTests/ChangeLog	2017-02-09 08:55:28 UTC (rev 211938)
@@ -1,3 +1,20 @@
+2016-12-06  Mark Lam  <[email protected]>
+
+        Introduce the concept of Immutable Prototype Exotic Objects to comply with the spec.
+        https://bugs.webkit.org/show_bug.cgi?id=165227
+        <rdar://problem/29442665>
+
+        Reviewed by Saam Barati.
+
+        * stress/get-from-scope-dynamic-onto-proxy.js:
+        - Updated error message.
+
+        * stress/proxy-dont-infinite-loop.js: Removed.
+        * stress/proxy-json-path.js: Removed.
+        * stress/rest-parameter-allocation-elimination-watchpoints-6.js: Removed.
+        - Removed these tests because the issue they are testing relies on being able to
+          set Object.prototype.__proto__ to something else (which is now not possible).
+
 2016-09-27  Filip Pizlo  <[email protected]>
 
         B3::lowerMacros forgets to before->updatePredecessorsAfter() when lowering ChillMod on ARM64

Modified: releases/WebKitGTK/webkit-2.14/JSTests/stress/get-from-scope-dynamic-onto-proxy.js (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/JSTests/stress/get-from-scope-dynamic-onto-proxy.js	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/JSTests/stress/get-from-scope-dynamic-onto-proxy.js	2017-02-09 08:55:28 UTC (rev 211938)
@@ -103,4 +103,4 @@
     thrown = e;
 }
 Object.prototype.__proto__ = null;
-shouldBe(String(thrown), `Error: NG`);
+shouldBe(String(thrown), `TypeError: Cannot set prototype of immutable prototype object`);

Deleted: releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-dont-infinite-loop.js (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-dont-infinite-loop.js	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-dont-infinite-loop.js	2017-02-09 08:55:28 UTC (rev 211938)
@@ -1,17 +0,0 @@
-function foo() {
-    let target = {
-      __proto__: null
-    };
-    let proxy = new Proxy(target, {
-        get(...args) {
-            return Reflect.get(...args);
-        }
-    });
-    Object.prototype.__proto__ = {
-       __proto__: proxy,
-    };
-
-    let a = {};
-    a.test;
-}
-foo();

Deleted: releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-json-path.js (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-json-path.js	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/JSTests/stress/proxy-json-path.js	2017-02-09 08:55:28 UTC (rev 211938)
@@ -1,25 +0,0 @@
-var target = { __proto__: null };
-var handler = {
-    get: function ()
-    {
-        throw new Error(`ng`);
-    }
-};
-
-var thrown = null;
-var hello = 42;
-// As a result, global object automatically inherit this proxy.
-Object.prototype.__proto__ = {
-    __proto__: new Proxy(target, handler)
-};
-
-try {
-    loadString(`hello = {"hello":"world"};proxy.ok = {}`);
-} catch (error) {
-    thrown = error;
-}
-Object.prototype.__proto__ = null;
-if (thrown === null)
-    throw new Error(`not thrown`);
-if (String(thrown) !== `Error: ng`)
-    throw new Error(`bad error: ${String(thrown)}`);

Modified: releases/WebKitGTK/webkit-2.14/LayoutTests/ChangeLog (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/LayoutTests/ChangeLog	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/LayoutTests/ChangeLog	2017-02-09 08:55:28 UTC (rev 211938)
@@ -1,3 +1,48 @@
+2016-12-06  Mark Lam  <[email protected]>
+
+        Introduce the concept of Immutable Prototype Exotic Objects to comply with the spec.
+        https://bugs.webkit.org/show_bug.cgi?id=165227
+        <rdar://problem/29442665>
+
+        Reviewed by Saam Barati.
+
+        The new prototype-assignment.js test is currently only enabled for LLInt only
+        run in the JSC tests until webkit.org/b/165401 is fixed.
+
+        * TestExpectations:
+        - Skip js/prototype-assignment.html for now until webkit.org/b/165401 is fixed.
+
+        * http/tests/security/window-named-valueOf-expected.txt:
+        * js/dom/proxy-is-not-allowed-in-global-prototype-chain-expected.txt:
+        * js/dom/proxy-is-not-allowed-in-global-prototype-chain.html:
+        - Updated error messages.
+
+        * js/prototype-assignment-expected.txt: Added.
+        * js/prototype-assignment.html: Added.
+        * js/script-tests/prototype-assignment.js: Added.
+        (else):
+        (reportError):
+        (shouldEqual):
+        (shouldThrow):
+        (stringify):
+        (makeTestID):
+        (doInternalSetPrototypeOf):
+        (ordinarySetPrototypeOf):
+        (setImmutablePrototype):
+        (windowProxySetPrototypeOf):
+        (initSetterExpectation):
+        (throwIfNoExceptionPending):
+        (objectSetPrototypeOf):
+        (setUnderscoreProto):
+        (reflectSetPrototypeOf):
+        (newObjectProto.toString):
+        (this.testObject.targets.push.value):
+        (this.testProxy.targets.push.setPrototypeOf):
+        (Symbol):
+        (test):
+        (runTests):
+        * js/setPrototypeOf-expected.txt:
+
 2016-11-30  Mark Lam  <[email protected]>
 
         Proxy is not allowed in the global prototype chain.

Modified: releases/WebKitGTK/webkit-2.14/LayoutTests/TestExpectations (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/LayoutTests/TestExpectations	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/LayoutTests/TestExpectations	2017-02-09 08:55:28 UTC (rev 211938)
@@ -666,6 +666,8 @@
 
 [ Debug ] js/regress-141098.html [ Slow ]
 
+webkit.org/b/165401 js/prototype-assignment.html [ Skip ]
+
 # IDBVersionChangeEvent tests need to be rewritten to use event constructors instead of createEvent,
 # after we implement the IDBVersionChangeEvent constructor.
 webkit.org/b/145390 storage/indexeddb/events.html [ Failure ]

Modified: releases/WebKitGTK/webkit-2.14/LayoutTests/http/tests/security/window-named-valueOf-expected.txt (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/LayoutTests/http/tests/security/window-named-valueOf-expected.txt	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/LayoutTests/http/tests/security/window-named-valueOf-expected.txt	2017-02-09 08:55:28 UTC (rev 211938)
@@ -1,2 +1,2 @@
-CONSOLE MESSAGE: line 1: Threw exception: TypeError: Illegal constructor
+CONSOLE MESSAGE: line 1: Threw exception: TypeError: Cannot set prototype of immutable prototype object
 This passes if it doesn't alert the contents of innocent-victim.  

Modified: releases/WebKitGTK/webkit-2.14/LayoutTests/js/dom/proxy-is-not-allowed-in-global-prototype-chain-expected.txt (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/LayoutTests/js/dom/proxy-is-not-allowed-in-global-prototype-chain-expected.txt	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/LayoutTests/js/dom/proxy-is-not-allowed-in-global-prototype-chain-expected.txt	2017-02-09 08:55:28 UTC (rev 211938)
@@ -1,3 +1,2 @@
-CONSOLE MESSAGE: TypeError: Proxy is not allowed in the global prototype chain.
-onerror saw TypeError: Proxy is not allowed in the global prototype chain.
+Caught: TypeError: Cannot set prototype of immutable prototype object
 

Modified: releases/WebKitGTK/webkit-2.14/LayoutTests/js/dom/proxy-is-not-allowed-in-global-prototype-chain.html (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/LayoutTests/js/dom/proxy-is-not-allowed-in-global-prototype-chain.html	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/LayoutTests/js/dom/proxy-is-not-allowed-in-global-prototype-chain.html	2017-02-09 08:55:28 UTC (rev 211938)
@@ -18,7 +18,6 @@
 
 } catch (e) {
     log("Caught: " + e);
-    log(e.stack);
 }
 
 function log(s)

Added: releases/WebKitGTK/webkit-2.14/LayoutTests/js/prototype-assignment-expected.txt (0 => 211938)


--- releases/WebKitGTK/webkit-2.14/LayoutTests/js/prototype-assignment-expected.txt	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.14/LayoutTests/js/prototype-assignment-expected.txt	2017-02-09 08:55:28 UTC (rev 211938)
@@ -0,0 +1,4 @@
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: releases/WebKitGTK/webkit-2.14/LayoutTests/js/prototype-assignment.html (0 => 211938)


--- releases/WebKitGTK/webkit-2.14/LayoutTests/js/prototype-assignment.html	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.14/LayoutTests/js/prototype-assignment.html	2017-02-09 08:55:28 UTC (rev 211938)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+</body>
+</html>

Added: releases/WebKitGTK/webkit-2.14/LayoutTests/js/script-tests/prototype-assignment.js (0 => 211938)


--- releases/WebKitGTK/webkit-2.14/LayoutTests/js/script-tests/prototype-assignment.js	                        (rev 0)
+++ releases/WebKitGTK/webkit-2.14/LayoutTests/js/script-tests/prototype-assignment.js	2017-02-09 08:55:28 UTC (rev 211938)
@@ -0,0 +1,438 @@
+//@ runFTLNoCJIT("--useJIT=false")
+// FIXME: Remove the "--useJIT=false" option when https://bugs.webkit.org/show_bug.cgi?id=165401 is fixed.
+
+// This test suite compares the behavior of setting the prototype on various values
+// (using Object.setPrototypeOf(), obj.__proto__ assignment, and Reflect.setPrototypeOf())
+// against what is specified in the ES spec.  The expected behavior specified according
+// to the spec is expressed in expectationsForObjectSetPrototypeOf,
+// expectationsForSetUnderscoreProto, and expectationsForReflectSetPrototypeOf.
+
+
+var inBrowser = (typeof window != "undefined");
+
+// Test configuration options:
+var verbose = false;
+var maxIterations = 1;
+var throwOnEachError = true;
+
+var testUndefined = true;
+var testNull = true;
+var testTrue = true;
+var testFalse = true;
+var testNumbers = true;
+var testString = true;
+var testSymbol = true;
+var testObject = true;
+var testGlobal = true;
+var testWindowProtos = inBrowser;
+
+//====================================================================================
+// Error messages:
+
+if (inBrowser) {
+    let userAgent = navigator.userAgent;
+    if (userAgent.match(/ Chrome\/[0-9]+/)) engine = "chrome";
+    else if (userAgent.match(/ Firefox\/[0-9]+/)) engine = "default";
+    else engine = "safari";
+} else
+    engine = "jsc";
+
+// Set default error messages and then override with engine specific ones below.
+DefaultTypeError = "TypeError: ";
+CannotSetPrototypeOfImmutablePrototypeObject = DefaultTypeError;
+CannotSetPrototypeOfThisObject = DefaultTypeError;
+CannotSetPrototypeOfUndefinedOrNull = DefaultTypeError;
+CannotSetPrototypeOfNonObject = DefaultTypeError;
+PrototypeValueCanOnlyBeAnObjectOrNull = DefaultTypeError;
+ObjectProtoCalledOnNullOrUndefinedError = DefaultTypeError;
+ReflectSetPrototypeOfRequiresTheFirstArgumentBeAnObject = DefaultTypeError;
+ReflectSetPrototypeOfRequiresTheSecondArgumentBeAnObjectOrNull = DefaultTypeError;
+
+if (engine == "jsc" || engine === "safari") {
+    CannotSetPrototypeOfImmutablePrototypeObject = "TypeError: Cannot set prototype of immutable prototype object";
+    CannotSetPrototypeOfThisObject = "TypeError: Cannot set prototype of this object";
+    CannotSetPrototypeOfUndefinedOrNull = "TypeError: Cannot set prototype of undefined or null";
+    CannotSetPrototypeOfNonObject = "TypeError: Cannot set prototype of non-object";
+    PrototypeValueCanOnlyBeAnObjectOrNull = "TypeError: Prototype value can only be an object or null";
+    ObjectProtoCalledOnNullOrUndefinedError = "TypeError: Object.prototype.__proto__ called on null or undefined";
+    ReflectSetPrototypeOfRequiresTheFirstArgumentBeAnObject = "TypeError: Reflect.setPrototypeOf requires the first argument be an object";
+    ReflectSetPrototypeOfRequiresTheSecondArgumentBeAnObjectOrNull = "TypeError: Reflect.setPrototypeOf requires the second argument be either an object or null";
+} else if (engine === "chrome") {
+    CannotSetPrototypeOfImmutablePrototypeObject = "TypeError: Immutable prototype object ";
+}
+
+//====================================================================================
+// Utility functions:
+
+if (inBrowser)
+    print = console.log;
+
+function reportError(errorMessage) {
+    if (throwOnEachError)
+        throw errorMessage;
+    else
+        print(errorMessage);
+}
+
+function shouldEqual(testID, resultType, actual, expected) {
+    if (actual != expected)
+        reportError("ERROR in " + resultType
+            + ": expect " + stringify(expected) + ", actual " + stringify(actual)
+            + " in test: " + testID.signature + " on iteration " + testID.iteration);
+}
+
+function shouldThrow(testID, resultType, actual, expected) {
+    let actualStr = "" + actual;
+    if (!actualStr.startsWith(expected))
+        reportError("ERROR in " + resultType
+            + ": expect " + expected + ", actual " + actual
+            + " in test: " + testID.signature + " on iteration " + testID.iteration);
+}
+
+function stringify(value) {
+    if (typeof value == "string") return '"' + value + '"';
+    if (typeof value == "symbol") return value.toString();
+
+    if (value === origGlobalProto) return "origGlobalProto"; 
+    if (value === origObjectProto) return "origObjectProto"; 
+    if (value === newObjectProto) return "newObjectProto";
+    if (value === proxyObject) return "proxyObject";
+
+    if (value === null) return "null";
+    if (typeof value == "object") return "object"; 
+    return "" + value;
+}
+
+function makeTestID(index, iteration, targetName, protoToSet, protoSetter, expected) {
+    let testID = {};
+    testID.signature = "[" + index + "] "
+        + protoSetter.actionName + "|"
+        + targetName + "|"
+        + stringify(protoToSet) + "|"
+        + stringify(expected.result) + "|"
+        + stringify(expected.proto) + "|"
+        + stringify(expected.exception);
+    testID.iteration = iteration;
+    return testID;
+}
+
+//====================================================================================
+// Functions to express the expectations of the ES specification:
+
+function doInternalSetPrototypeOf(result, target, origProto, newProto) {
+    if (!target.setPrototypeOf) {
+        result.success = true;
+        result.exception = undefined;
+        return;
+    }
+    target.setPrototypeOf(result, origProto, newProto);
+}
+
+// 9.1.2.1 OrdinarySetPrototypeOf ( O, V )
+// https://tc39.github.io/ecma262/#sec-ordinarysetprototypeof
+function ordinarySetPrototypeOf(result, currentProto, newProto) {
+    // 9.1.2.1-4 If SameValue(V, current) is true, return true.
+    if (newProto === currentProto) {
+        result.success = true;
+        return;
+    }
+    // 9.1.2.1-5 [extensibility check not tested here]
+    // 9.1.2.1-8 [cycle check not tested here]
+    result.success = true;
+}
+
+// 9.4.7.2 SetImmutablePrototype ( O, V )
+// https://tc39.github.io/ecma262/#sec-set-immutable-prototype
+function setImmutablePrototype(result, currentProto, newProto) {
+    if (newProto === currentProto) {
+        result.success = true;
+        return;
+    }
+    result.success = false;
+    result.exception = CannotSetPrototypeOfImmutablePrototypeObject;
+}
+
+// HTML spec: 7.4.2 [[SetPrototypeOf]] ( V )
+// https://html.spec.whatwg.org/#windowproxy-setprototypeof
+function windowProxySetPrototypeOf(result, currentProto, newProto) {
+    result.success = false;
+    result.exception = CannotSetPrototypeOfThisObject;
+}
+
+
+var count = 0;
+function initSetterExpectation(target, newProto) {
+    var targetValue = target.value();
+    var origProto = undefined;
+    if (targetValue != null && targetValue != undefined)
+        origProto = targetValue.__proto__; // Default to old proto.
+
+    var expected = {};
+    expected.targetValue = targetValue;
+    expected.origProto = origProto;
+    expected.exception = undefined;
+    expected.proto = origProto;
+    expected.result = undefined;
+
+    return expected;
+}
+
+// 19.1.2.21 Object.setPrototypeOf ( O, proto )
+// https://tc39.github.io/ecma262/#sec-object.setprototypeof
+function objectSetPrototypeOf(target, newProto) {
+    let expected = initSetterExpectation(target, newProto);
+    var targetValue = expected.targetValue;
+    var origProto = expected.origProto;
+
+    function throwIfNoExceptionPending(e) {
+        if (!expected.exception)
+            expected.exception = e;
+    }
+
+    // 19.1.2.21-1 Let O be ? RequireObjectCoercible(O).
+    if (targetValue == undefined || targetValue == null)
+        throwIfNoExceptionPending(CannotSetPrototypeOfUndefinedOrNull);
+
+    // 19.1.2.21-2 If Type(proto) is neither Object nor Null, throw a TypeError exception.
+    if (typeof newProto != "object")
+        throwIfNoExceptionPending(PrototypeValueCanOnlyBeAnObjectOrNull);
+
+    // 19.1.2.21-3 If Type(O) is not Object, return O.
+    else if (typeof targetValue != "object")
+        expected.result = targetValue;
+
+    // 19.1.2.21-4 Let status be ? O.[[SetPrototypeOf]](proto).
+    else {
+        // 19.1.2.21-5 If status is false, throw a TypeError exception.
+        let result = {};
+        doInternalSetPrototypeOf(result, target, origProto, newProto);
+        if (result.success)
+            expected.proto = newProto;
+        else
+            throwIfNoExceptionPending(result.exception);
+
+        // 19.1.2.21-6 Return O.
+        expected.result = targetValue;
+    }
+
+    return expected;
+}
+objectSetPrototypeOf.action = "" newProto) => Object.setPrototypeOf(obj, newProto);
+objectSetPrototypeOf.actionName = "Object.setPrototypeOf";
+
+
+// B.2.2.1.2 set Object.prototype.__proto__
+// https://tc39.github.io/ecma262/#sec-set-object.prototype.__proto__
+function setUnderscoreProto(target, newProto) {
+    let expected = initSetterExpectation(target, newProto);
+    var targetValue = expected.targetValue;
+    var origProto = expected.origProto;
+
+    function throwIfNoExceptionPending(e) {
+        if (!expected.exception)
+            expected.exception = e;
+    }
+
+    // B.2.2.1.2-1 Let O be ? RequireObjectCoercible(this value).
+    if (targetValue == undefined || targetValue == null)
+        throwIfNoExceptionPending(DefaultTypeError);
+
+    // B.2.2.1.2-2 If Type(proto) is neither Object nor Null, return undefined.
+    if (typeof newProto != "object")
+        expected.result = undefined;
+    
+    // B.2.2.1.2-3 If Type(O) is not Object, return undefined.
+    else if (typeof targetValue != "object")
+        expected.result = undefined;
+
+    // B.2.2.1.2-4 Let status be ? O.[[SetPrototypeOf]](proto).
+    else {
+        // B.2.2.1.2-5 If status is false, throw a TypeError exception.
+        let result = {};
+        doInternalSetPrototypeOf(result, target, origProto, newProto);
+        if (result.success)
+            expected.proto = newProto;
+        else
+            throwIfNoExceptionPending(result.exception);
+
+        // B.2.2.1.2-6 Return undefined.
+        expected.result = undefined;
+    }
+
+    // Override the result to be the newProto value because the statement obj.__proto__ = value
+    // will produce the rhs value, not the result of the obj.__proto__ setter.
+    expected.result = newProto;
+    return expected;    
+}
+setUnderscoreProto.action = "" newProto) => (obj.__proto__ = newProto);
+setUnderscoreProto.actionName = "obj.__proto__";
+
+
+// 26.1.13 Reflect.setPrototypeOf ( target, proto )
+// https://tc39.github.io/ecma262/#sec-reflect.setprototypeof
+// function expectationsForReflectSetPrototypeOf(target, newProto, targetExpectation) {
+function reflectSetPrototypeOf(target, newProto) {
+    let expected = initSetterExpectation(target, newProto);
+    var targetValue = expected.targetValue;
+    var origProto = expected.origProto;
+
+    function throwIfNoExceptionPending(e) {
+        if (!expected.exception)
+            expected.exception = e;
+    }
+
+    // 26.1.13-1 If Type(target) is not Object, throw a TypeError exception.
+    if (targetValue === null || typeof targetValue != "object")
+        throwIfNoExceptionPending(ReflectSetPrototypeOfRequiresTheFirstArgumentBeAnObject);
+
+    // 26.1.13-2 If Type(proto) is not Object and proto is not null, throw a TypeError exception.
+    if (typeof newProto != "object")
+        throwIfNoExceptionPending(ReflectSetPrototypeOfRequiresTheSecondArgumentBeAnObjectOrNull);
+    
+    // 26.1.13-3 Return ? target.[[SetPrototypeOf]](proto).
+    let result = {};
+    doInternalSetPrototypeOf(result, target, origProto, newProto);
+    expected.result = result.success;
+    if (result.success)
+        expected.proto = newProto;
+
+    return expected;    
+}
+reflectSetPrototypeOf.action = "" newProto) => Reflect.setPrototypeOf(obj, newProto);
+reflectSetPrototypeOf.actionName = "Reflect.setPrototypeOf";
+
+
+//====================================================================================
+// Test Data:
+
+var global = this;
+var origGlobalProto = global.__proto__;
+var origObjectProto = {}.__proto__;
+var proxyObject = new Proxy({ }, {
+    setPrototypeOf(target, value) {
+        throw "Thrown from proxy";
+    }
+});
+var newObjectProto = { toString() { return "newObjectProto"; } };
+
+var targets = [];
+
+if (this.testUndefined) targets.push({ name: "undefined", value: () => undefined });
+if (this.testNull)      targets.push({ name: "null", value: () => null });
+if (this.testTrue)     targets.push({ name: "true", value: () => true });
+if (this.testFalse)        targets.push({ name: "false", value: () => false });
+
+if (this.testNumbers) {
+    targets.push({ name: "0", value: () => 0 });
+    targets.push({ name: "11", value: () => 11 });
+    targets.push({ name: "123.456", value: () => 123.456 });
+}
+
+if (this.testString)    targets.push({ name: '"doh"', value: () => "doh" });
+if (this.testSymbol)    targets.push({ name: "Symbol(doh)", value: () => Symbol("doh") });
+
+if (this.testObject) {
+    targets.push({
+        name: "{}", 
+        value: () => {},
+        setPrototypeOf: ordinarySetPrototypeOf
+    });
+    targets.push({
+        name: "{}.__proto__", 
+        value: () => origObjectProto,
+        setPrototypeOf: setImmutablePrototype
+    });
+}
+if (this.testGlobal) {
+    targets.push({
+        name: inBrowser ? "window" : "global",
+        value: () => global,
+        setPrototypeOf: windowProxySetPrototypeOf
+    });
+}
+if (this.testWindowProtos) {
+    if (inBrowser) {
+        let depth = 1;
+        let proto = window.__proto__;
+        while (proto) { 
+            let name = "window";
+            for (var i = 0; i < depth; i++)
+                name += ".__proto__";
+
+            let currentProto = proto;
+            targets.push({
+                name: name, 
+                value: () => currentProto,
+                setPrototypeOf: setImmutablePrototype
+            });
+
+            proto = proto.__proto__;
+            depth++;
+        }
+    }
+}
+
+
+var newProtos = [
+    undefined,
+    null,
+    true,
+    false,
+    0,
+    11,
+    123.456,
+    "doh",
+    Symbol("doh"),
+    {},
+    origObjectProto,
+    origGlobalProto,
+    newObjectProto
+];
+
+var protoSetters = [
+    objectSetPrototypeOf,
+    setUnderscoreProto,
+    reflectSetPrototypeOf,
+];
+
+
+//====================================================================================
+// Test driver functions:
+
+function test(testID, targetValue, newProto, setterAction, expected) {
+    let exception = undefined;
+    let result = undefined;
+    try {
+        result = setterAction(targetValue, newProto);
+    } catch (e) {
+        exception = e;
+    }
+    shouldThrow(testID, "exception", exception, expected.exception);
+    if (!expected.exception) {
+        shouldEqual(testID, "__proto__", targetValue.__proto__, expected.proto);
+        shouldEqual(testID, "result", result, expected.result);
+    }
+}
+
+function runTests() {
+    let testIndex = 0;
+    for (protoSetter of protoSetters) {
+        for (target of targets) {
+            for (newProto of newProtos) {
+                let currentTestIndex = testIndex++;
+                for (var i = 0; i < maxIterations; i++) {
+                    let expected = protoSetter(target, newProto);
+                    let targetValue = expected.targetValue;
+
+                    let testID = makeTestID(currentTestIndex, i, target.name, newProto, protoSetter, expected);
+                    if (verbose && i == 0)
+                        print("test: " + testID.signature);
+
+                    test(testID, targetValue, newProto, protoSetter.action, expected);
+                }
+            }
+        }
+    }
+}
+
+runTests();

Modified: releases/WebKitGTK/webkit-2.14/LayoutTests/js/setPrototypeOf-expected.txt (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/LayoutTests/js/setPrototypeOf-expected.txt	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/LayoutTests/js/setPrototypeOf-expected.txt	2017-02-09 08:55:28 UTC (rev 211938)
@@ -30,87 +30,87 @@
 PASS Object.getPrototypeOf(value) is (value).__proto__
 
 Non-Coercible value
-PASS Object.setPrototypeOf(undefined, {}) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(null, {}) threw exception TypeError: Type error.
+PASS Object.setPrototypeOf(undefined, {}) threw exception TypeError: Cannot set prototype of undefined or null.
+PASS Object.setPrototypeOf(null, {}) threw exception TypeError: Cannot set prototype of undefined or null.
 
 Non-Object/Null proto
 object (Function)
-PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, true) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, false) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Type error.
+PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, true) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, false) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Prototype value can only be an object or null.
 object (Function2)
-PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, true) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, false) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Type error.
+PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, true) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, false) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Prototype value can only be an object or null.
 object (Object)
-PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, true) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, false) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Type error.
+PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, true) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, false) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Prototype value can only be an object or null.
 object (Object2)
-PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, true) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, false) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Type error.
+PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, true) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, false) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Prototype value can only be an object or null.
 object (RegExp)
-PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, true) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, false) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Type error.
+PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, true) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, false) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Prototype value can only be an object or null.
 object (Array)
-PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, true) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, false) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Type error.
+PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, true) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, false) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Prototype value can only be an object or null.
 object (Error)
-PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, true) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, false) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Type error.
+PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, true) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, false) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Prototype value can only be an object or null.
 object (Date)
-PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, true) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, false) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Type error.
+PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, true) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, false) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Prototype value can only be an object or null.
 object (Number)
-PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, true) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, false) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Type error.
+PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, true) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, false) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Prototype value can only be an object or null.
 object (Boolean)
-PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, true) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, false) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Type error.
+PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, true) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, false) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Prototype value can only be an object or null.
 object (String)
-PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, true) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, false) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Type error.
-PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Type error.
+PASS Object.setPrototypeOf(object, 0) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, true) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, false) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, 'string') threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, Symbol()) threw exception TypeError: Prototype value can only be an object or null.
+PASS Object.setPrototypeOf(object, undefined) threw exception TypeError: Prototype value can only be an object or null.
 
 Object and object proto
 object (Function) proto (Function)

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/ChangeLog	2017-02-09 08:55:28 UTC (rev 211938)
@@ -1,3 +1,30 @@
+2016-12-06  Mark Lam  <[email protected]>
+
+        Introduce the concept of Immutable Prototype Exotic Objects to comply with the spec.
+        https://bugs.webkit.org/show_bug.cgi?id=165227
+        <rdar://problem/29442665>
+
+        Reviewed by Saam Barati.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::setPrototypeWithCycleCheck):
+        - This is where we check for immutable prototype exotic objects and refuse to set
+          the prototype if needed.
+          See https://tc39.github.io/ecma262/#sec-immutable-prototype-exotic-objects.
+
+        * runtime/JSTypeInfo.h:
+        (JSC::TypeInfo::isImmutablePrototypeExoticObject):
+        * runtime/Structure.h:
+        - Add flag for declaring immutable prototype exotic objects.
+
+        * runtime/ObjectPrototype.h:
+        - Declare that Object.prototype is an immutable prototype exotic object.
+          See https://tc39.github.io/ecma262/#sec-properties-of-the-object-prototype-object.
+
+        * runtime/ObjectConstructor.cpp:
+        (JSC::objectConstructorSetPrototypeOf):
+        - Use better error messages.
+
 2016-11-30  Mark Lam  <[email protected]>
 
         Proxy is not allowed in the global prototype chain.

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSObject.cpp (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSObject.cpp	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSObject.cpp	2017-02-09 08:55:28 UTC (rev 211938)
@@ -1291,6 +1291,9 @@
     if (this->getPrototypeDirect() == prototype)
         return true;
 
+    if (this->structure(vm)->isImmutablePrototypeExoticObject())
+        return throwTypeError(exec, scope, ASCIILiteral("Cannot set prototype of immutable prototype object"));
+
     bool isExtensible = this->isExtensible(exec);
     if (vm.exception())
         return false;

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSTypeInfo.h (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSTypeInfo.h	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/JSTypeInfo.h	2017-02-09 08:55:28 UTC (rev 211938)
@@ -52,6 +52,7 @@
 static const unsigned NewImpurePropertyFiresWatchpoints = 1 << 12;
 static const unsigned IsEnvironmentRecord = 1 << 13;
 static const unsigned GetOwnPropertySlotIsImpureForPropertyAbsence = 1 << 14;
+static const unsigned IsImmutablePrototypeExoticObject = 1 << 15;
 
 class TypeInfo {
 public:
@@ -93,6 +94,7 @@
     bool getOwnPropertySlotIsImpureForPropertyAbsence() const { return isSetOnFlags2(GetOwnPropertySlotIsImpureForPropertyAbsence); }
     bool newImpurePropertyFiresWatchpoints() const { return isSetOnFlags2(NewImpurePropertyFiresWatchpoints); }
     bool isEnvironmentRecord() const { return isSetOnFlags2(IsEnvironmentRecord); }
+    bool isImmutablePrototypeExoticObject() const { return isSetOnFlags2(IsImmutablePrototypeExoticObject); }
 
     static ptrdiff_t flagsOffset()
     {

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/ObjectConstructor.cpp (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/ObjectConstructor.cpp	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/ObjectConstructor.cpp	2017-02-09 08:55:28 UTC (rev 211938)
@@ -224,11 +224,11 @@
 
     JSValue objectValue = exec->argument(0);
     if (objectValue.isUndefinedOrNull())
-        return throwVMTypeError(exec, scope);
+        return throwVMTypeError(exec, scope, ASCIILiteral("Cannot set prototype of undefined or null"));
 
     JSValue protoValue = exec->argument(1);
     if (!protoValue.isObject() && !protoValue.isNull())
-        return throwVMTypeError(exec, scope);
+        return throwVMTypeError(exec, scope, ASCIILiteral("Prototype value can only be an object or null"));
 
     JSObject* object = objectValue.toObject(exec);
     if (exec->hadException())

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/ObjectPrototype.h (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/ObjectPrototype.h	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/ObjectPrototype.h	2017-02-09 08:55:28 UTC (rev 211938)
@@ -28,6 +28,7 @@
 class ObjectPrototype : public JSNonFinalObject {
 public:
     typedef JSNonFinalObject Base;
+    static const unsigned StructureFlags = Base::StructureFlags | IsImmutablePrototypeExoticObject;
 
     static ObjectPrototype* create(VM&, JSGlobalObject*, Structure*);
 

Modified: releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/Structure.h (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/Structure.h	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/Source/_javascript_Core/runtime/Structure.h	2017-02-09 08:55:28 UTC (rev 211938)
@@ -219,6 +219,11 @@
             && typeInfo().newImpurePropertyFiresWatchpoints();
     }
 
+    bool isImmutablePrototypeExoticObject()
+    {
+        return typeInfo().isImmutablePrototypeExoticObject();
+    }
+
     // We use SlowPath in GetByIdStatus for structures that may get new impure properties later to prevent
     // DFG from inlining property accesses since structures don't transition when a new impure property appears.
     bool takesSlowPathInDFGForImpureProperty()

Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/ChangeLog	2017-02-09 08:55:28 UTC (rev 211938)
@@ -1,3 +1,38 @@
+2016-12-06  Mark Lam  <[email protected]>
+
+        Introduce the concept of Immutable Prototype Exotic Objects to comply with the spec.
+        https://bugs.webkit.org/show_bug.cgi?id=165227
+        <rdar://problem/29442665>
+
+        Reviewed by Saam Barati.
+
+        Make all objects in window.__proto__'s prototype chain immutable prototype exotic
+        objects.  This gives us roughly equivalent behavior to other browsers.  
+
+        Firefox's behavior differ slightly in that Firefox will fail any attempted
+        assignment their __proto__, while the immutable prototype exotic objects will
+        only fail if the assignment is of a different value.  See
+        https://tc39.github.io/ecma262/#sec-immutable-prototype-exotic-objects.
+
+        Chrome differs in that assignment to window.__proto__ is also handled like an
+        immutable prototype exotic object.  Instead we adhere to the current HTML spec
+        that says that the assignment should fail unconditionally.  See
+        https://html.spec.whatwg.org/#the-windowproxy-exotic-object and
+        https://html.spec.whatwg.org/#windowproxy-setprototypeof.
+
+        If the HTML spec is changed to make the WindowProxy and Location objects into
+        immutable prototype exotic objects later, we can update to match the spec then.
+
+        Test: js/prototype-assignment.html
+
+        * bindings/js/JSDOMWindowProperties.h:
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateHeader):
+        (GeneratePrototypeDeclaration):
+        * bindings/scripts/IDLAttributes.txt:
+        * dom/EventTarget.idl:
+        * page/DOMWindow.idl:
+
 2016-11-14  Brent Fulgham  <[email protected]>
 
         Correct handling of changing input type

Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/js/JSDOMWindowProperties.h (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/js/JSDOMWindowProperties.h	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/js/JSDOMWindowProperties.h	2017-02-09 08:55:28 UTC (rev 211938)
@@ -50,7 +50,7 @@
     static bool getOwnPropertySlot(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&);
     static bool getOwnPropertySlotByIndex(JSC::JSObject*, JSC::ExecState*, unsigned propertyName, JSC::PropertySlot&);
 
-    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | Base::StructureFlags;
+    static const unsigned StructureFlags = JSC::GetOwnPropertySlotIsImpureForPropertyAbsence | JSC::InterceptsGetOwnPropertySlotByIndexEvenWhenLengthIsNotZero | JSC::OverridesGetOwnPropertySlot | JSC::IsImmutablePrototypeExoticObject | Base::StructureFlags;
 
 protected:
     JSDOMWindowProperties(JSC::Structure* structure, JSC::JSGlobalObject& globalObject)

Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm	2017-02-09 08:55:28 UTC (rev 211938)
@@ -1232,9 +1232,13 @@
             $structureFlags{"JSC::GetOwnPropertySlotIsImpureForPropertyAbsence"} = 1;
         }
     }
+
     if ($interface->extendedAttributes->{"NewImpurePropertyFiresWatchpoints"}) {
         $structureFlags{"JSC::NewImpurePropertyFiresWatchpoints"} = 1;
     }
+    if ($interface->extendedAttributes->{"IsImmutablePrototypeExoticObject"}) {
+        $structureFlags{"JSC::IsImmutablePrototypeExoticObject"} = 1;
+    }
     if ($interface->extendedAttributes->{"CustomCall"}) {
         $structureFlags{"JSC::TypeOfShouldCallGetCallData"} = 1;
     }
@@ -5188,6 +5192,8 @@
         push(@$outputArray, "    static bool defineOwnProperty(JSC::JSObject*, JSC::ExecState*, JSC::PropertyName, const JSC::PropertyDescriptor&, bool shouldThrow);\n");
     }
 
+    $structureFlags{"JSC::IsImmutablePrototypeExoticObject"} = 1 if $interface->extendedAttributes->{IsImmutablePrototypeExoticObjectOnPrototype};
+
     # structure flags
     if (%structureFlags) {
         push(@$outputArray, "public:\n");

Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/scripts/IDLAttributes.txt (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/scripts/IDLAttributes.txt	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/bindings/scripts/IDLAttributes.txt	2017-02-09 08:55:28 UTC (rev 211938)
@@ -75,6 +75,8 @@
 ImplicitThis
 InitializedByEventConstructor
 InterfaceName=*
+IsImmutablePrototypeExoticObject
+IsImmutablePrototypeExoticObjectOnPrototype
 IsWeakCallback
 JSBuiltin
 JSBuiltinConstructor

Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/dom/EventTarget.idl (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/Source/WebCore/dom/EventTarget.idl	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/dom/EventTarget.idl	2017-02-09 08:55:28 UTC (rev 211938)
@@ -21,6 +21,7 @@
 [
     CustomToJSObject,
     Exposed=(Window,Worker),
+    IsImmutablePrototypeExoticObjectOnPrototype,
     JSCustomHeader,
     JSCustomToNativeObject,
 ] interface EventTarget {

Modified: releases/WebKitGTK/webkit-2.14/Source/WebCore/page/DOMWindow.idl (211937 => 211938)


--- releases/WebKitGTK/webkit-2.14/Source/WebCore/page/DOMWindow.idl	2017-02-09 08:55:07 UTC (rev 211937)
+++ releases/WebKitGTK/webkit-2.14/Source/WebCore/page/DOMWindow.idl	2017-02-09 08:55:28 UTC (rev 211938)
@@ -34,6 +34,8 @@
     ExportMacro=WEBCORE_EXPORT,
     ImplicitThis,
     InterfaceName=Window,
+    IsImmutablePrototypeExoticObject,
+    IsImmutablePrototypeExoticObjectOnPrototype,
     JSCustomDefineOwnProperty,
     JSCustomMarkFunction,
     JSCustomToNativeObject,
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to