Title: [222421] trunk
Revision
222421
Author
[email protected]
Date
2017-09-22 19:08:04 -0700 (Fri, 22 Sep 2017)

Log Message

Speculatively change iteration protocall to use the same next function
https://bugs.webkit.org/show_bug.cgi?id=175653

Reviewed by Saam Barati.

JSTests:

Change test to match the new iteration behavior.

* stress/spread-optimized-properly.js:

Source/_javascript_Core:

This patch speculatively makes a change to the iteration protocall to fetch the next
property immediately after calling the Symbol.iterator function. This is, in theory,
a breaking change, so we will see if this breaks things (most likely it won't as this
is a relatively subtle point).

See: https://github.com/tc39/ecma262/issues/976

* builtins/IteratorHelpers.js:
(performIteration):
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitEnumeration):
(JSC::BytecodeGenerator::emitIteratorNext):
(JSC::BytecodeGenerator::emitIteratorNextWithValue):
(JSC::BytecodeGenerator::emitDelegateYield):
* bytecompiler/BytecodeGenerator.h:
* bytecompiler/NodesCodegen.cpp:
(JSC::ArrayPatternNode::bindValue const):
* inspector/JSInjectedScriptHost.cpp:
(Inspector::JSInjectedScriptHost::iteratorEntries):
* runtime/IteratorOperations.cpp:
(JSC::iteratorNext):
(JSC::iteratorStep):
(JSC::iteratorClose):
(JSC::iteratorForIterable):
* runtime/IteratorOperations.h:
(JSC::forEachInIterable):
* runtime/JSGenericTypedArrayViewConstructorInlines.h:
(JSC::constructGenericTypedArrayViewFromIterator):
(JSC::constructGenericTypedArrayViewWithArguments):

LayoutTests:

Change test to match the new iteration behavior.

* js/sequence-iterator-protocol-2-expected.txt:
* js/sequence-iterator-protocol-2.html:

Modified Paths

Diff

Modified: trunk/JSTests/ChangeLog (222420 => 222421)


--- trunk/JSTests/ChangeLog	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/JSTests/ChangeLog	2017-09-23 02:08:04 UTC (rev 222421)
@@ -1,3 +1,14 @@
+2017-09-22  Keith Miller  <[email protected]>
+
+        Speculatively change iteration protocall to use the same next function
+        https://bugs.webkit.org/show_bug.cgi?id=175653
+
+        Reviewed by Saam Barati.
+
+        Change test to match the new iteration behavior.
+
+        * stress/spread-optimized-properly.js:
+
 2017-09-22  Yusuke Suzuki  <[email protected]>
 
         [DFG][FTL] Profile array vector length for array allocation

Modified: trunk/JSTests/stress/spread-optimized-properly.js (222420 => 222421)


--- trunk/JSTests/stress/spread-optimized-properly.js	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/JSTests/stress/spread-optimized-properly.js	2017-09-23 02:08:04 UTC (rev 222421)
@@ -149,7 +149,7 @@
         assert(t.length === 3);
         assert(t[0] === 1);
         assert(t[1] === 2);
-        assert(t[2] === 4);
+        assert(t[2] === 3);
         iterProto.next = oldNext;
     }
 });

Modified: trunk/JSTests/test262.yaml (222420 => 222421)


--- trunk/JSTests/test262.yaml	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/JSTests/test262.yaml	2017-09-23 02:08:04 UTC (rev 222421)
@@ -63546,9 +63546,9 @@
 - path: test262/test/language/expressions/async-generator/named-yield-spread-obj.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/compareArray.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/expressions/async-generator/named-yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/expressions/async-generator/named-yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/expressions/async-generator/named-yield-star-async-return.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/expressions/async-generator/named-yield-star-async-return.js
@@ -63910,9 +63910,9 @@
 - path: test262/test/language/expressions/async-generator/yield-spread-obj.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/compareArray.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/expressions/async-generator/yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/expressions/async-generator/yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/expressions/async-generator/yield-star-async-return.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/expressions/async-generator/yield-star-async-return.js
@@ -65238,9 +65238,9 @@
 - path: test262/test/language/expressions/class/async-gen-method-static-yield-spread-obj.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/compareArray.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/expressions/class/async-gen-method-static-yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/expressions/class/async-gen-method-static-yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/expressions/class/async-gen-method-static-yield-star-async-return.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/expressions/class/async-gen-method-static-yield-star-async-return.js
