From c7f7588b81f703f4501d4f5b9b18f085c4840a2c Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Fri, 9 Oct 2026 23:58:34 +0000 Subject: [PATCH] =?UTF-8?q?style:=20=E5=85=A8=20workspace=20=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E8=AE=A2=E6=AD=A3=EF=BC=8C=E6=B6=88=E9=99=A4=20fmt=20?= =?UTF-8?q?=E6=BC=82=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_builtins/src/array/common.rs | 3 +- crates/oxide_builtins/src/date.rs | 10 +--- crates/oxide_builtins/src/global/annex_b.rs | 11 +--- crates/oxide_builtins/src/module.rs | 15 ++--- crates/oxide_builtins/src/regexp.rs | 10 +++- .../tests/array_hole_semantics_tests.rs | 41 +++----------- crates/oxide_emit/src/compile_ctx.rs | 5 +- crates/oxide_emit/src/expr/identifier.rs | 3 +- crates/oxide_emit/src/function_body.rs | 51 ++++++++--------- crates/oxide_emit/src/module.rs | 14 ++--- .../src/stmt/basic/break_continue.rs | 55 ++++++++++--------- crates/oxide_emit/src/stmt/declaration/var.rs | 7 +-- crates/oxide_emit/tests/module_link_tests.rs | 5 +- crates/oxide_vm/src/async_func.rs | 40 +++++++++++--- crates/oxide_vm/src/bindings/bind_regexp.rs | 30 +++++----- crates/oxide_vm/src/bindings/bind_worker.rs | 21 ++----- crates/oxide_vm/src/bindings/mod.rs | 4 +- crates/oxide_vm/src/vm_dispatch_misc.rs | 22 +++----- crates/oxide_vm/src/vm_runtime.rs | 5 +- crates/oxide_vm/src/worker/bindings.rs | 20 ++++--- .../oxide_vm/tests/builtins_function_tests.rs | 7 +-- .../tests/catch_param_restricted_tests.rs | 6 +- crates/oxide_vm/tests/function_tests.rs | 5 +- 23 files changed, 172 insertions(+), 218 deletions(-) diff --git a/crates/oxide_builtins/src/array/common.rs b/crates/oxide_builtins/src/array/common.rs index 963a304f..1cf60485 100644 --- a/crates/oxide_builtins/src/array/common.rs +++ b/crates/oxide_builtins/src/array/common.rs @@ -191,8 +191,7 @@ pub(crate) fn unit_string_value(vm: &mut H, unit: u16) -> JsValue { pub(crate) fn arraylike_index_present(vm: &mut H, ptr: *mut JsObject, i: usize) -> bool { // SAFETY: ptr 来自 this/参数对象,指向存活对象。 let key_si = vm.string_key_si(&i.to_string()); - vm.has_property(unsafe { &*ptr }, key_si) - .unwrap_or(false) + vm.has_property(unsafe { &*ptr }, key_si).unwrap_or(false) } /// 元素读取失败时直接把异常作为 NativeResult::Err 返回。 diff --git a/crates/oxide_builtins/src/date.rs b/crates/oxide_builtins/src/date.rs index abc87611..b7061b55 100644 --- a/crates/oxide_builtins/src/date.rs +++ b/crates/oxide_builtins/src/date.rs @@ -1042,15 +1042,7 @@ pub fn date_set_year(vm: &mut H, args: &[u8]) -> NativeResult { let full_year = if (0..=99).contains(&y_int) { y_int + 1900 } else { y_int }; finish_local_setter( obj, - make_local_timestamp( - full_year as f64, - dm as f64, - dd as f64, - dh as f64, - dmin as f64, - dsec as f64, - dms as f64, - ), + make_local_timestamp(full_year as f64, dm as f64, dd as f64, dh as f64, dmin as f64, dsec as f64, dms as f64), ) } diff --git a/crates/oxide_builtins/src/global/annex_b.rs b/crates/oxide_builtins/src/global/annex_b.rs index 19aad1a4..1e3f9b64 100644 --- a/crates/oxide_builtins/src/global/annex_b.rs +++ b/crates/oxide_builtins/src/global/annex_b.rs @@ -23,11 +23,7 @@ fn escape_units(input: &[u16]) -> Vec { continue; } // 转义序列恒为全 ASCII,按码元推入。 - let text = if u <= 0xFF { - format!("%{u:02X}") - } else { - format!("%u{u:04X}") - }; + let text = if u <= 0xFF { format!("%{u:02X}") } else { format!("%u{u:04X}") }; out.extend(text.encode_utf16()); } out @@ -42,10 +38,7 @@ fn unescape_units(input: &[u16]) -> Vec { while i < input.len() { if input[i] == b'%' as u16 { // %uXXXX:后跟 4 位十六进制。 - if i + 6 <= input.len() - && input[i + 1] == b'u' as u16 - && (2..6).all(|k| hex_val(input[i + k]).is_some()) - { + if i + 6 <= input.len() && input[i + 1] == b'u' as u16 && (2..6).all(|k| hex_val(input[i + k]).is_some()) { let v = (0..4).fold(0u16, |acc, k| acc * 16 + hex_val(input[i + 2 + k]).unwrap()); out.push(v); i += 6; diff --git a/crates/oxide_builtins/src/module.rs b/crates/oxide_builtins/src/module.rs index fae23580..765e2fca 100644 --- a/crates/oxide_builtins/src/module.rs +++ b/crates/oxide_builtins/src/module.rs @@ -946,11 +946,10 @@ pub fn module_defer_object(vm: &mut H, args: &[u8]) -> NativeResult { let fn_val = vm.reg(args[1]); let ns_val = vm.reg(args[2]); // fn 为函数或 undefined(哨兵);其余抛 TypeError。 - let fn_is_function = fn_val.is_object() - && { - let ptr = fn_val.as_js_object_ptr(); - !ptr.is_null() && unsafe { (*ptr).is_function() } - }; + let fn_is_function = fn_val.is_object() && { + let ptr = fn_val.as_js_object_ptr(); + !ptr.is_null() && unsafe { (*ptr).is_function() } + }; if !fn_is_function && !fn_val.is_undefined() { return type_error(vm, "__moduleDeferObject: first argument must be a function or undefined"); } @@ -1165,11 +1164,7 @@ mod tests { // 再收集一次:若 error 边漏登,err 被回收、计数回落。 vm.collect_session_gc(); - assert_eq!( - vm.session_object_count(), - steady_count, - "失败缓存错误应跨收集存活(GC 边已登记)" - ); + assert_eq!(vm.session_object_count(), steady_count, "失败缓存错误应跨收集存活(GC 边已登记)"); // 原地 sweep 不搬移:ns 与状态盒原地保留,error 指针稳定。 let ns_obj = unsafe { &*ns_val.as_js_object_ptr() }; let state = deferred_state(ns_obj).expect("deferred state 应存活"); diff --git a/crates/oxide_builtins/src/regexp.rs b/crates/oxide_builtins/src/regexp.rs index 0514af68..9074ea73 100644 --- a/crates/oxide_builtins/src/regexp.rs +++ b/crates/oxide_builtins/src/regexp.rs @@ -842,12 +842,18 @@ pub fn regexp_compile(vm: &mut H, args: &[u8]) -> NativeResult { return NativeResult::Err(crate::error::create_type_error(vm, "null object")); } if !unsafe { &*this_ptr }.is_regexp_obj() { - return NativeResult::Err(crate::error::create_type_error(vm, "RegExp.prototype.compile called on non-RegExp object")); + return NativeResult::Err(crate::error::create_type_error( + vm, + "RegExp.prototype.compile called on non-RegExp object", + )); } // proto 精确恒等:子类实例(proto = 子类 prototype)抛 TypeError。 let proto_ptr = vm.builtin_proto(ProtoKind::RegExpProto); if unsafe { &*this_ptr }.proto() != JsValue::from_js_object(proto_ptr) { - return NativeResult::Err(crate::error::create_type_error(vm, "RegExp.prototype.compile called on subclass instance")); + return NativeResult::Err(crate::error::create_type_error( + vm, + "RegExp.prototype.compile called on subclass instance", + )); } // 第 2 / 3 步:pattern / flags 取参。 diff --git a/crates/oxide_builtins/tests/array_hole_semantics_tests.rs b/crates/oxide_builtins/tests/array_hole_semantics_tests.rs index 85790d1f..53b42f75 100644 --- a/crates/oxide_builtins/tests/array_hole_semantics_tests.rs +++ b/crates/oxide_builtins/tests/array_hole_semantics_tests.rs @@ -914,80 +914,57 @@ fn test_filter_boxed_string_this() { // 引擎钉:reduce 装箱串 this——从左到右累计,初值空串。 #[test] fn test_reduce_boxed_string_this() { - let out = eval_str( - "(() => { return Array.prototype.reduce.call('ab', (a, b) => a + b, ''); })()", - ) - .unwrap(); + let out = eval_str("(() => { return Array.prototype.reduce.call('ab', (a, b) => a + b, ''); })()").unwrap(); assert_eq!(out, "ab"); } // 引擎钉:reduceRight 装箱串 this——从右到左累计。 #[test] fn test_reduce_right_boxed_string_this() { - let out = eval_str( - "(() => { return Array.prototype.reduceRight.call('ab', (a, b) => a + b, ''); })()", - ) - .unwrap(); + let out = eval_str("(() => { return Array.prototype.reduceRight.call('ab', (a, b) => a + b, ''); })()").unwrap(); assert_eq!(out, "ba"); } // 引擎钉:find 装箱串 this——返回首个真值单元。 #[test] fn test_find_boxed_string_this() { - let out = eval_str( - "(() => { return Array.prototype.find.call('ab', c => c === 'b'); })()", - ) - .unwrap(); + let out = eval_str("(() => { return Array.prototype.find.call('ab', c => c === 'b'); })()").unwrap(); assert_eq!(out, "b"); } // 引擎钉:findIndex 装箱串 this——返回首个真值下标。 #[test] fn test_find_index_boxed_string_this() { - let out = eval_str( - "(() => { return String(Array.prototype.findIndex.call('ab', c => c === 'a')); })()", - ) - .unwrap(); + let out = eval_str("(() => { return String(Array.prototype.findIndex.call('ab', c => c === 'a')); })()").unwrap(); assert_eq!(out, "0"); } // 引擎钉:findLast 装箱串 this——返回末个真值单元。 #[test] fn test_find_last_boxed_string_this() { - let out = eval_str( - "(() => { return Array.prototype.findLast.call('ab', c => c === 'b'); })()", - ) - .unwrap(); + let out = eval_str("(() => { return Array.prototype.findLast.call('ab', c => c === 'b'); })()").unwrap(); assert_eq!(out, "b"); } // 引擎钉:findLastIndex 装箱串 this——返回末个真值下标。 #[test] fn test_find_last_index_boxed_string_this() { - let out = eval_str( - "(() => { return String(Array.prototype.findLastIndex.call('ab', c => c === 'b')); })()", - ) - .unwrap(); + let out = + eval_str("(() => { return String(Array.prototype.findLastIndex.call('ab', c => c === 'b')); })()").unwrap(); assert_eq!(out, "1"); } // 引擎钉:some 装箱串 this——任一单元真值即 true。 #[test] fn test_some_boxed_string_this() { - let out = eval_str( - "(() => { return String(Array.prototype.some.call('ab', c => c === 'b')); })()", - ) - .unwrap(); + let out = eval_str("(() => { return String(Array.prototype.some.call('ab', c => c === 'b')); })()").unwrap(); assert_eq!(out, "true"); } // 引擎钉:every 装箱串 this——全单元真值才 true。 #[test] fn test_every_boxed_string_this() { - let out = eval_str( - "(() => { return String(Array.prototype.every.call('ab', c => c !== 'x')); })()", - ) - .unwrap(); + let out = eval_str("(() => { return String(Array.prototype.every.call('ab', c => c !== 'x')); })()").unwrap(); assert_eq!(out, "true"); } diff --git a/crates/oxide_emit/src/compile_ctx.rs b/crates/oxide_emit/src/compile_ctx.rs index 36fe0e4d..ec286fe4 100644 --- a/crates/oxide_emit/src/compile_ctx.rs +++ b/crates/oxide_emit/src/compile_ctx.rs @@ -974,10 +974,7 @@ impl CompileCtx { ) -> IRFunction { // 编译期不变式:每个 DISPOSE_MARK 都有配对的 DISPOSE_POP,函数体收尾 // 释放作用域全部关闭(早 return 跳过 POP 归穿越面,不在此列)。 - debug_assert!( - self.labels.dispose_depth == 0, - "函数体收尾释放作用域深度须归零(mark/pop 未配对)" - ); + debug_assert!(self.labels.dispose_depth == 0, "函数体收尾释放作用域深度须归零(mark/pop 未配对)"); let upvalue_captures = self .current_upvalue_captures .iter() diff --git a/crates/oxide_emit/src/expr/identifier.rs b/crates/oxide_emit/src/expr/identifier.rs index a63f4fdb..141b9799 100644 --- a/crates/oxide_emit/src/expr/identifier.rs +++ b/crates/oxide_emit/src/expr/identifier.rs @@ -120,7 +120,8 @@ impl Emitter { // 被捕获参数经 visible_cell 回退命中 CELL_GET,判定后置即漏判。 if ctx.param_tdz_names.contains(name) { let _ = self.emit_tdz_throw(&format!("Cannot access '{name}' before initialization"), ctx); - } else if let Some((uv_idx, _)) = ctx.current_upvalue_captures.iter().enumerate().find(|(_, u)| u.name == name) { + } else if let Some((uv_idx, _)) = ctx.current_upvalue_captures.iter().enumerate().find(|(_, u)| u.name == name) + { ctx.inst(Inst::new( OpCode::LOAD_UPVALUE, Operand::Reg(result_reg), diff --git a/crates/oxide_emit/src/function_body.rs b/crates/oxide_emit/src/function_body.rs index 43fc4b7f..a82977c2 100644 --- a/crates/oxide_emit/src/function_body.rs +++ b/crates/oxide_emit/src/function_body.rs @@ -163,8 +163,8 @@ impl Emitter { /// 编译函数体并显式指定生成器标志(`function*` 走此入口)。 pub(crate) fn compile_generator_body<'a>( - &self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, - own_strict: bool, name: Option<&str>, + &self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, own_strict: bool, + name: Option<&str>, ) -> Result { self.compile_function_body_with_flags( param_specs, @@ -183,11 +183,19 @@ impl Emitter { /// 同时标记 `is_generator` 与 `is_async`,VM 调用时按异步生成器协议执行 /// (next 返回 Promise,yield 挂起与 await 挂起共存)。 pub(crate) fn compile_async_generator_body<'a>( - &self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, - own_strict: bool, name: Option<&str>, + &self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, own_strict: bool, + name: Option<&str>, ) -> Result { self.compile_function_body_with_flags( - param_specs, body_stmts, parent_ctx, false, false, true, true, own_strict, name, + param_specs, + body_stmts, + parent_ctx, + false, + false, + true, + true, + own_strict, + name, ) } @@ -300,8 +308,7 @@ impl Emitter { &self, param_specs: &[ParamSpec<'a>], body_stmts: &[Statement<'a>], parent_ctx: &CompileCtx, is_expression_body: bool, extra_bindings: &[(&str, u32)], body_context: FunctionBodyContext, mut emit_fields: Option, fields_after_super: bool, extra_capture_exprs: &[&'a Expression<'a>], - extra_upvalue_names: &[(&str, u8)], is_generator: bool, is_async: bool, own_strict: bool, - name: Option<&str>, + extra_upvalue_names: &[(&str, u8)], is_generator: bool, is_async: bool, own_strict: bool, name: Option<&str>, ) -> Result where E: FnMut(&Emitter, &mut CompileCtx) -> Result<(), String>, @@ -708,24 +715,18 @@ impl Emitter { || (fn_name == "arguments" && arguments_reg.is_some()); if !suppressed { let reg = ctx.alloc_reg(); - ctx.scopes - .symbols - .scopes - .last_mut() - .expect("函数作用域已压入") - .bindings - .insert( - fn_name.to_string(), - Binding { - reg, - initialized: true, - is_const: false, - lexical: false, - predeclared: false, - cell_idx: None, - non_writable: true, - }, - ); + ctx.scopes.symbols.scopes.last_mut().expect("函数作用域已压入").bindings.insert( + fn_name.to_string(), + Binding { + reg, + initialized: true, + is_const: false, + lexical: false, + predeclared: false, + cell_idx: None, + non_writable: true, + }, + ); ctx.own_bindings.insert(fn_name.to_string()); ctx.function_name = Some(fn_name.to_string()); ctx.function_name_reg = Some(reg); diff --git a/crates/oxide_emit/src/module.rs b/crates/oxide_emit/src/module.rs index 7b57a148..ea06e6fc 100644 --- a/crates/oxide_emit/src/module.rs +++ b/crates/oxide_emit/src/module.rs @@ -24,8 +24,7 @@ use oxide_ir::operand::Operand; use oxide_ir::{IRFunction, ParamLayout}; use oxide_parser::{ BindingPattern, Declaration, ExportDefaultDeclarationKind, Expression, ImportAttributeKey, - ImportDeclarationSpecifier, ImportPhase, ModuleExportName, Statement, VariableDeclarationKind, - WithClause, + ImportDeclarationSpecifier, ImportPhase, ModuleExportName, Statement, VariableDeclarationKind, WithClause, }; use oxide_types::MODULE_NAMESPACE_BINDING; @@ -501,9 +500,11 @@ impl Emitter { _ => continue, }; let is_new = !phase_map.contains_key(&spec); - let entry = phase_map - .entry(spec.clone()) - .or_insert_with(|| DepPhase { eager: false, defer: false, attrs }); + let entry = phase_map.entry(spec.clone()).or_insert_with(|| DepPhase { + eager: false, + defer: false, + attrs, + }); if is_new { defer_order.push(spec.clone()); } @@ -772,8 +773,7 @@ impl Emitter { ); } let bind_reg = if is_defer { - *ctx - .module_defer_ns_regs + *ctx.module_defer_ns_regs .get(&dep_spec) .ok_or_else(|| format!("module dependency missing: {dep_spec}"))? } else { diff --git a/crates/oxide_emit/src/stmt/basic/break_continue.rs b/crates/oxide_emit/src/stmt/basic/break_continue.rs index ee800478..443fa877 100644 --- a/crates/oxide_emit/src/stmt/basic/break_continue.rs +++ b/crates/oxide_emit/src/stmt/basic/break_continue.rs @@ -87,33 +87,34 @@ impl Emitter { pub(crate) fn emit_continue_statement( &self, stmt: &oxide_parser::ContinueStatement, ctx: &mut CompileCtx, ) -> Result, String> { - let (continue_label, fd_at_open, fod_at_open, fid_at_open, dd_at_open, target_v_reg) = - if let Some(label) = &stmt.label { - let name = label.name.as_str(); - let scope = ctx - .find_label(name) - .ok_or_else(|| format!("SyntaxError: Undefined label '{name}'"))?; - ( - scope.continue_label.ok_or_else(|| { - format!("SyntaxError: Illegal continue statement: '{name}' does not denote an iteration statement") - })?, - scope.finally_depth_at_open, - scope.for_of_depth_at_open, - scope.for_in_depth_at_open, - scope.dispose_depth_at_open, - scope.completion_reg, - ) - } else { - let entry = ctx.current_loop().ok_or("continue outside loop".to_string())?; - ( - entry.continue_label, - entry.finally_depth_at_open, - entry.for_of_depth_at_open, - entry.for_in_depth_at_open, - entry.dispose_depth_at_open, - Some(entry.v_reg), - ) - }; + let (continue_label, fd_at_open, fod_at_open, fid_at_open, dd_at_open, target_v_reg) = if let Some(label) = + &stmt.label + { + let name = label.name.as_str(); + let scope = ctx + .find_label(name) + .ok_or_else(|| format!("SyntaxError: Undefined label '{name}'"))?; + ( + scope.continue_label.ok_or_else(|| { + format!("SyntaxError: Illegal continue statement: '{name}' does not denote an iteration statement") + })?, + scope.finally_depth_at_open, + scope.for_of_depth_at_open, + scope.for_in_depth_at_open, + scope.dispose_depth_at_open, + scope.completion_reg, + ) + } else { + let entry = ctx.current_loop().ok_or("continue outside loop".to_string())?; + ( + entry.continue_label, + entry.finally_depth_at_open, + entry.for_of_depth_at_open, + entry.for_in_depth_at_open, + entry.dispose_depth_at_open, + Some(entry.v_reg), + ) + }; if let Some(target_v_reg) = target_v_reg { self.emit_completion_carry(ctx, target_v_reg); } diff --git a/crates/oxide_emit/src/stmt/declaration/var.rs b/crates/oxide_emit/src/stmt/declaration/var.rs index 72304a8e..b3f2edc0 100644 --- a/crates/oxide_emit/src/stmt/declaration/var.rs +++ b/crates/oxide_emit/src/stmt/declaration/var.rs @@ -6,8 +6,7 @@ use oxide_bytecode::opcode::OpCode; use oxide_ir::inst::Inst; use oxide_ir::operand::Operand; use oxide_parser::{ - BindingPattern, ForStatementInit, ForStatementLeft, Statement, VariableDeclaration, - VariableDeclarationKind, + BindingPattern, ForStatementInit, ForStatementLeft, Statement, VariableDeclaration, VariableDeclarationKind, }; impl Emitter { @@ -137,9 +136,7 @@ impl Emitter { /// using/await using 声明登记释放栈:把资源值(val_reg)压入释放栈。非 /// using/await using 声明不登记。a 槽为释放提示(0 = 同步、1 = 异步)。 - pub(crate) fn emit_dispose_register( - &self, val_reg: u32, kind: VariableDeclarationKind, ctx: &mut CompileCtx, - ) { + pub(crate) fn emit_dispose_register(&self, val_reg: u32, kind: VariableDeclarationKind, ctx: &mut CompileCtx) { if !matches!(kind, VariableDeclarationKind::Using | VariableDeclarationKind::AwaitUsing) { return; } diff --git a/crates/oxide_emit/tests/module_link_tests.rs b/crates/oxide_emit/tests/module_link_tests.rs index 684e014f..08a2dabe 100644 --- a/crates/oxide_emit/tests/module_link_tests.rs +++ b/crates/oxide_emit/tests/module_link_tests.rs @@ -446,10 +446,7 @@ fn ancestor_defer_back_edge_sentinel() { let (ir, _) = emit_module( main_src, "./main.js", - &[ - ("./main.js", ModuleKind::Js, main_src), - ("./dep.js", ModuleKind::Js, dep_src), - ], + &[("./main.js", ModuleKind::Js, main_src), ("./dep.js", ModuleKind::Js, dep_src)], ) .expect("祖先 defer 回边应编译成功"); // main:1 个 eager 依赖(dep)求值。 diff --git a/crates/oxide_vm/src/async_func.rs b/crates/oxide_vm/src/async_func.rs index 219811cc..28cc233d 100644 --- a/crates/oxide_vm/src/async_func.rs +++ b/crates/oxide_vm/src/async_func.rs @@ -574,9 +574,8 @@ impl Vm { /// 续 dispatch 并结算:运行 body 到下一个 AWAIT/RETURN/异常,挂起则快照新状态, /// 完成/异常则结算 capability。恢复调用方状态。 fn dispatch_and_finish_async( - &mut self, state_ptr: *mut AsyncState, saved: Box, - prev_ctx: Option, prev_dispatch: bool, prev_gen_ctx: Option, - prev_gen_dispatch: bool, + &mut self, state_ptr: *mut AsyncState, saved: Box, prev_ctx: Option, + prev_dispatch: bool, prev_gen_ctx: Option, prev_gen_dispatch: bool, ) -> Result<(), String> { let result = self.dispatch(); if std::mem::take(&mut self.async_suspended) { @@ -695,7 +694,12 @@ impl Vm { return Ok(()); } self.dispatch_and_finish_async( - state_ptr, saved, prev_ctx, prev_dispatch, prev_gen_ctx, prev_gen_dispatch, + state_ptr, + saved, + prev_ctx, + prev_dispatch, + prev_gen_ctx, + prev_gen_dispatch, ) } DisposeResumeKind::Unwind(handler) => { @@ -712,7 +716,12 @@ impl Vm { return Ok(()); } self.dispatch_and_finish_async( - state_ptr, saved, prev_ctx, prev_dispatch, prev_gen_ctx, prev_gen_dispatch, + state_ptr, + saved, + prev_ctx, + prev_dispatch, + prev_gen_ctx, + prev_gen_dispatch, ) } DisposeResumeKind::Escape(completion_val) => { @@ -727,7 +736,12 @@ impl Vm { return Ok(()); } self.dispatch_and_finish_async( - state_ptr, saved, prev_ctx, prev_dispatch, prev_gen_ctx, prev_gen_dispatch, + state_ptr, + saved, + prev_ctx, + prev_dispatch, + prev_gen_ctx, + prev_gen_dispatch, ) } else { // 无合并错误:执行完成。 @@ -742,13 +756,23 @@ impl Vm { return Ok(()); } self.dispatch_and_finish_async( - state_ptr, saved, prev_ctx, prev_dispatch, prev_gen_ctx, prev_gen_dispatch, + state_ptr, + saved, + prev_ctx, + prev_dispatch, + prev_gen_ctx, + prev_gen_dispatch, ) } Completion::Break { target_pc, .. } | Completion::Continue { target_pc, .. } => { self.pc = target_pc; self.dispatch_and_finish_async( - state_ptr, saved, prev_ctx, prev_dispatch, prev_gen_ctx, prev_gen_dispatch, + state_ptr, + saved, + prev_ctx, + prev_dispatch, + prev_gen_ctx, + prev_gen_dispatch, ) } } diff --git a/crates/oxide_vm/src/bindings/bind_regexp.rs b/crates/oxide_vm/src/bindings/bind_regexp.rs index eee142ca..c884f706 100644 --- a/crates/oxide_vm/src/bindings/bind_regexp.rs +++ b/crates/oxide_vm/src/bindings/bind_regexp.rs @@ -1,8 +1,8 @@ use std::sync::Arc; use crate::bindings::{ - apply_binding_table, bind_accessor_getter, bind_accessor_getset, bind_accessor_getter_key, - bind_well_known_method, configure_native_constructor, + apply_binding_table, bind_accessor_getset, bind_accessor_getter, bind_accessor_getter_key, bind_well_known_method, + configure_native_constructor, }; use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::JsObject; @@ -50,16 +50,7 @@ pub fn bind_regexp(core: &Arc, session: &KernelSession, global: &mut let sf = core.perm_interner().as_ref(); let mut bind_getset = |name: &str, getter: *const (), setter: *const ()| { let key = sf.intern(name).0; - bind_accessor_getset( - core, - session, - ctor, - key, - &format!("get {name}"), - &format!("set {name}"), - getter, - setter, - ); + bind_accessor_getset(core, session, ctor, key, &format!("get {name}"), &format!("set {name}"), getter, setter); }; // input/$_:get+set 对(唯一带 setter 的遗留访问器)。 bind_getset( @@ -74,9 +65,15 @@ pub fn bind_regexp(core: &Arc, session: &KernelSession, global: &mut ); // 其余 18 个 getter(set 恒 undefined)。 for (name, getter) in [ - ("lastMatch", oxide_builtins::regexp::regexp_legacy_get_last_match:: as *const ()), + ( + "lastMatch", + oxide_builtins::regexp::regexp_legacy_get_last_match:: as *const (), + ), ("$&", oxide_builtins::regexp::regexp_legacy_get_last_match:: as *const ()), - ("lastParen", oxide_builtins::regexp::regexp_legacy_get_last_paren:: as *const ()), + ( + "lastParen", + oxide_builtins::regexp::regexp_legacy_get_last_paren:: as *const (), + ), ("$+", oxide_builtins::regexp::regexp_legacy_get_last_paren:: as *const ()), ( "leftContext", @@ -87,7 +84,10 @@ pub fn bind_regexp(core: &Arc, session: &KernelSession, global: &mut "rightContext", oxide_builtins::regexp::regexp_legacy_get_right_context:: as *const (), ), - ("$'", oxide_builtins::regexp::regexp_legacy_get_right_context:: as *const ()), + ( + "$'", + oxide_builtins::regexp::regexp_legacy_get_right_context:: as *const (), + ), ("index", oxide_builtins::regexp::regexp_legacy_get_index:: as *const ()), ("$1", oxide_builtins::regexp::regexp_legacy_get_dollar_1:: as *const ()), ("$2", oxide_builtins::regexp::regexp_legacy_get_dollar_2:: as *const ()), diff --git a/crates/oxide_vm/src/bindings/bind_worker.rs b/crates/oxide_vm/src/bindings/bind_worker.rs index fdf60cc1..680852e3 100644 --- a/crates/oxide_vm/src/bindings/bind_worker.rs +++ b/crates/oxide_vm/src/bindings/bind_worker.rs @@ -45,11 +45,7 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut let function_proto = world.function_proto.as_ptr() as *mut JsObject; let mut ctor = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(function_proto)); ctor.set_function(true); - configure_native_constructor( - &mut ctor, - crate::worker::bindings::worker_constructor as *const (), - 1, - ); + configure_native_constructor(&mut ctor, crate::worker::bindings::worker_constructor as *const (), 1); let ptr = Box::into_raw(Box::new(ctor)); world.track_leaked_object(ptr); ptr @@ -63,7 +59,8 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut if sh.lookup_position(ctor.shape_id(), si_name).is_none() { let shape = sh.make_shape(ctor.shape_id(), si_name); ctor.set_shape_id(shape); - ctor.ensure_hash_props().push(JsValue::perm_string(sf.string_ptr(sf.intern("Worker").0))); + ctor.ensure_hash_props() + .push(JsValue::perm_string(sf.string_ptr(sf.intern("Worker").0))); let pos = ctor.hash_props_vec().map_or(0, |v| v.len() as u32).saturating_sub(1); ctor.set_data_meta(pos, PropAttributes::new(false, false, true)); ctor.bump_generation(); @@ -116,11 +113,7 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut proto, core, &[ - ( - "postMessage", - crate::worker::bindings::worker_post_message as *const (), - 1, - ), + ("postMessage", crate::worker::bindings::worker_post_message as *const (), 1), ("terminate", crate::worker::bindings::worker_terminate as *const (), 0), ], ); @@ -147,11 +140,7 @@ pub fn bind_worker(core: &Arc, session: &KernelSession, global: &mut global, core, &[ - ( - "postMessage", - crate::worker::bindings::self_post_message as *const (), - 1, - ), + ("postMessage", crate::worker::bindings::self_post_message as *const (), 1), ("close", crate::worker::bindings::self_close as *const (), 0), ], ); diff --git a/crates/oxide_vm/src/bindings/mod.rs b/crates/oxide_vm/src/bindings/mod.rs index 2acd6239..aafe22d9 100644 --- a/crates/oxide_vm/src/bindings/mod.rs +++ b/crates/oxide_vm/src/bindings/mod.rs @@ -56,8 +56,6 @@ pub mod bind_shared_array_buffer; pub mod bind_string; /// 未实现内置(Proxy/BigInt/WeakMap 等)的 stub 构造器绑定。 pub mod bind_stubs; -/// Worker 构造器绑定(Box 分配,不占 BuiltinWorld P 字段)。 -pub mod bind_worker; /// Symbol 构造器与原型的 native 方法绑定。 pub mod bind_symbol; /// Temporal 命名空间对象(Now/Instant/PlainDate/PlainTime)绑定。 @@ -66,6 +64,8 @@ pub mod bind_temporal; pub mod bind_typed_array; /// WeakMap 构造器与原型四方法的 native 绑定(弱族不占 BuiltinWorld 槽)。 pub mod bind_weak; +/// Worker 构造器绑定(Box 分配,不占 BuiltinWorld P 字段)。 +pub mod bind_worker; use std::sync::Arc; diff --git a/crates/oxide_vm/src/vm_dispatch_misc.rs b/crates/oxide_vm/src/vm_dispatch_misc.rs index f2abc510..d7564050 100644 --- a/crates/oxide_vm/src/vm_dispatch_misc.rs +++ b/crates/oxide_vm/src/vm_dispatch_misc.rs @@ -1,6 +1,6 @@ use crate::vm::{ - Completion, DisposeResumeKind, ForInIter, FrameArgs, FrameContinuation, PendingAsyncDispose, - TryHandler, Vm, MAX_PROTO_CHAIN_DEPTH, + Completion, DisposeResumeKind, ForInIter, FrameArgs, FrameContinuation, PendingAsyncDispose, TryHandler, Vm, + MAX_PROTO_CHAIN_DEPTH, }; use crate::vm_trace; use oxide_builtins::iterator::is_callable; @@ -817,18 +817,14 @@ impl Vm { /// 异常穿越释放:逆序释放 `depth` 以上资源。在途异常作 completion 种子(被折叠 /// 进 suppressed)。挂起时携 `Unwind(handler)`(handler 已弹出,恢复时重压再入 /// unwind)。 - pub(crate) fn dispose_above( - &mut self, depth: usize, handler: Option, - ) -> Result { + pub(crate) fn dispose_above(&mut self, depth: usize, handler: Option) -> Result { self.dispose_above_core(depth, DisposeResumeKind::Unwind(handler), self.exception_value) } /// 释放栈顶部 `n` 条资源(逃出释放:return/break/continue 完成值逃出作用域时 /// 逆序释放被逃出的资源)。`n` 超过栈长时按全量释放。在途 completion 初值为 /// None(完成值非 throw),挂起时携 `Escape(completion)` 供恢复后执行。 - pub(crate) fn dispose_top_n( - &mut self, n: usize, completion: Completion, - ) -> Result { + pub(crate) fn dispose_top_n(&mut self, n: usize, completion: Completion) -> Result { let depth = self.dispose_stack.len().saturating_sub(n); self.dispose_above_core(depth, DisposeResumeKind::Escape(completion), None) } @@ -896,16 +892,16 @@ impl Vm { let dispose_key = encode_symbol_key(self.realm_id(), WELL_KNOWN_SYMBOL_DISPOSE); let method = if hint == 1 { let async_key = encode_symbol_key(self.realm_id(), WELL_KNOWN_SYMBOL_ASYNC_DISPOSE); - let async_method = self - .ordinary_get(val_obj, async_key, value) - .map_err(|e| self.dispose_exc(e))?; + let async_method = self.ordinary_get(val_obj, async_key, value).map_err(|e| self.dispose_exc(e))?; if async_method.is_undefined() { - self.ordinary_get(val_obj, dispose_key, value).map_err(|e| self.dispose_exc(e))? + self.ordinary_get(val_obj, dispose_key, value) + .map_err(|e| self.dispose_exc(e))? } else { async_method } } else { - self.ordinary_get(val_obj, dispose_key, value).map_err(|e| self.dispose_exc(e))? + self.ordinary_get(val_obj, dispose_key, value) + .map_err(|e| self.dispose_exc(e))? }; Ok(method) } diff --git a/crates/oxide_vm/src/vm_runtime.rs b/crates/oxide_vm/src/vm_runtime.rs index 803e2bf1..7621c5b9 100644 --- a/crates/oxide_vm/src/vm_runtime.rs +++ b/crates/oxide_vm/src/vm_runtime.rs @@ -876,10 +876,7 @@ impl Vm { // 异常穿越释放:逆序释放该作用域内登记的资源(规范序 IteratorClose 先、 // DisposeResources 后)。释放方法抛错时新错误替代在途异常继续向外展开; // 异步释放挂起时登记在途状态并让出(恢复方重压 handler 再入本函数)。 - if matches!( - self.dispose_above(handler.dispose_depth, Some(handler))?, - DisposePhase::Suspended - ) { + if matches!(self.dispose_above(handler.dispose_depth, Some(handler))?, DisposePhase::Suspended) { return Ok(()); } if let Some(finally_pc) = handler.finally_pc { diff --git a/crates/oxide_vm/src/worker/bindings.rs b/crates/oxide_vm/src/worker/bindings.rs index e77d9872..1cb3cbe3 100644 --- a/crates/oxide_vm/src/worker/bindings.rs +++ b/crates/oxide_vm/src/worker/bindings.rs @@ -86,12 +86,7 @@ pub(crate) fn worker_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult { let url_val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() }; let url = match vm.lookup_str(url_val) { Some(u) => u, - None => { - return NativeResult::Err(oxide_builtins::error::create_type_error( - vm, - "Worker url must be a string", - )) - } + None => return NativeResult::Err(oxide_builtins::error::create_type_error(vm, "Worker url must be a string")), }; // 主线程侧读 url 文件(worker 脚本源码)。 @@ -120,9 +115,11 @@ pub(crate) fn worker_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult { // onmessage / onerror / onmessageerror:普通 own 数据属性(非枚举),初值 undefined。 let si_onmessage = vm.perm_intern("onmessage"); - let _ = vm.define_data_property(worker_obj, si_onmessage, JsValue::undefined(), PropAttributes::new(true, false, true)); + let _ = + vm.define_data_property(worker_obj, si_onmessage, JsValue::undefined(), PropAttributes::new(true, false, true)); let si_onerror = vm.perm_intern("onerror"); - let _ = vm.define_data_property(worker_obj, si_onerror, JsValue::undefined(), PropAttributes::new(true, false, true)); + let _ = + vm.define_data_property(worker_obj, si_onerror, JsValue::undefined(), PropAttributes::new(true, false, true)); let si_onmessageerror = vm.perm_intern("onmessageerror"); let _ = vm.define_data_property( worker_obj, @@ -133,7 +130,12 @@ pub(crate) fn worker_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult { // workerId:非枚举数据属性(值为 worker 编号,数值表示无 GC 边)。 let si_worker_id = vm.perm_intern("workerId"); - let _ = vm.define_data_property(worker_obj, si_worker_id, JsValue::float(id as f64), PropAttributes::new(true, false, true)); + let _ = vm.define_data_property( + worker_obj, + si_worker_id, + JsValue::float(id as f64), + PropAttributes::new(true, false, true), + ); // 登记 Worker 对象进注册表(GC 根,主线程事件循环据编号反查 onmessage)。 vm.worker_objects.insert(id, JsValue::from_js_object(ptr)); diff --git a/crates/oxide_vm/tests/builtins_function_tests.rs b/crates/oxide_vm/tests/builtins_function_tests.rs index 05c3d244..0c076a88 100644 --- a/crates/oxide_vm/tests/builtins_function_tests.rs +++ b/crates/oxide_vm/tests/builtins_function_tests.rs @@ -420,11 +420,8 @@ fn function_call_apply_bind_async_target_returns_promise() { fn function_call_async_target_rejection_keeps_value() { // 异步目标抛错:Promise 以原值拒绝,.then 的拒绝臂收到原值。 let mut vm = Vm::new(); - let result = eval_drain( - &mut vm, - "async function f(){ throw 42; } f.call(null).then(v => 'ok:'+v, e => 'err:'+e)", - ) - .unwrap(); + let result = + eval_drain(&mut vm, "async function f(){ throw 42; } f.call(null).then(v => 'ok:'+v, e => 'err:'+e)").unwrap(); assert_eq!(vm.lookup_str(result).unwrap_or_default(), "err:42"); } diff --git a/crates/oxide_vm/tests/catch_param_restricted_tests.rs b/crates/oxide_vm/tests/catch_param_restricted_tests.rs index 2151b6e8..b8778456 100644 --- a/crates/oxide_vm/tests/catch_param_restricted_tests.rs +++ b/crates/oxide_vm/tests/catch_param_restricted_tests.rs @@ -168,11 +168,7 @@ fn strict_ctx_indirect_eval_catch_arguments_throws() { #[test] fn sloppy_eval_completion_value_unaffected() { // 守卫:sloppy 上下文 eval 完成值不受严格性判定影响。 - assert_eq!( - eval("eval(\"1+2\")"), - "3", - "sloppy context eval completion value is unaffected" - ); + assert_eq!(eval("eval(\"1+2\")"), "3", "sloppy context eval completion value is unaffected"); } #[test] diff --git a/crates/oxide_vm/tests/function_tests.rs b/crates/oxide_vm/tests/function_tests.rs index d20d3bfe..bfe938f4 100644 --- a/crates/oxide_vm/tests/function_tests.rs +++ b/crates/oxide_vm/tests/function_tests.rs @@ -291,10 +291,7 @@ fn fn_name_recursive_call() { /// 断言运行期抛出未捕获 ReferenceError(默认参数 TDZ 守卫的期望形态)。 fn assert_dflt_tdz_reference_error(source: &str, msg: &str) { let err = eval(&mut Vm::new(), source).unwrap_err(); - assert!( - err.contains("ReferenceError"), - "{msg}: expected an uncaught ReferenceError, got: {err}" - ); + assert!(err.contains("ReferenceError"), "{msg}: expected an uncaught ReferenceError, got: {err}"); } #[test]