LibJS: Stop persisting basic_block_start_offsets on Executable

Keep basic block offsets as construction-only metadata rather than
storing them on every Executable. The validator now receives the offsets
through a transient Rust FFI span, and the bytecode dump rebuilds block
starts by scanning labels, terminators, and exception handler metadata.

Drop the table from the bytecode cache format and bump the format
version so old caches are rebuilt. This removes a field that was only
used by validation and bytecode dump paths.
This commit is contained in:
Andreas Kling 2026-05-13 20:36:54 +02:00 committed by Andreas Kling
parent 21cbfb3cb1
commit a31c2c388b
34 changed files with 248 additions and 284 deletions

View file

@ -5,6 +5,8 @@
*/
#include <AK/BinarySearch.h>
#include <AK/NumericLimits.h>
#include <AK/QuickSort.h>
#include <LibGC/Heap.h>
#include <LibGC/HeapBlock.h>
#include <LibJS/Bytecode/BasicBlock.h>
@ -174,6 +176,71 @@ static void dump_header(StringBuilder& output, Executable const& executable, boo
output.append('\n');
}
static bool instruction_is_terminator(Instruction const& instruction)
{
#define __BYTECODE_OP(op) \
case Instruction::Type::op: \
return Op::op::IsTerminator;
switch (instruction.type()) {
ENUMERATE_BYTECODE_OPS(__BYTECODE_OP)
default:
VERIFY_NOT_REACHED();
}
#undef __BYTECODE_OP
}
static Vector<u32> collect_basic_block_start_offsets(Executable const& executable)
{
Vector<u32> offsets;
auto append_offset = [&](size_t offset) {
VERIFY(offset <= NumericLimits<u32>::max());
auto offset32 = static_cast<u32>(offset);
if (!offsets.contains_slow(offset32))
offsets.append(offset32);
};
auto append_instruction_offset = [&](size_t offset) {
if (offset < executable.bytecode.size())
append_offset(offset);
};
append_offset(0);
for (InstructionStreamIterator it(executable.bytecode, &executable); !it.at_end(); ++it) {
auto const& instruction = *it;
auto next_offset = it.offset() + instruction.length();
const_cast<Instruction&>(instruction).visit_labels([&](Label& label) {
append_offset(label.address());
});
if (instruction_is_terminator(instruction) && next_offset < executable.bytecode.size())
append_offset(next_offset);
}
for (auto const& handler : executable.exception_handlers) {
append_instruction_offset(handler.start_offset);
append_instruction_offset(handler.end_offset);
append_instruction_offset(handler.handler_offset);
}
quick_sort(offsets);
return offsets;
}
Optional<size_t> Executable::basic_block_index_for_offset(size_t offset) const
{
VERIFY(offset <= NumericLimits<u32>::max());
auto basic_block_start_offsets = collect_basic_block_start_offsets(*this);
size_t index = 0;
if (binary_search(basic_block_start_offsets, static_cast<u32>(offset), &index))
return index;
return {};
}
static void dump_metadata(StringBuilder& output, Executable const& executable, bool use_color)
{
auto const green = use_color ? "\033[32m"sv : ""sv;
@ -183,7 +250,7 @@ static void dump_metadata(StringBuilder& output, Executable const& executable, b
auto const reset = use_color ? "\033[0m"sv : ""sv;
output.appendff(" {}Registers{}: {}\n", green, reset, executable.number_of_registers);
output.appendff(" {}Blocks{}: {}\n", green, reset, executable.basic_block_start_offsets.size());
output.appendff(" {}Blocks{}: {}\n", green, reset, collect_basic_block_start_offsets(executable).size());
if (!executable.local_variable_names.is_empty()) {
output.appendff(" {}Locals{}: ", green, reset);
@ -232,12 +299,13 @@ static void dump_bytecode(StringBuilder& output, Executable const& executable, b
auto const reset = use_color ? "\033[0m"sv : ""sv;
InstructionStreamIterator it(executable.bytecode, &executable);
auto basic_block_start_offsets = collect_basic_block_start_offsets(executable);
size_t basic_block_offset_index = 0;
while (!it.at_end()) {
if (basic_block_offset_index < executable.basic_block_start_offsets.size()
&& it.offset() == executable.basic_block_start_offsets[basic_block_offset_index]) {
if (basic_block_offset_index < basic_block_start_offsets.size()
&& it.offset() == basic_block_start_offsets[basic_block_offset_index]) {
if (basic_block_offset_index > 0)
output.append('\n');
output.appendff("{}block{}{}:\n", magenta, basic_block_offset_index, reset);
@ -333,7 +401,6 @@ size_t Executable::external_memory_size() const
for (auto const& blueprint : class_blueprints)
size = saturating_add_external_memory_size(size, vector_external_memory_size(blueprint.elements));
size = saturating_add_external_memory_size(size, vector_external_memory_size(exception_handlers));
size = saturating_add_external_memory_size(size, vector_external_memory_size(basic_block_start_offsets));
size = saturating_add_external_memory_size(size, vector_external_memory_size(source_map));
size = saturating_add_external_memory_size(size, vector_external_memory_size(local_variable_names));
size = saturating_add_external_memory_size(size, hash_map_external_memory_size(m_source_range_cache));

View file

@ -201,7 +201,6 @@ public:
};
Vector<ExceptionHandlers> exception_handlers;
Vector<size_t> basic_block_start_offsets;
Vector<SourceMapEntry> source_map;
@ -222,6 +221,7 @@ public:
return get_identifier(*index);
}
[[nodiscard]] COLD Optional<size_t> basic_block_index_for_offset(size_t offset) const;
[[nodiscard]] COLD Optional<ExceptionHandlers const&> exception_handlers_for_offset(size_t offset) const;
[[nodiscard]] Optional<SourceRange> source_range_at(size_t offset) const;

View file

@ -23,11 +23,9 @@ inline ByteString format_label(StringView name, Label const& label, Bytecode::Ex
builder.appendff("\033[32m{}\033[0m:", name);
auto address = label.address();
for (size_t i = 0; i < executable.basic_block_start_offsets.size(); ++i) {
if (executable.basic_block_start_offsets[i] == address) {
builder.appendff("\033[35mblock{}\033[0m", i);
return builder.to_byte_string();
}
if (auto basic_block_index = executable.basic_block_index_for_offset(address); basic_block_index.has_value()) {
builder.appendff("\033[35mblock{}\033[0m", basic_block_index.value());
return builder.to_byte_string();
}
builder.appendff("@{:x}", address);
return builder.to_byte_string();

View file

@ -94,7 +94,7 @@ static_assert(put_kind_variant_count == 5);
static constexpr u32 arguments_kind_variant_count = to_underlying(Op::ArgumentsKind::Unmapped) + 1;
static_assert(arguments_kind_variant_count == 2);
ErrorOr<void> validate_bytecode(Executable const& executable, CacheState cache_state)
ErrorOr<void> validate_bytecode(Executable const& executable, ReadonlySpan<u32> basic_block_offsets, CacheState cache_state)
{
JS::FFI::FFIValidatorBounds bounds {
.number_of_registers = executable.number_of_registers,
@ -134,11 +134,6 @@ ErrorOr<void> validate_bytecode(Executable const& executable, CacheState cache_s
});
}
Vector<u32> basic_block_offsets;
basic_block_offsets.ensure_capacity(executable.basic_block_start_offsets.size());
for (auto offset : executable.basic_block_start_offsets)
basic_block_offsets.append(static_cast<u32>(offset));
Vector<u32> source_map_offsets;
source_map_offsets.ensure_capacity(executable.source_map.size());
for (auto const& entry : executable.source_map)

View file

@ -7,6 +7,7 @@
#pragma once
#include <AK/Error.h>
#include <AK/Span.h>
#include <LibJS/Forward.h>
namespace JS::Bytecode {
@ -22,6 +23,6 @@ enum class CacheState : u8 {
AfterFixup,
};
ErrorOr<void> validate_bytecode(Executable const&, CacheState);
ErrorOr<void> validate_bytecode(Executable const&, ReadonlySpan<u32> basic_block_offsets, CacheState);
}

View file

@ -29,7 +29,7 @@ use crate::bytecode::validator::{
use crate::{CompiledProgram, CompiledProgramBytecode, ModuleCallbacks, ast, u32_from_usize};
const MAGIC: &[u8; 8] = b"LBJSBC\0\0";
const FORMAT_VERSION: u32 = 4;
const FORMAT_VERSION: u32 = 5;
const SOURCE_HASH_SIZE: usize = 32;
const COMPLETION_TYPE_VARIANT_COUNT: u32 = 6;
const ITERATOR_HINT_VARIANT_COUNT: u32 = 2;
@ -833,7 +833,7 @@ unsafe fn materialize_executable(
bytecode: executable.bytecode,
source_map: executable.source_map,
exception_handlers: executable.exception_handlers,
basic_block_start_offsets: executable.basic_block_start_offsets,
basic_block_start_offsets: Vec::new(),
number_of_registers: executable.number_of_registers,
number_of_arguments: executable.number_of_arguments,
};
@ -1903,7 +1903,6 @@ impl Encode for ExecutableRecord<'_> {
ConstantTable(&self.generator.constants).encode(encoder);
ExceptionHandlerTable(self.assembled).encode(encoder);
SourceMapTable(self.assembled).encode(encoder);
BasicBlockOffsetTable(self.assembled).encode(encoder);
LocalVariableTable(self.generator).encode(encoder);
SharedFunctionTable(self.generator).encode(encoder);
ClassBlueprintTable(self.generator).encode(encoder);
@ -1926,7 +1925,6 @@ impl ExecutableRecord<'_> {
constants: ConstantTable::decode(decoder)?,
exception_handlers: ExceptionHandlerTable::decode(decoder)?,
source_map: SourceMapTable::decode(decoder)?,
basic_block_start_offsets: BasicBlockOffsetTable::decode(decoder)?,
local_variables: LocalVariableTable::decode(decoder)?,
shared_functions: SharedFunctionTable::decode(decoder)?,
class_blueprints: ClassBlueprintTable::decode(decoder)?,
@ -1948,7 +1946,6 @@ struct DecodedExecutableRecord {
constants: Vec<ConstantValue>,
exception_handlers: Vec<ExceptionHandler>,
source_map: Vec<SourceMapEntry>,
basic_block_start_offsets: Vec<usize>,
local_variables: Vec<LocalVariable>,
shared_functions: Vec<DecodedFunctionRecord>,
class_blueprints: Vec<DecodedClassBlueprintRecord>,
@ -1968,7 +1965,6 @@ impl DecodedExecutableRecord {
+ self.constants.len()
+ self.exception_handlers.len()
+ self.source_map.len()
+ self.basic_block_start_offsets.len()
+ self.local_variables.len()
+ self.shared_functions.len()
+ self.class_blueprints.len();
@ -2227,22 +2223,6 @@ impl SourceMapTable<'_> {
}
}
struct BasicBlockOffsetTable<'a>(&'a AssembledBytecode);
impl Encode for BasicBlockOffsetTable<'_> {
fn encode(&self, encoder: &mut Encoder) {
encoder.sequence(&self.0.basic_block_start_offsets, |offset, encoder| {
offset.encode(encoder);
});
}
}
impl BasicBlockOffsetTable<'_> {
fn decode(decoder: &mut Decoder<'_>) -> Option<Vec<usize>> {
decoder.sequence_values(usize::decode)
}
}
struct LocalVariableTable<'a>(&'a Generator);
impl Encode for LocalVariableTable<'_> {

View file

@ -6,6 +6,7 @@
#include <LibJS/RustIntegration.h>
#include <AK/NumericLimits.h>
#include <AK/TemporaryChange.h>
#include <AK/Utf16String.h>
#include <AK/Utf16View.h>
@ -1046,9 +1047,13 @@ extern "C" void* rust_create_executable(
});
}
// Set basic block offsets
// Keep basic block offsets transient. They are only needed by the
// validator while this Executable is being constructed.
Vector<u32> basic_block_offsets;
basic_block_offsets.ensure_capacity(data->basic_block_count);
for (size_t i = 0; i < data->basic_block_count; ++i) {
executable->basic_block_start_offsets.append(data->basic_block_offsets[i]);
VERIFY(data->basic_block_offsets[i] <= NumericLimits<u32>::max());
basic_block_offsets.append(static_cast<u32>(data->basic_block_offsets[i]));
}
// Set local variable names
@ -1091,7 +1096,7 @@ extern "C" void* rust_create_executable(
auto const should_validate_bytecode = is_materializing_bytecode_cache;
#endif
if (should_validate_bytecode) {
if (auto validation = JS::Bytecode::validate_bytecode(*executable, JS::Bytecode::CacheState::BeforeFixup); validation.is_error()) {
if (auto validation = JS::Bytecode::validate_bytecode(*executable, basic_block_offsets.span(), JS::Bytecode::CacheState::BeforeFixup); validation.is_error()) {
if (is_materializing_bytecode_cache)
return nullptr;
#if !defined(NDEBUG) || defined(HAS_ADDRESS_SANITIZER)

View file

@ -20,7 +20,7 @@ block0:
throwInCatch$94c0d746 catch-scope-boundary.js:2:5
Registers: 7
Blocks: 7
Blocks: 6
Locals: e2~0, e~1, result~2
Constants:
[0] = String("bad")
@ -31,29 +31,27 @@ throwInCatch$94c0d746 catch-scope-boundary.js:2:5
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] Mov dst:result~2, src:String("bad")
[ 18] Jump target:block6
[ 18] Jump target:block5
block1:
[ 20] Catch dst:reg5
[ 28] SetLexicalEnvironment environment:reg4
[ 30] Mov dst:e~1, src:reg5
[ 40] Jump target:block4
[ 40] Jump target:block3
block2:
[ 48] Catch dst:reg6
[ 50] SetLexicalEnvironment environment:reg4
[ 58] Mov2 dst1:e2~0, src1:reg6, dst2:result~2, src2:String("good")
block3:
[ 70] Return value:result~2
block4:
block3:
[ 78] Throw src:Int32(2)
block5:
block4:
[ 80] Return value:result~2
block6:
block5:
[ 88] Throw src:Int32(1)
Exception handlers:

View file

@ -1,6 +1,6 @@
$82bdc9cb chained-member-call.js:12:1
Registers: 10
Blocks: 7
Blocks: 6
Constants:
[0] = Undefined
[1] = Int32(0)
@ -15,7 +15,7 @@ block1:
[ 20] Mov2 dst1:reg6, src1:Undefined, dst2:reg7, src2:reg6
block2:
[ 38] Jump target:block6
[ 38] Jump target:block5
block3:
[ 40] Mov dst:reg5, src:Undefined
@ -28,11 +28,9 @@ block4:
[ b8] Catch dst:reg5
[ c0] SetLexicalEnvironment environment:reg4
[ c8] Mov2 dst1:reg7, src1:Undefined, dst2:reg8, src2:reg7
block5:
[ e0] End value:reg7
block6:
block5:
[ e8] Mov dst:reg5, src:Undefined
[ f8] GetGlobal dst:reg9, `chained_dot_call`
[ 110] Call dst:reg7, callee:reg9, this_value:Undefined, chained_dot_call, arguments:[Int32(0)]

View file

@ -100,7 +100,7 @@ block0:
do_while_falsey$2b22dba1 condition-dead-code-elim.js:37:9
Registers: 7
Blocks: 4
Blocks: 1
Constants:
[0] = Bool(false)
[1] = Undefined
@ -109,16 +109,10 @@ do_while_falsey$2b22dba1 condition-dead-code-elim.js:37:9
block0:
[ 0] GetGlobal dst:reg6, `alive`
[ 18] Call dst:reg5, callee:reg6, this_value:Undefined, alive
block1:
[ 38] GetGlobal dst:reg6, `alive`
[ 50] Call dst:reg5, callee:reg6, this_value:Undefined, alive
block2:
[ 70] GetGlobal dst:reg6, `alive`
[ 88] Call dst:reg5, callee:reg6, this_value:Undefined, alive
block3:
[ a8] GetGlobal dst:reg6, `alive`
[ c0] Call dst:reg5, callee:reg6, this_value:Undefined, alive
[ e0] End value:Undefined

View file

@ -12,7 +12,7 @@ block0:
foo$1d0ffb84 conditional-register-order.js:2:5
Registers: 6
Blocks: 4
Blocks: 3
Constants:
[0] = Int32(1)
[1] = Int32(2)
@ -26,6 +26,4 @@ block1:
block2:
[ 28] Mov dst:reg5, src:Int32(2)
block3:
[ 38] Return value:reg5

View file

@ -1,23 +1,21 @@
$0a83f971 const-assignment-no-extra-tdz.js:5:1
Registers: 9
Blocks: 4
Blocks: 3
Locals: e~0
Constants:
[0] = Undefined
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] Jump target:block3
[ 8] Jump target:block2
block1:
[ 10] Catch dst:reg5
[ 18] SetLexicalEnvironment environment:reg4
[ 20] Mov3 dst1:e~0, src1:reg5, dst2:reg6, src2:Undefined, dst3:reg7, src3:reg6
block2:
[ 40] End value:reg6
block3:
block2:
[ 48] Mov dst:reg5, src:Undefined
[ 58] GetGlobal dst:reg8, `f`
[ 70] Call dst:reg6, callee:reg8, this_value:Undefined, f

View file

@ -1,6 +1,6 @@
$67bc40cb delete-super-eval-order.js:4:1
Registers: 10
Blocks: 4
Blocks: 3
Constants:
[0] = String("m")
[1] = Undefined
@ -13,17 +13,15 @@ block0:
[ 28] SetLexicalEnvironment environment:reg4
[ 30] NewClass dst:reg6, class_environment:reg5, class_blueprint_index:0, element_keys:[element_keys:String("m")]
[ 58] InitializeLexicalBinding `A`, src:reg6
[ 70] Jump target:block3
[ 70] Jump target:block2
block1:
[ 78] Catch dst:reg6
[ 80] SetLexicalEnvironment environment:reg4
[ 88] Mov2 dst1:reg5, src1:Undefined, dst2:reg7, src2:reg5
block2:
[ a0] End value:reg5
block3:
block2:
[ a8] Mov dst:reg6, src:Undefined
[ b8] GetGlobal dst:reg9, `A`
[ d0] CallConstruct dst:reg8, callee:reg9, A

View file

@ -1,6 +1,6 @@
$752dc5b7 delete-super-property.js:1:1
Registers: 11
Blocks: 7
Blocks: 6
Locals: e~0, e~1
Constants:
[0] = String("foo")
@ -22,7 +22,7 @@ block1:
[ 88] Mov3 dst1:e~0, src1:reg6, dst2:reg5, src2:Undefined, dst3:reg7, src3:reg5
block2:
[ a8] Jump target:block6
[ a8] Jump target:block5
block3:
[ b0] Mov dst:reg6, src:Undefined
@ -37,11 +37,9 @@ block4:
[ 150] Catch dst:reg6
[ 158] SetLexicalEnvironment environment:reg4
[ 160] Mov3 dst1:e~1, src1:reg6, dst2:reg7, src2:Undefined, dst3:reg9, src3:reg7
block5:
[ 180] End value:reg7
block6:
block5:
[ 188] Mov dst:reg6, src:Undefined
[ 198] GetGlobal dst:reg10, `A`
[ 1b0] CallConstruct dst:reg8, callee:reg10, A

View file

@ -12,7 +12,7 @@ block0:
test$e414328f do-while-register-allocation.js:9:5
Registers: 9
Blocks: 4
Blocks: 3
Locals: i~0
Constants:
[0] = Undefined
@ -30,11 +30,9 @@ block1:
[ 80] Mov dst:reg8, src:i~0
[ 90] Call dst:reg6, callee:reg7, this_value:Undefined, bar, arguments:[reg8]
[ b8] PostfixIncrement dst:reg6, src:i~0
[ c8] JumpLessThan lhs:i~0, rhs:Int32(7), true_target:block1, false_target:block2
block2:
[ c8] JumpLessThan lhs:i~0, rhs:Int32(7), true_target:block1, false_target:block3
block3:
[ e0] End value:Undefined

View file

@ -15,7 +15,7 @@ block0:
forLetClosure$9d2e257d for-loop-scoping.js:2:15
Registers: 10
Blocks: 5
Blocks: 4
Locals: fns~0
Constants:
[0] = Int32(0)
@ -32,7 +32,7 @@ block0:
[ 70] CreateLexicalEnvironment dst:reg5, parent:reg4, capacity:0
[ 80] CreateVariable `i`, is_immutable:false, is_global:false, is_strict:false
[ 90] InitializeLexicalBinding `i`, src:reg6
[ a8] Jump target:block3
[ a8] Jump target:block2
block1:
[ b0] GetById dst:reg7, base:fns~0, `push` (fns.push)
@ -44,17 +44,15 @@ block1:
[ 140] CreateLexicalEnvironment dst:reg5, parent:reg4, capacity:0
[ 150] CreateVariable `i`, is_immutable:false, is_global:false, is_strict:false
[ 160] InitializeLexicalBinding `i`, src:reg6
block2:
[ 178] GetBinding dst:reg7, `i`
[ 190] PostfixIncrement dst:reg6, src:reg7
[ 1a0] SetLexicalBinding `i`, src:reg7
block3:
block2:
[ 1b8] GetBinding dst:reg6, `i`
[ 1d0] JumpLessThan lhs:reg6, rhs:Int32(3), true_target:block1, false_target:block4
[ 1d0] JumpLessThan lhs:reg6, rhs:Int32(3), true_target:block1, false_target:block3
block4:
block3:
[ 1e8] SetLexicalEnvironment environment:reg4
[ 1f0] GetById dst:reg6, base:fns~0, `map` (fns.map)
[ 210] Mov dst:reg7, src:fns~0

View file

@ -13,7 +13,7 @@ block0:
f$567c3f32 for-of-cond-rhs-block-order.js:2:21
Registers: 17
Blocks: 20
Blocks: 19
Locals: r~0, n~1
Constants:
[0] = Bool(false)
@ -30,7 +30,7 @@ block1:
block2:
[ 20] IteratorNextUnpack dst_value:reg10, dst_done:reg11, iterator_object:reg5, iterator_next:reg8, iterator_done:reg6
[ 38] JumpIf condition:reg11, true_target:block1, false_target:block8
[ 38] JumpIf condition:reg11, true_target:block1, false_target:block7
block3:
[ 48] Mov dst:reg6, src:arg0
@ -53,56 +53,54 @@ block6:
[ 130] Catch dst:reg9
[ 138] SetLexicalEnvironment environment:reg4
[ 140] Mov dst:reg7, src:Int32(1)
[ 150] JumpStrictlyEquals lhs:reg7, rhs:Int32(1), true_target:block15, false_target:block16
block7:
[ 150] JumpStrictlyEquals lhs:reg7, rhs:Int32(1), true_target:block16, false_target:block17
block8:
[ 168] Mov dst:reg12, src:Bool(false)
[ 178] GetIterator dst_iterator_object:reg13, dst_iterator_next:reg14, dst_iterator_done:reg15, iterable:reg10
[ 190] IteratorNextUnpack dst_value:reg16, dst_done:reg12, iterator_object:reg13, iterator_next:reg14, iterator_done:reg15
[ 1a8] JumpFalse condition:reg12, target:block10
[ 1a8] JumpFalse condition:reg12, target:block9
block8:
[ 1b8] Mov dst:reg16, src:Undefined
[ 1c8] Jump target:block9
block9:
[ 1b8] Mov dst:reg16, src:Undefined
[ 1c8] Jump target:block10
[ 1d0] Mov dst:r~0, src:reg16
[ 1e0] JumpFalse condition:reg12, target:block11
block10:
[ 1d0] Mov dst:r~0, src:reg16
[ 1e0] JumpFalse condition:reg12, target:block12
[ 1f0] Mov dst:reg16, src:Undefined
[ 200] Jump target:block12
block11:
[ 1f0] Mov dst:reg16, src:Undefined
[ 200] Jump target:block13
[ 208] IteratorNextUnpack dst_value:reg16, dst_done:reg12, iterator_object:reg13, iterator_next:reg14, iterator_done:reg15
[ 220] JumpTrue condition:reg12, target:block10
block12:
[ 208] IteratorNextUnpack dst_value:reg16, dst_done:reg12, iterator_object:reg13, iterator_next:reg14, iterator_done:reg15
[ 220] JumpTrue condition:reg12, target:block11
[ 230] Mov dst:n~1, src:reg16
[ 240] JumpFalse condition:reg12, target:block14
block13:
[ 230] Mov dst:n~1, src:reg16
[ 240] JumpFalse condition:reg12, target:block15
block14:
[ 250] ThrowIfTDZ src:r~0
[ 258] Jump target:block2
block15:
block14:
[ 260] IteratorClose iterator_object:reg13, iterator_next:reg14, iterator_done:reg15, completion_value:Undefined
[ 278] Jump target:block14
[ 278] Jump target:block13
block16:
block15:
[ 280] IteratorClose iterator_object:reg5, iterator_next:reg8, iterator_done:reg6, completion_value:reg9
[ 298] Throw src:reg9
block17:
block16:
[ 2a0] IteratorClose iterator_object:reg5, iterator_next:reg8, iterator_done:reg6, completion_value:Undefined
[ 2b8] JumpStrictlyEquals lhs:reg7, rhs:Int32(2), true_target:block18, false_target:block19
[ 2b8] JumpStrictlyEquals lhs:reg7, rhs:Int32(2), true_target:block17, false_target:block18
block18:
block17:
[ 2d0] Return value:reg9
block19:
block18:
[ 2d8] Throw src:reg9
Exception handlers:

View file

@ -13,7 +13,7 @@ block0:
f$a6e23ba8 for-of-continue-with-block-scope.js:2:15
Registers: 18
Blocks: 12
Blocks: 11
Locals: o~0, t~1
Constants:
[0] = Int32(1)
@ -34,25 +34,23 @@ block1:
block2:
[ 68] IteratorNextUnpack dst_value:reg10, dst_done:reg11, iterator_object:reg5, iterator_next:reg6, iterator_done:reg7
[ 80] JumpIf condition:reg11, true_target:block1, false_target:block5
[ 80] JumpIf condition:reg11, true_target:block1, false_target:block4
block3:
[ 90] Catch dst:reg9
[ 98] SetLexicalEnvironment environment:reg4
[ a0] Mov dst:reg8, src:Int32(1)
[ b0] JumpStrictlyEquals lhs:reg8, rhs:Int32(1), true_target:block7, false_target:block8
block4:
[ b0] JumpStrictlyEquals lhs:reg8, rhs:Int32(1), true_target:block8, false_target:block9
block5:
[ c8] CreateLexicalEnvironment dst:reg12, parent:reg4, capacity:0
[ d8] CreateVariable `r`, is_immutable:true, is_global:false, is_strict:true
[ e8] InitializeLexicalBinding `r`, src:reg10
[ 100] GetBinding dst:reg14, `r`
[ 118] Not dst:reg13, src:reg14
[ 128] JumpFalse condition:reg13, target:block7
[ 128] JumpFalse condition:reg13, target:block6
block6:
block5:
[ 138] GetById dst:reg15, base:t~1, `push` (t.push)
[ 158] Mov dst:reg16, src:t~1
[ 168] GetBinding dst:reg17, `r`
@ -60,7 +58,7 @@ block6:
[ 1a8] SetLexicalEnvironment environment:reg4
[ 1b0] Jump target:block2
block7:
block6:
[ 1b8] GetById dst:reg13, base:t~1, `find` (t.find)
[ 1d8] Mov dst:reg14, src:t~1
[ 1e8] NewFunction dst:reg15, shared_function_data_index:0
@ -68,18 +66,18 @@ block7:
[ 228] SetLexicalEnvironment environment:reg4
[ 230] Jump target:block2
block8:
block7:
[ 238] IteratorClose iterator_object:reg5, iterator_next:reg6, iterator_done:reg7, completion_value:reg9
[ 250] Throw src:reg9
block9:
block8:
[ 258] IteratorClose iterator_object:reg5, iterator_next:reg6, iterator_done:reg7, completion_value:Undefined
[ 270] JumpStrictlyEquals lhs:reg8, rhs:Int32(2), true_target:block10, false_target:block11
[ 270] JumpStrictlyEquals lhs:reg8, rhs:Int32(2), true_target:block9, false_target:block10
block10:
block9:
[ 288] Return value:reg9
block11:
block10:
[ 290] Throw src:reg9
Exception handlers:

View file

@ -1,6 +1,6 @@
$0a509d5d for-of-iteration-env-capacity.js:1:14
Registers: 13
Blocks: 10
Blocks: 9
Locals: x~0
Constants:
[0] = Undefined
@ -19,34 +19,32 @@ block1:
block2:
[ 68] IteratorNextUnpack dst_value:reg11, dst_done:reg12, iterator_object:reg6, iterator_next:reg7, iterator_done:reg8
[ 80] JumpIf condition:reg12, true_target:block1, false_target:block5
[ 80] JumpIf condition:reg12, true_target:block1, false_target:block4
block3:
[ 90] Catch dst:reg10
[ 98] SetLexicalEnvironment environment:reg4
[ a0] Mov dst:reg9, src:Int32(1)
[ b0] JumpStrictlyEquals lhs:reg9, rhs:Int32(1), true_target:block5, false_target:block6
block4:
[ b0] JumpStrictlyEquals lhs:reg9, rhs:Int32(1), true_target:block6, false_target:block7
block5:
[ c8] Mov dst:x~0, src:reg11
[ d8] ThrowIfTDZ src:x~0
[ e0] Mov dst:reg5, src:x~0
[ f0] Jump target:block2
block6:
block5:
[ f8] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:reg10
[ 110] Throw src:reg10
block7:
block6:
[ 118] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:Undefined
[ 130] JumpStrictlyEquals lhs:reg9, rhs:Int32(2), true_target:block8, false_target:block9
[ 130] JumpStrictlyEquals lhs:reg9, rhs:Int32(2), true_target:block7, false_target:block8
block8:
block7:
[ 148] Return value:reg10
block9:
block8:
[ 150] Throw src:reg10
Exception handlers:

View file

@ -1,22 +1,20 @@
$aaec50d4 invalid-lhs-assignment-no-dead-code.js:8:1
Registers: 10
Blocks: 4
Blocks: 3
Constants:
[0] = Undefined
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] Jump target:block3
[ 8] Jump target:block2
block1:
[ 10] Catch dst:reg5
[ 18] SetLexicalEnvironment environment:reg4
[ 20] Mov2 dst1:reg6, src1:Undefined, dst2:reg7, src2:reg6
block2:
[ 38] End value:reg6
block3:
block2:
[ 40] Mov dst:reg5, src:Undefined
[ 50] GetGlobal dst:reg8, `f`
[ 68] NewFunction dst:reg9, shared_function_data_index:0

View file

@ -123,7 +123,7 @@ block5:
forOfTeardown$94a2ae97 lexical-env-teardown.js:38:5
Registers: 12
Blocks: 10
Blocks: 9
Locals: v~0, outer~1
Constants:
[0] = Int32(5)
@ -143,33 +143,31 @@ block1:
block2:
[ 60] IteratorNextUnpack dst_value:reg10, dst_done:reg11, iterator_object:reg6, iterator_next:reg7, iterator_done:reg8
[ 78] JumpIf condition:reg11, true_target:block1, false_target:block5
[ 78] JumpIf condition:reg11, true_target:block1, false_target:block4
block3:
[ 88] Catch dst:reg9
[ 90] SetLexicalEnvironment environment:reg4
[ 98] Mov dst:reg5, src:Int32(1)
[ a8] JumpStrictlyEquals lhs:reg5, rhs:Int32(1), true_target:block5, false_target:block6
block4:
[ a8] JumpStrictlyEquals lhs:reg5, rhs:Int32(1), true_target:block6, false_target:block7
block5:
[ c0] Mov dst:v~0, src:reg10
[ d0] ThrowIfTDZ src:v~0
[ d8] Jump target:block2
block6:
block5:
[ e0] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:reg9
[ f8] Throw src:reg9
block7:
block6:
[ 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
[ 118] JumpStrictlyEquals lhs:reg5, rhs:Int32(2), true_target:block7, false_target:block8
block8:
block7:
[ 130] Return value:reg9
block9:
block8:
[ 138] Throw src:reg9
Exception handlers:
@ -178,7 +176,7 @@ Exception handlers:
catchTeardown$ea214605 lexical-env-teardown.js:48:5
Registers: 7
Blocks: 4
Blocks: 3
Locals: e~0, outer~1
Constants:
[0] = Int32(6)
@ -188,17 +186,15 @@ catchTeardown$ea214605 lexical-env-teardown.js:48:5
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] Mov dst:outer~1, src:Int32(6)
[ 18] Jump target:block3
[ 18] Jump target:block2
block1:
[ 20] Catch dst:reg5
[ 28] SetLexicalEnvironment environment:reg4
[ 30] Mov dst:e~0, src:reg5
block2:
[ 40] Return value:outer~1
block3:
block2:
[ 48] GetGlobal dst:reg6, `Error`
[ 60] CallConstruct dst:reg5, callee:reg6, Error, arguments:[String("test")]
[ 80] Throw src:reg5

View file

@ -1,6 +1,6 @@
$932d2a38 logical-assignment-register-order.js:2:7
Registers: 8
Blocks: 4
Blocks: 3
block0:
[ 0] GetGlobal dst:reg5, `value`
@ -14,6 +14,4 @@ block1:
block2:
[ 70] Mov dst:reg7, src:reg5
block3:
[ 80] End value:reg7

View file

@ -1,6 +1,6 @@
$a37cd2a2 optional-chain-base-identifier.js:1:1
Registers: 9
Blocks: 4
Blocks: 3
Constants:
[0] = Int32(44)
[1] = Undefined
@ -17,15 +17,13 @@ block0:
[ 98] GetGlobal dst:reg7, `obj`
[ b0] GetById dst:reg8, base:reg7, `a` (obj.a)
[ d0] Mov2 dst1:reg5, src1:reg7, dst2:reg6, src2:reg8
[ e8] JumpNullish condition:reg6, true_target:block1, false_target:block3
[ e8] JumpNullish condition:reg6, true_target:block1, false_target:block2
block1:
[ f8] Mov dst:reg6, src:Undefined
block2:
[ 108] End value:reg6
block3:
block2:
[ 110] Mov dst:reg5, src:reg6
[ 120] GetById dst:reg6, base:reg6, `b`
[ 140] End value:reg6

View file

@ -23,21 +23,19 @@ block0:
member$b5894147 optional-chain.js:7:5
Registers: 7
Blocks: 4
Blocks: 3
Constants:
[0] = Undefined
block0:
[ 0] Mov2 dst1:reg5, src1:Undefined, dst2:reg6, src2:arg0
[ 18] JumpNullish condition:reg6, true_target:block1, false_target:block3
[ 18] JumpNullish condition:reg6, true_target:block1, false_target:block2
block1:
[ 28] Mov dst:reg6, src:Undefined
block2:
[ 38] Return value:reg6
block3:
block2:
[ 40] Mov dst:reg5, src:reg6
[ 50] GetById dst:reg6, base:reg6, `x`
[ 70] Return value:reg6
@ -45,26 +43,24 @@ block3:
nested_member$830d1888 optional-chain.js:10:5
Registers: 7
Blocks: 5
Blocks: 4
Constants:
[0] = Undefined
block0:
[ 0] Mov2 dst1:reg5, src1:Undefined, dst2:reg6, src2:arg0
[ 18] JumpNullish condition:reg6, true_target:block1, false_target:block3
[ 18] JumpNullish condition:reg6, true_target:block1, false_target:block2
block1:
[ 28] Mov dst:reg6, src:Undefined
block2:
[ 38] Return value:reg6
block3:
block2:
[ 40] Mov dst:reg5, src:reg6
[ 50] GetById dst:reg6, base:reg6, `x`
[ 70] JumpNullish condition:reg6, true_target:block1, false_target:block4
[ 70] JumpNullish condition:reg6, true_target:block1, false_target:block3
block4:
block3:
[ 80] Mov dst:reg5, src:reg6
[ 90] GetById dst:reg6, base:reg6, `y`
[ b0] Return value:reg6
@ -72,21 +68,19 @@ block4:
call_no_args$f2028fc1 optional-chain.js:13:5
Registers: 8
Blocks: 4
Blocks: 3
Constants:
[0] = Undefined
block0:
[ 0] Mov2 dst1:reg5, src1:Undefined, dst2:reg6, src2:arg0
[ 18] JumpNullish condition:reg6, true_target:block1, false_target:block3
[ 18] JumpNullish condition:reg6, true_target:block1, false_target:block2
block1:
[ 28] Mov dst:reg6, src:Undefined
block2:
[ 38] Return value:reg6
block3:
block2:
[ 40] Mov dst:reg5, src:reg6
[ 50] GetById dst:reg6, base:reg6, `foo`
[ 70] NewArray dst:reg7
@ -97,7 +91,7 @@ block3:
call_with_args$339c1d87 optional-chain.js:16:5
Registers: 11
Blocks: 4
Blocks: 3
Constants:
[0] = Undefined
[1] = Int32(1)
@ -106,15 +100,13 @@ call_with_args$339c1d87 optional-chain.js:16:5
block0:
[ 0] Mov2 dst1:reg5, src1:Undefined, dst2:reg6, src2:arg0
[ 18] JumpNullish condition:reg6, true_target:block1, false_target:block3
[ 18] JumpNullish condition:reg6, true_target:block1, false_target:block2
block1:
[ 28] Mov dst:reg6, src:Undefined
block2:
[ 38] Return value:reg6
block3:
block2:
[ 40] Mov dst:reg5, src:reg6
[ 50] GetById dst:reg6, base:reg6, `foo`
[ 70] Mov3 dst1:reg8, src1:Int32(1), dst2:reg9, src2:Int32(2), dst3:reg10, src3:Int32(3)
@ -126,22 +118,20 @@ block3:
computed$1d9658d2 optional-chain.js:19:5
Registers: 7
Blocks: 4
Blocks: 3
Constants:
[0] = Undefined
[1] = String("hello")
block0:
[ 0] Mov2 dst1:reg5, src1:Undefined, dst2:reg6, src2:arg0
[ 18] JumpNullish condition:reg6, true_target:block1, false_target:block3
[ 18] JumpNullish condition:reg6, true_target:block1, false_target:block2
block1:
[ 28] Mov dst:reg6, src:Undefined
block2:
[ 38] Return value:reg6
block3:
block2:
[ 40] Mov dst:reg5, src:reg6
[ 50] GetById dst:reg6, base:reg6, `hello`
[ 70] Return value:reg6
@ -149,21 +139,19 @@ block3:
member_then_call$adb462b3 optional-chain.js:22:5
Registers: 8
Blocks: 4
Blocks: 3
Constants:
[0] = Undefined
block0:
[ 0] Mov2 dst1:reg5, src1:Undefined, dst2:reg6, src2:arg0
[ 18] JumpNullish condition:reg6, true_target:block1, false_target:block3
[ 18] JumpNullish condition:reg6, true_target:block1, false_target:block2
block1:
[ 28] Mov dst:reg6, src:Undefined
block2:
[ 38] Return value:reg6
block3:
block2:
[ 40] Mov dst:reg5, src:reg6
[ 50] GetById dst:reg6, base:reg6, `x`
[ 70] Mov dst:reg5, src:reg6

View file

@ -15,7 +15,7 @@ block0:
sequentialTryCatch$0a8456ee sequential-try-blocks.js:2:5
Registers: 8
Blocks: 7
Blocks: 5
Locals: e~0, e~1, result~2
Constants:
[0] = String("")
@ -29,7 +29,7 @@ sequentialTryCatch$0a8456ee sequential-try-blocks.js:2:5
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] Mov dst:result~2, src:String("")
[ 18] Jump target:block3
[ 18] Jump target:block2
block1:
[ 20] Catch dst:reg5
@ -37,27 +37,23 @@ block1:
[ 30] Mov2 dst1:e~0, src1:reg5, dst2:reg6, src2:result~2
[ 48] Add dst:reg7, lhs:reg6, rhs:String("b")
[ 58] Mov dst:result~2, src:reg7
[ 68] Jump target:block4
block2:
[ 68] Jump target:block6
block3:
[ 70] Mov dst:reg5, src:result~2
[ 80] Add dst:reg7, lhs:reg5, rhs:String("a")
[ 90] Mov dst:result~2, src:reg7
[ a0] Throw src:Int32(1)
block4:
block3:
[ a8] Catch dst:reg7
[ b0] SetLexicalEnvironment environment:reg4
[ b8] Mov2 dst1:e~1, src1:reg7, dst2:reg5, src2:result~2
[ d0] Add dst:reg6, lhs:reg5, rhs:String("d")
[ e0] Mov dst:result~2, src:reg6
block5:
[ f0] Return value:result~2
block6:
block4:
[ f8] Mov dst:reg7, src:result~2
[ 108] Add dst:reg6, lhs:reg7, rhs:String("c")
[ 118] Mov dst:result~2, src:reg6
@ -65,7 +61,7 @@ block6:
Exception handlers:
[ 70 .. a8] => handler block1
[ f8 .. 130] => handler block4
[ f8 .. 130] => handler block3
"abcd"

View file

@ -18,7 +18,7 @@ block0:
C$9d8b2466 super-for-of-resolve-order.js:3:28
Registers: 13
Blocks: 10
Blocks: 9
Constants:
[0] = String("prop")
[1] = Int32(1)
@ -36,34 +36,32 @@ block1:
block2:
[ 50] IteratorNextUnpack dst_value:reg10, dst_done:reg11, iterator_object:reg6, iterator_next:reg7, iterator_done:reg8
[ 68] JumpIf condition:reg11, true_target:block1, false_target:block5
[ 68] JumpIf condition:reg11, true_target:block1, false_target:block4
block3:
[ 78] Catch dst:reg9
[ 80] SetLexicalEnvironment environment:reg4
[ 88] Mov dst:reg5, src:Int32(1)
[ 98] JumpStrictlyEquals lhs:reg5, rhs:Int32(1), true_target:block5, false_target:block6
block4:
[ 98] JumpStrictlyEquals lhs:reg5, rhs:Int32(1), true_target:block6, false_target:block7
block5:
[ b0] ResolveThisBinding
[ b8] ResolveSuperBase dst:reg12
[ c0] PutByIdWithThis base:reg12, this_value:this, `prop`, src:reg10, kind:Normal
[ e0] Jump target:block2
block6:
block5:
[ e8] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:reg9
[ 100] Throw src:reg9
block7:
block6:
[ 108] IteratorClose iterator_object:reg6, iterator_next:reg7, iterator_done:reg8, completion_value:Undefined
[ 120] JumpStrictlyEquals lhs:reg5, rhs:Int32(2), true_target:block8, false_target:block9
[ 120] JumpStrictlyEquals lhs:reg5, rhs:Int32(2), true_target:block7, false_target:block8
block8:
block7:
[ 138] Return value:reg9
block9:
block8:
[ 140] Throw src:reg9
Exception handlers:

View file

@ -50,7 +50,7 @@ block0:
method$994e3bed super-optional-call-this.js:6:9
Registers: 9
Blocks: 4
Blocks: 3
Constants:
[0] = Undefined
@ -60,15 +60,13 @@ block0:
[ 18] ResolveSuperBase dst:reg7
[ 20] GetByIdWithThis dst:reg8, base:reg7, `method`, this_value:this
[ 40] Mov2 dst1:reg5, src1:this, dst2:reg6, src2:reg8
[ 58] JumpNullish condition:reg6, true_target:block1, false_target:block3
[ 58] JumpNullish condition:reg6, true_target:block1, false_target:block2
block1:
[ 68] Mov dst:reg6, src:Undefined
block2:
[ 78] Return value:reg6
block3:
block2:
[ 80] NewArray dst:reg7
[ 90] CallWithArgumentArray dst:reg6, callee:reg6, this_value:reg5, arguments:reg7
[ a8] Mov dst:reg5, src:Undefined

View file

@ -28,7 +28,7 @@ block0:
eval$6559f0fb line 1, column 1
Registers: 7
Blocks: 5
Blocks: 3
Locals: x~0
Constants:
[0] = Undefined
@ -37,23 +37,19 @@ eval$6559f0fb line 1, column 1
block0:
[ 0] Mov dst:reg5, src:Undefined
[ 10] JumpStrictlyEquals lhs:Int32(1), rhs:Int32(1), true_target:block2, false_target:block1
block1:
[ 10] JumpStrictlyEquals lhs:Int32(1), rhs:Int32(1), true_target:block3, false_target:block2
block2:
[ 28] End value:reg5
block3:
block2:
[ 30] Mov2 dst1:reg5, src1:String("hello"), dst2:x~0, src2:Int32(1)
block4:
[ 48] End value:reg5
eval$6559f0fb line 1, column 1
Registers: 7
Blocks: 5
Blocks: 3
Constants:
[0] = Undefined
[1] = Int32(1)
@ -62,23 +58,19 @@ eval$6559f0fb line 1, column 1
block0:
[ 0] Mov dst:reg5, src:Undefined
[ 10] JumpStrictlyEquals lhs:Int32(1), rhs:Int32(1), true_target:block2, false_target:block1
block1:
[ 10] JumpStrictlyEquals lhs:Int32(1), rhs:Int32(1), true_target:block3, false_target:block2
block2:
[ 28] End value:reg5
block3:
block2:
[ 30] Mov2 dst1:reg5, src1:String("first"), dst2:reg5, src2:String("second")
block4:
[ 48] End value:reg5
eval$6da5c42b line 1, column 1
Registers: 7
Blocks: 6
Blocks: 4
Constants:
[0] = Undefined
[1] = Int32(1)
@ -87,21 +79,17 @@ eval$6da5c42b line 1, column 1
block0:
[ 0] Mov dst:reg5, src:Undefined
[ 10] JumpStrictlyEquals lhs:Int32(1), rhs:Int32(1), true_target:block2, false_target:block1
block1:
[ 10] JumpStrictlyEquals lhs:Int32(1), rhs:Int32(1), true_target:block3, false_target:block2
[ 28] Jump target:block3
block2:
[ 28] Jump target:block4
block3:
[ 30] Mov dst:reg5, src:String("matched")
[ 40] End value:reg5
block4:
block3:
[ 48] Mov dst:reg5, src:String("default")
block5:
[ 58] End value:reg5

View file

@ -22,7 +22,7 @@ block0:
switchWithBlockDecl$4f465f02 switch-scoping.js:2:5
Registers: 7
Blocks: 7
Blocks: 6
Locals: result~0
Constants:
[0] = Undefined
@ -37,28 +37,26 @@ block0:
[ 18] CreateLexicalEnvironment dst:reg5, parent:reg4, capacity:0
[ 28] CreateMutableBinding environment:reg5, `a`, can_be_deleted:false
[ 38] CreateMutableBinding environment:reg5, `b`, can_be_deleted:false
[ 48] JumpStrictlyEquals lhs:Int32(1), rhs:arg0, true_target:block3, false_target:block1
block1:
[ 48] JumpStrictlyEquals lhs:Int32(1), rhs:arg0, true_target:block4, false_target:block2
[ 60] JumpStrictlyEquals lhs:Int32(2), rhs:arg0, true_target:block4, false_target:block2
block2:
[ 60] JumpStrictlyEquals lhs:Int32(2), rhs:arg0, true_target:block5, false_target:block3
[ 78] Jump target:block5
block3:
[ 78] Jump target:block6
block4:
[ 80] InitializeLexicalBinding `a`, src:String("one")
[ 98] NewFunction dst:reg6, shared_function_data_index:0 (result)
[ b0] Mov dst:result~0, src:reg6
[ c0] Jump target:block6
[ c0] Jump target:block5
block5:
block4:
[ c8] InitializeLexicalBinding `b`, src:String("two")
[ e0] NewFunction dst:reg6, shared_function_data_index:1 (result)
[ f8] Mov dst:result~0, src:reg6
block6:
block5:
[ 108] SetLexicalEnvironment environment:reg4
[ 110] Call dst:reg5, callee:result~0, this_value:Undefined, result
[ 130] Return value:reg5

View file

@ -13,7 +13,7 @@ block0:
f$055cd79c switch-with-block-scope-return.js:2:5
Registers: 8
Blocks: 8
Blocks: 7
Constants:
[0] = Int32(1)
[1] = Int32(2)
@ -26,31 +26,29 @@ block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] CreateLexicalEnvironment dst:reg5, parent:reg4, capacity:0
[ 18] CreateImmutableBinding environment:reg5, `y`, strict_binding:true
[ 28] JumpStrictlyEquals lhs:Int32(1), rhs:arg0, true_target:block3, false_target:block1
block1:
[ 28] JumpStrictlyEquals lhs:Int32(1), rhs:arg0, true_target:block4, false_target:block2
[ 40] JumpStrictlyEquals lhs:Int32(2), rhs:arg0, true_target:block4, false_target:block2
block2:
[ 40] JumpStrictlyEquals lhs:Int32(2), rhs:arg0, true_target:block5, false_target:block3
[ 58] Jump target:block5
block3:
[ 58] Jump target:block6
block4:
[ 60] SetLexicalEnvironment environment:reg4
[ 68] Return value:String("one")
block5:
block4:
[ 70] InitializeLexicalBinding `y`, src:String("two")
[ 88] NewFunction dst:reg7, shared_function_data_index:0
[ a0] Call dst:reg6, callee:reg7, this_value:Undefined
[ c0] SetLexicalEnvironment environment:reg4
[ c8] Return value:reg6
block6:
block5:
[ d0] SetLexicalEnvironment environment:reg4
[ d8] Return value:String("other")
block7:
block6:
[ e0] SetLexicalEnvironment environment:reg4
[ e8] End value:Undefined

View file

@ -1,6 +1,6 @@
$80aea387 this-base-identifier.js:16:1
Registers: 10
Blocks: 4
Blocks: 3
Constants:
[0] = Undefined
@ -10,17 +10,15 @@ block0:
[ 20] Call dst:reg5, callee:reg6, this_value:Undefined, get_from_this
[ 40] GetGlobal dst:reg7, `set_on_this`
[ 58] Call dst:reg6, callee:reg7, this_value:Undefined, set_on_this
[ 78] Jump target:block3
[ 78] Jump target:block2
block1:
[ 80] Catch dst:reg5
[ 88] SetLexicalEnvironment environment:reg4
[ 90] Mov2 dst1:reg7, src1:Undefined, dst2:reg8, src2:reg7
block2:
[ a8] End value:reg7
block3:
block2:
[ b0] Mov dst:reg5, src:Undefined
[ c0] GetGlobal dst:reg9, `chained_this_access`
[ d8] Call dst:reg7, callee:reg9, this_value:Undefined, chained_this_access

View file

@ -1,6 +1,6 @@
$63c57e75 try-catch-completion-ordering.js:1:1
Registers: 8
Blocks: 4
Blocks: 3
Locals: e~0
Constants:
[0] = Undefined
@ -9,18 +9,16 @@ $63c57e75 try-catch-completion-ordering.js:1:1
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] Jump target:block3
[ 8] Jump target:block2
block1:
[ 10] Catch dst:reg5
[ 18] SetLexicalEnvironment environment:reg4
[ 20] Mov3 dst1:e~0, src1:reg5, dst2:reg6, src2:Undefined, dst3:reg6, src3:Int32(42)
[ 40] Mov dst:reg7, src:reg6
block2:
[ 50] End value:reg7
block3:
block2:
[ 58] Mov dst:reg5, src:Undefined
[ 68] Throw src:Null