@@ -65526,9 +65526,9 @@
 - path: test262/test/language/expressions/class/async-gen-method-yield-spread-obj.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/compareArray.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/expressions/class/async-gen-method-yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/expressions/class/async-gen-method-yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/expressions/class/async-gen-method-yield-star-async-return.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/expressions/class/async-gen-method-yield-star-async-return.js
@@ -79700,9 +79700,9 @@
 - path: test262/test/language/expressions/object/method-definition/async-gen-yield-spread-obj.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/compareArray.js", "../../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/expressions/object/method-definition/async-gen-yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/doneprintHandle.js"], [:async]
+  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/expressions/object/method-definition/async-gen-yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/doneprintHandle.js"], [:strict, :async]
+  cmd: runTest262 :fail, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/expressions/object/method-definition/async-gen-yield-star-async-return.js
   cmd: runTest262 :normal, "NoException", ["../../../../../harness/assert.js", "../../../../../harness/sta.js", "../../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/expressions/object/method-definition/async-gen-yield-star-async-return.js
@@ -87444,9 +87444,9 @@
 - path: test262/test/language/statements/async-generator/yield-spread-obj.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/compareArray.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/statements/async-generator/yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/statements/async-generator/yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/statements/async-generator/yield-star-async-return.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/statements/async-generator/yield-star-async-return.js
@@ -88208,9 +88208,9 @@
 - path: test262/test/language/statements/class/async-gen-method-static-yield-spread-obj.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/compareArray.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/statements/class/async-gen-method-static-yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/statements/class/async-gen-method-static-yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/statements/class/async-gen-method-static-yield-star-async-return.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/statements/class/async-gen-method-static-yield-star-async-return.js
@@ -88496,9 +88496,9 @@
 - path: test262/test/language/statements/class/async-gen-method-yield-spread-obj.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/compareArray.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/statements/class/async-gen-method-yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/statements/class/async-gen-method-yield-star-async-next.js
-  cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
+  cmd: runTest262 :fail, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:strict, :async]
 - path: test262/test/language/statements/class/async-gen-method-yield-star-async-return.js
   cmd: runTest262 :normal, "NoException", ["../../../../harness/assert.js", "../../../../harness/sta.js", "../../../../harness/doneprintHandle.js"], [:async]
 - path: test262/test/language/statements/class/async-gen-method-yield-star-async-return.js

Modified: trunk/LayoutTests/ChangeLog (222420 => 222421)


--- trunk/LayoutTests/ChangeLog	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/LayoutTests/ChangeLog	2017-09-23 02:08:04 UTC (rev 222421)
@@ -1,3 +1,15 @@
+2017-09-22  Keith Miller  <[email protected]>
+
+        Speculatively change iteration protocall to use the same next function
+        https://bugs.webkit.org/show_bug.cgi?id=175653
+
+        Reviewed by Saam Barati.
+
+        Change test to match the new iteration behavior.
+
+        * js/sequence-iterator-protocol-2-expected.txt:
+        * js/sequence-iterator-protocol-2.html:
+
 2017-09-22  Ryan Haddad  <[email protected]>
 
         WebRTC test gardening for iOS.

Modified: trunk/LayoutTests/js/sequence-iterator-protocol-2-expected.txt (222420 => 222421)


--- trunk/LayoutTests/js/sequence-iterator-protocol-2-expected.txt	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/LayoutTests/js/sequence-iterator-protocol-2-expected.txt	2017-09-23 02:08:04 UTC (rev 222421)
@@ -2,9 +2,9 @@
 CONSOLE MESSAGE: line 29: 1,2,3,1,2,3
 CONSOLE MESSAGE: line 33: 1,2,3,1,2,3
 CONSOLE MESSAGE: line 38: callCount: 3
-CONSOLE MESSAGE: line 66: 1,2,4,1,2,4
-CONSOLE MESSAGE: line 71: 1,2,4,1,2,4
-CONSOLE MESSAGE: line 75: callCount: 2
+CONSOLE MESSAGE: line 66: 1,2,3,1,2,3
+CONSOLE MESSAGE: line 71: 1,2,3,1,2,3
+CONSOLE MESSAGE: line 75: callCount: 0
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: trunk/LayoutTests/js/sequence-iterator-protocol-2.html (222420 => 222421)


