Files
ladybird/Tests/LibJS/Bytecode/expected/nested-function-decl-source-order.txt
Andreas Kling 010deec578 LibJS: Build functions_to_initialize in source order
ECMAScript hoisting keeps the LAST function declaration with a given
name. The Rust scope_collector and script GDI extraction implemented
this with a single reverse scan that pushed first-seen entries, which
left the resulting list in REVERSE source order. The C++ side then
iterated `m_functions_to_initialize.in_reverse()` to undo that.

Switch the Rust side to a two-pass forward scan that records the last
position per name and emits entries in source order, and drop the
matching `.in_reverse()` calls in Script.cpp and AbstractOperations.cpp.
Same hoisting semantics; NewFunction emission and global property
iteration order now follow the source.

The HashMap that tracks last positions is keyed on `SharedUtf16String`,
so each insert is a refcount bump on the AST's existing Rc instead of
a deep `Vec<u16>` clone.

Add bytecode tests at script and nested-function scope that exercise
multiple declarations and a duplicate name to pin the new ordering.
2026-04-27 08:04:11 +02:00

94 lines
2.5 KiB
Plaintext

$54f8ba98 nested-function-decl-source-order.js:15:1
Registers: 11
Blocks: 1
Constants:
[0] = Undefined
[1] = String(",")
block0:
[ 0] GetGlobal dst:reg6, `console`
[ 18] GetById dst:reg7, base:reg6, `log` (console.log)
[ 38] GetGlobal dst:reg10, `outer`
[ 50] Call dst:reg9, callee:reg10, this_value:Undefined, outer
[ 70] GetById dst:reg10, base:reg9, `join`
[ 90] Call dst:reg8, callee:reg10, this_value:reg9, <object>.join, arguments:[String(",")]
[ b8] Call dst:reg5, callee:reg7, this_value:reg6, console.log, arguments:[reg8]
[ e0] End value:reg5
outer$541206d9 nested-function-decl-source-order.js:12:5
Registers: 11
Blocks: 1
Locals: alpha~0, beta~1, delta~2, dup~3, gamma~4
Constants:
[0] = Undefined
block0:
[ 0] Mov3 dst1:alpha~0, src1:Undefined, dst2:beta~1, src2:Undefined, dst3:delta~2, src3:Undefined
[ 20] Mov2 dst1:dup~3, src1:Undefined, dst2:gamma~4, src2:Undefined
[ 38] NewFunction dst:alpha~0, shared_function_data_index:0
[ 50] NewFunction dst:beta~1, shared_function_data_index:1
[ 68] NewFunction dst:gamma~4, shared_function_data_index:2
[ 80] NewFunction dst:dup~3, shared_function_data_index:3
[ 98] NewFunction dst:delta~2, shared_function_data_index:4
[ b0] Call dst:reg5, callee:alpha~0, this_value:Undefined, alpha
[ d0] Call dst:reg6, callee:beta~1, this_value:Undefined, beta
[ f0] Call dst:reg7, callee:gamma~4, this_value:Undefined, gamma
[ 110] Call dst:reg8, callee:delta~2, this_value:Undefined, delta
[ 130] Call dst:reg9, callee:dup~3, this_value:Undefined, dup
[ 150] NewArray dst:reg10, elements:[reg5, reg6, reg7, reg8, reg9]
[ 178] Return value:reg10
alpha$3b8324cd nested-function-decl-source-order.js:6:24
Registers: 5
Blocks: 1
Constants:
[0] = Int32(1)
block0:
[ 0] Return value:Int32(1)
beta$d739d7c6 nested-function-decl-source-order.js:7:23
Registers: 5
Blocks: 1
Constants:
[0] = Int32(2)
block0:
[ 0] Return value:Int32(2)
gamma$09aead7f nested-function-decl-source-order.js:9:24
Registers: 5
Blocks: 1
Constants:
[0] = Int32(3)
block0:
[ 0] Return value:Int32(3)
delta$240367f0 nested-function-decl-source-order.js:11:24
Registers: 5
Blocks: 1
Constants:
[0] = Int32(4)
block0:
[ 0] Return value:Int32(4)
dup$510f266c nested-function-decl-source-order.js:10:22
Registers: 5
Blocks: 1
Constants:
[0] = String("second")
block0:
[ 0] Return value:String("second")
"1,2,3,4,second"