From 4bc6db4fa497d48b273d3362473f70f47e0a2e39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=88=B1=E7=89=B9=E6=AF=8F=E7=BE=8A=E9=98=9F?= Date: Fri, 7 Aug 2026 13:45:39 +0800 Subject: [PATCH] =?UTF-8?q?fix(vm):=20Function.prototype.call=20=E7=9A=84?= =?UTF-8?q?=20native=20=E9=94=99=E8=AF=AF=E8=BD=AC=20JS=20=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E5=8F=AF=E8=A2=AB=E6=8D=95=E8=8E=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_vm/src/dispatch/call.rs | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/crates/oxide_vm/src/dispatch/call.rs b/crates/oxide_vm/src/dispatch/call.rs index 6d203b8..dc47a56 100644 --- a/crates/oxide_vm/src/dispatch/call.rs +++ b/crates/oxide_vm/src/dispatch/call.rs @@ -72,9 +72,26 @@ impl Vm { if callee.is_object() { let obj = unsafe { &*callee.as_js_object_ptr() }; if obj.native_fn().is_some() { - let result = self.call_function_sync(callee, this, &args)?; - self.regs[0] = result; - return Ok(()); + match self.call_function_sync(callee, this, &args) { + Ok(val) => { + self.regs[0] = val; + return Ok(()); + } + Err(_) => { + // call_function_sync 已把 native 错误展平为 String, + // 原始 JsValue 暂存在 last_uncaught_value——恢复为 JS 异常, + // 使外围 try/catch 能捕获(而非作为引擎错误上抛)。 + let exc = self + .last_uncaught_value + .take() + .unwrap_or_else(|| oxide_builtins::error::create_error(self, "call failed")); + let kind = self.thrown_error_kind(exc); + self.exception_value = Some(exc); + self.pending_error_kind = Some(kind); + self.unwind()?; + return Ok(()); + } + } } } self.push_bytecode_frame(callee, this, &args, None, None, JsValue::undefined(), FrameContinuation::None)