Title: [211116] branches/safari-603-branch

Diff

Modified: branches/safari-603-branch/JSTests/ChangeLog (211115 => 211116)


--- branches/safari-603-branch/JSTests/ChangeLog	2017-01-24 23:29:25 UTC (rev 211115)
+++ branches/safari-603-branch/JSTests/ChangeLog	2017-01-24 23:29:30 UTC (rev 211116)
@@ -1,3 +1,24 @@
+2017-01-24  Matthew Hanson  <matthew_han...@apple.com>
+
+        Merge r211070. rdar://problem/30121809
+
+    2017-01-23  Saam Barati  <sbar...@apple.com>
+
+            https://bugs.webkit.org/show_bug.cgi?id=167247
+            JSC: operationSpreadGeneric uses the wrong global object for the builtin function and slow_path_spread consults the wrong global object to prove if the iterator protocol is unobservable
+            <rdar://problem/30121809>
+
+            Reviewed by Filip Pizlo.
+
+            * stress/spread-consults-correct-global-object.js: Added.
+            (assert):
+            (spread):
+            * stress/spread-correct-global-object-on-exception.js: Added.
+            (assert):
+            (spread):
+            (const.objectText.let.o.Symbol.iterator):
+            (catch):
+
 2017-01-18  Matthew Hanson  <matthew_han...@apple.com>
 
         Merge r210844. rdar://problem/29993906

Added: branches/safari-603-branch/JSTests/stress/spread-consults-correct-global-object.js (0 => 211116)


--- branches/safari-603-branch/JSTests/stress/spread-consults-correct-global-object.js	                        (rev 0)
+++ branches/safari-603-branch/JSTests/stress/spread-consults-correct-global-object.js	2017-01-24 23:29:30 UTC (rev 211116)
@@ -0,0 +1,18 @@
+function assert(b) {
+    if (!b)
+        throw new Error("Bad assertion");
+}
+function spread(a) {
+    return [...a];
+}
+noInline(spread);
+
+const foo = {};
+
+let secondGlobalObject = createGlobalObject();
+secondGlobalObject.Array.prototype[0] = foo;
+let x = secondGlobalObject.Function("return [, 20];")();
+let result = spread(x);
+assert(result.length === 2);
+assert(result[0] === foo);
+assert(result[1] === 20);

Added: branches/safari-603-branch/JSTests/stress/spread-correct-global-object-on-exception.js (0 => 211116)


--- branches/safari-603-branch/JSTests/stress/spread-correct-global-object-on-exception.js	                        (rev 0)
+++ branches/safari-603-branch/JSTests/stress/spread-correct-global-object-on-exception.js	2017-01-24 23:29:30 UTC (rev 211116)
@@ -0,0 +1,43 @@
+function assert(b) {
+    if (!b)
+        throw new Error("Bad assertion");
+}
+function spread(a) {
+    return [...a];
+}
+noInline(spread);
+
+const objectText = `
+    let o = {
+        [Symbol.iterator]() {
+            return {
+                next() {
+                    return {done: true};
+                }
+            };
+        }
+    };
+    o;
+`;
+
+let o = eval(objectText);
+for (let i = 0; i < 1000; i++) {
+    if (i % 23 === 0)
+        o = eval(objectText);
+    spread(o);
+}
+
+let myGlobalObject = globalObjectForObject(new Object);
+
+let secondGlobalObject = createGlobalObject();
+let o2 = secondGlobalObject.Function("return {};")();
+
+let error = null;
+try {
+    spread(o2);
+} catch(e) {
+    error = e;
+}
+
+assert(error);
+assert(globalObjectForObject(error) === myGlobalObject);

Modified: branches/safari-603-branch/Source/_javascript_Core/ChangeLog (211115 => 211116)


--- branches/safari-603-branch/Source/_javascript_Core/ChangeLog	2017-01-24 23:29:25 UTC (rev 211115)
+++ branches/safari-603-branch/Source/_javascript_Core/ChangeLog	2017-01-24 23:29:30 UTC (rev 211116)
@@ -1,5 +1,48 @@
 2017-01-24  Matthew Hanson  <matthew_han...@apple.com>
 
