fix: inline 回调抛原始异常值时 catch 保留原值不再包装成 Error

dispatch_native_call 的 NativeResult::Err 分支此前把非对象异常值
(用户 throw 的数字/字符串/null/undefined/false)包装成 Error 对象,
违反 ECMAScript throw 任意值语义:catch 应收到原始值。raise_call_error
与 TailCall 分支已通过 last_uncaught_value 保留原值,此处为唯一不一致点。
统一为原样保留异常值,并补数组回调/嵌套 inline/finally 组合回归测试。
This commit is contained in:
2026-08-15 05:49:59 +08:00
parent ee4a12668f
commit 461b18fa05
3 changed files with 160 additions and 13 deletions
+5 -13
View File
@@ -53,19 +53,11 @@ impl Vm {
Ok(())
}
NativeResult::Err(err_val) => {
let (error, kind) = if err_val.is_object() {
(err_val, self.thrown_error_kind(err_val))
} else {
let msg = if err_val.is_string() {
// SAFETY: err_val 是字符串值。
unsafe { (*err_val.as_string_ptr()).data.clone() }
} else {
format!("{err_val}")
};
builtins_debug!("native_call err={}", msg);
(oxide_builtins::error::create_error(self, &msg), "Error")
};
self.exception_value = Some(error);
// 异常值原样保留:native 内部错误均为 Error 对象(走上方分支),
// 非对象值来自用户回调 throw 的原始异常(经 last_uncaught_value
// 恢复),按 ECMAScript 语义 catch 须收到原值,不得包装成 Error。
let kind = self.thrown_error_kind(err_val);
self.exception_value = Some(err_val);
self.pending_error_kind = Some(kind);
self.unwind()
}