Skip to content

Commit 58ca1b2

Browse files
committed
Switch to trait based
1 parent 54050c0 commit 58ca1b2

File tree

5 files changed

+140
-113
lines changed

5 files changed

+140
-113
lines changed

boa_engine/src/context/mod.rs

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ pub use maybe_shared::MaybeShared;
1616
pub use std::marker::PhantomData;
1717
use std::{io::Read, path::Path, rc::Rc};
1818

19+
#[cfg(feature = "trace")]
20+
use crate::vm::trace;
21+
1922
use crate::{
2023
builtins,
2124
class::{Class, ClassBuilder},
@@ -380,38 +383,23 @@ impl<'host> Context<'host> {
380383
#[inline]
381384
/// Initializes a `Vm` trace from the context
382385
pub fn init_trace(&mut self) {
383-
let trace = crate::vm::trace::VmTrace::default();
386+
let trace = trace::VmTrace::default();
384387
self.vm.set_trace(trace);
385388
}
386389

387390
#[cfg(feature = "trace")]
388391
#[inline]
389392
/// Initializes a partial `Vm` trace from the context.
390393
pub fn init_partial_trace(&mut self) {
391-
let trace = crate::vm::trace::VmTrace::partial();
392-
self.vm.set_trace(trace);
393-
}
394-
395-
#[cfg(feature = "trace")]
396-
/// Initialize a provided custom trace
397-
pub fn set_custom_trace(&mut self, trace: crate::vm::trace::VmTrace) {
394+
let trace = trace::VmTrace::partial();
398395
self.vm.set_trace(trace);
399396
}
400397

401398
#[cfg(feature = "trace")]
402-
/// Sets custom handling of compilation trace output
403-
pub fn set_custom_compile_trace(&mut self, f: Box<dyn Fn(&str)>) {
404-
if let Some(trace) = &mut self.vm.trace {
405-
trace.set_compiled_action(f);
406-
}
407-
}
408-
409-
#[cfg(feature = "trace")]
410-
/// Sets custom handling of trace action.
411-
pub fn set_custom_runtime_trace(&mut self, f: Box<dyn Fn(&str)>) {
412-
if let Some(trace) = &mut self.vm.trace {
413-
trace.set_trace_action(f);
414-
}
399+
/// Sets custom handling of trace messages.
400+
pub fn set_tracer_implementation(&mut self, tracer: Box<dyn trace::Tracer>) {
401+
let trace = trace::VmTrace::default().with_tracer(tracer);
402+
self.vm.trace = Some(trace);
415403
}
416404

417405
/// Get optimizer options.

boa_engine/src/vm/code_block.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,10 @@ bitflags! {
7373
}
7474
}
7575

76+
#[cfg(feature = "trace")]
7677
bitflags! {
7778
/// Trace specific flags for [`CodeBlock`]
7879
#[derive(Clone, Copy, Debug, Finalize)]
79-
#[cfg(feature = "trace")]
8080
pub(crate) struct TraceFlags: u8 {
8181
/// Trace instruction execution to `stdout`.
8282
const TRACEABLE = 0b0000_0001;
@@ -133,6 +133,7 @@ pub struct CodeBlock {
133133
#[unsafe_ignore_trace]
134134
pub(crate) flags: Cell<CodeBlockFlags>,
135135

136+
#[cfg(feature = "trace")]
136137
#[unsafe_ignore_trace]
137138
pub(crate) trace_flags: Cell<TraceFlags>,
138139

@@ -182,8 +183,10 @@ impl CodeBlock {
182183
pub fn new(name: JsString, length: u32, strict: bool) -> Self {
183184
let mut flags = CodeBlockFlags::empty();
184185
flags.set(CodeBlockFlags::STRICT, strict);
186+
185187
#[cfg(feature = "trace")]
186188
let t_flags = TraceFlags::empty();
189+
187190
Self {
188191
bytecode: Box::default(),
189192
literals: Box::default(),

boa_engine/src/vm/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ mod runtime_limits;
3232
#[cfg(feature = "flowgraph")]
3333
pub mod flowgraph;
3434

35+
#[cfg(feature = "trace")]
36+
use trace::VmTrace;
37+
3538
pub use runtime_limits::RuntimeLimits;
3639

37-
use self::vm_trace::VmTrace;
3840
pub use {
3941
call_frame::{CallFrame, GeneratorResumeKind},
4042
code_block::CodeBlock,

boa_engine/src/vm/trace.rs

Lines changed: 59 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,41 @@ use boa_interner::{Interner, ToInternedString};
99

1010
use super::Vm;
1111

12+
// TODO: Build out further, maybe provide more element visiblity and events/outputs
13+
/// The `Tracer` trait is a customizable trait that can be provided to `Boa`
14+
/// for customizing output.
15+
pub trait Tracer {
16+
/// The output from tracing a `CodeBlock`'s bytecode.
17+
fn emit_bytecode_trace(&self, msg: &str);
18+
/// The output from entering a `CallFrame`.
19+
fn emit_call_frame_entrance_trace(&self, msg: &str);
20+
/// The trace output from an execution.
21+
fn emit_instruction_trace(&self, msg: &str);
22+
/// Trace output from exiting a `CallFrame`.
23+
fn emit_call_frame_exit_trace(&self, msg: &str);
24+
}
25+
26+
#[derive(Debug)]
27+
pub(crate) struct DefaultTracer;
28+
29+
impl Tracer for DefaultTracer {
30+
fn emit_bytecode_trace(&self, msg: &str) {
31+
println!("{msg}");
32+
}
33+
34+
fn emit_call_frame_entrance_trace(&self, msg: &str) {
35+
println!("{msg}");
36+
}
37+
38+
fn emit_instruction_trace(&self, msg: &str) {
39+
println!("{msg}");
40+
}
41+
42+
fn emit_call_frame_exit_trace(&self, msg: &str) {
43+
println!("{msg}");
44+
}
45+
}
46+
1247
bitflags! {
1348
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1449
pub(crate) struct TraceOptions: u8 {
@@ -28,16 +63,12 @@ impl Vm {
2863
impl Default for VmTrace {
2964
fn default() -> Self {
3065
Self {
31-
compiled_action: None,
32-
trace_action: None,
3366
options: Cell::new(TraceOptions::FULL_TRACE),
67+
tracer: Box::new(DefaultTracer),
3468
}
3569
}
3670
}
3771

38-
// Action function provided by the user.
39-
type ActionFunction = Box<dyn Fn(&str)>;
40-
4172
/// `VmTrace` is a boa spcific structure for running Boa's Virtual Machine trace.
4273
///
4374
/// The struct provides options for a user to set customized actions for handling
@@ -52,9 +83,8 @@ type ActionFunction = Box<dyn Fn(&str)>;
5283
/// After the Global callframe is initially provided. It searches
5384
/// for all possible compiled output
5485
pub struct VmTrace {
55-
compiled_action: Option<ActionFunction>,
56-
trace_action: Option<ActionFunction>,
5786
options: Cell<TraceOptions>,
87+
tracer: Box<dyn Tracer>,
5888
}
5989

6090
// ==== Public API ====
@@ -64,34 +94,21 @@ impl VmTrace {
6494
/// Create a partial `VmTrace`.
6595
pub fn partial() -> Self {
6696
Self {
67-
compiled_action: None,
68-
trace_action: None,
6997
options: Cell::new(TraceOptions::empty()),
98+
tracer: Box::new(DefaultTracer),
7099
}
71100
}
72101

73102
#[must_use]
74103
/// Method for adding a compiled action on initialization.
75-
pub fn with_compiled_action(mut self, f: ActionFunction) -> Self {
76-
self.set_compiled_action(f);
104+
pub fn with_tracer(mut self, tracer: Box<dyn Tracer>) -> Self {
105+
self.set_tracer(tracer);
77106
self
78107
}
79108

80-
#[must_use]
81-
/// Method for adding a trace action on initialization.
82-
pub fn with_trace_action(mut self, f: ActionFunction) -> Self {
83-
self.set_trace_action(f);
84-
self
85-
}
86-
87-
/// Sets the `compiled_action` of `VmTrace` to a custom user-defined action.
88-
pub fn set_compiled_action(&mut self, f: ActionFunction) {
89-
self.compiled_action = Some(f);
90-
}
91-
92-
/// Sets the `trace_action` of `VmTrace` to a custom user-defined action.
93-
pub fn set_trace_action(&mut self, f: ActionFunction) {
94-
self.trace_action = Some(f);
109+
/// Sets the current `Tracer` of `VmTrace`.
110+
pub fn set_tracer(&mut self, tracer: Box<dyn Tracer>) {
111+
self.tracer = tracer;
95112
}
96113
}
97114

@@ -133,32 +150,15 @@ impl VmTrace {
133150
}
134151
}
135152

136-
// ---- Trace Event/Action Methods ----
153+
// ==== Trace Event/Action Methods ====
154+
137155
impl VmTrace {
138156
const COLUMN_WIDTH: usize = 26;
139157
const TIME_COLUMN_WIDTH: usize = Self::COLUMN_WIDTH / 2;
140158
const OPCODE_COLUMN_WIDTH: usize = Self::COLUMN_WIDTH;
141159
const OPERAND_COLUMN_WIDTH: usize = Self::COLUMN_WIDTH;
142160
const NUMBER_OF_COLUMNS: usize = 4;
143161

144-
pub(crate) fn trigger_compiled_output_action(&self, msg: &str) {
145-
if let Some(action) = &self.compiled_action {
146-
action(&format!("{msg}\n"));
147-
} else {
148-
println!("{msg}");
149-
}
150-
}
151-
152-
pub(crate) fn trigger_trace_action(&self, msg: &str) {
153-
if let Some(action) = &self.trace_action {
154-
action(&format!("{msg}\n"));
155-
} else {
156-
println!("{msg}");
157-
}
158-
}
159-
}
160-
161-
impl VmTrace {
162162
/// Trace the current `CallFrame` according to current state
163163
pub(crate) fn trace_call_frame(&self, vm: &Vm, interner: &Interner) {
164164
if self.is_full_trace() {
@@ -187,7 +187,7 @@ impl VmTrace {
187187
"{msg:-^width$}",
188188
width = Self::COLUMN_WIDTH * Self::NUMBER_OF_COLUMNS - 10
189189
);
190-
self.trigger_trace_action(&frame_header);
190+
self.tracer.emit_call_frame_entrance_trace(&frame_header);
191191

192192
if vm.frames.len() == 1 {
193193
let column_headers = format!(
@@ -200,7 +200,7 @@ impl VmTrace {
200200
OPERAND_COLUMN_WIDTH = Self::OPERAND_COLUMN_WIDTH,
201201
);
202202

203-
self.trigger_trace_action(&column_headers);
203+
self.tracer.emit_call_frame_entrance_trace(&column_headers);
204204
}
205205
}
206206

@@ -216,26 +216,31 @@ impl VmTrace {
216216

217217
queue.extend(block.functions.iter().cloned());
218218

219-
self.trigger_compiled_output_action(&block.to_interned_string(interner));
219+
self.tracer
220+
.emit_bytecode_trace(&block.to_interned_string(interner));
220221
}
221222
}
222223
}
223224

224225
/// Searches and traces for only current frame's `CodeBlock`.
225226
pub(crate) fn trace_current_bytecode(&self, vm: &Vm, interner: &Interner) {
226-
self.trigger_compiled_output_action(&vm.frame().code_block().to_interned_string(interner));
227+
self.tracer
228+
.emit_bytecode_trace(&vm.frame().code_block().to_interned_string(interner));
227229
}
228230

229231
/// Emits an exit message for the current `CallFrame`.
230232
pub(crate) fn trace_frame_end(&self, vm: &Vm, return_msg: &str) {
231233
if self.should_trace() {
232-
let msg = format!(" Call Frame -- <Exiting {} via {return_msg}> ", vm.frame().code_block().name.to_std_string_escaped());
234+
let msg = format!(
235+
" Call Frame -- <Exiting {} via {return_msg}> ",
236+
vm.frame().code_block().name.to_std_string_escaped()
237+
);
233238
let frame_footer = format!(
234239
"{msg:-^width$}",
235240
width = Self::COLUMN_WIDTH * Self::NUMBER_OF_COLUMNS - 10
236241
);
237242

238-
self.trigger_trace_action(&frame_footer);
243+
self.tracer.emit_call_frame_exit_trace(&frame_footer);
239244
}
240245

241246
self.inactivate();
@@ -253,7 +258,7 @@ impl VmTrace {
253258
OPERAND_COLUMN_WIDTH = Self::OPERAND_COLUMN_WIDTH,
254259
);
255260

256-
self.trigger_trace_action(&instruction_trace);
261+
self.tracer.emit_instruction_trace(&instruction_trace);
257262
}
258263

259264
#[cfg(not(target_arch = "wasm32"))]
@@ -273,27 +278,12 @@ impl VmTrace {
273278
OPERAND_COLUMN_WIDTH = Self::OPERAND_COLUMN_WIDTH,
274279
);
275280

276-
self.trigger_trace_action(&instruction_trace);
281+
self.tracer.emit_instruction_trace(&instruction_trace);
277282
}
278283
}
279284

280285
impl fmt::Debug for VmTrace {
281286
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
282-
let compiled_action_val = if self.compiled_action.is_none() {
283-
"None"
284-
} else {
285-
"User Defined Fn"
286-
};
287-
288-
let trace_action_val = if self.trace_action.is_none() {
289-
"None"
290-
} else {
291-
"User Defined Fn"
292-
};
293-
294-
f.debug_struct("VmTrace")
295-
.field("Compiled Action", &compiled_action_val)
296-
.field("Runtime Trace Action", &trace_action_val)
297-
.finish()
287+
write!(f, "Current Active Tracer")
298288
}
299289
}

0 commit comments

Comments
 (0)