Commit 00a2481a authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[ignition] Move destructuring assignments to bytecode generation

Instead of de-sugaring destructuring assignment in the parser (using the
pattern rewriter), pass the Object/ArrayLiterals through to the bytecode
generator, which can desugar them in-place.

This allows us to decrease the amount of AST node creation, and improve
the generated bytecode using domain-specific knowledge. As a side effect
we partially fix an old execution ordering spec bug.

Currently only implemented for assignments, not declarations, as the
latter has some additional complexity.

Bug: v8:4951
Change-Id: I3d69d232bea2968ef20df68a74014d9e05808cfe
Reviewed-on: https://chromium-review.googlesource.com/c/1375660
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarAdam Klein <adamk@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58512}
parent 74d00a9b
...@@ -1720,10 +1720,11 @@ class VariableProxy final : public Expression { ...@@ -1720,10 +1720,11 @@ class VariableProxy final : public Expression {
friend base::ThreadedListTraits<VariableProxy>; friend base::ThreadedListTraits<VariableProxy>;
}; };
// Left-hand side can only be a property, a global or a (parameter or local) // Assignments to a property will use one of several types of property access.
// slot. // Otherwise, the assignment is to a non-property (a global, a local slot, a
enum LhsKind { // parameter slot, or a destructuring pattern).
VARIABLE, enum AssignType {
NON_PROPERTY,
NAMED_PROPERTY, NAMED_PROPERTY,
KEYED_PROPERTY, KEYED_PROPERTY,
NAMED_SUPER_PROPERTY, NAMED_SUPER_PROPERTY,
...@@ -1740,8 +1741,8 @@ class Property final : public Expression { ...@@ -1740,8 +1741,8 @@ class Property final : public Expression {
bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); } bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); }
// Returns the properties assign type. // Returns the properties assign type.
static LhsKind GetAssignType(Property* property) { static AssignType GetAssignType(Property* property) {
if (property == nullptr) return VARIABLE; if (property == nullptr) return NON_PROPERTY;
bool super_access = property->IsSuperAccess(); bool super_access = property->IsSuperAccess();
return (property->key()->IsPropertyName()) return (property->key()->IsPropertyName())
? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY) ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
......
...@@ -1249,7 +1249,7 @@ void AstPrinter::VisitProperty(Property* node) { ...@@ -1249,7 +1249,7 @@ void AstPrinter::VisitProperty(Property* node) {
IndentedScope indent(this, buf.start(), node->position()); IndentedScope indent(this, buf.start(), node->position());
Visit(node->obj()); Visit(node->obj());
LhsKind property_kind = Property::GetAssignType(node); AssignType property_kind = Property::GetAssignType(node);
if (property_kind == NAMED_PROPERTY || if (property_kind == NAMED_PROPERTY ||
property_kind == NAMED_SUPER_PROPERTY) { property_kind == NAMED_SUPER_PROPERTY) {
PrintLiteralIndented("NAME", node->key()->AsLiteral(), false); PrintLiteralIndented("NAME", node->key()->AsLiteral(), false);
......
...@@ -407,7 +407,6 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final { ...@@ -407,7 +407,6 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final {
BytecodeArrayBuilder& JumpIfTrue(ToBooleanMode mode, BytecodeLabel* label); BytecodeArrayBuilder& JumpIfTrue(ToBooleanMode mode, BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfFalse(ToBooleanMode mode, BytecodeLabel* label); BytecodeArrayBuilder& JumpIfFalse(ToBooleanMode mode, BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfNotHole(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfJSReceiver(BytecodeLabel* label); BytecodeArrayBuilder& JumpIfJSReceiver(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfNull(BytecodeLabel* label); BytecodeArrayBuilder& JumpIfNull(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfNotNull(BytecodeLabel* label); BytecodeArrayBuilder& JumpIfNotNull(BytecodeLabel* label);
......
...@@ -97,7 +97,8 @@ class BytecodeGenerator::ContextScope { ...@@ -97,7 +97,8 @@ class BytecodeGenerator::ContextScope {
class BytecodeGenerator::ControlScope { class BytecodeGenerator::ControlScope {
public: public:
explicit ControlScope(BytecodeGenerator* generator) explicit ControlScope(BytecodeGenerator* generator)
: generator_(generator), outer_(generator->execution_control()), : generator_(generator),
outer_(generator->execution_control()),
context_(generator->execution_context()) { context_(generator->execution_context()) {
generator_->set_execution_control(this); generator_->set_execution_control(this);
} }
...@@ -158,6 +159,16 @@ class BytecodeGenerator::ControlScope { ...@@ -158,6 +159,16 @@ class BytecodeGenerator::ControlScope {
// paths going through the finally-block to dispatch after leaving the block. // paths going through the finally-block to dispatch after leaving the block.
class BytecodeGenerator::ControlScope::DeferredCommands final { class BytecodeGenerator::ControlScope::DeferredCommands final {
public: public:
// Fixed value tokens for paths we know we need.
// Fallthrough is set to -1 to make it the fallthrough case of the jump table,
// where the remaining cases start at 0.
static const int kFallthroughToken = -1;
// TODO(leszeks): Rethrow being 0 makes it use up a valuable LdaZero, which
// means that other commands (such as break or return) have to use LdaSmi.
// This can very slightly bloat bytecode, so perhaps token values should all
// be shifted down by 1.
static const int kRethrowToken = 0;
DeferredCommands(BytecodeGenerator* generator, Register token_register, DeferredCommands(BytecodeGenerator* generator, Register token_register,
Register result_register) Register result_register)
: generator_(generator), : generator_(generator),
...@@ -165,8 +176,13 @@ class BytecodeGenerator::ControlScope::DeferredCommands final { ...@@ -165,8 +176,13 @@ class BytecodeGenerator::ControlScope::DeferredCommands final {
token_register_(token_register), token_register_(token_register),
result_register_(result_register), result_register_(result_register),
return_token_(-1), return_token_(-1),
async_return_token_(-1), async_return_token_(-1) {
rethrow_token_(-1) {} // There's always a rethrow path.
// TODO(leszeks): We could decouple deferred_ index and token to allow us
// to still push this lazily.
STATIC_ASSERT(kRethrowToken == 0);
deferred_.push_back({CMD_RETHROW, nullptr, kRethrowToken});
}
// One recorded control-flow command. // One recorded control-flow command.
struct Entry { struct Entry {
...@@ -211,7 +227,7 @@ class BytecodeGenerator::ControlScope::DeferredCommands final { ...@@ -211,7 +227,7 @@ class BytecodeGenerator::ControlScope::DeferredCommands final {
// Records the dispatch token to be used to identify the implicit fall-through // Records the dispatch token to be used to identify the implicit fall-through
// path at the end of a try-block into the corresponding finally-block. // path at the end of a try-block into the corresponding finally-block.
void RecordFallThroughPath() { void RecordFallThroughPath() {
builder()->LoadLiteral(Smi::FromInt(-1)); builder()->LoadLiteral(Smi::FromInt(kFallthroughToken));
builder()->StoreAccumulatorInRegister(token_register_); builder()->StoreAccumulatorInRegister(token_register_);
// Since we're not saving the accumulator in the result register, shove a // Since we're not saving the accumulator in the result register, shove a
// harmless value there instead so that it is still considered "killed" in // harmless value there instead so that it is still considered "killed" in
...@@ -277,7 +293,7 @@ class BytecodeGenerator::ControlScope::DeferredCommands final { ...@@ -277,7 +293,7 @@ class BytecodeGenerator::ControlScope::DeferredCommands final {
case CMD_ASYNC_RETURN: case CMD_ASYNC_RETURN:
return GetAsyncReturnToken(); return GetAsyncReturnToken();
case CMD_RETHROW: case CMD_RETHROW:
return GetRethrowToken(); return kRethrowToken;
default: default:
// TODO(leszeks): We could also search for entries with the same // TODO(leszeks): We could also search for entries with the same
// command and statement. // command and statement.
...@@ -299,13 +315,6 @@ class BytecodeGenerator::ControlScope::DeferredCommands final { ...@@ -299,13 +315,6 @@ class BytecodeGenerator::ControlScope::DeferredCommands final {
return async_return_token_; return async_return_token_;
} }
int GetRethrowToken() {
if (rethrow_token_ == -1) {
rethrow_token_ = GetNewTokenForCommand(CMD_RETHROW, nullptr);
}
return rethrow_token_;
}
int GetNewTokenForCommand(Command command, Statement* statement) { int GetNewTokenForCommand(Command command, Statement* statement) {
int token = static_cast<int>(deferred_.size()); int token = static_cast<int>(deferred_.size());
deferred_.push_back({command, statement, token}); deferred_.push_back({command, statement, token});
...@@ -320,7 +329,6 @@ class BytecodeGenerator::ControlScope::DeferredCommands final { ...@@ -320,7 +329,6 @@ class BytecodeGenerator::ControlScope::DeferredCommands final {
// Tokens for commands that don't need a statement. // Tokens for commands that don't need a statement.
int return_token_; int return_token_;
int async_return_token_; int async_return_token_;
int rethrow_token_;
}; };
// Scoped class for dealing with control flow reaching the function level. // Scoped class for dealing with control flow reaching the function level.
...@@ -639,9 +647,7 @@ class BytecodeGenerator::TestResultScope final : public ExpressionResultScope { ...@@ -639,9 +647,7 @@ class BytecodeGenerator::TestResultScope final : public ExpressionResultScope {
// Used when code special cases for TestResultScope and consumes any // Used when code special cases for TestResultScope and consumes any
// possible value by testing and jumping to a then/else label. // possible value by testing and jumping to a then/else label.
void SetResultConsumedByTest() { void SetResultConsumedByTest() { result_consumed_by_test_ = true; }
result_consumed_by_test_ = true;
}
bool result_consumed_by_test() { return result_consumed_by_test_; } bool result_consumed_by_test() { return result_consumed_by_test_; }
// Inverts the control flow of the operation, swapping the then and else // Inverts the control flow of the operation, swapping the then and else
...@@ -1347,8 +1353,7 @@ void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) { ...@@ -1347,8 +1353,7 @@ void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
VisitForEffect(stmt->expression()); VisitForEffect(stmt->expression());
} }
void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) { void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {}
}
void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) { void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
ConditionalControlFlowBuilder conditional_builder( ConditionalControlFlowBuilder conditional_builder(
...@@ -1552,9 +1557,9 @@ void BytecodeGenerator::VisitForInAssignment(Expression* expr) { ...@@ -1552,9 +1557,9 @@ void BytecodeGenerator::VisitForInAssignment(Expression* expr) {
// Evaluate assignment starting with the value to be stored in the // Evaluate assignment starting with the value to be stored in the
// accumulator. // accumulator.
Property* property = expr->AsProperty(); Property* property = expr->AsProperty();
LhsKind assign_type = Property::GetAssignType(property); AssignType assign_type = Property::GetAssignType(property);
switch (assign_type) { switch (assign_type) {
case VARIABLE: { case NON_PROPERTY: {
VariableProxy* proxy = expr->AsVariableProxy(); VariableProxy* proxy = expr->AsVariableProxy();
BuildVariableAssignment(proxy->var(), Token::ASSIGN, BuildVariableAssignment(proxy->var(), Token::ASSIGN,
proxy->hole_check_mode()); proxy->hole_check_mode());
...@@ -2416,20 +2421,37 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { ...@@ -2416,20 +2421,37 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
builder()->LoadAccumulatorWithRegister(literal); builder()->LoadAccumulatorWithRegister(literal);
} }
void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread, Register array, // Fill an array with values from an iterator, starting at a given index,
Register index, // optionally setting the 'done' register to true if the loop is exited because
FeedbackSlot index_slot, // the iterator is done (as opposed to e.g. the store into the array failing).
FeedbackSlot element_slot) { //
RegisterAllocationScope register_scope(this); // In pseudocode:
Register value = register_allocator()->NewRegister(); //
// loop {
builder()->SetExpressionAsStatementPosition(spread->expression()); // // Make sure we are considered 'done' if .next(), .done or .value fail.
IteratorRecord iterator = // done = true
BuildGetIteratorRecord(spread->expression(), IteratorType::kNormal); // value = iterator.next()
// if (value.done) break;
// value = value.value
// done = false
// array[index++] = value
// }
// done = true
void BytecodeGenerator::BuildFillArrayWithIterator(
IteratorRecord iterator, Register array, Register index, Register value,
Register done, FeedbackSlot next_value_slot, FeedbackSlot next_done_slot,
FeedbackSlot index_slot, FeedbackSlot element_slot) {
DCHECK(array.is_valid());
DCHECK(index.is_valid());
DCHECK(value.is_valid());
LoopBuilder loop_builder(builder(), nullptr, nullptr); LoopBuilder loop_builder(builder(), nullptr, nullptr);
loop_builder.LoopHeader(); loop_builder.LoopHeader();
if (done.is_valid()) {
builder()->LoadTrue().StoreAccumulatorInRegister(done);
}
// Call the iterator's .next() method. Break from the loop if the `done` // Call the iterator's .next() method. Break from the loop if the `done`
// property is truthy, otherwise load the value from the iterator result and // property is truthy, otherwise load the value from the iterator result and
// append the argument. // append the argument.
...@@ -2443,16 +2465,30 @@ void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread, Register array, ...@@ -2443,16 +2465,30 @@ void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread, Register array,
builder() builder()
// value = value.value // value = value.value
->LoadNamedProperty(value, ast_string_constants()->value_string(), ->LoadNamedProperty(value, ast_string_constants()->value_string(),
feedback_index(feedback_spec()->AddLoadICSlot())) feedback_index(next_value_slot));
.StoreAccumulatorInRegister(value) if (done.is_valid()) {
// done = false
builder()
->StoreAccumulatorInRegister(value)
.LoadFalse()
.StoreAccumulatorInRegister(done)
.LoadAccumulatorWithRegister(value);
}
builder()
// array[index] = value // array[index] = value
.StoreInArrayLiteral(array, index, feedback_index(element_slot)) ->StoreInArrayLiteral(array, index, feedback_index(element_slot))
// index++ // index++
.LoadAccumulatorWithRegister(index) .LoadAccumulatorWithRegister(index)
.UnaryOperation(Token::INC, feedback_index(index_slot)) .UnaryOperation(Token::INC, feedback_index(index_slot))
.StoreAccumulatorInRegister(index); .StoreAccumulatorInRegister(index);
loop_builder.BindContinueTarget(); loop_builder.BindContinueTarget();
loop_builder.JumpToHeader(loop_depth_); loop_builder.JumpToHeader(loop_depth_);
if (done.is_valid()) {
// Reaching here means that the loop was exited because of next_result.done
// being true, so set 'done' to true.
builder()->LoadTrue().StoreAccumulatorInRegister(done);
}
} }
void BytecodeGenerator::BuildCreateArrayLiteral( void BytecodeGenerator::BuildCreateArrayLiteral(
...@@ -2566,9 +2602,21 @@ void BytecodeGenerator::BuildCreateArrayLiteral( ...@@ -2566,9 +2602,21 @@ void BytecodeGenerator::BuildCreateArrayLiteral(
for (; current != end; ++current) { for (; current != end; ++current) {
Expression* subexpr = *current; Expression* subexpr = *current;
if (subexpr->IsSpread()) { if (subexpr->IsSpread()) {
RegisterAllocationScope scope(this);
builder()->SetExpressionAsStatementPosition(
subexpr->AsSpread()->expression());
VisitForAccumulatorValue(subexpr->AsSpread()->expression());
IteratorRecord iterator = BuildGetIteratorRecord(IteratorType::kNormal);
Register value = register_allocator()->NewRegister();
FeedbackSlot next_value_load_slot = feedback_spec()->AddLoadICSlot();
FeedbackSlot next_done_load_slot = feedback_spec()->AddLoadICSlot();
FeedbackSlot real_index_slot = index_slot.Get(); FeedbackSlot real_index_slot = index_slot.Get();
BuildArrayLiteralSpread(subexpr->AsSpread(), array, index, FeedbackSlot real_element_slot = element_slot.Get();
real_index_slot, element_slot.Get()); BuildFillArrayWithIterator(iterator, array, index, value,
Register::invalid_value(),
next_value_load_slot, next_done_load_slot,
real_index_slot, real_element_slot);
} else if (!subexpr->IsTheHoleLiteral()) { } else if (!subexpr->IsTheHoleLiteral()) {
// literal[index++] = subexpr // literal[index++] = subexpr
VisitForAccumulatorValue(subexpr); VisitForAccumulatorValue(subexpr);
...@@ -2905,18 +2953,18 @@ void BytecodeGenerator::BuildVariableAssignment( ...@@ -2905,18 +2953,18 @@ void BytecodeGenerator::BuildVariableAssignment(
} }
} }
void BytecodeGenerator::BuildLoadNamedProperty(Property* property, void BytecodeGenerator::BuildLoadNamedProperty(const Expression* object_expr,
Register object, Register object,
const AstRawString* name) { const AstRawString* name) {
if (ShouldOptimizeAsOneShot()) { if (ShouldOptimizeAsOneShot()) {
builder()->LoadNamedPropertyNoFeedback(object, name); builder()->LoadNamedPropertyNoFeedback(object, name);
} else { } else {
FeedbackSlot slot = GetCachedLoadICSlot(property->obj(), name); FeedbackSlot slot = GetCachedLoadICSlot(object_expr, name);
builder()->LoadNamedProperty(object, name, feedback_index(slot)); builder()->LoadNamedProperty(object, name, feedback_index(slot));
} }
} }
void BytecodeGenerator::BuildStoreNamedProperty(Property* property, void BytecodeGenerator::BuildStoreNamedProperty(const Expression* object_expr,
Register object, Register object,
const AstRawString* name) { const AstRawString* name) {
Register value; Register value;
...@@ -2928,7 +2976,7 @@ void BytecodeGenerator::BuildStoreNamedProperty(Property* property, ...@@ -2928,7 +2976,7 @@ void BytecodeGenerator::BuildStoreNamedProperty(Property* property,
if (ShouldOptimizeAsOneShot()) { if (ShouldOptimizeAsOneShot()) {
builder()->StoreNamedPropertyNoFeedback(object, name, language_mode()); builder()->StoreNamedPropertyNoFeedback(object, name, language_mode());
} else { } else {
FeedbackSlot slot = GetCachedStoreICSlot(property->obj(), name); FeedbackSlot slot = GetCachedStoreICSlot(object_expr, name);
builder()->StoreNamedProperty(object, name, feedback_index(slot), builder()->StoreNamedProperty(object, name, feedback_index(slot),
language_mode()); language_mode());
} }
...@@ -2938,35 +2986,66 @@ void BytecodeGenerator::BuildStoreNamedProperty(Property* property, ...@@ -2938,35 +2986,66 @@ void BytecodeGenerator::BuildStoreNamedProperty(Property* property,
} }
} }
void BytecodeGenerator::VisitAssignment(Assignment* expr) { // static
DCHECK(expr->target()->IsValidReferenceExpression() || BytecodeGenerator::AssignmentLhsData
(expr->op() == Token::INIT && expr->target()->IsVariableProxy() && BytecodeGenerator::AssignmentLhsData::NonProperty(Expression* expr) {
expr->target()->AsVariableProxy()->is_this())); return AssignmentLhsData(NON_PROPERTY, expr, RegisterList(), Register(),
Register object, key; Register(), nullptr, nullptr);
RegisterList super_property_args; }
const AstRawString* name; // static
BytecodeGenerator::AssignmentLhsData
BytecodeGenerator::AssignmentLhsData::NamedProperty(Expression* object_expr,
Register object,
const AstRawString* name) {
return AssignmentLhsData(NAMED_PROPERTY, nullptr, RegisterList(), object,
Register(), object_expr, name);
}
// static
BytecodeGenerator::AssignmentLhsData
BytecodeGenerator::AssignmentLhsData::KeyedProperty(Register object,
Register key) {
return AssignmentLhsData(KEYED_PROPERTY, nullptr, RegisterList(), object, key,
nullptr, nullptr);
}
// static
BytecodeGenerator::AssignmentLhsData
BytecodeGenerator::AssignmentLhsData::NamedSuperProperty(
RegisterList super_property_args) {
return AssignmentLhsData(NAMED_SUPER_PROPERTY, nullptr, super_property_args,
Register(), Register(), nullptr, nullptr);
}
// static
BytecodeGenerator::AssignmentLhsData
BytecodeGenerator::AssignmentLhsData::KeyedSuperProperty(
RegisterList super_property_args) {
return AssignmentLhsData(KEYED_SUPER_PROPERTY, nullptr, super_property_args,
Register(), Register(), nullptr, nullptr);
}
BytecodeGenerator::AssignmentLhsData BytecodeGenerator::PrepareAssignmentLhs(
Expression* lhs) {
// Left-hand side can only be a property, a global or a variable slot. // Left-hand side can only be a property, a global or a variable slot.
Property* property = expr->target()->AsProperty(); Property* property = lhs->AsProperty();
LhsKind assign_type = Property::GetAssignType(property); AssignType assign_type = Property::GetAssignType(property);
// Evaluate LHS expression. // Evaluate LHS expression.
switch (assign_type) { switch (assign_type) {
case VARIABLE: case NON_PROPERTY:
// Nothing to do to evaluate variable assignment LHS. return AssignmentLhsData::NonProperty(lhs);
break;
case NAMED_PROPERTY: { case NAMED_PROPERTY: {
object = VisitForRegisterValue(property->obj()); Register object = VisitForRegisterValue(property->obj());
name = property->key()->AsLiteral()->AsRawPropertyName(); const AstRawString* name =
break; property->key()->AsLiteral()->AsRawPropertyName();
return AssignmentLhsData::NamedProperty(property->obj(), object, name);
} }
case KEYED_PROPERTY: { case KEYED_PROPERTY: {
object = VisitForRegisterValue(property->obj()); Register object = VisitForRegisterValue(property->obj());
key = VisitForRegisterValue(property->key()); Register key = VisitForRegisterValue(property->key());
break; return AssignmentLhsData::KeyedProperty(object, key);
} }
case NAMED_SUPER_PROPERTY: { case NAMED_SUPER_PROPERTY: {
super_property_args = register_allocator()->NewRegisterList(4); RegisterList super_property_args =
register_allocator()->NewRegisterList(4);
SuperPropertyReference* super_property = SuperPropertyReference* super_property =
property->obj()->AsSuperPropertyReference(); property->obj()->AsSuperPropertyReference();
VisitForRegisterValue(super_property->this_var(), super_property_args[0]); VisitForRegisterValue(super_property->this_var(), super_property_args[0]);
...@@ -2975,81 +3054,511 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -2975,81 +3054,511 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
builder() builder()
->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName()) ->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
.StoreAccumulatorInRegister(super_property_args[2]); .StoreAccumulatorInRegister(super_property_args[2]);
break; return AssignmentLhsData::NamedSuperProperty(super_property_args);
} }
case KEYED_SUPER_PROPERTY: { case KEYED_SUPER_PROPERTY: {
super_property_args = register_allocator()->NewRegisterList(4); RegisterList super_property_args =
register_allocator()->NewRegisterList(4);
SuperPropertyReference* super_property = SuperPropertyReference* super_property =
property->obj()->AsSuperPropertyReference(); property->obj()->AsSuperPropertyReference();
VisitForRegisterValue(super_property->this_var(), super_property_args[0]); VisitForRegisterValue(super_property->this_var(), super_property_args[0]);
VisitForRegisterValue(super_property->home_object(), VisitForRegisterValue(super_property->home_object(),
super_property_args[1]); super_property_args[1]);
VisitForRegisterValue(property->key(), super_property_args[2]); VisitForRegisterValue(property->key(), super_property_args[2]);
break; return AssignmentLhsData::KeyedSuperProperty(super_property_args);
} }
} }
UNREACHABLE();
}
// Evaluate the value and potentially handle compound assignments by loading // Build the iteration finalizer called in the finally block of an iteration
// the left-hand side value and performing a binary operation. // protocol execution. This closes the iterator if needed, and suppresses any
if (expr->IsCompoundAssignment()) { // exception it throws if necessary.
switch (assign_type) { //
case VARIABLE: { // In pseudo-code, this builds:
VariableProxy* proxy = expr->target()->AsVariableProxy(); //
BuildVariableLoad(proxy->var(), proxy->hole_check_mode()); // try {
// if (!done) iterator.close()
// } catch (e) {
// if (iteration_continuation != RETHROW)
// rethrow e
// }
void BytecodeGenerator::BuildFinalizeIteration(
IteratorRecord iterator, Register done,
Register iteration_continuation_token) {
RegisterAllocationScope scope(this);
TryCatchBuilder try_control_builder(builder(), nullptr, nullptr,
HandlerTable::DESUGARING);
// Preserve the context in a dedicated register, so that it can be restored
// when the handler is entered by the stack-unwinding machinery.
// TODO(mstarzinger): Be smarter about register allocation.
Register context = register_allocator()->NewRegister();
builder()->MoveRegister(Register::current_context(), context);
// Evaluate the try-block inside a control scope. This simulates a handler
// that is intercepting 'throw' control commands.
try_control_builder.BeginTry(context);
{
ControlScopeForTryCatch scope(this, &try_control_builder);
// if (!done) iterator.close()
BytecodeLabel iterator_is_done;
builder()->LoadAccumulatorWithRegister(done).JumpIfTrue(
ToBooleanMode::kConvertToBoolean, &iterator_is_done);
BuildIteratorClose(iterator);
builder()->Bind(&iterator_is_done);
}
try_control_builder.EndTry();
// catch (e) {
// if (iteration_continuation != RETHROW)
// rethrow e
// }
// Reuse context register to store the exception.
Register close_exception = context;
builder()->StoreAccumulatorInRegister(close_exception);
BytecodeLabel suppress_close_exception;
builder()
->LoadLiteral(Smi::FromInt(ControlScope::DeferredCommands::kRethrowToken))
.CompareReference(iteration_continuation_token)
.JumpIfTrue(ToBooleanMode::kAlreadyBoolean, &suppress_close_exception)
.LoadAccumulatorWithRegister(close_exception)
.ReThrow()
.Bind(&suppress_close_exception);
try_control_builder.EndCatch();
}
// Get the default value of a destructuring target. Will mutate the
// destructuring target expression if there is a default value.
//
// For
// a = b
// in
// let {a = b} = c
// returns b and mutates the input into a.
Expression* BytecodeGenerator::GetDestructuringDefaultValue(
Expression** target) {
Expression* default_value = nullptr;
if ((*target)->IsAssignment()) {
Assignment* default_init = (*target)->AsAssignment();
DCHECK_EQ(default_init->op(), Token::ASSIGN);
default_value = default_init->value();
*target = default_init->target();
DCHECK((*target)->IsValidReferenceExpression() || (*target)->IsPattern());
}
return default_value;
}
// Convert a destructuring assignment to an array literal into a sequence of
// iterator accesses into the value being assigned (in the accumulator).
//
// [a().x, ...b] = accumulator
//
// becomes
//
// iterator = %GetIterator(accumulator)
// try {
//
// // Individual assignments read off the value from iterator.next() This gets
// // repeated per destructuring element.
// if (!done) {
// // Make sure we are considered 'done' if .next(), .done or .value fail.
// done = true
// var next_result = iterator.next()
// var tmp_done = next_result.done
// if (!tmp_done) {
// value = next_result.value
// done = false
// }
// }
// if (done)
// value = undefined
// a().x = value
//
// // A spread receives the remaining items in the iterator.
// var array = []
// var index = 0
// %FillArrayWithIterator(iterator, array, index, done)
// done = true
// b = array
//
// } catch(e) {
// iteration_continuation = RETHROW
// } finally {
// %FinalizeIteration(iterator, done, iteration_continuation)
// }
void BytecodeGenerator::BuildDestructuringArrayAssignment(
ArrayLiteral* pattern) {
RegisterAllocationScope scope(this);
Register value = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(value);
// Store the iterator in a dedicated register so that it can be closed on
// exit, and the 'done' value in a dedicated register so that it can be
// changed and accessed independently of the iteration result.
IteratorRecord iterator = BuildGetIteratorRecord(IteratorType::kNormal);
Register done = register_allocator()->NewRegister();
builder()->LoadFalse();
builder()->StoreAccumulatorInRegister(done);
TryFinallyBuilder try_control_builder(builder(), nullptr, nullptr,
HandlerTable::DESUGARING);
// Keep a continuation token and result for exceptions and returns in the
// destructuring body, so that we can close the iterator on abrupt
// completions. Same general appraoch as when visiting a TryFinallyStatement.
Register token = register_allocator()->NewRegister();
Register result = register_allocator()->NewRegister();
ControlScope::DeferredCommands commands(this, token, result);
// Preserve the context in a dedicated register, so that it can be restored
// when the handler is entered by the stack-unwinding machinery.
// TODO(mstarzinger): Be smarter about register allocation.
Register context = register_allocator()->NewRegister();
builder()->MoveRegister(Register::current_context(), context);
// Evaluate the destructuring logic inside a control scope. This simulates a
// handler that is intercepting all control commands.
try_control_builder.BeginTry(context);
{
ControlScopeForTryFinally scope(this, &try_control_builder, &commands);
Register next_result = register_allocator()->NewRegister();
FeedbackSlot next_value_load_slot = feedback_spec()->AddLoadICSlot();
FeedbackSlot next_done_load_slot = feedback_spec()->AddLoadICSlot();
Spread* spread = nullptr;
for (Expression* target : *pattern->values()) {
if (target->IsSpread()) {
spread = target->AsSpread();
break; break;
} }
case NAMED_PROPERTY: {
BuildLoadNamedProperty(property, object, name); Expression* default_value = GetDestructuringDefaultValue(&target);
break; if (!target->IsPattern()) {
builder()->SetExpressionAsStatementPosition(target);
} }
case KEYED_PROPERTY: {
// Key is already in accumulator at this point due to evaluating the AssignmentLhsData lhs_data = PrepareAssignmentLhs(target);
// LHS above.
FeedbackSlot slot = feedback_spec()->AddKeyedLoadICSlot(); // if (!done) {
builder()->LoadKeyedProperty(object, feedback_index(slot)); // // Make sure we are considered done if .next(), .done or .value fail.
break; // done = true
// var next_result = iterator.next()
// var tmp_done = next_result.done
// if (!tmp_done) {
// value = next_result.value
// done = false
// }
// }
// if (done)
// value = undefined
BytecodeLabels is_done(zone());
builder()->LoadAccumulatorWithRegister(done);
builder()->JumpIfTrue(ToBooleanMode::kConvertToBoolean, is_done.New());
builder()->LoadTrue().StoreAccumulatorInRegister(done);
BuildIteratorNext(iterator, next_result);
builder()
->LoadNamedProperty(next_result,
ast_string_constants()->done_string(),
feedback_index(next_done_load_slot))
.JumpIfTrue(ToBooleanMode::kConvertToBoolean, is_done.New())
.LoadNamedProperty(next_result,
ast_string_constants()->value_string(),
feedback_index(next_value_load_slot))
.StoreAccumulatorInRegister(next_result)
.LoadFalse()
.StoreAccumulatorInRegister(done)
.LoadAccumulatorWithRegister(next_result);
// Only do the assignment if this is not a hole (i.e. 'elided').
if (!target->IsTheHoleLiteral()) {
// [<pattern> = <init>] = <value>
// becomes (roughly)
// temp = <value>.next();
// <pattern> = temp === undefined ? <init> : temp;
BytecodeLabel do_assignment;
if (default_value) {
builder()->JumpIfNotUndefined(&do_assignment);
// Since done == true => temp == undefined, jump directly to using
// the default value for that case.
is_done.Bind(builder());
VisitForAccumulatorValue(default_value);
} else {
builder()->Jump(&do_assignment);
is_done.Bind(builder());
builder()->LoadUndefined();
}
builder()->Bind(&do_assignment);
// TODO(leszeks): This should be the position of the assignment.
BuildAssignment(lhs_data, Token::ASSIGN, LookupHoistingMode::kNormal);
} else {
DCHECK_EQ(lhs_data.assign_type(), NON_PROPERTY);
is_done.Bind(builder());
} }
case NAMED_SUPER_PROPERTY: { }
builder()->CallRuntime(Runtime::kLoadFromSuper,
super_property_args.Truncate(3)); if (spread) {
RegisterAllocationScope scope(this);
builder()->SetExpressionAsStatementPosition(spread);
// A spread is turned into a loop over the remainer of the iterator.
Expression* target = spread->expression();
AssignmentLhsData lhs_data = PrepareAssignmentLhs(target);
// var array = [];
Register array = register_allocator()->NewRegister();
builder()->CreateEmptyArrayLiteral(
feedback_index(feedback_spec()->AddLiteralSlot()));
builder()->StoreAccumulatorInRegister(array);
// var index = 0;
Register index = register_allocator()->NewRegister();
builder()->LoadLiteral(Smi::zero());
builder()->StoreAccumulatorInRegister(index);
// Fill the array with the iterator.
FeedbackSlot element_slot =
feedback_spec()->AddStoreInArrayLiteralICSlot();
FeedbackSlot index_slot = feedback_spec()->AddBinaryOpICSlot();
BuildFillArrayWithIterator(iterator, array, index, next_result, done,
next_value_load_slot, next_done_load_slot,
index_slot, element_slot);
// Assign the array to the LHS.
builder()->LoadAccumulatorWithRegister(array);
BuildAssignment(lhs_data, Token::ASSIGN, LookupHoistingMode::kNormal);
}
}
try_control_builder.EndTry();
// Record fall-through and exception cases.
commands.RecordFallThroughPath();
try_control_builder.LeaveTry();
try_control_builder.BeginHandler();
commands.RecordHandlerReThrowPath();
// Pending message object is saved on entry.
try_control_builder.BeginFinally();
Register message = context; // Reuse register.
// Clear message object as we enter the finally block.
builder()->LoadTheHole().SetPendingMessage().StoreAccumulatorInRegister(
message);
// Finish the iteration in the finally block.
BuildFinalizeIteration(iterator, done, token);
try_control_builder.EndFinally();
// Pending message object is restored on exit.
builder()->LoadAccumulatorWithRegister(message).SetPendingMessage();
// Dynamic dispatch after the finally-block.
commands.ApplyDeferredCommands();
if (!execution_result()->IsEffect()) {
builder()->LoadAccumulatorWithRegister(value);
}
}
// Convert a destructuring assignment to an object literal into a sequence of
// property accesses into the value being assigned (in the accumulator).
//
// { y, [x++]: a(), ...b.c } = value
//
// becomes
//
// var rest_runtime_callargs = new Array(3);
// rest_runtime_callargs[0] = value;
//
// rest_runtime_callargs[1] = value;
// y = value.y;
//
// var temp1 = %ToName(x++);
// rest_runtime_callargs[2] = temp1;
// a() = value[temp1];
//
// b.c = %CopyDataPropertiesWithExcludedProperties.call(rest_runtime_callargs);
void BytecodeGenerator::BuildDestructuringObjectAssignment(
ObjectLiteral* pattern) {
RegisterAllocationScope scope(this);
// if (value === null || value === undefined)
// throw new TypeError(kNonCoercible);
//
// TODO(leszeks): Eliminate check if value is known to be non-null (e.g.
// an object literal).
BytecodeLabel is_null_or_undefined, not_null_or_undefined;
builder()
->JumpIfNull(&is_null_or_undefined)
.JumpIfNotUndefined(&not_null_or_undefined);
{
builder()->Bind(&is_null_or_undefined);
// TODO(leszeks): Don't do this calculation here, but instead do it in a
// runtime method.
const AstRawString* property_name = ast_string_constants()->empty_string();
MessageTemplate msg = MessageTemplate::kNonCoercible;
for (ObjectLiteralProperty* pattern_property : *pattern->properties()) {
Expression* key = pattern_property->key();
if (key->IsPropertyName()) {
property_name = key->AsLiteral()->AsRawPropertyName();
msg = MessageTemplate::kNonCoercibleWithProperty;
break; break;
} }
case KEYED_SUPER_PROPERTY: { }
builder()->CallRuntime(Runtime::kLoadKeyedFromSuper,
super_property_args.Truncate(3)); RegisterList new_type_error_args = register_allocator()->NewRegisterList(2);
break; // throw %NewTypeError(msg, property_name, source_position)
builder()
->LoadLiteral(Smi::FromEnum(msg))
.StoreAccumulatorInRegister(new_type_error_args[0])
.LoadLiteral(property_name)
.StoreAccumulatorInRegister(new_type_error_args[1])
.CallRuntime(Runtime::kNewTypeError, new_type_error_args)
.Throw();
}
// Store the assignment value in a register.
Register value;
RegisterList rest_runtime_callargs;
if (pattern->has_rest_property()) {
rest_runtime_callargs =
register_allocator()->NewRegisterList(pattern->properties()->length());
value = rest_runtime_callargs[0];
} else {
value = register_allocator()->NewRegister();
}
builder()->Bind(&not_null_or_undefined).StoreAccumulatorInRegister(value);
int i = 0;
for (ObjectLiteralProperty* pattern_property : *pattern->properties()) {
RegisterAllocationScope scope(this);
// The key of the pattern becomes the key into the RHS value, and the value
// of the pattern becomes the target of the assignment.
//
// e.g. { a: b } = o becomes b = o.a
Expression* pattern_key = pattern_property->key();
Expression* target = pattern_property->value();
Expression* default_value = GetDestructuringDefaultValue(&target);
if (!target->IsPattern()) {
builder()->SetExpressionAsStatementPosition(target);
}
// Calculate this property's key into the assignment RHS value, additionally
// storing the key for rest_runtime_callargs if needed.
//
// The RHS is accessed using the key either by LoadNamedProperty (if
// value_name is valid) or by LoadKeyedProperty (otherwise).
const AstRawString* value_name = nullptr;
Register value_key;
if (pattern_property->kind() != ObjectLiteralProperty::Kind::SPREAD) {
if (pattern_key->IsPropertyName()) {
value_name = pattern_key->AsLiteral()->AsRawPropertyName();
}
if (pattern->has_rest_property() || !value_name) {
if (pattern->has_rest_property()) {
value_key = rest_runtime_callargs[i + 1];
} else {
value_key = register_allocator()->NewRegister();
}
if (pattern_property->is_computed_name()) {
// { [a()]: b().x } = c
// becomes
// var tmp = a()
// b().x = c[tmp]
DCHECK(!pattern_key->IsPropertyName() ||
!pattern_key->IsNumberLiteral());
VisitForAccumulatorValue(pattern_key);
builder()->ToName(value_key);
} else {
// We only need the key for non-computed properties when it is numeric
// or is being saved for the rest_runtime_callargs.
DCHECK(
pattern_key->IsNumberLiteral() ||
(pattern->has_rest_property() && pattern_key->IsPropertyName()));
VisitForRegisterValue(pattern_key, value_key);
}
} }
} }
BinaryOperation* binop = expr->AsCompoundAssignment()->binary_operation();
FeedbackSlot slot = feedback_spec()->AddBinaryOpICSlot(); AssignmentLhsData lhs_data = PrepareAssignmentLhs(target);
if (expr->value()->IsSmiLiteral()) {
builder()->BinaryOperationSmiLiteral( // Get the value from the RHS.
binop->op(), expr->value()->AsLiteral()->AsSmiLiteral(), if (pattern_property->kind() == ObjectLiteralProperty::Kind::SPREAD) {
feedback_index(slot)); DCHECK_EQ(i, pattern->properties()->length() - 1);
DCHECK(!value_key.is_valid());
DCHECK_NULL(value_name);
builder()->CallRuntime(Runtime::kCopyDataPropertiesWithExcludedProperties,
rest_runtime_callargs);
} else if (value_name) {
builder()->LoadNamedProperty(
value, value_name, feedback_index(feedback_spec()->AddLoadICSlot()));
} else { } else {
Register old_value = register_allocator()->NewRegister(); DCHECK(value_key.is_valid());
builder()->StoreAccumulatorInRegister(old_value); builder()->LoadAccumulatorWithRegister(value_key).LoadKeyedProperty(
VisitForAccumulatorValue(expr->value()); value, feedback_index(feedback_spec()->AddKeyedLoadICSlot()));
builder()->BinaryOperation(binop->op(), old_value, feedback_index(slot));
} }
} else {
VisitForAccumulatorValue(expr->value()); // {<pattern> = <init>} = <value>
// becomes
// temp = <value>;
// <pattern> = temp === undefined ? <init> : temp;
if (default_value) {
BytecodeLabel value_not_undefined;
builder()->JumpIfNotUndefined(&value_not_undefined);
VisitForAccumulatorValue(default_value);
builder()->Bind(&value_not_undefined);
}
BuildAssignment(lhs_data, Token::ASSIGN, LookupHoistingMode::kNormal);
i++;
} }
// Store the value. if (!execution_result()->IsEffect()) {
builder()->SetExpressionPosition(expr); builder()->LoadAccumulatorWithRegister(value);
switch (assign_type) { }
case VARIABLE: { }
// TODO(oth): The BuildVariableAssignment() call is hard to reason about.
// Is the value in the accumulator safe? Yes, but scary. void BytecodeGenerator::BuildAssignment(
VariableProxy* proxy = expr->target()->AsVariableProxy(); const AssignmentLhsData& lhs_data, Token::Value op,
BuildVariableAssignment(proxy->var(), expr->op(), LookupHoistingMode lookup_hoisting_mode) {
proxy->hole_check_mode(), // Assign the value to the LHS.
expr->lookup_hoisting_mode()); switch (lhs_data.assign_type()) {
case NON_PROPERTY: {
if (ObjectLiteral* pattern = lhs_data.expr()->AsObjectLiteral()) {
// Split object literals into destructuring.
DCHECK_EQ(op, Token::ASSIGN);
DCHECK_EQ(lookup_hoisting_mode, LookupHoistingMode::kNormal);
BuildDestructuringObjectAssignment(pattern);
} else if (ArrayLiteral* pattern = lhs_data.expr()->AsArrayLiteral()) {
// Split object literals into destructuring.
DCHECK_EQ(op, Token::ASSIGN);
DCHECK_EQ(lookup_hoisting_mode, LookupHoistingMode::kNormal);
BuildDestructuringArrayAssignment(pattern);
} else {
DCHECK(lhs_data.expr()->IsVariableProxy());
VariableProxy* proxy = lhs_data.expr()->AsVariableProxy();
BuildVariableAssignment(proxy->var(), op, proxy->hole_check_mode(),
lookup_hoisting_mode);
}
break; break;
} }
case NAMED_PROPERTY: { case NAMED_PROPERTY: {
BuildStoreNamedProperty(property, object, name); BuildStoreNamedProperty(lhs_data.object_expr(), lhs_data.object(),
lhs_data.name());
break; break;
} }
case KEYED_PROPERTY: { case KEYED_PROPERTY: {
...@@ -3059,8 +3568,8 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -3059,8 +3568,8 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
value = register_allocator()->NewRegister(); value = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(value); builder()->StoreAccumulatorInRegister(value);
} }
builder()->StoreKeyedProperty(object, key, feedback_index(slot), builder()->StoreKeyedProperty(lhs_data.object(), lhs_data.key(),
language_mode()); feedback_index(slot), language_mode());
if (!execution_result()->IsEffect()) { if (!execution_result()->IsEffect()) {
builder()->LoadAccumulatorWithRegister(value); builder()->LoadAccumulatorWithRegister(value);
} }
...@@ -3068,21 +3577,78 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) { ...@@ -3068,21 +3577,78 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
} }
case NAMED_SUPER_PROPERTY: { case NAMED_SUPER_PROPERTY: {
builder() builder()
->StoreAccumulatorInRegister(super_property_args[3]) ->StoreAccumulatorInRegister(lhs_data.super_property_args()[3])
.CallRuntime(StoreToSuperRuntimeId(), super_property_args); .CallRuntime(StoreToSuperRuntimeId(), lhs_data.super_property_args());
break; break;
} }
case KEYED_SUPER_PROPERTY: { case KEYED_SUPER_PROPERTY: {
builder() builder()
->StoreAccumulatorInRegister(super_property_args[3]) ->StoreAccumulatorInRegister(lhs_data.super_property_args()[3])
.CallRuntime(StoreKeyedToSuperRuntimeId(), super_property_args); .CallRuntime(StoreKeyedToSuperRuntimeId(),
lhs_data.super_property_args());
break; break;
} }
} }
} }
void BytecodeGenerator::VisitAssignment(Assignment* expr) {
AssignmentLhsData lhs_data = PrepareAssignmentLhs(expr->target());
VisitForAccumulatorValue(expr->value());
builder()->SetExpressionPosition(expr);
BuildAssignment(lhs_data, expr->op(), expr->lookup_hoisting_mode());
}
void BytecodeGenerator::VisitCompoundAssignment(CompoundAssignment* expr) { void BytecodeGenerator::VisitCompoundAssignment(CompoundAssignment* expr) {
VisitAssignment(expr); AssignmentLhsData lhs_data = PrepareAssignmentLhs(expr->target());
// Evaluate the value and potentially handle compound assignments by loading
// the left-hand side value and performing a binary operation.
switch (lhs_data.assign_type()) {
case NON_PROPERTY: {
VariableProxy* proxy = expr->target()->AsVariableProxy();
BuildVariableLoad(proxy->var(), proxy->hole_check_mode());
break;
}
case NAMED_PROPERTY: {
BuildLoadNamedProperty(lhs_data.object_expr(), lhs_data.object(),
lhs_data.name());
break;
}
case KEYED_PROPERTY: {
FeedbackSlot slot = feedback_spec()->AddKeyedLoadICSlot();
builder()
->LoadAccumulatorWithRegister(lhs_data.key())
.LoadKeyedProperty(lhs_data.object(), feedback_index(slot));
break;
}
case NAMED_SUPER_PROPERTY: {
builder()->CallRuntime(Runtime::kLoadFromSuper,
lhs_data.super_property_args().Truncate(3));
break;
}
case KEYED_SUPER_PROPERTY: {
builder()->CallRuntime(Runtime::kLoadKeyedFromSuper,
lhs_data.super_property_args().Truncate(3));
break;
}
}
BinaryOperation* binop = expr->AsCompoundAssignment()->binary_operation();
FeedbackSlot slot = feedback_spec()->AddBinaryOpICSlot();
if (expr->value()->IsSmiLiteral()) {
builder()->BinaryOperationSmiLiteral(
binop->op(), expr->value()->AsLiteral()->AsSmiLiteral(),
feedback_index(slot));
} else {
Register old_value = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(old_value);
VisitForAccumulatorValue(expr->value());
builder()->BinaryOperation(binop->op(), old_value, feedback_index(slot));
}
builder()->SetExpressionPosition(expr);
BuildAssignment(lhs_data, expr->op(), expr->lookup_hoisting_mode());
} }
// Suspends the generator to resume at the next suspend_id, with output stored // Suspends the generator to resume at the next suspend_id, with output stored
...@@ -3132,7 +3698,7 @@ void BytecodeGenerator::VisitYield(Yield* expr) { ...@@ -3132,7 +3698,7 @@ void BytecodeGenerator::VisitYield(Yield* expr) {
builder() builder()
->StoreAccumulatorInRegister(args[0]) // value ->StoreAccumulatorInRegister(args[0]) // value
.LoadFalse() .LoadFalse()
.StoreAccumulatorInRegister(args[1]) // done .StoreAccumulatorInRegister(args[1]) // done
.CallRuntime(Runtime::kInlineCreateIterResultObject, args); .CallRuntime(Runtime::kInlineCreateIterResultObject, args);
} }
} }
...@@ -3260,8 +3826,8 @@ void BytecodeGenerator::VisitYieldStar(YieldStar* expr) { ...@@ -3260,8 +3826,8 @@ void BytecodeGenerator::VisitYieldStar(YieldStar* expr) {
{ {
RegisterAllocationScope register_scope(this); RegisterAllocationScope register_scope(this);
RegisterList iterator_and_input = register_allocator()->NewRegisterList(2); RegisterList iterator_and_input = register_allocator()->NewRegisterList(2);
VisitForAccumulatorValue(expr->expression());
IteratorRecord iterator = BuildGetIteratorRecord( IteratorRecord iterator = BuildGetIteratorRecord(
expr->expression(),
register_allocator()->NewRegister() /* next method */, register_allocator()->NewRegister() /* next method */,
iterator_and_input[0], iterator_type); iterator_and_input[0], iterator_type);
...@@ -3495,15 +4061,15 @@ void BytecodeGenerator::VisitThrow(Throw* expr) { ...@@ -3495,15 +4061,15 @@ void BytecodeGenerator::VisitThrow(Throw* expr) {
} }
void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* property) { void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* property) {
LhsKind property_kind = Property::GetAssignType(property); AssignType property_kind = Property::GetAssignType(property);
switch (property_kind) { switch (property_kind) {
case VARIABLE: case NON_PROPERTY:
UNREACHABLE(); UNREACHABLE();
case NAMED_PROPERTY: { case NAMED_PROPERTY: {
builder()->SetExpressionPosition(property); builder()->SetExpressionPosition(property);
const AstRawString* name = const AstRawString* name =
property->key()->AsLiteral()->AsRawPropertyName(); property->key()->AsLiteral()->AsRawPropertyName();
BuildLoadNamedProperty(property, obj, name); BuildLoadNamedProperty(property->obj(), obj, name);
break; break;
} }
case KEYED_PROPERTY: { case KEYED_PROPERTY: {
...@@ -3569,7 +4135,7 @@ void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property, ...@@ -3569,7 +4135,7 @@ void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property,
} }
void BytecodeGenerator::VisitProperty(Property* expr) { void BytecodeGenerator::VisitProperty(Property* expr) {
LhsKind property_kind = Property::GetAssignType(expr); AssignType property_kind = Property::GetAssignType(expr);
if (property_kind != NAMED_SUPER_PROPERTY && if (property_kind != NAMED_SUPER_PROPERTY &&
property_kind != KEYED_SUPER_PROPERTY) { property_kind != KEYED_SUPER_PROPERTY) {
Register obj = VisitForRegisterValue(expr->obj()); Register obj = VisitForRegisterValue(expr->obj());
...@@ -4005,7 +4571,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -4005,7 +4571,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
// Left-hand side can only be a property, a global or a variable slot. // Left-hand side can only be a property, a global or a variable slot.
Property* property = expr->expression()->AsProperty(); Property* property = expr->expression()->AsProperty();
LhsKind assign_type = Property::GetAssignType(property); AssignType assign_type = Property::GetAssignType(property);
bool is_postfix = expr->is_postfix() && !execution_result()->IsEffect(); bool is_postfix = expr->is_postfix() && !execution_result()->IsEffect();
...@@ -4014,7 +4580,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -4014,7 +4580,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
RegisterList super_property_args; RegisterList super_property_args;
const AstRawString* name; const AstRawString* name;
switch (assign_type) { switch (assign_type) {
case VARIABLE: { case NON_PROPERTY: {
VariableProxy* proxy = expr->expression()->AsVariableProxy(); VariableProxy* proxy = expr->expression()->AsVariableProxy();
BuildVariableLoadForAccumulatorValue(proxy->var(), BuildVariableLoadForAccumulatorValue(proxy->var(),
proxy->hole_check_mode()); proxy->hole_check_mode());
...@@ -4082,7 +4648,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -4082,7 +4648,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
// Store the value. // Store the value.
builder()->SetExpressionPosition(expr); builder()->SetExpressionPosition(expr);
switch (assign_type) { switch (assign_type) {
case VARIABLE: { case NON_PROPERTY: {
VariableProxy* proxy = expr->expression()->AsVariableProxy(); VariableProxy* proxy = expr->expression()->AsVariableProxy();
BuildVariableAssignment(proxy->var(), expr->op(), BuildVariableAssignment(proxy->var(), expr->op(),
proxy->hole_check_mode()); proxy->hole_check_mode());
...@@ -4305,14 +4871,11 @@ void BytecodeGenerator::VisitImportCallExpression(ImportCallExpression* expr) { ...@@ -4305,14 +4871,11 @@ void BytecodeGenerator::VisitImportCallExpression(ImportCallExpression* expr) {
.CallRuntime(Runtime::kDynamicImportCall, args); .CallRuntime(Runtime::kDynamicImportCall, args);
} }
void BytecodeGenerator::BuildGetIterator(Expression* iterable, void BytecodeGenerator::BuildGetIterator(IteratorType hint) {
IteratorType hint) {
RegisterList args = register_allocator()->NewRegisterList(1); RegisterList args = register_allocator()->NewRegisterList(1);
Register method = register_allocator()->NewRegister(); Register method = register_allocator()->NewRegister();
Register obj = args[0]; Register obj = args[0];
VisitForAccumulatorValue(iterable);
if (hint == IteratorType::kAsync) { if (hint == IteratorType::kAsync) {
// Set method to GetMethod(obj, @@asyncIterator) // Set method to GetMethod(obj, @@asyncIterator)
builder()->StoreAccumulatorInRegister(obj).LoadAsyncIteratorProperty( builder()->StoreAccumulatorInRegister(obj).LoadAsyncIteratorProperty(
...@@ -4374,9 +4937,9 @@ void BytecodeGenerator::BuildGetIterator(Expression* iterable, ...@@ -4374,9 +4937,9 @@ void BytecodeGenerator::BuildGetIterator(Expression* iterable,
// Returns an IteratorRecord which is valid for the lifetime of the current // Returns an IteratorRecord which is valid for the lifetime of the current
// register_allocation_scope. // register_allocation_scope.
BytecodeGenerator::IteratorRecord BytecodeGenerator::BuildGetIteratorRecord( BytecodeGenerator::IteratorRecord BytecodeGenerator::BuildGetIteratorRecord(
Expression* iterable, Register next, Register object, IteratorType hint) { Register next, Register object, IteratorType hint) {
DCHECK(next.is_valid() && object.is_valid()); DCHECK(next.is_valid() && object.is_valid());
BuildGetIterator(iterable, hint); BuildGetIterator(hint);
builder() builder()
->StoreAccumulatorInRegister(object) ->StoreAccumulatorInRegister(object)
...@@ -4387,10 +4950,10 @@ BytecodeGenerator::IteratorRecord BytecodeGenerator::BuildGetIteratorRecord( ...@@ -4387,10 +4950,10 @@ BytecodeGenerator::IteratorRecord BytecodeGenerator::BuildGetIteratorRecord(
} }
BytecodeGenerator::IteratorRecord BytecodeGenerator::BuildGetIteratorRecord( BytecodeGenerator::IteratorRecord BytecodeGenerator::BuildGetIteratorRecord(
Expression* iterable, IteratorType hint) { IteratorType hint) {
Register next = register_allocator()->NewRegister(); Register next = register_allocator()->NewRegister();
Register object = register_allocator()->NewRegister(); Register object = register_allocator()->NewRegister();
return BuildGetIteratorRecord(iterable, next, object, hint); return BuildGetIteratorRecord(next, object, hint);
} }
void BytecodeGenerator::BuildIteratorNext(const IteratorRecord& iterator, void BytecodeGenerator::BuildIteratorNext(const IteratorRecord& iterator,
...@@ -4458,7 +5021,8 @@ void BytecodeGenerator::BuildIteratorClose(const IteratorRecord& iterator, ...@@ -4458,7 +5021,8 @@ void BytecodeGenerator::BuildIteratorClose(const IteratorRecord& iterator,
void BytecodeGenerator::VisitGetIterator(GetIterator* expr) { void BytecodeGenerator::VisitGetIterator(GetIterator* expr) {
builder()->SetExpressionPosition(expr); builder()->SetExpressionPosition(expr);
BuildGetIterator(expr->iterable(), expr->hint()); VisitForAccumulatorValue(expr->iterable());
BuildGetIterator(expr->hint());
} }
void BytecodeGenerator::VisitGetTemplateObject(GetTemplateObject* expr) { void BytecodeGenerator::VisitGetTemplateObject(GetTemplateObject* expr) {
......
...@@ -70,6 +70,79 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { ...@@ -70,6 +70,79 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
enum class TestFallthrough { kThen, kElse, kNone }; enum class TestFallthrough { kThen, kElse, kNone };
enum class TypeHint { kAny, kBoolean, kString }; enum class TypeHint { kAny, kBoolean, kString };
// An assignment has to evaluate its LHS before its RHS, but has to assign to
// the LHS after both evaluations are done. This class stores the data
// computed in the LHS evaulation that has to live across the RHS evaluation,
// and is used in the actual LHS assignment.
class AssignmentLhsData {
public:
static AssignmentLhsData NonProperty(Expression* expr);
static AssignmentLhsData NamedProperty(Expression* object_expr,
Register object,
const AstRawString* name);
static AssignmentLhsData KeyedProperty(Register object, Register key);
static AssignmentLhsData NamedSuperProperty(
RegisterList super_property_args);
static AssignmentLhsData KeyedSuperProperty(
RegisterList super_property_args);
AssignType assign_type() const { return assign_type_; }
Expression* expr() const {
DCHECK_EQ(assign_type_, NON_PROPERTY);
return expr_;
}
Expression* object_expr() const {
DCHECK_EQ(assign_type_, NAMED_PROPERTY);
return object_expr_;
}
Register object() const {
DCHECK(assign_type_ == NAMED_PROPERTY || assign_type_ == KEYED_PROPERTY);
return object_;
}
Register key() const {
DCHECK_EQ(assign_type_, KEYED_PROPERTY);
return key_;
}
const AstRawString* name() const {
DCHECK_EQ(assign_type_, NAMED_PROPERTY);
return name_;
}
RegisterList super_property_args() const {
DCHECK(assign_type_ == NAMED_SUPER_PROPERTY ||
assign_type_ == KEYED_SUPER_PROPERTY);
return super_property_args_;
}
private:
AssignmentLhsData(AssignType assign_type, Expression* expr,
RegisterList super_property_args, Register object,
Register key, Expression* object_expr,
const AstRawString* name)
: assign_type_(assign_type),
expr_(expr),
super_property_args_(super_property_args),
object_(object),
key_(key),
object_expr_(object_expr),
name_(name) {}
AssignType assign_type_;
// Different assignment types use different fields:
//
// NON_PROPERTY: expr
// NAMED_PROPERTY: object_expr, object, name
// KEYED_PROPERTY: object, key
// NAMED_SUPER_PROPERTY: super_property_args
// KEYED_SUPER_PROPERT: super_property_args
Expression* expr_;
RegisterList super_property_args_;
Register object_;
Register key_;
Expression* object_expr_;
const AstRawString* name_;
};
void GenerateBytecodeBody(); void GenerateBytecodeBody();
void AllocateDeferredConstants(Isolate* isolate, Handle<Script> script); void AllocateDeferredConstants(Isolate* isolate, Handle<Script> script);
...@@ -122,9 +195,17 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { ...@@ -122,9 +195,17 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void VisitPropertyLoadForRegister(Register obj, Property* expr, void VisitPropertyLoadForRegister(Register obj, Property* expr,
Register destination); Register destination);
void BuildLoadNamedProperty(Property* property, Register object, AssignmentLhsData PrepareAssignmentLhs(Expression* lhs);
void BuildAssignment(const AssignmentLhsData& data, Token::Value op,
LookupHoistingMode lookup_hoisting_mode);
Expression* GetDestructuringDefaultValue(Expression** target);
void BuildDestructuringArrayAssignment(ArrayLiteral* pattern);
void BuildDestructuringObjectAssignment(ObjectLiteral* pattern);
void BuildLoadNamedProperty(const Expression* object_expr, Register object,
const AstRawString* name); const AstRawString* name);
void BuildStoreNamedProperty(Property* property, Register object, void BuildStoreNamedProperty(const Expression* object_expr, Register object,
const AstRawString* name); const AstRawString* name);
void BuildVariableLoad(Variable* variable, HoleCheckMode hole_check_mode, void BuildVariableLoad(Variable* variable, HoleCheckMode hole_check_mode,
...@@ -160,19 +241,20 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { ...@@ -160,19 +241,20 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void BuildAwait(Expression* await_expr); void BuildAwait(Expression* await_expr);
void BuildGetIterator(Expression* iterable, IteratorType hint); void BuildFinalizeIteration(IteratorRecord iterator, Register done,
Register iteration_continuation_token);
void BuildGetIterator(IteratorType hint);
// Create an IteratorRecord with pre-allocated registers holding the next // Create an IteratorRecord with pre-allocated registers holding the next
// method and iterator object. // method and iterator object.
IteratorRecord BuildGetIteratorRecord(Expression* iterable, IteratorRecord BuildGetIteratorRecord(Register iterator_next,
Register iterator_next,
Register iterator_object, Register iterator_object,
IteratorType hint); IteratorType hint);
// Create an IteratorRecord allocating new registers to hold the next method // Create an IteratorRecord allocating new registers to hold the next method
// and iterator object. // and iterator object.
IteratorRecord BuildGetIteratorRecord(Expression* iterable, IteratorRecord BuildGetIteratorRecord(IteratorType hint);
IteratorType hint);
void BuildIteratorNext(const IteratorRecord& iterator, Register next_result); void BuildIteratorNext(const IteratorRecord& iterator, Register next_result);
void BuildIteratorClose(const IteratorRecord& iterator, void BuildIteratorClose(const IteratorRecord& iterator,
Expression* expr = nullptr); Expression* expr = nullptr);
...@@ -181,9 +263,12 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { ...@@ -181,9 +263,12 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
BytecodeLabel* if_called, BytecodeLabel* if_called,
BytecodeLabels* if_notcalled); BytecodeLabels* if_notcalled);
void BuildArrayLiteralSpread(Spread* spread, Register array, Register index, void BuildFillArrayWithIterator(IteratorRecord iterator, Register array,
FeedbackSlot index_slot, Register index, Register value, Register done,
FeedbackSlot element_slot); FeedbackSlot next_value_slot,
FeedbackSlot next_done_slot,
FeedbackSlot index_slot,
FeedbackSlot element_slot);
// Create Array literals. |expr| can be nullptr, but if provided, // Create Array literals. |expr| can be nullptr, but if provided,
// a boilerplate will be used to create an initial array for elements // a boilerplate will be used to create an initial array for elements
// before the first spread. // before the first spread.
......
...@@ -137,18 +137,39 @@ void Parser::DeclareAndInitializeVariables( ...@@ -137,18 +137,39 @@ void Parser::DeclareAndInitializeVariables(
this, block, declaration_descriptor, declaration, names); this, block, declaration_descriptor, declaration, names);
} }
namespace {
// Lightweight visitor for the case where bytecode does the desugaring.
void MarkVariablesWritten(Expression* expr) {
if (expr->IsVariableProxy()) {
expr->AsVariableProxy()->set_is_assigned();
} else if (expr->IsObjectLiteral()) {
for (ObjectLiteralProperty* prop : *expr->AsObjectLiteral()->properties()) {
MarkVariablesWritten(prop->value());
}
} else if (expr->IsArrayLiteral()) {
for (Expression* value : *expr->AsArrayLiteral()->values()) {
MarkVariablesWritten(value);
}
} else if (expr->IsSpread()) {
MarkVariablesWritten(expr->AsSpread()->expression());
} else if (expr->IsAssignment()) {
MarkVariablesWritten(expr->AsAssignment()->target());
}
}
} // namespace
void Parser::RewriteDestructuringAssignment(RewritableExpression* to_rewrite) { void Parser::RewriteDestructuringAssignment(RewritableExpression* to_rewrite) {
DCHECK(!to_rewrite->is_rewritten()); DCHECK(!to_rewrite->is_rewritten());
Assignment* assignment = to_rewrite->expression()->AsAssignment(); Assignment* assignment = to_rewrite->expression()->AsAssignment();
Expression* result = DCHECK_NOT_NULL(assignment);
PatternRewriter::RewriteDestructuringAssignment(this, assignment); MarkVariablesWritten(assignment->target());
to_rewrite->Rewrite(result);
} }
Expression* Parser::RewriteDestructuringAssignment(Assignment* assignment) { Expression* Parser::RewriteDestructuringAssignment(Assignment* assignment) {
DCHECK_NOT_NULL(assignment); DCHECK_NOT_NULL(assignment);
DCHECK_EQ(Token::ASSIGN, assignment->op()); DCHECK_EQ(Token::ASSIGN, assignment->op());
return PatternRewriter::RewriteDestructuringAssignment(this, assignment); MarkVariablesWritten(assignment->target());
return assignment;
} }
void PatternRewriter::DeclareAndInitializeVariables( void PatternRewriter::DeclareAndInitializeVariables(
......
...@@ -143,7 +143,7 @@ snippet: " ...@@ -143,7 +143,7 @@ snippet: "
" "
frame size: 8 frame size: 8
parameter count: 1 parameter count: 1
bytecode array length: 86 bytecode array length: 84
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
...@@ -152,28 +152,27 @@ bytecodes: [ ...@@ -152,28 +152,27 @@ bytecodes: [
B(Star), R(2), B(Star), R(2),
B(LdaConstant), U8(2), B(LdaConstant), U8(2),
/* 67 S> */ B(Star), R(1), /* 67 S> */ B(Star), R(1),
B(LdaNamedProperty), R(0), U8(3), U8(5), B(LdaNamedProperty), R(0), U8(3), U8(2),
B(Star), R(7), B(Star), R(6),
B(CallProperty0), R(7), R(0), U8(7), B(CallProperty0), R(6), R(0), U8(4),
B(Mov), R(0), R(6), B(Mov), R(0), R(5),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(5),
B(LdaNamedProperty), R(5), U8(4), U8(9),
B(Star), R(4), B(Star), R(4),
B(CallProperty0), R(4), R(5), U8(11), B(LdaNamedProperty), R(4), U8(4), U8(6),
B(Star), R(3), B(Star), R(3),
B(CallProperty0), R(3), R(4), U8(15),
B(Star), R(7),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(LdaNamedProperty), R(3), U8(5), U8(13), B(LdaNamedProperty), R(7), U8(5), U8(17),
B(JumpIfToBooleanTrue), U8(21), B(JumpIfToBooleanTrue), U8(19),
B(LdaNamedProperty), R(3), U8(6), U8(15), B(LdaNamedProperty), R(7), U8(6), U8(8),
B(Star), R(3), B(StaInArrayLiteral), R(2), R(1), U8(13),
B(StaInArrayLiteral), R(2), R(1), U8(3),
B(Ldar), R(1), B(Ldar), R(1),
B(Inc), U8(2), B(Inc), U8(12),
B(Star), R(1), B(Star), R(1),
B(JumpLoop), U8(35), I8(0), B(JumpLoop), U8(33), I8(0),
B(Ldar), R(2), B(Ldar), R(2),
/* 71 S> */ B(Return), /* 71 S> */ B(Return),
] ]
......
...@@ -14,7 +14,7 @@ snippet: " ...@@ -14,7 +14,7 @@ snippet: "
" "
frame size: 8 frame size: 8
parameter count: 1 parameter count: 1
bytecode array length: 189 bytecode array length: 190
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2), B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
...@@ -32,7 +32,7 @@ bytecodes: [ ...@@ -32,7 +32,7 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(2), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(2), U8(2), I8(0),
B(Ldar), R(5), B(Ldar), R(5),
/* 17 E> */ B(Throw), /* 17 E> */ B(Throw),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(5), R(2), B(Mov), R(5), R(2),
B(Jump), U8(95), B(Jump), U8(95),
...@@ -50,10 +50,10 @@ bytecodes: [ ...@@ -50,10 +50,10 @@ bytecodes: [
B(JumpIfTrue), U8(5), B(JumpIfTrue), U8(5),
B(Ldar), R(5), B(Ldar), R(5),
B(ReThrow), B(ReThrow),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(5), R(2), B(Mov), R(5), R(2),
B(Jump), U8(52), B(Jump), U8(51),
B(Jump), U8(36), B(Jump), U8(36),
B(Star), R(5), B(Star), R(5),
B(CreateCatchContext), R(5), U8(4), B(CreateCatchContext), R(5), U8(4),
...@@ -68,15 +68,15 @@ bytecodes: [ ...@@ -68,15 +68,15 @@ bytecodes: [
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(6), U8(2), B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(6), U8(2),
B(PopContext), R(5), B(PopContext), R(5),
B(Star), R(2), B(Star), R(2),
B(LdaSmi), I8(1), B(LdaSmi), I8(2),
B(Star), R(1), B(Star), R(1),
B(Jump), U8(16), B(Jump), U8(15),
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(2), B(Star), R(2),
B(Star), R(1), B(Star), R(1),
B(Jump), U8(8), B(Jump), U8(7),
B(Star), R(2), B(Star), R(2),
B(LdaSmi), I8(2), B(LdaZero),
B(Star), R(1), B(Star), R(1),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
...@@ -87,6 +87,8 @@ bytecodes: [ ...@@ -87,6 +87,8 @@ bytecodes: [
B(Ldar), R(1), B(Ldar), R(1),
B(SwitchOnSmiNoFeedback), U8(5), U8(3), I8(0), B(SwitchOnSmiNoFeedback), U8(5), U8(3), I8(0),
B(Jump), U8(22), B(Jump), U8(22),
B(Ldar), R(2),
B(ReThrow),
B(LdaTrue), B(LdaTrue),
B(Star), R(6), B(Star), R(6),
B(Mov), R(0), R(4), B(Mov), R(0), R(4),
...@@ -95,24 +97,22 @@ bytecodes: [ ...@@ -95,24 +97,22 @@ bytecodes: [
/* 22 S> */ B(Return), /* 22 S> */ B(Return),
B(Ldar), R(2), B(Ldar), R(2),
/* 22 S> */ B(Return), /* 22 S> */ B(Return),
B(Ldar), R(2),
B(ReThrow),
B(LdaUndefined), B(LdaUndefined),
/* 22 S> */ B(Return), /* 22 S> */ B(Return),
] ]
constant pool: [ constant pool: [
Smi [30], Smi [30],
Smi [70], Smi [71],
Smi [15], Smi [16],
Smi [7], Smi [7],
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
Smi [6], Smi [6],
Smi [20], Smi [9],
Smi [23], Smi [23],
] ]
handlers: [ handlers: [
[20, 134, 142], [20, 136, 144],
[23, 98, 100], [23, 100, 102],
] ]
--- ---
...@@ -122,7 +122,7 @@ snippet: " ...@@ -122,7 +122,7 @@ snippet: "
" "
frame size: 8 frame size: 8
parameter count: 1 parameter count: 1
bytecode array length: 233 bytecode array length: 235
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(3), B(SwitchOnGeneratorState), R(0), U8(0), U8(3),
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
...@@ -140,10 +140,10 @@ bytecodes: [ ...@@ -140,10 +140,10 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0),
B(Ldar), R(5), B(Ldar), R(5),
/* 17 E> */ B(Throw), /* 17 E> */ B(Throw),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(5), R(2), B(Mov), R(5), R(2),
B(Jump), U8(139), B(Jump), U8(140),
/* 22 S> */ B(LdaSmi), I8(42), /* 22 S> */ B(LdaSmi), I8(42),
B(Star), R(6), B(Star), R(6),
B(LdaFalse), B(LdaFalse),
...@@ -157,7 +157,7 @@ bytecodes: [ ...@@ -157,7 +157,7 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(5), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(5), U8(2), I8(0),
B(Ldar), R(5), B(Ldar), R(5),
/* 22 E> */ B(Throw), /* 22 E> */ B(Throw),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(5), R(2), B(Mov), R(5), R(2),
B(Jump), U8(95), B(Jump), U8(95),
...@@ -175,10 +175,10 @@ bytecodes: [ ...@@ -175,10 +175,10 @@ bytecodes: [
B(JumpIfTrue), U8(5), B(JumpIfTrue), U8(5),
B(Ldar), R(5), B(Ldar), R(5),
B(ReThrow), B(ReThrow),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(5), R(2), B(Mov), R(5), R(2),
B(Jump), U8(52), B(Jump), U8(51),
B(Jump), U8(36), B(Jump), U8(36),
B(Star), R(5), B(Star), R(5),
B(CreateCatchContext), R(5), U8(7), B(CreateCatchContext), R(5), U8(7),
...@@ -193,15 +193,15 @@ bytecodes: [ ...@@ -193,15 +193,15 @@ bytecodes: [
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(6), U8(2), B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(6), U8(2),
B(PopContext), R(5), B(PopContext), R(5),
B(Star), R(2), B(Star), R(2),
B(LdaSmi), I8(1), B(LdaSmi), I8(2),
B(Star), R(1), B(Star), R(1),
B(Jump), U8(16), B(Jump), U8(15),
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(2), B(Star), R(2),
B(Star), R(1), B(Star), R(1),
B(Jump), U8(8), B(Jump), U8(7),
B(Star), R(2), B(Star), R(2),
B(LdaSmi), I8(2), B(LdaZero),
B(Star), R(1), B(Star), R(1),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
...@@ -212,6 +212,8 @@ bytecodes: [ ...@@ -212,6 +212,8 @@ bytecodes: [
B(Ldar), R(1), B(Ldar), R(1),
B(SwitchOnSmiNoFeedback), U8(8), U8(3), I8(0), B(SwitchOnSmiNoFeedback), U8(8), U8(3), I8(0),
B(Jump), U8(22), B(Jump), U8(22),
B(Ldar), R(2),
B(ReThrow),
B(LdaTrue), B(LdaTrue),
B(Star), R(6), B(Star), R(6),
B(Mov), R(0), R(4), B(Mov), R(0), R(4),
...@@ -220,27 +222,25 @@ bytecodes: [ ...@@ -220,27 +222,25 @@ bytecodes: [
/* 31 S> */ B(Return), /* 31 S> */ B(Return),
B(Ldar), R(2), B(Ldar), R(2),
/* 31 S> */ B(Return), /* 31 S> */ B(Return),
B(Ldar), R(2),
B(ReThrow),
B(LdaUndefined), B(LdaUndefined),
/* 31 S> */ B(Return), /* 31 S> */ B(Return),
] ]
constant pool: [ constant pool: [
Smi [30], Smi [30],
Smi [74], Smi [75],
Smi [114], Smi [116],
Smi [15], Smi [16],
Smi [7], Smi [7],
Smi [15], Smi [16],
Smi [7], Smi [7],
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
Smi [6], Smi [6],
Smi [20], Smi [9],
Smi [23], Smi [23],
] ]
handlers: [ handlers: [
[20, 178, 186], [20, 181, 189],
[23, 142, 144], [23, 145, 147],
] ]
--- ---
...@@ -250,7 +250,7 @@ snippet: " ...@@ -250,7 +250,7 @@ snippet: "
" "
frame size: 22 frame size: 22
parameter count: 1 parameter count: 1
bytecode array length: 490 bytecode array length: 492
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(2), U8(0), U8(3), B(SwitchOnGeneratorState), R(2), U8(0), U8(3),
B(Mov), R(closure), R(11), B(Mov), R(closure), R(11),
...@@ -268,7 +268,7 @@ bytecodes: [ ...@@ -268,7 +268,7 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0),
B(Ldar), R(15), B(Ldar), R(15),
/* 17 E> */ B(Throw), /* 17 E> */ B(Throw),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(11), B(Star), R(11),
B(Mov), R(15), R(12), B(Mov), R(15), R(12),
B(JumpConstant), U8(18), B(JumpConstant), U8(18),
...@@ -293,7 +293,7 @@ bytecodes: [ ...@@ -293,7 +293,7 @@ bytecodes: [
B(JumpIfFalse), U8(7), B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(8), U8(9), B(LdaNamedProperty), R(6), U8(8), U8(9),
B(JumpIfToBooleanTrue), U8(68), B(JumpIfToBooleanTrue), U8(69),
B(LdaNamedProperty), R(6), U8(9), U8(11), B(LdaNamedProperty), R(6), U8(9), U8(11),
B(Star), R(8), B(Star), R(8),
B(LdaSmi), I8(2), B(LdaSmi), I8(2),
...@@ -313,13 +313,13 @@ bytecodes: [ ...@@ -313,13 +313,13 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(0),
B(Ldar), R(19), B(Ldar), R(19),
/* 42 E> */ B(Throw), /* 42 E> */ B(Throw),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(15), B(Star), R(15),
B(Mov), R(19), R(16), B(Mov), R(19), R(16),
B(Jump), U8(59), B(Jump), U8(58),
B(LdaZero), B(LdaZero),
B(Star), R(7), B(Star), R(7),
B(JumpLoop), U8(87), I8(0), B(JumpLoop), U8(88), I8(0),
B(Jump), U8(37), B(Jump), U8(37),
B(Star), R(19), B(Star), R(19),
B(CreateCatchContext), R(19), U8(12), B(CreateCatchContext), R(19), U8(12),
...@@ -340,9 +340,9 @@ bytecodes: [ ...@@ -340,9 +340,9 @@ bytecodes: [
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(16), B(Star), R(16),
B(Star), R(15), B(Star), R(15),
B(Jump), U8(8), B(Jump), U8(7),
B(Star), R(16), B(Star), R(16),
B(LdaSmi), I8(1), B(LdaZero),
B(Star), R(15), B(Star), R(15),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
...@@ -389,13 +389,13 @@ bytecodes: [ ...@@ -389,13 +389,13 @@ bytecodes: [
B(SetPendingMessage), B(SetPendingMessage),
B(Ldar), R(15), B(Ldar), R(15),
B(SwitchOnSmiNoFeedback), U8(15), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(15), U8(2), I8(0),
B(Jump), U8(13), B(Jump), U8(14),
B(LdaZero),
B(Star), R(11),
B(Mov), R(16), R(12),
B(Jump), U8(98),
B(Ldar), R(16), B(Ldar), R(16),
B(ReThrow), B(ReThrow),
B(LdaSmi), I8(1),
B(Star), R(11),
B(Mov), R(16), R(12),
B(Jump), U8(95),
B(LdaUndefined), B(LdaUndefined),
B(Star), R(16), B(Star), R(16),
B(Mov), R(2), R(15), B(Mov), R(2), R(15),
...@@ -410,10 +410,10 @@ bytecodes: [ ...@@ -410,10 +410,10 @@ bytecodes: [
B(JumpIfTrue), U8(5), B(JumpIfTrue), U8(5),
B(Ldar), R(15), B(Ldar), R(15),
B(ReThrow), B(ReThrow),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(11), B(Star), R(11),
B(Mov), R(15), R(12), B(Mov), R(15), R(12),
B(Jump), U8(52), B(Jump), U8(51),
B(Jump), U8(36), B(Jump), U8(36),
B(Star), R(15), B(Star), R(15),
B(CreateCatchContext), R(15), U8(17), B(CreateCatchContext), R(15), U8(17),
...@@ -428,15 +428,15 @@ bytecodes: [ ...@@ -428,15 +428,15 @@ bytecodes: [
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(16), U8(2), B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(16), U8(2),
B(PopContext), R(15), B(PopContext), R(15),
B(Star), R(12), B(Star), R(12),
B(LdaSmi), I8(1), B(LdaSmi), I8(2),
B(Star), R(11), B(Star), R(11),
B(Jump), U8(16), B(Jump), U8(15),
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(12), B(Star), R(12),
B(Star), R(11), B(Star), R(11),
B(Jump), U8(8), B(Jump), U8(7),
B(Star), R(12), B(Star), R(12),
B(LdaSmi), I8(2), B(LdaZero),
B(Star), R(11), B(Star), R(11),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
...@@ -447,6 +447,8 @@ bytecodes: [ ...@@ -447,6 +447,8 @@ bytecodes: [
B(Ldar), R(11), B(Ldar), R(11),
B(SwitchOnSmiNoFeedback), U8(19), U8(3), I8(0), B(SwitchOnSmiNoFeedback), U8(19), U8(3), I8(0),
B(Jump), U8(22), B(Jump), U8(22),
B(Ldar), R(12),
B(ReThrow),
B(LdaTrue), B(LdaTrue),
B(Star), R(16), B(Star), R(16),
B(Mov), R(2), R(14), B(Mov), R(2), R(14),
...@@ -455,41 +457,39 @@ bytecodes: [ ...@@ -455,41 +457,39 @@ bytecodes: [
/* 50 S> */ B(Return), /* 50 S> */ B(Return),
B(Ldar), R(12), B(Ldar), R(12),
/* 50 S> */ B(Return), /* 50 S> */ B(Return),
B(Ldar), R(12),
B(ReThrow),
B(LdaUndefined), B(LdaUndefined),
/* 50 S> */ B(Return), /* 50 S> */ B(Return),
] ]
constant pool: [ constant pool: [
Smi [30], Smi [30],
Smi [154], Smi [155],
Smi [371], Smi [373],
Smi [15], Smi [16],
Smi [7], Smi [7],
ARRAY_BOILERPLATE_DESCRIPTION_TYPE, ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
SYMBOL_TYPE, SYMBOL_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
Smi [15], Smi [16],
Smi [7], Smi [7],
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
Smi [6], Smi [6],
Smi [14], Smi [9],
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
Smi [396], Smi [397],
Smi [6], Smi [6],
Smi [20], Smi [9],
Smi [23], Smi [23],
] ]
handlers: [ handlers: [
[20, 435, 443], [20, 438, 446],
[23, 399, 401], [23, 402, 404],
[61, 222, 230], [62, 224, 232],
[64, 185, 187], [65, 187, 189],
[291, 301, 303], [292, 302, 304],
] ]
--- ---
...@@ -500,7 +500,7 @@ snippet: " ...@@ -500,7 +500,7 @@ snippet: "
" "
frame size: 17 frame size: 17
parameter count: 1 parameter count: 1
bytecode array length: 479 bytecode array length: 482
bytecodes: [ bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(5), B(SwitchOnGeneratorState), R(0), U8(0), U8(5),
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
...@@ -518,13 +518,13 @@ bytecodes: [ ...@@ -518,13 +518,13 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(5), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(5), U8(2), I8(0),
B(Ldar), R(5), B(Ldar), R(5),
/* 44 E> */ B(Throw), /* 44 E> */ B(Throw),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(5), R(2), B(Mov), R(5), R(2),
B(JumpConstant), U8(18), B(JumpConstant), U8(18),
/* 49 S> */ B(LdaGlobal), U8(7), U8(0), /* 49 S> */ B(LdaGlobal), U8(7), U8(0),
B(Star), R(12), B(Star), R(9),
/* 56 E> */ B(CallUndefinedReceiver0), R(12), U8(2), /* 56 E> */ B(CallUndefinedReceiver0), R(9), U8(2),
B(Star), R(10), B(Star), R(10),
B(LdaNamedProperty), R(10), U8(8), U8(4), B(LdaNamedProperty), R(10), U8(8), U8(4),
B(JumpIfUndefined), U8(17), B(JumpIfUndefined), U8(17),
...@@ -548,14 +548,14 @@ bytecodes: [ ...@@ -548,14 +548,14 @@ bytecodes: [
B(Ldar), R(6), B(Ldar), R(6),
B(SwitchOnSmiNoFeedback), U8(11), U8(2), I8(1), B(SwitchOnSmiNoFeedback), U8(11), U8(2), I8(1),
B(CallProperty1), R(9), R(7), R(8), U8(14), B(CallProperty1), R(9), R(7), R(8), U8(14),
B(Jump), U8(110), B(Jump), U8(111),
B(LdaNamedProperty), R(7), U8(13), U8(16), B(LdaNamedProperty), R(7), U8(13), U8(16),
B(JumpIfUndefined), U8(13), B(JumpIfUndefined), U8(13),
B(JumpIfNull), U8(11), B(JumpIfNull), U8(11),
B(Star), R(12), B(Star), R(12),
B(CallProperty1), R(12), R(7), R(8), U8(18), B(CallProperty1), R(12), R(7), R(8), U8(18),
B(Jump), U8(93), B(Jump), U8(94),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(8), R(2), B(Mov), R(8), R(2),
B(JumpConstant), U8(19), B(JumpConstant), U8(19),
...@@ -619,13 +619,13 @@ bytecodes: [ ...@@ -619,13 +619,13 @@ bytecodes: [
B(Star), R(8), B(Star), R(8),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1), B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1),
B(Star), R(6), B(Star), R(6),
B(JumpLoop), U8(206), I8(0), B(JumpLoop), U8(207), I8(0),
B(LdaNamedProperty), R(5), U8(16), U8(32), B(LdaNamedProperty), R(5), U8(16), U8(32),
B(Star), R(7), B(Star), R(7),
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(TestReferenceEqual), R(6), B(TestReferenceEqual), R(6),
B(JumpIfFalse), U8(10), B(JumpIfFalse), U8(11),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(7), R(2), B(Mov), R(7), R(2),
B(Jump), U8(95), B(Jump), U8(95),
...@@ -643,10 +643,10 @@ bytecodes: [ ...@@ -643,10 +643,10 @@ bytecodes: [
B(JumpIfTrue), U8(5), B(JumpIfTrue), U8(5),
B(Ldar), R(5), B(Ldar), R(5),
B(ReThrow), B(ReThrow),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(1), B(Star), R(1),
B(Mov), R(5), R(2), B(Mov), R(5), R(2),
B(Jump), U8(52), B(Jump), U8(51),
B(Jump), U8(36), B(Jump), U8(36),
B(Star), R(5), B(Star), R(5),
B(CreateCatchContext), R(5), U8(17), B(CreateCatchContext), R(5), U8(17),
...@@ -661,15 +661,15 @@ bytecodes: [ ...@@ -661,15 +661,15 @@ bytecodes: [
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(6), U8(2), B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(6), U8(2),
B(PopContext), R(5), B(PopContext), R(5),
B(Star), R(2), B(Star), R(2),
B(LdaSmi), I8(1), B(LdaSmi), I8(2),
B(Star), R(1), B(Star), R(1),
B(Jump), U8(16), B(Jump), U8(15),
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(2), B(Star), R(2),
B(Star), R(1), B(Star), R(1),
B(Jump), U8(8), B(Jump), U8(7),
B(Star), R(2), B(Star), R(2),
B(LdaSmi), I8(2), B(LdaZero),
B(Star), R(1), B(Star), R(1),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
...@@ -680,6 +680,8 @@ bytecodes: [ ...@@ -680,6 +680,8 @@ bytecodes: [
B(Ldar), R(1), B(Ldar), R(1),
B(SwitchOnSmiNoFeedback), U8(20), U8(3), I8(0), B(SwitchOnSmiNoFeedback), U8(20), U8(3), I8(0),
B(Jump), U8(22), B(Jump), U8(22),
B(Ldar), R(2),
B(ReThrow),
B(LdaTrue), B(LdaTrue),
B(Star), R(6), B(Star), R(6),
B(Mov), R(0), R(4), B(Mov), R(0), R(4),
...@@ -688,38 +690,36 @@ bytecodes: [ ...@@ -688,38 +690,36 @@ bytecodes: [
/* 60 S> */ B(Return), /* 60 S> */ B(Return),
B(Ldar), R(2), B(Ldar), R(2),
/* 60 S> */ B(Return), /* 60 S> */ B(Return),
B(Ldar), R(2),
B(ReThrow),
B(LdaUndefined), B(LdaUndefined),
/* 60 S> */ B(Return), /* 60 S> */ B(Return),
] ]
constant pool: [ constant pool: [
Smi [30], Smi [30],
Smi [201], Smi [203],
Smi [251], Smi [253],
Smi [310], Smi [312],
Smi [360], Smi [363],
Smi [15], Smi [16],
Smi [7], Smi [7],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"],
SYMBOL_TYPE, SYMBOL_TYPE,
SYMBOL_TYPE, SYMBOL_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
Smi [11], Smi [11],
Smi [36], Smi [37],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["throw"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["throw"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
Smi [385], Smi [387],
Smi [286], Smi [287],
Smi [6], Smi [6],
Smi [20], Smi [9],
Smi [23], Smi [23],
] ]
handlers: [ handlers: [
[20, 424, 432], [20, 428, 436],
[23, 388, 390], [23, 392, 394],
] ]
...@@ -67,7 +67,7 @@ snippet: " ...@@ -67,7 +67,7 @@ snippet: "
" "
frame size: 10 frame size: 10
parameter count: 1 parameter count: 1
bytecode array length: 109 bytecode array length: 107
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdaGlobal), U8(0), U8(0), /* 34 S> */ B(LdaGlobal), U8(0), U8(0),
...@@ -78,32 +78,31 @@ bytecodes: [ ...@@ -78,32 +78,31 @@ bytecodes: [
B(Star), R(4), B(Star), R(4),
B(LdaConstant), U8(3), B(LdaConstant), U8(3),
B(Star), R(3), B(Star), R(3),
/* 49 S> */ B(CreateArrayLiteral), U8(4), U8(8), U8(37), /* 49 S> */ B(CreateArrayLiteral), U8(4), U8(5), U8(37),
B(Star), R(7),
B(LdaNamedProperty), R(7), U8(5), U8(6),
B(Star), R(8), B(Star), R(8),
B(LdaNamedProperty), R(8), U8(5), U8(9), B(CallProperty0), R(8), R(7), U8(8),
B(Star), R(9),
B(CallProperty0), R(9), R(8), U8(11),
B(Mov), R(0), R(2), B(Mov), R(0), R(2),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(7),
B(LdaNamedProperty), R(7), U8(6), U8(13),
B(Star), R(6), B(Star), R(6),
B(CallProperty0), R(6), R(7), U8(15), B(LdaNamedProperty), R(6), U8(6), U8(10),
B(Star), R(5), B(Star), R(5),
B(CallProperty0), R(5), R(6), U8(19),
B(Star), R(9),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
B(LdaNamedProperty), R(5), U8(7), U8(17), B(LdaNamedProperty), R(9), U8(7), U8(21),
B(JumpIfToBooleanTrue), U8(21), B(JumpIfToBooleanTrue), U8(19),
B(LdaNamedProperty), R(5), U8(8), U8(19), B(LdaNamedProperty), R(9), U8(8), U8(12),
B(Star), R(5), B(StaInArrayLiteral), R(4), R(3), U8(17),
B(StaInArrayLiteral), R(4), R(3), U8(6),
B(Ldar), R(3), B(Ldar), R(3),
B(Inc), U8(5), B(Inc), U8(16),
B(Star), R(3), B(Star), R(3),
B(JumpLoop), U8(35), I8(0), B(JumpLoop), U8(33), I8(0),
B(LdaSmi), I8(4), B(LdaSmi), I8(4),
B(StaInArrayLiteral), R(4), R(3), U8(6), B(StaInArrayLiteral), R(4), R(3), U8(17),
B(Mov), R(4), R(3), B(Mov), R(4), R(3),
B(CallJSRuntime), U8(%reflect_apply), R(1), U8(3), B(CallJSRuntime), U8(%reflect_apply), R(1), U8(3),
B(LdaUndefined), B(LdaUndefined),
......
...@@ -10,120 +10,79 @@ snippet: " ...@@ -10,120 +10,79 @@ snippet: "
var x, a = [0,1,2,3]; var x, a = [0,1,2,3];
[x] = a; [x] = a;
" "
frame size: 17 frame size: 14
parameter count: 1 parameter count: 1
bytecode array length: 259 bytecode array length: 160
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(1), B(Star), R(1),
/* 56 S> */ B(Star), R(2), /* 60 S> */ B(LdaNamedProperty), R(1), U8(1), U8(1),
/* 62 E> */ B(LdaNamedProperty), R(2), U8(1), U8(1), B(Star), R(6),
B(Star), R(12), B(CallProperty0), R(6), R(1), U8(3),
B(CallProperty0), R(12), R(2), U8(3), B(Mov), R(1), R(5),
B(Mov), R(1), R(11), B(Mov), R(1), R(2),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(3),
B(LdaNamedProperty), R(3), U8(2), U8(5),
B(Star), R(4), B(Star), R(4),
B(LdaNamedProperty), R(4), U8(2), U8(5),
B(Star), R(3),
B(LdaFalse), B(LdaFalse),
B(Star), R(5),
B(LdaZero),
B(Star), R(8),
B(Mov), R(context), R(13),
B(Mov), R(context), R(14),
B(Ldar), R(5),
B(JumpIfToBooleanTrue), U8(43),
B(LdaTrue),
B(Star), R(5),
B(CallProperty0), R(4), R(3), U8(7),
B(Star), R(6),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(6), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(3), U8(9),
B(JumpIfToBooleanFalse), U8(7),
B(LdaUndefined),
B(Star), R(7), B(Star), R(7),
B(Jump), U8(11), B(Mov), R(context), R(10),
B(LdaNamedProperty), R(6), U8(4), U8(11), /* 57 S> */ B(Ldar), R(7),
B(JumpIfToBooleanTrue), U8(37),
B(LdaTrue),
B(Star), R(7), B(Star), R(7),
B(CallProperty0), R(3), R(4), U8(11),
B(Star), R(11),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), U8(1),
B(LdaNamedProperty), R(11), U8(3), U8(9),
B(JumpIfToBooleanTrue), U8(15),
B(LdaNamedProperty), R(11), U8(4), U8(7),
B(Star), R(11),
B(LdaFalse), B(LdaFalse),
B(Star), R(5), B(Star), R(7),
B(LdaSmi), I8(2), B(Ldar), R(11),
B(Star), R(8), B(Jump), U8(3),
/* 57 S> */ B(Mov), R(7), R(0), B(LdaUndefined),
B(LdaZero), B(Star), R(0),
B(Star), R(8),
B(Jump), U8(33),
B(Star), R(15),
/* 57 E> */ B(CreateCatchContext), R(15), U8(5),
B(PushContext), R(15),
B(Star), R(14),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(8), U8(13),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(8),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(16),
B(CallRuntime), U16(Runtime::kReThrow), R(16), U8(1),
B(PopContext), R(15),
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(12), B(Star), R(9),
B(Star), R(11), B(Star), R(8),
B(Jump), U8(7), B(Jump), U8(7),
B(Star), R(12),
B(LdaZero),
B(Star), R(11),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(13),
B(Ldar), R(5),
B(JumpIfToBooleanTrue), U8(90),
B(LdaNamedProperty), R(3), U8(6), U8(14),
B(Star), R(9), B(Star), R(9),
B(TestUndetectable), B(LdaZero),
B(JumpIfFalse), U8(4), B(Star), R(8),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(8), U8(16),
B(JumpIfFalse), U8(47),
B(Ldar), R(9),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(14),
B(LdaConstant), U8(7),
B(Star), R(15),
B(CallRuntime), U16(Runtime::kNewTypeError), R(14), U8(2),
B(Throw),
B(Mov), R(context), R(14),
B(Mov), R(9), R(15),
B(Mov), R(3), R(16),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(15), U8(2),
B(Jump), U8(6),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
B(Ldar), R(14),
B(Jump), U8(27),
B(Mov), R(9), R(14),
B(Mov), R(3), R(15),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(14), U8(2),
B(Star), R(10), B(Star), R(10),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(10), U8(1), B(Mov), R(context), R(12),
B(JumpIfToBooleanFalse), U8(4), B(Ldar), R(7),
B(Jump), U8(7), B(JumpIfToBooleanTrue), U8(27),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1), B(LdaNamedProperty), R(4), U8(5), U8(13),
B(Ldar), R(13), B(JumpIfUndefined), U8(21),
B(JumpIfNull), U8(19),
B(Star), R(13),
B(CallProperty0), R(13), R(4), U8(15),
B(Jump), U8(2),
B(JumpIfJSReceiver), U8(9),
B(Star), R(13),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(13), U8(1),
B(Jump), U8(12),
B(Star), R(12),
B(LdaZero),
B(TestReferenceEqual), R(8),
B(JumpIfTrue), U8(5),
B(Ldar), R(12),
B(ReThrow),
B(Ldar), R(10),
B(SetPendingMessage), B(SetPendingMessage),
B(LdaZero), B(LdaZero),
B(TestReferenceEqual), R(11), B(TestReferenceEqual), R(8),
B(JumpIfFalse), U8(5), B(JumpIfFalse), U8(5),
B(Ldar), R(12), B(Ldar), R(9),
B(ReThrow), B(ReThrow),
B(LdaUndefined), B(LdaUndefined),
/* 65 S> */ B(Return), /* 65 S> */ B(Return),
...@@ -134,14 +93,11 @@ constant pool: [ ...@@ -134,14 +93,11 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
] ]
handlers: [ handlers: [
[46, 137, 145], [44, 86, 94],
[49, 104, 106], [106, 135, 137],
[203, 213, 215],
] ]
--- ---
...@@ -149,166 +105,120 @@ snippet: " ...@@ -149,166 +105,120 @@ snippet: "
var x, y, a = [0,1,2,3]; var x, y, a = [0,1,2,3];
[,x,...y] = a; [,x,...y] = a;
" "
frame size: 20 frame size: 15
parameter count: 1 parameter count: 1
bytecode array length: 368 bytecode array length: 258
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(2), B(Star), R(2),
/* 59 S> */ B(Star), R(3), /* 69 S> */ B(LdaNamedProperty), R(2), U8(1), U8(1),
/* 71 E> */ B(LdaNamedProperty), R(3), U8(1), U8(1), B(Star), R(7),
B(Star), R(15), B(CallProperty0), R(7), R(2), U8(3),
B(CallProperty0), R(15), R(3), U8(3), B(Mov), R(2), R(6),
B(Mov), R(2), R(14), B(Mov), R(2), R(3),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(4),
B(LdaNamedProperty), R(4), U8(2), U8(5),
B(Star), R(5), B(Star), R(5),
B(LdaNamedProperty), R(5), U8(2), U8(5),
B(Star), R(4),
B(LdaFalse), B(LdaFalse),
B(Star), R(6),
B(LdaZero),
B(Star), R(9),
B(Mov), R(context), R(16),
B(Mov), R(context), R(17),
B(Ldar), R(6),
B(JumpIfToBooleanTrue), U8(43),
B(LdaTrue),
B(Star), R(6),
B(CallProperty0), R(5), R(4), U8(7),
B(Star), R(7),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(7), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(LdaNamedProperty), R(7), U8(3), U8(9),
B(JumpIfToBooleanFalse), U8(7),
B(LdaUndefined),
B(Star), R(8), B(Star), R(8),
B(Jump), U8(11), B(Mov), R(context), R(11),
B(LdaNamedProperty), R(7), U8(4), U8(11), B(Ldar), R(8),
B(JumpIfToBooleanTrue), U8(35),
B(LdaTrue),
B(Star), R(8), B(Star), R(8),
B(CallProperty0), R(4), R(5), U8(11),
B(Star), R(12),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdaNamedProperty), R(12), U8(3), U8(9),
B(JumpIfToBooleanTrue), U8(13),
B(LdaNamedProperty), R(12), U8(4), U8(7),
B(Star), R(12),
B(LdaFalse), B(LdaFalse),
B(Star), R(6),
B(Ldar), R(6),
B(JumpIfToBooleanTrue), U8(43),
B(LdaTrue),
B(Star), R(6),
B(CallProperty0), R(5), R(4), U8(13),
B(Star), R(7),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(7), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(LdaNamedProperty), R(7), U8(3), U8(9),
B(JumpIfToBooleanFalse), U8(7),
B(LdaUndefined),
B(Star), R(8), B(Star), R(8),
B(Jump), U8(11), B(Ldar), R(12),
B(LdaNamedProperty), R(7), U8(4), U8(11), /* 61 S> */ B(Ldar), R(8),
B(JumpIfToBooleanTrue), U8(37),
B(LdaTrue),
B(Star), R(8), B(Star), R(8),
B(CallProperty0), R(4), R(5), U8(13),
B(Star), R(12),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdaNamedProperty), R(12), U8(3), U8(9),
B(JumpIfToBooleanTrue), U8(15),
B(LdaNamedProperty), R(12), U8(4), U8(7),
B(Star), R(12),
B(LdaFalse), B(LdaFalse),
B(Star), R(6), B(Star), R(8),
B(LdaSmi), I8(2), B(Ldar), R(12),
B(Star), R(9), B(Jump), U8(3),
/* 61 S> */ B(Mov), R(8), R(0), B(LdaUndefined),
B(LdaZero), B(Star), R(0),
B(Star), R(9), /* 63 S> */ B(CreateEmptyArrayLiteral), U8(15),
/* 61 E> */ B(CreateEmptyArrayLiteral), U8(15), B(Star), R(13),
B(Star), R(10),
B(LdaZero), B(LdaZero),
B(Star), R(11), B(Star), R(14),
B(Ldar), R(6),
B(JumpIfToBooleanTrue), U8(50),
B(StackCheck),
B(LdaTrue), B(LdaTrue),
B(Star), R(6), B(Star), R(8),
B(CallProperty0), R(5), R(4), U8(16), B(CallProperty0), R(4), R(5), U8(19),
B(Star), R(7), B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(7), U8(1), B(JumpIfJSReceiver), U8(7),
B(ToBooleanLogicalNot), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(JumpIfFalse), U8(7), B(LdaNamedProperty), R(12), U8(3), U8(21),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1), B(JumpIfToBooleanTrue), U8(29),
B(LdaNamedProperty), R(7), U8(3), U8(9), B(LdaNamedProperty), R(12), U8(4), U8(7),
B(JumpIfToBooleanTrue), U8(13), B(Star), R(12),
B(LdaNamedProperty), R(7), U8(4), U8(11),
B(StaInArrayLiteral), R(10), R(11), U8(18),
B(LdaFalse), B(LdaFalse),
B(Star), R(6), B(Star), R(8),
B(Ldar), R(11), B(Ldar), R(12),
B(Inc), U8(20), B(StaInArrayLiteral), R(13), R(14), U8(16),
B(Star), R(11), B(Ldar), R(14),
B(JumpLoop), U8(49), I8(0), B(Inc), U8(18),
/* 66 S> */ B(Mov), R(10), R(1), B(Star), R(14),
B(JumpLoop), U8(43), I8(0),
B(LdaTrue),
B(Star), R(8),
B(Mov), R(13), R(1),
B(Ldar), R(1), B(Ldar), R(1),
B(Jump), U8(33),
B(Star), R(18),
/* 66 E> */ B(CreateCatchContext), R(18), U8(5),
B(PushContext), R(18),
B(Star), R(17),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(9), U8(21),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(9),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(19),
B(CallRuntime), U16(Runtime::kReThrow), R(19), U8(1),
B(PopContext), R(18),
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(15), B(Star), R(10),
B(Star), R(14), B(Star), R(9),
B(Jump), U8(7), B(Jump), U8(7),
B(Star), R(15), B(Star), R(10),
B(LdaZero), B(LdaZero),
B(Star), R(14), B(Star), R(9),
B(LdaTheHole),
B(SetPendingMessage),
B(Star), R(16),
B(Ldar), R(6),
B(JumpIfToBooleanTrue), U8(90),
B(LdaNamedProperty), R(4), U8(6), U8(22),
B(Star), R(12),
B(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(9), U8(24),
B(JumpIfFalse), U8(47),
B(Ldar), R(12),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(17),
B(LdaConstant), U8(7),
B(Star), R(18),
B(CallRuntime), U16(Runtime::kNewTypeError), R(17), U8(2),
B(Throw),
B(Mov), R(context), R(17),
B(Mov), R(12), R(18),
B(Mov), R(4), R(19),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(18), U8(2),
B(Jump), U8(6),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
B(Ldar), R(17), B(Star), R(11),
B(Jump), U8(27), B(Mov), R(context), R(13),
B(Mov), R(12), R(17), B(Ldar), R(8),
B(Mov), R(4), R(18), B(JumpIfToBooleanTrue), U8(27),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(17), U8(2), B(LdaNamedProperty), R(5), U8(5), U8(23),
B(JumpIfUndefined), U8(21),
B(JumpIfNull), U8(19),
B(Star), R(14),
B(CallProperty0), R(14), R(5), U8(25),
B(Jump), U8(2),
B(JumpIfJSReceiver), U8(9),
B(Star), R(14),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(14), U8(1),
B(Jump), U8(12),
B(Star), R(13), B(Star), R(13),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(13), U8(1), B(LdaZero),
B(JumpIfToBooleanFalse), U8(4), B(TestReferenceEqual), R(9),
B(Jump), U8(7), B(JumpIfTrue), U8(5),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(13), U8(1), B(Ldar), R(13),
B(Ldar), R(16), B(ReThrow),
B(Ldar), R(11),
B(SetPendingMessage), B(SetPendingMessage),
B(LdaZero), B(LdaZero),
B(TestReferenceEqual), R(14), B(TestReferenceEqual), R(9),
B(JumpIfFalse), U8(5), B(JumpIfFalse), U8(5),
B(Ldar), R(15), B(Ldar), R(10),
B(ReThrow), B(ReThrow),
B(LdaUndefined), B(LdaUndefined),
/* 74 S> */ B(Return), /* 74 S> */ B(Return),
...@@ -319,14 +229,11 @@ constant pool: [ ...@@ -319,14 +229,11 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
] ]
handlers: [ handlers: [
[46, 246, 254], [44, 184, 192],
[49, 213, 215], [204, 233, 235],
[312, 322, 324],
] ]
--- ---
...@@ -334,153 +241,100 @@ snippet: " ...@@ -334,153 +241,100 @@ snippet: "
var x={}, y, a = [0]; var x={}, y, a = [0];
[x.foo,y=4] = a; [x.foo,y=4] = a;
" "
frame size: 19 frame size: 16
parameter count: 1 parameter count: 1
bytecode array length: 332 bytecode array length: 211
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 40 S> */ B(CreateEmptyObjectLiteral), /* 40 S> */ B(CreateEmptyObjectLiteral),
B(Star), R(0), B(Star), R(0),
/* 51 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37), /* 51 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(2), B(Star), R(2),
/* 56 S> */ B(Star), R(3), /* 68 S> */ B(LdaNamedProperty), R(2), U8(1), U8(1),
/* 70 E> */ B(LdaNamedProperty), R(3), U8(1), U8(1), B(Star), R(7),
B(Star), R(14), B(CallProperty0), R(7), R(2), U8(3),
B(CallProperty0), R(14), R(3), U8(3), B(Mov), R(2), R(6),
B(Mov), R(2), R(13), B(Mov), R(2), R(3),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(4),
B(LdaNamedProperty), R(4), U8(2), U8(5),
B(Star), R(5), B(Star), R(5),
B(LdaNamedProperty), R(5), U8(2), U8(5),
B(Star), R(4),
B(LdaFalse), B(LdaFalse),
B(Star), R(6),
B(LdaZero),
B(Star), R(9),
B(Mov), R(context), R(15),
B(Mov), R(context), R(16),
B(Ldar), R(6),
B(JumpIfToBooleanTrue), U8(43),
B(LdaTrue),
B(Star), R(6),
B(CallProperty0), R(5), R(4), U8(7),
B(Star), R(7),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(7), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(LdaNamedProperty), R(7), U8(3), U8(9),
B(JumpIfToBooleanFalse), U8(7),
B(LdaUndefined),
B(Star), R(8), B(Star), R(8),
B(Jump), U8(11), B(Mov), R(context), R(11),
B(LdaNamedProperty), R(7), U8(4), U8(11), /* 59 S> */ B(Ldar), R(8),
B(Mov), R(0), R(13),
B(JumpIfToBooleanTrue), U8(37),
B(LdaTrue),
B(Star), R(8), B(Star), R(8),
B(CallProperty0), R(4), R(5), U8(11),
B(Star), R(12),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdaNamedProperty), R(12), U8(3), U8(9),
B(JumpIfToBooleanTrue), U8(15),
B(LdaNamedProperty), R(12), U8(4), U8(7),
B(Star), R(12),
B(LdaFalse), B(LdaFalse),
B(Star), R(6),
B(LdaSmi), I8(2),
B(Star), R(9),
B(Ldar), R(8),
/* 59 E> */ B(StaNamedProperty), R(0), U8(5), U8(13),
B(LdaZero),
B(Star), R(9),
B(Ldar), R(6),
B(JumpIfToBooleanTrue), U8(43),
B(LdaTrue),
B(Star), R(6),
B(CallProperty0), R(5), R(4), U8(15),
B(Star), R(7),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(7), U8(1),
B(ToBooleanLogicalNot),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(LdaNamedProperty), R(7), U8(3), U8(9),
B(JumpIfToBooleanFalse), U8(7),
B(LdaUndefined),
B(Star), R(8), B(Star), R(8),
B(Jump), U8(11), B(Ldar), R(12),
B(LdaNamedProperty), R(7), U8(4), U8(11), B(Jump), U8(3),
B(LdaUndefined),
B(StaNamedProperty), R(13), U8(5), U8(13),
/* 63 S> */ B(Ldar), R(8),
B(JumpIfToBooleanTrue), U8(37),
B(LdaTrue),
B(Star), R(8), B(Star), R(8),
B(CallProperty0), R(4), R(5), U8(15),
B(Star), R(12),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdaNamedProperty), R(12), U8(3), U8(9),
B(JumpIfToBooleanTrue), U8(15),
B(LdaNamedProperty), R(12), U8(4), U8(7),
B(Star), R(12),
B(LdaFalse), B(LdaFalse),
B(Star), R(6), B(Star), R(8),
B(LdaSmi), I8(2), B(Ldar), R(12),
B(Star), R(9), B(JumpIfNotUndefined), U8(4),
B(Mov), R(8), R(10),
/* 63 S> */ B(Ldar), R(10),
B(JumpIfNotUndefined), U8(6),
B(LdaSmi), I8(4), B(LdaSmi), I8(4),
B(Jump), U8(4),
B(Ldar), R(10),
B(Star), R(1), B(Star), R(1),
B(LdaZero),
B(Star), R(9),
B(Jump), U8(33),
B(Star), R(17),
/* 63 E> */ B(CreateCatchContext), R(17), U8(6),
B(PushContext), R(17),
B(Star), R(16),
B(LdaSmi), I8(2),
B(TestEqualStrict), R(9), U8(17),
B(JumpIfFalse), U8(6),
B(LdaSmi), I8(1),
B(Star), R(9),
B(LdaImmutableCurrentContextSlot), U8(4),
B(Star), R(18),
B(CallRuntime), U16(Runtime::kReThrow), R(18), U8(1),
B(PopContext), R(17),
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(14), B(Star), R(10),
B(Star), R(13), B(Star), R(9),
B(Jump), U8(7), B(Jump), U8(7),
B(Star), R(14), B(Star), R(10),
B(LdaZero), B(LdaZero),
B(Star), R(13), B(Star), R(9),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
B(Star), R(15),
B(Ldar), R(6),
B(JumpIfToBooleanTrue), U8(90),
B(LdaNamedProperty), R(4), U8(7), U8(18),
B(Star), R(11), B(Star), R(11),
B(TestUndetectable), B(Mov), R(context), R(14),
B(JumpIfFalse), U8(4), B(Ldar), R(8),
B(Jump), U8(79), B(JumpIfToBooleanTrue), U8(27),
B(LdaSmi), I8(1), B(LdaNamedProperty), R(5), U8(6), U8(17),
B(TestEqualStrict), R(9), U8(20), B(JumpIfUndefined), U8(21),
B(JumpIfFalse), U8(47), B(JumpIfNull), U8(19),
B(Star), R(15),
B(CallProperty0), R(15), R(5), U8(19),
B(Jump), U8(2),
B(JumpIfJSReceiver), U8(9),
B(Star), R(15),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(15), U8(1),
B(Jump), U8(12),
B(Star), R(14),
B(LdaZero),
B(TestReferenceEqual), R(9),
B(JumpIfTrue), U8(5),
B(Ldar), R(14),
B(ReThrow),
B(Ldar), R(11), B(Ldar), R(11),
B(TestTypeOf), U8(6),
B(JumpIfFalse), U8(4),
B(Jump), U8(18),
B(Wide), B(LdaSmi), I16(154),
B(Star), R(16),
B(LdaConstant), U8(8),
B(Star), R(17),
B(CallRuntime), U16(Runtime::kNewTypeError), R(16), U8(2),
B(Throw),
B(Mov), R(context), R(16),
B(Mov), R(11), R(17),
B(Mov), R(4), R(18),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(17), U8(2),
B(Jump), U8(6),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(16),
B(Jump), U8(27),
B(Mov), R(11), R(16),
B(Mov), R(4), R(17),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(16), U8(2),
B(Star), R(12),
B(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(12), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(Ldar), R(15),
B(SetPendingMessage), B(SetPendingMessage),
B(LdaZero), B(LdaZero),
B(TestReferenceEqual), R(13), B(TestReferenceEqual), R(9),
B(JumpIfFalse), U8(5), B(JumpIfFalse), U8(5),
B(Ldar), R(14), B(Ldar), R(10),
B(ReThrow), B(ReThrow),
B(LdaUndefined), B(LdaUndefined),
/* 73 S> */ B(Return), /* 73 S> */ B(Return),
...@@ -492,14 +346,11 @@ constant pool: [ ...@@ -492,14 +346,11 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["foo"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["foo"],
SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
] ]
handlers: [ handlers: [
[49, 210, 218], [47, 137, 145],
[52, 177, 179], [157, 186, 188],
[276, 286, 288],
] ]
--- ---
...@@ -509,22 +360,21 @@ snippet: " ...@@ -509,22 +360,21 @@ snippet: "
" "
frame size: 5 frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 37 bytecode array length: 35
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41), /* 45 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41),
B(Star), R(1), B(Star), R(1),
/* 52 S> */ B(Star), R(2), /* 52 S> */ B(JumpIfNull), U8(4),
B(JumpIfUndefined), U8(6), B(JumpIfNotUndefined), U8(16),
B(Ldar), R(2),
B(JumpIfNotNull), U8(16),
B(LdaSmi), I8(81), B(LdaSmi), I8(81),
B(Star), R(3), B(Star), R(2),
B(LdaConstant), U8(1), B(LdaConstant), U8(1),
B(Star), R(3),
/* 57 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw),
B(Star), R(4), B(Star), R(4),
B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2), /* 54 S> */ B(LdaNamedProperty), R(4), U8(1), U8(1),
/* 54 E> */ B(Throw),
/* 54 S> */ B(LdaNamedProperty), R(2), U8(1), U8(1),
B(Star), R(0), B(Star), R(0),
B(LdaUndefined), B(LdaUndefined),
/* 63 S> */ B(Return), /* 63 S> */ B(Return),
...@@ -543,25 +393,24 @@ snippet: " ...@@ -543,25 +393,24 @@ snippet: "
" "
frame size: 5 frame size: 5
parameter count: 1 parameter count: 1
bytecode array length: 42 bytecode array length: 40
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 40 S> */ B(CreateEmptyObjectLiteral), /* 40 S> */ B(CreateEmptyObjectLiteral),
B(Star), R(0), B(Star), R(0),
/* 48 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41), /* 48 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41),
B(Star), R(1), B(Star), R(1),
/* 55 S> */ B(Star), R(2), /* 55 S> */ B(JumpIfNull), U8(4),
B(JumpIfUndefined), U8(6), B(JumpIfNotUndefined), U8(16),
B(Ldar), R(2),
B(JumpIfNotNull), U8(16),
B(LdaSmi), I8(81), B(LdaSmi), I8(81),
B(Star), R(3), B(Star), R(2),
B(LdaConstant), U8(1), B(LdaConstant), U8(1),
B(Star), R(4), B(Star), R(3),
B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2), /* 66 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
/* 57 E> */ B(Throw), B(Throw),
/* 59 E> */ B(LdaNamedProperty), R(2), U8(1), U8(1), /* 61 S> */ B(Star), R(4),
/* 61 E> */ B(StaNamedProperty), R(0), U8(2), U8(3), B(LdaNamedProperty), R(4), U8(1), U8(1),
B(StaNamedProperty), R(0), U8(2), U8(3),
B(LdaUndefined), B(LdaUndefined),
/* 72 S> */ B(Return), /* 72 S> */ B(Return),
] ]
...@@ -580,33 +429,28 @@ snippet: " ...@@ -580,33 +429,28 @@ snippet: "
" "
frame size: 6 frame size: 6
parameter count: 1 parameter count: 1
bytecode array length: 61 bytecode array length: 50
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41), /* 45 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41),
B(Star), R(1), B(Star), R(1),
/* 62 S> */ B(Star), R(2), /* 62 S> */ B(JumpIfNull), U8(4),
B(JumpIfUndefined), U8(6), B(JumpIfNotUndefined), U8(16),
B(Ldar), R(2),
B(JumpIfNotNull), U8(16),
B(LdaSmi), I8(81), B(LdaSmi), I8(81),
B(Star), R(4), B(Star), R(2),
B(LdaConstant), U8(1), B(LdaConstant), U8(1),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kNewTypeError), R(4), U8(2),
/* 64 E> */ B(Throw),
B(LdaNamedProperty), R(2), U8(1), U8(1),
B(Star), R(3), B(Star), R(3),
/* 64 S> */ B(JumpIfNotUndefined), U8(5), /* 74 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw),
B(Star), R(4),
/* 64 S> */ B(LdaConstant), U8(1),
B(Star), R(5),
B(LdaNamedProperty), R(4), U8(1), U8(1),
B(JumpIfNotUndefined), U8(3),
B(LdaZero), B(LdaZero),
B(Jump), U8(4),
B(Ldar), R(3),
B(Star), R(0), B(Star), R(0),
/* 71 S> */ B(LdaConstant), U8(1), /* 71 S> */ B(CallRuntime), U16(Runtime::kCopyDataPropertiesWithExcludedProperties), R(4), U8(2),
B(Star), R(5), B(StaGlobal), U8(2), U8(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kCopyDataPropertiesWithExcludedProperties), R(4), U8(2),
/* 71 E> */ B(StaGlobal), U8(2), U8(3),
B(LdaUndefined), B(LdaUndefined),
/* 80 S> */ B(Return), /* 80 S> */ B(Return),
] ]
......
...@@ -282,7 +282,7 @@ bytecodes: [ ...@@ -282,7 +282,7 @@ bytecodes: [
B(JumpIfFalse), U8(7), B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(7), U8(13), B(LdaNamedProperty), R(6), U8(7), U8(13),
B(JumpIfToBooleanTrue), U8(27), B(JumpIfToBooleanTrue), U8(28),
B(LdaNamedProperty), R(6), U8(8), U8(15), B(LdaNamedProperty), R(6), U8(8), U8(15),
B(Star), R(8), B(Star), R(8),
B(LdaSmi), I8(2), B(LdaSmi), I8(2),
...@@ -290,10 +290,10 @@ bytecodes: [ ...@@ -290,10 +290,10 @@ bytecodes: [
B(Mov), R(8), R(3), B(Mov), R(8), R(3),
/* 23 E> */ B(StackCheck), /* 23 E> */ B(StackCheck),
B(Mov), R(3), R(0), B(Mov), R(3), R(0),
/* 56 S> */ B(LdaZero), /* 56 S> */ B(LdaSmi), I8(1),
B(Star), R(12), B(Star), R(12),
B(Mov), R(8), R(13), B(Mov), R(8), R(13),
B(Jump), U8(53), B(Jump), U8(52),
B(Jump), U8(37), B(Jump), U8(37),
B(Star), R(16), B(Star), R(16),
B(CreateCatchContext), R(16), U8(9), B(CreateCatchContext), R(16), U8(9),
...@@ -314,9 +314,9 @@ bytecodes: [ ...@@ -314,9 +314,9 @@ bytecodes: [
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(13), B(Star), R(13),
B(Star), R(12), B(Star), R(12),
B(Jump), U8(8), B(Jump), U8(7),
B(Star), R(13), B(Star), R(13),
B(LdaSmi), I8(1), B(LdaZero),
B(Star), R(12), B(Star), R(12),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
...@@ -391,14 +391,14 @@ bytecodes: [ ...@@ -391,14 +391,14 @@ bytecodes: [
B(Ldar), R(12), B(Ldar), R(12),
B(SwitchOnSmiNoFeedback), U8(12), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(12), U8(2), I8(0),
B(Jump), U8(19), B(Jump), U8(19),
B(Ldar), R(13),
B(ReThrow),
B(LdaTrue), B(LdaTrue),
B(Star), R(17), B(Star), R(17),
B(Mov), R(2), R(15), B(Mov), R(2), R(15),
B(Mov), R(13), R(16), B(Mov), R(13), R(16),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(15), U8(3), B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(15), U8(3),
/* 68 S> */ B(Return), /* 68 S> */ B(Return),
B(Ldar), R(13),
B(ReThrow),
B(LdaUndefined), B(LdaUndefined),
B(Star), R(13), B(Star), R(13),
B(LdaTrue), B(LdaTrue),
...@@ -438,13 +438,13 @@ constant pool: [ ...@@ -438,13 +438,13 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
Smi [6], Smi [6],
Smi [20], Smi [9],
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
] ]
handlers: [ handlers: [
[20, 426, 428], [20, 426, 428],
[26, 201, 209], [26, 202, 210],
[29, 164, 166], [29, 165, 167],
[270, 316, 318], [270, 316, 318],
] ]
...@@ -716,7 +716,7 @@ bytecodes: [ ...@@ -716,7 +716,7 @@ bytecodes: [
B(JumpIfFalse), U8(7), B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(4), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(4), U8(1),
B(LdaNamedProperty), R(4), U8(4), U8(10), B(LdaNamedProperty), R(4), U8(4), U8(10),
B(JumpIfToBooleanTrue), U8(30), B(JumpIfToBooleanTrue), U8(31),
/* 58 E> */ B(LdaNamedProperty), R(4), U8(5), U8(12), /* 58 E> */ B(LdaNamedProperty), R(4), U8(5), U8(12),
B(Star), R(6), B(Star), R(6),
B(LdaSmi), I8(2), B(LdaSmi), I8(2),
...@@ -726,9 +726,9 @@ bytecodes: [ ...@@ -726,9 +726,9 @@ bytecodes: [
/* 53 E> */ B(StackCheck), /* 53 E> */ B(StackCheck),
/* 87 S> */ B(LdaNamedProperty), R(1), U8(6), U8(16), /* 87 S> */ B(LdaNamedProperty), R(1), U8(6), U8(16),
B(Star), R(11), B(Star), R(11),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(10), B(Star), R(10),
B(Jump), U8(53), B(Jump), U8(52),
B(Jump), U8(37), B(Jump), U8(37),
B(Star), R(14), B(Star), R(14),
B(CreateCatchContext), R(14), U8(7), B(CreateCatchContext), R(14), U8(7),
...@@ -749,9 +749,9 @@ bytecodes: [ ...@@ -749,9 +749,9 @@ bytecodes: [
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(11), B(Star), R(11),
B(Star), R(10), B(Star), R(10),
B(Jump), U8(8), B(Jump), U8(7),
B(Star), R(11), B(Star), R(11),
B(LdaSmi), I8(1), B(LdaZero),
B(Star), R(10), B(Star), R(10),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
...@@ -799,14 +799,14 @@ bytecodes: [ ...@@ -799,14 +799,14 @@ bytecodes: [
B(Ldar), R(10), B(Ldar), R(10),
B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(0),
B(Jump), U8(19), B(Jump), U8(19),
B(Ldar), R(11),
B(ReThrow),
B(LdaFalse), B(LdaFalse),
B(Star), R(15), B(Star), R(15),
B(Mov), R(0), R(13), B(Mov), R(0), R(13),
B(Mov), R(11), R(14), B(Mov), R(11), R(14),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(13), U8(3), B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(13), U8(3),
/* 96 S> */ B(Return), /* 96 S> */ B(Return),
B(Ldar), R(11),
B(ReThrow),
B(LdaUndefined), B(LdaUndefined),
B(Star), R(11), B(Star), R(11),
B(LdaFalse), B(LdaFalse),
...@@ -844,13 +844,13 @@ constant pool: [ ...@@ -844,13 +844,13 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""], ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
Smi [6], Smi [6],
Smi [20], Smi [9],
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
] ]
handlers: [ handlers: [
[16, 305, 307], [16, 305, 307],
[28, 151, 159], [28, 152, 160],
[31, 114, 116], [31, 115, 117],
[220, 230, 232], [220, 230, 232],
] ]
...@@ -166,7 +166,7 @@ bytecodes: [ ...@@ -166,7 +166,7 @@ bytecodes: [
B(JumpIfFalse), U8(7), B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
B(LdaNamedProperty), R(5), U8(3), U8(8), B(LdaNamedProperty), R(5), U8(3), U8(8),
B(JumpIfToBooleanTrue), U8(27), B(JumpIfToBooleanTrue), U8(28),
B(LdaNamedProperty), R(5), U8(4), U8(10), B(LdaNamedProperty), R(5), U8(4), U8(10),
B(Star), R(7), B(Star), R(7),
B(LdaSmi), I8(2), B(LdaSmi), I8(2),
...@@ -174,10 +174,10 @@ bytecodes: [ ...@@ -174,10 +174,10 @@ bytecodes: [
B(Mov), R(7), R(1), B(Mov), R(7), R(1),
/* 54 E> */ B(StackCheck), /* 54 E> */ B(StackCheck),
B(Mov), R(1), R(2), B(Mov), R(1), R(2),
/* 73 S> */ B(LdaZero), /* 73 S> */ B(LdaSmi), I8(1),
B(Star), R(10), B(Star), R(10),
B(Mov), R(7), R(11), B(Mov), R(7), R(11),
B(Jump), U8(49), B(Jump), U8(48),
B(Jump), U8(33), B(Jump), U8(33),
B(Star), R(14), B(Star), R(14),
B(CreateCatchContext), R(14), U8(5), B(CreateCatchContext), R(14), U8(5),
...@@ -195,9 +195,9 @@ bytecodes: [ ...@@ -195,9 +195,9 @@ bytecodes: [
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(11), B(Star), R(11),
B(Star), R(10), B(Star), R(10),
B(Jump), U8(8), B(Jump), U8(7),
B(Star), R(11), B(Star), R(11),
B(LdaSmi), I8(1), B(LdaZero),
B(Star), R(10), B(Star), R(10),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
...@@ -246,9 +246,9 @@ bytecodes: [ ...@@ -246,9 +246,9 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(8), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(8), U8(2), I8(0),
B(Jump), U8(8), B(Jump), U8(8),
B(Ldar), R(11), B(Ldar), R(11),
/* 85 S> */ B(Return),
B(Ldar), R(11),
B(ReThrow), B(ReThrow),
B(Ldar), R(11),
/* 85 S> */ B(Return),
B(LdaUndefined), B(LdaUndefined),
/* 85 S> */ B(Return), /* 85 S> */ B(Return),
] ]
...@@ -265,8 +265,8 @@ constant pool: [ ...@@ -265,8 +265,8 @@ constant pool: [
Smi [9], Smi [9],
] ]
handlers: [ handlers: [
[11, 124, 132], [11, 125, 133],
[14, 91, 93], [14, 92, 94],
[193, 203, 205], [193, 203, 205],
] ]
...@@ -443,7 +443,7 @@ bytecodes: [ ...@@ -443,7 +443,7 @@ bytecodes: [
B(JumpIfFalse), U8(7), B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(LdaNamedProperty), R(3), U8(4), U8(10), B(LdaNamedProperty), R(3), U8(4), U8(10),
B(JumpIfToBooleanTrue), U8(30), B(JumpIfToBooleanTrue), U8(31),
/* 67 E> */ B(LdaNamedProperty), R(3), U8(5), U8(12), /* 67 E> */ B(LdaNamedProperty), R(3), U8(5), U8(12),
B(Star), R(5), B(Star), R(5),
B(LdaSmi), I8(2), B(LdaSmi), I8(2),
...@@ -453,9 +453,9 @@ bytecodes: [ ...@@ -453,9 +453,9 @@ bytecodes: [
/* 62 E> */ B(StackCheck), /* 62 E> */ B(StackCheck),
/* 96 S> */ B(LdaNamedProperty), R(0), U8(6), U8(16), /* 96 S> */ B(LdaNamedProperty), R(0), U8(6), U8(16),
B(Star), R(9), B(Star), R(9),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(8), B(Star), R(8),
B(Jump), U8(49), B(Jump), U8(48),
B(Jump), U8(33), B(Jump), U8(33),
B(Star), R(12), B(Star), R(12),
B(CreateCatchContext), R(12), U8(7), B(CreateCatchContext), R(12), U8(7),
...@@ -473,9 +473,9 @@ bytecodes: [ ...@@ -473,9 +473,9 @@ bytecodes: [
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(9), B(Star), R(9),
B(Star), R(8), B(Star), R(8),
B(Jump), U8(8), B(Jump), U8(7),
B(Star), R(9), B(Star), R(9),
B(LdaSmi), I8(1), B(LdaZero),
B(Star), R(8), B(Star), R(8),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
...@@ -524,9 +524,9 @@ bytecodes: [ ...@@ -524,9 +524,9 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(0),
B(Jump), U8(8), B(Jump), U8(8),
B(Ldar), R(9), B(Ldar), R(9),
/* 105 S> */ B(Return),
B(Ldar), R(9),
B(ReThrow), B(ReThrow),
B(Ldar), R(9),
/* 105 S> */ B(Return),
B(LdaUndefined), B(LdaUndefined),
/* 105 S> */ B(Return), /* 105 S> */ B(Return),
] ]
...@@ -545,8 +545,8 @@ constant pool: [ ...@@ -545,8 +545,8 @@ constant pool: [
Smi [9], Smi [9],
] ]
handlers: [ handlers: [
[13, 132, 140], [13, 133, 141],
[16, 99, 101], [16, 100, 102],
[201, 211, 213], [201, 211, 213],
] ]
...@@ -794,7 +794,7 @@ bytecodes: [ ...@@ -794,7 +794,7 @@ bytecodes: [
B(JumpIfFalse), U8(7), B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(6), U8(8), B(LdaNamedProperty), R(6), U8(6), U8(8),
B(JumpIfToBooleanTrue), U8(65), B(JumpIfToBooleanTrue), U8(66),
B(LdaNamedProperty), R(6), U8(7), U8(10), B(LdaNamedProperty), R(6), U8(7), U8(10),
B(Star), R(8), B(Star), R(8),
B(LdaSmi), I8(2), B(LdaSmi), I8(2),
...@@ -813,13 +813,13 @@ bytecodes: [ ...@@ -813,13 +813,13 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(8), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(8), U8(2), I8(0),
B(Ldar), R(15), B(Ldar), R(15),
/* 40 E> */ B(Throw), /* 40 E> */ B(Throw),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(11), B(Star), R(11),
B(Mov), R(15), R(12), B(Mov), R(15), R(12),
B(Jump), U8(55), B(Jump), U8(54),
B(LdaZero), B(LdaZero),
B(Star), R(7), B(Star), R(7),
B(JumpLoop), U8(84), I8(0), B(JumpLoop), U8(85), I8(0),
B(Jump), U8(33), B(Jump), U8(33),
B(Star), R(15), B(Star), R(15),
B(CreateCatchContext), R(15), U8(10), B(CreateCatchContext), R(15), U8(10),
...@@ -837,9 +837,9 @@ bytecodes: [ ...@@ -837,9 +837,9 @@ bytecodes: [
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(12), B(Star), R(12),
B(Star), R(11), B(Star), R(11),
B(Jump), U8(8), B(Jump), U8(7),
B(Star), R(12), B(Star), R(12),
B(LdaSmi), I8(1), B(LdaZero),
B(Star), R(11), B(Star), R(11),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
...@@ -888,9 +888,9 @@ bytecodes: [ ...@@ -888,9 +888,9 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(13), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(13), U8(2), I8(0),
B(Jump), U8(8), B(Jump), U8(8),
B(Ldar), R(12), B(Ldar), R(12),
/* 49 S> */ B(Return),
B(Ldar), R(12),
B(ReThrow), B(ReThrow),
B(Ldar), R(12),
/* 49 S> */ B(Return),
B(LdaUndefined), B(LdaUndefined),
/* 49 S> */ B(Return), /* 49 S> */ B(Return),
] ]
...@@ -903,7 +903,7 @@ constant pool: [ ...@@ -903,7 +903,7 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
Smi [15], Smi [16],
Smi [7], Smi [7],
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
...@@ -912,8 +912,8 @@ constant pool: [ ...@@ -912,8 +912,8 @@ constant pool: [
Smi [9], Smi [9],
] ]
handlers: [ handlers: [
[48, 199, 207], [48, 200, 208],
[51, 166, 168], [51, 167, 169],
[268, 278, 280], [268, 278, 280],
] ]
......
...@@ -138,7 +138,7 @@ bytecodes: [ ...@@ -138,7 +138,7 @@ bytecodes: [
B(JumpIfFalse), U8(7), B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
B(LdaNamedProperty), R(6), U8(7), U8(9), B(LdaNamedProperty), R(6), U8(7), U8(9),
B(JumpIfToBooleanTrue), U8(65), B(JumpIfToBooleanTrue), U8(66),
B(LdaNamedProperty), R(6), U8(8), U8(11), B(LdaNamedProperty), R(6), U8(8), U8(11),
B(Star), R(8), B(Star), R(8),
B(LdaSmi), I8(2), B(LdaSmi), I8(2),
...@@ -157,13 +157,13 @@ bytecodes: [ ...@@ -157,13 +157,13 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(9), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(9), U8(2), I8(0),
B(Ldar), R(15), B(Ldar), R(15),
/* 36 E> */ B(Throw), /* 36 E> */ B(Throw),
B(LdaZero), B(LdaSmi), I8(1),
B(Star), R(11), B(Star), R(11),
B(Mov), R(15), R(12), B(Mov), R(15), R(12),
B(Jump), U8(55), B(Jump), U8(54),
B(LdaZero), B(LdaZero),
B(Star), R(7), B(Star), R(7),
B(JumpLoop), U8(84), I8(0), B(JumpLoop), U8(85), I8(0),
B(Jump), U8(33), B(Jump), U8(33),
B(Star), R(15), B(Star), R(15),
B(CreateCatchContext), R(15), U8(11), B(CreateCatchContext), R(15), U8(11),
...@@ -181,9 +181,9 @@ bytecodes: [ ...@@ -181,9 +181,9 @@ bytecodes: [
B(LdaSmi), I8(-1), B(LdaSmi), I8(-1),
B(Star), R(12), B(Star), R(12),
B(Star), R(11), B(Star), R(11),
B(Jump), U8(8), B(Jump), U8(7),
B(Star), R(12), B(Star), R(12),
B(LdaSmi), I8(1), B(LdaZero),
B(Star), R(11), B(Star), R(11),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
...@@ -232,9 +232,9 @@ bytecodes: [ ...@@ -232,9 +232,9 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(14), U8(2), I8(0), B(SwitchOnSmiNoFeedback), U8(14), U8(2), I8(0),
B(Jump), U8(8), B(Jump), U8(8),
B(Ldar), R(12), B(Ldar), R(12),
/* 44 S> */ B(Return),
B(Ldar), R(12),
B(ReThrow), B(ReThrow),
B(Ldar), R(12),
/* 44 S> */ B(Return),
B(LdaUndefined), B(LdaUndefined),
/* 44 S> */ B(Return), /* 44 S> */ B(Return),
] ]
...@@ -248,7 +248,7 @@ constant pool: [ ...@@ -248,7 +248,7 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
Smi [15], Smi [16],
Smi [7], Smi [7],
SCOPE_INFO_TYPE, SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"], ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
...@@ -257,8 +257,8 @@ constant pool: [ ...@@ -257,8 +257,8 @@ constant pool: [
Smi [9], Smi [9],
] ]
handlers: [ handlers: [
[48, 202, 210], [48, 203, 211],
[51, 169, 171], [51, 170, 172],
[271, 281, 283], [271, 281, 283],
] ]
...@@ -288,8 +288,8 @@ bytecodes: [ ...@@ -288,8 +288,8 @@ bytecodes: [
B(Ldar), R(1), B(Ldar), R(1),
/* 54 S> */ B(Return), /* 54 S> */ B(Return),
/* 43 S> */ B(LdaGlobal), U8(4), U8(0), /* 43 S> */ B(LdaGlobal), U8(4), U8(0),
B(Star), R(8), B(Star), R(5),
/* 50 E> */ B(CallUndefinedReceiver0), R(8), U8(2), /* 50 E> */ B(CallUndefinedReceiver0), R(5), U8(2),
B(Star), R(6), B(Star), R(6),
B(LdaNamedProperty), R(6), U8(5), U8(4), B(LdaNamedProperty), R(6), U8(5), U8(4),
B(Star), R(7), B(Star), R(7),
......
...@@ -94,7 +94,7 @@ snippet: " ...@@ -94,7 +94,7 @@ snippet: "
" "
frame size: 10 frame size: 10
parameter count: 1 parameter count: 1
bytecode array length: 133 bytecode array length: 131
bytecodes: [ bytecodes: [
/* 30 E> */ B(StackCheck), /* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0), B(CreateBlockContext), U8(0),
...@@ -115,32 +115,31 @@ bytecodes: [ ...@@ -115,32 +115,31 @@ bytecodes: [
B(Star), R(4), B(Star), R(4),
B(LdaConstant), U8(4), B(LdaConstant), U8(4),
B(Star), R(3), B(Star), R(3),
/* 101 S> */ B(CreateArrayLiteral), U8(5), U8(5), U8(37), /* 101 S> */ B(CreateArrayLiteral), U8(5), U8(2), U8(37),
B(Star), R(7),
B(LdaNamedProperty), R(7), U8(6), U8(3),
B(Star), R(8), B(Star), R(8),
B(LdaNamedProperty), R(8), U8(6), U8(6), B(CallProperty0), R(8), R(7), U8(5),
B(Star), R(9),
B(CallProperty0), R(9), R(8), U8(8),
B(Mov), R(5), R(2), B(Mov), R(5), R(2),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(7),
B(LdaNamedProperty), R(7), U8(7), U8(10),
B(Star), R(6), B(Star), R(6),
B(CallProperty0), R(6), R(7), U8(12), B(LdaNamedProperty), R(6), U8(7), U8(7),
B(Star), R(5), B(Star), R(5),
B(CallProperty0), R(5), R(6), U8(16),
B(Star), R(9),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
B(LdaNamedProperty), R(5), U8(8), U8(14), B(LdaNamedProperty), R(9), U8(8), U8(18),
B(JumpIfToBooleanTrue), U8(21), B(JumpIfToBooleanTrue), U8(19),
B(LdaNamedProperty), R(5), U8(9), U8(16), B(LdaNamedProperty), R(9), U8(9), U8(9),
B(Star), R(5), B(StaInArrayLiteral), R(4), R(3), U8(14),
B(StaInArrayLiteral), R(4), R(3), U8(3),
B(Ldar), R(3), B(Ldar), R(3),
B(Inc), U8(2), B(Inc), U8(13),
B(Star), R(3), B(Star), R(3),
B(JumpLoop), U8(35), I8(0), B(JumpLoop), U8(33), I8(0),
B(LdaSmi), I8(4), B(LdaSmi), I8(4),
B(StaInArrayLiteral), R(4), R(3), U8(3), B(StaInArrayLiteral), R(4), R(3), U8(14),
B(Mov), R(4), R(3), B(Mov), R(4), R(3),
B(CallJSRuntime), U8(%reflect_construct), R(2), U8(2), B(CallJSRuntime), U8(%reflect_construct), R(2), U8(2),
B(LdaUndefined), B(LdaUndefined),
......
...@@ -93,7 +93,7 @@ snippet: " ...@@ -93,7 +93,7 @@ snippet: "
" "
frame size: 13 frame size: 13
parameter count: 1 parameter count: 1
bytecode array length: 130 bytecode array length: 128
bytecodes: [ bytecodes: [
B(CreateRestParameter), B(CreateRestParameter),
B(Star), R(2), B(Star), R(2),
...@@ -112,28 +112,27 @@ bytecodes: [ ...@@ -112,28 +112,27 @@ bytecodes: [
B(Inc), U8(3), B(Inc), U8(3),
/* 152 S> */ B(Star), R(6), /* 152 S> */ B(Star), R(6),
B(LdaNamedProperty), R(2), U8(0), U8(4), B(LdaNamedProperty), R(2), U8(0), U8(4),
B(Star), R(12), B(Star), R(11),
B(CallProperty0), R(12), R(2), U8(6), B(CallProperty0), R(11), R(2), U8(6),
B(Mov), R(2), R(11), B(Mov), R(2), R(10),
B(Mov), R(1), R(4), B(Mov), R(1), R(4),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0), B(CallRuntime), U16(Runtime::kThrowSymbolIteratorInvalid), R(0), U8(0),
B(Star), R(10),
B(LdaNamedProperty), R(10), U8(1), U8(8),
B(Star), R(9), B(Star), R(9),
B(CallProperty0), R(9), R(10), U8(10), B(LdaNamedProperty), R(9), U8(1), U8(8),
B(Star), R(8), B(Star), R(8),
B(CallProperty0), R(8), R(9), U8(14),
B(Star), R(12),
B(JumpIfJSReceiver), U8(7), B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1), B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdaNamedProperty), R(8), U8(2), U8(12), B(LdaNamedProperty), R(12), U8(2), U8(16),
B(JumpIfToBooleanTrue), U8(21), B(JumpIfToBooleanTrue), U8(19),
B(LdaNamedProperty), R(8), U8(3), U8(14), B(LdaNamedProperty), R(12), U8(3), U8(10),
B(Star), R(8),
B(StaInArrayLiteral), R(7), R(6), U8(1), B(StaInArrayLiteral), R(7), R(6), U8(1),
B(Ldar), R(6), B(Ldar), R(6),
B(Inc), U8(3), B(Inc), U8(3),
B(Star), R(6), B(Star), R(6),
B(JumpLoop), U8(35), I8(0), B(JumpLoop), U8(33), I8(0),
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
B(StaInArrayLiteral), R(7), R(6), U8(1), B(StaInArrayLiteral), R(7), R(6), U8(1),
B(Mov), R(5), R(6), B(Mov), R(5), R(6),
......
...@@ -3641,8 +3641,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3641,8 +3641,16 @@ TEST(MaybeAssignedInsideLoop) {
Input module_and_script_tests[] = { Input module_and_script_tests[] = {
{true, "for (j=x; j<10; ++j) { foo = j }", top}, {true, "for (j=x; j<10; ++j) { foo = j }", top},
{true, "for (j=x; j<10; ++j) { [foo] = [j] }", top}, {true, "for (j=x; j<10; ++j) { [foo] = [j] }", top},
{true, "for (j=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
{true, "for (j=x; j<10; ++j) { var foo = j }", top}, {true, "for (j=x; j<10; ++j) { var foo = j }", top},
{true, "for (j=x; j<10; ++j) { var [foo] = [j] }", top}, {true, "for (j=x; j<10; ++j) { var [foo] = [j] }", top},
{true, "for (j=x; j<10; ++j) { var [[foo]=[42]] = [] }", top},
{true, "for (j=x; j<10; ++j) { var foo; foo = j }", top},
{true, "for (j=x; j<10; ++j) { var foo; [foo] = [j] }", top},
{true, "for (j=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (j=x; j<10; ++j) { let foo; foo = j }", {0}},
{true, "for (j=x; j<10; ++j) { let foo; [foo] = [j] }", {0}},
{true, "for (j=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0}},
{false, "for (j=x; j<10; ++j) { let foo = j }", {0}}, {false, "for (j=x; j<10; ++j) { let foo = j }", {0}},
{false, "for (j=x; j<10; ++j) { let [foo] = [j] }", {0}}, {false, "for (j=x; j<10; ++j) { let [foo] = [j] }", {0}},
{false, "for (j=x; j<10; ++j) { const foo = j }", {0}}, {false, "for (j=x; j<10; ++j) { const foo = j }", {0}},
...@@ -3651,8 +3659,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3651,8 +3659,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for ({j}=x; j<10; ++j) { foo = j }", top}, {true, "for ({j}=x; j<10; ++j) { foo = j }", top},
{true, "for ({j}=x; j<10; ++j) { [foo] = [j] }", top}, {true, "for ({j}=x; j<10; ++j) { [foo] = [j] }", top},
{true, "for ({j}=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
{true, "for ({j}=x; j<10; ++j) { var foo = j }", top}, {true, "for ({j}=x; j<10; ++j) { var foo = j }", top},
{true, "for ({j}=x; j<10; ++j) { var [foo] = [j] }", top}, {true, "for ({j}=x; j<10; ++j) { var [foo] = [j] }", top},
{true, "for ({j}=x; j<10; ++j) { var [[foo]=[42]] = [] }", top},
{true, "for ({j}=x; j<10; ++j) { var foo; foo = j }", top},
{true, "for ({j}=x; j<10; ++j) { var foo; [foo] = [j] }", top},
{true, "for ({j}=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
{true, "for ({j}=x; j<10; ++j) { let foo; foo = j }", {0}},
{true, "for ({j}=x; j<10; ++j) { let foo; [foo] = [j] }", {0}},
{true, "for ({j}=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0}},
{false, "for ({j}=x; j<10; ++j) { let foo = j }", {0}}, {false, "for ({j}=x; j<10; ++j) { let foo = j }", {0}},
{false, "for ({j}=x; j<10; ++j) { let [foo] = [j] }", {0}}, {false, "for ({j}=x; j<10; ++j) { let [foo] = [j] }", {0}},
{false, "for ({j}=x; j<10; ++j) { const foo = j }", {0}}, {false, "for ({j}=x; j<10; ++j) { const foo = j }", {0}},
...@@ -3661,8 +3677,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3661,8 +3677,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (var j=x; j<10; ++j) { foo = j }", top}, {true, "for (var j=x; j<10; ++j) { foo = j }", top},
{true, "for (var j=x; j<10; ++j) { [foo] = [j] }", top}, {true, "for (var j=x; j<10; ++j) { [foo] = [j] }", top},
{true, "for (var j=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
{true, "for (var j=x; j<10; ++j) { var foo = j }", top}, {true, "for (var j=x; j<10; ++j) { var foo = j }", top},
{true, "for (var j=x; j<10; ++j) { var [foo] = [j] }", top}, {true, "for (var j=x; j<10; ++j) { var [foo] = [j] }", top},
{true, "for (var j=x; j<10; ++j) { var [[foo]=[42]] = [] }", top},
{true, "for (var j=x; j<10; ++j) { var foo; foo = j }", top},
{true, "for (var j=x; j<10; ++j) { var foo; [foo] = [j] }", top},
{true, "for (var j=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (var j=x; j<10; ++j) { let foo; foo = j }", {0}},
{true, "for (var j=x; j<10; ++j) { let foo; [foo] = [j] }", {0}},
{true, "for (var j=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0}},
{false, "for (var j=x; j<10; ++j) { let foo = j }", {0}}, {false, "for (var j=x; j<10; ++j) { let foo = j }", {0}},
{false, "for (var j=x; j<10; ++j) { let [foo] = [j] }", {0}}, {false, "for (var j=x; j<10; ++j) { let [foo] = [j] }", {0}},
{false, "for (var j=x; j<10; ++j) { const foo = j }", {0}}, {false, "for (var j=x; j<10; ++j) { const foo = j }", {0}},
...@@ -3671,8 +3695,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3671,8 +3695,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (var {j}=x; j<10; ++j) { foo = j }", top}, {true, "for (var {j}=x; j<10; ++j) { foo = j }", top},
{true, "for (var {j}=x; j<10; ++j) { [foo] = [j] }", top}, {true, "for (var {j}=x; j<10; ++j) { [foo] = [j] }", top},
{true, "for (var {j}=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
{true, "for (var {j}=x; j<10; ++j) { var foo = j }", top}, {true, "for (var {j}=x; j<10; ++j) { var foo = j }", top},
{true, "for (var {j}=x; j<10; ++j) { var [foo] = [j] }", top}, {true, "for (var {j}=x; j<10; ++j) { var [foo] = [j] }", top},
{true, "for (var {j}=x; j<10; ++j) { var [[foo]=[42]] = [] }", top},
{true, "for (var {j}=x; j<10; ++j) { var foo; foo = j }", top},
{true, "for (var {j}=x; j<10; ++j) { var foo; [foo] = [j] }", top},
{true, "for (var {j}=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (var {j}=x; j<10; ++j) { let foo; foo = j }", {0}},
{true, "for (var {j}=x; j<10; ++j) { let foo; [foo] = [j] }", {0}},
{true, "for (var {j}=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0}},
{false, "for (var {j}=x; j<10; ++j) { let foo = j }", {0}}, {false, "for (var {j}=x; j<10; ++j) { let foo = j }", {0}},
{false, "for (var {j}=x; j<10; ++j) { let [foo] = [j] }", {0}}, {false, "for (var {j}=x; j<10; ++j) { let [foo] = [j] }", {0}},
{false, "for (var {j}=x; j<10; ++j) { const foo = j }", {0}}, {false, "for (var {j}=x; j<10; ++j) { const foo = j }", {0}},
...@@ -3681,8 +3713,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3681,8 +3713,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (let j=x; j<10; ++j) { foo = j }", top}, {true, "for (let j=x; j<10; ++j) { foo = j }", top},
{true, "for (let j=x; j<10; ++j) { [foo] = [j] }", top}, {true, "for (let j=x; j<10; ++j) { [foo] = [j] }", top},
{true, "for (let j=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
{true, "for (let j=x; j<10; ++j) { var foo = j }", top}, {true, "for (let j=x; j<10; ++j) { var foo = j }", top},
{true, "for (let j=x; j<10; ++j) { var [foo] = [j] }", top}, {true, "for (let j=x; j<10; ++j) { var [foo] = [j] }", top},
{true, "for (let j=x; j<10; ++j) { var [[foo]=[42]] = [] }", top},
{true, "for (let j=x; j<10; ++j) { var foo; foo = j }", top},
{true, "for (let j=x; j<10; ++j) { var foo; [foo] = [j] }", top},
{true, "for (let j=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (let j=x; j<10; ++j) { let foo; foo = j }", {0, 0}},
{true, "for (let j=x; j<10; ++j) { let foo; [foo] = [j] }", {0, 0}},
{true, "for (let j=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0, 0}},
{false, "for (let j=x; j<10; ++j) { let foo = j }", {0, 0}}, {false, "for (let j=x; j<10; ++j) { let foo = j }", {0, 0}},
{false, "for (let j=x; j<10; ++j) { let [foo] = [j] }", {0, 0, 0}}, {false, "for (let j=x; j<10; ++j) { let [foo] = [j] }", {0, 0, 0}},
{false, "for (let j=x; j<10; ++j) { const foo = j }", {0, 0}}, {false, "for (let j=x; j<10; ++j) { const foo = j }", {0, 0}},
...@@ -3693,8 +3733,18 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3693,8 +3733,18 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (let {j}=x; j<10; ++j) { foo = j }", top}, {true, "for (let {j}=x; j<10; ++j) { foo = j }", top},
{true, "for (let {j}=x; j<10; ++j) { [foo] = [j] }", top}, {true, "for (let {j}=x; j<10; ++j) { [foo] = [j] }", top},
{true, "for (let {j}=x; j<10; ++j) { [[foo]=[42]] = [] }", top},
{true, "for (let {j}=x; j<10; ++j) { var foo = j }", top}, {true, "for (let {j}=x; j<10; ++j) { var foo = j }", top},
{true, "for (let {j}=x; j<10; ++j) { var [foo] = [j] }", top}, {true, "for (let {j}=x; j<10; ++j) { var [foo] = [j] }", top},
{true, "for (let {j}=x; j<10; ++j) { var [[foo]=[42]] = [] }", top},
{true, "for (let {j}=x; j<10; ++j) { var foo; foo = j }", top},
{true, "for (let {j}=x; j<10; ++j) { var foo; [foo] = [j] }", top},
{true, "for (let {j}=x; j<10; ++j) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (let {j}=x; j<10; ++j) { let foo; foo = j }", {0, 0}},
{true, "for (let {j}=x; j<10; ++j) { let foo; [foo] = [j] }", {0, 0}},
{true,
"for (let {j}=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }",
{0, 0}},
{false, "for (let {j}=x; j<10; ++j) { let foo = j }", {0, 0}}, {false, "for (let {j}=x; j<10; ++j) { let foo = j }", {0, 0}},
{false, "for (let {j}=x; j<10; ++j) { let [foo] = [j] }", {0, 0, 0}}, {false, "for (let {j}=x; j<10; ++j) { let [foo] = [j] }", {0, 0, 0}},
{false, "for (let {j}=x; j<10; ++j) { const foo = j }", {0, 0}}, {false, "for (let {j}=x; j<10; ++j) { const foo = j }", {0, 0}},
...@@ -3705,8 +3755,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3705,8 +3755,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (j of x) { foo = j }", top}, {true, "for (j of x) { foo = j }", top},
{true, "for (j of x) { [foo] = [j] }", top}, {true, "for (j of x) { [foo] = [j] }", top},
{true, "for (j of x) { [[foo]=[42]] = [] }", top},
{true, "for (j of x) { var foo = j }", top}, {true, "for (j of x) { var foo = j }", top},
{true, "for (j of x) { var [foo] = [j] }", top}, {true, "for (j of x) { var [foo] = [j] }", top},
{true, "for (j of x) { var [[foo]=[42]] = [] }", top},
{true, "for (j of x) { var foo; foo = j }", top},
{true, "for (j of x) { var foo; [foo] = [j] }", top},
{true, "for (j of x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (j of x) { let foo; foo = j }", {1}},
{true, "for (j of x) { let foo; [foo] = [j] }", {1}},
{true, "for (j of x) { let foo; [[foo]=[42]] = [] }", {1}},
{false, "for (j of x) { let foo = j }", {1}}, {false, "for (j of x) { let foo = j }", {1}},
{false, "for (j of x) { let [foo] = [j] }", {1}}, {false, "for (j of x) { let [foo] = [j] }", {1}},
{false, "for (j of x) { const foo = j }", {1}}, {false, "for (j of x) { const foo = j }", {1}},
...@@ -3715,8 +3773,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3715,8 +3773,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for ({j} of x) { foo = j }", top}, {true, "for ({j} of x) { foo = j }", top},
{true, "for ({j} of x) { [foo] = [j] }", top}, {true, "for ({j} of x) { [foo] = [j] }", top},
{true, "for ({j} of x) { [[foo]=[42]] = [] }", top},
{true, "for ({j} of x) { var foo = j }", top}, {true, "for ({j} of x) { var foo = j }", top},
{true, "for ({j} of x) { var [foo] = [j] }", top}, {true, "for ({j} of x) { var [foo] = [j] }", top},
{true, "for ({j} of x) { var [[foo]=[42]] = [] }", top},
{true, "for ({j} of x) { var foo; foo = j }", top},
{true, "for ({j} of x) { var foo; [foo] = [j] }", top},
{true, "for ({j} of x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for ({j} of x) { let foo; foo = j }", {1}},
{true, "for ({j} of x) { let foo; [foo] = [j] }", {1}},
{true, "for ({j} of x) { let foo; [[foo]=[42]] = [] }", {1}},
{false, "for ({j} of x) { let foo = j }", {1}}, {false, "for ({j} of x) { let foo = j }", {1}},
{false, "for ({j} of x) { let [foo] = [j] }", {1}}, {false, "for ({j} of x) { let [foo] = [j] }", {1}},
{false, "for ({j} of x) { const foo = j }", {1}}, {false, "for ({j} of x) { const foo = j }", {1}},
...@@ -3725,8 +3791,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3725,8 +3791,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (var j of x) { foo = j }", top}, {true, "for (var j of x) { foo = j }", top},
{true, "for (var j of x) { [foo] = [j] }", top}, {true, "for (var j of x) { [foo] = [j] }", top},
{true, "for (var j of x) { [[foo]=[42]] = [] }", top},
{true, "for (var j of x) { var foo = j }", top}, {true, "for (var j of x) { var foo = j }", top},
{true, "for (var j of x) { var [foo] = [j] }", top}, {true, "for (var j of x) { var [foo] = [j] }", top},
{true, "for (var j of x) { var [[foo]=[42]] = [] }", top},
{true, "for (var j of x) { var foo; foo = j }", top},
{true, "for (var j of x) { var foo; [foo] = [j] }", top},
{true, "for (var j of x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (var j of x) { let foo; foo = j }", {1}},
{true, "for (var j of x) { let foo; [foo] = [j] }", {1}},
{true, "for (var j of x) { let foo; [[foo]=[42]] = [] }", {1}},
{false, "for (var j of x) { let foo = j }", {1}}, {false, "for (var j of x) { let foo = j }", {1}},
{false, "for (var j of x) { let [foo] = [j] }", {1}}, {false, "for (var j of x) { let [foo] = [j] }", {1}},
{false, "for (var j of x) { const foo = j }", {1}}, {false, "for (var j of x) { const foo = j }", {1}},
...@@ -3735,8 +3809,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3735,8 +3809,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (var {j} of x) { foo = j }", top}, {true, "for (var {j} of x) { foo = j }", top},
{true, "for (var {j} of x) { [foo] = [j] }", top}, {true, "for (var {j} of x) { [foo] = [j] }", top},
{true, "for (var {j} of x) { [[foo]=[42]] = [] }", top},
{true, "for (var {j} of x) { var foo = j }", top}, {true, "for (var {j} of x) { var foo = j }", top},
{true, "for (var {j} of x) { var [foo] = [j] }", top}, {true, "for (var {j} of x) { var [foo] = [j] }", top},
{true, "for (var {j} of x) { var [[foo]=[42]] = [] }", top},
{true, "for (var {j} of x) { var foo; foo = j }", top},
{true, "for (var {j} of x) { var foo; [foo] = [j] }", top},
{true, "for (var {j} of x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (var {j} of x) { let foo; foo = j }", {1}},
{true, "for (var {j} of x) { let foo; [foo] = [j] }", {1}},
{true, "for (var {j} of x) { let foo; [[foo]=[42]] = [] }", {1}},
{false, "for (var {j} of x) { let foo = j }", {1}}, {false, "for (var {j} of x) { let foo = j }", {1}},
{false, "for (var {j} of x) { let [foo] = [j] }", {1}}, {false, "for (var {j} of x) { let [foo] = [j] }", {1}},
{false, "for (var {j} of x) { const foo = j }", {1}}, {false, "for (var {j} of x) { const foo = j }", {1}},
...@@ -3745,8 +3827,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3745,8 +3827,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (let j of x) { foo = j }", top}, {true, "for (let j of x) { foo = j }", top},
{true, "for (let j of x) { [foo] = [j] }", top}, {true, "for (let j of x) { [foo] = [j] }", top},
{true, "for (let j of x) { [[foo]=[42]] = [] }", top},
{true, "for (let j of x) { var foo = j }", top}, {true, "for (let j of x) { var foo = j }", top},
{true, "for (let j of x) { var [foo] = [j] }", top}, {true, "for (let j of x) { var [foo] = [j] }", top},
{true, "for (let j of x) { var [[foo]=[42]] = [] }", top},
{true, "for (let j of x) { var foo; foo = j }", top},
{true, "for (let j of x) { var foo; [foo] = [j] }", top},
{true, "for (let j of x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (let j of x) { let foo; foo = j }", {0, 1, 0}},
{true, "for (let j of x) { let foo; [foo] = [j] }", {0, 1, 0}},
{true, "for (let j of x) { let foo; [[foo]=[42]] = [] }", {0, 1, 0}},
{false, "for (let j of x) { let foo = j }", {0, 1, 0}}, {false, "for (let j of x) { let foo = j }", {0, 1, 0}},
{false, "for (let j of x) { let [foo] = [j] }", {0, 1, 0}}, {false, "for (let j of x) { let [foo] = [j] }", {0, 1, 0}},
{false, "for (let j of x) { const foo = j }", {0, 1, 0}}, {false, "for (let j of x) { const foo = j }", {0, 1, 0}},
...@@ -3755,8 +3845,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3755,8 +3845,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (let {j} of x) { foo = j }", top}, {true, "for (let {j} of x) { foo = j }", top},
{true, "for (let {j} of x) { [foo] = [j] }", top}, {true, "for (let {j} of x) { [foo] = [j] }", top},
{true, "for (let {j} of x) { [[foo]=[42]] = [] }", top},
{true, "for (let {j} of x) { var foo = j }", top}, {true, "for (let {j} of x) { var foo = j }", top},
{true, "for (let {j} of x) { var [foo] = [j] }", top}, {true, "for (let {j} of x) { var [foo] = [j] }", top},
{true, "for (let {j} of x) { var [[foo]=[42]] = [] }", top},
{true, "for (let {j} of x) { var foo; foo = j }", top},
{true, "for (let {j} of x) { var foo; [foo] = [j] }", top},
{true, "for (let {j} of x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (let {j} of x) { let foo; foo = j }", {0, 1, 0}},
{true, "for (let {j} of x) { let foo; [foo] = [j] }", {0, 1, 0}},
{true, "for (let {j} of x) { let foo; [[foo]=[42]] = [] }", {0, 1, 0}},
{false, "for (let {j} of x) { let foo = j }", {0, 1, 0}}, {false, "for (let {j} of x) { let foo = j }", {0, 1, 0}},
{false, "for (let {j} of x) { let [foo] = [j] }", {0, 1, 0}}, {false, "for (let {j} of x) { let [foo] = [j] }", {0, 1, 0}},
{false, "for (let {j} of x) { const foo = j }", {0, 1, 0}}, {false, "for (let {j} of x) { const foo = j }", {0, 1, 0}},
...@@ -3765,8 +3863,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3765,8 +3863,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (const j of x) { foo = j }", top}, {true, "for (const j of x) { foo = j }", top},
{true, "for (const j of x) { [foo] = [j] }", top}, {true, "for (const j of x) { [foo] = [j] }", top},
{true, "for (const j of x) { [[foo]=[42]] = [] }", top},
{true, "for (const j of x) { var foo = j }", top}, {true, "for (const j of x) { var foo = j }", top},
{true, "for (const j of x) { var [foo] = [j] }", top}, {true, "for (const j of x) { var [foo] = [j] }", top},
{true, "for (const j of x) { var [[foo]=[42]] = [] }", top},
{true, "for (const j of x) { var foo; foo = j }", top},
{true, "for (const j of x) { var foo; [foo] = [j] }", top},
{true, "for (const j of x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (const j of x) { let foo; foo = j }", {0, 1, 0}},
{true, "for (const j of x) { let foo; [foo] = [j] }", {0, 1, 0}},
{true, "for (const j of x) { let foo; [[foo]=[42]] = [] }", {0, 1, 0}},
{false, "for (const j of x) { let foo = j }", {0, 1, 0}}, {false, "for (const j of x) { let foo = j }", {0, 1, 0}},
{false, "for (const j of x) { let [foo] = [j] }", {0, 1, 0}}, {false, "for (const j of x) { let [foo] = [j] }", {0, 1, 0}},
{false, "for (const j of x) { const foo = j }", {0, 1, 0}}, {false, "for (const j of x) { const foo = j }", {0, 1, 0}},
...@@ -3775,8 +3881,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3775,8 +3881,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (const {j} of x) { foo = j }", top}, {true, "for (const {j} of x) { foo = j }", top},
{true, "for (const {j} of x) { [foo] = [j] }", top}, {true, "for (const {j} of x) { [foo] = [j] }", top},
{true, "for (const {j} of x) { [[foo]=[42]] = [] }", top},
{true, "for (const {j} of x) { var foo = j }", top}, {true, "for (const {j} of x) { var foo = j }", top},
{true, "for (const {j} of x) { var [foo] = [j] }", top}, {true, "for (const {j} of x) { var [foo] = [j] }", top},
{true, "for (const {j} of x) { var [[foo]=[42]] = [] }", top},
{true, "for (const {j} of x) { var foo; foo = j }", top},
{true, "for (const {j} of x) { var foo; [foo] = [j] }", top},
{true, "for (const {j} of x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (const {j} of x) { let foo; foo = j }", {0, 1, 0}},
{true, "for (const {j} of x) { let foo; [foo] = [j] }", {0, 1, 0}},
{true, "for (const {j} of x) { let foo; [[foo]=[42]] = [] }", {0, 1, 0}},
{false, "for (const {j} of x) { let foo = j }", {0, 1, 0}}, {false, "for (const {j} of x) { let foo = j }", {0, 1, 0}},
{false, "for (const {j} of x) { let [foo] = [j] }", {0, 1, 0}}, {false, "for (const {j} of x) { let [foo] = [j] }", {0, 1, 0}},
{false, "for (const {j} of x) { const foo = j }", {0, 1, 0}}, {false, "for (const {j} of x) { const foo = j }", {0, 1, 0}},
...@@ -3785,8 +3899,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3785,8 +3899,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (j in x) { foo = j }", top}, {true, "for (j in x) { foo = j }", top},
{true, "for (j in x) { [foo] = [j] }", top}, {true, "for (j in x) { [foo] = [j] }", top},
{true, "for (j in x) { [[foo]=[42]] = [] }", top},
{true, "for (j in x) { var foo = j }", top}, {true, "for (j in x) { var foo = j }", top},
{true, "for (j in x) { var [foo] = [j] }", top}, {true, "for (j in x) { var [foo] = [j] }", top},
{true, "for (j in x) { var [[foo]=[42]] = [] }", top},
{true, "for (j in x) { var foo; foo = j }", top},
{true, "for (j in x) { var foo; [foo] = [j] }", top},
{true, "for (j in x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (j in x) { let foo; foo = j }", {0}},
{true, "for (j in x) { let foo; [foo] = [j] }", {0}},
{true, "for (j in x) { let foo; [[foo]=[42]] = [] }", {0}},
{false, "for (j in x) { let foo = j }", {0}}, {false, "for (j in x) { let foo = j }", {0}},
{false, "for (j in x) { let [foo] = [j] }", {0}}, {false, "for (j in x) { let [foo] = [j] }", {0}},
{false, "for (j in x) { const foo = j }", {0}}, {false, "for (j in x) { const foo = j }", {0}},
...@@ -3795,8 +3917,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3795,8 +3917,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for ({j} in x) { foo = j }", top}, {true, "for ({j} in x) { foo = j }", top},
{true, "for ({j} in x) { [foo] = [j] }", top}, {true, "for ({j} in x) { [foo] = [j] }", top},
{true, "for ({j} in x) { [[foo]=[42]] = [] }", top},
{true, "for ({j} in x) { var foo = j }", top}, {true, "for ({j} in x) { var foo = j }", top},
{true, "for ({j} in x) { var [foo] = [j] }", top}, {true, "for ({j} in x) { var [foo] = [j] }", top},
{true, "for ({j} in x) { var [[foo]=[42]] = [] }", top},
{true, "for ({j} in x) { var foo; foo = j }", top},
{true, "for ({j} in x) { var foo; [foo] = [j] }", top},
{true, "for ({j} in x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for ({j} in x) { let foo; foo = j }", {0}},
{true, "for ({j} in x) { let foo; [foo] = [j] }", {0}},
{true, "for ({j} in x) { let foo; [[foo]=[42]] = [] }", {0}},
{false, "for ({j} in x) { let foo = j }", {0}}, {false, "for ({j} in x) { let foo = j }", {0}},
{false, "for ({j} in x) { let [foo] = [j] }", {0}}, {false, "for ({j} in x) { let [foo] = [j] }", {0}},
{false, "for ({j} in x) { const foo = j }", {0}}, {false, "for ({j} in x) { const foo = j }", {0}},
...@@ -3805,8 +3935,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3805,8 +3935,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (var j in x) { foo = j }", top}, {true, "for (var j in x) { foo = j }", top},
{true, "for (var j in x) { [foo] = [j] }", top}, {true, "for (var j in x) { [foo] = [j] }", top},
{true, "for (var j in x) { [[foo]=[42]] = [] }", top},
{true, "for (var j in x) { var foo = j }", top}, {true, "for (var j in x) { var foo = j }", top},
{true, "for (var j in x) { var [foo] = [j] }", top}, {true, "for (var j in x) { var [foo] = [j] }", top},
{true, "for (var j in x) { var [[foo]=[42]] = [] }", top},
{true, "for (var j in x) { var foo; foo = j }", top},
{true, "for (var j in x) { var foo; [foo] = [j] }", top},
{true, "for (var j in x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (var j in x) { let foo; foo = j }", {0}},
{true, "for (var j in x) { let foo; [foo] = [j] }", {0}},
{true, "for (var j in x) { let foo; [[foo]=[42]] = [] }", {0}},
{false, "for (var j in x) { let foo = j }", {0}}, {false, "for (var j in x) { let foo = j }", {0}},
{false, "for (var j in x) { let [foo] = [j] }", {0}}, {false, "for (var j in x) { let [foo] = [j] }", {0}},
{false, "for (var j in x) { const foo = j }", {0}}, {false, "for (var j in x) { const foo = j }", {0}},
...@@ -3815,8 +3953,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3815,8 +3953,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (var {j} in x) { foo = j }", top}, {true, "for (var {j} in x) { foo = j }", top},
{true, "for (var {j} in x) { [foo] = [j] }", top}, {true, "for (var {j} in x) { [foo] = [j] }", top},
{true, "for (var {j} in x) { [[foo]=[42]] = [] }", top},
{true, "for (var {j} in x) { var foo = j }", top}, {true, "for (var {j} in x) { var foo = j }", top},
{true, "for (var {j} in x) { var [foo] = [j] }", top}, {true, "for (var {j} in x) { var [foo] = [j] }", top},
{true, "for (var {j} in x) { var [[foo]=[42]] = [] }", top},
{true, "for (var {j} in x) { var foo; foo = j }", top},
{true, "for (var {j} in x) { var foo; [foo] = [j] }", top},
{true, "for (var {j} in x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (var {j} in x) { let foo; foo = j }", {0}},
{true, "for (var {j} in x) { let foo; [foo] = [j] }", {0}},
{true, "for (var {j} in x) { let foo; [[foo]=[42]] = [] }", {0}},
{false, "for (var {j} in x) { let foo = j }", {0}}, {false, "for (var {j} in x) { let foo = j }", {0}},
{false, "for (var {j} in x) { let [foo] = [j] }", {0}}, {false, "for (var {j} in x) { let [foo] = [j] }", {0}},
{false, "for (var {j} in x) { const foo = j }", {0}}, {false, "for (var {j} in x) { const foo = j }", {0}},
...@@ -3825,8 +3971,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3825,8 +3971,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (let j in x) { foo = j }", top}, {true, "for (let j in x) { foo = j }", top},
{true, "for (let j in x) { [foo] = [j] }", top}, {true, "for (let j in x) { [foo] = [j] }", top},
{true, "for (let j in x) { [[foo]=[42]] = [] }", top},
{true, "for (let j in x) { var foo = j }", top}, {true, "for (let j in x) { var foo = j }", top},
{true, "for (let j in x) { var [foo] = [j] }", top}, {true, "for (let j in x) { var [foo] = [j] }", top},
{true, "for (let j in x) { var [[foo]=[42]] = [] }", top},
{true, "for (let j in x) { var foo; foo = j }", top},
{true, "for (let j in x) { var foo; [foo] = [j] }", top},
{true, "for (let j in x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (let j in x) { let foo; foo = j }", {0, 0, 0}},
{true, "for (let j in x) { let foo; [foo] = [j] }", {0, 0, 0}},
{true, "for (let j in x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
{false, "for (let j in x) { let foo = j }", {0, 0, 0}}, {false, "for (let j in x) { let foo = j }", {0, 0, 0}},
{false, "for (let j in x) { let [foo] = [j] }", {0, 0, 0}}, {false, "for (let j in x) { let [foo] = [j] }", {0, 0, 0}},
{false, "for (let j in x) { const foo = j }", {0, 0, 0}}, {false, "for (let j in x) { const foo = j }", {0, 0, 0}},
...@@ -3835,8 +3989,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3835,8 +3989,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (let {j} in x) { foo = j }", top}, {true, "for (let {j} in x) { foo = j }", top},
{true, "for (let {j} in x) { [foo] = [j] }", top}, {true, "for (let {j} in x) { [foo] = [j] }", top},
{true, "for (let {j} in x) { [[foo]=[42]] = [] }", top},
{true, "for (let {j} in x) { var foo = j }", top}, {true, "for (let {j} in x) { var foo = j }", top},
{true, "for (let {j} in x) { var [foo] = [j] }", top}, {true, "for (let {j} in x) { var [foo] = [j] }", top},
{true, "for (let {j} in x) { var [[foo]=[42]] = [] }", top},
{true, "for (let {j} in x) { var foo; foo = j }", top},
{true, "for (let {j} in x) { var foo; [foo] = [j] }", top},
{true, "for (let {j} in x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (let {j} in x) { let foo; foo = j }", {0, 0, 0}},
{true, "for (let {j} in x) { let foo; [foo] = [j] }", {0, 0, 0}},
{true, "for (let {j} in x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
{false, "for (let {j} in x) { let foo = j }", {0, 0, 0}}, {false, "for (let {j} in x) { let foo = j }", {0, 0, 0}},
{false, "for (let {j} in x) { let [foo] = [j] }", {0, 0, 0}}, {false, "for (let {j} in x) { let [foo] = [j] }", {0, 0, 0}},
{false, "for (let {j} in x) { const foo = j }", {0, 0, 0}}, {false, "for (let {j} in x) { const foo = j }", {0, 0, 0}},
...@@ -3845,8 +4007,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3845,8 +4007,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (const j in x) { foo = j }", top}, {true, "for (const j in x) { foo = j }", top},
{true, "for (const j in x) { [foo] = [j] }", top}, {true, "for (const j in x) { [foo] = [j] }", top},
{true, "for (const j in x) { [[foo]=[42]] = [] }", top},
{true, "for (const j in x) { var foo = j }", top}, {true, "for (const j in x) { var foo = j }", top},
{true, "for (const j in x) { var [foo] = [j] }", top}, {true, "for (const j in x) { var [foo] = [j] }", top},
{true, "for (const j in x) { var [[foo]=[42]] = [] }", top},
{true, "for (const j in x) { var foo; foo = j }", top},
{true, "for (const j in x) { var foo; [foo] = [j] }", top},
{true, "for (const j in x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (const j in x) { let foo; foo = j }", {0, 0, 0}},
{true, "for (const j in x) { let foo; [foo] = [j] }", {0, 0, 0}},
{true, "for (const j in x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
{false, "for (const j in x) { let foo = j }", {0, 0, 0}}, {false, "for (const j in x) { let foo = j }", {0, 0, 0}},
{false, "for (const j in x) { let [foo] = [j] }", {0, 0, 0}}, {false, "for (const j in x) { let [foo] = [j] }", {0, 0, 0}},
{false, "for (const j in x) { const foo = j }", {0, 0, 0}}, {false, "for (const j in x) { const foo = j }", {0, 0, 0}},
...@@ -3855,8 +4025,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3855,8 +4025,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "for (const {j} in x) { foo = j }", top}, {true, "for (const {j} in x) { foo = j }", top},
{true, "for (const {j} in x) { [foo] = [j] }", top}, {true, "for (const {j} in x) { [foo] = [j] }", top},
{true, "for (const {j} in x) { [[foo]=[42]] = [] }", top},
{true, "for (const {j} in x) { var foo = j }", top}, {true, "for (const {j} in x) { var foo = j }", top},
{true, "for (const {j} in x) { var [foo] = [j] }", top}, {true, "for (const {j} in x) { var [foo] = [j] }", top},
{true, "for (const {j} in x) { var [[foo]=[42]] = [] }", top},
{true, "for (const {j} in x) { var foo; foo = j }", top},
{true, "for (const {j} in x) { var foo; [foo] = [j] }", top},
{true, "for (const {j} in x) { var foo; [[foo]=[42]] = [] }", top},
{true, "for (const {j} in x) { let foo; foo = j }", {0, 0, 0}},
{true, "for (const {j} in x) { let foo; [foo] = [j] }", {0, 0, 0}},
{true, "for (const {j} in x) { let foo; [[foo]=[42]] = [] }", {0, 0, 0}},
{false, "for (const {j} in x) { let foo = j }", {0, 0, 0}}, {false, "for (const {j} in x) { let foo = j }", {0, 0, 0}},
{false, "for (const {j} in x) { let [foo] = [j] }", {0, 0, 0}}, {false, "for (const {j} in x) { let [foo] = [j] }", {0, 0, 0}},
{false, "for (const {j} in x) { const foo = j }", {0, 0, 0}}, {false, "for (const {j} in x) { const foo = j }", {0, 0, 0}},
...@@ -3865,8 +4043,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3865,8 +4043,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "while (j) { foo = j }", top}, {true, "while (j) { foo = j }", top},
{true, "while (j) { [foo] = [j] }", top}, {true, "while (j) { [foo] = [j] }", top},
{true, "while (j) { [[foo]=[42]] = [] }", top},
{true, "while (j) { var foo = j }", top}, {true, "while (j) { var foo = j }", top},
{true, "while (j) { var [foo] = [j] }", top}, {true, "while (j) { var [foo] = [j] }", top},
{true, "while (j) { var [[foo]=[42]] = [] }", top},
{true, "while (j) { var foo; foo = j }", top},
{true, "while (j) { var foo; [foo] = [j] }", top},
{true, "while (j) { var foo; [[foo]=[42]] = [] }", top},
{true, "while (j) { let foo; foo = j }", {0}},
{true, "while (j) { let foo; [foo] = [j] }", {0}},
{true, "while (j) { let foo; [[foo]=[42]] = [] }", {0}},
{false, "while (j) { let foo = j }", {0}}, {false, "while (j) { let foo = j }", {0}},
{false, "while (j) { let [foo] = [j] }", {0}}, {false, "while (j) { let [foo] = [j] }", {0}},
{false, "while (j) { const foo = j }", {0}}, {false, "while (j) { const foo = j }", {0}},
...@@ -3875,8 +4061,16 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3875,8 +4061,16 @@ TEST(MaybeAssignedInsideLoop) {
{true, "do { foo = j } while (j)", top}, {true, "do { foo = j } while (j)", top},
{true, "do { [foo] = [j] } while (j)", top}, {true, "do { [foo] = [j] } while (j)", top},
{true, "do { [[foo]=[42]] = [] } while (j)", top},
{true, "do { var foo = j } while (j)", top}, {true, "do { var foo = j } while (j)", top},
{true, "do { var [foo] = [j] } while (j)", top}, {true, "do { var [foo] = [j] } while (j)", top},
{true, "do { var [[foo]=[42]] = [] } while (j)", top},
{true, "do { var foo; foo = j } while (j)", top},
{true, "do { var foo; [foo] = [j] } while (j)", top},
{true, "do { var foo; [[foo]=[42]] = [] } while (j)", top},
{true, "do { let foo; foo = j } while (j)", {0}},
{true, "do { let foo; [foo] = [j] } while (j)", {0}},
{true, "do { let foo; [[foo]=[42]] = [] } while (j)", {0}},
{false, "do { let foo = j } while (j)", {0}}, {false, "do { let foo = j } while (j)", {0}},
{false, "do { let [foo] = [j] } while (j)", {0}}, {false, "do { let [foo] = [j] } while (j)", {0}},
{false, "do { const foo = j } while (j)", {0}}, {false, "do { const foo = j } while (j)", {0}},
......
...@@ -145,38 +145,6 @@ ...@@ -145,38 +145,6 @@
'language/eval-code/direct/var-env-lower-lex-catch-non-strict': [FAIL], 'language/eval-code/direct/var-env-lower-lex-catch-non-strict': [FAIL],
# https://bugs.chromium.org/p/v8/issues/detail?id=4951 # https://bugs.chromium.org/p/v8/issues/detail?id=4951
'language/expressions/assignment/dstr-array-elem-iter-rtrn-close-err': [FAIL],
'language/expressions/assignment/dstr-array-elem-iter-thrw-close': [FAIL],
'language/expressions/assignment/dstr-array-elem-iter-thrw-close-err': [FAIL],
'language/expressions/assignment/dstr-array-elem-trlg-iter-list-thrw-close': [FAIL],
'language/expressions/assignment/dstr-array-elem-trlg-iter-list-thrw-close-err': [FAIL],
'language/expressions/assignment/dstr-array-elem-trlg-iter-rest-rtrn-close': [FAIL],
'language/expressions/assignment/dstr-array-elem-trlg-iter-rest-rtrn-close-err': [FAIL],
'language/expressions/assignment/dstr-array-elem-trlg-iter-rest-rtrn-close-null': [FAIL],
'language/expressions/assignment/dstr-array-elem-trlg-iter-rest-thrw-close': [FAIL],
'language/expressions/assignment/dstr-array-elem-trlg-iter-rest-thrw-close-err': [FAIL],
'language/expressions/assignment/dstr-array-rest-iter-rtrn-close': [FAIL],
'language/expressions/assignment/dstr-array-rest-iter-rtrn-close-err': [FAIL],
'language/expressions/assignment/dstr-array-rest-iter-rtrn-close-null': [FAIL],
'language/expressions/assignment/dstr-array-rest-iter-thrw-close': [FAIL],
'language/expressions/assignment/dstr-array-rest-iter-thrw-close-err': [FAIL],
'language/expressions/assignment/dstr-array-rest-lref-err': [FAIL],
'language/statements/for-of/dstr-array-elem-iter-rtrn-close-err': [FAIL],
'language/statements/for-of/dstr-array-elem-iter-thrw-close': [FAIL],
'language/statements/for-of/dstr-array-elem-iter-thrw-close-err': [FAIL],
'language/statements/for-of/dstr-array-elem-trlg-iter-list-thrw-close': [FAIL],
'language/statements/for-of/dstr-array-elem-trlg-iter-list-thrw-close-err': [FAIL],
'language/statements/for-of/dstr-array-elem-trlg-iter-rest-rtrn-close': [FAIL],
'language/statements/for-of/dstr-array-elem-trlg-iter-rest-rtrn-close-err': [FAIL],
'language/statements/for-of/dstr-array-elem-trlg-iter-rest-rtrn-close-null': [FAIL],
'language/statements/for-of/dstr-array-elem-trlg-iter-rest-thrw-close': [FAIL],
'language/statements/for-of/dstr-array-elem-trlg-iter-rest-thrw-close-err': [FAIL],
'language/statements/for-of/dstr-array-rest-iter-rtrn-close': [FAIL],
'language/statements/for-of/dstr-array-rest-iter-rtrn-close-err': [FAIL],
'language/statements/for-of/dstr-array-rest-iter-rtrn-close-null': [FAIL],
'language/statements/for-of/dstr-array-rest-iter-thrw-close': [FAIL],
'language/statements/for-of/dstr-array-rest-iter-thrw-close-err': [FAIL],
'language/statements/for-of/dstr-array-rest-lref-err': [FAIL],
'language/expressions/assignment/destructuring/iterator-destructuring-property-reference-target-evaluation-order': [FAIL], 'language/expressions/assignment/destructuring/iterator-destructuring-property-reference-target-evaluation-order': [FAIL],
'language/expressions/assignment/destructuring/keyed-destructuring-property-reference-target-evaluation-order': [FAIL], 'language/expressions/assignment/destructuring/keyed-destructuring-property-reference-target-evaluation-order': [FAIL],
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment