feat: 为 VM 添加结构化日志

This commit is contained in:
爱特每羊队
2026-06-26 20:50:05 +08:00
parent e730d0fd2d
commit b986a8f229
18 changed files with 297 additions and 34 deletions
+28 -5
View File
@@ -1,4 +1,5 @@
use crate::vm::{FrameContinuation, TryHandler, Vm};
use crate::vm_trace;
use oxide_bytecode::opcode;
use oxide_types::object::PropAttributes;
use oxide_types::value::JsValue;
@@ -76,6 +77,7 @@ impl Vm {
}
pub(crate) fn dispatch_define_accessor(&mut self, rd: usize, a: usize, b: usize) -> Result<(), String> {
vm_trace!("DEFINE_ACCESSOR rd={} getter={} setter={}", rd, a, b);
let prop_idx = self.bytecode[self.pc] as usize;
self.pc += 1;
if prop_idx >= self.immutables().len() {
@@ -109,13 +111,23 @@ impl Vm {
pub(crate) fn dispatch_return(&mut self, rd: usize) -> Result<Option<JsValue>, String> {
let result = self.regs[rd];
crate::vm_debug!("RETURN depth={}", self.frames.len());
crate::vm_debug!(
"RETURN depth={} saved_pc={}",
self.frames.len(),
self.frames.last().map(|f| f.return_addr).unwrap_or(0)
);
if let Some(frame) = self.frames.pop() {
let construct_result_reg = frame.construct_result_reg;
let constructed_this = frame.constructed_this;
let is_derived_constructor = frame.is_derived_constructor;
let continuation = frame.continuation;
let callee_this = self.regs[254];
vm_trace!(
"RETURN frame: continuation={:?}, derived={}, result_reg={}",
continuation,
is_derived_constructor,
rd
);
self.restore_frame(frame);
if let (Some(target_reg), Some(constructed_this)) = (construct_result_reg, constructed_this) {
if is_derived_constructor && result.is_undefined() && callee_this.is_undefined() {
@@ -124,24 +136,32 @@ impl Vm {
}
self.regs[target_reg as usize] = if result.is_object() { result } else { constructed_this };
self.regs[0] = self.regs[target_reg as usize];
vm_trace!("RETURN constructor: target_reg={} regs[0]={:?}", target_reg, self.regs[0]);
} else {
match continuation {
FrameContinuation::None => self.regs[0] = result,
FrameContinuation::AccessorGet { target_reg } => self.regs[target_reg as usize] = result,
FrameContinuation::AccessorSet => {}
FrameContinuation::AccessorGet { target_reg } => {
self.regs[target_reg as usize] = result;
vm_trace!("RETURN accessor_get: target_reg={}", target_reg);
}
FrameContinuation::AccessorSet => {
vm_trace!("RETURN accessor_set");
}
}
}
Ok(None)
} else {
vm_trace!("RETURN top-level: regs[0]={:?}", result);
Ok(Some(result))
}
}
pub(crate) fn dispatch_throw(&mut self, rd: usize) -> Result<bool, String> {
crate::vm_debug!("THROW pc={}", self.pc);
let exc_value = self.regs[rd];
let kind = self.thrown_error_kind(exc_value);
vm_trace!("THROW pc={} kind={}", self.pc, kind);
self.exception_value = Some(exc_value);
self.pending_error_kind = Some(self.thrown_error_kind(exc_value));
self.pending_error_kind = Some(kind);
self.unwind().map(|_| true)
}
@@ -161,12 +181,14 @@ impl Vm {
}
pub(crate) fn dispatch_try_end(&mut self) {
vm_trace!("TRY_END");
self.try_stack.pop();
}
pub(crate) fn dispatch_try_finally_begin(&mut self, instr: u32) {
let offset = opcode::offset16(instr) as isize;
let finally_pc = ((self.pc as isize) + offset - 1) as usize;
vm_trace!("TRY_FINALLY_BEGIN finally_pc={}", finally_pc);
self.try_stack.push(TryHandler {
catch_pc: None,
finally_pc: Some(finally_pc),
@@ -175,6 +197,7 @@ impl Vm {
}
pub(crate) fn dispatch_try_finally_end(&mut self) -> Result<bool, String> {
vm_trace!("TRY_FINALLY_END has_pending_exc={}", self.pending_exception.is_some());
self.try_stack.pop();
if self.pending_exception.is_some() && self.exception_value.is_none() {
self.exception_value = self.pending_exception.take();