Title: [262567] trunk
Revision
262567
Author
[email protected]
Date
2020-06-04 13:49:22 -0700 (Thu, 04 Jun 2020)

Log Message

GetMethod isn't performed properly on iterators
https://bugs.webkit.org/show_bug.cgi?id=212771

Reviewed by Saam Barati.

JSTests:

* test262/expectations.yaml: Mark 26 test cases as passing.

Source/_javascript_Core:

Before this change, iterator's "return" and "throw" methods with value of `null` were
considered incorrect rather than missing, causing TypeError to be thrown.

This patch aligns method lookup of iterators with the spec [1], V8, and SpiderMonkey
by utilizing isUndefinedOrNull(), which doesn't special-case [[IsHTMLDDA]] objects [2],
fixing a few Annex B tests.

for/of microbenchmarks are neutral.

[1]: https://tc39.es/ecma262/#sec-getmethod (step 3)
[2]: https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot

* builtins/AsyncFromSyncIteratorPrototype.js:
* bytecompiler/BytecodeGenerator.cpp:
(JSC::BytecodeGenerator::emitIteratorGenericClose):
(JSC::BytecodeGenerator::emitGetAsyncIterator):
(JSC::BytecodeGenerator::emitDelegateYield):
* runtime/IteratorOperations.cpp:
(JSC::iteratorClose):
* runtime/JSGenericTypedArrayViewConstructorInlines.h:
(JSC::constructGenericTypedArrayViewWithArguments):

Modified Paths

Diff

Modified: trunk/JSTests/ChangeLog (262566 => 262567)


--- trunk/JSTests/ChangeLog	2020-06-04 20:38:29 UTC (rev 262566)
+++ trunk/JSTests/ChangeLog	2020-06-04 20:49:22 UTC (rev 262567)
@@ -1,5 +1,14 @@
 2020-06-04  Alexey Shvayka  <[email protected]>
 
+        GetMethod isn't performed properly on iterators
+        https://bugs.webkit.org/show_bug.cgi?id=212771
+
+        Reviewed by Saam Barati.
+
+        * test262/expectations.yaml: Mark 26 test cases as passing.
+
+2020-06-04  Alexey Shvayka  <[email protected]>
+
         Update test262 to commit 290ceba31fea
         https://bugs.webkit.org/show_bug.cgi?id=212752
 

Modified: trunk/JSTests/test262/expectations.yaml (262566 => 262567)


--- trunk/JSTests/test262/expectations.yaml	2020-06-04 20:38:29 UTC (rev 262566)
+++ trunk/JSTests/test262/expectations.yaml	2020-06-04 20:49:22 UTC (rev 262567)
@@ -304,12 +304,6 @@
 test/annexB/language/expressions/assignment/dstr/object-pattern-emulates-undefined.js:
   default: 'Test262Error: Expected SameValue(«undefined», «[object Function]») to be true'
   strict mode: 'Test262Error: Expected SameValue(«undefined», «[object Function]») to be true'
-test/annexB/language/expressions/yield/star-iterable-return-emulates-undefined-throws-when-called.js:
-  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
-  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
-test/annexB/language/expressions/yield/star-iterable-throw-emulates-undefined-throws-when-called.js:
-  default: 'Test262Error: Expected SameValue(«1», «0») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«1», «0») to be true'
 test/annexB/language/function-code/block-decl-func-skip-arguments.js:
   default: 'Test262Error: Expected SameValue(«function arguments() {}», «[object Arguments]») to be true'
 test/annexB/language/function-code/block-decl-func-skip-early-err-block.js:
@@ -624,12 +618,6 @@
 test/annexB/language/statements/const/dstr/object-pattern-emulates-undefined.js:
   default: 'Test262Error: Expected SameValue(«undefined», «[object Function]») to be true'
   strict mode: 'Test262Error: Expected SameValue(«undefined», «[object Function]») to be true'
-test/annexB/language/statements/for-await-of/iterator-close-return-emulates-undefined-throws-when-called.js:
-  default: "Test262:AsyncTestFailure:Test262Error: Test262Error: expected TypeError because `iter[Symbol.asyncIterator]() returned a non-object: Test262Error: shouldn't touch Symbol.iterator Expected SameValue(«function Test262Error(message) {"
-  strict mode: "Test262:AsyncTestFailure:Test262Error: Test262Error: expected TypeError because `iter[Symbol.asyncIterator]() returned a non-object: Test262Error: shouldn't touch Symbol.iterator Expected SameValue(«function Test262Error(message) {"
-test/annexB/language/statements/for-of/iterator-close-return-emulates-undefined-throws-when-called.js:
-  default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
-  strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all'
 test/annexB/language/statements/function/default-parameters-emulates-undefined.js:
   default: 'Test262Error: Expected SameValue(«undefined», «[object Function]») to be true'
   strict mode: 'Test262Error: Expected SameValue(«undefined», «[object Function]») to be true'