+        Merge r211070. rdar://problem/30121809
+
+    2017-01-23  Saam Barati  <sbar...@apple.com>
+
+            https://bugs.webkit.org/show_bug.cgi?id=167247
+            JSC: operationSpreadGeneric uses the wrong global object for the builtin function and slow_path_spread consults the wrong global object to prove if the iterator protocol is unobservable
+            <rdar://problem/30121809>
+
+            Reviewed by Filip Pizlo.
+
+            There were two bugs in the different tiers with respect to how
+            spread handled global objects.
+
+            The first was in the LLInt/baseline inside slow_path_spread:
+
+            We consulted the lexical global object instead of the thing we're
+            spreading's global object to determine if the array iterator protocol
+            is unobservable. This is wrong if the incoming array is from a different
+            global object. We must consult the incoming array's global object
+            to determine if it can be spread using the fast path.
+
+            The second was in operationSpreadGeneric in the DFG/FTL:
+
+            We were always using the incoming array's global object, even
+            when going down the slow path. This is wrong because we were
+            fetching the builtin iteration function helper from the incoming
+            array's global object, which meant that if the iterator function
+            were to throw an exception, it could leak objects from a different
+            global object. We should be executing the iterator function with
+            the lexical global object.
+
+            * dfg/DFGOperations.cpp:
+            * jsc.cpp:
+            (GlobalObject::finishCreation):
+            (functionGlobalObjectForObject):
+            * runtime/CommonSlowPaths.cpp:
+            (JSC::SLOW_PATH_DECL):
+            * runtime/JSArray.h:
+            * runtime/JSArrayInlines.h:
+            (JSC::JSArray::isIteratorProtocolFastAndNonObservable):
+
+2017-01-24  Matthew Hanson  <matthew_han...@apple.com>
+
         Merge r211069. rdar://problem/30173274
 
     2017-01-22  Filip Pizlo  <fpi...@apple.com>

Modified: branches/safari-603-branch/Source/_javascript_Core/dfg/DFGOperations.cpp (211115 => 211116)


--- branches/safari-603-branch/Source/_javascript_Core/dfg/DFGOperations.cpp	2017-01-24 23:29:25 UTC (rev 211115)
+++ branches/safari-603-branch/Source/_javascript_Core/dfg/DFGOperations.cpp	2017-01-24 23:29:30 UTC (rev 211116)
@@ -47,6 +47,7 @@
 #include "Interpreter.h"
 #include "JIT.h"
 #include "JITExceptions.h"
+#include "JSArrayInlines.h"
 #include "JSCInlines.h"
 #include "JSFixedArray.h"
 #include "JSGenericTypedArrayViewConstructorInlines.h"
@@ -1984,19 +1985,18 @@
 
     auto throwScope = DECLARE_THROW_SCOPE(vm);
 
