LibJS: Fix destructured primitive string const loops
Mark binding-pattern identifiers with their declaration kind so local destructuring assignments use the normal TDZ and const assignment path. This makes local const destructuring match the environment-backed path. Also teach GetById to expose primitive string virtual index properties before boxing, matching StringGetOwnProperty and GetByValue. Together these fix the SpiderMonkey for-in/of const declaration coverage and the lexical destructuring TDZ test.
This commit is contained in:
parent
b42aa88189
commit
bf530ad2af
21 changed files with 286 additions and 235 deletions
|
|
@ -14,6 +14,7 @@
|
|||
#include <LibJS/Runtime/Completion.h>
|
||||
#include <LibJS/Runtime/ECMAScriptFunctionObject.h>
|
||||
#include <LibJS/Runtime/FunctionObject.h>
|
||||
#include <LibJS/Runtime/PrimitiveString.h>
|
||||
#include <LibJS/Runtime/Shape.h>
|
||||
#include <LibJS/Runtime/VM.h>
|
||||
#include <LibJS/Runtime/Value.h>
|
||||
|
|
@ -91,6 +92,15 @@ ALWAYS_INLINE ThrowCompletionOr<Value> get_by_id(VM& vm, GetBaseIdentifier get_b
|
|||
}
|
||||
}
|
||||
|
||||
auto const& property_name = get_property_name();
|
||||
if (base_value.is_string()) {
|
||||
// https://tc39.es/ecma262/#sec-stringgetownproperty
|
||||
// String exotic objects expose virtual own properties for canonical string indexes.
|
||||
auto string_value = TRY(base_value.as_string().get(vm, property_name));
|
||||
if (string_value.has_value())
|
||||
return *string_value;
|
||||
}
|
||||
|
||||
auto base_obj = TRY(base_object_for_get(vm, base_value, get_base_identifier, get_property_name));
|
||||
|
||||
if constexpr (mode == GetByIdMode::Length) {
|
||||
|
|
@ -152,7 +162,7 @@ ALWAYS_INLINE ThrowCompletionOr<Value> get_by_id(VM& vm, GetBaseIdentifier get_b
|
|||
prototype_chain_validity = shape.prototype()->shape().prototype_chain_validity();
|
||||
|
||||
CacheableGetPropertyMetadata cacheable_metadata;
|
||||
auto value = TRY(base_obj->internal_get(get_property_name(), this_value, &cacheable_metadata));
|
||||
auto value = TRY(base_obj->internal_get(property_name, this_value, &cacheable_metadata));
|
||||
|
||||
// If internal_get() caused object's shape change, we can no longer be sure
|
||||
// that collected metadata is valid, e.g. if getter in prototype chain added
|
||||
|
|
|
|||
|
|
@ -7012,6 +7012,9 @@ fn assign_to_for_in_of_lhs(generator: &mut Generator, lhs: &ForInOfLhs, value: &
|
|||
// =============================================================================
|
||||
|
||||
/// Whether we are initializing a new binding or setting an existing one.
|
||||
// https://tc39.es/ecma262/#sec-runtime-semantics-bindinginitialization
|
||||
// https://tc39.es/ecma262/#sec-runtime-semantics-destructuringassignmentevaluation
|
||||
// Binding patterns initialize lexical declarations, while assignment patterns perform PutValue.
|
||||
#[derive(Clone, Copy)]
|
||||
enum BindingMode {
|
||||
/// `const` or `let` declarations: emit InitializeLexicalBinding.
|
||||
|
|
@ -7063,8 +7066,17 @@ fn emit_set_variable_with_mode(
|
|||
let arena = generator.arena.clone();
|
||||
let ident = &arena.identifiers[id];
|
||||
if ident.is_local() {
|
||||
let local = generator.resolve_local(ident.local_index, ident.local_type.unwrap());
|
||||
generator.emit_mov(&local, value);
|
||||
match mode {
|
||||
BindingMode::InitializeLexical => {
|
||||
let local = generator.resolve_local(ident.local_index, ident.local_type.unwrap());
|
||||
generator.emit_mov(&local, value);
|
||||
generator.mark_local_initialized(ident.local_index);
|
||||
}
|
||||
BindingMode::Set => {
|
||||
emit_tdz_check_if_needed(generator, id);
|
||||
emit_set_variable(generator, id, value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let id = generator.intern_identifier_id(ident.name);
|
||||
match mode {
|
||||
|
|
|
|||
|
|
@ -212,8 +212,6 @@ impl Parser<'_> {
|
|||
.zip(bound_names.iter())
|
||||
.map(|(n, (_, id))| (n.as_slice(), Some(*id)))
|
||||
.collect();
|
||||
// NOTE: Binding pattern identifiers don't get declaration_kind,
|
||||
// matching C++ behavior where only simple identifiers do.
|
||||
let Self {
|
||||
scope_collector, arena, ..
|
||||
} = self;
|
||||
|
|
@ -221,7 +219,7 @@ impl Parser<'_> {
|
|||
&entries,
|
||||
declaration_line,
|
||||
declaration_column,
|
||||
None,
|
||||
Some(DeclarationKind::Var),
|
||||
&mut arena.identifiers,
|
||||
&arena.strings,
|
||||
&mut arena.scopes,
|
||||
|
|
@ -230,17 +228,13 @@ impl Parser<'_> {
|
|||
let refs: Vec<&[u16]> = name_strs.iter().map(|n| n.as_slice()).collect();
|
||||
self.scope_collector
|
||||
.add_lexical_declaration(&refs, declaration_line, declaration_column);
|
||||
// Register each binding pattern identifier for scope analysis
|
||||
// so they get is_local() annotations.
|
||||
// NOTE: C++ does not pass declaration_kind for binding pattern identifiers,
|
||||
// only for simple identifier declarations.
|
||||
let Self {
|
||||
scope_collector, arena, ..
|
||||
} = self;
|
||||
for (_name, id) in &bound_names {
|
||||
scope_collector.register_identifier(
|
||||
*id,
|
||||
None,
|
||||
Some(kind),
|
||||
&mut arena.identifiers,
|
||||
&arena.strings,
|
||||
&mut arena.scopes,
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ Program (script) @6:1
|
|||
│ ├─ BindingPattern (object)
|
||||
│ │ ├─ entry
|
||||
│ │ │ └─ name
|
||||
│ │ │ └─ Identifier "foo" [global] @6:7
|
||||
│ │ │ └─ Identifier "foo" [global] (let) @6:7
|
||||
│ │ └─ entry
|
||||
│ │ └─ name
|
||||
│ │ └─ Identifier "bar" [global] @6:12
|
||||
│ │ └─ Identifier "bar" [global] (let) @6:12
|
||||
│ └─ ObjectExpression @6:20
|
||||
├─ VariableDeclaration (let) @7:1
|
||||
│ └─ VariableDeclarator @7:1
|
||||
|
|
@ -16,23 +16,23 @@ Program (script) @6:1
|
|||
│ │ │ ├─ name
|
||||
│ │ │ │ └─ Identifier "x" [global] @7:7
|
||||
│ │ │ └─ alias
|
||||
│ │ │ └─ Identifier "aliased" [global] @7:10
|
||||
│ │ │ └─ Identifier "aliased" [global] (let) @7:10
|
||||
│ │ └─ entry
|
||||
│ │ ├─ name
|
||||
│ │ │ └─ Identifier "y" [global] @7:19
|
||||
│ │ └─ alias
|
||||
│ │ └─ Identifier "also" [global] @7:22
|
||||
│ │ └─ Identifier "also" [global] (let) @7:22
|
||||
│ └─ ObjectExpression @7:31
|
||||
├─ VariableDeclaration (let) @8:1
|
||||
│ └─ VariableDeclarator @8:1
|
||||
│ ├─ BindingPattern (array)
|
||||
│ │ ├─ entry
|
||||
│ │ │ └─ alias
|
||||
│ │ │ └─ Identifier "first" [global] @8:7
|
||||
│ │ │ └─ Identifier "first" [global] (let) @8:7
|
||||
│ │ ├─ Elision
|
||||
│ │ └─ entry
|
||||
│ │ └─ alias
|
||||
│ │ └─ Identifier "third" [global] @8:16
|
||||
│ │ └─ Identifier "third" [global] (let) @8:16
|
||||
│ └─ ArrayExpression @8:26
|
||||
├─ VariableDeclaration (let) @9:1
|
||||
│ └─ VariableDeclarator @9:1
|
||||
|
|
@ -44,26 +44,26 @@ Program (script) @6:1
|
|||
│ │ │ └─ BindingPattern (object)
|
||||
│ │ │ └─ entry
|
||||
│ │ │ └─ name
|
||||
│ │ │ └─ Identifier "inner" [global] @9:17
|
||||
│ │ │ └─ Identifier "inner" [global] (let) @9:17
|
||||
│ │ └─ entry (rest)
|
||||
│ │ └─ name
|
||||
│ │ └─ Identifier "rest" [global] @9:29
|
||||
│ │ └─ Identifier "rest" [global] (let) @9:29
|
||||
│ └─ ObjectExpression @9:38
|
||||
├─ VariableDeclaration (let) @10:1
|
||||
│ └─ VariableDeclarator @10:1
|
||||
│ ├─ BindingPattern (array)
|
||||
│ │ ├─ entry
|
||||
│ │ │ └─ alias
|
||||
│ │ │ └─ Identifier "a" [global] @10:7
|
||||
│ │ │ └─ Identifier "a" [global] (let) @10:7
|
||||
│ │ └─ entry
|
||||
│ │ └─ alias
|
||||
│ │ └─ BindingPattern (array)
|
||||
│ │ ├─ entry
|
||||
│ │ │ └─ alias
|
||||
│ │ │ └─ Identifier "b" [global] @10:12
|
||||
│ │ │ └─ Identifier "b" [global] (let) @10:12
|
||||
│ │ └─ entry
|
||||
│ │ └─ alias
|
||||
│ │ └─ Identifier "c" [global] @10:15
|
||||
│ │ └─ Identifier "c" [global] (let) @10:15
|
||||
│ └─ ArrayExpression @10:23
|
||||
└─ FunctionDeclaration "destructured" @12:1
|
||||
├─ parameters
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ Program (script) @1:1
|
|||
│ │ ├─ name
|
||||
│ │ │ └─ Identifier "foo" [global] @1:7
|
||||
│ │ └─ alias
|
||||
│ │ └─ Identifier "a" [global] @1:12
|
||||
│ │ └─ Identifier "a" [global] (let) @1:12
|
||||
│ └─ entry
|
||||
│ ├─ name
|
||||
│ │ └─ Identifier "1" [global] @1:15
|
||||
│ └─ alias
|
||||
│ └─ Identifier "b" [global] @1:18
|
||||
│ └─ Identifier "b" [global] (let) @1:18
|
||||
└─ ObjectExpression @1:24
|
||||
├─ ObjectProperty @1:24
|
||||
│ ├─ StringLiteral "foo" @1:26
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ Program (script) @1:1
|
|||
│ ├─ BindingPattern (array)
|
||||
│ │ ├─ entry
|
||||
│ │ │ └─ alias
|
||||
│ │ │ └─ Identifier "a" [variable:0] @2:10
|
||||
│ │ │ └─ Identifier "a" [variable:0] (let) @2:10
|
||||
│ │ └─ entry
|
||||
│ │ └─ alias
|
||||
│ │ └─ Identifier "b" [variable:1] @2:13
|
||||
│ │ └─ Identifier "b" [variable:1] (let) @2:13
|
||||
│ └─ ArrayExpression @2:18
|
||||
│ ├─ NumericLiteral 1 @2:19
|
||||
│ └─ NumericLiteral 2 @2:22
|
||||
|
|
@ -19,12 +19,12 @@ Program (script) @1:1
|
|||
│ ├─ BindingPattern (object)
|
||||
│ │ ├─ entry
|
||||
│ │ │ └─ name
|
||||
│ │ │ └─ Identifier "x" [variable:2] @3:11
|
||||
│ │ │ └─ Identifier "x" [variable:2] (let) @3:11
|
||||
│ │ └─ entry
|
||||
│ │ ├─ name
|
||||
│ │ │ └─ Identifier "y" [global] @3:14
|
||||
│ │ └─ alias
|
||||
│ │ └─ Identifier "z" [variable:3] @3:17
|
||||
│ │ └─ Identifier "z" [variable:3] (let) @3:17
|
||||
│ └─ ObjectExpression @3:23
|
||||
│ ├─ ObjectProperty @3:23
|
||||
│ │ ├─ StringLiteral "x" @3:25
|
||||
|
|
@ -36,7 +36,7 @@ Program (script) @1:1
|
|||
└─ BinaryExpression (+) @4:22
|
||||
├─ BinaryExpression (+) @4:18
|
||||
│ ├─ BinaryExpression (+) @4:14
|
||||
│ │ ├─ Identifier "a" [variable:0] @4:12
|
||||
│ │ └─ Identifier "b" [variable:1] @4:16
|
||||
│ └─ Identifier "x" [variable:2] @4:20
|
||||
└─ Identifier "z" [variable:3] @4:24
|
||||
│ │ ├─ Identifier "a" [variable:0] (let) @4:12
|
||||
│ │ └─ Identifier "b" [variable:1] (let) @4:16
|
||||
│ └─ Identifier "x" [variable:2] (let) @4:20
|
||||
└─ Identifier "z" [variable:3] (let) @4:24
|
||||
|
|
|
|||
|
|
@ -61,18 +61,18 @@ Program (script) @2:1
|
|||
│ │ └─ BindingPattern (array)
|
||||
│ │ ├─ entry
|
||||
│ │ │ └─ alias
|
||||
│ │ │ └─ Identifier "a" [variable:0] @25:15
|
||||
│ │ │ └─ Identifier "a" [variable:0] (let) @25:15
|
||||
│ │ └─ entry
|
||||
│ │ └─ alias
|
||||
│ │ └─ Identifier "b" [variable:1] @25:18
|
||||
│ │ └─ Identifier "b" [variable:1] (let) @25:18
|
||||
│ ├─ rhs
|
||||
│ │ └─ Identifier "pairs" [argument:0] @25:24
|
||||
│ └─ body
|
||||
│ └─ BlockStatement @25:31
|
||||
│ └─ ExpressionStatement @26:9
|
||||
│ └─ BinaryExpression (+) @26:11
|
||||
│ ├─ Identifier "a" [variable:0] @26:9
|
||||
│ └─ Identifier "b" [variable:1] @26:13
|
||||
│ ├─ Identifier "a" [variable:0] (let) @26:9
|
||||
│ └─ Identifier "b" [variable:1] (let) @26:13
|
||||
└─ FunctionDeclaration "for_in_eval" [direct-eval] [uses-this] [might-need-arguments] @31:1
|
||||
├─ parameters
|
||||
│ └─ Identifier "obj" @31:22
|
||||
|
|
|
|||
|
|
@ -87,10 +87,10 @@ Program (script) @4:1
|
|||
│ │ ├─ BindingPattern (array)
|
||||
│ │ │ ├─ entry
|
||||
│ │ │ │ └─ alias
|
||||
│ │ │ │ └─ Identifier "a" [variable:0] @28:10
|
||||
│ │ │ │ └─ Identifier "a" [variable:0] (let) @28:10
|
||||
│ │ │ └─ entry
|
||||
│ │ │ └─ alias
|
||||
│ │ │ └─ Identifier "b" [variable:1] @28:13
|
||||
│ │ │ └─ Identifier "b" [variable:1] (let) @28:13
|
||||
│ │ └─ ArrayExpression @28:18
|
||||
│ │ ├─ NumericLiteral 1 @28:19
|
||||
│ │ └─ NumericLiteral 2 @28:22
|
||||
|
|
@ -99,10 +99,10 @@ Program (script) @4:1
|
|||
│ │ ├─ BindingPattern (object)
|
||||
│ │ │ ├─ entry
|
||||
│ │ │ │ └─ name
|
||||
│ │ │ │ └─ Identifier "c" [variable:2] @29:13
|
||||
│ │ │ │ └─ Identifier "c" [variable:2] (const) @29:13
|
||||
│ │ │ └─ entry
|
||||
│ │ │ └─ name
|
||||
│ │ │ └─ Identifier "d" [variable:3] @29:16
|
||||
│ │ │ └─ Identifier "d" [variable:3] (const) @29:16
|
||||
│ │ └─ ObjectExpression @29:22
|
||||
│ │ ├─ ObjectProperty @29:22
|
||||
│ │ │ ├─ StringLiteral "c" @29:24
|
||||
|
|
@ -115,10 +115,10 @@ Program (script) @4:1
|
|||
│ │ ├─ BindingPattern (array)
|
||||
│ │ │ ├─ entry
|
||||
│ │ │ │ └─ alias
|
||||
│ │ │ │ └─ Identifier "e" [variable:4] @30:10
|
||||
│ │ │ │ └─ Identifier "e" [variable:4] (var) @30:10
|
||||
│ │ │ └─ entry (rest)
|
||||
│ │ │ └─ alias
|
||||
│ │ │ └─ Identifier "f" [variable:5] @30:16
|
||||
│ │ │ └─ Identifier "f" [variable:5] (var) @30:16
|
||||
│ │ └─ ArrayExpression @30:21
|
||||
│ │ ├─ NumericLiteral 5 @30:22
|
||||
│ │ ├─ NumericLiteral 6 @30:25
|
||||
|
|
@ -129,13 +129,13 @@ Program (script) @4:1
|
|||
│ │ ├─ BinaryExpression (+) @31:22
|
||||
│ │ │ ├─ BinaryExpression (+) @31:18
|
||||
│ │ │ │ ├─ BinaryExpression (+) @31:14
|
||||
│ │ │ │ │ ├─ Identifier "a" [variable:0] @31:12
|
||||
│ │ │ │ │ └─ Identifier "b" [variable:1] @31:16
|
||||
│ │ │ │ └─ Identifier "c" [variable:2] @31:20
|
||||
│ │ │ └─ Identifier "d" [variable:3] @31:24
|
||||
│ │ └─ Identifier "e" [variable:4] @31:28
|
||||
│ │ │ │ │ ├─ Identifier "a" [variable:0] (let) @31:12
|
||||
│ │ │ │ │ └─ Identifier "b" [variable:1] (let) @31:16
|
||||
│ │ │ │ └─ Identifier "c" [variable:2] (const) @31:20
|
||||
│ │ │ └─ Identifier "d" [variable:3] (const) @31:24
|
||||
│ │ └─ Identifier "e" [variable:4] (var) @31:28
|
||||
│ └─ MemberExpression [computed] @31:33
|
||||
│ ├─ Identifier "f" [variable:5] @31:32
|
||||
│ ├─ Identifier "f" [variable:5] (var) @31:32
|
||||
│ └─ NumericLiteral 0 @31:34
|
||||
└─ FunctionDeclaration "multi_declarator" @35:1
|
||||
└─ body
|
||||
|
|
|
|||
|
|
@ -49,13 +49,13 @@ Program (script) @3:1
|
|||
│ │ │ ├─ name
|
||||
│ │ │ │ └─ Identifier "arguments" [variable:0] @37:11
|
||||
│ │ │ └─ alias
|
||||
│ │ │ └─ Identifier "x" [variable:1] @37:22
|
||||
│ │ │ └─ Identifier "x" [variable:1] (let) @37:22
|
||||
│ │ └─ ObjectExpression @37:28
|
||||
│ │ └─ ObjectProperty @37:28
|
||||
│ │ ├─ StringLiteral "arguments" @37:30
|
||||
│ │ └─ NumericLiteral 1 @37:41
|
||||
│ └─ ReturnStatement @38:5
|
||||
│ └─ Identifier "x" [variable:1] @38:12
|
||||
│ └─ Identifier "x" [variable:1] (let) @38:12
|
||||
└─ FunctionDeclaration "method_named_arguments" @42:1
|
||||
└─ body
|
||||
└─ FunctionBody @43:5
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ block0:
|
|||
[ 70] End value:reg5
|
||||
|
||||
|
||||
f$ce57f4e1 assign-to-let-variable-tdz.js:7:5
|
||||
f$d3dfd701 assign-to-let-variable-tdz.js:7:5
|
||||
Registers: 10
|
||||
Blocks: 3
|
||||
Locals: a~0
|
||||
|
|
@ -26,23 +26,19 @@ block0:
|
|||
[ 0] ThrowIfNullish src:arg0
|
||||
[ 8] GetById dst:reg5, base:arg0, `location`
|
||||
[ 20] Mov dst:a~0, src:reg5
|
||||
[ 30] ThrowIfTDZ src:a~0
|
||||
[ 38] Typeof dst:reg5, src:a~0
|
||||
[ 48] LooselyEquals dst:reg6, lhs:String("string"), rhs:reg5
|
||||
[ 58] Mov dst:reg5, src:reg6
|
||||
[ 68] JumpFalse condition:reg6, target:block2
|
||||
[ 30] Typeof dst:reg5, src:a~0
|
||||
[ 40] LooselyEquals dst:reg6, lhs:String("string"), rhs:reg5
|
||||
[ 50] Mov dst:reg5, src:reg6
|
||||
[ 60] JumpFalse condition:reg6, target:block2
|
||||
|
||||
block1:
|
||||
[ 78] GetGlobal dst:reg8, `g`
|
||||
[ 88] ThrowIfTDZ src:a~0
|
||||
[ 90] Mov dst:reg9, src:a~0
|
||||
[ a0] Call dst:reg7, callee:reg8, this_value:Undefined, g, arguments:[reg9]
|
||||
[ c8] ThrowIfTDZ src:a~0
|
||||
[ d0] Mov2 dst1:a~0, src1:reg7, dst2:reg5, src2:reg7
|
||||
[ 70] GetGlobal dst:reg8, `g`
|
||||
[ 80] Mov dst:reg9, src:a~0
|
||||
[ 90] Call dst:reg7, callee:reg8, this_value:Undefined, g, arguments:[reg9]
|
||||
[ b8] Mov2 dst1:a~0, src1:reg7, dst2:reg5, src2:reg7
|
||||
|
||||
block2:
|
||||
[ e8] ThrowIfTDZ src:a~0
|
||||
[ f0] Return value:a~0
|
||||
[ d0] Return value:a~0
|
||||
|
||||
|
||||
g$f452072f assign-to-let-variable-tdz.js:4:17
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ block0:
|
|||
[ 30] End value:reg5
|
||||
|
||||
|
||||
f$c7e5aa3e destructure-array-rest.js:6:5
|
||||
f$26085a1b destructure-array-rest.js:6:5
|
||||
Registers: 14
|
||||
Blocks: 19
|
||||
Locals: a~0, b~1
|
||||
|
|
@ -34,65 +34,64 @@ block1:
|
|||
[ 80] JumpIf condition:reg9, true_target:block14, false_target:block13
|
||||
|
||||
block2:
|
||||
[ 90] ThrowIfTDZ src:b~1
|
||||
[ 98] Return value:b~1
|
||||
[ 90] Return value:b~1
|
||||
|
||||
block3:
|
||||
[ a0] Jump target:block5
|
||||
[ 98] Jump target:block5
|
||||
|
||||
block4:
|
||||
[ a8] Mov dst:reg12, src:Undefined
|
||||
[ b8] Jump target:block6
|
||||
[ a0] Mov dst:reg12, src:Undefined
|
||||
[ b0] Jump target:block6
|
||||
|
||||
block5:
|
||||
[ c0] IteratorNextUnpack dst_value:reg12, dst_done:reg6, iterator_object:reg7, iterator_next:reg8, iterator_done:reg9
|
||||
[ d8] JumpTrue condition:reg6, target:block4
|
||||
[ b8] IteratorNextUnpack dst_value:reg12, dst_done:reg6, iterator_object:reg7, iterator_next:reg8, iterator_done:reg9
|
||||
[ d0] JumpTrue condition:reg6, target:block4
|
||||
|
||||
block6:
|
||||
[ e8] Mov dst:a~0, src:reg12
|
||||
[ f8] JumpFalse condition:reg6, target:block8
|
||||
[ e0] Mov dst:a~0, src:reg12
|
||||
[ f0] JumpFalse condition:reg6, target:block8
|
||||
|
||||
block7:
|
||||
[ 108] NewArray dst:reg13
|
||||
[ 118] Jump target:block9
|
||||
[ 100] NewArray dst:reg13
|
||||
[ 110] Jump target:block9
|
||||
|
||||
block8:
|
||||
[ 120] IteratorToArray dst:reg13, iterator_object:reg7, iterator_next_method:reg8, iterator_done_property:reg9
|
||||
[ 118] IteratorToArray dst:reg13, iterator_object:reg7, iterator_next_method:reg8, iterator_done_property:reg9
|
||||
|
||||
block9:
|
||||
[ 138] Mov dst:b~1, src:reg13
|
||||
[ 130] Mov dst:b~1, src:reg13
|
||||
|
||||
block10:
|
||||
[ 148] JumpFalse condition:reg9, target:block12
|
||||
[ 140] JumpFalse condition:reg9, target:block12
|
||||
|
||||
block11:
|
||||
[ 158] Jump target:block2
|
||||
[ 150] Return value:b~1
|
||||
|
||||
block12:
|
||||
[ 160] IteratorClose iterator_object:reg7, iterator_next:reg8, iterator_done:reg9, completion_value:Undefined
|
||||
[ 178] Jump target:block11
|
||||
[ 158] IteratorClose iterator_object:reg7, iterator_next:reg8, iterator_done:reg9, completion_value:Undefined
|
||||
[ 170] Jump target:block11
|
||||
|
||||
block13:
|
||||
[ 180] JumpStrictlyEquals lhs:reg10, rhs:Int32(1), true_target:block15, false_target:block16
|
||||
[ 178] JumpStrictlyEquals lhs:reg10, rhs:Int32(1), true_target:block15, false_target:block16
|
||||
|
||||
block14:
|
||||
[ 198] JumpStrictlyEquals lhs:reg10, rhs:Int32(2), true_target:block17, false_target:block18
|
||||
[ 190] JumpStrictlyEquals lhs:reg10, rhs:Int32(2), true_target:block17, false_target:block18
|
||||
|
||||
block15:
|
||||
[ 1b0] IteratorClose iterator_object:reg7, iterator_next:reg8, iterator_done:reg9, completion_value:reg11
|
||||
[ 1c8] Throw src:reg11
|
||||
[ 1a8] IteratorClose iterator_object:reg7, iterator_next:reg8, iterator_done:reg9, completion_value:reg11
|
||||
[ 1c0] Throw src:reg11
|
||||
|
||||
block16:
|
||||
[ 1d0] IteratorClose iterator_object:reg7, iterator_next:reg8, iterator_done:reg9, completion_value:Undefined
|
||||
[ 1e8] Jump target:block14
|
||||
[ 1c8] IteratorClose iterator_object:reg7, iterator_next:reg8, iterator_done:reg9, completion_value:Undefined
|
||||
[ 1e0] Jump target:block14
|
||||
|
||||
block17:
|
||||
[ 1f0] Return value:reg11
|
||||
[ 1e8] Return value:reg11
|
||||
|
||||
block18:
|
||||
[ 1f8] Throw src:reg11
|
||||
[ 1f0] Throw src:reg11
|
||||
|
||||
Exception handlers:
|
||||
[ a0 .. c0] => handler block1
|
||||
[ e8 .. 120] => handler block1
|
||||
[ 138 .. 148] => handler block1
|
||||
[ 98 .. b8] => handler block1
|
||||
[ e0 .. 118] => handler block1
|
||||
[ 130 .. 140] => handler block1
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ block0:
|
|||
[ 58] End value:reg5
|
||||
|
||||
|
||||
f$f789224c destructuring-let-compound-assign.js:2:5
|
||||
f$ffd4f57c destructuring-let-compound-assign.js:2:5
|
||||
Registers: 8
|
||||
Blocks: 1
|
||||
Locals: a~0
|
||||
|
|
@ -23,11 +23,9 @@ f$f789224c destructuring-let-compound-assign.js:2:5
|
|||
block0:
|
||||
[ 0] ThrowIfNullish src:arg0
|
||||
[ 8] GetById dst:reg5, base:arg0, `patchFlag`
|
||||
[ 20] Mov dst:a~0, src:reg5
|
||||
[ 30] ThrowIfTDZ src:a~0
|
||||
[ 38] Mov2 dst1:reg5, src1:a~0, dst2:reg6, src2:arg1
|
||||
[ 50] GetById dst:reg7, base:reg6, `patchFlag` (e.patchFlag)
|
||||
[ 68] BitwiseAnd dst:reg6, lhs:Int32(16), rhs:reg7
|
||||
[ 78] BitwiseOr dst:reg7, lhs:reg5, rhs:reg6
|
||||
[ 88] Mov dst:a~0, src:reg7
|
||||
[ 98] End value:Undefined
|
||||
[ 20] Mov3 dst1:a~0, src1:reg5, dst2:reg5, src2:a~0, dst3:reg6, src3:arg1
|
||||
[ 40] GetById dst:reg7, base:reg6, `patchFlag` (e.patchFlag)
|
||||
[ 58] BitwiseAnd dst:reg6, lhs:Int32(16), rhs:reg7
|
||||
[ 68] BitwiseOr dst:reg7, lhs:reg5, rhs:reg6
|
||||
[ 78] Mov dst:a~0, src:reg7
|
||||
[ 88] End value:Undefined
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ block0:
|
|||
[ b8] End value:reg5
|
||||
|
||||
|
||||
collect$aa10966b for-in-object-property-iterator-next.js:2:18
|
||||
collect$a1c4c33b for-in-object-property-iterator-next.js:2:18
|
||||
Registers: 12
|
||||
Blocks: 6
|
||||
Locals: key~0, keys~1
|
||||
|
|
@ -47,8 +47,6 @@ block4:
|
|||
block5:
|
||||
[ 68] Mov dst:key~0, src:reg6
|
||||
[ 78] GetById dst:reg9, base:keys~1, `push` (keys.push)
|
||||
[ 90] Mov dst:reg10, src:keys~1
|
||||
[ a0] ThrowIfTDZ src:key~0
|
||||
[ a8] Mov dst:reg11, src:key~0
|
||||
[ b8] Call dst:reg8, callee:reg9, this_value:reg10, keys.push, arguments:[reg11]
|
||||
[ e0] Jump target:block2
|
||||
[ 90] Mov2 dst1:reg10, src1:keys~1, dst2:reg11, src2:key~0
|
||||
[ a8] Call dst:reg8, callee:reg9, this_value:reg10, keys.push, arguments:[reg11]
|
||||
[ d0] Jump target:block2
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ block0:
|
|||
[ 38] End value:reg5
|
||||
|
||||
|
||||
f$08f135b5 for-of-cond-rhs-block-order.js:2:21
|
||||
f$8a532e3d for-of-cond-rhs-block-order.js:2:21
|
||||
Registers: 19
|
||||
Blocks: 31
|
||||
Locals: r~0, n~1
|
||||
|
|
@ -69,85 +69,84 @@ block9:
|
|||
[ 1a0] JumpIf condition:reg15, true_target:block22, false_target:block21
|
||||
|
||||
block10:
|
||||
[ 1b0] ThrowIfTDZ src:r~0
|
||||
[ 1b8] Jump target:block2
|
||||
[ 1b0] Jump target:block2
|
||||
|
||||
block11:
|
||||
[ 1c0] Jump target:block13
|
||||
[ 1b8] Jump target:block13
|
||||
|
||||
block12:
|
||||
[ 1c8] Mov dst:reg18, src:Undefined
|
||||
[ 1d8] Jump target:block14
|
||||
[ 1c0] Mov dst:reg18, src:Undefined
|
||||
[ 1d0] Jump target:block14
|
||||
|
||||
block13:
|
||||
[ 1e0] IteratorNextUnpack dst_value:reg18, dst_done:reg12, iterator_object:reg13, iterator_next:reg14, iterator_done:reg15
|
||||
[ 1f8] JumpTrue condition:reg12, target:block12
|
||||
[ 1d8] IteratorNextUnpack dst_value:reg18, dst_done:reg12, iterator_object:reg13, iterator_next:reg14, iterator_done:reg15
|
||||
[ 1f0] JumpTrue condition:reg12, target:block12
|
||||
|
||||
block14:
|
||||
[ 208] Mov dst:r~0, src:reg18
|
||||
[ 218] JumpFalse condition:reg12, target:block16
|
||||
[ 200] Mov dst:r~0, src:reg18
|
||||
[ 210] JumpFalse condition:reg12, target:block16
|
||||
|
||||
block15:
|
||||
[ 228] Mov dst:reg18, src:Undefined
|
||||
[ 238] Jump target:block17
|
||||
[ 220] Mov dst:reg18, src:Undefined
|
||||
[ 230] Jump target:block17
|
||||
|
||||
block16:
|
||||
[ 240] IteratorNextUnpack dst_value:reg18, dst_done:reg12, iterator_object:reg13, iterator_next:reg14, iterator_done:reg15
|
||||
[ 258] JumpTrue condition:reg12, target:block15
|
||||
[ 238] IteratorNextUnpack dst_value:reg18, dst_done:reg12, iterator_object:reg13, iterator_next:reg14, iterator_done:reg15
|
||||
[ 250] JumpTrue condition:reg12, target:block15
|
||||
|
||||
block17:
|
||||
[ 268] Mov dst:n~1, src:reg18
|
||||
[ 260] Mov dst:n~1, src:reg18
|
||||
|
||||
block18:
|
||||
[ 278] JumpFalse condition:reg15, target:block20
|
||||
[ 270] JumpFalse condition:reg15, target:block20
|
||||
|
||||
block19:
|
||||
[ 288] Jump target:block10
|
||||
[ 280] Jump target:block10
|
||||
|
||||
block20:
|
||||
[ 290] IteratorClose iterator_object:reg13, iterator_next:reg14, iterator_done:reg15, completion_value:Undefined
|
||||
[ 2a8] Jump target:block19
|
||||
[ 288] IteratorClose iterator_object:reg13, iterator_next:reg14, iterator_done:reg15, completion_value:Undefined
|
||||
[ 2a0] Jump target:block19
|
||||
|
||||
block21:
|
||||
[ 2b0] JumpStrictlyEquals lhs:reg16, rhs:Int32(1), true_target:block23, false_target:block24
|
||||
[ 2a8] JumpStrictlyEquals lhs:reg16, rhs:Int32(1), true_target:block23, false_target:block24
|
||||
|
||||
block22:
|
||||
[ 2c8] JumpStrictlyEquals lhs:reg16, rhs:Int32(2), true_target:block25, false_target:block26
|
||||
[ 2c0] JumpStrictlyEquals lhs:reg16, rhs:Int32(2), true_target:block25, false_target:block26
|
||||
|
||||
block23:
|
||||
[ 2e0] IteratorClose iterator_object:reg13, iterator_next:reg14, iterator_done:reg15, completion_value:reg17
|
||||
[ 2f8] Throw src:reg17
|
||||
[ 2d8] IteratorClose iterator_object:reg13, iterator_next:reg14, iterator_done:reg15, completion_value:reg17
|
||||
[ 2f0] Throw src:reg17
|
||||
|
||||
block24:
|
||||
[ 300] IteratorClose iterator_object:reg13, iterator_next:reg14, iterator_done:reg15, completion_value:Undefined
|
||||
[ 318] Jump target:block22
|
||||
[ 2f8] IteratorClose iterator_object:reg13, iterator_next:reg14, iterator_done:reg15, completion_value:Undefined
|
||||
[ 310] Jump target:block22
|
||||
|
||||
block25:
|
||||
[ 320] Mov2 dst1:reg7, src1:reg16, dst2:reg9, src2:reg17
|
||||
[ 338] Jump target:block7
|
||||
[ 318] Mov2 dst1:reg7, src1:reg16, dst2:reg9, src2:reg17
|
||||
[ 330] Jump target:block7
|
||||
|
||||
block26:
|
||||
[ 340] Throw src:reg17
|
||||
[ 338] Throw src:reg17
|
||||
|
||||
block27:
|
||||
[ 348] IteratorClose iterator_object:reg5, iterator_next:reg8, iterator_done:reg6, completion_value:reg9
|
||||
[ 360] Throw src:reg9
|
||||
[ 340] IteratorClose iterator_object:reg5, iterator_next:reg8, iterator_done:reg6, completion_value:reg9
|
||||
[ 358] Throw src:reg9
|
||||
|
||||
block28:
|
||||
[ 368] IteratorClose iterator_object:reg5, iterator_next:reg8, iterator_done:reg6, completion_value:Undefined
|
||||
[ 380] JumpStrictlyEquals lhs:reg7, rhs:Int32(2), true_target:block29, false_target:block30
|
||||
[ 360] IteratorClose iterator_object:reg5, iterator_next:reg8, iterator_done:reg6, completion_value:Undefined
|
||||
[ 378] JumpStrictlyEquals lhs:reg7, rhs:Int32(2), true_target:block29, false_target:block30
|
||||
|
||||
block29:
|
||||
[ 398] Return value:reg9
|
||||
[ 390] Return value:reg9
|
||||
|
||||
block30:
|
||||
[ 3a0] Throw src:reg9
|
||||
[ 398] Throw src:reg9
|
||||
|
||||
Exception handlers:
|
||||
[ 150 .. 1c0] => handler block6
|
||||
[ 1c0 .. 1e0] => handler block9
|
||||
[ 1e0 .. 208] => handler block6
|
||||
[ 208 .. 240] => handler block9
|
||||
[ 240 .. 268] => handler block6
|
||||
[ 268 .. 278] => handler block9
|
||||
[ 278 .. 348] => handler block6
|
||||
[ 150 .. 1b8] => handler block6
|
||||
[ 1b8 .. 1d8] => handler block9
|
||||
[ 1d8 .. 200] => handler block6
|
||||
[ 200 .. 238] => handler block9
|
||||
[ 238 .. 260] => handler block6
|
||||
[ 260 .. 270] => handler block9
|
||||
[ 270 .. 340] => handler block6
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
$0a509d5d for-of-iteration-env-capacity.js:1:14
|
||||
$078cac4d for-of-iteration-env-capacity.js:1:14
|
||||
Registers: 13
|
||||
Blocks: 9
|
||||
Locals: x~0
|
||||
|
|
@ -28,24 +28,22 @@ block3:
|
|||
[ b0] JumpStrictlyEquals lhs:reg9, rhs:Int32(1), true_target:block5, false_target:block6
|
||||
|
||||
block4:
|
||||
[ c8] Mov dst:x~0, src:reg11
|
||||
[ d8] ThrowIfTDZ src:x~0
|
||||
[ e0] Mov dst:reg5, src:x~0
|
||||
[ f0] Jump target:block2
|
||||
[ c8] Mov2 dst1:x~0, src1:reg11, dst2:reg5, src2:x~0
|
||||
[ e0] Jump target:block2
|
||||
|
||||
block5:
|
||||
[ f8] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:reg10
|
||||
[ 110] Throw src:reg10
|
||||
[ e8] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:reg10
|
||||
[ 100] Throw src:reg10
|
||||
|
||||
block6:
|
||||
[ 118] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:Undefined
|
||||
[ 130] JumpStrictlyEquals lhs:reg9, rhs:Int32(2), true_target:block7, false_target:block8
|
||||
[ 108] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:Undefined
|
||||
[ 120] JumpStrictlyEquals lhs:reg9, rhs:Int32(2), true_target:block7, false_target:block8
|
||||
|
||||
block7:
|
||||
[ 148] Return value:reg10
|
||||
[ 138] Return value:reg10
|
||||
|
||||
block8:
|
||||
[ 150] Throw src:reg10
|
||||
[ 140] Throw src:reg10
|
||||
|
||||
Exception handlers:
|
||||
[ c8 .. f8] => handler block3
|
||||
[ c8 .. e8] => handler block3
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ block0:
|
|||
[ c0] End value:reg5
|
||||
|
||||
|
||||
forOfBreak$0dacb993 for-of-iterator-close.js:2:18
|
||||
forOfBreak$7367477b for-of-iterator-close.js:2:18
|
||||
Registers: 13
|
||||
Blocks: 13
|
||||
Locals: x~0
|
||||
|
|
@ -48,38 +48,37 @@ block4:
|
|||
|
||||
block5:
|
||||
[ b8] Mov dst:x~0, src:reg10
|
||||
[ c8] ThrowIfTDZ src:x~0
|
||||
[ d0] JumpStrictlyEquals lhs:x~0, rhs:Int32(2), true_target:block6, false_target:block7
|
||||
[ c8] JumpStrictlyEquals lhs:x~0, rhs:Int32(2), true_target:block6, false_target:block7
|
||||
|
||||
block6:
|
||||
[ e8] Mov dst:reg5, src:Int32(3)
|
||||
[ f8] Jump target:block4
|
||||
[ e0] Mov dst:reg5, src:Int32(3)
|
||||
[ f0] Jump target:block4
|
||||
|
||||
block7:
|
||||
[ 100] Jump target:block2
|
||||
[ f8] Jump target:block2
|
||||
|
||||
block8:
|
||||
[ 108] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:reg9
|
||||
[ 120] Throw src:reg9
|
||||
[ 100] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:reg9
|
||||
[ 118] Throw src:reg9
|
||||
|
||||
block9:
|
||||
[ 128] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:Undefined
|
||||
[ 140] JumpStrictlyEquals lhs:reg5, rhs:Int32(3), true_target:block1, false_target:block10
|
||||
[ 120] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:Undefined
|
||||
[ 138] JumpStrictlyEquals lhs:reg5, rhs:Int32(3), true_target:block1, false_target:block10
|
||||
|
||||
block10:
|
||||
[ 158] JumpStrictlyEquals lhs:reg5, rhs:Int32(2), true_target:block11, false_target:block12
|
||||
[ 150] JumpStrictlyEquals lhs:reg5, rhs:Int32(2), true_target:block11, false_target:block12
|
||||
|
||||
block11:
|
||||
[ 170] Return value:reg9
|
||||
[ 168] Return value:reg9
|
||||
|
||||
block12:
|
||||
[ 178] Throw src:reg9
|
||||
[ 170] Throw src:reg9
|
||||
|
||||
Exception handlers:
|
||||
[ b8 .. 108] => handler block3
|
||||
[ b8 .. 100] => handler block3
|
||||
|
||||
|
||||
forOfReturn$3e676e69 for-of-iterator-close.js:9:18
|
||||
forOfReturn$3ba37d59 for-of-iterator-close.js:9:18
|
||||
Registers: 12
|
||||
Blocks: 10
|
||||
Locals: x~0
|
||||
|
|
@ -110,30 +109,28 @@ block4:
|
|||
[ a0] JumpStrictlyEquals lhs:reg5, rhs:Int32(1), true_target:block6, false_target:block7
|
||||
|
||||
block5:
|
||||
[ b8] Mov dst:x~0, src:reg10
|
||||
[ c8] ThrowIfTDZ src:x~0
|
||||
[ d0] Mov2 dst1:reg9, src1:x~0, dst2:reg5, src2:Int32(2)
|
||||
[ e8] Jump target:block4
|
||||
[ b8] Mov3 dst1:x~0, src1:reg10, dst2:reg9, src2:x~0, dst3:reg5, src3:Int32(2)
|
||||
[ d8] Jump target:block4
|
||||
|
||||
block6:
|
||||
[ f0] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:reg9
|
||||
[ 108] Throw src:reg9
|
||||
[ e0] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:reg9
|
||||
[ f8] Throw src:reg9
|
||||
|
||||
block7:
|
||||
[ 110] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:Undefined
|
||||
[ 128] JumpStrictlyEquals lhs:reg5, rhs:Int32(2), true_target:block8, false_target:block9
|
||||
[ 100] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:Undefined
|
||||
[ 118] JumpStrictlyEquals lhs:reg5, rhs:Int32(2), true_target:block8, false_target:block9
|
||||
|
||||
block8:
|
||||
[ 140] Return value:reg9
|
||||
[ 130] Return value:reg9
|
||||
|
||||
block9:
|
||||
[ 148] Throw src:reg9
|
||||
[ 138] Throw src:reg9
|
||||
|
||||
Exception handlers:
|
||||
[ b8 .. f0] => handler block3
|
||||
[ b8 .. e0] => handler block3
|
||||
|
||||
|
||||
forAwaitOfBreak$16089337 for-of-iterator-close.js:16:24
|
||||
forAwaitOfBreak$976a8bbf for-of-iterator-close.js:16:24
|
||||
Registers: 18
|
||||
Blocks: 30
|
||||
Locals: x~0
|
||||
|
|
@ -186,77 +183,76 @@ block9:
|
|||
|
||||
block10:
|
||||
[ 150] Mov dst:x~0, src:reg10
|
||||
[ 160] ThrowIfTDZ src:x~0
|
||||
[ 168] JumpStrictlyEquals lhs:x~0, rhs:Int32(2), true_target:block11, false_target:block12
|
||||
[ 160] JumpStrictlyEquals lhs:x~0, rhs:Int32(2), true_target:block11, false_target:block12
|
||||
|
||||
block11:
|
||||
[ 180] Mov dst:reg8, src:Int32(3)
|
||||
[ 190] Jump target:block5
|
||||
[ 178] Mov dst:reg8, src:Int32(3)
|
||||
[ 188] Jump target:block5
|
||||
|
||||
block12:
|
||||
[ 198] Jump target:block3
|
||||
[ 190] Jump target:block3
|
||||
|
||||
block13:
|
||||
[ 1a0] Jump target:block25
|
||||
[ 198] Jump target:block25
|
||||
|
||||
block14:
|
||||
[ 1a8] GetMethod dst:reg12, object:reg5, `return`
|
||||
[ 1b8] JumpUndefined condition:reg12, true_target:block15, false_target:block16
|
||||
[ 1a0] GetMethod dst:reg12, object:reg5, `return`
|
||||
[ 1b0] JumpUndefined condition:reg12, true_target:block15, false_target:block16
|
||||
|
||||
block15:
|
||||
[ 1c8] JumpStrictlyEquals lhs:reg8, rhs:Int32(3), true_target:block2, false_target:block20
|
||||
[ 1c0] JumpStrictlyEquals lhs:reg8, rhs:Int32(3), true_target:block2, false_target:block20
|
||||
|
||||
block16:
|
||||
[ 1e0] Call dst:reg13, callee:reg12, this_value:reg5
|
||||
[ 200] Await continuation_label:block17, argument:reg13
|
||||
[ 1d8] Call dst:reg13, callee:reg12, this_value:reg5
|
||||
[ 1f8] Await continuation_label:block17, argument:reg13
|
||||
|
||||
block17:
|
||||
[ 210] Mov dst:reg14, src:reg0
|
||||
[ 220] GetCompletionFields type_dst:reg15, value_dst:reg16, completion:reg14
|
||||
[ 230] JumpStrictlyEquals lhs:reg15, rhs:Int32(1), true_target:block18, false_target:block19
|
||||
[ 208] Mov dst:reg14, src:reg0
|
||||
[ 218] GetCompletionFields type_dst:reg15, value_dst:reg16, completion:reg14
|
||||
[ 228] JumpStrictlyEquals lhs:reg15, rhs:Int32(1), true_target:block18, false_target:block19
|
||||
|
||||
block18:
|
||||
[ 248] ThrowIfNotObject src:reg16
|
||||
[ 250] Jump target:block15
|
||||
[ 240] ThrowIfNotObject src:reg16
|
||||
[ 248] Jump target:block15
|
||||
|
||||
block19:
|
||||
[ 258] Throw src:reg16
|
||||
[ 250] Throw src:reg16
|
||||
|
||||
block20:
|
||||
[ 260] JumpStrictlyEquals lhs:reg8, rhs:Int32(2), true_target:block21, false_target:block22
|
||||
[ 258] JumpStrictlyEquals lhs:reg8, rhs:Int32(2), true_target:block21, false_target:block22
|
||||
|
||||
block21:
|
||||
[ 278] Return value:reg9
|
||||
[ 270] Return value:reg9
|
||||
|
||||
block22:
|
||||
[ 280] Throw src:reg9
|
||||
[ 278] Throw src:reg9
|
||||
|
||||
block23:
|
||||
[ 288] Throw src:reg9
|
||||
[ 280] Throw src:reg9
|
||||
|
||||
block24:
|
||||
[ 290] Catch dst:reg12
|
||||
[ 298] Jump target:block23
|
||||
[ 288] Catch dst:reg12
|
||||
[ 290] Jump target:block23
|
||||
|
||||
block25:
|
||||
[ 2a0] GetMethod dst:reg12, object:reg5, `return`
|
||||
[ 2b0] JumpUndefined condition:reg12, true_target:block23, false_target:block26
|
||||
[ 298] GetMethod dst:reg12, object:reg5, `return`
|
||||
[ 2a8] JumpUndefined condition:reg12, true_target:block23, false_target:block26
|
||||
|
||||
block26:
|
||||
[ 2c0] Call dst:reg13, callee:reg12, this_value:reg5
|
||||
[ 2e0] Await continuation_label:block27, argument:reg13
|
||||
[ 2b8] Call dst:reg13, callee:reg12, this_value:reg5
|
||||
[ 2d8] Await continuation_label:block27, argument:reg13
|
||||
|
||||
block27:
|
||||
[ 2f0] Mov dst:reg14, src:reg0
|
||||
[ 300] GetCompletionFields type_dst:reg15, value_dst:reg16, completion:reg14
|
||||
[ 310] JumpStrictlyEquals lhs:reg15, rhs:Int32(1), true_target:block28, false_target:block29
|
||||
[ 2e8] Mov dst:reg14, src:reg0
|
||||
[ 2f8] GetCompletionFields type_dst:reg15, value_dst:reg16, completion:reg14
|
||||
[ 308] JumpStrictlyEquals lhs:reg15, rhs:Int32(1), true_target:block28, false_target:block29
|
||||
|
||||
block28:
|
||||
[ 328] Jump target:block23
|
||||
[ 320] Jump target:block23
|
||||
|
||||
block29:
|
||||
[ 330] Throw src:reg16
|
||||
[ 328] Throw src:reg16
|
||||
|
||||
Exception handlers:
|
||||
[ 150 .. 1a0] => handler block4
|
||||
[ 2a0 .. 338] => handler block24
|
||||
[ 150 .. 198] => handler block4
|
||||
[ 298 .. 330] => handler block24
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ block0:
|
|||
[ 18] Return value:outer~1
|
||||
|
||||
|
||||
forInTeardown$7c859710 lexical-env-teardown.js:28:5
|
||||
forInTeardown$fde78f98 lexical-env-teardown.js:28:5
|
||||
Registers: 8
|
||||
Blocks: 6
|
||||
Locals: k~0, outer~1
|
||||
|
|
@ -117,11 +117,10 @@ block4:
|
|||
|
||||
block5:
|
||||
[ b8] Mov dst:k~0, src:reg5
|
||||
[ c8] ThrowIfTDZ src:k~0
|
||||
[ d0] Jump target:block2
|
||||
[ c8] Jump target:block2
|
||||
|
||||
|
||||
forOfTeardown$94a2ae97 lexical-env-teardown.js:38:5
|
||||
forOfTeardown$269c4d7f lexical-env-teardown.js:38:5
|
||||
Registers: 12
|
||||
Blocks: 9
|
||||
Locals: v~0, outer~1
|
||||
|
|
@ -153,25 +152,24 @@ block3:
|
|||
|
||||
block4:
|
||||
[ c0] Mov dst:v~0, src:reg10
|
||||
[ d0] ThrowIfTDZ src:v~0
|
||||
[ d8] Jump target:block2
|
||||
[ d0] Jump target:block2
|
||||
|
||||
block5:
|
||||
[ e0] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:reg9
|
||||
[ f8] Throw src:reg9
|
||||
[ d8] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:reg9
|
||||
[ f0] Throw src:reg9
|
||||
|
||||
block6:
|
||||
[ 100] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:Undefined
|
||||
[ 118] JumpStrictlyEquals lhs:reg5, rhs:Int32(2), true_target:block7, false_target:block8
|
||||
[ f8] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:Undefined
|
||||
[ 110] JumpStrictlyEquals lhs:reg5, rhs:Int32(2), true_target:block7, false_target:block8
|
||||
|
||||
block7:
|
||||
[ 130] Return value:reg9
|
||||
[ 128] Return value:reg9
|
||||
|
||||
block8:
|
||||
[ 138] Throw src:reg9
|
||||
[ 130] Throw src:reg9
|
||||
|
||||
Exception handlers:
|
||||
[ c0 .. e0] => handler block3
|
||||
[ c0 .. d8] => handler block3
|
||||
|
||||
|
||||
catchTeardown$6b833e8d lexical-env-teardown.js:48:5
|
||||
|
|
|
|||
|
|
@ -80,3 +80,19 @@ test("const creation in inner scope", () => {
|
|||
} while (false);
|
||||
expect(constantValue).toBe(1);
|
||||
});
|
||||
|
||||
test("reassignment to destructured const in function", () => {
|
||||
expect(() => {
|
||||
(() => {
|
||||
const { value } = { value: 1 };
|
||||
value = 2;
|
||||
})();
|
||||
}).toThrowWithMessage(TypeError, "Invalid assignment to const variable");
|
||||
|
||||
expect(() => {
|
||||
(() => {
|
||||
const [value] = [1];
|
||||
[value] = [2];
|
||||
})();
|
||||
}).toThrowWithMessage(TypeError, "Invalid assignment to const variable");
|
||||
});
|
||||
|
|
|
|||
|
|
@ -217,6 +217,18 @@ describe("special left hand sides", () => {
|
|||
|
||||
expect(vals).toEqual(["0", "1"]);
|
||||
});
|
||||
|
||||
test("Cannot change destructured constant declaration in body", () => {
|
||||
const vals = [];
|
||||
for (const { 0: value } in "ab") {
|
||||
expect(() => {
|
||||
value = "x";
|
||||
}).toThrowWithMessage(TypeError, "Invalid assignment to const variable");
|
||||
vals.push(value);
|
||||
}
|
||||
|
||||
expect(vals).toEqual(["0", "1"]);
|
||||
});
|
||||
});
|
||||
|
||||
test("remove properties while iterating", () => {
|
||||
|
|
|
|||
|
|
@ -150,4 +150,16 @@ describe("special left hand sides", () => {
|
|||
|
||||
expect(vals).toEqual([1, 2]);
|
||||
});
|
||||
|
||||
test("Cannot change destructured constant declaration in body", () => {
|
||||
const vals = [];
|
||||
for (const [value] of [[1], [2]]) {
|
||||
expect(() => {
|
||||
value = 3;
|
||||
}).toThrowWithMessage(TypeError, "Invalid assignment to const variable");
|
||||
vals.push(value);
|
||||
}
|
||||
|
||||
expect(vals).toEqual([1, 2]);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -269,6 +269,19 @@ test("string object: string property indexing", () => {
|
|||
expect(lastSetThisValue).toBeNull();
|
||||
lastSetThisValue = null;
|
||||
});
|
||||
|
||||
test("primitive string object destructuring sees virtual indexed properties", () => {
|
||||
const { 0: first, 1: second, length } = "ab";
|
||||
expect(first).toBe("a");
|
||||
expect(second).toBe("b");
|
||||
expect(length).toBe(2);
|
||||
|
||||
const values = [];
|
||||
for (const { 0: c } of "ab") {
|
||||
values.push(c);
|
||||
}
|
||||
expect(values).toEqual(["a", "b"]);
|
||||
});
|
||||
test("string object: string property name access", () => {
|
||||
expect(new String("").length).toBe(0);
|
||||
expect(new String("foo").length).toBe(3);
|
||||
|
|
|
|||
Loading…
Reference in a new issue