View file

@ -14,7 +14,7 @@ block0:
tryCatchWithBlocks$fc7f9ac0 try-catch-scoping.js:2:5
Registers: 11
Blocks: 4
Blocks: 3
Locals: y~0, z~1, e~2, x~3
Constants:
[0] = Int32(1)
@ -25,7 +25,7 @@ tryCatchWithBlocks$fc7f9ac0 try-catch-scoping.js:2:5
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] Mov dst:x~3, src:Int32(1)
[ 18] Jump target:block3
[ 18] Jump target:block2
block1:
[ 20] Catch dst:reg5
@ -36,11 +36,9 @@ block1:
[ 80] Add dst:reg9, lhs:x~3, rhs:e~2
[ 90] Add dst:reg10, lhs:reg9, rhs:z~1
[ a0] Call dst:reg6, callee:reg8, this_value:reg7, console.log, arguments:[reg10]
block2:
[ c8] End value:Undefined
block3:
block2:
[ d0] Mov dst:y~0, src:Int32(2)
[ e0] Throw src:y~0

View file

@ -1,23 +1,21 @@
$84f4cb35 using-declaration-non-local-env.js:1:1
Registers: 9
Blocks: 4
Blocks: 3
Locals: e~0
Constants:
[0] = Undefined
block0:
[ 0] GetLexicalEnvironment dst:reg4
[ 8] Jump target:block3
[ 8] Jump target:block2
block1:
[ 10] Catch dst:reg5
[ 18] SetLexicalEnvironment environment:reg4
[ 20] Mov3 dst1:e~0, src1:reg5, dst2:reg6, src2:Undefined, dst3:reg7, src3:reg6
block2:
[ 40] End value:reg6
block3:
block2:
[ 48] Mov dst:reg5, src:Undefined
[ 58] NewFunction dst:reg8, shared_function_data_index:0
[ 70] Call dst:reg6, callee:reg8, this_value:Undefined