--- trunk/LayoutTests/js/sequence-iterator-protocol-2.html	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/LayoutTests/js/sequence-iterator-protocol-2.html	2017-09-23 02:08:04 UTC (rev 222421)
@@ -66,7 +66,7 @@
             log(`${b}`);
 
             iterProto.next = oldNext;
-            ctx.setLineDash([1,2,4]);
+            ctx.setLineDash([1,2,3]);
             a = ctx.getLineDash();
             log(a);
             if (a.toString() !== b.toString())
@@ -73,8 +73,8 @@
                 throw new Error("Bad result. They should be equal.");
 
             log(`callCount: ${callCount}`);
-            if (callCount !== 2)
-                throw new Error("Bad result. callCount should be 2.");
+            if (callCount !== 0)
+                throw new Error("Bad result. callCount should be 0.");
 
         </script>
 

Modified: trunk/Source/_javascript_Core/ChangeLog (222420 => 222421)


--- trunk/Source/_javascript_Core/ChangeLog	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/Source/_javascript_Core/ChangeLog	2017-09-23 02:08:04 UTC (rev 222421)
@@ -1,3 +1,40 @@
+2017-09-22  Keith Miller  <[email protected]>
+
+        Speculatively change iteration protocall to use the same next function
+        https://bugs.webkit.org/show_bug.cgi?id=175653
+
+        Reviewed by Saam Barati.
+
+        This patch speculatively makes a change to the iteration protocall to fetch the next
+        property immediately after calling the Symbol.iterator function. This is, in theory,
+        a breaking change, so we will see if this breaks things (most likely it won't as this
+        is a relatively subtle point).
+
+        See: https://github.com/tc39/ecma262/issues/976
+
+        * builtins/IteratorHelpers.js:
+        (performIteration):
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitEnumeration):
+        (JSC::BytecodeGenerator::emitIteratorNext):
+        (JSC::BytecodeGenerator::emitIteratorNextWithValue):
+        (JSC::BytecodeGenerator::emitDelegateYield):
+        * bytecompiler/BytecodeGenerator.h:
+        * bytecompiler/NodesCodegen.cpp:
+        (JSC::ArrayPatternNode::bindValue const):
+        * inspector/JSInjectedScriptHost.cpp:
+        (Inspector::JSInjectedScriptHost::iteratorEntries):
+        * runtime/IteratorOperations.cpp:
+        (JSC::iteratorNext):
+        (JSC::iteratorStep):
+        (JSC::iteratorClose):
+        (JSC::iteratorForIterable):
+        * runtime/IteratorOperations.h:
+        (JSC::forEachInIterable):
+        * runtime/JSGenericTypedArrayViewConstructorInlines.h:
+        (JSC::constructGenericTypedArrayViewFromIterator):
+        (JSC::constructGenericTypedArrayViewWithArguments):
+
 2017-09-22  Fujii Hironori  <[email protected]>
 
         [Win64] Crashes in Yarr JIT compiled code

Modified: trunk/Source/_javascript_Core/builtins/IteratorHelpers.js (222420 => 222421)


--- trunk/Source/_javascript_Core/builtins/IteratorHelpers.js	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/Source/_javascript_Core/builtins/IteratorHelpers.js	2017-09-23 02:08:04 UTC (rev 222421)
@@ -33,10 +33,11 @@
     let result = [];
 
     let iterator = iterable.@iteratorSymbol();
+    let next = iterator.next;
     let item;
     let index = 0;
     while (true) {
-        item = iterator.next();
+        item = next.@call(iterator);
         if (!@isObject(item))
             @throwTypeError("Iterator result interface is not an object");
         if (item.done)

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (222420 => 222421)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2017-09-23 02:08:04 UTC (rev 222421)
@@ -4315,8 +4315,8 @@
 
     RefPtr<RegisterID> subject = newTemporary();
     emitNode(subject.get(), subjectNode);
-
     RefPtr<RegisterID> iterator = isForAwait ? emitGetAsyncIterator(subject.get(), node) : emitGetIterator(subject.get(), node);
+    RefPtr<RegisterID> nextMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().next);
 
     Ref<Label> loopDone = newLabel();
     Ref<Label> tryStartLabel = newLabel();
