From d4ed76855e45180c33cdf43ff58443591b74b50d Mon Sep 17 00:00:00 2001 From: pjh456 <147148383@qq.com> Date: Fri, 25 Sep 2026 04:59:19 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20fmt=20=E6=94=B6=E5=8F=A3=E4=B8=8E=20clip?= =?UTF-8?q?py=20ptr=5Feq=20=E6=94=B6=E6=95=9B=EF=BC=8CpadStart=20=E6=B5=8B?= =?UTF-8?q?=E8=AF=95=E6=9C=9F=E6=9C=9B=E5=AF=B9=E9=BD=90=E7=A0=81=E5=85=83?= =?UTF-8?q?=E5=8F=A3=E5=BE=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- crates/oxide_builtins/src/function.rs | 4 +- crates/oxide_builtins/src/json.rs | 6 +- crates/oxide_vm/src/async_func.rs | 73 ++++++++++--------- crates/oxide_vm/src/async_generator.rs | 9 +-- crates/oxide_vm/src/bindings/bind_function.rs | 4 +- crates/oxide_vm/src/generator.rs | 12 ++- crates/oxide_vm/src/vm/dynamic.rs | 6 +- crates/oxide_vm/src/vm/vmhost.rs | 8 +- .../oxide_vm/tests/builtins_string_tests.rs | 3 +- 9 files changed, 62 insertions(+), 63 deletions(-) diff --git a/crates/oxide_builtins/src/function.rs b/crates/oxide_builtins/src/function.rs index 708d58dd..b4a1cf00 100644 --- a/crates/oxide_builtins/src/function.rs +++ b/crates/oxide_builtins/src/function.rs @@ -44,9 +44,7 @@ pub fn async_generator_function_constructor(vm: &mut H, args: &[u8]) /// 无实参时函数体为空串。实参转单元序列后经 `source_escape` 源码域转义再 /// 动态编译(`is_generator` / `is_async` 决定 wrap 源码函数形态)。 /// 编译成功返回函数对象,语法错误抛 SyntaxError,实参 ToPrimitive 失败抛 TypeError。 -fn dynamic_function_core( - vm: &mut H, arg_regs: &[u8], is_generator: bool, is_async: bool, -) -> NativeResult { +fn dynamic_function_core(vm: &mut H, arg_regs: &[u8], is_generator: bool, is_async: bool) -> NativeResult { let (param_regs, body_reg) = if arg_regs.is_empty() { (vec![], None) } else { diff --git a/crates/oxide_builtins/src/json.rs b/crates/oxide_builtins/src/json.rs index f4edd923..92135e78 100644 --- a/crates/oxide_builtins/src/json.rs +++ b/crates/oxide_builtins/src/json.rs @@ -172,11 +172,7 @@ struct JsonNode { /// (进入时先计入再判定,防深嵌套在递归展开前耗尽栈)。 /// - 重复对象键:末写胜(键序由 build_js_value 统一)。 fn parse_json(text: &str) -> Result { - let mut p = JsonParser { - text, - pos: 0, - depth: 0, - }; + let mut p = JsonParser { text, pos: 0, depth: 0 }; p.skip_ws(); let node = p.parse_value()?; p.skip_ws(); diff --git a/crates/oxide_vm/src/async_func.rs b/crates/oxide_vm/src/async_func.rs index 6c5c8ac5..c4d04773 100644 --- a/crates/oxide_vm/src/async_func.rs +++ b/crates/oxide_vm/src/async_func.rs @@ -405,42 +405,43 @@ pub(crate) fn init_async_intrinsics(vm: &mut Vm) { let af_ctor_label = sf.intern("AsyncFunctionCtor").0; let af_reuse_key = oxide_kernel::builtin::FnWrapperKey::new(0, af_ctor_label, 0, 0); // SAFETY: async_function_constructor 是 NativeFn 函数项。 - let af_ctor_fn_ptr = unsafe { - NativeFnPtr::from_raw(oxide_builtins::function::async_function_constructor:: as *const ()) - }; - let (af_ctor_ptr, af_ctor_is_new) = match vm.session.builtin_world().find_fn_wrapper(af_reuse_key, af_ctor_fn_ptr, 1) { - Some(ptr) => (ptr, false), - None => { - // [[Prototype]] = Function 构造器本体(与 Function 构造器同链, - // `Object.getPrototypeOf(AsyncFunction) === Function` 语义)。 - let fn_ctor_val = - JsValue::from_js_object(vm.session.builtin_world().function_constructor.as_ptr() as *mut JsObject); - let mut af_ctor = Box::new(JsObject::new_empty(EMPTY_SHAPE_ID, fn_ctor_val)); - af_ctor.set_function(true); - af_ctor.set_native_arg_count(1); - af_ctor.set_native_fn(Some(af_ctor_fn_ptr)); - // 构造器 tag:IsConstructor 判定与 new 表达式派发据此放行。 - af_ctor.type_tag = JsObject::OBJ_TYPE_CONSTRUCTOR; - // 自身属性序:length、name、prototype、@@toStringTag(CreateBuiltinFunction 序)。 - let length_si = sf.intern("length").0; - let length_shape = sh.make_shape(EMPTY_SHAPE_ID, length_si); - af_ctor.set_shape_id(length_shape); - let name_si = sf.intern("name").0; - let name_shape = sh.make_shape(af_ctor.shape_id(), name_si); - af_ctor.set_shape_id(name_shape); - let proto_si = sf.intern("prototype").0; - let proto_shape = sh.make_shape(af_ctor.shape_id(), proto_si); - af_ctor.set_shape_id(proto_shape); - let tag_key = - oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG); - let tag_shape = sh.make_shape(af_ctor.shape_id(), tag_key); - af_ctor.set_shape_id(tag_shape); - let af_ctor_ptr = Box::into_raw(af_ctor); - // 登记进 world 释放表(带复用键):session 收尾统一释放构造器本体与属性区。 - vm.session.builtin_world().track_fn_wrapper(af_ctor_ptr, af_reuse_key); - (af_ctor_ptr, true) - } - }; + let af_ctor_fn_ptr = + unsafe { NativeFnPtr::from_raw(oxide_builtins::function::async_function_constructor:: as *const ()) }; + let (af_ctor_ptr, af_ctor_is_new) = + match vm.session.builtin_world().find_fn_wrapper(af_reuse_key, af_ctor_fn_ptr, 1) { + Some(ptr) => (ptr, false), + None => { + // [[Prototype]] = Function 构造器本体(与 Function 构造器同链, + // `Object.getPrototypeOf(AsyncFunction) === Function` 语义)。 + let fn_ctor_val = + JsValue::from_js_object(vm.session.builtin_world().function_constructor.as_ptr() as *mut JsObject); + let mut af_ctor = Box::new(JsObject::new_empty(EMPTY_SHAPE_ID, fn_ctor_val)); + af_ctor.set_function(true); + af_ctor.set_native_arg_count(1); + af_ctor.set_native_fn(Some(af_ctor_fn_ptr)); + // 构造器 tag:IsConstructor 判定与 new 表达式派发据此放行。 + af_ctor.type_tag = JsObject::OBJ_TYPE_CONSTRUCTOR; + // 自身属性序:length、name、prototype、@@toStringTag(CreateBuiltinFunction 序)。 + let length_si = sf.intern("length").0; + let length_shape = sh.make_shape(EMPTY_SHAPE_ID, length_si); + af_ctor.set_shape_id(length_shape); + let name_si = sf.intern("name").0; + let name_shape = sh.make_shape(af_ctor.shape_id(), name_si); + af_ctor.set_shape_id(name_shape); + let proto_si = sf.intern("prototype").0; + let proto_shape = sh.make_shape(af_ctor.shape_id(), proto_si); + af_ctor.set_shape_id(proto_shape); + let tag_key = oxide_types::private_key::make_well_known_symbol_key( + oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG, + ); + let tag_shape = sh.make_shape(af_ctor.shape_id(), tag_key); + af_ctor.set_shape_id(tag_shape); + let af_ctor_ptr = Box::into_raw(af_ctor); + // 登记进 world 释放表(带复用键):session 收尾统一释放构造器本体与属性区。 + vm.session.builtin_world().track_fn_wrapper(af_ctor_ptr, af_reuse_key); + (af_ctor_ptr, true) + } + }; // %AsyncFunction.prototype%:proto = Function.prototype,constructor = %AsyncFunction%。 let mut af_proto = Box::new(JsObject::new_empty(EMPTY_SHAPE_ID, fn_proto_val)); diff --git a/crates/oxide_vm/src/async_generator.rs b/crates/oxide_vm/src/async_generator.rs index 1887b295..e954d846 100644 --- a/crates/oxide_vm/src/async_generator.rs +++ b/crates/oxide_vm/src/async_generator.rs @@ -932,9 +932,7 @@ pub(crate) fn init_async_generator_intrinsics(vm: &mut Vm) { let agf_reuse_key = oxide_kernel::builtin::FnWrapperKey::new(0, agf_ctor_label, 0, 0); // SAFETY: async_generator_function_constructor 是 NativeFn 函数项。 let agf_ctor_fn_ptr = unsafe { - NativeFnPtr::from_raw( - oxide_builtins::function::async_generator_function_constructor:: as *const (), - ) + NativeFnPtr::from_raw(oxide_builtins::function::async_generator_function_constructor:: as *const ()) }; let (agf_ctor_ptr, agf_ctor_is_new) = match world.find_fn_wrapper(agf_reuse_key, agf_ctor_fn_ptr, 1) { Some(ptr) => (ptr, false), @@ -955,8 +953,9 @@ pub(crate) fn init_async_generator_intrinsics(vm: &mut Vm) { let proto_si = sf.intern("prototype").0; let proto_shape = sh.make_shape(agf_ctor.shape_id(), proto_si); agf_ctor.set_shape_id(proto_shape); - let tag_key = - oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG); + let tag_key = oxide_types::private_key::make_well_known_symbol_key( + oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG, + ); let tag_shape = sh.make_shape(agf_ctor.shape_id(), tag_key); agf_ctor.set_shape_id(tag_shape); let agf_ctor_ptr = Box::into_raw(agf_ctor); diff --git a/crates/oxide_vm/src/bindings/bind_function.rs b/crates/oxide_vm/src/bindings/bind_function.rs index a97cee7a..d2864628 100644 --- a/crates/oxide_vm/src/bindings/bind_function.rs +++ b/crates/oxide_vm/src/bindings/bind_function.rs @@ -100,7 +100,9 @@ fn bind_function_proto_restricted(core: &Arc, session: &KernelSessio thrower.set_native_arg_count(0); let name_shape = shape_forge.make_shape(thrower.shape_id(), si_name); thrower.set_shape_id(name_shape); - thrower.ensure_hash_props().push(JsValue::perm_string(string_forge.string_ptr(si_label))); + thrower + .ensure_hash_props() + .push(JsValue::perm_string(string_forge.string_ptr(si_label))); let name_pos = thrower.hash_props_vec().map_or(0, |v| v.len() as u32).saturating_sub(1); thrower.set_data_meta(name_pos, PropAttributes::new(false, false, true)); let length_shape = shape_forge.make_shape(thrower.shape_id(), si_length); diff --git a/crates/oxide_vm/src/generator.rs b/crates/oxide_vm/src/generator.rs index 9e876188..91f7e5f8 100644 --- a/crates/oxide_vm/src/generator.rs +++ b/crates/oxide_vm/src/generator.rs @@ -772,11 +772,8 @@ pub(crate) fn init_generator_intrinsics(vm: &mut Vm) { let gf_ctor_label = sf.intern("GeneratorFunctionCtor").0; let gf_reuse_key = oxide_kernel::builtin::FnWrapperKey::new(0, gf_ctor_label, 0, 0); // SAFETY: generator_function_constructor 是 NativeFn 函数项。 - let gf_ctor_fn_ptr = unsafe { - NativeFnPtr::from_raw( - oxide_builtins::function::generator_function_constructor:: as *const (), - ) - }; + let gf_ctor_fn_ptr = + unsafe { NativeFnPtr::from_raw(oxide_builtins::function::generator_function_constructor:: as *const ()) }; let (gf_ctor_ptr, gf_ctor_is_new) = match world.find_fn_wrapper(gf_reuse_key, gf_ctor_fn_ptr, 1) { Some(ptr) => (ptr, false), None => { @@ -796,8 +793,9 @@ pub(crate) fn init_generator_intrinsics(vm: &mut Vm) { let proto_si = sf.intern("prototype").0; let proto_shape = sh.make_shape(gf_ctor.shape_id(), proto_si); gf_ctor.set_shape_id(proto_shape); - let tag_key = - oxide_types::private_key::make_well_known_symbol_key(oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG); + let tag_key = oxide_types::private_key::make_well_known_symbol_key( + oxide_types::private_key::WELL_KNOWN_SYMBOL_TO_STRING_TAG, + ); let tag_shape = sh.make_shape(gf_ctor.shape_id(), tag_key); gf_ctor.set_shape_id(tag_shape); let gf_ctor_ptr = Box::into_raw(gf_ctor); diff --git a/crates/oxide_vm/src/vm/dynamic.rs b/crates/oxide_vm/src/vm/dynamic.rs index 70cecb00..2e355d1e 100644 --- a/crates/oxide_vm/src/vm/dynamic.rs +++ b/crates/oxide_vm/src/vm/dynamic.rs @@ -44,7 +44,11 @@ impl Vm { // 函数形态按生成器 / 异步标志分流,编译标志(is_generator / is_async) // 由 emit 层从 AST 读回,函数对象原型与 prototype 属性面随之自动分流。 let prefix = if is_async { - if is_generator { "async function*" } else { "async function" } + if is_generator { + "async function*" + } else { + "async function" + } } else if is_generator { "function*" } else { diff --git a/crates/oxide_vm/src/vm/vmhost.rs b/crates/oxide_vm/src/vm/vmhost.rs index 3b8ab048..49e1a8d7 100644 --- a/crates/oxide_vm/src/vm/vmhost.rs +++ b/crates/oxide_vm/src/vm/vmhost.rs @@ -189,10 +189,10 @@ impl oxide_runtime_api::VmHost for Vm { if !proto.is_object() { return false; } - let p = proto.as_js_object_ptr(); - p == self.generator_function_proto.as_ptr() as *mut JsObject - || p == self.async_function_proto.as_ptr() as *mut JsObject - || p == self.async_generator_function_proto.as_ptr() as *mut JsObject + let p = proto.as_js_object_ptr() as *const JsObject; + std::ptr::eq(p, self.generator_function_proto.as_ptr()) + || std::ptr::eq(p, self.async_function_proto.as_ptr()) + || std::ptr::eq(p, self.async_generator_function_proto.as_ptr()) } fn promote_if_needed_for_write_ptr(&mut self, target_ptr: *mut JsObject, value: JsValue) -> JsValue { self.promote_if_needed_for_write_ptr(target_ptr, value) diff --git a/crates/oxide_vm/tests/builtins_string_tests.rs b/crates/oxide_vm/tests/builtins_string_tests.rs index aa287248..595fa824 100644 --- a/crates/oxide_vm/tests/builtins_string_tests.rs +++ b/crates/oxide_vm/tests/builtins_string_tests.rs @@ -1111,8 +1111,9 @@ fn string_slice_astral_character_indices() { ) .unwrap(); assert!(r.as_bool()); + // padStart 按码元口径:😀 占 2 单元,距目标 3 仅差 1 单元,补 1 个 x。 let s = eval(&mut vm, "'\\u{1F600}'.padStart(3, 'x')").unwrap(); - assert_eq!(to_str(&vm, s), "xx\u{1F600}"); + assert_eq!(to_str(&vm, s), "x\u{1F600}"); } #[test]