Reland "[esnext] load iterator.next only once at beginning of iteration"

https://github.com/tc39/ecma262/pull/988 gained concensus during the
september 2017 TC39 meetings. This moves the load of the "next" method
to the very beginning of the iteration protocol, rather than during
each iteration step.

This impacts:

- yield*
- for-of loops
- spread arguments
- array spreads

In the v8 implementation, this also affects async iteration versions of
these things (the sole exception being the Async-From-Sync iterator,
which requires a few more changes to work with this, likely done in a
followup patch).

This change introduces a new AST node, ResolvedProperty, which can be used
as a callee by Call nodes to produce the same bytecode as Property calls,
without observably re-loading the property. This is used in several
AST-desugarings involving the iteration protocol.

BUG=v8:6861, v8:5699
R=rmcilroy@chromium.org
TBR=neis@chromium.org, adamk@chromium.org

Cq-Include-Trybots: luci.v8.try:v8_linux_noi18n_rel_ng
Change-Id: I9685db6e85315ba8a2df87a4537c2bf491e1e35b
Reviewed-on: https://chromium-review.googlesource.com/857593
Commit-Queue: Caitlin Potter <caitp@igalia.com>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50518}
This commit is contained in:
Caitlin Potter 2018-01-11 12:24:11 -05:00 committed by Commit Bot
parent ca54981260
commit 2d889aa9a4
29 changed files with 1951 additions and 1826 deletions

View File