@@ -663,12 +651,6 @@
 test/built-ins/ArrayIteratorPrototype/next/detach-typedarray-in-progress.js:
   default: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
   strict mode: 'Test262Error: Expected a TypeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
-test/built-ins/AsyncFromSyncIteratorPrototype/return/return-null.js:
-  default: 'Test262:AsyncTestFailure:TypeError: null is not a function'
-  strict mode: 'Test262:AsyncTestFailure:TypeError: null is not a function'
-test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-null.js:
-  default: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected SameValue(«TypeError: null is not a function», «[object Object]») to be true'
-  strict mode: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected SameValue(«TypeError: null is not a function», «[object Object]») to be true'
 test/built-ins/AsyncGeneratorPrototype/return/return-suspendedYield-promise.js:
   default: 'Test262:AsyncTestFailure:Test262Error: Test262Error: AsyncGeneratorResolve(generator, resultValue, true) Expected SameValue(«[object Promise]», «unwrapped-value») to be true'
   strict mode: 'Test262:AsyncTestFailure:Test262Error: Test262Error: AsyncGeneratorResolve(generator, resultValue, true) Expected SameValue(«[object Promise]», «unwrapped-value») to be true'
@@ -1545,9 +1527,6 @@
 test/built-ins/TypedArrayConstructors/ctors/buffer-arg/length-to-number-detachbuffer.js:
   default: 'Test262Error: Expected a TypeError but got a RangeError (Testing with Float64Array.)'
   strict mode: 'Test262Error: Expected a TypeError but got a RangeError (Testing with Float64Array.)'
-test/built-ins/TypedArrayConstructors/ctors/object-arg/iterator-is-null-as-array-like.js:
-  default: 'TypeError: Type error (Testing with Float64Array.)'
-  strict mode: 'TypeError: Type error (Testing with Float64Array.)'
 test/built-ins/TypedArrayConstructors/ctors/object-arg/length-excessive-throws.js:
   default: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
   strict mode: 'Test262Error: Expected a RangeError to be thrown but no exception was thrown at all (Testing with Float64Array.)'
@@ -2141,12 +2120,6 @@
   strict mode: 'Test262Error: Expected SameValue(«[object AsyncGenerator]», «[object AsyncGenerator]») to be false'
 test/language/expressions/async-generator/named-eval-var-scope-syntax-err.js:
   default: 'Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all'
-test/language/expressions/async-generator/yield-star-getiter-async-return-method-is-null.js:
-  default: "Test262:AsyncTestFailure:TypeError: null is not a function (near '...yield* asyncIterable...')"
-  strict mode: "Test262:AsyncTestFailure:TypeError: null is not a function (near '...yield* asyncIterable...')"
-test/language/expressions/async-generator/yield-star-getiter-async-throw-method-is-null.js:
-  default: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected SameValue(«0», «1») to be true'
-  strict mode: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected SameValue(«0», «1») to be true'
 test/language/expressions/await/async-await-interleaved.js:
   default: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected [Await: 1, Promise: 1, Promise: 2, Await: 2] and [Await: 1, Promise: 1, Await: 2, Promise: 2] to have the same contents. Async/await and promises should be interleaved'
   strict mode: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected [Await: 1, Promise: 1, Promise: 2, Await: 2] and [Await: 1, Promise: 1, Await: 2, Promise: 2] to have the same contents. Async/await and promises should be interleaved'
@@ -3032,9 +3005,6 @@
 test/language/expressions/yield/star-iterable.js:
   default: 'Test262Error: First result `done` flag Expected SameValue(«false», «undefined») to be true'
   strict mode: 'Test262Error: First result `done` flag Expected SameValue(«false», «undefined») to be true'
-test/language/expressions/yield/star-return-is-null.js:
-  default: "TypeError: null is not a function (near '...yield* iterable...')"
-  strict mode: "TypeError: null is not a function (near '...yield* iterable...')"
 test/language/expressions/yield/star-rhs-iter-nrml-res-done-no-value.js:
   default: 'Test262Error: access count (first iteration) Expected SameValue(«1», «0») to be true'
   strict mode: 'Test262Error: access count (first iteration) Expected SameValue(«1», «0») to be true'
