Changeset 262165 in webkit


Ignore:
Timestamp:
May 26, 2020 3:16:10 PM (4 years ago)
Author:
Alexey Shvayka
Message:

IteratorClose should suppress GetMethod errors
https://bugs.webkit.org/show_bug.cgi?id=212378

Reviewed by Keith Miller.

JSTests:

  • stress/custom-iterators.js:
  • stress/iterator-return-abrupt-lookup-builtins.js: Added.
  • test262/expectations.yaml: Mark 4 test cases as passing.

Source/JavaScriptCore:

This patch implements recent spec change [1] that prevents "return" method lookup error
from overriding outer exception, aligning JSC with V8 and SpiderMonkey.

It is accomplished by moving pushTry() before emitGetById() in BytecodeGenerator.cpp
(covered by test262 suite) and removal of RETURN_IF_EXCEPTION in IteratorOperations.cpp
(added a stress test).

Before this patch, JSC partly implemented the spec change [1] by suppressing TypeError
if "return" method of iterator was not callable.

BytecodeGenerator::emitDelegateYield() is intentionally left unchanged.
Also, this patch utilizes emitIteratorGenericClose() to avoid code duplication.
for/of microbenchmarks are neutral.

[1]: https://github.com/tc39/ecma262/pull/1408

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitGenericEnumeration):
(JSC::BytecodeGenerator::emitEnumeration):

  • runtime/IteratorOperations.cpp:

(JSC::iteratorClose):

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r262100 r262165  
     12020-05-26  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        IteratorClose should suppress GetMethod errors
     4        https://bugs.webkit.org/show_bug.cgi?id=212378
     5
     6        Reviewed by Keith Miller.
     7
     8        * stress/custom-iterators.js:
     9        * stress/iterator-return-abrupt-lookup-builtins.js: Added.
     10        * test262/expectations.yaml: Mark 4 test cases as passing.
     11
    1122020-05-23  Caio Lima  <ticaiolima@gmail.com>
    213
  • trunk/JSTests/stress/custom-iterators.js

    r260323 r262165  
    136136    }
    137137} catch (e) {
    138     if (String(e) !== "Error: looking up return.")
     138    if (String(e) !== "Error: Terminate iteration.")
    139139        throw e;
    140140}
  • trunk/JSTests/test262/expectations.yaml

    r262088 r262165  
    32593259test/language/statements/for-await-of/async-func-decl-dstr-array-elem-target-simple-strict.js:
    32603260  strict mode: 'Test262: This statement should not be evaluated.'
    3261 test/language/statements/for-await-of/iterator-close-throw-get-method-abrupt.js:
    3262   default: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected SameValue(«function Object() {'
    3263   strict mode: 'Test262:AsyncTestFailure:Test262Error: Test262Error: Expected SameValue(«function Object() {'
    32643261test/language/statements/for-await-of/let-array-with-newline.js:
    32653262  default: 'Test262: This statement should not be evaluated.'
     
    34763473  default: 'Test262: This statement should not be evaluated.'
    34773474  strict mode: 'Test262: This statement should not be evaluated.'
    3478 test/language/statements/for-of/iterator-close-throw-get-method-abrupt.js:
    3479   default: 'Test262Error: Expected a Test262Error but got a Object'
    3480   strict mode: 'Test262Error: Expected a Test262Error but got a Object'
    34813475test/language/statements/for-of/let-array-with-newline.js:
    34823476  default: 'Test262: This statement should not be evaluated.'
  • trunk/Source/JavaScriptCore/ChangeLog

    r262161 r262165  
     12020-05-26  Alexey Shvayka  <shvaikalesh@gmail.com>
     2
     3        IteratorClose should suppress GetMethod errors
     4        https://bugs.webkit.org/show_bug.cgi?id=212378
     5
     6        Reviewed by Keith Miller.
     7
     8        This patch implements recent spec change [1] that prevents "return" method lookup error
     9        from overriding outer exception, aligning JSC with V8 and SpiderMonkey.
     10
     11        It is accomplished by moving pushTry() before emitGetById() in BytecodeGenerator.cpp
     12        (covered by test262 suite) and removal of RETURN_IF_EXCEPTION in IteratorOperations.cpp
     13        (added a stress test).
     14
     15        Before this patch, JSC partly implemented the spec change [1] by suppressing TypeError
     16        if "return" method of iterator was not callable.
     17
     18        BytecodeGenerator::emitDelegateYield() is intentionally left unchanged.
     19        Also, this patch utilizes emitIteratorGenericClose() to avoid code duplication.
     20        for/of microbenchmarks are neutral.
     21
     22        [1]: https://github.com/tc39/ecma262/pull/1408
     23
     24        * bytecompiler/BytecodeGenerator.cpp:
     25        (JSC::BytecodeGenerator::emitGenericEnumeration):
     26        (JSC::BytecodeGenerator::emitEnumeration):
     27        * runtime/IteratorOperations.cpp:
     28        (JSC::iteratorClose):
     29
    1302020-05-26  Mark Lam  <mark.lam@apple.com>
    231
  • trunk/Source/JavaScriptCore/bytecompiler/BytecodeGenerator.cpp

    r262083 r262165  
    40834083            restoreScopeRegister();
    40844084
    4085             Ref<Label> finallyDone = newLabel();
    4086 
    4087             RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().returnKeyword);
    4088             emitJumpIfTrue(emitIsUndefined(newTemporary(), returnMethod.get()), finallyDone.get());
    4089 
    40904085            Ref<Label> returnCallTryStart = newLabel();
    40914086            emitLabel(returnCallTryStart.get());
    40924087            TryData* returnCallTryData = pushTry(returnCallTryStart.get(), catchLabel.get(), HandlerType::SynthesizedCatch);
    40934088
    4094             CallArguments returnArguments(*this, nullptr);
    4095             move(returnArguments.thisRegister(), iterator.get());
    4096             emitCall(value.get(), returnMethod.get(), NoExpectedFunction, returnArguments, node->divot(), node->divotStart(), node->divotEnd(), DebuggableCall::No);
    4097 
    4098             if (isForAwait)
    4099                 emitAwait(value.get());
    4100 
    4101             emitJumpIfTrue(emitIsObject(newTemporary(), value.get()), finallyDone.get());
    4102             emitThrowTypeError("Iterator result interface is not an object."_s);
    4103 
    4104             emitLabel(finallyDone.get());
     4089            emitIteratorGenericClose(iterator.get(), node, shouldEmitAwait);
     4090            Ref<Label> finallyDone = newEmittedLabel();
    41054091            emitFinallyCompletion(finallyContext, endCatchLabel.get());
    41064092
     
    42394225            restoreScopeRegister();
    42404226
    4241             Ref<Label> finallyDone = newLabel();
    4242 
    4243             RefPtr<RegisterID> returnMethod = emitGetById(newTemporary(), iterator.get(), propertyNames().returnKeyword);
    4244             emitJumpIfTrue(emitIsUndefined(newTemporary(), returnMethod.get()), finallyDone.get());
    4245 
    42464227            Ref<Label> returnCallTryStart = newLabel();
    42474228            emitLabel(returnCallTryStart.get());
    42484229            TryData* returnCallTryData = pushTry(returnCallTryStart.get(), catchLabel.get(), HandlerType::SynthesizedCatch);
    42494230
    4250             CallArguments returnArguments(*this, nullptr);
    4251             move(returnArguments.thisRegister(), iterator.get());
    4252             emitCall(value.get(), returnMethod.get(), NoExpectedFunction, returnArguments, node->divot(), node->divotStart(), node->divotEnd(), DebuggableCall::No);
    4253 
    4254             emitJumpIfTrue(emitIsObject(newTemporary(), value.get()), finallyDone.get());
    4255             emitThrowTypeError("Iterator result interface is not an object."_s);
    4256 
    4257             emitLabel(finallyDone.get());
     4231            emitIteratorGenericClose(iterator.get(), node, EmitAwait::No);
     4232            Ref<Label> finallyDone = newEmittedLabel();
    42584233            emitFinallyCompletion(finallyContext, endCatchLabel.get());
    42594234
  • trunk/Source/JavaScriptCore/runtime/IteratorOperations.cpp

    r261755 r262165  
    9494        catchScope.clearException();
    9595    }
     96
    9697    JSValue returnFunction = iterationRecord.iterator.get(globalObject, vm.propertyNames->returnKeyword);
    97     RETURN_IF_EXCEPTION(throwScope, void());
    98 
    99     if (returnFunction.isUndefined()) {
     98    if (UNLIKELY(throwScope.exception()) || returnFunction.isUndefined()) {
    10099        if (exception)
    101100            throwException(globalObject, throwScope, exception);
Note: See TracChangeset for help on using the changeset viewer.