Ignore:
Timestamp:
May 26, 2020, 3:16:10 PM (5 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):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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
Note: See TracChangeset for help on using the changeset viewer.