@ -195,6 +195,11 @@ void AstNumberingVisitor::VisitProperty(Property* node) {
Visit(node->obj());
}
void AstNumberingVisitor::VisitResolvedProperty(ResolvedProperty* node) {
Visit(node->object());
Visit(node->property());
}
void AstNumberingVisitor::VisitAssignment(Assignment* node) {
Visit(node->target());
Visit(node->value());
@ -251,6 +256,7 @@ void AstNumberingVisitor::VisitForInStatement(ForInStatement* node) {
void AstNumberingVisitor::VisitForOfStatement(ForOfStatement* node) {
Visit(node->assign_iterator()); // Not part of loop.
Visit(node->assign_next());
node->set_first_suspend_id(suspend_count_);
Visit(node->next_result());
Visit(node->result_done());

View File

@ -392,6 +392,14 @@ void AstTraversalVisitor<Subclass>::VisitProperty(Property* expr) {
RECURSE_EXPRESSION(Visit(expr->key()));
}
template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitResolvedProperty(
ResolvedProperty* expr) {
PROCESS_EXPRESSION(expr);
RECURSE_EXPRESSION(VisitVariableProxy(expr->object()));
RECURSE_EXPRESSION(VisitVariableProxy(expr->property()));
}
template <class Subclass>
void AstTraversalVisitor<Subclass>::VisitCall(Call* expr) {
PROCESS_EXPRESSION(expr);

View File

@ -805,6 +805,10 @@ Call::CallType Call::GetCallType() const {
}
}
if (expression()->IsResolvedProperty()) {
return RESOLVED_PROPERTY_CALL;
}
return OTHER_CALL;
}

View File

@ -94,6 +94,7 @@ namespace internal {
V(Literal) \
V(NativeFunctionLiteral) \
V(Property) \
V(ResolvedProperty) \
V(RewritableExpression) \
V(Spread) \
V(SuperCallReference) \
@ -590,11 +591,13 @@ class ForInStatement final : public ForEachStatement {
class ForOfStatement final : public ForEachStatement {
public:
void Initialize(Statement* body, Variable* iterator,
Expression* assign_iterator, Expression* next_result,
Expression* result_done, Expression* assign_each) {
Expression* assign_iterator, Expression* assign_next,
Expression* next_result, Expression* result_done,
Expression* assign_each) {
ForEachStatement::Initialize(body);
iterator_ = iterator;
assign_iterator_ = assign_iterator;
assign_next_ = assign_next;
next_result_ = next_result;
result_done_ = result_done;
assign_each_ = assign_each;
@ -609,6 +612,9 @@ class ForOfStatement final : public ForEachStatement {
return assign_iterator_;
}
// iteratorRecord.next = iterator.next
Expression* assign_next() const { return assign_next_; }
// result = iterator.next() // with type check
Expression* next_result() const {
return next_result_;
@ -624,6 +630,12 @@ class ForOfStatement final : public ForEachStatement {
return assign_each_;
}
void set_assign_iterator(Expression* e) { assign_iterator_ = e; }
void set_assign_next(Expression* e) { assign_next_ = e; }
void set_next_result(Expression* e) { next_result_ = e; }
void set_result_done(Expression* e) { result_done_ = e; }
void set_assign_each(Expression* e) { assign_each_ = e; }
private:
friend class AstNodeFactory;
@ -637,6 +649,7 @@ class ForOfStatement final : public ForEachStatement {
Variable* iterator_;
Expression* assign_iterator_;
Expression* assign_next_;
Expression* next_result_;
Expression* result_done_;
Expression* assign_each_;
@ -1607,6 +1620,25 @@ class Property final : public Expression {
Expression* key_;
};
// ResolvedProperty pairs a receiver field with a value field. It allows Call
// to support arbitrary receivers while still taking advantage of TypeFeedback.
class ResolvedProperty final : public Expression {
public:
VariableProxy* object() const { return object_; }
VariableProxy* property() const { return property_; }
void set_object(VariableProxy* e) { object_ = e; }
void set_property(VariableProxy* e) { property_ = e; }
private:
friend class AstNodeFactory;
ResolvedProperty(VariableProxy* obj, VariableProxy* property, int pos)
: Expression(pos, kResolvedProperty), object_(obj), property_(property) {}
VariableProxy* object_;
VariableProxy* property_;
};
class Call final : public Expression {
public:
@ -1633,6 +1665,7 @@ class Call final : public Expression {
NAMED_SUPER_PROPERTY_CALL,
KEYED_SUPER_PROPERTY_CALL,
SUPER_CALL,
RESOLVED_PROPERTY_CALL,
OTHER_CALL
};
@ -2104,7 +2137,6 @@ class YieldStar final : public Suspend {
// - One for awaiting the iterator result yielded by the delegated iterator
// (await_delegated_iterator_output_suspend_id)
int await_iterator_close_suspend_id() const {
DCHECK_NE(-1, await_iterator_close_suspend_id_);
return await_iterator_close_suspend_id_;
}
void set_await_iterator_close_suspend_id(int id) {
@ -2112,7 +2144,6 @@ class YieldStar final : public Suspend {
}
int await_delegated_iterator_output_suspend_id() const {
DCHECK_NE(-1, await_delegated_iterator_output_suspend_id_);
return await_delegated_iterator_output_suspend_id_;
}
void set_await_delegated_iterator_output_suspend_id(int id) {
@ -2997,6 +3028,12 @@ class AstNodeFactory final BASE_EMBEDDED {
return new (zone_) Property(obj, key, pos);
}
ResolvedProperty* NewResolvedProperty(VariableProxy* obj,
VariableProxy* property,
int pos = kNoSourcePosition) {
return new (zone_) ResolvedProperty(obj, property, pos);
}
Call* NewCall(Expression* expression, ZoneList<Expression*>* arguments,
int pos, Call::PossiblyEval possibly_eval = Call::NOT_EVAL) {
return new (zone_) Call(expression, arguments, pos, possibly_eval);

View File

@ -326,6 +326,7 @@ void CallPrinter::VisitProperty(Property* node) {
}
}
void CallPrinter::VisitResolvedProperty(ResolvedProperty* node) {}
void CallPrinter::VisitCall(Call* node) {
bool was_found = false;
@ -1249,6 +1250,14 @@ void AstPrinter::VisitProperty(Property* node) {
}
}
void AstPrinter::VisitResolvedProperty(ResolvedProperty* node) {
EmbeddedVector<char, 128> buf;
SNPrintF(buf, "RESOLVED-PROPERTY");
IndentedScope indent(this, buf.start(), node->position());
PrintIndentedVisit("RECEIVER", node->object());
PrintIndentedVisit("PROPERTY", node->property());
}
void AstPrinter::VisitCall(Call* node) {
EmbeddedVector<char, 128> buf;

View File

@ -232,10 +232,9 @@ void BaseCollectionsAssembler::AddConstructorEntriesFromIterable(
TNode<Object> add_func = GetAddFunction(variant, context, collection);
IteratorBuiltinsAssembler iterator_assembler(this->state());
TNode<Object> iterator =
CAST(iterator_assembler.GetIterator(context, iterable));
IteratorRecord iterator = iterator_assembler.GetIterator(context, iterable);
CSA_ASSERT(this, Word32BinaryNot(IsUndefined(iterator)));
CSA_ASSERT(this, Word32BinaryNot(IsUndefined(iterator.object)));
TNode<Object> fast_iterator_result_map =
LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);

View File

@ -11,9 +11,10 @@ namespace internal {
using compiler::Node;
Node* IteratorBuiltinsAssembler::GetIterator(Node* context, Node* object,
Label* if_exception,
Variable* exception) {
IteratorRecord IteratorBuiltinsAssembler::GetIterator(Node* context,
Node* object,
Label* if_exception,
Variable* exception) {
Node* method = GetProperty(context, object, factory()->iterator_symbol());
GotoIfException(method, if_exception, exception);
@ -21,9 +22,9 @@ Node* IteratorBuiltinsAssembler::GetIterator(Node* context, Node* object,
Node* iterator = CallJS(callable, context, method, object);
GotoIfException(iterator, if_exception, exception);
Label done(this), if_notobject(this, Label::kDeferred);
Label get_next(this), if_notobject(this, Label::kDeferred);
GotoIf(TaggedIsSmi(iterator), &if_notobject);
Branch(IsJSReceiver(iterator), &done, &if_notobject);
Branch(IsJSReceiver(iterator), &get_next, &if_notobject);
BIND(&if_notobject);
{
@ -34,24 +35,21 @@ Node* IteratorBuiltinsAssembler::GetIterator(Node* context, Node* object,
Unreachable();
}
BIND(&done);
return iterator;
BIND(&get_next);
Node* const next = GetProperty(context, iterator, factory()->next_string());
GotoIfException(next, if_exception, exception);
return IteratorRecord{TNode<JSReceiver>::UncheckedCast(iterator),
TNode<Object>::UncheckedCast(next)};
}
Node* IteratorBuiltinsAssembler::IteratorStep(Node* context, Node* iterator,
Label* if_done,
Node* fast_iterator_result_map,
Label* if_exception,
Variable* exception) {
Node* IteratorBuiltinsAssembler::IteratorStep(
Node* context, const IteratorRecord& iterator, Label* if_done,
Node* fast_iterator_result_map, Label* if_exception, Variable* exception) {
DCHECK_NOT_NULL(if_done);
// IteratorNext
Node* next_method = GetProperty(context, iterator, factory()->next_string());
GotoIfException(next_method, if_exception, exception);
// 1. a. Let result be ? Invoke(iterator, "next", « »).
Callable callable = CodeFactory::Call(isolate());
Node* result = CallJS(callable, context, next_method, iterator);
Node* result = CallJS(callable, context, iterator.next, iterator.object);
GotoIfException(result, if_exception, exception);
// 3. If Type(result) is not Object, throw a TypeError exception.
@ -129,20 +127,20 @@ Node* IteratorBuiltinsAssembler::IteratorValue(Node* context, Node* result,
return var_value.value();
}
void IteratorBuiltinsAssembler::IteratorCloseOnException(Node* context,
Node* iterator,
Label* if_exception,
Variable* exception) {
void IteratorBuiltinsAssembler::IteratorCloseOnException(
Node* context, const IteratorRecord& iterator, Label* if_exception,
Variable* exception) {
// Perform ES #sec-iteratorclose when an exception occurs. This simpler
// algorithm does not include redundant steps which are never reachable from
// the spec IteratorClose algorithm.
DCHECK_NOT_NULL(if_exception);
DCHECK_NOT_NULL(exception);
CSA_ASSERT(this, IsNotTheHole(exception->value()));
CSA_ASSERT(this, IsJSReceiver(iterator));
CSA_ASSERT(this, IsJSReceiver(iterator.object));
// Let return be ? GetMethod(iterator, "return").
Node* method = GetProperty(context, iterator, factory()->return_string());
Node* method =
GetProperty(context, iterator.object, factory()->return_string());
GotoIfException(method, if_exception, exception);
// If return is undefined, return Completion(completion).
@ -152,7 +150,7 @@ void IteratorBuiltinsAssembler::IteratorCloseOnException(Node* context,
// Let innerResult be Call(return, iterator, « »).
// If an exception occurs, the original exception remains bound
Node* inner_result =
CallJS(CodeFactory::Call(isolate()), context, method, iterator);
CallJS(CodeFactory::Call(isolate()), context, method, iterator.object);
GotoIfException(inner_result, if_exception, nullptr);
// (If completion.[[Type]] is throw) return Completion(completion).
@ -160,9 +158,8 @@ void IteratorBuiltinsAssembler::IteratorCloseOnException(Node* context,
}
}
void IteratorBuiltinsAssembler::IteratorCloseOnException(Node* context,
Node* iterator,
Variable* exception) {
void IteratorBuiltinsAssembler::IteratorCloseOnException(
Node* context, const IteratorRecord& iterator, Variable* exception) {
Label rethrow(this, Label::kDeferred);
IteratorCloseOnException(context, iterator, &rethrow, exception);

View File

@ -19,16 +19,17 @@ class IteratorBuiltinsAssembler : public CodeStubAssembler {
// https://tc39.github.io/ecma262/#sec-getiterator --- never used for
// @@asyncIterator.
Node* GetIterator(Node* context, Node* object, Label* if_exception = nullptr,
Variable* exception = nullptr);
IteratorRecord GetIterator(Node* context, Node* object,
Label* if_exception = nullptr,
Variable* exception = nullptr);
// https://tc39.github.io/ecma262/#sec-iteratorstep
// Returns `false` if the iterator is done, otherwise returns an
// iterator result.
// `fast_iterator_result_map` refers to the map for the JSIteratorResult
// object, loaded from the native context.
Node* IteratorStep(Node* context, Node* iterator, Label* if_done,
Node* fast_iterator_result_map = nullptr,
Node* IteratorStep(Node* context, const IteratorRecord& iterator,
Label* if_done, Node* fast_iterator_result_map = nullptr,
Label* if_exception = nullptr,
Variable* exception = nullptr);
@ -42,9 +43,9 @@ class IteratorBuiltinsAssembler : public CodeStubAssembler {
Variable* exception = nullptr);
// https://tc39.github.io/ecma262/#sec-iteratorclose
void IteratorCloseOnException(Node* context, Node* iterator,
void IteratorCloseOnException(Node* context, const IteratorRecord& iterator,
Label* if_exception, Variable* exception);
void IteratorCloseOnException(Node* context, Node* iterator,
void IteratorCloseOnException(Node* context, const IteratorRecord& iterator,
Variable* exception);
};

View File

@ -1744,8 +1744,9 @@ TF_BUILTIN(PerformNativePromiseThen, PromiseBuiltinsAssembler) {
}
Node* PromiseBuiltinsAssembler::PerformPromiseAll(
Node* context, Node* constructor, Node* capability, Node* iterator,
Label* if_exception, Variable* var_exception) {
Node* context, Node* constructor, Node* capability,
const IteratorRecord& iterator, Label* if_exception,
Variable* var_exception) {
IteratorBuiltinsAssembler iter_assembler(state());
Label close_iterator(this);
@ -1951,7 +1952,7 @@ TF_BUILTIN(PromiseAll, PromiseBuiltinsAssembler) {
// Let iterator be GetIterator(iterable).
// IfAbruptRejectPromise(iterator, promiseCapability).
Node* const iterable = Parameter(Descriptor::kIterable);
Node* const iterator = iter_assembler.GetIterator(
IteratorRecord iterator = iter_assembler.GetIterator(
context, iterable, &reject_promise, &var_exception);
// Let result be PerformPromiseAll(iteratorRecord, C, promiseCapability).
@ -2088,7 +2089,7 @@ TF_BUILTIN(PromiseRace, PromiseBuiltinsAssembler) {
// Let iterator be GetIterator(iterable).
// IfAbruptRejectPromise(iterator, promiseCapability).
Node* const iterable = Parameter(Descriptor::kIterable);
Node* const iterator = iter_assembler.GetIterator(
IteratorRecord iterator = iter_assembler.GetIterator(
context, iterable, &reject_promise, &var_exception);
// Let result be PerformPromiseRace(iteratorRecord, C, promiseCapability).

View File

@ -157,7 +157,7 @@ class PromiseBuiltinsAssembler : public CodeStubAssembler {
Node* CreateThrowerFunction(Node* reason, Node* native_context);
Node* PerformPromiseAll(Node* context, Node* constructor, Node* capability,
Node* iterator, Label* if_exception,
const IteratorRecord& record, Label* if_exception,
Variable* var_exception);
Node* IncrementSmiCell(Node* cell, Label* if_overflow = nullptr);

View File

@ -71,6 +71,17 @@ enum class PrimitiveType { kBoolean, kNumber, kString, kSymbol };
promise_default_resolve_handler_symbol, \
PromiseDefaultResolveHandlerSymbol)
// Returned from IteratorBuiltinsAssembler::GetIterator(). Struct is declared
// here to simplify use in other generated builtins.
struct IteratorRecord {
public:
// iteratorRecord.[[Iterator]]
compiler::TNode<JSReceiver> object;
// iteratorRecord.[[NextMethod]]
compiler::TNode<Object> next;
};
// Provides JavaScript-specific "macro-assembler" functionality on top of the
// CodeAssembler. By factoring the JavaScript-isms out of the CodeAssembler,
// it's possible to add JavaScript-specific useful CodeAssembler "macros"

View File

@ -837,14 +837,6 @@ class BytecodeGenerator::FeedbackSlotCache : public ZoneObject {
class BytecodeGenerator::IteratorRecord final {
public:
// TODO(caitp): This constructor is used for legacy code which doesn't load
// the `next` method immediately during GetIterator. It should be removed once
// the followup CL lands.
IteratorRecord(Register object_register,
IteratorType type = IteratorType::kNormal)
: type_(type), object_(object_register) {
DCHECK(object_.is_valid());
}
IteratorRecord(Register object_register, Register next_register,
IteratorType type = IteratorType::kNormal)
: type_(type), object_(object_register), next_(next_register) {
@ -1700,6 +1692,7 @@ void BytecodeGenerator::VisitForOfStatement(ForOfStatement* stmt) {
builder()->SetExpressionAsStatementPosition(stmt->assign_iterator());
VisitForEffect(stmt->assign_iterator());
VisitForEffect(stmt->assign_next());
VisitIterationHeader(stmt, &loop_builder);
builder()->SetExpressionAsStatementPosition(stmt->next_result());
@ -2981,7 +2974,9 @@ void BytecodeGenerator::VisitYield(Yield* expr) {
//
// let output; // uninitialized
//
// let iterator = GetIterator(iterable);
// let iteratorRecord = GetIterator(iterable);
// let iterator = iteratorRecord.[[Iterator]];
// let next = iteratorRecord.[[NextMethod]];
// let input = undefined;
// let resumeMode = kNext;
//
@ -2990,25 +2985,25 @@ void BytecodeGenerator::VisitYield(Yield* expr) {
// // Forward input according to resumeMode and obtain output.
// switch (resumeMode) {
// case kNext:
// output = iterator.next(input);
// output = next.[[Call]](iterator, « »);;
// break;
// case kReturn:
// let iteratorReturn = iterator.return;
// if (IS_NULL_OR_UNDEFINED(iteratorReturn)) return input;
// output = %_Call(iteratorReturn, iterator, input);
// output = iteratorReturn.[[Call]](iterator, «input»);
// break;
// case kThrow:
// let iteratorThrow = iterator.throw;
// if (IS_NULL_OR_UNDEFINED(iteratorThrow)) {
// let iteratorReturn = iterator.return;
// if (!IS_NULL_OR_UNDEFINED(iteratorReturn)) {
// output = %_Call(iteratorReturn, iterator);
// output = iteratorReturn.[[Call]](iterator, « »);
// if (IS_ASYNC_GENERATOR) output = await output;
// if (!IS_RECEIVER(output)) %ThrowIterResultNotAnObject(output);
// }
// throw MakeTypeError(kThrowMethodMissing);
// }
// output = %_Call(iteratorThrow, iterator, input);
// output = iteratorThrow.[[Call]](iterator, «input»);
// break;
// }
//
@ -3041,12 +3036,11 @@ void BytecodeGenerator::VisitYieldStar(YieldStar* expr) {
{
RegisterAllocationScope register_scope(this);
RegisterList iterator_and_input = register_allocator()->NewRegisterList(2);
IteratorRecord iterator(iterator_and_input[0], iterator_type);
BuildGetIterator(expr->expression(), iterator_type);
builder()->StoreAccumulatorInRegister(iterator.object());
IteratorRecord iterator = BuildGetIteratorRecord(
expr->expression(),
register_allocator()->NewRegister() /* next method */,
iterator_and_input[0], iterator_type);
Register input = iterator_and_input[1];
builder()->LoadUndefined().StoreAccumulatorInRegister(input);
@ -3078,109 +3072,46 @@ void BytecodeGenerator::VisitYieldStar(YieldStar* expr) {
// {JSGeneratorObject::kNext} in this case.
STATIC_ASSERT(JSGeneratorObject::kNext == 0);
{
RegisterAllocationScope register_scope(this);
// output = iterator.next(input);
Register iterator_next = register_allocator()->NewRegister();
FeedbackSlot load_slot = feedback_spec()->AddLoadICSlot();
FeedbackSlot call_slot = feedback_spec()->AddCallICSlot();
builder()
->LoadNamedProperty(iterator.object(),
ast_string_constants()->next_string(),
feedback_index(load_slot))
.StoreAccumulatorInRegister(iterator_next)
.CallProperty(iterator_next, iterator_and_input,
feedback_index(call_slot))
.Jump(after_switch.New());
FeedbackSlot slot = feedback_spec()->AddCallICSlot();
builder()->CallProperty(iterator.next(), iterator_and_input,
feedback_index(slot));
builder()->Jump(after_switch.New());
}
STATIC_ASSERT(JSGeneratorObject::kReturn == 1);
builder()->Bind(switch_jump_table, JSGeneratorObject::kReturn);
{
RegisterAllocationScope register_scope(this);
BytecodeLabels return_input(zone());
// Trigger return from within the inner iterator.
Register iterator_return = register_allocator()->NewRegister();
FeedbackSlot load_slot = feedback_spec()->AddLoadICSlot();
FeedbackSlot call_slot = feedback_spec()->AddCallICSlot();
builder()
->LoadNamedProperty(iterator.object(),
ast_string_constants()->return_string(),
feedback_index(load_slot))
.JumpIfUndefined(return_input.New())
.JumpIfNull(return_input.New())
.StoreAccumulatorInRegister(iterator_return)
.CallProperty(iterator_return, iterator_and_input,
feedback_index(call_slot))
.Jump(after_switch.New());
const AstRawString* return_string =
ast_string_constants()->return_string();
BytecodeLabels no_return_method(zone());
return_input.Bind(builder());
{
builder()->LoadAccumulatorWithRegister(input);
if (iterator_type == IteratorType::kAsync) {
execution_control()->AsyncReturnAccumulator();
} else {
execution_control()->ReturnAccumulator();
}
BuildCallIteratorMethod(iterator.object(), return_string,
iterator_and_input, after_switch.New(),
&no_return_method);
no_return_method.Bind(builder());
builder()->LoadAccumulatorWithRegister(input);
if (iterator_type == IteratorType::kAsync) {
execution_control()->AsyncReturnAccumulator();
} else {
execution_control()->ReturnAccumulator();
}
}
STATIC_ASSERT(JSGeneratorObject::kThrow == 2);
builder()->Bind(switch_jump_table, JSGeneratorObject::kThrow);
{
BytecodeLabels iterator_throw_is_undefined(zone());
{
RegisterAllocationScope register_scope(this);
// If the inner iterator has a throw method, use it to trigger an
// exception inside.
Register iterator_throw = register_allocator()->NewRegister();
FeedbackSlot load_slot = feedback_spec()->AddLoadICSlot();
FeedbackSlot call_slot = feedback_spec()->AddCallICSlot();
builder()
->LoadNamedProperty(iterator.object(),
ast_string_constants()->throw_string(),
feedback_index(load_slot))
.JumpIfUndefined(iterator_throw_is_undefined.New())
.JumpIfNull(iterator_throw_is_undefined.New())
.StoreAccumulatorInRegister(iterator_throw);
builder()
->CallProperty(iterator_throw, iterator_and_input,
feedback_index(call_slot))
.Jump(after_switch.New());
}
const AstRawString* throw_string =
ast_string_constants()->throw_string();
BytecodeLabels no_throw_method(zone());
BuildCallIteratorMethod(iterator.object(), throw_string,
iterator_and_input, after_switch.New(),
&no_throw_method);
iterator_throw_is_undefined.Bind(builder());
{
RegisterAllocationScope register_scope(this);
BytecodeLabels throw_throw_method_missing(zone());
Register iterator_return = register_allocator()->NewRegister();
// If iterator.throw does not exist, try to use iterator.return to
// inform the iterator that it should stop.
FeedbackSlot load_slot = feedback_spec()->AddLoadICSlot();
FeedbackSlot call_slot = feedback_spec()->AddCallICSlot();
builder()
->LoadNamedProperty(iterator.object(),
ast_string_constants()->return_string(),
feedback_index(load_slot))
.StoreAccumulatorInRegister(iterator_return);
builder()
->JumpIfUndefined(throw_throw_method_missing.New())
.JumpIfNull(throw_throw_method_missing.New())
.CallProperty(iterator_return, RegisterList(iterator.object()),
feedback_index(call_slot));
if (iterator_type == IteratorType::kAsync) {
// For async generators, await the result of the .return() call.
BuildAwait(expr->await_iterator_close_suspend_id());
builder()->StoreAccumulatorInRegister(output);
}
builder()
->JumpIfJSReceiver(throw_throw_method_missing.New())
.CallRuntime(Runtime::kThrowIteratorResultNotAnObject, output);
throw_throw_method_missing.Bind(builder());
builder()->CallRuntime(Runtime::kThrowThrowMethodMissing);
}
// If there is no "throw" method, perform IteratorClose, and finally
// throw a TypeError.
no_throw_method.Bind(builder());
BuildIteratorClose(iterator, expr->await_iterator_close_suspend_id());
builder()->CallRuntime(Runtime::kThrowThrowMethodMissing);
}
after_switch.Bind(builder());
@ -3433,6 +3364,11 @@ void BytecodeGenerator::VisitProperty(Property* expr) {
}
}
void BytecodeGenerator::VisitResolvedProperty(ResolvedProperty* expr) {
// Handled by VisitCall().
UNREACHABLE();
}
void BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args,
RegisterList* arg_regs) {
// Visit arguments.
@ -3475,6 +3411,13 @@ void BytecodeGenerator::VisitCall(Call* expr) {
VisitPropertyLoadForRegister(args.last_register(), property, callee);
break;
}
case Call::RESOLVED_PROPERTY_CALL: {
ResolvedProperty* resolved = callee_expr->AsResolvedProperty();
VisitAndPushIntoRegisterList(resolved->object(), &args);
VisitForAccumulatorValue(resolved->property());
builder()->StoreAccumulatorInRegister(callee);
break;
}
case Call::GLOBAL_CALL: {
// Receiver is undefined for global calls.
if (!is_spread_call) {
@ -3583,7 +3526,8 @@ void BytecodeGenerator::VisitCall(Call* expr) {
DCHECK(!implicit_undefined_receiver);
builder()->CallWithSpread(callee, args, feedback_slot_index);
} else if (call_type == Call::NAMED_PROPERTY_CALL ||
call_type == Call::KEYED_PROPERTY_CALL) {
call_type == Call::KEYED_PROPERTY_CALL ||
call_type == Call::RESOLVED_PROPERTY_CALL) {
DCHECK(!implicit_undefined_receiver);
builder()->CallProperty(callee, args, feedback_slot_index);
} else if (implicit_undefined_receiver) {
@ -4155,11 +4099,10 @@ void BytecodeGenerator::BuildGetIterator(Expression* iterable,
// Returns an IteratorRecord which is valid for the lifetime of the current
// register_allocation_scope.
BytecodeGenerator::IteratorRecord BytecodeGenerator::BuildGetIteratorRecord(
Expression* iterable, IteratorType hint) {
Expression* iterable, Register next, Register object, IteratorType hint) {
DCHECK(next.is_valid() && object.is_valid());
BuildGetIterator(iterable, hint);
Register object = register_allocator()->NewRegister();
Register next = register_allocator()->NewRegister();
builder()
->StoreAccumulatorInRegister(object)
.LoadNamedProperty(object, ast_string_constants()->next_string(),
@ -4168,6 +4111,13 @@ BytecodeGenerator::IteratorRecord BytecodeGenerator::BuildGetIteratorRecord(
return IteratorRecord(object, next, hint);
}
BytecodeGenerator::IteratorRecord BytecodeGenerator::BuildGetIteratorRecord(
Expression* iterable, IteratorType hint) {
Register next = register_allocator()->NewRegister();
Register object = register_allocator()->NewRegister();
return BuildGetIteratorRecord(iterable, next, object, hint);
}
void BytecodeGenerator::BuildIteratorNext(const IteratorRecord& iterator,
Register next_result) {
DCHECK(next_result.is_valid());
@ -4184,6 +4134,53 @@ void BytecodeGenerator::BuildIteratorNext(const IteratorRecord& iterator,
.Bind(&is_object);
}
void BytecodeGenerator::BuildCallIteratorMethod(Register iterator,
const AstRawString* method_name,
RegisterList receiver_and_args,
BytecodeLabel* if_called,
BytecodeLabels* if_notcalled) {
RegisterAllocationScope register_scope(this);
Register method = register_allocator()->NewRegister();
FeedbackSlot slot = feedback_spec()->AddLoadICSlot();
builder()
->LoadNamedProperty(iterator, method_name, feedback_index(slot))
.JumpIfUndefined(if_notcalled->New())
.JumpIfNull(if_notcalled->New())
.StoreAccumulatorInRegister(method)
.CallProperty(method, receiver_and_args,
feedback_index(feedback_spec()->AddCallICSlot()))
.Jump(if_called);
}
void BytecodeGenerator::BuildIteratorClose(const IteratorRecord& iterator,
int suspend_id) {
RegisterAllocationScope register_scope(this);
BytecodeLabels done(zone());
BytecodeLabel if_called;
RegisterList args = RegisterList(iterator.object());
BuildCallIteratorMethod(iterator.object(),
ast_string_constants()->return_string(), args,
&if_called, &done);
builder()->Bind(&if_called);
if (iterator.type() == IteratorType::kAsync) {
DCHECK_GE(suspend_id, 0);
BuildAwait(suspend_id);
}
builder()->JumpIfJSReceiver(done.New());
{
RegisterAllocationScope register_scope(this);
Register return_result = register_allocator()->NewRegister();
builder()
->StoreAccumulatorInRegister(return_result)
.CallRuntime(Runtime::kThrowIteratorResultNotAnObject, return_result);
}
done.Bind(builder());
}
void BytecodeGenerator::VisitGetIterator(GetIterator* expr) {
builder()->SetExpressionPosition(expr);
BuildGetIterator(expr->iterable(), expr->hint());

View File

@ -151,9 +151,24 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildAwait(int suspend_id);
void BuildGetIterator(Expression* iterable, IteratorType hint);
// Create an IteratorRecord with pre-allocated registers holding the next
// method and iterator object.
IteratorRecord BuildGetIteratorRecord(Expression* iterable,
Register iterator_next,
Register iterator_object,
IteratorType hint);
// Create an IteratorRecord allocating new registers to hold the next method
// and iterator object.
IteratorRecord BuildGetIteratorRecord(Expression* iterable,
IteratorType hint);
void BuildIteratorNext(const IteratorRecord& iterator, Register next_result);
void BuildIteratorClose(const IteratorRecord& iterator, int suspend_id = -1);
void BuildCallIteratorMethod(Register iterator, const AstRawString* method,
RegisterList receiver_and_args,
BytecodeLabel* if_called,
BytecodeLabels* if_notcalled);
void BuildArrayLiteralSpread(Spread* spread, Register array);

View File

@ -1890,13 +1890,11 @@ void Parser::DeclareFunctionNameVar(const AstRawString* function_name,
// !%_IsJSReceiver(result = Await(iterator.next())) &&
// %ThrowIteratorResultNotAnObject(result)
// [endif]
Expression* Parser::BuildIteratorNextResult(Expression* iterator,
Expression* Parser::BuildIteratorNextResult(VariableProxy* iterator,
VariableProxy* next,
Variable* result, IteratorType type,
int pos) {
Expression* next_literal = factory()->NewStringLiteral(
ast_value_factory()->next_string(), kNoSourcePosition);
Expression* next_property =
factory()->NewProperty(iterator, next_literal, kNoSourcePosition);
Expression* next_property = factory()->NewResolvedProperty(iterator, next);
ZoneList<Expression*>* next_arguments =
new (zone()) ZoneList<Expression*>(0, zone());
Expression* next_call =
@ -2099,6 +2097,7 @@ Statement* Parser::InitializeForOfStatement(
auto avfactory = ast_value_factory();
Variable* iterator = NewTemporary(avfactory->dot_iterator_string());
Variable* next = NewTemporary(avfactory->empty_string());
Variable* result = NewTemporary(avfactory->dot_result_string());
Variable* completion = NewTemporary(avfactory->empty_string());
@ -2111,6 +2110,17 @@ Statement* Parser::InitializeForOfStatement(
iterable->position());
}
Expression* assign_next;
{
assign_next = factory()->NewAssignment(
Token::ASSIGN, factory()->NewVariableProxy(next),
factory()->NewProperty(factory()->NewVariableProxy(iterator),
factory()->NewStringLiteral(
avfactory->next_string(), kNoSourcePosition),
kNoSourcePosition),
kNoSourcePosition);
}
// [if (IteratorType == kNormal)]
// !%_IsJSReceiver(result = iterator.next()) &&
// %ThrowIteratorResultNotAnObject(result)
@ -2120,9 +2130,10 @@ Statement* Parser::InitializeForOfStatement(
// [endif]
Expression* next_result;
{
Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
next_result =
BuildIteratorNextResult(iterator_proxy, result, type, next_result_pos);
VariableProxy* iterator_proxy = factory()->NewVariableProxy(iterator);
VariableProxy* next_proxy = factory()->NewVariableProxy(next);
next_result = BuildIteratorNextResult(iterator_proxy, next_proxy, result,
type, next_result_pos);
}
// result.done
@ -2192,8 +2203,8 @@ Statement* Parser::InitializeForOfStatement(
body = block;
}
for_of->Initialize(body, iterator, assign_iterator, next_result, result_done,
assign_each);
for_of->Initialize(body, iterator, assign_iterator, assign_next, next_result,
result_done, assign_each);
return finalize ? FinalizeForOfStatement(for_of, completion, type, nopos)
: for_of;
}

View File

@ -402,13 +402,14 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
Expression* RewriteDestructuringAssignment(Assignment* assignment);
// [if (IteratorType == kAsync)]
// !%_IsJSReceiver(result = Await(iterator.next()) &&
// !%_IsJSReceiver(result = Await(next.[[Call]](iterator, « »)) &&
// %ThrowIteratorResultNotAnObject(result)
// [else]
// !%_IsJSReceiver(result = iterator.next()) &&
// !%_IsJSReceiver(result = next.[[Call]](iterator, « »)) &&
// %ThrowIteratorResultNotAnObject(result)
// [endif]
Expression* BuildIteratorNextResult(Expression* iterator, Variable* result,
Expression* BuildIteratorNextResult(VariableProxy* iterator,
VariableProxy* next, Variable* result,
IteratorType type, int pos);
// Initialize the components of a for-in / for-of statement.

View File

@ -445,6 +445,11 @@ void PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
auto iterator = CreateTempVar(factory()->NewGetIterator(
factory()->NewVariableProxy(temp), current_value_, IteratorType::kNormal,
current_value_->position()));
auto next = CreateTempVar(factory()->NewProperty(
factory()->NewVariableProxy(iterator),
factory()->NewStringLiteral(ast_value_factory()->next_string(),
kNoSourcePosition),
kNoSourcePosition));
auto done =
CreateTempVar(factory()->NewBooleanLiteral(false, kNoSourcePosition));
auto result = CreateTempVar();
@ -525,7 +530,8 @@ void PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
next_block->statements()->Add(
factory()->NewExpressionStatement(
parser_->BuildIteratorNextResult(
factory()->NewVariableProxy(iterator), result,
factory()->NewVariableProxy(iterator),
factory()->NewVariableProxy(next), result,
IteratorType::kNormal, kNoSourcePosition),
kNoSourcePosition),
zone());
@ -599,6 +605,7 @@ void PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
// result = IteratorNext(iterator);
Statement* get_next = factory()->NewExpressionStatement(
parser_->BuildIteratorNextResult(factory()->NewVariableProxy(iterator),
factory()->NewVariableProxy(next),
result, IteratorType::kNormal, nopos),
nopos);
@ -756,6 +763,7 @@ NOT_A_PATTERN(ImportCallExpression)
NOT_A_PATTERN(Literal)
NOT_A_PATTERN(NativeFunctionLiteral)
NOT_A_PATTERN(RegExpLiteral)
NOT_A_PATTERN(ResolvedProperty)
NOT_A_PATTERN(ReturnStatement)
NOT_A_PATTERN(SloppyBlockFunctionStatement)
NOT_A_PATTERN(Spread)

View File

@ -275,248 +275,248 @@ snippet: "
async function* f() { for (let x of [42]) yield x }
f();
"
frame size: 22
frame size: 23
parameter count: 1
bytecode array length: 536
bytecodes: [
B(Ldar), R(2),
B(JumpIfUndefined), U8(18),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetContext), R(2), U8(1),
B(PushContext), R(11),
B(PushContext), R(12),
B(RestoreGeneratorState), R(2),
B(Star), R(10),
B(Star), R(11),
B(SwitchOnSmiNoFeedback), U8(0), U8(3), I8(0),
B(Abort), U8(15),
B(LdaSmi), I8(-2),
B(Star), R(10),
B(Mov), R(closure), R(11),
B(Mov), R(this), R(12),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(11), U8(2),
B(Star), R(11),
B(Mov), R(closure), R(12),
B(Mov), R(this), R(13),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(12), U8(2),
B(Star), R(2),
/* 17 E> */ B(StackCheck),
B(Mov), R(context), R(13),
B(Mov), R(context), R(14),
B(Mov), R(context), R(15),
B(Ldar), R(2),
/* 17 E> */ B(SuspendGenerator), R(2), R(0), U8(15), U8(0),
/* 17 E> */ B(SuspendGenerator), R(2), R(0), U8(16), U8(0),
/* 50 S> */ B(Return),
B(ResumeGenerator), R(2), R(10), R(0), U8(15),
B(Star), R(15),
B(ResumeGenerator), R(2), R(11), R(0), U8(16),
B(Star), R(16),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0),
B(Ldar), R(15),
B(Ldar), R(16),
/* 17 E> */ B(Throw),
B(LdaZero),
B(Star), R(11),
B(Mov), R(15), R(12),
B(Star), R(12),
B(Mov), R(16), R(13),
B(JumpConstant), U8(20),
B(LdaZero),
B(Star), R(6),
B(Mov), R(context), R(17),
B(Star), R(7),
B(Mov), R(context), R(18),
B(Mov), R(context), R(19),
/* 36 S> */ B(CreateArrayLiteral), U8(5), U8(0), U8(37),
B(Star), R(19),
B(LdaNamedProperty), R(19), U8(6), U8(1),
B(Star), R(20),
B(CallProperty0), R(20), R(19), U8(3),
B(LdaNamedProperty), R(20), U8(6), U8(1),
B(Star), R(21),
B(CallProperty0), R(21), R(20), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(4),
B(Ldar), R(10),
B(SwitchOnSmiNoFeedback), U8(7), U8(1), I8(1),
/* 36 E> */ B(LdaNamedProperty), R(4), U8(7), U8(5),
B(Star), R(5),
B(Ldar), R(11),
B(SwitchOnSmiNoFeedback), U8(8), U8(1), I8(1),
B(LdaSmi), I8(-2),
/* 36 E> */ B(TestEqualStrictNoFeedback), R(10),
B(TestEqualStrictNoFeedback), R(11),
B(JumpIfTrue), U8(4),
B(Abort), U8(15),
/* 31 S> */ B(LdaNamedProperty), R(4), U8(8), U8(5),
B(Star), R(19),
B(CallProperty0), R(19), R(4), U8(7),
B(Star), R(5),
/* 31 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(5), U8(1),
/* 31 S> */ B(CallProperty0), R(5), R(4), U8(7),
B(Star), R(6),
/* 31 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(6), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
B(LdaNamedProperty), R(5), U8(9), U8(9),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(9), U8(9),
B(JumpIfToBooleanTrue), U8(70),
B(LdaNamedProperty), R(5), U8(10), U8(11),
B(Star), R(7),
B(LdaNamedProperty), R(6), U8(10), U8(11),
B(Star), R(8),
B(LdaSmi), I8(2),
B(Star), R(6),
B(Mov), R(7), R(3),
B(Star), R(7),
B(Mov), R(8), R(3),
/* 22 E> */ B(StackCheck),
B(Mov), R(3), R(0),
/* 42 S> */ B(LdaFalse),
B(Star), R(21),
B(Mov), R(2), R(19),
B(Mov), R(0), R(20),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorYield), R(19), U8(3),
B(SuspendGenerator), R(2), R(0), U8(19), U8(1),
B(Star), R(22),
B(Mov), R(2), R(20),
B(Mov), R(0), R(21),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorYield), R(20), U8(3),
B(SuspendGenerator), R(2), R(0), U8(20), U8(1),
/* 50 S> */ B(Return),
B(ResumeGenerator), R(2), R(10), R(0), U8(19),
B(Star), R(19),
B(ResumeGenerator), R(2), R(11), R(0), U8(20),
B(Star), R(20),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(SwitchOnSmiNoFeedback), U8(11), U8(2), I8(0),
B(Ldar), R(19),
B(Ldar), R(20),
/* 42 E> */ B(Throw),
B(LdaZero),
B(Star), R(15),
B(Mov), R(19), R(16),
B(Star), R(16),
B(Mov), R(20), R(17),
B(Jump), U8(62),
B(LdaZero),
B(Star), R(6),
B(JumpLoop), U8(109), I8(0),
B(Star), R(7),
B(JumpLoop), U8(103), I8(0),
B(Jump), U8(40),
B(Star), R(19),
B(Star), R(20),
B(Ldar), R(closure),
B(CreateCatchContext), R(19), U8(13), U8(14),
B(Star), R(18),
B(CreateCatchContext), R(20), U8(13), U8(14),
B(Star), R(19),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(18),
B(PushContext), R(19),
B(Ldar), R(19),
B(PushContext), R(20),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(6), U8(13),
B(TestEqualStrict), R(7), U8(13),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(6),
B(Star), R(7),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(20),
B(CallRuntime), U16(Runtime::kReThrow), R(20), U8(1),
B(PopContext), R(19),
B(Star), R(21),
B(CallRuntime), U16(Runtime::kReThrow), R(21), U8(1),
B(PopContext), R(20),
B(LdaSmi), I8(-1),
B(Star), R(17),
B(Star), R(16),
B(Star), R(15),
B(Jump), U8(8),
B(Star), R(16),
B(Star), R(17),
B(LdaSmi), I8(1),
B(Star), R(15),
B(Star), R(16),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(17),
B(Star), R(18),
B(LdaZero),
B(TestEqualStrict), R(6), U8(14),
B(TestEqualStrict), R(7), U8(14),
B(JumpIfTrue), U8(90),
B(LdaNamedProperty), R(4), U8(15), U8(15),
B(Star), R(8),
B(Star), R(9),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(6), U8(17),
B(TestEqualStrict), R(7), U8(17),
B(JumpIfFalse), U8(47),
B(Ldar), R(8),
B(Ldar), R(9),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(144),
B(Star), R(18),
B(LdaConstant), U8(16),
B(Star), R(19),
B(CallRuntime), U16(Runtime::kNewTypeError), R(18), U8(2),
B(LdaConstant), U8(16),
B(Star), R(20),
B(CallRuntime), U16(Runtime::kNewTypeError), R(19), U8(2),
B(Throw),
B(Mov), R(context), R(18),
B(Mov), R(8), R(19),
B(Mov), R(4), R(20),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(19), U8(2),
B(Mov), R(context), R(19),
B(Mov), R(9), R(20),
B(Mov), R(4), R(21),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(20), U8(2),
B(Jump), U8(6),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(18),
B(Ldar), R(19),
B(Jump), U8(27),
B(Mov), R(8), R(18),
B(Mov), R(4), R(19),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(18), U8(2),
B(Star), R(9),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(9), U8(1),
B(Mov), R(9), R(19),
B(Mov), R(4), R(20),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(19), U8(2),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(10), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
B(Ldar), R(17),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
B(Ldar), R(18),
B(SetPendingMessage),
B(Ldar), R(15),
B(Ldar), R(16),
B(SwitchOnSmiNoFeedback), U8(17), U8(2), I8(0),
B(Jump), U8(13),
B(LdaZero),
B(Star), R(11),
B(Mov), R(16), R(12),
B(Star), R(12),
B(Mov), R(17), R(13),
B(Jump), U8(103),
B(Ldar), R(16),
B(Ldar), R(17),
B(ReThrow),
B(LdaUndefined),
B(Star), R(16),
B(Mov), R(2), R(15),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(15), U8(2),
B(SuspendGenerator), R(2), R(0), U8(15), U8(2),
/* 50 S> */ B(Return),
B(ResumeGenerator), R(2), R(10), R(0), U8(15),
B(Star), R(15),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(Star), R(16),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(16),
B(JumpIfTrue), U8(5),
B(Ldar), R(15),
B(ReThrow),
B(LdaZero),
B(Star), R(11),
B(Mov), R(15), R(12),
B(Jump), U8(55),
B(Jump), U8(39),
B(Star), R(15),
B(Ldar), R(closure),
B(CreateCatchContext), R(15), U8(13), U8(19),
B(Star), R(14),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(14),
B(PushContext), R(15),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(17),
B(Mov), R(2), R(16),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(16), U8(2),
B(PopContext), R(15),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(16), U8(2),
B(SuspendGenerator), R(2), R(0), U8(16), U8(2),
/* 50 S> */ B(Return),
B(ResumeGenerator), R(2), R(11), R(0), U8(16),
B(Star), R(16),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(Star), R(17),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(17),
B(JumpIfTrue), U8(5),
B(Ldar), R(16),
B(ReThrow),
B(LdaZero),
B(Star), R(12),
B(LdaSmi), I8(1),
B(Star), R(11),
B(Jump), U8(16),
B(LdaSmi), I8(-1),
B(Star), R(12),
B(Star), R(11),
B(Jump), U8(8),
B(Star), R(12),
B(LdaSmi), I8(2),
B(Star), R(11),
B(Mov), R(16), R(13),
B(Jump), U8(55),
B(Jump), U8(39),
B(Star), R(16),
B(Ldar), R(closure),
B(CreateCatchContext), R(16), U8(13), U8(19),
B(Star), R(15),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(15),
B(PushContext), R(16),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(18),
B(Mov), R(2), R(17),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(17), U8(2),
B(PopContext), R(16),
B(Star), R(13),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorClose), R(2), U8(1),
B(Ldar), R(13),
B(LdaSmi), I8(1),
B(Star), R(12),
B(Jump), U8(16),
B(LdaSmi), I8(-1),
B(Star), R(13),
B(Star), R(12),
B(Jump), U8(8),
B(Star), R(13),
B(LdaSmi), I8(2),
B(Star), R(12),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(11),
B(Star), R(14),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorClose), R(2), U8(1),
B(Ldar), R(14),
B(SetPendingMessage),
B(Ldar), R(12),
B(SwitchOnSmiNoFeedback), U8(21), U8(3), I8(0),
B(Jump), U8(22),
B(LdaTrue),
B(Star), R(16),
B(Mov), R(2), R(14),
B(Mov), R(12), R(15),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorResolve), R(14), U8(3),
B(Star), R(17),
B(Mov), R(2), R(15),
B(Mov), R(13), R(16),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorResolve), R(15), U8(3),
/* 50 S> */ B(Return),
B(Ldar), R(12),
B(Ldar), R(13),
/* 50 S> */ B(Return),
B(Ldar), R(12),
B(Ldar), R(13),
B(ReThrow),
B(LdaUndefined),
/* 50 S> */ B(Return),
]
constant pool: [
Smi [37],
Smi [97],
Smi [103],
Smi [399],
Smi [15],
Smi [7],
TUPLE2_TYPE,
SYMBOL_TYPE,
Smi [78],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
Smi [72],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
Smi [15],
@ -547,9 +547,9 @@ snippet: "
async function* f() { yield* g() }
f();
"
frame size: 17
frame size: 18
parameter count: 1
bytecode array length: 525
bytecode array length: 526
bytecodes: [
B(Ldar), R(0),
B(JumpIfUndefined), U8(18),
@ -582,44 +582,44 @@ bytecodes: [
B(Mov), R(6), R(3),
B(JumpConstant), U8(22),
/* 49 S> */ B(LdaGlobal), U8(7), U8(0),
B(Star), R(12),
/* 56 E> */ B(CallUndefinedReceiver0), R(12), U8(2),
B(Star), R(10),
B(LdaNamedProperty), R(10), U8(8), U8(4),
B(Star), R(13),
/* 56 E> */ B(CallUndefinedReceiver0), R(13), U8(2),
B(Star), R(11),
B(LdaNamedProperty), R(11), U8(8), U8(4),
B(JumpIfUndefined), U8(17),
B(JumpIfNull), U8(15),
B(Star), R(11),
B(CallProperty0), R(11), R(10), U8(6),
B(Star), R(12),
B(CallProperty0), R(12), R(11), U8(6),
B(JumpIfJSReceiver), U8(23),
B(CallRuntime), U16(Runtime::kThrowSymbolAsyncIteratorInvalid), R(0), U8(0),
B(LdaNamedProperty), R(10), U8(9), U8(8),
B(Star), R(11),
B(CallProperty0), R(11), R(10), U8(10),
B(Star), R(11),
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(11), U8(1),
B(LdaNamedProperty), R(11), U8(9), U8(8),
B(Star), R(12),
B(CallProperty0), R(12), R(11), U8(10),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_CreateAsyncFromSyncIterator), R(12), U8(1),
B(Star), R(8),
B(LdaNamedProperty), R(8), U8(10), U8(12),
B(Star), R(10),
B(LdaUndefined),
B(Star), R(9),
B(LdaZero),
B(Star), R(7),
B(Ldar), R(1),
B(SwitchOnSmiNoFeedback), U8(10), U8(3), I8(1),
B(SwitchOnSmiNoFeedback), U8(11), U8(3), I8(1),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(1),
B(JumpIfTrue), U8(4),
B(Abort), U8(15),
B(Ldar), R(7),
B(SwitchOnSmiNoFeedback), U8(13), U8(2), I8(1),
B(LdaNamedProperty), R(8), U8(15), U8(12),
B(Star), R(12),
B(CallProperty1), R(12), R(8), R(9), U8(14),
B(Jump), U8(111),
B(SwitchOnSmiNoFeedback), U8(14), U8(2), I8(1),
B(CallProperty1), R(10), R(8), R(9), U8(14),
B(Jump), U8(112),
B(LdaNamedProperty), R(8), U8(16), U8(16),
B(JumpIfUndefined), U8(13),
B(JumpIfNull), U8(11),
B(Star), R(12),
B(CallProperty1), R(12), R(8), R(9), U8(18),
B(Jump), U8(94),
B(Star), R(13),
B(CallProperty1), R(13), R(8), R(9), U8(18),
B(Jump), U8(95),
B(LdaZero),
B(Star), R(2),
B(Mov), R(9), R(3),
@ -627,14 +627,15 @@ bytecodes: [
B(LdaNamedProperty), R(8), U8(17), U8(20),
B(JumpIfUndefined), U8(13),
B(JumpIfNull), U8(11),
B(Star), R(12),
B(CallProperty1), R(12), R(8), R(9), U8(22),
B(Jump), U8(69),
B(Star), R(13),
B(CallProperty1), R(13), R(8), R(9), U8(22),
B(Jump), U8(70),
B(LdaNamedProperty), R(8), U8(16), U8(24),
B(Star), R(12),
B(JumpIfUndefined), U8(56),
B(JumpIfNull), U8(54),
B(CallProperty0), R(12), R(8), U8(26),
B(JumpIfUndefined), U8(59),
B(JumpIfNull), U8(57),
B(Star), R(13),
B(CallProperty0), R(13), R(8), U8(26),
B(Jump), U8(2),
B(Star), R(14),
B(Mov), R(0), R(13),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(13), U8(2),
@ -650,43 +651,43 @@ bytecodes: [
B(Ldar), R(13),
B(ReThrow),
B(Ldar), R(13),
B(Mov), R(13), R(6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(JumpIfJSReceiver), U8(9),
B(Star), R(15),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(15), U8(1),
B(CallRuntime), U16(Runtime::kThrowThrowMethodMissing), R(0), U8(0),
B(Star), R(13),
B(Mov), R(0), R(12),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(12), U8(2),
B(SuspendGenerator), R(0), R(0), U8(12), U8(3),
B(Star), R(14),
B(Mov), R(0), R(13),
B(CallJSRuntime), U8(%async_generator_await_uncaught), R(13), U8(2),
B(SuspendGenerator), R(0), R(0), U8(13), U8(3),
/* 60 S> */ B(Return),
B(ResumeGenerator), R(0), R(1), R(0), U8(12),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1),
B(ResumeGenerator), R(0), R(1), R(0), U8(13),
B(Star), R(13),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1),
B(Star), R(14),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(13),
B(TestEqualStrictNoFeedback), R(14),
B(JumpIfTrue), U8(5),
B(Ldar), R(12),
B(Ldar), R(13),
B(ReThrow),
B(Ldar), R(12),
B(Mov), R(12), R(6),
B(Ldar), R(13),
B(Mov), R(13), R(6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(18), U8(28),
B(JumpIfToBooleanTrue), U8(40),
B(LdaNamedProperty), R(6), U8(19), U8(30),
B(Star), R(15),
B(LdaFalse),
B(Star), R(16),
B(Mov), R(0), R(14),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorYield), R(14), U8(3),
B(SuspendGenerator), R(0), R(0), U8(14), U8(1),
B(LdaFalse),
B(Star), R(17),
B(Mov), R(0), R(15),
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorYield), R(15), U8(3),
B(SuspendGenerator), R(0), R(0), U8(15), U8(1),
/* 60 S> */ B(Return),
B(ResumeGenerator), R(0), R(1), R(0), U8(14),
B(ResumeGenerator), R(0), R(1), R(0), U8(15),
B(Star), R(9),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1),
B(Star), R(7),
B(JumpLoop), U8(231), I8(0),
B(JumpLoop), U8(226), I8(0),
B(LdaNamedProperty), R(6), U8(19), U8(32),
B(Star), R(8),
B(LdaSmi), I8(1),
@ -764,35 +765,35 @@ bytecodes: [
]
constant pool: [
Smi [37],
Smi [118],
Smi [118],
Smi [118],
Smi [388],
Smi [124],
Smi [124],
Smi [124],
Smi [389],
Smi [15],
Smi [7],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"],
SYMBOL_TYPE,
SYMBOL_TYPE,
Smi [216],
Smi [102],
Smi [155],
Smi [17],
Smi [42],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
Smi [211],
Smi [98],
Smi [150],
Smi [11],
Smi [36],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["throw"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [".catch"],
FIXED_ARRAY_TYPE,
Smi [409],
Smi [296],
Smi [410],
Smi [297],
Smi [6],
Smi [20],
Smi [23],
]
handlers: [
[40, 470, 478],
[43, 431, 433],
[40, 471, 479],
[43, 432, 434],
]

File diff suppressed because it is too large Load Diff

View File

@ -9,112 +9,112 @@ wrap: yes
snippet: "
for (var p of [0, 1, 2]) {}
"
frame size: 14
frame size: 15
parameter count: 1
bytecode array length: 248
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaZero),
B(Star), R(4),
B(Mov), R(context), R(10),
B(Star), R(5),
B(Mov), R(context), R(11),
B(Mov), R(context), R(12),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(1), U8(1),
B(Star), R(13),
B(CallProperty0), R(13), R(12), U8(3),
B(LdaNamedProperty), R(13), U8(1), U8(1),
B(Star), R(14),
B(CallProperty0), R(14), R(13), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(2),
/* 43 S> */ B(LdaNamedProperty), R(2), U8(2), U8(5),
B(Star), R(12),
B(CallProperty0), R(12), R(2), U8(7),
/* 48 E> */ B(LdaNamedProperty), R(2), U8(2), U8(5),
B(Star), R(3),
/* 43 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(3), U8(1),
/* 43 S> */ B(CallProperty0), R(3), R(2), U8(7),
B(Star), R(4),
/* 43 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(4), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(LdaNamedProperty), R(3), U8(3), U8(9),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(4), U8(1),
B(LdaNamedProperty), R(4), U8(3), U8(9),
B(JumpIfToBooleanTrue), U8(25),
B(LdaNamedProperty), R(3), U8(4), U8(11),
B(Star), R(5),
B(LdaNamedProperty), R(4), U8(4), U8(11),
B(Star), R(6),
B(LdaSmi), I8(2),
B(Star), R(4),
B(Mov), R(5), R(0),
B(Star), R(5),
B(Mov), R(6), R(0),
/* 34 E> */ B(StackCheck),
B(Mov), R(0), R(1),
B(LdaZero),
B(Star), R(4),
B(JumpLoop), U8(50), I8(0),
B(Star), R(5),
B(JumpLoop), U8(44), I8(0),
B(Jump), U8(36),
B(Star), R(12),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(5), U8(6),
B(PushContext), R(12),
B(Star), R(11),
B(CreateCatchContext), R(13), U8(5), U8(6),
B(PushContext), R(13),
B(Star), R(12),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(4), U8(13),
B(TestEqualStrict), R(5), U8(13),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(4),
B(Star), R(5),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kReThrow), R(13), U8(1),
B(PopContext), R(12),
B(Star), R(14),
B(CallRuntime), U16(Runtime::kReThrow), R(14), U8(1),
B(PopContext), R(13),
B(LdaSmi), I8(-1),
B(Star), R(10),
B(Star), R(9),
B(Star), R(8),
B(Jump), U8(7),
B(Star), R(9),
B(LdaZero),
B(Star), R(8),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(10),
B(LdaZero),
B(TestEqualStrict), R(4), U8(14),
B(Star), R(9),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(11),
B(LdaZero),
B(TestEqualStrict), R(5), U8(14),
B(JumpIfTrue), U8(90),
B(LdaNamedProperty), R(2), U8(7), U8(15),
B(Star), R(6),
B(Star), R(7),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(4), U8(17),
B(TestEqualStrict), R(5), U8(17),
B(JumpIfFalse), U8(47),
B(Ldar), R(6),
B(Ldar), R(7),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(144),
B(Star), R(11),
B(LdaConstant), U8(8),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kNewTypeError), R(11), U8(2),
B(LdaConstant), U8(8),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kNewTypeError), R(12), U8(2),
B(Throw),
B(Mov), R(context), R(11),
B(Mov), R(6), R(12),
B(Mov), R(2), R(13),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(12), U8(2),
B(Mov), R(context), R(12),
B(Mov), R(7), R(13),
B(Mov), R(2), R(14),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(13), U8(2),
B(Jump), U8(6),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(11),
B(Ldar), R(12),
B(Jump), U8(27),
B(Mov), R(6), R(11),
B(Mov), R(2), R(12),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(11), U8(2),
B(Star), R(7),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(7), U8(1),
B(Mov), R(7), R(12),
B(Mov), R(2), R(13),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(12), U8(2),
B(Star), R(8),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(8), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(Ldar), R(10),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1),
B(Ldar), R(11),
B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(8),
B(TestEqualStrictNoFeedback), R(9),
B(JumpIfFalse), U8(5),
B(Ldar), R(9),
B(Ldar), R(10),
B(ReThrow),
B(LdaUndefined),
/* 62 S> */ B(Return),
@ -141,7 +141,7 @@ snippet: "
var x = 'potatoes';
for (var p of x) { return p; }
"
frame size: 15
frame size: 16
parameter count: 1
bytecode array length: 258
bytecodes: [
@ -149,108 +149,108 @@ bytecodes: [
/* 42 S> */ B(LdaConstant), U8(0),
B(Star), R(0),
B(LdaZero),
B(Star), R(5),
B(Mov), R(context), R(11),
B(Star), R(6),
B(Mov), R(context), R(12),
B(Mov), R(context), R(13),
/* 68 S> */ B(LdaNamedProperty), R(0), U8(1), U8(0),
B(Star), R(14),
B(CallProperty0), R(14), R(0), U8(2),
B(Mov), R(0), R(13),
B(Star), R(15),
B(CallProperty0), R(15), R(0), U8(2),
B(Mov), R(0), R(14),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(3),
/* 63 S> */ B(LdaNamedProperty), R(3), U8(2), U8(4),
B(Star), R(13),
B(CallProperty0), R(13), R(3), U8(6),
/* 68 E> */ B(LdaNamedProperty), R(3), U8(2), U8(4),
B(Star), R(4),
/* 63 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(4), U8(1),
/* 63 S> */ B(CallProperty0), R(4), R(3), U8(6),
B(Star), R(5),
/* 63 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(5), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(4), U8(1),
B(LdaNamedProperty), R(4), U8(3), U8(8),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
B(LdaNamedProperty), R(5), U8(3), U8(8),
B(JumpIfToBooleanTrue), U8(27),
B(LdaNamedProperty), R(4), U8(4), U8(10),
B(Star), R(6),
B(LdaNamedProperty), R(5), U8(4), U8(10),
B(Star), R(7),
B(LdaSmi), I8(2),
B(Star), R(5),
B(Mov), R(6), R(1),
B(Star), R(6),
B(Mov), R(7), R(1),
/* 54 E> */ B(StackCheck),
B(Mov), R(1), R(2),
/* 73 S> */ B(LdaZero),
B(Star), R(9),
B(Mov), R(6), R(10),
B(Star), R(10),
B(Mov), R(7), R(11),
B(Jump), U8(52),
B(Jump), U8(36),
B(Star), R(13),
B(Star), R(14),
B(Ldar), R(closure),
B(CreateCatchContext), R(13), U8(5), U8(6),
B(PushContext), R(13),
B(Star), R(12),
B(CreateCatchContext), R(14), U8(5), U8(6),
B(PushContext), R(14),
B(Star), R(13),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(5), U8(12),
B(TestEqualStrict), R(6), U8(12),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(5),
B(Star), R(6),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(14),
B(CallRuntime), U16(Runtime::kReThrow), R(14), U8(1),
B(PopContext), R(13),
B(Star), R(15),
B(CallRuntime), U16(Runtime::kReThrow), R(15), U8(1),
B(PopContext), R(14),
B(LdaSmi), I8(-1),
B(Star), R(11),
B(Star), R(10),
B(Star), R(9),
B(Jump), U8(8),
B(Star), R(10),
B(Star), R(11),
B(LdaSmi), I8(1),
B(Star), R(9),
B(Star), R(10),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(11),
B(Star), R(12),
B(LdaZero),
B(TestEqualStrict), R(5), U8(13),
B(TestEqualStrict), R(6), U8(13),
B(JumpIfTrue), U8(90),
B(LdaNamedProperty), R(3), U8(7), U8(14),
B(Star), R(7),
B(Star), R(8),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(5), U8(16),
B(TestEqualStrict), R(6), U8(16),
B(JumpIfFalse), U8(47),
B(Ldar), R(7),
B(Ldar), R(8),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(144),
B(Star), R(12),
B(LdaConstant), U8(8),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kNewTypeError), R(12), U8(2),
B(LdaConstant), U8(8),
B(Star), R(14),
B(CallRuntime), U16(Runtime::kNewTypeError), R(13), U8(2),
B(Throw),
B(Mov), R(context), R(12),
B(Mov), R(7), R(13),
B(Mov), R(3), R(14),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(13), U8(2),
B(Mov), R(context), R(13),
B(Mov), R(8), R(14),
B(Mov), R(3), R(15),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(14), U8(2),
B(Jump), U8(6),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(12),
B(Ldar), R(13),
B(Jump), U8(27),
B(Mov), R(7), R(12),
B(Mov), R(3), R(13),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(12), U8(2),
B(Star), R(8),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(8), U8(1),
B(Mov), R(8), R(13),
B(Mov), R(3), R(14),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(13), U8(2),
B(Star), R(9),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(9), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1),
B(Ldar), R(11),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
B(Ldar), R(12),
B(SetPendingMessage),
B(Ldar), R(9),
B(Ldar), R(10),
B(SwitchOnSmiNoFeedback), U8(9), U8(2), I8(0),
B(Jump), U8(8),
B(Ldar), R(10),
B(Ldar), R(11),
/* 85 S> */ B(Return),
B(Ldar), R(10),
B(Ldar), R(11),
B(ReThrow),
B(LdaUndefined),
/* 85 S> */ B(Return),
@ -281,38 +281,38 @@ snippet: "
if (x == 20) break;
}
"
frame size: 14
frame size: 15
parameter count: 1
bytecode array length: 266
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaZero),
B(Star), R(4),
B(Mov), R(context), R(10),
B(Star), R(5),
B(Mov), R(context), R(11),
B(Mov), R(context), R(12),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(12),
B(LdaNamedProperty), R(12), U8(1), U8(1),
B(Star), R(13),
B(CallProperty0), R(13), R(12), U8(3),
B(LdaNamedProperty), R(13), U8(1), U8(1),
B(Star), R(14),
B(CallProperty0), R(14), R(13), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(2),
/* 43 S> */ B(LdaNamedProperty), R(2), U8(2), U8(5),
B(Star), R(12),
B(CallProperty0), R(12), R(2), U8(7),
/* 48 E> */ B(LdaNamedProperty), R(2), U8(2), U8(5),
B(Star), R(3),
/* 43 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(3), U8(1),
/* 43 S> */ B(CallProperty0), R(3), R(2), U8(7),
B(Star), R(4),
/* 43 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(4), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(LdaNamedProperty), R(3), U8(3), U8(9),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(4), U8(1),
B(LdaNamedProperty), R(4), U8(3), U8(9),
B(JumpIfToBooleanTrue), U8(43),
B(LdaNamedProperty), R(3), U8(4), U8(11),
B(Star), R(5),
B(LdaNamedProperty), R(4), U8(4), U8(11),
B(Star), R(6),
B(LdaSmi), I8(2),
B(Star), R(4),
B(Mov), R(5), R(0),
B(Star), R(5),
B(Mov), R(6), R(0),
/* 34 E> */ B(StackCheck),
B(Mov), R(0), R(1),
/* 66 S> */ B(LdaSmi), I8(10),
@ -324,77 +324,77 @@ bytecodes: [
B(JumpIfFalse), U8(4),
/* 104 S> */ B(Jump), U8(8),
B(LdaZero),
B(Star), R(4),
B(JumpLoop), U8(68), I8(0),
B(Star), R(5),
B(JumpLoop), U8(62), I8(0),
B(Jump), U8(36),
B(Star), R(12),
B(Star), R(13),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(5), U8(6),
B(PushContext), R(12),
B(Star), R(11),
B(CreateCatchContext), R(13), U8(5), U8(6),
B(PushContext), R(13),
B(Star), R(12),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(4), U8(15),
B(TestEqualStrict), R(5), U8(15),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(4),
B(Star), R(5),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kReThrow), R(13), U8(1),
B(PopContext), R(12),
B(Star), R(14),
B(CallRuntime), U16(Runtime::kReThrow), R(14), U8(1),
B(PopContext), R(13),
B(LdaSmi), I8(-1),
B(Star), R(10),
B(Star), R(9),
B(Star), R(8),
B(Jump), U8(7),
B(Star), R(9),
B(LdaZero),
B(Star), R(8),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(10),
B(LdaZero),
B(TestEqualStrict), R(4), U8(16),
B(Star), R(9),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(11),
B(LdaZero),
B(TestEqualStrict), R(5), U8(16),
B(JumpIfTrue), U8(90),
B(LdaNamedProperty), R(2), U8(7), U8(17),
B(Star), R(6),
B(Star), R(7),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(4), U8(19),
B(TestEqualStrict), R(5), U8(19),
B(JumpIfFalse), U8(47),
B(Ldar), R(6),
B(Ldar), R(7),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(144),
B(Star), R(11),
B(LdaConstant), U8(8),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kNewTypeError), R(11), U8(2),
B(LdaConstant), U8(8),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kNewTypeError), R(12), U8(2),
B(Throw),
B(Mov), R(context), R(11),
B(Mov), R(6), R(12),
B(Mov), R(2), R(13),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(12), U8(2),
B(Mov), R(context), R(12),
B(Mov), R(7), R(13),
B(Mov), R(2), R(14),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(13), U8(2),
B(Jump), U8(6),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(11),
B(Ldar), R(12),
B(Jump), U8(27),
B(Mov), R(6), R(11),
B(Mov), R(2), R(12),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(11), U8(2),
B(Star), R(7),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(7), U8(1),
B(Mov), R(7), R(12),
B(Mov), R(2), R(13),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(12), U8(2),
B(Star), R(8),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(8), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(Ldar), R(10),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1),
B(Ldar), R(11),
B(SetPendingMessage),
B(LdaZero),
B(TestEqualStrictNoFeedback), R(8),
B(TestEqualStrictNoFeedback), R(9),
B(JumpIfFalse), U8(5),
B(Ldar), R(9),
B(Ldar), R(10),
B(ReThrow),
B(LdaUndefined),
/* 113 S> */ B(Return),
@ -421,118 +421,118 @@ snippet: "
var x = { 'a': 1, 'b': 2 };
for (x['a'] of [1,2,3]) { return x['a']; }
"
frame size: 13
frame size: 14
parameter count: 1
bytecode array length: 268
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41), R(7),
B(Mov), R(7), R(0),
/* 42 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41), R(8),
B(Mov), R(8), R(0),
B(LdaZero),
B(Star), R(3),
B(Mov), R(context), R(9),
B(Star), R(4),
B(Mov), R(context), R(10),
B(Mov), R(context), R(11),
/* 77 S> */ B(CreateArrayLiteral), U8(1), U8(1), U8(37),
B(Star), R(11),
B(LdaNamedProperty), R(11), U8(2), U8(2),
B(Star), R(12),
B(CallProperty0), R(12), R(11), U8(4),
B(LdaNamedProperty), R(12), U8(2), U8(2),
B(Star), R(13),
B(CallProperty0), R(13), R(12), U8(4),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(1),
/* 68 S> */ B(LdaNamedProperty), R(1), U8(3), U8(6),
B(Star), R(11),
B(CallProperty0), R(11), R(1), U8(8),
/* 77 E> */ B(LdaNamedProperty), R(1), U8(3), U8(6),
B(Star), R(2),
/* 68 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(2), U8(1),
/* 68 S> */ B(CallProperty0), R(2), R(1), U8(8),
B(Star), R(3),
/* 68 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(3), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(2), U8(1),
B(LdaNamedProperty), R(2), U8(4), U8(10),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(LdaNamedProperty), R(3), U8(4), U8(10),
B(JumpIfToBooleanTrue), U8(30),
/* 67 E> */ B(LdaNamedProperty), R(2), U8(5), U8(12),
B(Star), R(4),
/* 67 E> */ B(LdaNamedProperty), R(3), U8(5), U8(12),
B(Star), R(5),
B(LdaSmi), I8(2),
B(Star), R(3),
B(Ldar), R(4),
B(Star), R(4),
B(Ldar), R(5),
B(StaNamedProperty), R(0), U8(6), U8(14),
/* 62 E> */ B(StackCheck),
/* 96 S> */ B(LdaNamedProperty), R(0), U8(6), U8(16),
B(Star), R(8),
B(LdaZero),
B(Star), R(7),
B(Jump), U8(52),
B(Jump), U8(36),
B(Star), R(11),
B(Ldar), R(closure),
B(CreateCatchContext), R(11), U8(7), U8(8),
B(PushContext), R(11),
B(Star), R(10),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(3), U8(18),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(3),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kReThrow), R(12), U8(1),
B(PopContext), R(11),
B(LdaSmi), I8(-1),
B(Star), R(8),
B(Star), R(7),
B(Jump), U8(8),
B(Star), R(8),
B(LdaSmi), I8(1),
B(Star), R(7),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(9),
B(LdaZero),
B(TestEqualStrict), R(3), U8(19),
B(Star), R(8),
B(Jump), U8(52),
B(Jump), U8(36),
B(Star), R(12),
B(Ldar), R(closure),
B(CreateCatchContext), R(12), U8(7), U8(8),
B(PushContext), R(12),
B(Star), R(11),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(4), U8(18),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(4),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kReThrow), R(13), U8(1),
B(PopContext), R(12),
B(LdaSmi), I8(-1),
B(Star), R(9),
B(Star), R(8),
B(Jump), U8(8),
B(Star), R(9),
B(LdaSmi), I8(1),
B(Star), R(8),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(10),
B(LdaZero),
B(TestEqualStrict), R(4), U8(19),
B(JumpIfTrue), U8(90),
B(LdaNamedProperty), R(1), U8(9), U8(20),
B(Star), R(5),
B(Star), R(6),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(3), U8(22),
B(TestEqualStrict), R(4), U8(22),
B(JumpIfFalse), U8(47),
B(Ldar), R(5),
B(Ldar), R(6),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(144),
B(Star), R(10),
B(LdaConstant), U8(10),
B(Star), R(11),
B(CallRuntime), U16(Runtime::kNewTypeError), R(10), U8(2),
B(LdaConstant), U8(10),
B(Star), R(12),
B(CallRuntime), U16(Runtime::kNewTypeError), R(11), U8(2),
B(Throw),
B(Mov), R(context), R(10),
B(Mov), R(5), R(11),
B(Mov), R(1), R(12),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(11), U8(2),
B(Mov), R(context), R(11),
B(Mov), R(6), R(12),
B(Mov), R(1), R(13),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(12), U8(2),
B(Jump), U8(6),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(10),
B(Ldar), R(11),
B(Jump), U8(27),
B(Mov), R(5), R(10),
B(Mov), R(1), R(11),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(10), U8(2),
B(Star), R(6),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(6), U8(1),
B(Mov), R(6), R(11),
B(Mov), R(1), R(12),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(11), U8(2),
B(Star), R(7),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(7), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(Ldar), R(9),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(Ldar), R(10),
B(SetPendingMessage),
B(Ldar), R(7),
B(Ldar), R(8),
B(SwitchOnSmiNoFeedback), U8(11), U8(2), I8(0),
B(Jump), U8(8),
B(Ldar), R(8),
B(Ldar), R(9),
/* 105 S> */ B(Return),
B(Ldar), R(8),
B(Ldar), R(9),
B(ReThrow),
B(LdaUndefined),
/* 105 S> */ B(Return),

File diff suppressed because it is too large Load Diff

View File

@ -119,173 +119,173 @@ snippet: "
function* f() { for (let x of [42]) yield x }
f();
"
frame size: 17
frame size: 18
parameter count: 1
bytecode array length: 374
bytecodes: [
B(Ldar), R(2),
B(JumpIfUndefined), U8(18),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetContext), R(2), U8(1),
B(PushContext), R(11),
B(PushContext), R(12),
B(RestoreGeneratorState), R(2),
B(Star), R(10),
B(Star), R(11),
B(SwitchOnSmiNoFeedback), U8(0), U8(2), I8(0),
B(Abort), U8(15),
B(LdaSmi), I8(-2),
B(Star), R(10),
B(Mov), R(closure), R(11),
B(Mov), R(this), R(12),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(11), U8(2),
B(Star), R(11),
B(Mov), R(closure), R(12),
B(Mov), R(this), R(13),
B(InvokeIntrinsic), U8(Runtime::k_CreateJSGeneratorObject), R(12), U8(2),
B(Star), R(2),
/* 11 E> */ B(StackCheck),
/* 11 E> */ B(SuspendGenerator), R(2), R(0), U8(11), U8(0),
/* 11 E> */ B(SuspendGenerator), R(2), R(0), U8(12), U8(0),
/* 44 S> */ B(Return),
B(ResumeGenerator), R(2), R(10), R(0), U8(11),
B(Star), R(11),
B(ResumeGenerator), R(2), R(11), R(0), U8(12),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(SwitchOnSmiNoFeedback), U8(2), U8(2), I8(0),
B(Ldar), R(11),
B(Ldar), R(12),
/* 11 E> */ B(Throw),
B(Ldar), R(11),
B(Ldar), R(12),
/* 44 S> */ B(Return),
B(LdaZero),
B(Star), R(6),
B(Mov), R(context), R(13),
B(Star), R(7),
B(Mov), R(context), R(14),
B(Mov), R(context), R(15),
/* 30 S> */ B(CreateArrayLiteral), U8(4), U8(0), U8(37),
B(Star), R(15),
B(LdaNamedProperty), R(15), U8(5), U8(1),
B(Star), R(16),
B(CallProperty0), R(16), R(15), U8(3),
B(LdaNamedProperty), R(16), U8(5), U8(1),
B(Star), R(17),
B(CallProperty0), R(17), R(16), U8(3),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(4),
B(Ldar), R(10),
B(SwitchOnSmiNoFeedback), U8(6), U8(1), I8(1),
/* 30 E> */ B(LdaNamedProperty), R(4), U8(6), U8(5),
B(Star), R(5),
B(Ldar), R(11),
B(SwitchOnSmiNoFeedback), U8(7), U8(1), I8(1),
B(LdaSmi), I8(-2),
/* 30 E> */ B(TestEqualStrictNoFeedback), R(10),
B(TestEqualStrictNoFeedback), R(11),
B(JumpIfTrue), U8(4),
B(Abort), U8(15),
/* 25 S> */ B(LdaNamedProperty), R(4), U8(7), U8(5),
B(Star), R(15),
B(CallProperty0), R(15), R(4), U8(7),
B(Star), R(5),
/* 25 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(5), U8(1),
/* 25 S> */ B(CallProperty0), R(5), R(4), U8(7),
B(Star), R(6),
/* 25 E> */ B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(6), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
B(LdaNamedProperty), R(5), U8(8), U8(9),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(8), U8(9),
B(JumpIfToBooleanTrue), U8(67),
B(LdaNamedProperty), R(5), U8(9), U8(11),
B(Star), R(7),
B(LdaNamedProperty), R(6), U8(9), U8(11),
B(Star), R(8),
B(LdaSmi), I8(2),
B(Star), R(6),
B(Mov), R(7), R(3),
B(Star), R(7),
B(Mov), R(8), R(3),
/* 16 E> */ B(StackCheck),
B(Mov), R(3), R(0),
/* 36 S> */ B(LdaFalse),
B(Star), R(16),
B(Mov), R(0), R(15),
B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(15), U8(2),
B(SuspendGenerator), R(2), R(0), U8(15), U8(1),
B(Star), R(17),
B(Mov), R(0), R(16),
B(InvokeIntrinsic), U8(Runtime::k_CreateIterResultObject), R(16), U8(2),
B(SuspendGenerator), R(2), R(0), U8(16), U8(1),
/* 44 S> */ B(Return),
B(ResumeGenerator), R(2), R(10), R(0), U8(15),
B(Star), R(15),
B(ResumeGenerator), R(2), R(11), R(0), U8(16),
B(Star), R(16),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(2), U8(1),
B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(0),
B(Ldar), R(15),
B(Ldar), R(16),
/* 36 E> */ B(Throw),
B(LdaZero),
B(Star), R(11),
B(Mov), R(15), R(12),
B(Star), R(12),
B(Mov), R(16), R(13),
B(Jump), U8(58),
B(LdaZero),
B(Star), R(6),
B(JumpLoop), U8(106), I8(0),
B(Star), R(7),
B(JumpLoop), U8(100), I8(0),
B(Jump), U8(36),
B(Star), R(15),
B(Star), R(16),
B(Ldar), R(closure),
B(CreateCatchContext), R(15), U8(12), U8(13),
B(PushContext), R(15),
B(Star), R(14),
B(CreateCatchContext), R(16), U8(12), U8(13),
B(PushContext), R(16),
B(Star), R(15),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(6), U8(13),
B(TestEqualStrict), R(7), U8(13),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(6),
B(Star), R(7),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(16),
B(CallRuntime), U16(Runtime::kReThrow), R(16), U8(1),
B(PopContext), R(15),
B(Star), R(17),
B(CallRuntime), U16(Runtime::kReThrow), R(17), U8(1),
B(PopContext), R(16),
B(LdaSmi), I8(-1),
B(Star), R(13),
B(Star), R(12),
B(Star), R(11),
B(Jump), U8(8),
B(Star), R(12),
B(Star), R(13),
B(LdaSmi), I8(1),
B(Star), R(11),
B(Star), R(12),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(13),
B(Star), R(14),
B(LdaZero),
B(TestEqualStrict), R(6), U8(14),
B(TestEqualStrict), R(7), U8(14),
B(JumpIfTrue), U8(90),
B(LdaNamedProperty), R(4), U8(14), U8(15),
B(Star), R(8),
B(Star), R(9),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(6), U8(17),
B(TestEqualStrict), R(7), U8(17),
B(JumpIfFalse), U8(47),
B(Ldar), R(8),
B(Ldar), R(9),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(144),
B(Star), R(14),
B(LdaConstant), U8(15),
B(Star), R(15),
B(CallRuntime), U16(Runtime::kNewTypeError), R(14), U8(2),
B(LdaConstant), U8(15),
B(Star), R(16),
B(CallRuntime), U16(Runtime::kNewTypeError), R(15), U8(2),
B(Throw),
B(Mov), R(context), R(14),
B(Mov), R(8), R(15),
B(Mov), R(4), R(16),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(15), U8(2),
B(Mov), R(context), R(15),
B(Mov), R(9), R(16),
B(Mov), R(4), R(17),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(16), U8(2),
B(Jump), U8(6),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(14),
B(Ldar), R(15),
B(Jump), U8(27),
B(Mov), R(8), R(14),
B(Mov), R(4), R(15),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(14), U8(2),
B(Star), R(9),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(9), U8(1),
B(Mov), R(9), R(15),
B(Mov), R(4), R(16),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(15), U8(2),
B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(10), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
B(Ldar), R(13),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
B(Ldar), R(14),
B(SetPendingMessage),
B(Ldar), R(11),
B(Ldar), R(12),
B(SwitchOnSmiNoFeedback), U8(16), U8(2), I8(0),
B(Jump), U8(8),
B(Ldar), R(12),
B(Ldar), R(13),
/* 44 S> */ B(Return),
B(Ldar), R(12),
B(Ldar), R(13),
B(ReThrow),
B(LdaUndefined),
/* 44 S> */ B(Return),
]
constant pool: [
Smi [29],
Smi [84],
Smi [90],
Smi [10],
Smi [7],
TUPLE2_TYPE,
SYMBOL_TYPE,
Smi [75],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
Smi [69],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
Smi [15],
@ -309,9 +309,9 @@ snippet: "
function* f() { yield* g() }
f();
"
frame size: 9
frame size: 10
parameter count: 1
bytecode array length: 251
bytecode array length: 255
bytecodes: [
B(Ldar), R(0),
B(JumpIfUndefined), U8(18),
@ -339,52 +339,54 @@ bytecodes: [
B(Ldar), R(2),
/* 54 S> */ B(Return),
/* 43 S> */ B(LdaGlobal), U8(4), U8(0),
B(Star), R(8),
/* 50 E> */ B(CallUndefinedReceiver0), R(8), U8(2),
B(Star), R(6),
B(LdaNamedProperty), R(6), U8(5), U8(4),
B(Star), R(9),
/* 50 E> */ B(CallUndefinedReceiver0), R(9), U8(2),
B(Star), R(7),
B(CallProperty0), R(7), R(6), U8(6),
B(LdaNamedProperty), R(7), U8(5), U8(4),
B(Star), R(8),
B(CallProperty0), R(8), R(7), U8(6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(4),
B(LdaNamedProperty), R(4), U8(6), U8(8),
B(Star), R(6),
B(LdaUndefined),
B(Star), R(5),
B(LdaZero),
B(Star), R(3),
B(Ldar), R(1),
B(SwitchOnSmiNoFeedback), U8(6), U8(1), I8(1),
B(SwitchOnSmiNoFeedback), U8(7), U8(1), I8(1),
B(LdaSmi), I8(-2),
B(TestEqualStrictNoFeedback), R(1),
B(JumpIfTrue), U8(4),
B(Abort), U8(15),
B(Ldar), R(3),
B(SwitchOnSmiNoFeedback), U8(7), U8(2), I8(1),
B(LdaNamedProperty), R(4), U8(9), U8(8),
B(Star), R(8),
B(CallProperty1), R(8), R(4), R(5), U8(10),
B(Jump), U8(65),
B(SwitchOnSmiNoFeedback), U8(8), U8(2), I8(1),
B(CallProperty1), R(6), R(4), R(5), U8(10),
B(Jump), U8(69),
B(LdaNamedProperty), R(4), U8(10), U8(12),
B(JumpIfUndefined), U8(13),
B(JumpIfNull), U8(11),
B(Star), R(8),
B(CallProperty1), R(8), R(4), R(5), U8(14),
B(Jump), U8(48),
B(Star), R(9),
B(CallProperty1), R(9), R(4), R(5), U8(14),
B(Jump), U8(52),
B(Ldar), R(5),
/* 54 S> */ B(Return),
B(LdaNamedProperty), R(4), U8(11), U8(16),
B(JumpIfUndefined), U8(13),
B(JumpIfNull), U8(11),
B(Star), R(8),
B(CallProperty1), R(8), R(4), R(5), U8(18),
B(Jump), U8(28),
B(Star), R(9),
B(CallProperty1), R(9), R(4), R(5), U8(18),
B(Jump), U8(32),
B(LdaNamedProperty), R(4), U8(10), U8(20),
B(Star), R(8),
B(JumpIfUndefined), U8(15),
B(JumpIfNull), U8(13),
B(CallProperty0), R(8), R(4), U8(22),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(2), U8(1),
B(JumpIfUndefined), U8(21),
B(JumpIfNull), U8(19),
B(Star), R(9),
B(CallProperty0), R(9), R(4), U8(22),
B(Jump), U8(2),
B(JumpIfJSReceiver), U8(9),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
B(CallRuntime), U16(Runtime::kThrowThrowMethodMissing), R(0), U8(0),
B(Star), R(2),
B(JumpIfJSReceiver), U8(7),
@ -392,13 +394,13 @@ bytecodes: [
B(LdaNamedProperty), R(2), U8(12), U8(24),
B(JumpIfToBooleanTrue), U8(26),
B(Ldar), R(2),
B(SuspendGenerator), R(0), R(0), U8(8), U8(1),
B(SuspendGenerator), R(0), R(0), U8(9), U8(1),
/* 54 S> */ B(Return),
B(ResumeGenerator), R(0), R(1), R(0), U8(8),
B(ResumeGenerator), R(0), R(1), R(0), U8(9),
B(Star), R(5),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1),
B(Star), R(3),
B(JumpLoop), U8(132), I8(0),
B(JumpLoop), U8(130), I8(0),
B(LdaNamedProperty), R(2), U8(13), U8(26),
B(Star), R(4),
B(LdaSmi), I8(1),
@ -411,15 +413,15 @@ bytecodes: [
]
constant pool: [
Smi [29],
Smi [85],
Smi [91],
Smi [10],
Smi [7],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"],
SYMBOL_TYPE,
Smi [117],
Smi [17],
Smi [37],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
Smi [115],
Smi [11],
Smi [31],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["throw"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],

View File

@ -9,10 +9,10 @@ function testFunction() {
var arr = |_|[1];
var all = |_|[];
for (var |_|k in |_|arr) { all.|C|push(k); }
for (var |_|k of |_|arr) { all.|C|push(k); }
for (var |C|k of |_|arr) { all.|C|push(k); }
for (var |_|k in |_|obj) { all.|C|push(k); }
for (let |_|k in |_|arr) { all.|C|push(k); }
for (let |_|k of |_|arr) { all.|C|push(k); }
for (let |C|k of |_|arr) { all.|C|push(k); }
for (let |_|k in |_|obj) { all.|C|push(k); }
var iterable = |_|{
@ -28,9 +28,9 @@ function testFunction() {
};|R|
}
};
for (var |_|k of |_|iterable) { all.|C|push(k); }
for (var |C|k of |_|iterable) { all.|C|push(k); }
|_|iterable.i = 0;
for (let |_|k of |_|iterable) { all.|C|push(k); }
for (let |C|k of |_|iterable) { all.|C|push(k); }
|R|}
(anonymous) (expr.js:0:0)

View File

@ -95,10 +95,10 @@ function testForLoop() {
|R|}
function testForOfLoop() {
for (var |_|k of |_|[]) {}
for (var |_|k of |_|[1]) |_|k;
for (var |C|k of |_|[]) {}
for (var |C|k of |_|[1]) |_|k;
var a = |_|[];
for (var |_|k of |_|a) {}
for (var |C|k of |_|a) {}
|R|}
function testForInLoop() {

View File

@ -37,6 +37,8 @@
var r2 = testMax(1, 2);
assertEquals(3, called);
// .next() is only loaded once during the iteration prologue (see
// https://github.com/tc39/ecma262/pull/988/ and v8:6861)
assertEquals(1, called);
assertEquals(2, r2);
})();

View File

@ -220,13 +220,11 @@ assertThrows('fold(sum, 0, unreachable({}))', TypeError);
assertThrows('fold(sum, 0, unreachable(false))', TypeError);
assertThrows('fold(sum, 0, unreachable(37))', TypeError);
// "next" is looked up each time.
assertThrows('fold(sum, 0, remove_next_after(integers_until(10), 5))',
TypeError);
// It is not called at any other time.
// "next" is looked up only once during the iteration prologue (see
// https://github.com/tc39/ecma262/pull/988)
assertEquals(45, fold(sum, 0, remove_next_after(integers_until(10), 5)));
assertEquals(45,
fold(sum, 0, remove_next_after(integers_until(10), 10)));
// It is not looked up too many times.
assertEquals(45,
fold(sum, 0, poison_next_after(integers_until(10), 10)));

View File

@ -376,6 +376,11 @@ testSpreadCallsStrict();
a[3] = 4;
var called = 0;
// .next method is only accessed during iteration prologue (see
// https://github.com/tc39/ecma262/pull/988)
let ArrayIteratorPrototype = Array.prototype[Symbol.iterator]().__proto__;
let ArrayIteratorPrototypeNextDescriptor =
Object.getOwnPropertyDescriptor(ArrayIteratorPrototype, 'next');
Object.defineProperty(Array.prototype, 2, {
get: function() {
var ai = a[Symbol.iterator]();
@ -384,7 +389,8 @@ testSpreadCallsStrict();
get: function() {
called++;
return original_next;
}
},
configurable: true
});
return 3;
},
@ -392,8 +398,10 @@ testSpreadCallsStrict();
});
assertEquals(10, sum(...a));
assertEquals(2, called);
assertEquals(0, called);
Object.defineProperty(ArrayIteratorPrototype, 'next',
ArrayIteratorPrototypeNextDescriptor);
Object.defineProperty(Array.prototype, 2, {});
})();
@ -430,9 +438,9 @@ testSpreadCallsStrict();
countArgs(...a);
// should be called 4 times; 3 for the values, 1 for the final
// {value: undefined, done: true} pair
assertEquals(4, called);
// .next method is only accessed during iteration prologue (see
// https://github.com/tc39/ecma262/pull/988)
assertEquals(1, called);
})();
(function testArrayIteratorPrototypeModified() {

View File

@ -48,7 +48,9 @@
var r2 = testArgumentsPoint(1, 2);
assertEquals(3, called);
// .next() is only loaded once during the iteration prologue (see
// https://github.com/tc39/ecma262/pull/988/ and v8:6861)
assertEquals(1, called);
assertInstanceof(r2, ArgumentsPoint);
assertInstanceof(r2, Point);
assertEquals(r2.x, 1);

View File

@ -341,16 +341,30 @@ function TestTypedArray(constr, elementSize, typicalElement) {
// Modified %ArrayIteratorPrototype%.next() method is honoured (v8:5699)
const ArrayIteratorPrototype = Object.getPrototypeOf([][Symbol.iterator]());
const ArrayIteratorPrototypeNextDescriptor =
Object.getOwnPropertyDescriptor(ArrayIteratorPrototype, 'next');
const ArrayIteratorPrototypeNext = ArrayIteratorPrototype.next;
ArrayIteratorPrototype.next = function() {
return { done: true };
};
genArr = new constr([1, 2, 3]);
assertEquals(0, genArr.length);
ArrayIteratorPrototype.next = ArrayIteratorPrototypeNext;
// Modified %ArrayIteratorPrototype%.next() during iteration is honoured as
// well.
// Modified %ArrayIteratorPrototype%.next() is only loaded during the iterator
// prologue.
let nextMethod = ArrayIteratorPrototypeNext;
let getNextCount = 0;
Object.defineProperty(ArrayIteratorPrototype, 'next', {
get() {
getNextCount++;
return nextMethod;
},
set(v) { nextMethod = v; },
configurable: true
});
genArr = new constr(Object.defineProperty([1, , 3], 1, {
get() {
ArrayIteratorPrototype.next = function() {
@ -359,9 +373,13 @@ function TestTypedArray(constr, elementSize, typicalElement) {
return 2;
}
}));
assertEquals(2, genArr.length);
Object.defineProperty(ArrayIteratorPrototype, 'next',
ArrayIteratorPrototypeNextDescriptor);
assertEquals(1, getNextCount);
assertEquals(3, genArr.length);
assertEquals(1, genArr[0]);
assertEquals(2, genArr[1]);
assertEquals(3, genArr[2]);
ArrayIteratorPrototype.next = ArrayIteratorPrototypeNext;
}

View File

@ -423,19 +423,8 @@
'built-ins/Proxy/ownKeys/return-duplicate-symbol-entries-throws': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=6861
'language/statements/for-of/iterator-next-reference': [FAIL],
'language/expressions/async-generator/named-yield-star-async-next': [FAIL],
'language/expressions/async-generator/yield-star-async-next': [FAIL],
'language/expressions/class/async-gen-method-yield-star-async-next': [FAIL],
'language/expressions/class/async-gen-method-static-yield-star-async-next': [FAIL],
'language/expressions/object/method-definition/async-gen-yield-star-async-next': [FAIL],
'language/statements/async-generator/yield-star-async-next': [FAIL],
'language/statements/class/async-gen-method-yield-star-async-next': [FAIL],
'language/statements/class/async-gen-method-static-yield-star-async-next': [FAIL],
'language/expressions/object/method-definition/async-gen-yield-star-sync-next': [FAIL],
'language/expressions/class/async-gen-method-static-yield-star-sync-next': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=6861
'language/expressions/async-generator/yield-star-sync-next': [FAIL],
'language/statements/class/async-gen-method-static-yield-star-sync-next': [FAIL],
'language/expressions/async-generator/named-yield-star-sync-next': [FAIL],