Skip to content

Commit b1e3fd4

Browse files
committed
fix(runtime): add block stack popping to br_table instruction
The br_table instruction was missing critical block stack management. When br_table branches to a target N levels up, it jumps over the End instructions of N intermediate blocks. Those blocks must be popped from the block tracking stack, just like the br instruction does. Without this fix, loops in compiled Rust code (like core::fmt::write) would only execute once because br 0 targeted the wrong block due to extra blocks remaining on the stack.
1 parent 012df8e commit b1e3fd4

File tree

1 file changed

+61
-2
lines changed

1 file changed

+61
-2
lines changed

wrt-runtime/src/stackless/engine.rs

Lines changed: 61 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1390,6 +1390,12 @@ impl StacklessEngine {
13901390
let value = locals[local_idx as usize].clone();
13911391
#[cfg(feature = "tracing")]
13921392
trace!("LocalGet: local[{}] = {:?}", local_idx, value);
1393+
// Debug: trace LocalGet in function 222 for key locals (0=pieces, 2=Arguments)
1394+
#[cfg(feature = "std")]
1395+
if func_idx == 222 && (local_idx == 0 || local_idx == 2) {
1396+
eprintln!("[LOCALGET-222] pc={}, local[{}] = {:?}",
1397+
pc, local_idx, value);
1398+
}
13931399
#[cfg(feature = "std")]
13941400
{
13951401
// Debug suspicious values that might be bad pointers
@@ -1412,6 +1418,12 @@ impl StacklessEngine {
14121418
#[cfg(feature = "tracing")]
14131419

14141420
trace!("LocalSet: setting local[{}] = {:?}", local_idx, value);
1421+
// Debug: trace LocalSet in function 222 (core::fmt::write)
1422+
#[cfg(feature = "std")]
1423+
if func_idx == 222 {
1424+
eprintln!("[LOCALSET-222] pc={}, local[{}] = {:?}",
1425+
pc, local_idx, value);
1426+
}
14151427
if (local_idx as usize) < locals.len() {
14161428
locals[local_idx as usize] = value;
14171429
} else {
@@ -1431,6 +1443,12 @@ impl StacklessEngine {
14311443
#[cfg(feature = "tracing")]
14321444

14331445
trace!("LocalTee: setting local[{}] = {:?} (keeping on stack)", local_idx, value);
1446+
// Debug: trace LocalTee in function 222 (core::fmt::write)
1447+
#[cfg(feature = "std")]
1448+
if func_idx == 222 {
1449+
eprintln!("[LOCALTEE-222] pc={}, local[{}] = {:?}",
1450+
pc, local_idx, value);
1451+
}
14341452
if (local_idx as usize) < locals.len() {
14351453
locals[local_idx as usize] = value;
14361454
} else {
@@ -2373,8 +2391,8 @@ impl StacklessEngine {
23732391
if (offset >= 0xffd60 && offset <= 0xffdd0) ||
23742392
(offset >= 0x1076c0 && offset <= 0x1077f0) ||
23752393
(offset >= 0x1023c0 && offset <= 0x102400) {
2376-
eprintln!("[I32Load-ARGDATA] offset=0x{:x}, value=0x{:x} ({})",
2377-
offset, value as u32, value);
2394+
eprintln!("[I32Load-ARGDATA] func={}, pc={}, offset=0x{:x}, value=0x{:x} ({})",
2395+
func_idx, pc, offset, value as u32, value);
23782396
}
23792397
// Debug: trace reads from datetime region
23802398
#[cfg(feature = "std")]
@@ -3146,6 +3164,11 @@ impl StacklessEngine {
31463164
if func_idx == 76 {
31473165
eprintln!("[BLOCK] func_idx=76, pc={}, block_depth={}", pc, block_depth);
31483166
}
3167+
// Trace block entry in func 222
3168+
#[cfg(feature = "std")]
3169+
if func_idx == 222 {
3170+
eprintln!("[BLOCK-222] pc={}, block_depth={}", pc, block_depth);
3171+
}
31493172
// Just execute through the block - End will decrement depth
31503173
}
31513174
Instruction::Loop { block_type_idx } => {
@@ -3158,11 +3181,25 @@ impl StacklessEngine {
31583181
if func_idx == 76 {
31593182
eprintln!("[LOOP] func_idx=76, pc={}, block_depth={}", pc, block_depth);
31603183
}
3184+
// Trace loop entry in func 222
3185+
#[cfg(feature = "std")]
3186+
if func_idx == 222 {
3187+
eprintln!("[LOOP-222] pc={}, block_depth={}", pc, block_depth);
3188+
}
31613189
// Just execute through - Br will handle jumping back to start
31623190
}
31633191
Instruction::Br(label_idx) => {
31643192
#[cfg(feature = "tracing")]
31653193
trace!("Br: label_idx={} (unconditional branch)", label_idx);
3194+
// Trace Br in func 222
3195+
#[cfg(feature = "std")]
3196+
if func_idx == 222 {
3197+
eprintln!("[BR-222] pc={}, label_idx={}, block_depth={}, block_stack.len()={}",
3198+
pc, label_idx, block_depth, block_stack.len());
3199+
for (i, (btype, bpc, _, _)) in block_stack.iter().enumerate() {
3200+
eprintln!("[BR-222] block_stack[{}]: {} at pc={}", i, btype, bpc);
3201+
}
3202+
}
31663203
// Trace Br in func 76 (extend_desugared)
31673204
#[cfg(feature = "std")]
31683205
if func_idx == 76 {
@@ -3325,6 +3362,12 @@ impl StacklessEngine {
33253362
eprintln!("[BRIF-211] pc={}, label_idx={}, condition={} (from_utf8_result), will_branch={}",
33263363
pc, label_idx, condition, condition != 0);
33273364
}
3365+
// Trace BrIf in func 222 (core::fmt::write)
3366+
#[cfg(feature = "std")]
3367+
if func_idx == 222 {
3368+
eprintln!("[BRIF-222] pc={}, label_idx={}, condition={}, will_branch={}",
3369+
pc, label_idx, condition, condition != 0);
3370+
}
33283371
if condition != 0 {
33293372
// Branch conditionally - same logic as Br
33303373
if (label_idx as usize) < block_stack.len() {
@@ -3690,6 +3733,16 @@ impl StacklessEngine {
36903733
let _ = operand_stack.pop();
36913734
}
36923735

3736+
// Pop all inner blocks from the stack since we're jumping over
3737+
// their End instructions (same as Br instruction logic)
3738+
let blocks_to_pop = label_idx as usize;
3739+
for _ in 0..blocks_to_pop {
3740+
if !block_stack.is_empty() {
3741+
block_stack.pop();
3742+
block_depth -= 1;
3743+
}
3744+
}
3745+
36933746
if block_type == "loop" {
36943747
// For Loop: jump backward to the loop start
36953748
#[cfg(feature = "tracing")]
@@ -3791,6 +3844,12 @@ impl StacklessEngine {
37913844
if func_idx == 76 {
37923845
eprintln!("[END] func_idx=76, pc={}, closes {} from pc={}, block_depth={}", pc, block_type, start_pc, block_depth);
37933846
}
3847+
// Trace End in func 222
3848+
#[cfg(feature = "std")]
3849+
if func_idx == 222 {
3850+
eprintln!("[END-222] pc={}, closes {} from pc={}, block_depth={}, block_stack.len()={}",
3851+
pc, block_type, start_pc, block_depth, block_stack.len());
3852+
}
37943853
} else {
37953854
#[cfg(feature = "tracing")]
37963855
trace!("End at pc={} (closes block, depth now {})", pc, block_depth);

0 commit comments

Comments
 (0)