From 838f216ea3eb0d27f03cb53a94e0bc161d9a493f Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Mon, 8 Jun 2026 22:11:55 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=B8=85=E7=90=86=20CallFrame=20?= =?UTF-8?q?=E6=97=A0=E6=95=88=E5=AD=97=E6=AE=B5=E5=B9=B6=E6=8E=A5=E5=85=A5?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=90=8D=E5=85=83=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_compiler/src/emitter.rs | 8 +++++-- crates/oxide_vm/src/builtins/error.rs | 32 +++++++++++++++++++++++++++ crates/oxide_vm/src/vm.rs | 14 +++++------- 3 files changed, 43 insertions(+), 11 deletions(-) diff --git a/crates/oxide_compiler/src/emitter.rs b/crates/oxide_compiler/src/emitter.rs index 34af9b88..163253de 100644 --- a/crates/oxide_compiler/src/emitter.rs +++ b/crates/oxide_compiler/src/emitter.rs @@ -377,8 +377,9 @@ impl Compiler { }; // Compile body into sub-module - let sub_module = + let mut sub_module = self.compile_function_body(¶m_names, body_stmts, ctx, false)?; + sub_module.function_name = Some(name.clone()); ctx.sub_modules.push(sub_module); // 1-indexed: 0 = no sub_module (sentinel) let sub_idx = ctx.sub_modules.len() as u32; @@ -1223,8 +1224,11 @@ impl Compiler { &[] }; - let sub_module = + let mut sub_module = self.compile_function_body(¶m_names, body_stmts, ctx, false)?; + if let Some(id) = &fe.id { + sub_module.function_name = Some(id.name.to_string()); + } ctx.sub_modules.push(sub_module); // 1-indexed: 0 = no sub_module (sentinel) let sub_idx = ctx.sub_modules.len() as u32; diff --git a/crates/oxide_vm/src/builtins/error.rs b/crates/oxide_vm/src/builtins/error.rs index 8fedd48d..e132ab02 100644 --- a/crates/oxide_vm/src/builtins/error.rs +++ b/crates/oxide_vm/src/builtins/error.rs @@ -163,3 +163,35 @@ pub fn error_stack_getter(vm: &mut Vm, _args: &[u8]) -> NativeResult { let si = vm.kernel().string_forge().intern(&result).0; Ok(JsValue::string(si, 0)) } + +#[cfg(test)] +mod tests { + use super::error_stack_getter; + use crate::vm::{CallFrame, Vm}; + use oxide_types::value::JsValue; + + #[test] + fn error_stack_uses_call_frame_function_name() { + let mut vm = Vm::new(); + let name_si = vm.kernel().string_forge().intern("foo").0; + vm.frames.push(CallFrame { + return_addr: 0, + function_name: name_si, + caller_reg_limit: 1, + saved_regs: vec![JsValue::undefined()].into_boxed_slice(), + saved_this: JsValue::undefined(), + saved_new_target: JsValue::undefined(), + }); + + let stack = error_stack_getter(&mut vm, &[0]).unwrap(); + let stack_str = vm + .kernel() + .string_forge() + .lookup(stack.as_string_index()) + .unwrap_or_default(); + assert!( + stack_str.contains("foo"), + "expected function name in stack: {stack_str}" + ); + } +} diff --git a/crates/oxide_vm/src/vm.rs b/crates/oxide_vm/src/vm.rs index c974d806..0883adef 100644 --- a/crates/oxide_vm/src/vm.rs +++ b/crates/oxide_vm/src/vm.rs @@ -135,10 +135,6 @@ macro_rules! member_read_prop { pub struct CallFrame { pub return_addr: usize, - pub n_locals: u8, - pub n_args: u8, - pub function_obj_reg: u8, - pub frame_base: u8, pub function_name: u32, pub caller_reg_limit: u8, pub saved_regs: Box<[JsValue]>, @@ -779,11 +775,11 @@ impl Vm { // Push call frame self.frames.push(CallFrame { return_addr: self.pc, - n_locals: sub_n_args as u8, - n_args: sub_n_args as u8, - function_obj_reg: callee_reg as u8, - frame_base: sub_param_base as u8, - function_name: 0, + function_name: self.sub_modules[sub_idx] + .function_name + .as_deref() + .map(|name| self.kernel.string_forge().intern(name).0) + .unwrap_or(0), caller_reg_limit, saved_regs, saved_this,