Skip to content

Commit 55786ce

Browse files
authored
feat(vm): explicit call frame boundaries (#5010)
This Pull Request fixes/closes [#4986](#4986) It changes the following: - Trace a new call frame whenever a new frame is pushed onto the stack. - Ensure each code block’s compiled output is printed only once.
1 parent c0a01d4 commit 55786ce

File tree

3 files changed

+22
-27
lines changed

3 files changed

+22
-27
lines changed

core/engine/src/bytecompiler/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2656,6 +2656,8 @@ impl<'ctx> ByteCompiler<'ctx> {
26562656
global_fns: self.global_fns.into_boxed_slice(),
26572657
global_vars: self.global_vars.into_boxed_slice(),
26582658
debug_id: CodeBlock::get_next_codeblock_id(),
2659+
#[cfg(feature = "trace")]
2660+
traced: Cell::new(false),
26592661
}
26602662
}
26612663

core/engine/src/vm/code_block.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,10 @@ pub struct CodeBlock {
168168

169169
// Used for identifying anonymous functions in compiled output and call frames.
170170
pub(crate) debug_id: u64,
171+
172+
#[cfg(feature = "trace")]
173+
#[unsafe_ignore_trace]
174+
pub(crate) traced: Cell<bool>,
171175
}
172176

173177
/// ---- `CodeBlock` public API ----
@@ -198,6 +202,8 @@ impl CodeBlock {
198202
global_fns: Box::default(),
199203
global_vars: Box::default(),
200204
debug_id: CodeBlock::get_next_codeblock_id(),
205+
#[cfg(feature = "trace")]
206+
traced: Cell::new(false),
201207
}
202208
}
203209

core/engine/src/vm/mod.rs

Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ pub struct Vm {
100100

101101
#[cfg(feature = "trace")]
102102
pub(crate) trace: bool,
103+
#[cfg(feature = "trace")]
104+
pub(crate) current_frame: Option<*const CallFrame>,
103105
}
104106

105107
/// The stack holds the [`JsValue`]s for the calling convention and registers.
@@ -336,6 +338,8 @@ impl Vm {
336338
shadow_stack: ShadowStack::default(),
337339
#[cfg(feature = "trace")]
338340
trace: false,
341+
#[cfg(feature = "trace")]
342+
current_frame: None,
339343
}
340344
}
341345

@@ -608,7 +612,11 @@ impl Context {
608612
)
609613
};
610614

611-
println!("{}", frame.code_block);
615+
// Only print a functions compiled output if it has not been printed already
616+
if !frame.code_block.traced.get() {
617+
println!("{}", frame.code_block);
618+
frame.code_block.traced.set(true);
619+
}
612620
println!(
613621
"{msg:-^width$}",
614622
width = Self::COLUMN_WIDTH * Self::NUMBER_OF_COLUMNS - 10
@@ -632,6 +640,11 @@ impl Context {
632640
where
633641
F: FnOnce(&mut Context, Opcode) -> ControlFlow<CompletionRecord>,
634642
{
643+
if self.vm.current_frame != Some(self.vm.frame()) {
644+
println!();
645+
self.trace_call_frame();
646+
self.vm.current_frame = Some(self.vm.frame());
647+
}
635648
let frame = self.vm.frame();
636649
let (instruction, _) = frame
637650
.code_block
@@ -643,22 +656,6 @@ impl Context {
643656
.code_block()
644657
.instruction_operands(&instruction);
645658

646-
match opcode {
647-
Opcode::Call
648-
| Opcode::CallSpread
649-
| Opcode::CallEval
650-
| Opcode::CallEvalSpread
651-
| Opcode::New
652-
| Opcode::NewSpread
653-
| Opcode::Return
654-
| Opcode::SuperCall
655-
| Opcode::SuperCallSpread
656-
| Opcode::SuperCallDerived => {
657-
println!();
658-
}
659-
_ => {}
660-
}
661-
662659
let instant = Instant::now();
663660
let result = self.execute_instruction(f, opcode);
664661
let duration = instant.elapsed();
@@ -855,11 +852,6 @@ impl Context {
855852
/// "clock cycles" have passed.
856853
#[allow(clippy::future_not_send)]
857854
pub(crate) async fn run_async_with_budget(&mut self, budget: u32) -> CompletionRecord {
858-
#[cfg(feature = "trace")]
859-
if self.vm.trace {
860-
self.trace_call_frame();
861-
}
862-
863855
let mut runtime_budget: u32 = budget;
864856

865857
while let Some(byte) = self
@@ -895,11 +887,6 @@ impl Context {
895887
}
896888

897889
pub(crate) fn run(&mut self) -> CompletionRecord {
898-
#[cfg(feature = "trace")]
899-
if self.vm.trace {
900-
self.trace_call_frame();
901-
}
902-
903890
while let Some(byte) = self
904891
.vm
905892
.frame()

0 commit comments

Comments
 (0)