Commit 5e725a2b authored by Leszek Swirski's avatar Leszek Swirski Committed by Commit Bot

[parser] Don't desugar destructuring declarations.

Emit a single destructuring assignment for destructuring declarations,
which can be desugared by the bytecode generator. This allows us to
remove destructuring desugaring from the parser (specifically, the
pattern rewriter) entirely.

The pattern "rewriter" is now only responsible for walking the
destructuring pattern to declare variables, mark them assigned, and
potentially rewrite scopes for the edge case of parameters with a sloppy
eval.

Note that since the rewriter is no longer rewriting, we have to flip the
VariableProxy copying logic for var re-lookup, so that we now pass the
new VariableProxy to the variable declaration and leave the original
unresolved (rather than passing the original through and rewriting to a
new unresolved VariableProxy).

This change does have some effect on breakpoint locations, due to some
of the available information changing between the parser and bytecode
generator, however the new locations appear to be more consistent
between assignments and declarations.

Change-Id: I3a58dd0a387d2bfb8e5e9e22dde0acc5f440cb82
Reviewed-on: https://chromium-review.googlesource.com/c/1382462
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 avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58670}
parent 5f138ac1
...@@ -2730,34 +2730,14 @@ class GetIterator final : public Expression { ...@@ -2730,34 +2730,14 @@ class GetIterator final : public Expression {
Expression* iterable() const { return iterable_; } Expression* iterable() const { return iterable_; }
Expression* iterable_for_call_printer() const {
return destructured_iterable_ != nullptr ? destructured_iterable_
: iterable_;
}
private: private:
friend class AstNodeFactory; friend class AstNodeFactory;
GetIterator(Expression* iterable, Expression* destructured_iterable,
IteratorType hint, int pos)
: Expression(pos, kGetIterator),
hint_(hint),
iterable_(iterable),
destructured_iterable_(destructured_iterable) {}
GetIterator(Expression* iterable, IteratorType hint, int pos) GetIterator(Expression* iterable, IteratorType hint, int pos)
: Expression(pos, kGetIterator), : Expression(pos, kGetIterator), hint_(hint), iterable_(iterable) {}
hint_(hint),
iterable_(iterable),
destructured_iterable_(nullptr) {}
IteratorType hint_; IteratorType hint_;
Expression* iterable_; Expression* iterable_;
// iterable_ is the variable proxy, while destructured_iterable_ points to
// the raw value stored in the variable proxy. This is only used for
// pretty printing error messages.
Expression* destructured_iterable_;
}; };
// Represents the spec operation `GetTemplateObject(templateLiteral)` // Represents the spec operation `GetTemplateObject(templateLiteral)`
...@@ -3397,12 +3377,6 @@ class AstNodeFactory final { ...@@ -3397,12 +3377,6 @@ class AstNodeFactory final {
return new (zone_) EmptyParentheses(pos); return new (zone_) EmptyParentheses(pos);
} }
GetIterator* NewGetIterator(Expression* iterable,
Expression* destructured_iterable,
IteratorType hint, int pos) {
return new (zone_) GetIterator(iterable, destructured_iterable, hint, pos);
}
GetIterator* NewGetIterator(Expression* iterable, IteratorType hint, GetIterator* NewGetIterator(Expression* iterable, IteratorType hint,
int pos) { int pos) {
return new (zone_) GetIterator(iterable, hint, pos); return new (zone_) GetIterator(iterable, hint, pos);
......
...@@ -285,7 +285,24 @@ void CallPrinter::VisitVariableProxy(VariableProxy* node) { ...@@ -285,7 +285,24 @@ void CallPrinter::VisitVariableProxy(VariableProxy* node) {
void CallPrinter::VisitAssignment(Assignment* node) { void CallPrinter::VisitAssignment(Assignment* node) {
Find(node->target()); Find(node->target());
Find(node->value()); if (node->target()->IsArrayLiteral()) {
// Special case the visit for destructuring array assignment.
bool was_found = false;
if (node->value()->position() == position_) {
is_iterator_error_ = true;
was_found = !found_;
if (was_found) {
found_ = true;
}
}
Find(node->value(), true);
if (was_found) {
done_ = true;
found_ = false;
}
} else {
Find(node->value());
}
} }
void CallPrinter::VisitCompoundAssignment(CompoundAssignment* node) { void CallPrinter::VisitCompoundAssignment(CompoundAssignment* node) {
...@@ -347,7 +364,7 @@ void CallPrinter::VisitCall(Call* node) { ...@@ -347,7 +364,7 @@ void CallPrinter::VisitCall(Call* node) {
found_ = true; found_ = true;
} }
Find(node->expression(), true); Find(node->expression(), true);
if (!was_found) Print("(...)"); if (!was_found && !is_iterator_error_) Print("(...)");
FindArguments(node->arguments()); FindArguments(node->arguments());
if (was_found) { if (was_found) {
done_ = true; done_ = true;
...@@ -371,7 +388,7 @@ void CallPrinter::VisitCallNew(CallNew* node) { ...@@ -371,7 +388,7 @@ void CallPrinter::VisitCallNew(CallNew* node) {
} }
found_ = true; found_ = true;
} }
Find(node->expression(), was_found); Find(node->expression(), was_found || is_iterator_error_);
FindArguments(node->arguments()); FindArguments(node->arguments());
if (was_found) { if (was_found) {
done_ = true; done_ = true;
...@@ -465,7 +482,7 @@ void CallPrinter::VisitGetIterator(GetIterator* node) { ...@@ -465,7 +482,7 @@ void CallPrinter::VisitGetIterator(GetIterator* node) {
found_ = true; found_ = true;
} }
} }
Find(node->iterable_for_call_printer(), true); Find(node->iterable(), true);
if (was_found) { if (was_found) {
done_ = true; done_ = true;
found_ = false; found_ = false;
......
...@@ -3197,7 +3197,8 @@ Expression* BytecodeGenerator::GetDestructuringDefaultValue( ...@@ -3197,7 +3197,8 @@ Expression* BytecodeGenerator::GetDestructuringDefaultValue(
// %FinalizeIteration(iterator, done, iteration_continuation) // %FinalizeIteration(iterator, done, iteration_continuation)
// } // }
void BytecodeGenerator::BuildDestructuringArrayAssignment( void BytecodeGenerator::BuildDestructuringArrayAssignment(
ArrayLiteral* pattern) { ArrayLiteral* pattern, Token::Value op,
LookupHoistingMode lookup_hoisting_mode) {
RegisterAllocationScope scope(this); RegisterAllocationScope scope(this);
Register value = register_allocator()->NewRegister(); Register value = register_allocator()->NewRegister();
...@@ -3302,8 +3303,7 @@ void BytecodeGenerator::BuildDestructuringArrayAssignment( ...@@ -3302,8 +3303,7 @@ void BytecodeGenerator::BuildDestructuringArrayAssignment(
} }
builder()->Bind(&do_assignment); builder()->Bind(&do_assignment);
// TODO(leszeks): This should be the position of the assignment. BuildAssignment(lhs_data, op, lookup_hoisting_mode);
BuildAssignment(lhs_data, Token::ASSIGN, LookupHoistingMode::kNormal);
} else { } else {
DCHECK_EQ(lhs_data.assign_type(), NON_PROPERTY); DCHECK_EQ(lhs_data.assign_type(), NON_PROPERTY);
is_done.Bind(builder()); is_done.Bind(builder());
...@@ -3312,10 +3312,14 @@ void BytecodeGenerator::BuildDestructuringArrayAssignment( ...@@ -3312,10 +3312,14 @@ void BytecodeGenerator::BuildDestructuringArrayAssignment(
if (spread) { if (spread) {
RegisterAllocationScope scope(this); RegisterAllocationScope scope(this);
builder()->SetExpressionAsStatementPosition(spread);
// A spread is turned into a loop over the remainer of the iterator. // A spread is turned into a loop over the remainer of the iterator.
Expression* target = spread->expression(); Expression* target = spread->expression();
if (!target->IsPattern()) {
builder()->SetExpressionAsStatementPosition(spread);
}
AssignmentLhsData lhs_data = PrepareAssignmentLhs(target); AssignmentLhsData lhs_data = PrepareAssignmentLhs(target);
// var array = []; // var array = [];
...@@ -3339,7 +3343,7 @@ void BytecodeGenerator::BuildDestructuringArrayAssignment( ...@@ -3339,7 +3343,7 @@ void BytecodeGenerator::BuildDestructuringArrayAssignment(
// Assign the array to the LHS. // Assign the array to the LHS.
builder()->LoadAccumulatorWithRegister(array); builder()->LoadAccumulatorWithRegister(array);
BuildAssignment(lhs_data, Token::ASSIGN, LookupHoistingMode::kNormal); BuildAssignment(lhs_data, op, lookup_hoisting_mode);
} }
} }
try_control_builder.EndTry(); try_control_builder.EndTry();
...@@ -3393,7 +3397,8 @@ void BytecodeGenerator::BuildDestructuringArrayAssignment( ...@@ -3393,7 +3397,8 @@ void BytecodeGenerator::BuildDestructuringArrayAssignment(
// //
// b.c = %CopyDataPropertiesWithExcludedProperties.call(rest_runtime_callargs); // b.c = %CopyDataPropertiesWithExcludedProperties.call(rest_runtime_callargs);
void BytecodeGenerator::BuildDestructuringObjectAssignment( void BytecodeGenerator::BuildDestructuringObjectAssignment(
ObjectLiteral* pattern) { ObjectLiteral* pattern, Token::Value op,
LookupHoistingMode lookup_hoisting_mode) {
RegisterAllocationScope scope(this); RegisterAllocationScope scope(this);
// if (value === null || value === undefined) // if (value === null || value === undefined)
...@@ -3411,6 +3416,7 @@ void BytecodeGenerator::BuildDestructuringObjectAssignment( ...@@ -3411,6 +3416,7 @@ void BytecodeGenerator::BuildDestructuringObjectAssignment(
// TODO(leszeks): Don't do this calculation here, but instead do it in a // TODO(leszeks): Don't do this calculation here, but instead do it in a
// runtime method. // runtime method.
auto source_position = pattern->position();
const AstRawString* property_name = ast_string_constants()->empty_string(); const AstRawString* property_name = ast_string_constants()->empty_string();
MessageTemplate msg = MessageTemplate::kNonCoercible; MessageTemplate msg = MessageTemplate::kNonCoercible;
for (ObjectLiteralProperty* pattern_property : *pattern->properties()) { for (ObjectLiteralProperty* pattern_property : *pattern->properties()) {
...@@ -3418,12 +3424,14 @@ void BytecodeGenerator::BuildDestructuringObjectAssignment( ...@@ -3418,12 +3424,14 @@ void BytecodeGenerator::BuildDestructuringObjectAssignment(
if (key->IsPropertyName()) { if (key->IsPropertyName()) {
property_name = key->AsLiteral()->AsRawPropertyName(); property_name = key->AsLiteral()->AsRawPropertyName();
msg = MessageTemplate::kNonCoercibleWithProperty; msg = MessageTemplate::kNonCoercibleWithProperty;
source_position = key->position();
break; break;
} }
} }
RegisterList new_type_error_args = register_allocator()->NewRegisterList(2); RegisterList new_type_error_args = register_allocator()->NewRegisterList(2);
// throw %NewTypeError(msg, property_name, source_position) // throw %NewTypeError(msg, property_name, source_position)
builder()->SetExpressionPosition(source_position);
builder() builder()
->LoadLiteral(Smi::FromEnum(msg)) ->LoadLiteral(Smi::FromEnum(msg))
.StoreAccumulatorInRegister(new_type_error_args[0]) .StoreAccumulatorInRegister(new_type_error_args[0])
...@@ -3528,7 +3536,7 @@ void BytecodeGenerator::BuildDestructuringObjectAssignment( ...@@ -3528,7 +3536,7 @@ void BytecodeGenerator::BuildDestructuringObjectAssignment(
builder()->Bind(&value_not_undefined); builder()->Bind(&value_not_undefined);
} }
BuildAssignment(lhs_data, Token::ASSIGN, LookupHoistingMode::kNormal); BuildAssignment(lhs_data, op, lookup_hoisting_mode);
i++; i++;
} }
...@@ -3546,14 +3554,10 @@ void BytecodeGenerator::BuildAssignment( ...@@ -3546,14 +3554,10 @@ void BytecodeGenerator::BuildAssignment(
case NON_PROPERTY: { case NON_PROPERTY: {
if (ObjectLiteral* pattern = lhs_data.expr()->AsObjectLiteral()) { if (ObjectLiteral* pattern = lhs_data.expr()->AsObjectLiteral()) {
// Split object literals into destructuring. // Split object literals into destructuring.
DCHECK_EQ(op, Token::ASSIGN); BuildDestructuringObjectAssignment(pattern, op, lookup_hoisting_mode);
DCHECK_EQ(lookup_hoisting_mode, LookupHoistingMode::kNormal);
BuildDestructuringObjectAssignment(pattern);
} else if (ArrayLiteral* pattern = lhs_data.expr()->AsArrayLiteral()) { } else if (ArrayLiteral* pattern = lhs_data.expr()->AsArrayLiteral()) {
// Split object literals into destructuring. // Split object literals into destructuring.
DCHECK_EQ(op, Token::ASSIGN); BuildDestructuringArrayAssignment(pattern, op, lookup_hoisting_mode);
DCHECK_EQ(lookup_hoisting_mode, LookupHoistingMode::kNormal);
BuildDestructuringArrayAssignment(pattern);
} else { } else {
DCHECK(lhs_data.expr()->IsVariableProxy()); DCHECK(lhs_data.expr()->IsVariableProxy());
VariableProxy* proxy = lhs_data.expr()->AsVariableProxy(); VariableProxy* proxy = lhs_data.expr()->AsVariableProxy();
......
...@@ -200,8 +200,12 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> { ...@@ -200,8 +200,12 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
LookupHoistingMode lookup_hoisting_mode); LookupHoistingMode lookup_hoisting_mode);
Expression* GetDestructuringDefaultValue(Expression** target); Expression* GetDestructuringDefaultValue(Expression** target);
void BuildDestructuringArrayAssignment(ArrayLiteral* pattern); void BuildDestructuringArrayAssignment(
void BuildDestructuringObjectAssignment(ObjectLiteral* pattern); ArrayLiteral* pattern, Token::Value op,
LookupHoistingMode lookup_hoisting_mode);
void BuildDestructuringObjectAssignment(
ObjectLiteral* pattern, Token::Value op,
LookupHoistingMode lookup_hoisting_mode);
void BuildLoadNamedProperty(const Expression* object_expr, Register object, void BuildLoadNamedProperty(const Expression* object_expr, Register object,
const AstRawString* name); const AstRawString* name);
......
This diff is collapsed.
...@@ -300,7 +300,7 @@ bytecodes: [ ...@@ -300,7 +300,7 @@ bytecodes: [
B(Star), R(7), B(Star), R(7),
B(Mov), R(8), R(3), B(Mov), R(8), R(3),
/* 22 E> */ B(StackCheck), /* 22 E> */ B(StackCheck),
B(Mov), R(3), R(0), /* 31 S> */ B(Mov), R(3), R(0),
/* 42 S> */ B(LdaFalse), /* 42 S> */ B(LdaFalse),
B(Star), R(21), B(Star), R(21),
B(Mov), R(2), R(19), B(Mov), R(2), R(19),
......
...@@ -18,7 +18,7 @@ bytecodes: [ ...@@ -18,7 +18,7 @@ bytecodes: [
B(CreateRestParameter), B(CreateRestParameter),
B(Star), R(0), B(Star), R(0),
/* 10 E> */ B(StackCheck), /* 10 E> */ B(StackCheck),
B(Star), R(1), /* 22 S> */ B(Star), R(1),
/* 42 S> */ B(Return), /* 42 S> */ B(Return),
] ]
constant pool: [ constant pool: [
...@@ -38,8 +38,8 @@ bytecodes: [ ...@@ -38,8 +38,8 @@ bytecodes: [
B(CreateRestParameter), B(CreateRestParameter),
B(Star), R(0), B(Star), R(0),
/* 10 E> */ B(StackCheck), /* 10 E> */ B(StackCheck),
B(Mov), R(arg0), R(1), /* 12 S> */ B(Mov), R(arg0), R(1),
B(Mov), R(0), R(2), /* 25 S> */ B(Mov), R(0), R(2),
/* 29 S> */ B(Ldar), R(2), /* 29 S> */ B(Ldar), R(2),
/* 45 S> */ B(Return), /* 45 S> */ B(Return),
] ]
...@@ -60,8 +60,8 @@ bytecodes: [ ...@@ -60,8 +60,8 @@ bytecodes: [
B(CreateRestParameter), B(CreateRestParameter),
B(Star), R(0), B(Star), R(0),
/* 10 E> */ B(StackCheck), /* 10 E> */ B(StackCheck),
B(Mov), R(arg0), R(1), /* 12 S> */ B(Mov), R(arg0), R(1),
B(Mov), R(0), R(2), /* 25 S> */ B(Mov), R(0), R(2),
/* 29 S> */ B(LdaZero), /* 29 S> */ B(LdaZero),
/* 44 E> */ B(LdaKeyedProperty), R(2), U8(0), /* 44 E> */ B(LdaKeyedProperty), R(2), U8(0),
/* 48 S> */ B(Return), /* 48 S> */ B(Return),
...@@ -85,8 +85,8 @@ bytecodes: [ ...@@ -85,8 +85,8 @@ bytecodes: [
B(CreateRestParameter), B(CreateRestParameter),
B(Star), R(0), B(Star), R(0),
/* 10 E> */ B(StackCheck), /* 10 E> */ B(StackCheck),
B(Mov), R(arg0), R(1), /* 12 S> */ B(Mov), R(arg0), R(1),
B(Mov), R(0), R(2), /* 25 S> */ B(Mov), R(0), R(2),
/* 29 S> */ B(LdaZero), /* 29 S> */ B(LdaZero),
/* 44 E> */ B(LdaKeyedProperty), R(2), U8(1), /* 44 E> */ B(LdaKeyedProperty), R(2), U8(1),
B(Star), R(4), B(Star), R(4),
......
...@@ -371,7 +371,7 @@ bytecodes: [ ...@@ -371,7 +371,7 @@ bytecodes: [
B(Star), R(2), B(Star), R(2),
B(LdaConstant), U8(1), B(LdaConstant), U8(1),
B(Star), R(3), B(Star), R(3),
/* 57 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), /* 54 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw), B(Throw),
B(Star), R(4), B(Star), R(4),
/* 54 S> */ B(LdaNamedProperty), R(4), U8(1), U8(1), /* 54 S> */ B(LdaNamedProperty), R(4), U8(1), U8(1),
...@@ -406,7 +406,7 @@ bytecodes: [ ...@@ -406,7 +406,7 @@ bytecodes: [
B(Star), R(2), B(Star), R(2),
B(LdaConstant), U8(1), B(LdaConstant), U8(1),
B(Star), R(3), B(Star), R(3),
/* 66 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), /* 57 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw), B(Throw),
/* 61 S> */ B(Star), R(4), /* 61 S> */ B(Star), R(4),
B(LdaNamedProperty), R(4), U8(1), U8(1), B(LdaNamedProperty), R(4), U8(1), U8(1),
...@@ -440,7 +440,7 @@ bytecodes: [ ...@@ -440,7 +440,7 @@ bytecodes: [
B(Star), R(2), B(Star), R(2),
B(LdaConstant), U8(1), B(LdaConstant), U8(1),
B(Star), R(3), B(Star), R(3),
/* 74 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2), /* 64 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(2), U8(2),
B(Throw), B(Throw),
B(Star), R(4), B(Star), R(4),
/* 64 S> */ B(LdaConstant), U8(1), /* 64 S> */ B(LdaConstant), U8(1),
......
...@@ -73,13 +73,13 @@ bytecodes: [ ...@@ -73,13 +73,13 @@ bytecodes: [
B(Star), R(7), B(Star), R(7),
B(Mov), R(8), R(3), B(Mov), R(8), R(3),
/* 23 E> */ B(StackCheck), /* 23 E> */ B(StackCheck),
B(Mov), R(3), R(0), /* 38 S> */ B(Mov), R(3), R(0),
B(LdaZero), B(LdaZero),
B(Star), R(7), B(Star), R(7),
B(JumpLoop), U8(79), I8(0), B(JumpLoop), U8(79), I8(0),
B(Jump), U8(37), B(Jump), U8(37),
B(Star), R(16), B(Star), R(16),
B(CreateCatchContext), R(16), U8(9), /* 38 E> */ B(CreateCatchContext), R(16), U8(9),
B(Star), R(15), B(Star), R(15),
B(LdaTheHole), B(LdaTheHole),
B(SetPendingMessage), B(SetPendingMessage),
...@@ -289,7 +289,7 @@ bytecodes: [ ...@@ -289,7 +289,7 @@ bytecodes: [
B(Star), R(7), B(Star), R(7),
B(Mov), R(8), R(3), B(Mov), R(8), R(3),
/* 23 E> */ B(StackCheck), /* 23 E> */ B(StackCheck),
B(Mov), R(3), R(0), /* 38 S> */ B(Mov), R(3), R(0),
/* 56 S> */ B(LdaSmi), I8(1), /* 56 S> */ B(LdaSmi), I8(1),
B(Star), R(12), B(Star), R(12),
B(Mov), R(8), R(13), B(Mov), R(8), R(13),
...@@ -517,7 +517,7 @@ bytecodes: [ ...@@ -517,7 +517,7 @@ bytecodes: [
B(Star), R(7), B(Star), R(7),
B(Mov), R(8), R(3), B(Mov), R(8), R(3),
/* 23 E> */ B(StackCheck), /* 23 E> */ B(StackCheck),
B(Mov), R(3), R(0), /* 38 S> */ B(Mov), R(3), R(0),
/* 63 S> */ B(LdaSmi), I8(10), /* 63 S> */ B(LdaSmi), I8(10),
/* 69 E> */ B(TestEqual), R(0), U8(17), /* 69 E> */ B(TestEqual), R(0), U8(17),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
......
...@@ -81,7 +81,7 @@ bytecodes: [ ...@@ -81,7 +81,7 @@ bytecodes: [
B(JumpIfUndefined), U8(8), B(JumpIfUndefined), U8(8),
B(Star), R(1), B(Star), R(1),
/* 54 E> */ B(StackCheck), /* 54 E> */ B(StackCheck),
B(Star), R(2), /* 63 S> */ B(Star), R(2),
/* 82 S> */ B(Return), /* 82 S> */ B(Return),
B(ForInStep), R(7), B(ForInStep), R(7),
B(Star), R(7), B(Star), R(7),
...@@ -121,7 +121,7 @@ bytecodes: [ ...@@ -121,7 +121,7 @@ bytecodes: [
B(JumpIfUndefined), U8(17), B(JumpIfUndefined), U8(17),
B(Star), R(1), B(Star), R(1),
/* 45 E> */ B(StackCheck), /* 45 E> */ B(StackCheck),
B(Star), R(2), /* 54 S> */ B(Star), R(2),
/* 70 S> */ B(Ldar), R(1), /* 70 S> */ B(Ldar), R(1),
/* 75 E> */ B(Add), R(0), U8(2), /* 75 E> */ B(Add), R(0), U8(2),
B(Mov), R(0), R(8), B(Mov), R(0), R(8),
......
...@@ -42,13 +42,13 @@ bytecodes: [ ...@@ -42,13 +42,13 @@ bytecodes: [
B(Star), R(5), B(Star), R(5),
B(Mov), R(6), R(0), B(Mov), R(6), R(0),
/* 34 E> */ B(StackCheck), /* 34 E> */ B(StackCheck),
B(Mov), R(0), R(1), /* 43 S> */ B(Mov), R(0), R(1),
B(LdaZero), B(LdaZero),
B(Star), R(5), B(Star), R(5),
B(JumpLoop), U8(44), I8(0), B(JumpLoop), U8(44), I8(0),
B(Jump), U8(33), B(Jump), U8(33),
B(Star), R(13), B(Star), R(13),
B(CreateCatchContext), R(13), U8(5), /* 43 E> */ B(CreateCatchContext), R(13), U8(5),
B(PushContext), R(13), B(PushContext), R(13),
B(Star), R(12), B(Star), R(12),
B(LdaSmi), I8(2), B(LdaSmi), I8(2),
...@@ -173,7 +173,7 @@ bytecodes: [ ...@@ -173,7 +173,7 @@ bytecodes: [
B(Star), R(6), B(Star), R(6),
B(Mov), R(7), R(1), B(Mov), R(7), R(1),
/* 54 E> */ B(StackCheck), /* 54 E> */ B(StackCheck),
B(Mov), R(1), R(2), /* 63 S> */ B(Mov), R(1), R(2),
/* 73 S> */ B(LdaSmi), I8(1), /* 73 S> */ B(LdaSmi), I8(1),
B(Star), R(10), B(Star), R(10),
B(Mov), R(7), R(11), B(Mov), R(7), R(11),
...@@ -310,7 +310,7 @@ bytecodes: [ ...@@ -310,7 +310,7 @@ bytecodes: [
B(Star), R(5), B(Star), R(5),
B(Mov), R(6), R(0), B(Mov), R(6), R(0),
/* 34 E> */ B(StackCheck), /* 34 E> */ B(StackCheck),
B(Mov), R(0), R(1), /* 43 S> */ B(Mov), R(0), R(1),
/* 66 S> */ B(LdaSmi), I8(10), /* 66 S> */ B(LdaSmi), I8(10),
/* 72 E> */ B(TestEqual), R(1), U8(13), /* 72 E> */ B(TestEqual), R(1), U8(13),
B(JumpIfFalse), U8(4), B(JumpIfFalse), U8(4),
......
...@@ -145,7 +145,7 @@ bytecodes: [ ...@@ -145,7 +145,7 @@ bytecodes: [
B(Star), R(7), B(Star), R(7),
B(Mov), R(8), R(3), B(Mov), R(8), R(3),
/* 16 E> */ B(StackCheck), /* 16 E> */ B(StackCheck),
B(Mov), R(3), R(0), /* 25 S> */ B(Mov), R(3), R(0),
/* 36 S> */ B(LdaFalse), /* 36 S> */ B(LdaFalse),
B(Star), R(16), B(Star), R(16),
B(Mov), R(0), R(15), B(Mov), R(0), R(15),
......
...@@ -220,23 +220,22 @@ snippet: " ...@@ -220,23 +220,22 @@ snippet: "
" "
frame size: 6 frame size: 6
parameter count: 1 parameter count: 1
bytecode array length: 64 bytecode array length: 62
bytecodes: [ bytecodes: [
/* 10 E> */ B(StackCheck), /* 10 E> */ B(StackCheck),
B(CreateObjectLiteral), U8(0), U8(0), U8(41), /* 37 S> */ B(CreateObjectLiteral), U8(0), U8(0), U8(41),
B(Star), R(3), B(JumpIfNull), U8(4),
B(JumpIfUndefined), U8(6), B(JumpIfNotUndefined), U8(16),
B(Ldar), R(3),
B(JumpIfNotNull), U8(16),
B(LdaSmi), I8(81), B(LdaSmi), I8(81),
B(Star), R(4), B(Star), R(3),
B(LdaConstant), U8(1), B(LdaConstant), U8(1),
B(Star), R(4),
/* 28 E> */ B(CallRuntime), U16(Runtime::kNewTypeError), R(3), U8(2),
B(Throw),
B(Star), R(5), B(Star), R(5),
B(CallRuntime), U16(Runtime::kNewTypeError), R(4), U8(2), /* 28 S> */ B(LdaNamedProperty), R(5), U8(1), U8(1),
/* 28 E> */ B(Throw),
/* 37 S> */ B(LdaNamedProperty), R(3), U8(1), U8(1),
B(Star), R(1), B(Star), R(1),
/* 37 S> */ B(LdaNamedProperty), R(3), U8(2), U8(3), /* 31 S> */ B(LdaNamedProperty), R(5), U8(2), U8(3),
B(Star), R(2), B(Star), R(2),
/* 55 S> */ B(LdaZero), /* 55 S> */ B(LdaZero),
/* 55 E> */ B(TestGreaterThan), R(2), U8(5), /* 55 E> */ B(TestGreaterThan), R(2), U8(5),
......
...@@ -57,7 +57,7 @@ bytecodes: [ ...@@ -57,7 +57,7 @@ bytecodes: [
B(Star), R(2), B(Star), R(2),
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
/* 128 E> */ B(StackCheck), /* 128 E> */ B(StackCheck),
B(Mov), R(2), R(3), /* 136 S> */ B(Mov), R(2), R(3),
/* 140 S> */ B(Ldar), R(closure), /* 140 S> */ B(Ldar), R(closure),
B(GetSuperConstructor), R(5), B(GetSuperConstructor), R(5),
B(LdaSmi), I8(1), B(LdaSmi), I8(1),
...@@ -99,7 +99,7 @@ bytecodes: [ ...@@ -99,7 +99,7 @@ bytecodes: [
B(Star), R(2), B(Star), R(2),
B(Mov), R(closure), R(1), B(Mov), R(closure), R(1),
/* 128 E> */ B(StackCheck), /* 128 E> */ B(StackCheck),
B(Mov), R(2), R(3), /* 136 S> */ B(Mov), R(2), R(3),
/* 140 S> */ B(Ldar), R(closure), /* 140 S> */ B(Ldar), R(closure),
B(GetSuperConstructor), R(5), B(GetSuperConstructor), R(5),
B(CreateEmptyArrayLiteral), U8(0), B(CreateEmptyArrayLiteral), U8(0),
......
...@@ -3724,9 +3724,9 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3724,9 +3724,9 @@ TEST(MaybeAssignedInsideLoop) {
{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}}, {true, "for (let j=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", {0, 0}},
{false, "for (let j=x; j<10; ++j) { let foo = j }", {0, 0}}, {false, "for (let j=x; j<10; ++j) { let foo = j }", {0, 0}},
{false, "for (let j=x; j<10; ++j) { let [foo] = [j] }", {0, 0, 0}}, {false, "for (let j=x; j<10; ++j) { let [foo] = [j] }", {0, 0}},
{false, "for (let j=x; j<10; ++j) { const foo = j }", {0, 0}}, {false, "for (let j=x; j<10; ++j) { const foo = j }", {0, 0}},
{false, "for (let j=x; j<10; ++j) { const [foo] = [j] }", {0, 0, 0}}, {false, "for (let j=x; j<10; ++j) { const [foo] = [j] }", {0, 0}},
{false, {false,
"for (let j=x; j<10; ++j) { function foo() {return j} }", "for (let j=x; j<10; ++j) { function foo() {return j} }",
{0, 0, 0}}, {0, 0, 0}},
...@@ -3746,9 +3746,9 @@ TEST(MaybeAssignedInsideLoop) { ...@@ -3746,9 +3746,9 @@ TEST(MaybeAssignedInsideLoop) {
"for (let {j}=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }", "for (let {j}=x; j<10; ++j) { let foo; [[foo]=[42]] = [] }",
{0, 0}}, {0, 0}},
{false, "for (let {j}=x; j<10; ++j) { let foo = j }", {0, 0}}, {false, "for (let {j}=x; j<10; ++j) { let foo = j }", {0, 0}},
{false, "for (let {j}=x; j<10; ++j) { let [foo] = [j] }", {0, 0, 0}}, {false, "for (let {j}=x; j<10; ++j) { let [foo] = [j] }", {0, 0}},
{false, "for (let {j}=x; j<10; ++j) { const foo = j }", {0, 0}}, {false, "for (let {j}=x; j<10; ++j) { const foo = j }", {0, 0}},
{false, "for (let {j}=x; j<10; ++j) { const [foo] = [j] }", {0, 0, 0}}, {false, "for (let {j}=x; j<10; ++j) { const [foo] = [j] }", {0, 0}},
{false, {false,
"for (let {j}=x; j<10; ++j) { function foo(){return j} }", "for (let {j}=x; j<10; ++j) { function foo(){return j} }",
{0, 0, 0}}, {0, 0, 0}},
......
...@@ -21,89 +21,89 @@ function listener(event, exec_state, event_data, data) { ...@@ -21,89 +21,89 @@ function listener(event, exec_state, event_data, data) {
} catch (e) { } catch (e) {
exception = e; exception = e;
print(e); print(e);
} } // B34
}; };
Debug.setListener(listener); Debug.setListener(listener);
var id = x => x; // B9 B10 B36 B37 var id = x => x; // B11 B12 B42 B43
function test() { function test() {
debugger; // B0 debugger; // B0
function fx1([ function fx1([
a, // B2 a, // B3
b // B3 b // B4
]) { ]) { // B2
assertEquals([1, 2], [a, b]); // B4 assertEquals([1, 2], [a, b]); // B5
} // B5 } // B6
fx1([1, 2, 3]); // B1 fx1([1, 2, 3]); // B1
function f2([ function f2([
a, // B7 a, // B9
b = id(3) // B8 b = id(3) // B10
]) { ]) { // B8
assertEquals([4, 3], [a, b]); // B11 assertEquals([4, 3], [a, b]); // B13
} // B12 } // B14
f2([4]); // B6 f2([4]); // B7
function f3({ function f3({
x: a, // B14 x: a, // B17
y: b // B15 y: b // B18
}) { }) { // B16
assertEquals([5, 6], [a, b]); // B16 assertEquals([5, 6], [a, b]); // B19
} // B17 } // B20
f3({y: 6, x: 5}); // B13 f3({y: 6, x: 5}); // B15
function f4([ function f4([
a, // B19 a, // B23
{ {
b, // B20 b, // B24
c, // B21 c, // B25
} }
]) { ]) { // B22
assertEquals([2, 4, 6], [a, b, c]); // B22 assertEquals([2, 4, 6], [a, b, c]); // B26
} // B23 } // B27
f4([2, {c: 6, b: 4}]); // B18 f4([2, {c: 6, b: 4}]); // B21
function f5([ function f5([
{ {
a, // B25 a, // B30
b = 7 // B26 b = 7 // B31
}, },
c = 3 // B27 c = 3 // B32
] = [{a:1}]) { ] = [{a:1}]) { // B29
assertEquals([1, 7, 3], [a, b, c]); // B28 assertEquals([1, 7, 3], [a, b, c]); // B33
} // B29 } // B34
f5(); // B24 f5(); // B28
var name = "x"; // B30 var name = "x"; // B35
function f6({ function f6({
[id(name)]: a, // B34 B35 [id(name)]: a, // B40 B41
b = a // B38 b = a // B44
}) { }) { // B39
assertEquals([9, 9], [a, b]); // B39 assertEquals([9, 9], [a, b]); // B45
} // B40 } // B46
var o6 = {}; // B31 var o6 = {}; // B36
o6[name] = 9; // B32 o6[name] = 9; // B37
f6(o6); // B33 f6(o6); // B38
try { try {
throw [3, 4]; // B41 throw [3, 4]; // B47
} catch ([ } catch ([
a, // B42 a, // B49
b, // B43 b, // B50
c = 6 // B44 c = 6 // B51
]) { ]) { // B48
assertEquals([3, 4, 6], [a, b, c]); // B45 assertEquals([3, 4, 6], [a, b, c]); // B52
} }
var { var {
x: a, x: a, // B54
y: b = 9 y: b = 9 // B55
} = { x: 4 }; // B46 } = { x: 4 }; // B53
assertEquals([4, 9], [a, b]); // B47 assertEquals([4, 9], [a, b]); // B56
} // B48 } // B57
test(); test();
Debug.setListener(null); // B49 Debug.setListener(null); // B58
assertNull(exception); assertNull(exception);
...@@ -41,5 +41,5 @@ Debug.setListener(null); // c ...@@ -41,5 +41,5 @@ Debug.setListener(null); // c
assertNull(exception); assertNull(exception);
assertEquals("default", result); assertEquals("default", result);
assertEquals(["a0","b13","f18b13","d2f18b13","d19f18b13","g14b13","c0"], assertEquals(["a0","b13","f31b13","f18b13","d2f18b13","d19f18b13","g14b13","c0"],
log); log);
...@@ -15,7 +15,7 @@ function testFunction() { ...@@ -15,7 +15,7 @@ function testFunction() {
var y = |_|(a = 100); var y = |_|(a = 100);
var z = |_|x + (a = 1) + (a = 2) + (a = 3) + |C|f(); var z = |_|x + (a = 1) + (a = 2) + (a = 3) + |C|f();
function f() { function f() {
for (let { x, y } = |_|{ x: 0, y: 1 }; y |_|> 0; --|_|y) { let z = |_|x + y; } for (let { |_|x, |_|y } = |_|{ x: 0, y: 1 }; y |_|> 0; --|_|y) { let z = |_|x + y; }
|R|} |R|}
var b = obj1.|_|a; var b = obj1.|_|a;
|_|(async function asyncF() { |_|(async function asyncF() {
...@@ -89,6 +89,20 @@ testFunction (test.js:10:44) ...@@ -89,6 +89,20 @@ testFunction (test.js:10:44)
for (let { x, y } = #{ x: 0, y: 1 }; y > 0; --y) { let z = x + y; } for (let { x, y } = #{ x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
} }
f (test.js:12:15)
testFunction (test.js:10:44)
(anonymous) (expr.js:0:0)
function f() {
for (let { #x, y } = { x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
}
f (test.js:12:18)
testFunction (test.js:10:44)
(anonymous) (expr.js:0:0)
function f() {
for (let { x, #y } = { x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
}
f (test.js:12:42) f (test.js:12:42)
testFunction (test.js:10:44) testFunction (test.js:10:44)
(anonymous) (expr.js:0:0) (anonymous) (expr.js:0:0)
......
...@@ -15,7 +15,7 @@ function testFunction() { ...@@ -15,7 +15,7 @@ function testFunction() {
var y = |_|(a = 100); var y = |_|(a = 100);
var z = |_|x + (a = 1) + (a = 2) + (a = 3) + |C|f(); var z = |_|x + (a = 1) + (a = 2) + (a = 3) + |C|f();
function f() { function f() {
for (let { x, y } = |_|{ x: 0, y: 1 }; y |_|> 0; --|_|y) { let z = |_|x + y; } for (let { |_|x, |_|y } = |_|{ x: 0, y: 1 }; y |_|> 0; --|_|y) { let z = |_|x + y; }
|R|} |R|}
var b = obj1.|_|a; var b = obj1.|_|a;
|_|(async function asyncF() { |_|(async function asyncF() {
...@@ -89,6 +89,20 @@ testFunction (test.js:10:44) ...@@ -89,6 +89,20 @@ testFunction (test.js:10:44)
for (let { x, y } = #{ x: 0, y: 1 }; y > 0; --y) { let z = x + y; } for (let { x, y } = #{ x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
} }
f (test.js:12:15)
testFunction (test.js:10:44)
(anonymous) (expr.js:0:0)
function f() {
for (let { #x, y } = { x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
}
f (test.js:12:18)
testFunction (test.js:10:44)
(anonymous) (expr.js:0:0)
function f() {
for (let { x, #y } = { x: 0, y: 1 }; y > 0; --y) { let z = x + y; }
}
f (test.js:12:42) f (test.js:12:42)
testFunction (test.js:10:44) testFunction (test.js:10:44)
(anonymous) (expr.js:0:0) (anonymous) (expr.js:0:0)
......
...@@ -251,6 +251,12 @@ testFunction (test.js:25:11) ...@@ -251,6 +251,12 @@ testFunction (test.js:25:11)
return { value: this.i++, done: false };# return { value: this.i++, done: false };#
} }
testFunction (test.js:25:11)
(anonymous) (expr.js:0:0)
};
for (var #k of iterable) { all.push(k); }
iterable.i = 0;
testFunction (test.js:25:32) testFunction (test.js:25:32)
(anonymous) (expr.js:0:0) (anonymous) (expr.js:0:0)
}; };
...@@ -337,6 +343,12 @@ testFunction (test.js:27:11) ...@@ -337,6 +343,12 @@ testFunction (test.js:27:11)
return { value: this.i++, done: false };# return { value: this.i++, done: false };#
} }
testFunction (test.js:27:11)
(anonymous) (expr.js:0:0)
iterable.i = 0;
for (let #k of iterable) { all.push(k); }
}
testFunction (test.js:27:32) testFunction (test.js:27:32)
(anonymous) (expr.js:0:0) (anonymous) (expr.js:0:0)
iterable.i = 0; iterable.i = 0;
......
...@@ -10,6 +10,12 @@ paused ...@@ -10,6 +10,12 @@ paused
#c(f, 2); #c(f, 2);
} }
paused
function c(f#, ...args) { return f(...args); }
paused
function c(f, ...args#) { return f(...args); }
paused paused
function c(f, ...args) { #return f(...args); } function c(f, ...args) { #return f(...args); }
......
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
var { [x] : y } = undefined; var { [x] : y } = undefined;
^ ^
TypeError: Cannot destructure 'undefined' or 'null'. TypeError: Cannot destructure 'undefined' or 'null'.
at *%(basename)s:5:19 at *%(basename)s:5:5
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
var { 1: x } = undefined; var { 1: x } = undefined;
^ ^
TypeError: Cannot destructure 'undefined' or 'null'. TypeError: Cannot destructure 'undefined' or 'null'.
at *%(basename)s:5:16 at *%(basename)s:5:5
...@@ -2,4 +2,4 @@ ...@@ -2,4 +2,4 @@
var { x } = undefined; var { x } = undefined;
^ ^
TypeError: Cannot destructure property `x` of 'undefined' or 'null'. TypeError: Cannot destructure property `x` of 'undefined' or 'null'.
at *%(basename)s:5:13 at *%(basename)s:5:7
*%(basename)s:7: TypeError: nonIterable(...) is not a function or its return value is not iterable *%(basename)s:7: TypeError: nonIterable is not a function or its return value is not iterable
[...nonIterable()]; [...nonIterable()];
^ ^
TypeError: nonIterable(...) is not a function or its return value is not iterable TypeError: nonIterable is not a function or its return value is not iterable
at *%(basename)s:7:5 at *%(basename)s:7:5
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