-    JSGlobalObject* globalObject = iterable->structure(vm)->globalObject();
-    if (!globalObject)
-        globalObject = exec->lexicalGlobalObject();
-
-    if (isJSArray(iterable) && globalObject->isArrayIteratorProtocolFastAndNonObservable()) {
+    if (isJSArray(iterable)) {
         JSArray* array = jsCast<JSArray*>(iterable);
-        throwScope.release();
-        return JSFixedArray::createFromArray(exec, vm, array);
+        if (array->isIteratorProtocolFastAndNonObservable()) {
+            throwScope.release();
+            return JSFixedArray::createFromArray(exec, vm, array);
+        }
     }
 
     // FIXME: we can probably make this path faster by having our caller JS code call directly into
     // the iteration protocol builtin: https://bugs.webkit.org/show_bug.cgi?id=164520
 
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     JSArray* array;
     {
         JSFunction* iterationFunction = globalObject->iteratorProtocolFunction();
@@ -2022,7 +2022,7 @@
 
     ASSERT(isJSArray(cell));
     JSArray* array = jsCast<JSArray*>(cell);
-    ASSERT(array->globalObject()->isArrayIteratorProtocolFastAndNonObservable());
+    ASSERT(array->isIteratorProtocolFastAndNonObservable());
 
     return JSFixedArray::createFromArray(exec, vm, array);
 }

Modified: branches/safari-603-branch/Source/_javascript_Core/jsc.cpp (211115 => 211116)


--- branches/safari-603-branch/Source/_javascript_Core/jsc.cpp	2017-01-24 23:29:25 UTC (rev 211115)
+++ branches/safari-603-branch/Source/_javascript_Core/jsc.cpp	2017-01-24 23:29:30 UTC (rev 211116)
@@ -1007,6 +1007,7 @@
 static EncodedJSValue JSC_HOST_CALL functionGetRandomSeed(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionSetRandomSeed(ExecState*);
 static EncodedJSValue JSC_HOST_CALL functionIsRope(ExecState*);
+static EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(ExecState*);
 
 struct Script {
     enum class StrictMode {
@@ -1231,6 +1232,8 @@
         addFunction(vm, "setRandomSeed", functionSetRandomSeed, 1);
         addFunction(vm, "isRope", functionIsRope, 1);
 
+        addFunction(vm, "globalObjectForObject", functionGlobalObjectForObject, 1);
+
         addFunction(vm, "is32BitPlatform", functionIs32BitPlatform, 0);
 
         addFunction(vm, "loadModule", functionLoadModule, 1);
@@ -2104,6 +2107,15 @@
     return JSValue::encode(jsBoolean(!impl));
 }
 
+EncodedJSValue JSC_HOST_CALL functionGlobalObjectForObject(ExecState* exec)
+{
+    JSValue value = exec->argument(0);
+    RELEASE_ASSERT(value.isObject());
+    JSGlobalObject* globalObject = jsCast<JSObject*>(value)->globalObject();
+    RELEASE_ASSERT(globalObject);
+    return JSValue::encode(globalObject);
+}
+
 EncodedJSValue JSC_HOST_CALL functionReadline(ExecState* exec)
 {
     Vector<char, 256> line;

Modified: branches/safari-603-branch/Source/_javascript_Core/runtime/CommonSlowPaths.cpp (211115 => 211116)


--- branches/safari-603-branch/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2017-01-24 23:29:25 UTC (rev 211115)
+++ branches/safari-603-branch/Source/_javascript_Core/runtime/CommonSlowPaths.cpp	2017-01-24 23:29:30 UTC (rev 211116)
@@ -43,6 +43,7 @@
 #include "Interpreter.h"
 #include "IteratorOperations.h"
 #include "JIT.h"
+#include "JSArrayInlines.h"
 #include "JSCInlines.h"
 #include "JSCJSValue.h"
 #include "JSFixedArray.h"
@@ -1034,16 +1035,18 @@
 
     JSValue iterable = OP_C(2).jsValue();
 
-    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
-
-    if (iterable.isCell() && isJSArray(iterable.asCell()) && globalObject->isArrayIteratorProtocolFastAndNonObservable()) {
-        // JSFixedArray::createFromArray does not consult the prototype chain,
-        // so we must be sure that not consulting the prototype chain would
-        // produce the same value during iteration.
+    if (iterable.isCell() && isJSArray(iterable.asCell())) {
         JSArray* array = jsCast<JSArray*>(iterable);
-        RETURN(JSFixedArray::createFromArray(exec, vm, array));
+        if (array->isIteratorProtocolFastAndNonObservable()) {
+            // JSFixedArray::createFromArray does not consult the prototype chain,
+            // so we must be sure that not consulting the prototype chain would
+            // produce the same value during iteration.
+            RETURN(JSFixedArray::createFromArray(exec, vm, array));
+        }
     }
 
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+
     JSArray* array;
     {
         JSFunction* iterationFunction = globalObject->iteratorProtocolFunction();

Modified: branches/safari-603-branch/Source/_javascript_Core/runtime/JSArray.h (211115 => 211116)


--- branches/safari-603-branch/Source/_javascript_Core/runtime/JSArray.h	2017-01-24 23:29:25 UTC (rev 211115)
+++ branches/safari-603-branch/Source/_javascript_Core/runtime/JSArray.h	2017-01-24 23:29:30 UTC (rev 211116)
@@ -150,6 +150,8 @@
     JS_EXPORT_PRIVATE void fillArgList(ExecState*, MarkedArgumentBuffer&);
     JS_EXPORT_PRIVATE void copyToArguments(ExecState*, VirtualRegister firstElementDest, unsigned offset, unsigned length);
 
+    bool isIteratorProtocolFastAndNonObservable();
+
     static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype, IndexingType indexingType)
     {
         return Structure::create(vm, globalObject, prototype, TypeInfo(ArrayType, StructureFlags), info(), indexingType);

Modified: branches/safari-603-branch/Source/_javascript_Core/runtime/JSArrayInlines.h (211115 => 211116)


--- branches/safari-603-branch/Source/_javascript_Core/runtime/JSArrayInlines.h	2017-01-24 23:29:25 UTC (rev 211115)
+++ branches/safari-603-branch/Source/_javascript_Core/runtime/JSArrayInlines.h	2017-01-24 23:29:30 UTC (rev 211116)
@@ -93,4 +93,9 @@
     return lengthValue.toLength(exec);
 }
 
+ALWAYS_INLINE bool JSArray::isIteratorProtocolFastAndNonObservable()
+{
+    return globalObject()->isArrayIteratorProtocolFastAndNonObservable();
+}
+
 } // namespace JSC
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to