@@ -4422,7 +4422,7 @@
         }
 
         {
-            emitIteratorNext(value.get(), iterator.get(), node, isForAwait ? EmitAwait::Yes : EmitAwait::No);
+            emitIteratorNext(value.get(), nextMethod.get(), iterator.get(), node, isForAwait ? EmitAwait::Yes : EmitAwait::No);
 
             emitJumpIfTrue(emitGetById(newTemporary(), value.get(), propertyNames().done), loopDone.get());
             emitGetById(value.get(), value.get(), propertyNames().value);
@@ -4587,13 +4587,12 @@
     return dst;
 }
     
-RegisterID* BytecodeGenerator::emitIteratorNext(RegisterID* dst, RegisterID* iterator, const ThrowableExpressionData* node, EmitAwait doEmitAwait)
+RegisterID* BytecodeGenerator::emitIteratorNext(RegisterID* dst, RegisterID* nextMethod, RegisterID* iterator, const ThrowableExpressionData* node, EmitAwait doEmitAwait)
 {
     {
-        RefPtr<RegisterID> next = emitGetById(newTemporary(), iterator, propertyNames().next);
         CallArguments nextArguments(*this, nullptr);
         emitMove(nextArguments.thisRegister(), iterator);
-        emitCall(dst, next.get(), NoExpectedFunction, nextArguments, node->divot(), node->divotStart(), node->divotEnd(), DebuggableCall::No);
+        emitCall(dst, nextMethod, NoExpectedFunction, nextArguments, node->divot(), node->divotStart(), node->divotEnd(), DebuggableCall::No);
 
         if (doEmitAwait == EmitAwait::Yes)
             emitAwait(dst);
@@ -4607,14 +4606,13 @@
     return dst;
 }
 
-RegisterID* BytecodeGenerator::emitIteratorNextWithValue(RegisterID* dst, RegisterID* iterator, RegisterID* value, const ThrowableExpressionData* node)
+RegisterID* BytecodeGenerator::emitIteratorNextWithValue(RegisterID* dst, RegisterID* nextMethod, RegisterID* iterator, RegisterID* value, const ThrowableExpressionData* node)
 {
     {
-        RefPtr<RegisterID> next = emitGetById(newTemporary(), iterator, propertyNames().next);
         CallArguments nextArguments(*this, nullptr, 1);
         emitMove(nextArguments.thisRegister(), iterator);
         emitMove(nextArguments.argumentRegister(0), value);
-        emitCall(dst, next.get(), NoExpectedFunction, nextArguments, node->divot(), node->divotStart(), node->divotEnd(), DebuggableCall::No);
+        emitCall(dst, nextMethod, NoExpectedFunction, nextArguments, node->divot(), node->divotStart(), node->divotEnd(), DebuggableCall::No);
     }
 
     return dst;
@@ -4916,8 +4914,7 @@
     emitJump(asyncIteratorFound.get());
     emitLabel(asyncIteratorNotFound.get());
 
-    RefPtr<RegisterID> commonIterator = emitGetById(newTemporary(), argument, propertyNames().iteratorSymbol);
-    emitCallIterator(commonIterator.get(), argument, node);
+    RefPtr<RegisterID> commonIterator = emitGetIterator(argument, node);
     emitMove(iterator.get(), commonIterator.get());
 
     auto varCreateAsyncFromSyncIterator = variable(propertyNames().builtinNames().createAsyncFromSyncIteratorPrivateName());
@@ -4947,6 +4944,7 @@
     RefPtr<RegisterID> value = newTemporary();
     {
         RefPtr<RegisterID> iterator = parseMode() == SourceParseMode::AsyncGeneratorBodyMode ? emitGetAsyncIterator(argument, node) : emitGetIterator(argument, node);
+        RefPtr<RegisterID> nextMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().next);
 
         Ref<Label> loopDone = newLabel();
         {
@@ -5044,7 +5042,7 @@
             }
 
             emitLabel(nextElement.get());
-            emitIteratorNextWithValue(value.get(), iterator.get(), value.get(), node);
+            emitIteratorNextWithValue(value.get(), nextMethod.get(), iterator.get(), value.get(), node);
 
             emitLabel(branchOnResult.get());
 

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h (222420 => 222421)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.h	2017-09-23 02:08:04 UTC (rev 222421)
@@ -780,8 +780,8 @@
         RegisterID* emitIsDerivedArray(RegisterID* dst, RegisterID* src) { return emitIsCellWithType(dst, src, DerivedArrayType); }
         void emitRequireObjectCoercible(RegisterID* value, const String& error);
 
-        RegisterID* emitIteratorNext(RegisterID* dst, RegisterID* iterator, const ThrowableExpressionData* node, JSC::EmitAwait = JSC::EmitAwait::No);
-        RegisterID* emitIteratorNextWithValue(RegisterID* dst, RegisterID* iterator, RegisterID* value, const ThrowableExpressionData* node);
+        RegisterID* emitIteratorNext(RegisterID* dst, RegisterID* nextMethod, RegisterID* iterator, const ThrowableExpressionData* node, JSC::EmitAwait = JSC::EmitAwait::No);
+        RegisterID* emitIteratorNextWithValue(RegisterID* dst, RegisterID* nextMethod, RegisterID* iterator, RegisterID* value, const ThrowableExpressionData* node);
         void emitIteratorClose(RegisterID* iterator, const ThrowableExpressionData* node, EmitAwait = EmitAwait::No);
 
         RegisterID* emitRestParameter(RegisterID* result, unsigned numParametersToSkip);

Modified: trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp (222420 => 222421)


--- trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/Source/_javascript_Core/bytecompiler/NodesCodegen.cpp	2017-09-23 02:08:04 UTC (rev 222421)
@@ -3944,6 +3944,7 @@
         generator.emitMove(args.thisRegister(), rhs);
         generator.emitCall(iterator.get(), iterator.get(), NoExpectedFunction, args, divot(), divotStart(), divotEnd(), DebuggableCall::No);
     }
+    RefPtr<RegisterID> nextMethod = generator.emitGetById(generator.newTemporary(), iterator.get(), generator.propertyNames().next);
 
     if (m_targetPatterns.isEmpty()) {
         generator.emitIteratorClose(iterator.get(), this);
@@ -3962,7 +3963,7 @@
                 generator.emitJumpIfTrue(done.get(), iterationSkipped.get());
 
             RefPtr<RegisterID> value = generator.newTemporary();
-            generator.emitIteratorNext(value.get(), iterator.get(), this);
+            generator.emitIteratorNext(value.get(), nextMethod.get(), iterator.get(), this);
             generator.emitGetById(done.get(), value.get(), generator.propertyNames().done);
             generator.emitJumpIfTrue(done.get(), iterationSkipped.get());
             generator.emitGetById(value.get(), value.get(), generator.propertyNames().value);
@@ -3998,7 +3999,7 @@
             generator.emitLabel(loopStart.get());
 
             RefPtr<RegisterID> value = generator.newTemporary();
-            generator.emitIteratorNext(value.get(), iterator.get(), this);
+            generator.emitIteratorNext(value.get(), nextMethod.get(), iterator.get(), this);
             generator.emitGetById(done.get(), value.get(), generator.propertyNames().done);
             generator.emitJumpIfTrue(done.get(), iterationDone.get());
             generator.emitGetById(value.get(), value.get(), generator.propertyNames().value);

Modified: trunk/Source/_javascript_Core/inspector/JSInjectedScriptHost.cpp (222420 => 222421)


--- trunk/Source/_javascript_Core/inspector/JSInjectedScriptHost.cpp	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/Source/_javascript_Core/inspector/JSInjectedScriptHost.cpp	2017-09-23 02:08:04 UTC (rev 222421)
@@ -586,6 +586,8 @@
     if (!iterator)
         return jsUndefined();
 
+    IterationRecord iterationRecord = { iterator, iterator.get(exec, vm.propertyNames->next) };
+
     unsigned numberToFetch = 5;
     JSValue numberToFetchArg = exec->argument(1);
     double fetchDouble = numberToFetchArg.toInteger(exec);
@@ -597,7 +599,7 @@
     RETURN_IF_EXCEPTION(scope, { });
 
     for (unsigned i = 0; i < numberToFetch; ++i) {
-        JSValue next = iteratorStep(exec, iterator);
+        JSValue next = iteratorStep(exec, iterationRecord);
         if (UNLIKELY(scope.exception()) || next.isFalse())
             break;
 
@@ -609,7 +611,7 @@
         array->putDirectIndex(exec, i, entry);
         if (UNLIKELY(scope.exception())) {
             scope.release();
-            iteratorClose(exec, iterator);
+            iteratorClose(exec, iterationRecord);
             break;
         }
     }

Modified: trunk/Source/_javascript_Core/runtime/IteratorOperations.cpp (222420 => 222421)


--- trunk/Source/_javascript_Core/runtime/IteratorOperations.cpp	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/Source/_javascript_Core/runtime/IteratorOperations.cpp	2017-09-23 02:08:04 UTC (rev 222421)
@@ -36,13 +36,13 @@
 
 namespace JSC {
 
-JSValue iteratorNext(ExecState* exec, JSValue iterator, JSValue value)
+JSValue iteratorNext(ExecState* exec, IterationRecord iterationRecord, JSValue argument)
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    JSValue nextFunction = iterator.get(exec, vm.propertyNames->next);
-    RETURN_IF_EXCEPTION(scope, JSValue());
+    JSValue iterator = iterationRecord.iterator;
+    JSValue nextFunction = iterationRecord.nextMethod;
 
     CallData nextFunctionCallData;
     CallType nextFunctionCallType = getCallData(nextFunction, nextFunctionCallData);
@@ -50,8 +50,8 @@
         return throwTypeError(exec, scope);
 
     MarkedArgumentBuffer nextFunctionArguments;
-    if (!value.isEmpty())
-        nextFunctionArguments.append(value);
+    if (!argument.isEmpty())
+        nextFunctionArguments.append(argument);
     JSValue result = call(exec, nextFunction, nextFunctionCallType, nextFunctionCallData, iterator, nextFunctionArguments);
     RETURN_IF_EXCEPTION(scope, JSValue());
 
@@ -61,11 +61,6 @@
     return result;
 }
 
-JSValue iteratorNext(ExecState* exec, JSValue iterator)
-{
-    return iteratorNext(exec, iterator, JSValue());
-}
-
 JSValue iteratorValue(ExecState* exec, JSValue iterResult)
 {
     return iterResult.get(exec, exec->vm().propertyNames->value);
@@ -77,12 +72,12 @@
     return done.toBoolean(exec);
 }
 
-JSValue iteratorStep(ExecState* exec, JSValue iterator)
+JSValue iteratorStep(ExecState* exec, IterationRecord iterationRecord)
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    JSValue result = iteratorNext(exec, iterator);
+    JSValue result = iteratorNext(exec, iterationRecord);
     RETURN_IF_EXCEPTION(scope, JSValue());
     bool done = iteratorComplete(exec, result);
     RETURN_IF_EXCEPTION(scope, JSValue());
@@ -91,7 +86,7 @@
     return result;
 }
 
-void iteratorClose(ExecState* exec, JSValue iterator)
+void iteratorClose(ExecState* exec, IterationRecord iterationRecord)
 {
     VM& vm = exec->vm();
     auto throwScope = DECLARE_THROW_SCOPE(vm);
@@ -102,7 +97,7 @@
         exception = catchScope.exception();
         catchScope.clearException();
     }
-    JSValue returnFunction = iterator.get(exec, vm.propertyNames->returnKeyword);
+    JSValue returnFunction = iterationRecord.iterator.get(exec, vm.propertyNames->returnKeyword);
     RETURN_IF_EXCEPTION(throwScope, void());
 
     if (returnFunction.isUndefined()) {
@@ -122,7 +117,7 @@
     }
 
     MarkedArgumentBuffer returnFunctionArguments;
-    JSValue innerResult = call(exec, returnFunction, returnFunctionCallType, returnFunctionCallData, iterator, returnFunctionArguments);
+    JSValue innerResult = call(exec, returnFunction, returnFunctionCallType, returnFunctionCallData, iterationRecord.iterator, returnFunctionArguments);
 
     if (exception) {
         throwException(exec, throwScope, exception);
@@ -190,7 +185,7 @@
     return method;
 }
 
-JSValue iteratorForIterable(ExecState& state, JSObject* object, JSValue iteratorMethod)
+IterationRecord iteratorForIterable(ExecState& state, JSObject* object, JSValue iteratorMethod)
 {
     VM& vm = state.vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
@@ -211,34 +206,40 @@
         return { };
     }
 
-    return iterator;
+    JSValue nextMethod = iterator.getObject()->get(&state, vm.propertyNames->next);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    return { iterator, nextMethod };
 }
 
