mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-05-11 17:37:33 +02:00
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.
94 lines
2.5 KiB
Plaintext
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"
|