@@ -3044,9 +3014,6 @@
 test/language/expressions/yield/star-rhs-iter-thrw-res-done-no-value.js:
   default: 'Test262Error: access count (second iteration) Expected SameValue(«1», «0») to be true'
   strict mode: 'Test262Error: access count (second iteration) Expected SameValue(«1», «0») to be true'
-test/language/expressions/yield/star-throw-is-null.js:
-  default: 'Test262Error: Expected SameValue(«0», «1») to be true'
-  strict mode: 'Test262Error: Expected SameValue(«0», «1») to be true'
 test/language/global-code/script-decl-func-err-non-configurable.js:
   default: 'Test262Error: writable, non-enumerable data property Expected a TypeError to be thrown but no exception was thrown at all'
   strict mode: 'Test262Error: writable, non-enumerable data property Expected a TypeError to be thrown but no exception was thrown at all'
@@ -3279,9 +3246,6 @@
   strict mode: 'Test262: This statement should not be evaluated.'
 test/language/statements/for-await-of/async-func-decl-dstr-array-elem-target-simple-strict.js:
   strict mode: 'Test262: This statement should not be evaluated.'
-test/language/statements/for-await-of/iterator-close-non-throw-get-method-is-null.js:
-  default: "Test262:AsyncTestFailure:TypeError: null is not a function (near '..._ of iterable...')"
-  strict mode: "Test262:AsyncTestFailure:TypeError: null is not a function (near '..._ of iterable...')"
 test/language/statements/for-await-of/let-array-with-newline.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/for-await-of/ticks-with-async-iter-resolved-promise-and-constructor-lookup-two.js:
@@ -3496,9 +3460,6 @@
 test/language/statements/for-of/head-var-no-expr.js:
   default: 'Test262: This statement should not be evaluated.'
   strict mode: 'Test262: This statement should not be evaluated.'
-test/language/statements/for-of/iterator-close-non-throw-get-method-is-null.js:
-  default: "TypeError: null is not a function (near '..._ of iterable...')"
-  strict mode: "TypeError: null is not a function (near '..._ of iterable...')"
 test/language/statements/for-of/let-array-with-newline.js:
   default: 'Test262: This statement should not be evaluated.'
 test/language/statements/for/head-lhs-let.js:

Modified: trunk/Source/_javascript_Core/ChangeLog (262566 => 262567)


--- trunk/Source/_javascript_Core/ChangeLog	2020-06-04 20:38:29 UTC (rev 262566)
+++ trunk/Source/_javascript_Core/ChangeLog	2020-06-04 20:49:22 UTC (rev 262567)
@@ -1,3 +1,32 @@
+2020-06-04  Alexey Shvayka  <[email protected]>
+
+        GetMethod isn't performed properly on iterators
+        https://bugs.webkit.org/show_bug.cgi?id=212771
+
+        Reviewed by Saam Barati.
+
+        Before this change, iterator's "return" and "throw" methods with value of `null` were
+        considered incorrect rather than missing, causing TypeError to be thrown.
+
+        This patch aligns method lookup of iterators with the spec [1], V8, and SpiderMonkey
+        by utilizing isUndefinedOrNull(), which doesn't special-case [[IsHTMLDDA]] objects [2],
+        fixing a few Annex B tests.
+
+        for/of microbenchmarks are neutral.
+
+        [1]: https://tc39.es/ecma262/#sec-getmethod (step 3)
+        [2]: https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot
+
+        * builtins/AsyncFromSyncIteratorPrototype.js:
+        * bytecompiler/BytecodeGenerator.cpp:
+        (JSC::BytecodeGenerator::emitIteratorGenericClose):
+        (JSC::BytecodeGenerator::emitGetAsyncIterator):
+        (JSC::BytecodeGenerator::emitDelegateYield):
+        * runtime/IteratorOperations.cpp:
+        (JSC::iteratorClose):
+        * runtime/JSGenericTypedArrayViewConstructorInlines.h:
+        (JSC::constructGenericTypedArrayViewWithArguments):
+
 2020-06-04  Mark Lam  <[email protected]>
 
         Reduce DFGDoesGCCheck to only storing a uint32_t.

Modified: trunk/Source/_javascript_Core/builtins/AsyncFromSyncIteratorPrototype.js (262566 => 262567)


--- trunk/Source/_javascript_Core/builtins/AsyncFromSyncIteratorPrototype.js	2020-06-04 20:38:29 UTC (rev 262566)
+++ trunk/Source/_javascript_Core/builtins/AsyncFromSyncIteratorPrototype.js	2020-06-04 20:49:22 UTC (rev 262567)
@@ -74,7 +74,7 @@
         return promise;
     }
 
