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