-JSValue iteratorForIterable(ExecState* state, JSValue iterable)
+IterationRecord iteratorForIterable(ExecState* state, JSValue iterable)
 {
     VM& vm = state->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
     
     JSValue iteratorFunction = iterable.get(state, vm.propertyNames->iteratorSymbol);
-    RETURN_IF_EXCEPTION(scope, JSValue());
+    RETURN_IF_EXCEPTION(scope, { });
     
     CallData iteratorFunctionCallData;
     CallType iteratorFunctionCallType = getCallData(iteratorFunction, iteratorFunctionCallData);
     if (iteratorFunctionCallType == CallType::None) {
         throwTypeError(state, scope);
-        return JSValue();
+        return { };
     }
 
     ArgList iteratorFunctionArguments;
     JSValue iterator = call(state, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
-    RETURN_IF_EXCEPTION(scope, JSValue());
+    RETURN_IF_EXCEPTION(scope, { });
 
     if (!iterator.isObject()) {
         throwTypeError(state, scope);
-        return JSValue();
+        return { };
     }
 
-    return iterator;
+    JSValue nextMethod = iterator.getObject()->get(state, vm.propertyNames->next);
+    RETURN_IF_EXCEPTION(scope, { });
+
+    return { iterator, nextMethod };
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/runtime/IteratorOperations.h (222420 => 222421)


--- trunk/Source/_javascript_Core/runtime/IteratorOperations.h	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/Source/_javascript_Core/runtime/IteratorOperations.h	2017-09-23 02:08:04 UTC (rev 222421)
@@ -32,24 +32,27 @@
 
 namespace JSC {
 
-JSValue iteratorNext(ExecState*, JSValue iterator, JSValue);
-JSValue iteratorNext(ExecState*, JSValue iterator);
-JS_EXPORT_PRIVATE JSValue iteratorValue(ExecState*, JSValue iterator);
-bool iteratorComplete(ExecState*, JSValue iterator);
-JS_EXPORT_PRIVATE JSValue iteratorStep(ExecState*, JSValue iterator);
-JS_EXPORT_PRIVATE void iteratorClose(ExecState*, JSValue iterator);
+struct IterationRecord {
+    JSValue iterator;
+    JSValue nextMethod;
+};
+
+JSValue iteratorNext(ExecState*, IterationRecord, JSValue argument = JSValue());
+JS_EXPORT_PRIVATE JSValue iteratorValue(ExecState*, JSValue iterResult);
+bool iteratorComplete(ExecState*, JSValue iterResult);
+JS_EXPORT_PRIVATE JSValue iteratorStep(ExecState*, IterationRecord);
+JS_EXPORT_PRIVATE void iteratorClose(ExecState*, IterationRecord);
 JS_EXPORT_PRIVATE JSObject* createIteratorResultObject(ExecState*, JSValue, bool done);
 
 Structure* createIteratorResultObjectStructure(VM&, JSGlobalObject&);
 
 JS_EXPORT_PRIVATE JSValue iteratorMethod(ExecState&, JSObject*);
-JS_EXPORT_PRIVATE JSValue iteratorForIterable(ExecState&, JSObject*, JSValue iteratorMethod);
+JS_EXPORT_PRIVATE IterationRecord iteratorForIterable(ExecState&, JSObject*, JSValue iteratorMethod);
+JS_EXPORT_PRIVATE IterationRecord iteratorForIterable(ExecState*, JSValue iterable);
 
 JS_EXPORT_PRIVATE JSValue iteratorMethod(ExecState&, JSObject*);
 JS_EXPORT_PRIVATE bool hasIteratorMethod(ExecState&, JSValue);
 
-JS_EXPORT_PRIVATE JSValue iteratorForIterable(ExecState*, JSValue iterable);
-
 template<typename CallBackType>
 void forEachInIterable(ExecState* exec, JSValue iterable, const CallBackType& callback)
 {
@@ -56,10 +59,10 @@
     auto& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    JSValue iterator = iteratorForIterable(exec, iterable);
+    IterationRecord iterationRecord = iteratorForIterable(exec, iterable);
     RETURN_IF_EXCEPTION(scope, void());
     while (true) {
-        JSValue next = iteratorStep(exec, iterator);
+        JSValue next = iteratorStep(exec, iterationRecord);
         if (UNLIKELY(scope.exception()) || next.isFalse())
             return;
 
@@ -69,7 +72,7 @@
         callback(vm, exec, nextValue);
         if (UNLIKELY(scope.exception())) {
             scope.release();
-            iteratorClose(exec, iterator);
+            iteratorClose(exec, iterationRecord);
             return;
         }
     }
@@ -81,10 +84,10 @@
     auto& vm = state.vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    auto iterator = iteratorForIterable(state, iterable, iteratorMethod);
+    auto iterationRecord = iteratorForIterable(state, iterable, iteratorMethod);
     RETURN_IF_EXCEPTION(scope, void());
     while (true) {
-        JSValue next = iteratorStep(&state, iterator);
+        JSValue next = iteratorStep(&state, iterationRecord);
         if (UNLIKELY(scope.exception()) || next.isFalse())
             return;
 
@@ -94,7 +97,7 @@
         callback(vm, state, nextValue);
         if (UNLIKELY(scope.exception())) {
             scope.release();
-            iteratorClose(&state, iterator);
+            iteratorClose(&state, iterationRecord);
             return;
         }
     }

Modified: trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewConstructorInlines.h (222420 => 222421)


--- trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewConstructorInlines.h	2017-09-23 00:55:23 UTC (rev 222420)
+++ trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewConstructorInlines.h	2017-09-23 02:08:04 UTC (rev 222421)
@@ -77,28 +77,17 @@
 }
 
 template<typename ViewClass>
-inline JSObject* constructGenericTypedArrayViewFromIterator(ExecState* exec, Structure* structure, JSValue iterator)
+inline JSObject* constructGenericTypedArrayViewFromIterator(ExecState* exec, Structure* structure, JSObject* iterable, JSValue iteratorMethod)
 {
     VM& vm = exec->vm();
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    if (!iterator.isObject())
-        return throwTypeError(exec, scope, ASCIILiteral("Symbol.Iterator for the first argument did not return an object."));
-
     MarkedArgumentBuffer storage;
-    while (true) {
-        JSValue next = iteratorStep(exec, iterator);
-        RETURN_IF_EXCEPTION(scope, nullptr);
+    forEachInIterable(*exec, iterable, iteratorMethod, [&] (VM&, ExecState&, JSValue value) {
+        storage.append(value);
+    });
+    RETURN_IF_EXCEPTION(scope, nullptr);
 
-        if (next.isFalse())
-            break;
-
-        JSValue nextItem = iteratorValue(exec, next);
-        RETURN_IF_EXCEPTION(scope, nullptr);
-
-        storage.append(nextItem);
-    }
-
     ViewClass* result = ViewClass::createUninitialized(exec, structure, storage.size());
     EXCEPTION_ASSERT(!!scope.exception() == !result);
     if (UNLIKELY(!result))
@@ -172,17 +161,7 @@
                     || lengthSlot.isAccessor() || lengthSlot.isCustom() || lengthSlot.isTaintedByOpaqueObject()
                     || hasAnyArrayStorage(object->indexingType()))) {
 
-                    CallData callData;
-                    CallType callType = getCallData(iteratorFunc, callData);
-                    if (callType == CallType::None)
-                        return throwTypeError(exec, scope, ASCIILiteral("Symbol.Iterator for the first argument cannot be called."));
-
-                    ArgList arguments;
-                    JSValue iterator = call(exec, iteratorFunc, callType, callData, object, arguments);
-                    RETURN_IF_EXCEPTION(scope, nullptr);
-
-                    scope.release();
-                    return constructGenericTypedArrayViewFromIterator<ViewClass>(exec, structure, iterator);
+                    return constructGenericTypedArrayViewFromIterator<ViewClass>(exec, structure, object, iteratorFunc);
             }
 
             if (lengthSlot.isUnset())
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to