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 {
friend base::ThreadedListTraits<VariableProxy>;
};
// Left-hand side can only be a property, a global or a (parameter or local)
// slot.
enum LhsKind {
VARIABLE,
// Assignments to a property will use one of several types of property access.
// Otherwise, the assignment is to a non-property (a global, a local slot, a
// parameter slot, or a destructuring pattern).
enum AssignType {
NON_PROPERTY,
NAMED_PROPERTY,
KEYED_PROPERTY,
NAMED_SUPER_PROPERTY,
......@@ -1740,8 +1741,8 @@ class Property final : public Expression {
bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); }
// Returns the properties assign type.
static LhsKind GetAssignType(Property* property) {
if (property == nullptr) return VARIABLE;
static AssignType GetAssignType(Property* property) {
if (property == nullptr) return NON_PROPERTY;
bool super_access = property->IsSuperAccess();
return (property->key()->IsPropertyName())
? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
......
......@@ -1249,7 +1249,7 @@ void AstPrinter::VisitProperty(Property* node) {
IndentedScope indent(this, buf.start(), node->position());
Visit(node->obj());
LhsKind property_kind = Property::GetAssignType(node);
AssignType property_kind = Property::GetAssignType(node);
if (property_kind == NAMED_PROPERTY ||
property_kind == NAMED_SUPER_PROPERTY) {
PrintLiteralIndented("NAME", node->key()->AsLiteral(), false);
......
......@@ -407,7 +407,6 @@ class V8_EXPORT_PRIVATE BytecodeArrayBuilder final {
BytecodeArrayBuilder& JumpIfTrue(ToBooleanMode mode, BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfFalse(ToBooleanMode mode, BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfNotHole(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfJSReceiver(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfNull(BytecodeLabel* label);
BytecodeArrayBuilder& JumpIfNotNull(BytecodeLabel* label);
......
......@@ -97,7 +97,8 @@ class BytecodeGenerator::ContextScope {
class BytecodeGenerator::ControlScope {
public:
explicit ControlScope(BytecodeGenerator* generator)
: generator_(generator), outer_(generator->execution_control()),
: generator_(generator),
outer_(generator->execution_control()),
context_(generator->execution_context()) {
generator_->set_execution_control(this);
}
......@@ -158,6 +159,16 @@ class BytecodeGenerator::ControlScope {
// paths going through the finally-block to dispatch after leaving the block.
class BytecodeGenerator::ControlScope::DeferredCommands final {
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,
Register result_register)
: generator_(generator),
......@@ -165,8 +176,13 @@ class BytecodeGenerator::ControlScope::DeferredCommands final {
token_register_(token_register),
result_register_(result_register),
return_token_(-1),
async_return_token_(-1),
rethrow_token_(-1) {}
async_return_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.
struct Entry {
......@@ -211,7 +227,7 @@ class BytecodeGenerator::ControlScope::DeferredCommands final {
// 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.
void RecordFallThroughPath() {
builder()->LoadLiteral(Smi::FromInt(-1));
builder()->LoadLiteral(Smi::FromInt(kFallthroughToken));
builder()->StoreAccumulatorInRegister(token_register_);
// 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
......@@ -277,7 +293,7 @@ class BytecodeGenerator::ControlScope::DeferredCommands final {
case CMD_ASYNC_RETURN:
return GetAsyncReturnToken();
case CMD_RETHROW:
return GetRethrowToken();
return kRethrowToken;
default:
// TODO(leszeks): We could also search for entries with the same
// command and statement.
......@@ -299,13 +315,6 @@ class BytecodeGenerator::ControlScope::DeferredCommands final {
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 token = static_cast<int>(deferred_.size());
deferred_.push_back({command, statement, token});
......@@ -320,7 +329,6 @@ class BytecodeGenerator::ControlScope::DeferredCommands final {
// Tokens for commands that don't need a statement.
int return_token_;
int async_return_token_;
int rethrow_token_;
};
// Scoped class for dealing with control flow reaching the function level.
......@@ -639,9 +647,7 @@ class BytecodeGenerator::TestResultScope final : public ExpressionResultScope {
// Used when code special cases for TestResultScope and consumes any
// possible value by testing and jumping to a then/else label.
void SetResultConsumedByTest() {
result_consumed_by_test_ = true;
}
void SetResultConsumedByTest() { result_consumed_by_test_ = true; }
bool result_consumed_by_test() { return result_consumed_by_test_; }
// Inverts the control flow of the operation, swapping the then and else
......@@ -1347,8 +1353,7 @@ void BytecodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
VisitForEffect(stmt->expression());
}
void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
}
void BytecodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {}
void BytecodeGenerator::VisitIfStatement(IfStatement* stmt) {
ConditionalControlFlowBuilder conditional_builder(
......@@ -1552,9 +1557,9 @@ void BytecodeGenerator::VisitForInAssignment(Expression* expr) {
// Evaluate assignment starting with the value to be stored in the
// accumulator.
Property* property = expr->AsProperty();
LhsKind assign_type = Property::GetAssignType(property);
AssignType assign_type = Property::GetAssignType(property);
switch (assign_type) {
case VARIABLE: {
case NON_PROPERTY: {
VariableProxy* proxy = expr->AsVariableProxy();
BuildVariableAssignment(proxy->var(), Token::ASSIGN,
proxy->hole_check_mode());
......@@ -2416,20 +2421,37 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
builder()->LoadAccumulatorWithRegister(literal);
}
void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread, Register array,
Register index,
FeedbackSlot index_slot,
FeedbackSlot element_slot) {
RegisterAllocationScope register_scope(this);
Register value = register_allocator()->NewRegister();
builder()->SetExpressionAsStatementPosition(spread->expression());
IteratorRecord iterator =
BuildGetIteratorRecord(spread->expression(), IteratorType::kNormal);
// Fill an array with values from an iterator, starting at a given index,
// optionally setting the 'done' register to true if the loop is exited because
// the iterator is done (as opposed to e.g. the store into the array failing).
//
// In pseudocode:
//
// loop {
// // Make sure we are considered 'done' if .next(), .done or .value fail.
// done = true
// 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);
loop_builder.LoopHeader();
if (done.is_valid()) {
builder()->LoadTrue().StoreAccumulatorInRegister(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
// append the argument.
......@@ -2443,16 +2465,30 @@ void BytecodeGenerator::BuildArrayLiteralSpread(Spread* spread, Register array,
builder()
// value = value.value
->LoadNamedProperty(value, ast_string_constants()->value_string(),
feedback_index(feedback_spec()->AddLoadICSlot()))
.StoreAccumulatorInRegister(value)
feedback_index(next_value_slot));
if (done.is_valid()) {
// done = false
builder()
->StoreAccumulatorInRegister(value)
.LoadFalse()
.StoreAccumulatorInRegister(done)
.LoadAccumulatorWithRegister(value);
}
builder()
// array[index] = value
.StoreInArrayLiteral(array, index, feedback_index(element_slot))
->StoreInArrayLiteral(array, index, feedback_index(element_slot))
// index++
.LoadAccumulatorWithRegister(index)
.UnaryOperation(Token::INC, feedback_index(index_slot))
.StoreAccumulatorInRegister(index);
loop_builder.BindContinueTarget();
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(
......@@ -2566,9 +2602,21 @@ void BytecodeGenerator::BuildCreateArrayLiteral(
for (; current != end; ++current) {
Expression* subexpr = *current;
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();
BuildArrayLiteralSpread(subexpr->AsSpread(), array, index,
real_index_slot, element_slot.Get());
FeedbackSlot real_element_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()) {
// literal[index++] = subexpr
VisitForAccumulatorValue(subexpr);
......@@ -2905,18 +2953,18 @@ void BytecodeGenerator::BuildVariableAssignment(
}
}
void BytecodeGenerator::BuildLoadNamedProperty(Property* property,
void BytecodeGenerator::BuildLoadNamedProperty(const Expression* object_expr,
Register object,
const AstRawString* name) {
if (ShouldOptimizeAsOneShot()) {
builder()->LoadNamedPropertyNoFeedback(object, name);
} else {
FeedbackSlot slot = GetCachedLoadICSlot(property->obj(), name);
FeedbackSlot slot = GetCachedLoadICSlot(object_expr, name);
builder()->LoadNamedProperty(object, name, feedback_index(slot));
}
}
void BytecodeGenerator::BuildStoreNamedProperty(Property* property,
void BytecodeGenerator::BuildStoreNamedProperty(const Expression* object_expr,
Register object,
const AstRawString* name) {
Register value;
......@@ -2928,7 +2976,7 @@ void BytecodeGenerator::BuildStoreNamedProperty(Property* property,
if (ShouldOptimizeAsOneShot()) {
builder()->StoreNamedPropertyNoFeedback(object, name, language_mode());
} else {
FeedbackSlot slot = GetCachedStoreICSlot(property->obj(), name);
FeedbackSlot slot = GetCachedStoreICSlot(object_expr, name);
builder()->StoreNamedProperty(object, name, feedback_index(slot),
language_mode());
}
......@@ -2938,35 +2986,66 @@ void BytecodeGenerator::BuildStoreNamedProperty(Property* property,
}
}
void BytecodeGenerator::VisitAssignment(Assignment* expr) {
DCHECK(expr->target()->IsValidReferenceExpression() ||
(expr->op() == Token::INIT && expr->target()->IsVariableProxy() &&
expr->target()->AsVariableProxy()->is_this()));
Register object, key;
RegisterList super_property_args;
const AstRawString* name;
// static
BytecodeGenerator::AssignmentLhsData
BytecodeGenerator::AssignmentLhsData::NonProperty(Expression* expr) {
return AssignmentLhsData(NON_PROPERTY, expr, RegisterList(), Register(),
Register(), nullptr, nullptr);
}
// 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.
Property* property = expr->target()->AsProperty();
LhsKind assign_type = Property::GetAssignType(property);
Property* property = lhs->AsProperty();
AssignType assign_type = Property::GetAssignType(property);
// Evaluate LHS expression.
switch (assign_type) {
case VARIABLE:
// Nothing to do to evaluate variable assignment LHS.
break;
case NON_PROPERTY:
return AssignmentLhsData::NonProperty(lhs);
case NAMED_PROPERTY: {
object = VisitForRegisterValue(property->obj());
name = property->key()->AsLiteral()->AsRawPropertyName();
break;
Register object = VisitForRegisterValue(property->obj());
const AstRawString* name =
property->key()->AsLiteral()->AsRawPropertyName();
return AssignmentLhsData::NamedProperty(property->obj(), object, name);
}
case KEYED_PROPERTY: {
object = VisitForRegisterValue(property->obj());
key = VisitForRegisterValue(property->key());
break;
Register object = VisitForRegisterValue(property->obj());
Register key = VisitForRegisterValue(property->key());
return AssignmentLhsData::KeyedProperty(object, key);
}
case NAMED_SUPER_PROPERTY: {
super_property_args = register_allocator()->NewRegisterList(4);
RegisterList super_property_args =
register_allocator()->NewRegisterList(4);
SuperPropertyReference* super_property =
property->obj()->AsSuperPropertyReference();
VisitForRegisterValue(super_property->this_var(), super_property_args[0]);
......@@ -2975,81 +3054,511 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
builder()
->LoadLiteral(property->key()->AsLiteral()->AsRawPropertyName())
.StoreAccumulatorInRegister(super_property_args[2]);
break;
return AssignmentLhsData::NamedSuperProperty(super_property_args);
}
case KEYED_SUPER_PROPERTY: {
super_property_args = register_allocator()->NewRegisterList(4);
RegisterList super_property_args =
register_allocator()->NewRegisterList(4);
SuperPropertyReference* super_property =
property->obj()->AsSuperPropertyReference();
VisitForRegisterValue(super_property->this_var(), super_property_args[0]);
VisitForRegisterValue(super_property->home_object(),
super_property_args[1]);
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
// the left-hand side value and performing a binary operation.
if (expr->IsCompoundAssignment()) {
switch (assign_type) {
case VARIABLE: {
VariableProxy* proxy = expr->target()->AsVariableProxy();
BuildVariableLoad(proxy->var(), proxy->hole_check_mode());
// Build the iteration finalizer called in the finally block of an iteration
// protocol execution. This closes the iterator if needed, and suppresses any
// exception it throws if necessary.
//
// In pseudo-code, this builds:
//
// 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;
}
case NAMED_PROPERTY: {
BuildLoadNamedProperty(property, object, name);
break;
Expression* default_value = GetDestructuringDefaultValue(&target);
if (!target->IsPattern()) {
builder()->SetExpressionAsStatementPosition(target);
}
case KEYED_PROPERTY: {
// Key is already in accumulator at this point due to evaluating the
// LHS above.
FeedbackSlot slot = feedback_spec()->AddKeyedLoadICSlot();
builder()->LoadKeyedProperty(object, feedback_index(slot));
break;
AssignmentLhsData lhs_data = PrepareAssignmentLhs(target);
// 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
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;
}
case KEYED_SUPER_PROPERTY: {
builder()->CallRuntime(Runtime::kLoadKeyedFromSuper,
super_property_args.Truncate(3));
break;
}
RegisterList new_type_error_args = register_allocator()->NewRegisterList(2);
// 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();
if (expr->value()->IsSmiLiteral()) {
builder()->BinaryOperationSmiLiteral(
binop->op(), expr->value()->AsLiteral()->AsSmiLiteral(),
feedback_index(slot));
AssignmentLhsData lhs_data = PrepareAssignmentLhs(target);
// Get the value from the RHS.
if (pattern_property->kind() == ObjectLiteralProperty::Kind::SPREAD) {
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 {
Register old_value = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(old_value);
VisitForAccumulatorValue(expr->value());
builder()->BinaryOperation(binop->op(), old_value, feedback_index(slot));
DCHECK(value_key.is_valid());
builder()->LoadAccumulatorWithRegister(value_key).LoadKeyedProperty(
value, feedback_index(feedback_spec()->AddKeyedLoadICSlot()));
}
} 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.
builder()->SetExpressionPosition(expr);
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.
VariableProxy* proxy = expr->target()->AsVariableProxy();
BuildVariableAssignment(proxy->var(), expr->op(),
proxy->hole_check_mode(),
expr->lookup_hoisting_mode());
if (!execution_result()->IsEffect()) {
builder()->LoadAccumulatorWithRegister(value);
}
}
void BytecodeGenerator::BuildAssignment(
const AssignmentLhsData& lhs_data, Token::Value op,
LookupHoistingMode lookup_hoisting_mode) {
// Assign the value to the LHS.
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;
}
case NAMED_PROPERTY: {
BuildStoreNamedProperty(property, object, name);
BuildStoreNamedProperty(lhs_data.object_expr(), lhs_data.object(),
lhs_data.name());
break;
}
case KEYED_PROPERTY: {
......@@ -3059,8 +3568,8 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
value = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(value);
}
builder()->StoreKeyedProperty(object, key, feedback_index(slot),
language_mode());
builder()->StoreKeyedProperty(lhs_data.object(), lhs_data.key(),
feedback_index(slot), language_mode());
if (!execution_result()->IsEffect()) {
builder()->LoadAccumulatorWithRegister(value);
}
......@@ -3068,21 +3577,78 @@ void BytecodeGenerator::VisitAssignment(Assignment* expr) {
}
case NAMED_SUPER_PROPERTY: {
builder()
->StoreAccumulatorInRegister(super_property_args[3])
.CallRuntime(StoreToSuperRuntimeId(), super_property_args);
->StoreAccumulatorInRegister(lhs_data.super_property_args()[3])
.CallRuntime(StoreToSuperRuntimeId(), lhs_data.super_property_args());
break;
}
case KEYED_SUPER_PROPERTY: {
builder()
->StoreAccumulatorInRegister(super_property_args[3])
.CallRuntime(StoreKeyedToSuperRuntimeId(), super_property_args);
->StoreAccumulatorInRegister(lhs_data.super_property_args()[3])
.CallRuntime(StoreKeyedToSuperRuntimeId(),
lhs_data.super_property_args());
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) {
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
......@@ -3132,7 +3698,7 @@ void BytecodeGenerator::VisitYield(Yield* expr) {
builder()
->StoreAccumulatorInRegister(args[0]) // value
.LoadFalse()
.StoreAccumulatorInRegister(args[1]) // done
.StoreAccumulatorInRegister(args[1]) // done
.CallRuntime(Runtime::kInlineCreateIterResultObject, args);
}
}
......@@ -3260,8 +3826,8 @@ void BytecodeGenerator::VisitYieldStar(YieldStar* expr) {
{
RegisterAllocationScope register_scope(this);
RegisterList iterator_and_input = register_allocator()->NewRegisterList(2);
VisitForAccumulatorValue(expr->expression());
IteratorRecord iterator = BuildGetIteratorRecord(
expr->expression(),
register_allocator()->NewRegister() /* next method */,
iterator_and_input[0], iterator_type);
......@@ -3495,15 +4061,15 @@ void BytecodeGenerator::VisitThrow(Throw* expr) {
}
void BytecodeGenerator::VisitPropertyLoad(Register obj, Property* property) {
LhsKind property_kind = Property::GetAssignType(property);
AssignType property_kind = Property::GetAssignType(property);
switch (property_kind) {
case VARIABLE:
case NON_PROPERTY:
UNREACHABLE();
case NAMED_PROPERTY: {
builder()->SetExpressionPosition(property);
const AstRawString* name =
property->key()->AsLiteral()->AsRawPropertyName();
BuildLoadNamedProperty(property, obj, name);
BuildLoadNamedProperty(property->obj(), obj, name);
break;
}
case KEYED_PROPERTY: {
......@@ -3569,7 +4135,7 @@ void BytecodeGenerator::VisitKeyedSuperPropertyLoad(Property* property,
}
void BytecodeGenerator::VisitProperty(Property* expr) {
LhsKind property_kind = Property::GetAssignType(expr);
AssignType property_kind = Property::GetAssignType(expr);
if (property_kind != NAMED_SUPER_PROPERTY &&
property_kind != KEYED_SUPER_PROPERTY) {
Register obj = VisitForRegisterValue(expr->obj());
......@@ -4005,7 +4571,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
// Left-hand side can only be a property, a global or a variable slot.
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();
......@@ -4014,7 +4580,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
RegisterList super_property_args;
const AstRawString* name;
switch (assign_type) {
case VARIABLE: {
case NON_PROPERTY: {
VariableProxy* proxy = expr->expression()->AsVariableProxy();
BuildVariableLoadForAccumulatorValue(proxy->var(),
proxy->hole_check_mode());
......@@ -4082,7 +4648,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
// Store the value.
builder()->SetExpressionPosition(expr);
switch (assign_type) {
case VARIABLE: {
case NON_PROPERTY: {
VariableProxy* proxy = expr->expression()->AsVariableProxy();
BuildVariableAssignment(proxy->var(), expr->op(),
proxy->hole_check_mode());
......@@ -4305,14 +4871,11 @@ void BytecodeGenerator::VisitImportCallExpression(ImportCallExpression* expr) {
.CallRuntime(Runtime::kDynamicImportCall, args);
}
void BytecodeGenerator::BuildGetIterator(Expression* iterable,
IteratorType hint) {
void BytecodeGenerator::BuildGetIterator(IteratorType hint) {
RegisterList args = register_allocator()->NewRegisterList(1);
Register method = register_allocator()->NewRegister();
Register obj = args[0];
VisitForAccumulatorValue(iterable);
if (hint == IteratorType::kAsync) {
// Set method to GetMethod(obj, @@asyncIterator)
builder()->StoreAccumulatorInRegister(obj).LoadAsyncIteratorProperty(
......@@ -4374,9 +4937,9 @@ void BytecodeGenerator::BuildGetIterator(Expression* iterable,
// Returns an IteratorRecord which is valid for the lifetime of the current
// register_allocation_scope.
BytecodeGenerator::IteratorRecord BytecodeGenerator::BuildGetIteratorRecord(
Expression* iterable, Register next, Register object, IteratorType hint) {
Register next, Register object, IteratorType hint) {
DCHECK(next.is_valid() && object.is_valid());
BuildGetIterator(iterable, hint);
BuildGetIterator(hint);
builder()
->StoreAccumulatorInRegister(object)
......@@ -4387,10 +4950,10 @@ BytecodeGenerator::IteratorRecord BytecodeGenerator::BuildGetIteratorRecord(
}
BytecodeGenerator::IteratorRecord BytecodeGenerator::BuildGetIteratorRecord(
Expression* iterable, IteratorType hint) {
IteratorType hint) {
Register next = 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,
......@@ -4458,7 +5021,8 @@ void BytecodeGenerator::BuildIteratorClose(const IteratorRecord& iterator,
void BytecodeGenerator::VisitGetIterator(GetIterator* expr) {
builder()->SetExpressionPosition(expr);
BuildGetIterator(expr->iterable(), expr->hint());
VisitForAccumulatorValue(expr->iterable());
BuildGetIterator(expr->hint());
}
void BytecodeGenerator::VisitGetTemplateObject(GetTemplateObject* expr) {
......
......@@ -70,6 +70,79 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
enum class TestFallthrough { kThen, kElse, kNone };
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 AllocateDeferredConstants(Isolate* isolate, Handle<Script> script);
......@@ -122,9 +195,17 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
void VisitPropertyLoadForRegister(Register obj, Property* expr,
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);
void BuildStoreNamedProperty(Property* property, Register object,
void BuildStoreNamedProperty(const Expression* object_expr, Register object,
const AstRawString* name);
void BuildVariableLoad(Variable* variable, HoleCheckMode hole_check_mode,
......@@ -160,19 +241,20 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
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
// method and iterator object.
IteratorRecord BuildGetIteratorRecord(Expression* iterable,
Register iterator_next,
IteratorRecord BuildGetIteratorRecord(Register iterator_next,
Register iterator_object,
IteratorType hint);
// Create an IteratorRecord allocating new registers to hold the next method
// and iterator object.
IteratorRecord BuildGetIteratorRecord(Expression* iterable,
IteratorType hint);
IteratorRecord BuildGetIteratorRecord(IteratorType hint);
void BuildIteratorNext(const IteratorRecord& iterator, Register next_result);
void BuildIteratorClose(const IteratorRecord& iterator,
Expression* expr = nullptr);
......@@ -181,9 +263,12 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
BytecodeLabel* if_called,
BytecodeLabels* if_notcalled);
void BuildArrayLiteralSpread(Spread* spread, Register array, Register index,
FeedbackSlot index_slot,
FeedbackSlot element_slot);
void 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);
// Create Array literals. |expr| can be nullptr, but if provided,
// a boilerplate will be used to create an initial array for elements
// before the first spread.
......
......@@ -137,18 +137,39 @@ void Parser::DeclareAndInitializeVariables(
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) {
DCHECK(!to_rewrite->is_rewritten());
Assignment* assignment = to_rewrite->expression()->AsAssignment();
Expression* result =
PatternRewriter::RewriteDestructuringAssignment(this, assignment);
to_rewrite->Rewrite(result);
DCHECK_NOT_NULL(assignment);
MarkVariablesWritten(assignment->target());
}
Expression* Parser::RewriteDestructuringAssignment(Assignment* assignment) {
DCHECK_NOT_NULL(assignment);
DCHECK_EQ(Token::ASSIGN, assignment->op());
return PatternRewriter::RewriteDestructuringAssignment(this, assignment);
MarkVariablesWritten(assignment->target());
return assignment;
}
void PatternRewriter::DeclareAndInitializeVariables(
......
......@@ -143,7 +143,7 @@ snippet: "
"
frame size: 8
parameter count: 1
bytecode array length: 86
bytecode array length: 84
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 42 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
......@@ -152,28 +152,27 @@ bytecodes: [
B(Star), R(2),
B(LdaConstant), U8(2),
/* 67 S> */ B(Star), R(1),
B(LdaNamedProperty), R(0), U8(3), U8(5),
B(Star), R(7),
B(CallProperty0), R(7), R(0), U8(7),
B(Mov), R(0), R(6),
B(LdaNamedProperty), R(0), U8(3), U8(2),
B(Star), R(6),
B(CallProperty0), R(6), R(0), U8(4),
B(Mov), R(0), R(5),
B(JumpIfJSReceiver), U8(7),
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(CallProperty0), R(4), R(5), U8(11),
B(LdaNamedProperty), R(4), U8(4), U8(6),
B(Star), R(3),
B(CallProperty0), R(3), R(4), U8(15),
B(Star), R(7),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
B(LdaNamedProperty), R(3), U8(5), U8(13),
B(JumpIfToBooleanTrue), U8(21),
B(LdaNamedProperty), R(3), U8(6), U8(15),
B(Star), R(3),
B(StaInArrayLiteral), R(2), R(1), U8(3),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(7), U8(1),
B(LdaNamedProperty), R(7), U8(5), U8(17),
B(JumpIfToBooleanTrue), U8(19),
B(LdaNamedProperty), R(7), U8(6), U8(8),
B(StaInArrayLiteral), R(2), R(1), U8(13),
B(Ldar), R(1),
B(Inc), U8(2),
B(Inc), U8(12),
B(Star), R(1),
B(JumpLoop), U8(35), I8(0),
B(JumpLoop), U8(33), I8(0),
B(Ldar), R(2),
/* 71 S> */ B(Return),
]
......
......@@ -14,7 +14,7 @@ snippet: "
"
frame size: 8
parameter count: 1
bytecode array length: 189
bytecode array length: 190
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(2),
B(Mov), R(closure), R(1),
......@@ -32,7 +32,7 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(2), U8(2), I8(0),
B(Ldar), R(5),
/* 17 E> */ B(Throw),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(5), R(2),
B(Jump), U8(95),
......@@ -50,10 +50,10 @@ bytecodes: [
B(JumpIfTrue), U8(5),
B(Ldar), R(5),
B(ReThrow),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(5), R(2),
B(Jump), U8(52),
B(Jump), U8(51),
B(Jump), U8(36),
B(Star), R(5),
B(CreateCatchContext), R(5), U8(4),
......@@ -68,15 +68,15 @@ bytecodes: [
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(6), U8(2),
B(PopContext), R(5),
B(Star), R(2),
B(LdaSmi), I8(1),
B(LdaSmi), I8(2),
B(Star), R(1),
B(Jump), U8(16),
B(Jump), U8(15),
B(LdaSmi), I8(-1),
B(Star), R(2),
B(Star), R(1),
B(Jump), U8(8),
B(Jump), U8(7),
B(Star), R(2),
B(LdaSmi), I8(2),
B(LdaZero),
B(Star), R(1),
B(LdaTheHole),
B(SetPendingMessage),
......@@ -87,6 +87,8 @@ bytecodes: [
B(Ldar), R(1),
B(SwitchOnSmiNoFeedback), U8(5), U8(3), I8(0),
B(Jump), U8(22),
B(Ldar), R(2),
B(ReThrow),
B(LdaTrue),
B(Star), R(6),
B(Mov), R(0), R(4),
......@@ -95,24 +97,22 @@ bytecodes: [
/* 22 S> */ B(Return),
B(Ldar), R(2),
/* 22 S> */ B(Return),
B(Ldar), R(2),
B(ReThrow),
B(LdaUndefined),
/* 22 S> */ B(Return),
]
constant pool: [
Smi [30],
Smi [70],
Smi [15],
Smi [71],
Smi [16],
Smi [7],
SCOPE_INFO_TYPE,
Smi [6],
Smi [20],
Smi [9],
Smi [23],
]
handlers: [
[20, 134, 142],
[23, 98, 100],
[20, 136, 144],
[23, 100, 102],
]
---
......@@ -122,7 +122,7 @@ snippet: "
"
frame size: 8
parameter count: 1
bytecode array length: 233
bytecode array length: 235
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(3),
B(Mov), R(closure), R(1),
......@@ -140,10 +140,10 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0),
B(Ldar), R(5),
/* 17 E> */ B(Throw),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(5), R(2),
B(Jump), U8(139),
B(Jump), U8(140),
/* 22 S> */ B(LdaSmi), I8(42),
B(Star), R(6),
B(LdaFalse),
......@@ -157,7 +157,7 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(5), U8(2), I8(0),
B(Ldar), R(5),
/* 22 E> */ B(Throw),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(5), R(2),
B(Jump), U8(95),
......@@ -175,10 +175,10 @@ bytecodes: [
B(JumpIfTrue), U8(5),
B(Ldar), R(5),
B(ReThrow),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(5), R(2),
B(Jump), U8(52),
B(Jump), U8(51),
B(Jump), U8(36),
B(Star), R(5),
B(CreateCatchContext), R(5), U8(7),
......@@ -193,15 +193,15 @@ bytecodes: [
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(6), U8(2),
B(PopContext), R(5),
B(Star), R(2),
B(LdaSmi), I8(1),
B(LdaSmi), I8(2),
B(Star), R(1),
B(Jump), U8(16),
B(Jump), U8(15),
B(LdaSmi), I8(-1),
B(Star), R(2),
B(Star), R(1),
B(Jump), U8(8),
B(Jump), U8(7),
B(Star), R(2),
B(LdaSmi), I8(2),
B(LdaZero),
B(Star), R(1),
B(LdaTheHole),
B(SetPendingMessage),
......@@ -212,6 +212,8 @@ bytecodes: [
B(Ldar), R(1),
B(SwitchOnSmiNoFeedback), U8(8), U8(3), I8(0),
B(Jump), U8(22),
B(Ldar), R(2),
B(ReThrow),
B(LdaTrue),
B(Star), R(6),
B(Mov), R(0), R(4),
......@@ -220,27 +222,25 @@ bytecodes: [
/* 31 S> */ B(Return),
B(Ldar), R(2),
/* 31 S> */ B(Return),
B(Ldar), R(2),
B(ReThrow),
B(LdaUndefined),
/* 31 S> */ B(Return),
]
constant pool: [
Smi [30],
Smi [74],
Smi [114],
Smi [15],
Smi [75],
Smi [116],
Smi [16],
Smi [7],
Smi [15],
Smi [16],
Smi [7],
SCOPE_INFO_TYPE,
Smi [6],
Smi [20],
Smi [9],
Smi [23],
]
handlers: [
[20, 178, 186],
[23, 142, 144],
[20, 181, 189],
[23, 145, 147],
]
---
......@@ -250,7 +250,7 @@ snippet: "
"
frame size: 22
parameter count: 1
bytecode array length: 490
bytecode array length: 492
bytecodes: [
B(SwitchOnGeneratorState), R(2), U8(0), U8(3),
B(Mov), R(closure), R(11),
......@@ -268,7 +268,7 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(3), U8(2), I8(0),
B(Ldar), R(15),
/* 17 E> */ B(Throw),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(11),
B(Mov), R(15), R(12),
B(JumpConstant), U8(18),
......@@ -293,7 +293,7 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
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(Star), R(8),
B(LdaSmi), I8(2),
......@@ -313,13 +313,13 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(0),
B(Ldar), R(19),
/* 42 E> */ B(Throw),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(15),
B(Mov), R(19), R(16),
B(Jump), U8(59),
B(Jump), U8(58),
B(LdaZero),
B(Star), R(7),
B(JumpLoop), U8(87), I8(0),
B(JumpLoop), U8(88), I8(0),
B(Jump), U8(37),
B(Star), R(19),
B(CreateCatchContext), R(19), U8(12),
......@@ -340,9 +340,9 @@ bytecodes: [
B(LdaSmi), I8(-1),
B(Star), R(16),
B(Star), R(15),
B(Jump), U8(8),
B(Jump), U8(7),
B(Star), R(16),
B(LdaSmi), I8(1),
B(LdaZero),
B(Star), R(15),
B(LdaTheHole),
B(SetPendingMessage),
......@@ -389,13 +389,13 @@ bytecodes: [
B(SetPendingMessage),
B(Ldar), R(15),
B(SwitchOnSmiNoFeedback), U8(15), U8(2), I8(0),
B(Jump), U8(13),
B(LdaZero),
B(Star), R(11),
B(Mov), R(16), R(12),
B(Jump), U8(98),
B(Jump), U8(14),
B(Ldar), R(16),
B(ReThrow),
B(LdaSmi), I8(1),
B(Star), R(11),
B(Mov), R(16), R(12),
B(Jump), U8(95),
B(LdaUndefined),
B(Star), R(16),
B(Mov), R(2), R(15),
......@@ -410,10 +410,10 @@ bytecodes: [
B(JumpIfTrue), U8(5),
B(Ldar), R(15),
B(ReThrow),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(11),
B(Mov), R(15), R(12),
B(Jump), U8(52),
B(Jump), U8(51),
B(Jump), U8(36),
B(Star), R(15),
B(CreateCatchContext), R(15), U8(17),
......@@ -428,15 +428,15 @@ bytecodes: [
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(16), U8(2),
B(PopContext), R(15),
B(Star), R(12),
B(LdaSmi), I8(1),
B(LdaSmi), I8(2),
B(Star), R(11),
B(Jump), U8(16),
B(Jump), U8(15),
B(LdaSmi), I8(-1),
B(Star), R(12),
B(Star), R(11),
B(Jump), U8(8),
B(Jump), U8(7),
B(Star), R(12),
B(LdaSmi), I8(2),
B(LdaZero),
B(Star), R(11),
B(LdaTheHole),
B(SetPendingMessage),
......@@ -447,6 +447,8 @@ bytecodes: [
B(Ldar), R(11),
B(SwitchOnSmiNoFeedback), U8(19), U8(3), I8(0),
B(Jump), U8(22),
B(Ldar), R(12),
B(ReThrow),
B(LdaTrue),
B(Star), R(16),
B(Mov), R(2), R(14),
......@@ -455,41 +457,39 @@ bytecodes: [
/* 50 S> */ B(Return),
B(Ldar), R(12),
/* 50 S> */ B(Return),
B(Ldar), R(12),
B(ReThrow),
B(LdaUndefined),
/* 50 S> */ B(Return),
]
constant pool: [
Smi [30],
Smi [154],
Smi [371],
Smi [15],
Smi [155],
Smi [373],
Smi [16],
Smi [7],
ARRAY_BOILERPLATE_DESCRIPTION_TYPE,
SYMBOL_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
Smi [15],
Smi [16],
Smi [7],
SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
Smi [6],
Smi [14],
Smi [9],
SCOPE_INFO_TYPE,
Smi [396],
Smi [397],
Smi [6],
Smi [20],
Smi [9],
Smi [23],
]
handlers: [
[20, 435, 443],
[23, 399, 401],
[61, 222, 230],
[64, 185, 187],
[291, 301, 303],
[20, 438, 446],
[23, 402, 404],
[62, 224, 232],
[65, 187, 189],
[292, 302, 304],
]
---
......@@ -500,7 +500,7 @@ snippet: "
"
frame size: 17
parameter count: 1
bytecode array length: 479
bytecode array length: 482
bytecodes: [
B(SwitchOnGeneratorState), R(0), U8(0), U8(5),
B(Mov), R(closure), R(1),
......@@ -518,13 +518,13 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(5), U8(2), I8(0),
B(Ldar), R(5),
/* 44 E> */ B(Throw),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(5), R(2),
B(JumpConstant), U8(18),
/* 49 S> */ B(LdaGlobal), U8(7), U8(0),
B(Star), R(12),
/* 56 E> */ B(CallUndefinedReceiver0), R(12), U8(2),
B(Star), R(9),
/* 56 E> */ B(CallUndefinedReceiver0), R(9), U8(2),
B(Star), R(10),
B(LdaNamedProperty), R(10), U8(8), U8(4),
B(JumpIfUndefined), U8(17),
......@@ -548,14 +548,14 @@ bytecodes: [
B(Ldar), R(6),
B(SwitchOnSmiNoFeedback), U8(11), U8(2), I8(1),
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(JumpIfUndefined), U8(13),
B(JumpIfNull), U8(11),
B(Star), R(12),
B(CallProperty1), R(12), R(7), R(8), U8(18),
B(Jump), U8(93),
B(LdaZero),
B(Jump), U8(94),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(8), R(2),
B(JumpConstant), U8(19),
......@@ -619,13 +619,13 @@ bytecodes: [
B(Star), R(8),
B(InvokeIntrinsic), U8(Runtime::k_GeneratorGetResumeMode), R(0), U8(1),
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(Star), R(7),
B(LdaSmi), I8(1),
B(TestReferenceEqual), R(6),
B(JumpIfFalse), U8(10),
B(LdaZero),
B(JumpIfFalse), U8(11),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(7), R(2),
B(Jump), U8(95),
......@@ -643,10 +643,10 @@ bytecodes: [
B(JumpIfTrue), U8(5),
B(Ldar), R(5),
B(ReThrow),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(1),
B(Mov), R(5), R(2),
B(Jump), U8(52),
B(Jump), U8(51),
B(Jump), U8(36),
B(Star), R(5),
B(CreateCatchContext), R(5), U8(17),
......@@ -661,15 +661,15 @@ bytecodes: [
B(InvokeIntrinsic), U8(Runtime::k_AsyncGeneratorReject), R(6), U8(2),
B(PopContext), R(5),
B(Star), R(2),
B(LdaSmi), I8(1),
B(LdaSmi), I8(2),
B(Star), R(1),
B(Jump), U8(16),
B(Jump), U8(15),
B(LdaSmi), I8(-1),
B(Star), R(2),
B(Star), R(1),
B(Jump), U8(8),
B(Jump), U8(7),
B(Star), R(2),
B(LdaSmi), I8(2),
B(LdaZero),
B(Star), R(1),
B(LdaTheHole),
B(SetPendingMessage),
......@@ -680,6 +680,8 @@ bytecodes: [
B(Ldar), R(1),
B(SwitchOnSmiNoFeedback), U8(20), U8(3), I8(0),
B(Jump), U8(22),
B(Ldar), R(2),
B(ReThrow),
B(LdaTrue),
B(Star), R(6),
B(Mov), R(0), R(4),
......@@ -688,38 +690,36 @@ bytecodes: [
/* 60 S> */ B(Return),
B(Ldar), R(2),
/* 60 S> */ B(Return),
B(Ldar), R(2),
B(ReThrow),
B(LdaUndefined),
/* 60 S> */ B(Return),
]
constant pool: [
Smi [30],
Smi [201],
Smi [251],
Smi [310],
Smi [360],
Smi [15],
Smi [203],
Smi [253],
Smi [312],
Smi [363],
Smi [16],
Smi [7],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["g"],
SYMBOL_TYPE,
SYMBOL_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
Smi [11],
Smi [36],
Smi [37],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["throw"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
SCOPE_INFO_TYPE,
Smi [385],
Smi [286],
Smi [387],
Smi [287],
Smi [6],
Smi [20],
Smi [9],
Smi [23],
]
handlers: [
[20, 424, 432],
[23, 388, 390],
[20, 428, 436],
[23, 392, 394],
]
......@@ -67,7 +67,7 @@ snippet: "
"
frame size: 10
parameter count: 1
bytecode array length: 109
bytecode array length: 107
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdaGlobal), U8(0), U8(0),
......@@ -78,32 +78,31 @@ bytecodes: [
B(Star), R(4),
B(LdaConstant), U8(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(LdaNamedProperty), R(8), U8(5), U8(9),
B(Star), R(9),
B(CallProperty0), R(9), R(8), U8(11),
B(CallProperty0), R(8), R(7), U8(8),
B(Mov), R(0), R(2),
B(JumpIfJSReceiver), U8(7),
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(CallProperty0), R(6), R(7), U8(15),
B(LdaNamedProperty), R(6), U8(6), U8(10),
B(Star), R(5),
B(CallProperty0), R(5), R(6), U8(19),
B(Star), R(9),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
B(LdaNamedProperty), R(5), U8(7), U8(17),
B(JumpIfToBooleanTrue), U8(21),
B(LdaNamedProperty), R(5), U8(8), U8(19),
B(Star), R(5),
B(StaInArrayLiteral), R(4), R(3), U8(6),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
B(LdaNamedProperty), R(9), U8(7), U8(21),
B(JumpIfToBooleanTrue), U8(19),
B(LdaNamedProperty), R(9), U8(8), U8(12),
B(StaInArrayLiteral), R(4), R(3), U8(17),
B(Ldar), R(3),
B(Inc), U8(5),
B(Inc), U8(16),
B(Star), R(3),
B(JumpLoop), U8(35), I8(0),
B(JumpLoop), U8(33), I8(0),
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(CallJSRuntime), U8(%reflect_apply), R(1), U8(3),
B(LdaUndefined),
......
......@@ -10,120 +10,79 @@ snippet: "
var x, a = [0,1,2,3];
[x] = a;
"
frame size: 17
frame size: 14
parameter count: 1
bytecode array length: 259
bytecode array length: 160
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 45 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(1),
/* 56 S> */ B(Star), R(2),
/* 62 E> */ B(LdaNamedProperty), R(2), U8(1), U8(1),
B(Star), R(12),
B(CallProperty0), R(12), R(2), U8(3),
B(Mov), R(1), R(11),
/* 60 S> */ B(LdaNamedProperty), R(1), U8(1), U8(1),
B(Star), R(6),
B(CallProperty0), R(6), R(1), U8(3),
B(Mov), R(1), R(5),
B(Mov), R(1), R(2),
B(JumpIfJSReceiver), U8(7),
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(LdaNamedProperty), R(4), U8(2), U8(5),
B(Star), R(3),
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(Jump), U8(11),
B(LdaNamedProperty), R(6), U8(4), U8(11),
B(Mov), R(context), R(10),
/* 57 S> */ B(Ldar), R(7),
B(JumpIfToBooleanTrue), U8(37),
B(LdaTrue),
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(Star), R(5),
B(LdaSmi), I8(2),
B(Star), R(8),
/* 57 S> */ B(Mov), R(7), R(0),
B(LdaZero),
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(Star), R(7),
B(Ldar), R(11),
B(Jump), U8(3),
B(LdaUndefined),
B(Star), R(0),
B(LdaSmi), I8(-1),
B(Star), R(12),
B(Star), R(11),
B(Star), R(9),
B(Star), R(8),
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(TestUndetectable),
B(JumpIfFalse), U8(4),
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(LdaZero),
B(Star), R(8),
B(LdaTheHole),
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(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(10), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(10), U8(1),
B(Ldar), R(13),
B(Mov), R(context), R(12),
B(Ldar), R(7),
B(JumpIfToBooleanTrue), U8(27),
B(LdaNamedProperty), R(4), U8(5), U8(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(LdaZero),
B(TestReferenceEqual), R(11),
B(TestReferenceEqual), R(8),
B(JumpIfFalse), U8(5),
B(Ldar), R(12),
B(Ldar), R(9),
B(ReThrow),
B(LdaUndefined),
/* 65 S> */ B(Return),
......@@ -134,14 +93,11 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[46, 137, 145],
[49, 104, 106],
[203, 213, 215],
[44, 86, 94],
[106, 135, 137],
]
---
......@@ -149,166 +105,120 @@ snippet: "
var x, y, a = [0,1,2,3];
[,x,...y] = a;
"
frame size: 20
frame size: 15
parameter count: 1
bytecode array length: 368
bytecode array length: 258
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 48 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(2),
/* 59 S> */ B(Star), R(3),
/* 71 E> */ B(LdaNamedProperty), R(3), U8(1), U8(1),
B(Star), R(15),
B(CallProperty0), R(15), R(3), U8(3),
B(Mov), R(2), R(14),
/* 69 S> */ B(LdaNamedProperty), R(2), U8(1), U8(1),
B(Star), R(7),
B(CallProperty0), R(7), R(2), U8(3),
B(Mov), R(2), R(6),
B(Mov), R(2), R(3),
B(JumpIfJSReceiver), U8(7),
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(LdaNamedProperty), R(5), U8(2), U8(5),
B(Star), R(4),
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(Jump), U8(11),
B(LdaNamedProperty), R(7), U8(4), U8(11),
B(Mov), R(context), R(11),
B(Ldar), R(8),
B(JumpIfToBooleanTrue), U8(35),
B(LdaTrue),
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(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(Jump), U8(11),
B(LdaNamedProperty), R(7), U8(4), U8(11),
B(Ldar), R(12),
/* 61 S> */ B(Ldar), R(8),
B(JumpIfToBooleanTrue), U8(37),
B(LdaTrue),
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(Star), R(6),
B(LdaSmi), I8(2),
B(Star), R(9),
/* 61 S> */ B(Mov), R(8), R(0),
B(LdaZero),
B(Star), R(9),
/* 61 E> */ B(CreateEmptyArrayLiteral), U8(15),
B(Star), R(10),
B(Star), R(8),
B(Ldar), R(12),
B(Jump), U8(3),
B(LdaUndefined),
B(Star), R(0),
/* 63 S> */ B(CreateEmptyArrayLiteral), U8(15),
B(Star), R(13),
B(LdaZero),
B(Star), R(11),
B(Ldar), R(6),
B(JumpIfToBooleanTrue), U8(50),
B(StackCheck),
B(Star), R(14),
B(LdaTrue),
B(Star), R(6),
B(CallProperty0), R(5), R(4), U8(16),
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(JumpIfToBooleanTrue), U8(13),
B(LdaNamedProperty), R(7), U8(4), U8(11),
B(StaInArrayLiteral), R(10), R(11), U8(18),
B(Star), R(8),
B(CallProperty0), R(4), R(5), U8(19),
B(Star), R(12),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdaNamedProperty), R(12), U8(3), U8(21),
B(JumpIfToBooleanTrue), U8(29),
B(LdaNamedProperty), R(12), U8(4), U8(7),
B(Star), R(12),
B(LdaFalse),
B(Star), R(6),
B(Ldar), R(11),
B(Inc), U8(20),
B(Star), R(11),
B(JumpLoop), U8(49), I8(0),
/* 66 S> */ B(Mov), R(10), R(1),
B(Star), R(8),
B(Ldar), R(12),
B(StaInArrayLiteral), R(13), R(14), U8(16),
B(Ldar), R(14),
B(Inc), U8(18),
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(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(Star), R(15),
B(Star), R(14),
B(Star), R(10),
B(Star), R(9),
B(Jump), U8(7),
B(Star), R(15),
B(Star), R(10),
B(LdaZero),
B(Star), R(14),
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(Star), R(9),
B(LdaTheHole),
B(SetPendingMessage),
B(Ldar), R(17),
B(Jump), U8(27),
B(Mov), R(12), R(17),
B(Mov), R(4), R(18),
B(InvokeIntrinsic), U8(Runtime::k_Call), R(17), U8(2),
B(Star), R(11),
B(Mov), R(context), R(13),
B(Ldar), R(8),
B(JumpIfToBooleanTrue), U8(27),
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(InvokeIntrinsic), U8(Runtime::k_IsJSReceiver), R(13), U8(1),
B(JumpIfToBooleanFalse), U8(4),
B(Jump), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(13), U8(1),
B(Ldar), R(16),
B(LdaZero),
B(TestReferenceEqual), R(9),
B(JumpIfTrue), U8(5),
B(Ldar), R(13),
B(ReThrow),
B(Ldar), R(11),
B(SetPendingMessage),
B(LdaZero),
B(TestReferenceEqual), R(14),
B(TestReferenceEqual), R(9),
B(JumpIfFalse), U8(5),
B(Ldar), R(15),
B(Ldar), R(10),
B(ReThrow),
B(LdaUndefined),
/* 74 S> */ B(Return),
......@@ -319,14 +229,11 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[46, 246, 254],
[49, 213, 215],
[312, 322, 324],
[44, 184, 192],
[204, 233, 235],
]
---
......@@ -334,153 +241,100 @@ snippet: "
var x={}, y, a = [0];
[x.foo,y=4] = a;
"
frame size: 19
frame size: 16
parameter count: 1
bytecode array length: 332
bytecode array length: 211
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 40 S> */ B(CreateEmptyObjectLiteral),
B(Star), R(0),
/* 51 S> */ B(CreateArrayLiteral), U8(0), U8(0), U8(37),
B(Star), R(2),
/* 56 S> */ B(Star), R(3),
/* 70 E> */ B(LdaNamedProperty), R(3), U8(1), U8(1),
B(Star), R(14),
B(CallProperty0), R(14), R(3), U8(3),
B(Mov), R(2), R(13),
/* 68 S> */ B(LdaNamedProperty), R(2), U8(1), U8(1),
B(Star), R(7),
B(CallProperty0), R(7), R(2), U8(3),
B(Mov), R(2), R(6),
B(Mov), R(2), R(3),
B(JumpIfJSReceiver), U8(7),
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(LdaNamedProperty), R(5), U8(2), U8(5),
B(Star), R(4),
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(Jump), U8(11),
B(LdaNamedProperty), R(7), U8(4), U8(11),
B(Mov), R(context), R(11),
/* 59 S> */ B(Ldar), R(8),
B(Mov), R(0), R(13),
B(JumpIfToBooleanTrue), U8(37),
B(LdaTrue),
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(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(Jump), U8(11),
B(LdaNamedProperty), R(7), U8(4), U8(11),
B(Ldar), R(12),
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(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(Star), R(6),
B(LdaSmi), I8(2),
B(Star), R(9),
B(Mov), R(8), R(10),
/* 63 S> */ B(Ldar), R(10),
B(JumpIfNotUndefined), U8(6),
B(Star), R(8),
B(Ldar), R(12),
B(JumpIfNotUndefined), U8(4),
B(LdaSmi), I8(4),
B(Jump), U8(4),
B(Ldar), R(10),
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(Star), R(14),
B(Star), R(13),
B(Star), R(10),
B(Star), R(9),
B(Jump), U8(7),
B(Star), R(14),
B(Star), R(10),
B(LdaZero),
B(Star), R(13),
B(Star), R(9),
B(LdaTheHole),
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(TestUndetectable),
B(JumpIfFalse), U8(4),
B(Jump), U8(79),
B(LdaSmi), I8(1),
B(TestEqualStrict), R(9), U8(20),
B(JumpIfFalse), U8(47),
B(Mov), R(context), R(14),
B(Ldar), R(8),
B(JumpIfToBooleanTrue), U8(27),
B(LdaNamedProperty), R(5), U8(6), U8(17),
B(JumpIfUndefined), U8(21),
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(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(LdaZero),
B(TestReferenceEqual), R(13),
B(TestReferenceEqual), R(9),
B(JumpIfFalse), U8(5),
B(Ldar), R(14),
B(Ldar), R(10),
B(ReThrow),
B(LdaUndefined),
/* 73 S> */ B(Return),
......@@ -492,14 +346,11 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["foo"],
SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
]
handlers: [
[49, 210, 218],
[52, 177, 179],
[276, 286, 288],
[47, 137, 145],
[157, 186, 188],
]
---
......@@ -509,22 +360,21 @@ snippet: "
"
frame size: 5
parameter count: 1
bytecode array length: 37
bytecode array length: 35
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41),
B(Star), R(1),
/* 52 S> */ B(Star), R(2),
B(JumpIfUndefined), U8(6),
B(Ldar), R(2),
B(JumpIfNotNull), U8(16),
/* 52 S> */ B(JumpIfNull), U8(4),
B(JumpIfNotUndefined), U8(16),
B(LdaSmi), I8(81),
B(Star), R(3),
B(Star), R(2),
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(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2),
/* 54 E> */ B(Throw),
/* 54 S> */ B(LdaNamedProperty), R(2), U8(1), U8(1),
/* 54 S> */ B(LdaNamedProperty), R(4), U8(1), U8(1),
B(Star), R(0),
B(LdaUndefined),
/* 63 S> */ B(Return),
......@@ -543,25 +393,24 @@ snippet: "
"
frame size: 5
parameter count: 1
bytecode array length: 42
bytecode array length: 40
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 40 S> */ B(CreateEmptyObjectLiteral),
B(Star), R(0),
/* 48 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41),
B(Star), R(1),
/* 55 S> */ B(Star), R(2),
B(JumpIfUndefined), U8(6),
B(Ldar), R(2),
B(JumpIfNotNull), U8(16),
/* 55 S> */ B(JumpIfNull), U8(4),
B(JumpIfNotUndefined), U8(16),
B(LdaSmi), I8(81),
B(Star), R(3),
B(Star), R(2),
B(LdaConstant), U8(1),
B(Star), R(4),
B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2),
/* 57 E> */ B(Throw),
/* 59 E> */ B(LdaNamedProperty), R(2), U8(1), U8(1),
/* 61 E> */ B(StaNamedProperty), R(0), U8(2), U8(3),
B(Star), R(3),
/* 66 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw),
/* 61 S> */ B(Star), R(4),
B(LdaNamedProperty), R(4), U8(1), U8(1),
B(StaNamedProperty), R(0), U8(2), U8(3),
B(LdaUndefined),
/* 72 S> */ B(Return),
]
......@@ -580,33 +429,28 @@ snippet: "
"
frame size: 6
parameter count: 1
bytecode array length: 61
bytecode array length: 50
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 45 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41),
B(Star), R(1),
/* 62 S> */ B(Star), R(2),
B(JumpIfUndefined), U8(6),
B(Ldar), R(2),
B(JumpIfNotNull), U8(16),
/* 62 S> */ B(JumpIfNull), U8(4),
B(JumpIfNotUndefined), U8(16),
B(LdaSmi), I8(81),
B(Star), R(4),
B(Star), R(2),
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),
/* 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(Jump), U8(4),
B(Ldar), R(3),
B(Star), R(0),
/* 71 S> */ B(LdaConstant), U8(1),
B(Star), R(5),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kCopyDataPropertiesWithExcludedProperties), R(4), U8(2),
/* 71 E> */ B(StaGlobal), U8(2), U8(3),
/* 71 S> */ B(CallRuntime), U16(Runtime::kCopyDataPropertiesWithExcludedProperties), R(4), U8(2),
B(StaGlobal), U8(2), U8(3),
B(LdaUndefined),
/* 80 S> */ B(Return),
]
......
......@@ -282,7 +282,7 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
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(Star), R(8),
B(LdaSmi), I8(2),
......@@ -290,10 +290,10 @@ bytecodes: [
B(Mov), R(8), R(3),
/* 23 E> */ B(StackCheck),
B(Mov), R(3), R(0),
/* 56 S> */ B(LdaZero),
/* 56 S> */ B(LdaSmi), I8(1),
B(Star), R(12),
B(Mov), R(8), R(13),
B(Jump), U8(53),
B(Jump), U8(52),
B(Jump), U8(37),
B(Star), R(16),
B(CreateCatchContext), R(16), U8(9),
......@@ -314,9 +314,9 @@ bytecodes: [
B(LdaSmi), I8(-1),
B(Star), R(13),
B(Star), R(12),
B(Jump), U8(8),
B(Jump), U8(7),
B(Star), R(13),
B(LdaSmi), I8(1),
B(LdaZero),
B(Star), R(12),
B(LdaTheHole),
B(SetPendingMessage),
......@@ -391,14 +391,14 @@ bytecodes: [
B(Ldar), R(12),
B(SwitchOnSmiNoFeedback), U8(12), U8(2), I8(0),
B(Jump), U8(19),
B(Ldar), R(13),
B(ReThrow),
B(LdaTrue),
B(Star), R(17),
B(Mov), R(2), R(15),
B(Mov), R(13), R(16),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(15), U8(3),
/* 68 S> */ B(Return),
B(Ldar), R(13),
B(ReThrow),
B(LdaUndefined),
B(Star), R(13),
B(LdaTrue),
......@@ -438,13 +438,13 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
Smi [6],
Smi [20],
Smi [9],
SCOPE_INFO_TYPE,
]
handlers: [
[20, 426, 428],
[26, 201, 209],
[29, 164, 166],
[26, 202, 210],
[29, 165, 167],
[270, 316, 318],
]
......@@ -716,7 +716,7 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(4), U8(1),
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),
B(Star), R(6),
B(LdaSmi), I8(2),
......@@ -726,9 +726,9 @@ bytecodes: [
/* 53 E> */ B(StackCheck),
/* 87 S> */ B(LdaNamedProperty), R(1), U8(6), U8(16),
B(Star), R(11),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(10),
B(Jump), U8(53),
B(Jump), U8(52),
B(Jump), U8(37),
B(Star), R(14),
B(CreateCatchContext), R(14), U8(7),
......@@ -749,9 +749,9 @@ bytecodes: [
B(LdaSmi), I8(-1),
B(Star), R(11),
B(Star), R(10),
B(Jump), U8(8),
B(Jump), U8(7),
B(Star), R(11),
B(LdaSmi), I8(1),
B(LdaZero),
B(Star), R(10),
B(LdaTheHole),
B(SetPendingMessage),
......@@ -799,14 +799,14 @@ bytecodes: [
B(Ldar), R(10),
B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(0),
B(Jump), U8(19),
B(Ldar), R(11),
B(ReThrow),
B(LdaFalse),
B(Star), R(15),
B(Mov), R(0), R(13),
B(Mov), R(11), R(14),
B(InvokeIntrinsic), U8(Runtime::k_AsyncFunctionResolve), R(13), U8(3),
/* 96 S> */ B(Return),
B(Ldar), R(11),
B(ReThrow),
B(LdaUndefined),
B(Star), R(11),
B(LdaFalse),
......@@ -844,13 +844,13 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
ONE_BYTE_INTERNALIZED_STRING_TYPE [""],
Smi [6],
Smi [20],
Smi [9],
SCOPE_INFO_TYPE,
]
handlers: [
[16, 305, 307],
[28, 151, 159],
[31, 114, 116],
[28, 152, 160],
[31, 115, 117],
[220, 230, 232],
]
......@@ -166,7 +166,7 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
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(Star), R(7),
B(LdaSmi), I8(2),
......@@ -174,10 +174,10 @@ bytecodes: [
B(Mov), R(7), R(1),
/* 54 E> */ B(StackCheck),
B(Mov), R(1), R(2),
/* 73 S> */ B(LdaZero),
/* 73 S> */ B(LdaSmi), I8(1),
B(Star), R(10),
B(Mov), R(7), R(11),
B(Jump), U8(49),
B(Jump), U8(48),
B(Jump), U8(33),
B(Star), R(14),
B(CreateCatchContext), R(14), U8(5),
......@@ -195,9 +195,9 @@ bytecodes: [
B(LdaSmi), I8(-1),
B(Star), R(11),
B(Star), R(10),
B(Jump), U8(8),
B(Jump), U8(7),
B(Star), R(11),
B(LdaSmi), I8(1),
B(LdaZero),
B(Star), R(10),
B(LdaTheHole),
B(SetPendingMessage),
......@@ -246,9 +246,9 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(8), U8(2), I8(0),
B(Jump), U8(8),
B(Ldar), R(11),
/* 85 S> */ B(Return),
B(Ldar), R(11),
B(ReThrow),
B(Ldar), R(11),
/* 85 S> */ B(Return),
B(LdaUndefined),
/* 85 S> */ B(Return),
]
......@@ -265,8 +265,8 @@ constant pool: [
Smi [9],
]
handlers: [
[11, 124, 132],
[14, 91, 93],
[11, 125, 133],
[14, 92, 94],
[193, 203, 205],
]
......@@ -443,7 +443,7 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(3), U8(1),
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),
B(Star), R(5),
B(LdaSmi), I8(2),
......@@ -453,9 +453,9 @@ bytecodes: [
/* 62 E> */ B(StackCheck),
/* 96 S> */ B(LdaNamedProperty), R(0), U8(6), U8(16),
B(Star), R(9),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(8),
B(Jump), U8(49),
B(Jump), U8(48),
B(Jump), U8(33),
B(Star), R(12),
B(CreateCatchContext), R(12), U8(7),
......@@ -473,9 +473,9 @@ bytecodes: [
B(LdaSmi), I8(-1),
B(Star), R(9),
B(Star), R(8),
B(Jump), U8(8),
B(Jump), U8(7),
B(Star), R(9),
B(LdaSmi), I8(1),
B(LdaZero),
B(Star), R(8),
B(LdaTheHole),
B(SetPendingMessage),
......@@ -524,9 +524,9 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(10), U8(2), I8(0),
B(Jump), U8(8),
B(Ldar), R(9),
/* 105 S> */ B(Return),
B(Ldar), R(9),
B(ReThrow),
B(Ldar), R(9),
/* 105 S> */ B(Return),
B(LdaUndefined),
/* 105 S> */ B(Return),
]
......@@ -545,8 +545,8 @@ constant pool: [
Smi [9],
]
handlers: [
[13, 132, 140],
[16, 99, 101],
[13, 133, 141],
[16, 100, 102],
[201, 211, 213],
]
......@@ -794,7 +794,7 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
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(Star), R(8),
B(LdaSmi), I8(2),
......@@ -813,13 +813,13 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(8), U8(2), I8(0),
B(Ldar), R(15),
/* 40 E> */ B(Throw),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(11),
B(Mov), R(15), R(12),
B(Jump), U8(55),
B(Jump), U8(54),
B(LdaZero),
B(Star), R(7),
B(JumpLoop), U8(84), I8(0),
B(JumpLoop), U8(85), I8(0),
B(Jump), U8(33),
B(Star), R(15),
B(CreateCatchContext), R(15), U8(10),
......@@ -837,9 +837,9 @@ bytecodes: [
B(LdaSmi), I8(-1),
B(Star), R(12),
B(Star), R(11),
B(Jump), U8(8),
B(Jump), U8(7),
B(Star), R(12),
B(LdaSmi), I8(1),
B(LdaZero),
B(Star), R(11),
B(LdaTheHole),
B(SetPendingMessage),
......@@ -888,9 +888,9 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(13), U8(2), I8(0),
B(Jump), U8(8),
B(Ldar), R(12),
/* 49 S> */ B(Return),
B(Ldar), R(12),
B(ReThrow),
B(Ldar), R(12),
/* 49 S> */ B(Return),
B(LdaUndefined),
/* 49 S> */ B(Return),
]
......@@ -903,7 +903,7 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
Smi [15],
Smi [16],
Smi [7],
SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
......@@ -912,8 +912,8 @@ constant pool: [
Smi [9],
]
handlers: [
[48, 199, 207],
[51, 166, 168],
[48, 200, 208],
[51, 167, 169],
[268, 278, 280],
]
......
......@@ -138,7 +138,7 @@ bytecodes: [
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), U8(1),
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(Star), R(8),
B(LdaSmi), I8(2),
......@@ -157,13 +157,13 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(9), U8(2), I8(0),
B(Ldar), R(15),
/* 36 E> */ B(Throw),
B(LdaZero),
B(LdaSmi), I8(1),
B(Star), R(11),
B(Mov), R(15), R(12),
B(Jump), U8(55),
B(Jump), U8(54),
B(LdaZero),
B(Star), R(7),
B(JumpLoop), U8(84), I8(0),
B(JumpLoop), U8(85), I8(0),
B(Jump), U8(33),
B(Star), R(15),
B(CreateCatchContext), R(15), U8(11),
......@@ -181,9 +181,9 @@ bytecodes: [
B(LdaSmi), I8(-1),
B(Star), R(12),
B(Star), R(11),
B(Jump), U8(8),
B(Jump), U8(7),
B(Star), R(12),
B(LdaSmi), I8(1),
B(LdaZero),
B(Star), R(11),
B(LdaTheHole),
B(SetPendingMessage),
......@@ -232,9 +232,9 @@ bytecodes: [
B(SwitchOnSmiNoFeedback), U8(14), U8(2), I8(0),
B(Jump), U8(8),
B(Ldar), R(12),
/* 44 S> */ B(Return),
B(Ldar), R(12),
B(ReThrow),
B(Ldar), R(12),
/* 44 S> */ B(Return),
B(LdaUndefined),
/* 44 S> */ B(Return),
]
......@@ -248,7 +248,7 @@ constant pool: [
ONE_BYTE_INTERNALIZED_STRING_TYPE ["next"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["done"],
ONE_BYTE_INTERNALIZED_STRING_TYPE ["value"],
Smi [15],
Smi [16],
Smi [7],
SCOPE_INFO_TYPE,
ONE_BYTE_INTERNALIZED_STRING_TYPE ["return"],
......@@ -257,8 +257,8 @@ constant pool: [
Smi [9],
]
handlers: [
[48, 202, 210],
[51, 169, 171],
[48, 203, 211],
[51, 170, 172],
[271, 281, 283],
]
......@@ -288,8 +288,8 @@ bytecodes: [
B(Ldar), R(1),
/* 54 S> */ B(Return),
/* 43 S> */ B(LdaGlobal), U8(4), U8(0),
B(Star), R(8),
/* 50 E> */ B(CallUndefinedReceiver0), R(8), U8(2),
B(Star), R(5),
/* 50 E> */ B(CallUndefinedReceiver0), R(5), U8(2),
B(Star), R(6),
B(LdaNamedProperty), R(6), U8(5), U8(4),
B(Star), R(7),
......
......@@ -94,7 +94,7 @@ snippet: "
"
frame size: 10
parameter count: 1
bytecode array length: 133
bytecode array length: 131
bytecodes: [
/* 30 E> */ B(StackCheck),
B(CreateBlockContext), U8(0),
......@@ -115,32 +115,31 @@ bytecodes: [
B(Star), R(4),
B(LdaConstant), U8(4),
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(LdaNamedProperty), R(8), U8(6), U8(6),
B(Star), R(9),
B(CallProperty0), R(9), R(8), U8(8),
B(CallProperty0), R(8), R(7), U8(5),
B(Mov), R(5), R(2),
B(JumpIfJSReceiver), U8(7),
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(CallProperty0), R(6), R(7), U8(12),
B(LdaNamedProperty), R(6), U8(7), U8(7),
B(Star), R(5),
B(CallProperty0), R(5), R(6), U8(16),
B(Star), R(9),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), U8(1),
B(LdaNamedProperty), R(5), U8(8), U8(14),
B(JumpIfToBooleanTrue), U8(21),
B(LdaNamedProperty), R(5), U8(9), U8(16),
B(Star), R(5),
B(StaInArrayLiteral), R(4), R(3), U8(3),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(9), U8(1),
B(LdaNamedProperty), R(9), U8(8), U8(18),
B(JumpIfToBooleanTrue), U8(19),
B(LdaNamedProperty), R(9), U8(9), U8(9),
B(StaInArrayLiteral), R(4), R(3), U8(14),
B(Ldar), R(3),
B(Inc), U8(2),
B(Inc), U8(13),
B(Star), R(3),
B(JumpLoop), U8(35), I8(0),
B(JumpLoop), U8(33), I8(0),
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(CallJSRuntime), U8(%reflect_construct), R(2), U8(2),
B(LdaUndefined),
......
......@@ -93,7 +93,7 @@ snippet: "
"
frame size: 13
parameter count: 1
bytecode array length: 130
bytecode array length: 128
bytecodes: [
B(CreateRestParameter),
B(Star), R(2),
......@@ -112,28 +112,27 @@ bytecodes: [
B(Inc), U8(3),
/* 152 S> */ B(Star), R(6),
B(LdaNamedProperty), R(2), U8(0), U8(4),
B(Star), R(12),
B(CallProperty0), R(12), R(2), U8(6),
B(Mov), R(2), R(11),
B(Star), R(11),
B(CallProperty0), R(11), R(2), U8(6),
B(Mov), R(2), R(10),
B(Mov), R(1), R(4),
B(JumpIfJSReceiver), U8(7),
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(CallProperty0), R(9), R(10), U8(10),
B(LdaNamedProperty), R(9), U8(1), U8(8),
B(Star), R(8),
B(CallProperty0), R(8), R(9), U8(14),
B(Star), R(12),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(8), U8(1),
B(LdaNamedProperty), R(8), U8(2), U8(12),
B(JumpIfToBooleanTrue), U8(21),
B(LdaNamedProperty), R(8), U8(3), U8(14),
B(Star), R(8),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(12), U8(1),
B(LdaNamedProperty), R(12), U8(2), U8(16),
B(JumpIfToBooleanTrue), U8(19),
B(LdaNamedProperty), R(12), U8(3), U8(10),
B(StaInArrayLiteral), R(7), R(6), U8(1),
B(Ldar), R(6),
B(Inc), U8(3),
B(Star), R(6),
B(JumpLoop), U8(35), I8(0),
B(JumpLoop), U8(33), I8(0),
B(LdaSmi), I8(1),
B(StaInArrayLiteral), R(7), R(6), U8(1),
B(Mov), R(5), R(6),
......
......@@ -3641,8 +3641,16 @@ TEST(MaybeAssignedInsideLoop) {
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]=[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]=[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) { const foo = j }", {0}},
......@@ -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]=[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]=[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) { const foo = j }", {0}},
......@@ -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]=[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]=[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) { const foo = j }", {0}},
......@@ -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]=[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]=[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) { const foo = j }", {0}},
......@@ -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]=[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]=[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, 0}},
{false, "for (let j=x; j<10; ++j) { const foo = j }", {0, 0}},
......@@ -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]=[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]=[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, 0}},
{false, "for (let {j}=x; j<10; ++j) { const foo = j }", {0, 0}},
......@@ -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]=[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]=[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) { const foo = j }", {1}},
......@@ -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]=[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]=[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) { const foo = j }", {1}},
......@@ -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]=[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]=[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) { const foo = j }", {1}},
......@@ -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]=[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]=[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) { const foo = j }", {1}},
......@@ -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]=[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]=[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) { const foo = j }", {0, 1, 0}},
......@@ -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]=[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]=[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) { const foo = j }", {0, 1, 0}},
......@@ -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]=[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]=[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) { const foo = j }", {0, 1, 0}},
......@@ -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]=[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]=[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) { const foo = j }", {0, 1, 0}},
......@@ -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]=[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]=[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) { const foo = j }", {0}},
......@@ -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]=[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]=[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) { const foo = j }", {0}},
......@@ -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]=[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]=[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) { const foo = j }", {0}},
......@@ -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]=[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]=[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) { const foo = j }", {0}},
......@@ -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]=[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]=[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) { const foo = j }", {0, 0, 0}},
......@@ -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]=[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]=[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) { const foo = j }", {0, 0, 0}},
......@@ -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]=[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]=[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) { const foo = j }", {0, 0, 0}},
......@@ -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]=[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]=[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) { const foo = j }", {0, 0, 0}},
......@@ -3865,8 +4043,16 @@ TEST(MaybeAssignedInsideLoop) {
{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]=[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) { const foo = j }", {0}},
......@@ -3875,8 +4061,16 @@ TEST(MaybeAssignedInsideLoop) {
{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]=[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 { const foo = j } while (j)", {0}},
......
......@@ -145,38 +145,6 @@
'language/eval-code/direct/var-env-lower-lex-catch-non-strict': [FAIL],
# 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/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