diff --git a/Cargo.lock b/Cargo.lock index f8159d06..1e0d6242 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1160,7 +1160,7 @@ dependencies = [ [[package]] name = "oxide_builtins" -version = "0.13.13" +version = "0.13.14" dependencies = [ "chrono", "fast-float", @@ -1185,7 +1185,7 @@ dependencies = [ [[package]] name = "oxide_bytecode" -version = "0.13.13" +version = "0.13.14" dependencies = [ "num-bigint", "oxide_log", @@ -1193,7 +1193,7 @@ dependencies = [ [[package]] name = "oxide_cfg" -version = "0.13.13" +version = "0.13.14" dependencies = [ "oxide_bytecode", "oxide_emit", @@ -1204,7 +1204,7 @@ dependencies = [ [[package]] name = "oxide_cli" -version = "0.13.13" +version = "0.13.14" dependencies = [ "ansi_term", "bumpalo", @@ -1226,7 +1226,7 @@ dependencies = [ [[package]] name = "oxide_code_cache" -version = "0.13.13" +version = "0.13.14" dependencies = [ "lru", "oxide_bytecode", @@ -1235,7 +1235,7 @@ dependencies = [ [[package]] name = "oxide_compiler" -version = "0.13.13" +version = "0.13.14" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1255,7 +1255,7 @@ dependencies = [ [[package]] name = "oxide_dce" -version = "0.13.13" +version = "0.13.14" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1269,7 +1269,7 @@ dependencies = [ [[package]] name = "oxide_emit" -version = "0.13.13" +version = "0.13.14" dependencies = [ "num-bigint", "oxc_allocator", @@ -1284,7 +1284,7 @@ dependencies = [ [[package]] name = "oxide_engine" -version = "0.13.13" +version = "0.13.14" dependencies = [ "oxide_bytecode", "oxide_compiler", @@ -1296,7 +1296,7 @@ dependencies = [ [[package]] name = "oxide_ir" -version = "0.13.13" +version = "0.13.14" dependencies = [ "oxide_bytecode", "oxide_log", @@ -1305,7 +1305,7 @@ dependencies = [ [[package]] name = "oxide_kernel" -version = "0.13.13" +version = "0.13.14" dependencies = [ "bumpalo", "dashmap", @@ -1319,7 +1319,7 @@ dependencies = [ [[package]] name = "oxide_liveness" -version = "0.13.13" +version = "0.13.14" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1331,7 +1331,7 @@ dependencies = [ [[package]] name = "oxide_log" -version = "0.13.13" +version = "0.13.14" dependencies = [ "tracing", "tracing-appender", @@ -1340,7 +1340,7 @@ dependencies = [ [[package]] name = "oxide_parser" -version = "0.13.13" +version = "0.13.14" dependencies = [ "oxc_allocator", "oxc_ast", @@ -1355,7 +1355,7 @@ dependencies = [ [[package]] name = "oxide_regalloc" -version = "0.13.13" +version = "0.13.14" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1371,7 +1371,7 @@ dependencies = [ [[package]] name = "oxide_runtime_api" -version = "0.13.13" +version = "0.13.14" dependencies = [ "num-bigint", "num-traits", @@ -1384,7 +1384,7 @@ dependencies = [ [[package]] name = "oxide_test262" -version = "0.13.13" +version = "0.13.14" dependencies = [ "oxide_bytecode", "oxide_compiler", @@ -1402,7 +1402,7 @@ dependencies = [ [[package]] name = "oxide_types" -version = "0.13.13" +version = "0.13.14" dependencies = [ "bumpalo", "dashmap", @@ -1415,7 +1415,7 @@ dependencies = [ [[package]] name = "oxide_vm" -version = "0.13.13" +version = "0.13.14" dependencies = [ "bumpalo", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 33448c26..3df1d5af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ members = [ ] [workspace.package] -version = "0.13.13" +version = "0.13.14" edition = "2021" license = "MIT" rust-version = "1.80" diff --git a/crates/oxide_vm/src/dispatch/call.rs b/crates/oxide_vm/src/dispatch/call.rs index 12ae7788..1fffc979 100644 --- a/crates/oxide_vm/src/dispatch/call.rs +++ b/crates/oxide_vm/src/dispatch/call.rs @@ -137,8 +137,14 @@ impl Vm { let sub = self.callee_module(obj); if matches!(sub, Some(m) if m.is_async || m.is_generator) { self.constructing_native = false; + let gen_pc = self.pc; let result = self.call_bytecode_function_inline(callee, obj, this, &args)?; - self.regs[0] = result; + // 参数初始化抛错已就地展开(unwind 改写 pc 至 catch):异常值已 + // 写入 catch 参数,再写结果寄存器会覆盖之——仅在初始化成功(pc 未动) + // 时交付结果。 + if self.pc == gen_pc { + self.regs[0] = result; + } return Ok(()); } } diff --git a/crates/oxide_vm/tests/builtins_function_tests.rs b/crates/oxide_vm/tests/builtins_function_tests.rs index b59da845..05c3d244 100644 --- a/crates/oxide_vm/tests/builtins_function_tests.rs +++ b/crates/oxide_vm/tests/builtins_function_tests.rs @@ -450,3 +450,28 @@ fn function_bind_async_generator_target_returns_iterator() { let result = eval(&mut vm, "async function* g(){ return 99; } typeof g.bind(null)()").unwrap(); assert_eq!(vm.lookup_str(result).unwrap_or_default(), "object"); } + +#[test] +fn function_call_generator_param_default_throw_keeps_catch_value() { + // 生成器目标带抛错的参数默认值,经 call/apply/bind 调用且调用点在 try/catch 内: + // catch 参数须是抛出的原值 42,不得被占位迭代器对象覆盖。 + let mut vm = Vm::new(); + let result = eval( + &mut vm, + "function* g(x = (function(){ throw 42; })()) { yield 1; } try { g.call(null); } catch (e) { e; }", + ) + .unwrap(); + assert_eq!(result, JsValue::int(42)); + let result = eval( + &mut vm, + "function* g(x = (function(){ throw 42; })()) { yield 1; } try { g.apply(null, []); } catch (e) { e; }", + ) + .unwrap(); + assert_eq!(result, JsValue::int(42)); + let result = eval( + &mut vm, + "function* g(x = (function(){ throw 42; })()) { yield 1; } try { g.bind(null)(); } catch (e) { e; }", + ) + .unwrap(); + assert_eq!(result, JsValue::int(42)); +}