Ignore:
Timestamp:
Jun 4, 2020, 1:49:22 PM (5 years ago)
Author:
Alexey Shvayka
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/JavaScriptCore:

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):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r262354 r262567  
    47244724    Ref<Label> done = newLabel();
    47254725    RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator, propertyNames().returnKeyword);
    4726     emitJumpIfTrue(emitIsUndefined(newTemporary(), returnMethod.get()), done.get());
     4726    emitJumpIfTrue(emitIsUndefinedOrNull(newTemporary(), returnMethod.get()), done.get());
    47274727
    47284728    RefPtr<RegisterID> value = newTemporary();
     
    47474747    Ref<Label> iteratorReceived = newLabel();
    47484748
    4749     emitJumpIfTrue(emitUnaryOp<OpEqNull>(newTemporary(), iterator.get()), asyncIteratorNotFound.get());
     4749    emitJumpIfTrue(emitIsUndefinedOrNull(newTemporary(), iterator.get()), asyncIteratorNotFound.get());
    47504750
    47514751    emitJump(asyncIteratorFound.get());
     
    48164816                    Ref<Label> throwMethodFound = newLabel();
    48174817                    RefPtr<RegisterID> throwMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().throwKeyword);
    4818                     emitJumpIfFalse(emitIsUndefined(newTemporary(), throwMethod.get()), throwMethodFound.get());
     4818                    emitJumpIfFalse(emitIsUndefinedOrNull(newTemporary(), throwMethod.get()), throwMethodFound.get());
    48194819
    48204820                    EmitAwait emitAwaitInIteratorClose = parseMode() == SourceParseMode::AsyncGeneratorBodyMode ? EmitAwait::Yes : EmitAwait::No;
     
    48374837                    Ref<Label> returnMethodFound = newLabel();
    48384838                    RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().returnKeyword);
    4839                     emitJumpIfFalse(emitIsUndefined(newTemporary(), returnMethod.get()), returnMethodFound.get());
     4839                    emitJumpIfFalse(emitIsUndefinedOrNull(newTemporary(), returnMethod.get()), returnMethodFound.get());
    48404840
    48414841                    move(value.get(), generatorValueRegister());
Note: See TracChangeset for help on using the changeset viewer.