-    if (returnMethod === @undefined) {
+    if (@isUndefinedOrNull(returnMethod)) {
         @resolvePromiseWithFirstResolvingFunctionCallCheck(promise, { value, done: true });
         return promise;
     }
@@ -121,7 +121,7 @@
         return promise;
     }
 
-    if (throwMethod === @undefined) {
+    if (@isUndefinedOrNull(throwMethod)) {
         @rejectPromiseWithFirstResolvingFunctionCallCheck(promise, exception);
         return promise;
     }

Modified: trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp (262566 => 262567)


--- trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2020-06-04 20:38:29 UTC (rev 262566)
+++ trunk/Source/_javascript_Core/bytecompiler/BytecodeGenerator.cpp	2020-06-04 20:49:22 UTC (rev 262567)
@@ -4723,7 +4723,7 @@
 {
     Ref<Label> done = newLabel();
     RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator, propertyNames().returnKeyword);
-    emitJumpIfTrue(emitIsUndefined(newTemporary(), returnMethod.get()), done.get());
+    emitJumpIfTrue(emitIsUndefinedOrNull(newTemporary(), returnMethod.get()), done.get());
 
     RefPtr<RegisterID> value = newTemporary();
     CallArguments returnArguments(*this, nullptr);
@@ -4746,7 +4746,7 @@
     Ref<Label> asyncIteratorFound = newLabel();
     Ref<Label> iteratorReceived = newLabel();
 
-    emitJumpIfTrue(emitUnaryOp<OpEqNull>(newTemporary(), iterator.get()), asyncIteratorNotFound.get());
+    emitJumpIfTrue(emitIsUndefinedOrNull(newTemporary(), iterator.get()), asyncIteratorNotFound.get());
 
     emitJump(asyncIteratorFound.get());
     emitLabel(asyncIteratorNotFound.get());
@@ -4815,7 +4815,7 @@
                 {
                     Ref<Label> throwMethodFound = newLabel();
                     RefPtr<RegisterID> throwMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().throwKeyword);
-                    emitJumpIfFalse(emitIsUndefined(newTemporary(), throwMethod.get()), throwMethodFound.get());
+                    emitJumpIfFalse(emitIsUndefinedOrNull(newTemporary(), throwMethod.get()), throwMethodFound.get());
 
                     EmitAwait emitAwaitInIteratorClose = parseMode() == SourceParseMode::AsyncGeneratorBodyMode ? EmitAwait::Yes : EmitAwait::No;
                     emitIteratorGenericClose(iterator.get(), node, emitAwaitInIteratorClose);
@@ -4836,7 +4836,7 @@
                 {
                     Ref<Label> returnMethodFound = newLabel();
                     RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().returnKeyword);
-                    emitJumpIfFalse(emitIsUndefined(newTemporary(), returnMethod.get()), returnMethodFound.get());
+                    emitJumpIfFalse(emitIsUndefinedOrNull(newTemporary(), returnMethod.get()), returnMethodFound.get());
 
                     move(value.get(), generatorValueRegister());
 

Modified: trunk/Source/_javascript_Core/runtime/IteratorOperations.cpp (262566 => 262567)


--- trunk/Source/_javascript_Core/runtime/IteratorOperations.cpp	2020-06-04 20:38:29 UTC (rev 262566)
+++ trunk/Source/_javascript_Core/runtime/IteratorOperations.cpp	2020-06-04 20:49:22 UTC (rev 262567)
@@ -95,7 +95,7 @@
     }
 
     JSValue returnFunction = iterationRecord.iterator.get(globalObject, vm.propertyNames->returnKeyword);
-    if (UNLIKELY(throwScope.exception()) || returnFunction.isUndefined()) {
+    if (UNLIKELY(throwScope.exception()) || returnFunction.isUndefinedOrNull()) {
         if (exception)
             throwException(globalObject, throwScope, exception);
         return;

Modified: trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewConstructorInlines.h (262566 => 262567)


--- trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewConstructorInlines.h	2020-06-04 20:38:29 UTC (rev 262566)
+++ trunk/Source/_javascript_Core/runtime/JSGenericTypedArrayViewConstructorInlines.h	2020-06-04 20:49:22 UTC (rev 262567)
@@ -169,7 +169,7 @@
             // 3) The base object might have indexed getters.
             // it should not be observable that we do not use the iterator.
 
-            if (!iteratorFunc.isUndefined()
+            if (!iteratorFunc.isUndefinedOrNull()
                 && (iteratorFunc != object->globalObject(vm)->arrayProtoValuesFunction()
                     || lengthSlot.isAccessor() || lengthSlot.isCustom() || lengthSlot.isTaintedByOpaqueObject()
                     || hasAnyArrayStorage(object->indexingType()))) {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to