diff --git a/Cargo.lock b/Cargo.lock index 0043f86b..66f5edf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1160,7 +1160,7 @@ dependencies = [ [[package]] name = "oxide_builtins" -version = "0.8.72" +version = "0.8.73" dependencies = [ "chrono", "fast-float", @@ -1185,7 +1185,7 @@ dependencies = [ [[package]] name = "oxide_bytecode" -version = "0.8.72" +version = "0.8.73" dependencies = [ "num-bigint", "oxide_log", @@ -1193,7 +1193,7 @@ dependencies = [ [[package]] name = "oxide_cfg" -version = "0.8.72" +version = "0.8.73" dependencies = [ "oxide_bytecode", "oxide_emit", @@ -1204,7 +1204,7 @@ dependencies = [ [[package]] name = "oxide_cli" -version = "0.8.72" +version = "0.8.73" dependencies = [ "ansi_term", "bumpalo", @@ -1226,7 +1226,7 @@ dependencies = [ [[package]] name = "oxide_code_cache" -version = "0.8.72" +version = "0.8.73" dependencies = [ "lru", "oxide_bytecode", @@ -1235,7 +1235,7 @@ dependencies = [ [[package]] name = "oxide_compiler" -version = "0.8.72" +version = "0.8.73" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1255,7 +1255,7 @@ dependencies = [ [[package]] name = "oxide_dce" -version = "0.8.72" +version = "0.8.73" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1269,7 +1269,7 @@ dependencies = [ [[package]] name = "oxide_emit" -version = "0.8.72" +version = "0.8.73" dependencies = [ "num-bigint", "oxc_allocator", @@ -1284,7 +1284,7 @@ dependencies = [ [[package]] name = "oxide_engine" -version = "0.8.72" +version = "0.8.73" dependencies = [ "oxide_bytecode", "oxide_compiler", @@ -1296,7 +1296,7 @@ dependencies = [ [[package]] name = "oxide_ir" -version = "0.8.72" +version = "0.8.73" dependencies = [ "oxide_bytecode", "oxide_log", @@ -1305,7 +1305,7 @@ dependencies = [ [[package]] name = "oxide_kernel" -version = "0.8.72" +version = "0.8.73" dependencies = [ "bumpalo", "dashmap", @@ -1319,7 +1319,7 @@ dependencies = [ [[package]] name = "oxide_liveness" -version = "0.8.72" +version = "0.8.73" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1331,7 +1331,7 @@ dependencies = [ [[package]] name = "oxide_log" -version = "0.8.72" +version = "0.8.73" dependencies = [ "tracing", "tracing-appender", @@ -1340,7 +1340,7 @@ dependencies = [ [[package]] name = "oxide_parser" -version = "0.8.72" +version = "0.8.73" dependencies = [ "oxc_allocator", "oxc_ast", @@ -1355,7 +1355,7 @@ dependencies = [ [[package]] name = "oxide_regalloc" -version = "0.8.72" +version = "0.8.73" dependencies = [ "oxide_bytecode", "oxide_cfg", @@ -1371,7 +1371,7 @@ dependencies = [ [[package]] name = "oxide_runtime_api" -version = "0.8.72" +version = "0.8.73" dependencies = [ "num-bigint", "num-traits", @@ -1384,7 +1384,7 @@ dependencies = [ [[package]] name = "oxide_test262" -version = "0.8.72" +version = "0.8.73" dependencies = [ "oxide_bytecode", "oxide_compiler", @@ -1402,7 +1402,7 @@ dependencies = [ [[package]] name = "oxide_types" -version = "0.8.72" +version = "0.8.73" dependencies = [ "bumpalo", "dashmap", @@ -1415,7 +1415,7 @@ dependencies = [ [[package]] name = "oxide_vm" -version = "0.8.72" +version = "0.8.73" dependencies = [ "bumpalo", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 9491f039..753dbbfd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ members = [ ] [workspace.package] -version = "0.8.72" +version = "0.8.73" edition = "2021" license = "MIT" rust-version = "1.80" diff --git a/crates/oxide_builtins/src/error.rs b/crates/oxide_builtins/src/error.rs index 858d085e..58ae068f 100644 --- a/crates/oxide_builtins/src/error.rs +++ b/crates/oxide_builtins/src/error.rs @@ -1,8 +1,5 @@ -use std::sync::Arc; - use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; -use oxide_runtime_api::{to_string_full, NativeResult, VmHost}; -use oxide_types::mem::P; +use oxide_runtime_api::{to_string_full, NativeResult, ProtoKind, VmHost}; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::value::JsValue; @@ -25,10 +22,8 @@ fn set_own_message(host: &mut H, this: *mut JsObject, args: &[u8]) -> return NativeResult::Err(create_type_error(host, "Cannot convert value to a string")); } }; - let sf = Arc::clone(host.kernel_core().perm_interner()); - let sh = Arc::clone(host.kernel_core().shape_forge()); - let si = sf.intern("message").0; - let new_shape = sh.make_shape(EMPTY_SHAPE_ID, si); + let si = host.perm_intern("message"); + let new_shape = host.make_shape(EMPTY_SHAPE_ID, si); let perm_val = host.new_string(&msg_str); unsafe { (*this).set_shape_id(new_shape); @@ -43,20 +38,18 @@ fn set_own_message(host: &mut H, this: *mut JsObject, args: &[u8]) -> /// 这是引擎内部构造错误的统一入口,供 VM/native 层抛错使用。 pub fn create_kind_error(host: &mut H, kind: &str, msg: &str) -> JsValue { let proto_ptr = match kind { - "TypeError" => P::as_ptr(&host.session().builtin_world().type_error_proto) as *mut JsObject, - "RangeError" => P::as_ptr(&host.session().builtin_world().range_error_proto) as *mut JsObject, - "ReferenceError" => P::as_ptr(&host.session().builtin_world().reference_error_proto) as *mut JsObject, - "SyntaxError" => P::as_ptr(&host.session().builtin_world().syntax_error_proto) as *mut JsObject, - "URIError" => P::as_ptr(&host.session().builtin_world().uri_error_proto) as *mut JsObject, - "EvalError" => P::as_ptr(&host.session().builtin_world().eval_error_proto) as *mut JsObject, - _ => P::as_ptr(&host.session().builtin_world().error_proto) as *mut JsObject, + "TypeError" => host.builtin_proto(ProtoKind::TypeErrorProto), + "RangeError" => host.builtin_proto(ProtoKind::RangeErrorProto), + "ReferenceError" => host.builtin_proto(ProtoKind::ReferenceErrorProto), + "SyntaxError" => host.builtin_proto(ProtoKind::SyntaxErrorProto), + "URIError" => host.builtin_proto(ProtoKind::UriErrorProto), + "EvalError" => host.builtin_proto(ProtoKind::EvalErrorProto), + _ => host.builtin_proto(ProtoKind::ErrorProto), }; let obj = host.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto_ptr))); - let sf = Arc::clone(host.kernel_core().perm_interner()); - let sh = Arc::clone(host.kernel_core().shape_forge()); if !msg.is_empty() { - let si_msg = sf.intern("message").0; - let shape = sh.make_shape(EMPTY_SHAPE_ID, si_msg); + let si_msg = host.perm_intern("message"); + let shape = host.make_shape(EMPTY_SHAPE_ID, si_msg); let msg_val = host.new_string(msg); unsafe { (*obj).set_shape_id(shape); @@ -160,7 +153,7 @@ pub fn create_uri_error(host: &mut H, msg: &str) -> JsValue { } macro_rules! error_ctor { - ($name:ident, $proto_field:ident) => { + ($name:ident, $proto_kind:ident) => { /// 对应 Error 子类(如 `TypeError`)的构造函数:接收第一个实参作为 message, /// 返回携带 Error 家族标签(`[[ErrorData]]` 谓词)的实例。 /// @@ -172,7 +165,7 @@ macro_rules! error_ctor { pub fn $name(host: &mut H, args: &[u8]) -> NativeResult { let this_val = host.reg(if args.is_empty() { 0 } else { args[0] }); let new_target = host.reg(255); - let proto_ptr = P::as_ptr(&host.session().builtin_world().$proto_field) as *mut JsObject; + let proto_ptr = host.builtin_proto(ProtoKind::$proto_kind); let this = if this_val.is_object() && new_target.is_object() { this_val.as_js_object_ptr() } else { @@ -195,21 +188,19 @@ macro_rules! error_ctor { }; } -error_ctor!(error_constructor, error_proto); -error_ctor!(type_error_constructor, type_error_proto); -error_ctor!(reference_error_constructor, reference_error_proto); -error_ctor!(range_error_constructor, range_error_proto); -error_ctor!(syntax_error_constructor, syntax_error_proto); -error_ctor!(uri_error_constructor, uri_error_proto); -error_ctor!(eval_error_constructor, eval_error_proto); +error_ctor!(error_constructor, ErrorProto); +error_ctor!(type_error_constructor, TypeErrorProto); +error_ctor!(reference_error_constructor, ReferenceErrorProto); +error_ctor!(range_error_constructor, RangeErrorProto); +error_ctor!(syntax_error_constructor, SyntaxErrorProto); +error_ctor!(uri_error_constructor, UriErrorProto); +error_ctor!(eval_error_constructor, EvalErrorProto); /// 在对象上追加一个非枚举数据属性(writable/configurable=true,enumerable=false), /// 与 `CreateNonEnumerableDataPropertyOrThrow` 语义一致。 fn set_own_data_prop(host: &mut H, obj: *mut JsObject, key: &str, val: JsValue) { - let sf = Arc::clone(host.kernel_core().perm_interner()); - let sh = Arc::clone(host.kernel_core().shape_forge()); - let si = sf.intern(key).0; - let new_shape = sh.make_shape(unsafe { (*obj).shape_id() }, si); + let si = host.perm_intern(key); + let new_shape = host.make_shape(unsafe { (*obj).shape_id() }, si); unsafe { (*obj).set_shape_id(new_shape); let pos = (*obj).push_prop(val); @@ -229,7 +220,7 @@ pub fn install_error_cause(host: &mut H, obj: *mut JsObject, options: } // SAFETY: is_object 保证指针非空且对象本 session 存活。 let opts = unsafe { &*options.as_js_object_ptr() }; - let si = host.kernel_core().perm_interner().intern("cause").0; + let si = host.perm_intern("cause"); if host.resolve_property(opts, si).is_none() { return NativeResult::Ok(JsValue::undefined()); } @@ -257,7 +248,7 @@ pub fn install_error_cause(host: &mut H, obj: *mut JsObject, options: pub fn suppressed_error_constructor(host: &mut H, args: &[u8]) -> NativeResult { let this_val = host.reg(if args.is_empty() { 0 } else { args[0] }); let new_target = host.reg(255); - let proto_ptr = P::as_ptr(&host.session().builtin_world().suppressed_error_proto) as *mut JsObject; + let proto_ptr = host.builtin_proto(ProtoKind::SuppressedErrorProto); let obj = if this_val.is_object() && new_target.is_object() { this_val.as_js_object_ptr() } else { @@ -302,7 +293,7 @@ pub fn suppressed_error_constructor(host: &mut H, args: &[u8]) -> Nat /// - 错误值/suppressed 值原样存储,不做任何转换; /// - 返回对象 proto = suppressed_error_proto,标记 OBJ_TYPE_ERROR。 pub fn create_suppressed_error(host: &mut H, error_val: JsValue, suppressed_val: JsValue) -> JsValue { - let proto_ptr = P::as_ptr(&host.session().builtin_world().suppressed_error_proto) as *mut JsObject; + let proto_ptr = host.builtin_proto(ProtoKind::SuppressedErrorProto); let obj = host.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto_ptr))); set_own_data_prop(host, obj, "error", error_val); set_own_data_prop(host, obj, "suppressed", suppressed_val); @@ -332,9 +323,8 @@ pub fn error_to_string(host: &mut H, args: &[u8]) -> NativeResult { return NativeResult::Err(err); } let obj = unsafe { &*this_val.as_js_object_ptr() }; - let sf = Arc::clone(host.kernel_core().perm_interner()); - let si_name = sf.intern("name").0; - let si_msg = sf.intern("message").0; + let si_name = host.perm_intern("name"); + let si_msg = host.perm_intern("message"); let name_str = match host.ordinary_get(obj, si_name, this_val) { Ok(v) if v.is_undefined() => "Error".to_string(), @@ -383,9 +373,8 @@ pub fn error_stack_getter(host: &mut H, args: &[u8]) -> NativeResult if !obj.is_error_obj() { return NativeResult::Ok(JsValue::undefined()); } - let sf = Arc::clone(host.kernel_core().perm_interner()); - let si_name = sf.intern("name").0; - let si_msg = sf.intern("message").0; + let si_name = host.perm_intern("name"); + let si_msg = host.perm_intern("message"); let n = host .resolve_property(obj, si_name) .and_then(|v| host.lookup_str(v)) @@ -421,7 +410,7 @@ pub fn error_stack_setter(host: &mut H, args: &[u8]) -> NativeResult if !this_val.is_object() { return NativeResult::Err(create_type_error(host, "Error.prototype.stack setter called on non-object")); } - let home = P::as_ptr(&host.session().builtin_world().error_proto) as *mut JsObject; + let home = host.builtin_proto(ProtoKind::ErrorProto); if std::ptr::eq(this_val.as_js_object_ptr(), home) { return NativeResult::Err(create_type_error(host, "cannot assign to read only property of Error prototype")); } @@ -431,7 +420,7 @@ pub fn error_stack_setter(host: &mut H, args: &[u8]) -> NativeResult } // SAFETY: is_object 保证指针非空且对象本 session 存活;写入路径对象不搬移。 let this_obj = unsafe { &mut *this_val.as_js_object_ptr() }; - let si = host.kernel_core().perm_interner().intern("stack").0; + let si = host.perm_intern("stack"); match host.get_own_property_slot(this_obj, si) { None => match host.define_data_property(this_obj, si, val, PropAttributes::new(true, true, true)) { Ok(()) => NativeResult::Ok(JsValue::undefined()), @@ -477,9 +466,8 @@ pub fn error_to_json(host: &mut H, args: &[u8]) -> NativeResult { } // SAFETY: is_object 保证指针非空且对象本 session 存活;读取期间不搬移。 let obj = unsafe { &*this_val.as_js_object_ptr() }; - let sf = Arc::clone(host.kernel_core().perm_interner()); - let si_name = sf.intern("name").0; - let si_msg = sf.intern("message").0; + let si_name = host.perm_intern("name"); + let si_msg = host.perm_intern("message"); let name_val = match host.ordinary_get(obj, si_name, this_val) { Ok(v) => v, @@ -517,16 +505,15 @@ pub fn error_to_json(host: &mut H, args: &[u8]) -> NativeResult { } // 新对象:proto = %Object.prototype%,name/message 为可枚举数据属性。 - let object_proto = P::as_ptr(&host.session().builtin_world().object_proto) as *mut JsObject; + let object_proto = host.builtin_proto(ProtoKind::ObjectProto); let ptr = host.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto))); // SAFETY: ptr 由 alloc_object 新建,非空 arena 指针;后续 shape/属性分配不改对象地址,无别名。 let obj_ref = unsafe { &mut *ptr }; - let sh = Arc::clone(host.kernel_core().shape_forge()); - let name_shape = sh.make_shape(EMPTY_SHAPE_ID, si_name); + let name_shape = host.make_shape(EMPTY_SHAPE_ID, si_name); obj_ref.set_shape_id(name_shape); let name_pos = obj_ref.push_prop(host.new_string(&name_str)); obj_ref.set_data_meta(name_pos, PropAttributes::new(true, true, true)); - let msg_shape = sh.make_shape(obj_ref.shape_id(), si_msg); + let msg_shape = host.make_shape(obj_ref.shape_id(), si_msg); obj_ref.set_shape_id(msg_shape); let msg_pos = obj_ref.push_prop(host.new_string(&msg_str)); obj_ref.set_data_meta(msg_pos, PropAttributes::new(true, true, true)); diff --git a/crates/oxide_builtins/src/iterator.rs b/crates/oxide_builtins/src/iterator.rs index 41886df8..872fab2f 100644 --- a/crates/oxide_builtins/src/iterator.rs +++ b/crates/oxide_builtins/src/iterator.rs @@ -1,9 +1,10 @@ use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::private_key::{encode_symbol_key, make_int_key}; +use oxide_types::string_forge::PermInterner; use oxide_types::value::JsValue; -use oxide_runtime_api::{to_object, NativeResult, VmHost}; +use oxide_runtime_api::{to_object, NativeResult, ProtoKind, VmHost}; const INNER_PROP: &str = "__inner__"; const INDEX_PROP: &str = "__index__"; @@ -47,7 +48,7 @@ pub fn iterator_constructor(vm: &mut H, args: &[u8]) -> NativeResult if proto.is_object() { let proto_ptr = proto.as_js_object_ptr(); if !proto_ptr.is_null() { - let home = vm.session().builtin_world().iterator_proto.as_ptr() as *mut JsObject; + let home = vm.builtin_proto(ProtoKind::IteratorProto); if std::ptr::eq(proto_ptr, home) { return NativeResult::Err(crate::error::create_type_error(vm, "Iterator is not a constructor")); } @@ -68,12 +69,11 @@ pub fn iterator_constructor(vm: &mut H, args: &[u8]) -> NativeResult /// lookup 失败(极端:global 无 `Iterator`)返回 undefined,不 panic。 pub fn iterator_constructor_getter(vm: &mut H, _args: &[u8]) -> NativeResult { let (shape_id, global_ptr) = { - let session = vm.session(); - let global = session.global_object(); + let global = vm.global_object(); (global.shape_id(), global.as_ptr() as *mut JsObject) }; - let si = vm.kernel_core().perm_interner().intern("Iterator").0; - let Some(pos) = vm.kernel_core().shape_forge().lookup_position(shape_id, si) else { + let si = vm.perm_intern("Iterator"); + let Some(pos) = vm.lookup_position(shape_id, si) else { return NativeResult::Ok(JsValue::undefined()); }; NativeResult::Ok(unsafe { &*global_ptr }.get_prop_at(pos)) @@ -81,8 +81,9 @@ pub fn iterator_constructor_getter(vm: &mut H, _args: &[u8]) -> Nativ /// `%IteratorPrototype%` 上 `Symbol.toStringTag` 访问器的 getter:返回 `"Iterator"`。 pub fn iterator_to_string_tag_getter(vm: &mut H, _args: &[u8]) -> NativeResult { - let sf = vm.kernel_core().perm_interner().as_ref(); - NativeResult::Ok(JsValue::perm_string(sf.string_ptr(sf.intern("Iterator").0))) + // SAFETY: perm interner 随 VM 存活,本表达式内只读即时消费。 + let sf = vm.perm_interner_ptr() as *const PermInterner; + NativeResult::Ok(JsValue::perm_string(unsafe { &*sf }.string_ptr(vm.perm_intern("Iterator")))) } /// 忽略原型属性的 setter 的共享实现(对应规范 SetterThatIgnoresPrototypeProperties): @@ -100,7 +101,7 @@ fn iterator_setter_ignore_proto_props(vm: &mut H, args: &[u8], key: u if !this_val.is_object() { return NativeResult::Err(crate::error::create_type_error(vm, "Iterator property setter called on non-object")); } - let home = vm.session().builtin_world().iterator_proto.as_ptr() as *mut JsObject; + let home = vm.builtin_proto(ProtoKind::IteratorProto); if std::ptr::eq(this_val.as_js_object_ptr(), home) { return NativeResult::Err(crate::error::create_type_error( vm, @@ -109,12 +110,7 @@ fn iterator_setter_ignore_proto_props(vm: &mut H, args: &[u8], key: u } let val = if args.len() > 1 { vm.reg(args[1]) } else { JsValue::undefined() }; let this_obj = unsafe { &mut *this_val.as_js_object_ptr() }; - if vm - .kernel_core() - .shape_forge() - .lookup_position(this_obj.shape_id(), key) - .is_none() - { + if vm.lookup_position(this_obj.shape_id(), key).is_none() { match vm.define_data_property(this_obj, key, val, PropAttributes::new(true, true, true)) { Ok(()) => NativeResult::Ok(JsValue::undefined()), Err(err) => NativeResult::Err(crate::error::create_type_error(vm, &err)), @@ -129,7 +125,7 @@ fn iterator_setter_ignore_proto_props(vm: &mut H, args: &[u8], key: u /// `constructor` 访问器的 setter(键 = "constructor")。 pub fn iterator_constructor_setter(vm: &mut H, args: &[u8]) -> NativeResult { - let key = vm.kernel_core().perm_interner().intern("constructor").0; + let key = vm.perm_intern("constructor"); iterator_setter_ignore_proto_props(vm, args, key) } @@ -154,7 +150,7 @@ pub fn iterator_dispose(vm: &mut H, args: &[u8]) -> NativeResult { )); } let obj = unsafe { &*this_val.as_js_object_ptr() }; - let return_si = vm.kernel_core().perm_interner().intern("return").0; + let return_si = vm.perm_intern("return"); let return_fn = match vm.ordinary_get(obj, return_si, this_val) { Ok(f) if is_callable(f) => f, Ok(_) => JsValue::undefined(), @@ -203,7 +199,7 @@ pub(crate) fn validate_terminal_and_get_direct( /// - `next` getter 抛错时透传原异常值。 pub(crate) fn get_iterator_direct(vm: &mut H, this_val: JsValue) -> Result<(JsValue, JsValue), JsValue> { let iter_obj = unsafe { &*this_val.as_js_object_ptr() }; - let next_si = vm.kernel_core().perm_interner().intern("next").0; + let next_si = vm.perm_intern("next"); let next = vm.ordinary_get(iter_obj, next_si, this_val).map_err(|e| engine_error(vm, &e))?; Ok((this_val, next)) } @@ -222,12 +218,12 @@ pub(crate) fn iterator_record_step( return Err(crate::error::create_type_error(vm, "iterator result is not an object")); } let result_obj = unsafe { &*result.as_js_object_ptr() }; - let done_si = vm.kernel_core().perm_interner().intern("done").0; + let done_si = vm.perm_intern("done"); let done = vm.ordinary_get(result_obj, done_si, result).map_err(|e| engine_error(vm, &e))?; if oxide_runtime_api::to_boolean(done) { return Ok(None); } - let value_si = vm.kernel_core().perm_interner().intern("value").0; + let value_si = vm.perm_intern("value"); let value = vm .ordinary_get(result_obj, value_si, result) .map_err(|e| engine_error(vm, &e))?; @@ -248,7 +244,7 @@ pub(crate) fn iterator_close_record( vm: &mut H, iterated: JsValue, completion_err: Option, ) -> Result<(), JsValue> { let iter_obj = unsafe { &*iterated.as_js_object_ptr() }; - let return_si = vm.kernel_core().perm_interner().intern("return").0; + let return_si = vm.perm_intern("return"); let return_fn = match vm.ordinary_get(iter_obj, return_si, iterated) { Ok(f) if is_callable(f) => f, Ok(_) => { @@ -439,17 +435,17 @@ fn get_iterator_flattenable(vm: &mut H, value: JsValue) -> Result<(Js fn make_iterator_helper( vm: &mut H, inner: JsValue, next: JsValue, kind: IteratorHelperKind, callback: JsValue, counter: JsValue, ) -> JsValue { - let helper_proto = vm.session().builtin_world().iterator_helper_proto.as_ptr() as *mut JsObject; + let helper_proto = vm.builtin_proto(ProtoKind::IteratorHelperProto); let wrapper = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(helper_proto))); let wrapper_obj = unsafe { &mut *wrapper }; - let inner_si = vm.kernel_core().perm_interner().intern(INNER_PROP).0; - let next_si = vm.kernel_core().perm_interner().intern(NEXT_CACHE_PROP).0; - let kind_si = vm.kernel_core().perm_interner().intern(KIND_PROP).0; - let state_si = vm.kernel_core().perm_interner().intern(STATE_PROP).0; - let counter_si = vm.kernel_core().perm_interner().intern(COUNTER_PROP).0; - let callback_si = vm.kernel_core().perm_interner().intern(CALLBACK_PROP).0; - let inner_iter_si = vm.kernel_core().perm_interner().intern(INNER_ITER_PROP).0; - let inner_next_si = vm.kernel_core().perm_interner().intern(INNER_NEXT_PROP).0; + let inner_si = vm.perm_intern(INNER_PROP); + let next_si = vm.perm_intern(NEXT_CACHE_PROP); + let kind_si = vm.perm_intern(KIND_PROP); + let state_si = vm.perm_intern(STATE_PROP); + let counter_si = vm.perm_intern(COUNTER_PROP); + let callback_si = vm.perm_intern(CALLBACK_PROP); + let inner_iter_si = vm.perm_intern(INNER_ITER_PROP); + let inner_next_si = vm.perm_intern(INNER_NEXT_PROP); vm.set_or_create_prop_value(wrapper_obj, inner_si, inner); vm.set_or_create_prop_value(wrapper_obj, next_si, next); vm.set_or_create_prop_value(wrapper_obj, kind_si, JsValue::int(kind as i32)); @@ -471,7 +467,7 @@ fn validate_helper_this(vm: &mut H, this_val: JsValue, method: &str) return Err(crate::error::create_type_error(vm, &format!("{method} called on non-object"))); } let obj = unsafe { &*this_val.as_js_object_ptr() }; - let inner_si = vm.kernel_core().perm_interner().intern(INNER_PROP).0; + let inner_si = vm.perm_intern(INNER_PROP); let inner = vm.ordinary_get(obj, inner_si, this_val).map_err(|e| engine_error(vm, &e))?; if !inner.is_object() { return Err(crate::error::create_type_error(vm, &format!("{method} called on non-iterator-helper"))); @@ -709,7 +705,7 @@ pub fn iterator_to_array(vm: &mut H, args: &[u8]) -> NativeResult { /// 按元素列表构造普通数组,以 Array.prototype 为原型(对应规范 CreateArrayFromList)。 fn make_array_from_list(vm: &mut H, items: &[JsValue]) -> JsValue { - let array_proto = vm.session().builtin_world().array_proto.as_ptr() as *mut JsObject; + let array_proto = vm.builtin_proto(ProtoKind::ArrayProto); let arr = vm.alloc_object(JsObject::new_array( EMPTY_SHAPE_ID, JsValue::from_js_object(array_proto), @@ -863,7 +859,7 @@ pub fn iterator_helper_next(vm: &mut H, args: &[u8]) -> NativeResult Err(v) => return NativeResult::Err(v), }; let helper = unsafe { &mut *this_val.as_js_object_ptr() }; - let state_si = vm.kernel_core().perm_interner().intern(STATE_PROP).0; + let state_si = vm.perm_intern(STATE_PROP); let state = read_slot_int(vm, helper, state_si, 2); if state == 2 { return NativeResult::Ok(make_iter_result(vm, JsValue::undefined(), true)); @@ -871,10 +867,10 @@ pub fn iterator_helper_next(vm: &mut H, args: &[u8]) -> NativeResult if state == 1 { return NativeResult::Err(crate::error::create_type_error(vm, "Iterator helper is already executing")); } - let kind_si = vm.kernel_core().perm_interner().intern(KIND_PROP).0; + let kind_si = vm.perm_intern(KIND_PROP); let kind = IteratorHelperKind::from_i32(read_slot_int(vm, helper, kind_si, 0)); vm.set_or_create_prop_value(helper, state_si, JsValue::int(1)); - let next_si = vm.kernel_core().perm_interner().intern(NEXT_CACHE_PROP).0; + let next_si = vm.perm_intern(NEXT_CACHE_PROP); let next = vm.ordinary_get(helper, next_si, this_val).unwrap_or(JsValue::undefined()); let step = match kind { IteratorHelperKind::Map => helper_step_map(vm, this_val, helper, inner, next), @@ -914,7 +910,7 @@ pub fn iterator_helper_return(vm: &mut H, args: &[u8]) -> NativeResul Err(v) => return NativeResult::Err(v), }; let helper = unsafe { &mut *this_val.as_js_object_ptr() }; - let state_si = vm.kernel_core().perm_interner().intern(STATE_PROP).0; + let state_si = vm.perm_intern(STATE_PROP); let state = read_slot_int(vm, helper, state_si, 2); if state == 2 { return NativeResult::Ok(make_iter_result(vm, JsValue::undefined(), true)); @@ -923,9 +919,9 @@ pub fn iterator_helper_return(vm: &mut H, args: &[u8]) -> NativeResul return NativeResult::Err(crate::error::create_type_error(vm, "Iterator helper is already executing")); } vm.set_or_create_prop_value(helper, state_si, JsValue::int(2)); - let kind_si = vm.kernel_core().perm_interner().intern(KIND_PROP).0; + let kind_si = vm.perm_intern(KIND_PROP); if IteratorHelperKind::from_i32(read_slot_int(vm, helper, kind_si, 0)) == IteratorHelperKind::FlatMap { - let inner_iter_si = vm.kernel_core().perm_interner().intern(INNER_ITER_PROP).0; + let inner_iter_si = vm.perm_intern(INNER_ITER_PROP); if let Ok(inner_iter) = vm.ordinary_get(helper, inner_iter_si, this_val) { if inner_iter.is_object() { // 内层关闭出错:以该错误关外层(外层 return 错误被吞),传播内层错误。 @@ -956,7 +952,7 @@ pub fn iterator_helper_throw(vm: &mut H, args: &[u8]) -> NativeResult Err(v) => return NativeResult::Err(v), }; let helper = unsafe { &mut *this_val.as_js_object_ptr() }; - let state_si = vm.kernel_core().perm_interner().intern(STATE_PROP).0; + let state_si = vm.perm_intern(STATE_PROP); let state = read_slot_int(vm, helper, state_si, 2); if state == 2 { return NativeResult::Err(value); @@ -965,9 +961,9 @@ pub fn iterator_helper_throw(vm: &mut H, args: &[u8]) -> NativeResult return NativeResult::Err(crate::error::create_type_error(vm, "Iterator helper is already executing")); } vm.set_or_create_prop_value(helper, state_si, JsValue::int(2)); - let kind_si = vm.kernel_core().perm_interner().intern(KIND_PROP).0; + let kind_si = vm.perm_intern(KIND_PROP); if IteratorHelperKind::from_i32(read_slot_int(vm, helper, kind_si, 0)) == IteratorHelperKind::FlatMap { - let inner_iter_si = vm.kernel_core().perm_interner().intern(INNER_ITER_PROP).0; + let inner_iter_si = vm.perm_intern(INNER_ITER_PROP); if let Ok(inner_iter) = vm.ordinary_get(helper, inner_iter_si, this_val) { if inner_iter.is_object() { // throw 语义:原值胜出,内层/外层关闭错误均被吞。 @@ -984,8 +980,8 @@ pub fn iterator_helper_throw(vm: &mut H, args: &[u8]) -> NativeResult fn helper_step_map( vm: &mut H, this_val: JsValue, helper: &mut JsObject, inner: JsValue, next: JsValue, ) -> Result, JsValue> { - let counter_si = vm.kernel_core().perm_interner().intern(COUNTER_PROP).0; - let callback_si = vm.kernel_core().perm_interner().intern(CALLBACK_PROP).0; + let counter_si = vm.perm_intern(COUNTER_PROP); + let callback_si = vm.perm_intern(CALLBACK_PROP); let mapper = vm.ordinary_get(helper, callback_si, this_val).unwrap_or(JsValue::undefined()); let counter = read_counter(vm, helper, counter_si); let value = match iterator_record_step(vm, next, inner) { @@ -1012,8 +1008,8 @@ fn helper_step_map( fn helper_step_filter( vm: &mut H, this_val: JsValue, helper: &mut JsObject, inner: JsValue, next: JsValue, ) -> Result, JsValue> { - let counter_si = vm.kernel_core().perm_interner().intern(COUNTER_PROP).0; - let callback_si = vm.kernel_core().perm_interner().intern(CALLBACK_PROP).0; + let counter_si = vm.perm_intern(COUNTER_PROP); + let callback_si = vm.perm_intern(CALLBACK_PROP); let predicate = vm.ordinary_get(helper, callback_si, this_val).unwrap_or(JsValue::undefined()); let mut counter = read_counter(vm, helper, counter_si); loop { @@ -1045,7 +1041,7 @@ fn helper_step_filter( fn helper_step_take( vm: &mut H, helper: &mut JsObject, inner: JsValue, next: JsValue, ) -> Result, JsValue> { - let counter_si = vm.kernel_core().perm_interner().intern(COUNTER_PROP).0; + let counter_si = vm.perm_intern(COUNTER_PROP); let remaining = read_slot_double(vm, helper, counter_si, f64::INFINITY); if remaining == 0.0 { // remaining 归零:正常完成形态关底层(return 错误胜出)。 @@ -1068,7 +1064,7 @@ fn helper_step_take( fn helper_step_drop( vm: &mut H, helper: &mut JsObject, inner: JsValue, next: JsValue, ) -> Result, JsValue> { - let counter_si = vm.kernel_core().perm_interner().intern(COUNTER_PROP).0; + let counter_si = vm.perm_intern(COUNTER_PROP); let mut remaining = read_slot_double(vm, helper, counter_si, 0.0); while remaining > 0.0 { if remaining != f64::INFINITY { @@ -1096,10 +1092,10 @@ fn helper_step_drop( fn helper_step_flat_map( vm: &mut H, this_val: JsValue, helper: &mut JsObject, outer: JsValue, outer_next: JsValue, ) -> Result, JsValue> { - let counter_si = vm.kernel_core().perm_interner().intern(COUNTER_PROP).0; - let callback_si = vm.kernel_core().perm_interner().intern(CALLBACK_PROP).0; - let inner_iter_si = vm.kernel_core().perm_interner().intern(INNER_ITER_PROP).0; - let inner_next_si = vm.kernel_core().perm_interner().intern(INNER_NEXT_PROP).0; + let counter_si = vm.perm_intern(COUNTER_PROP); + let callback_si = vm.perm_intern(CALLBACK_PROP); + let inner_iter_si = vm.perm_intern(INNER_ITER_PROP); + let inner_next_si = vm.perm_intern(INNER_NEXT_PROP); let mapper = vm.ordinary_get(helper, callback_si, this_val).unwrap_or(JsValue::undefined()); let mut counter = read_counter(vm, helper, counter_si); loop { @@ -1246,13 +1242,13 @@ pub(crate) fn build_iterator_wrapper( ) -> JsValue { let iterator_proto = match wrapper_proto { Some(proto) => proto, - None => vm.session().builtin_world().iterator_proto.as_ptr() as *mut JsObject, + None => vm.builtin_proto(ProtoKind::IteratorProto), }; let wrapper = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(iterator_proto))); - let inner_si = vm.kernel_core().perm_interner().intern(INNER_PROP).0; - let index_si = vm.kernel_core().perm_interner().intern(INDEX_PROP).0; - let next_si = vm.kernel_core().perm_interner().intern("next").0; + let inner_si = vm.perm_intern(INNER_PROP); + let index_si = vm.perm_intern(INDEX_PROP); + let next_si = vm.perm_intern("next"); let wrapper_obj = unsafe { &mut *wrapper }; vm.set_or_create_prop_value(wrapper_obj, inner_si, inner); vm.set_or_create_prop_value(wrapper_obj, index_si, JsValue::int(0)); @@ -1261,7 +1257,7 @@ pub(crate) fn build_iterator_wrapper( // "只读一次"同模式),消费期直读槽不重触发 getter;非鸭子路径无槽,wrapper next // 回退重读内层 next(既有行为)。 if let Some(next_fn) = cached_next { - let next_cache_si = vm.kernel_core().perm_interner().intern(NEXT_CACHE_PROP).0; + let next_cache_si = vm.perm_intern(NEXT_CACHE_PROP); vm.set_or_create_prop_value(wrapper_obj, next_cache_si, next_fn); } @@ -1270,7 +1266,7 @@ pub(crate) fn build_iterator_wrapper( // for-of/解构的 IteratorClose 需要 return 方法:条件暴露(内层有可调用 return 时)。 // `yield*` 委托(bind_return=false)不绑定,转发时对内层延迟 GetMethod。 - let return_si = vm.kernel_core().perm_interner().intern("return").0; + let return_si = vm.perm_intern("return"); if bind_return && inner.is_object() { let inner_obj = unsafe { &*inner.as_js_object_ptr() }; if let Ok(return_fn) = vm.ordinary_get(inner_obj, return_si, inner) { @@ -1290,14 +1286,14 @@ fn iterator_wrapper_return(vm: &mut H, args: &[u8]) -> NativeResult { return NativeResult::Ok(JsValue::undefined()); } let wrapper = unsafe { &*this_val.as_js_object_ptr() }; - let inner_si = vm.kernel_core().perm_interner().intern(INNER_PROP).0; + let inner_si = vm.perm_intern(INNER_PROP); let inner = match vm.ordinary_get(wrapper, inner_si, this_val) { Ok(inner) if inner.is_object() => inner, _ => return NativeResult::Ok(JsValue::undefined()), }; // 延迟 GetMethod:内层无 return 方法时返回 undefined(IteratorClose 跳过)。 let inner_obj = unsafe { &*inner.as_js_object_ptr() }; - let return_si = vm.kernel_core().perm_interner().intern("return").0; + let return_si = vm.perm_intern("return"); let return_fn = match vm.ordinary_get(inner_obj, return_si, inner) { Ok(f) if is_callable(f) => f, _ => return NativeResult::Ok(JsValue::undefined()), @@ -1323,8 +1319,8 @@ pub fn iterator_wrapper_next(vm: &mut H, args: &[u8]) -> NativeResult } let wrapper = unsafe { &mut *this_val.as_js_object_ptr() }; - let inner_si = vm.kernel_core().perm_interner().intern(INNER_PROP).0; - let index_si = vm.kernel_core().perm_interner().intern(INDEX_PROP).0; + let inner_si = vm.perm_intern(INNER_PROP); + let index_si = vm.perm_intern(INDEX_PROP); let inner = match vm.ordinary_get(wrapper, inner_si, this_val) { Ok(inner) if !inner.is_undefined() => inner, _ => return NativeResult::Err(crate::error::create_type_error(vm, "Iterator wrapper has no inner iterator")), @@ -1340,7 +1336,7 @@ pub fn iterator_wrapper_next(vm: &mut H, args: &[u8]) -> NativeResult // 鸭子回退包装器优先读 `__next__` 槽(from() 时只读一次的缓存闭包, // 消费期不重触发 getter);槽缺失或不可调用时回退重读内层 next // (非鸭子路径既有行为)。 - let next_cache_si = vm.kernel_core().perm_interner().intern(NEXT_CACHE_PROP).0; + let next_cache_si = vm.perm_intern(NEXT_CACHE_PROP); let cached = match vm.ordinary_get(wrapper, next_cache_si, this_val) { Ok(c) => c, Err(err) => { @@ -1355,7 +1351,7 @@ pub fn iterator_wrapper_next(vm: &mut H, args: &[u8]) -> NativeResult cached } else { let inner_obj = unsafe { &*inner.as_js_object_ptr() }; - let next_si = vm.kernel_core().perm_interner().intern("next").0; + let next_si = vm.perm_intern("next"); match vm.ordinary_get(inner_obj, next_si, inner) { Ok(n) => n, Err(err) => { @@ -1405,7 +1401,7 @@ pub(crate) fn peek_iterator_method(vm: &mut H, value: JsValue) -> Res // (与 get_iterator 的 String 臂同口径)。默认迭代器被删除/置 null 时须落 // array-like,而非按"String 恒可迭代"放行迭代路径。 if value.is_string() { - let proto_ptr = vm.session().builtin_world().string_proto.as_ptr() as *mut JsObject; + let proto_ptr = vm.builtin_proto(ProtoKind::StringProto); // SAFETY: string_proto 是 BuiltinWorld 长驻原型对象,进程内有效且不被 GC 搬移。 let proto_obj = unsafe { &*proto_ptr }; let sym_iter_si = encode_symbol_key(vm.realm_id(), 0); @@ -1465,7 +1461,7 @@ pub(crate) fn peek_iterator_method(vm: &mut H, value: JsValue) -> Res // 装箱串不套用:get_iterator 的 String 臂无 duck-next 回退,规范也只看 // @@iterator(Array.from/%TypedArray%.from 应落 array-like)。 if !obj.is_string_obj() { - let next_si = vm.kernel_core().perm_interner().intern("next").0; + let next_si = vm.perm_intern("next"); if let Ok(next) = vm.ordinary_get(obj, next_si, value) { if is_callable(next) { return Ok(true); @@ -1490,21 +1486,17 @@ fn builtin_iterator_default_intact(vm: &mut H, value: JsValue, method if !method.is_object() { return false; } - let (anchor_ptr, anchor_name) = { - let session = vm.session(); - let world = session.builtin_world(); - if is_array_value(value) { - (world.array_proto.as_ptr() as *mut JsObject, "values") - } else if is_typed_array_value(value) { - (world.typed_array_proto.as_ptr() as *mut JsObject, "values") - } else if is_map_value(value) { - (world.map_proto.as_ptr() as *mut JsObject, "entries") - } else { - (world.set_proto.as_ptr() as *mut JsObject, "values") - } + let (anchor_ptr, anchor_name) = if is_array_value(value) { + (vm.builtin_proto(ProtoKind::ArrayProto), "values") + } else if is_typed_array_value(value) { + (vm.builtin_proto(ProtoKind::TypedArrayProto), "values") + } else if is_map_value(value) { + (vm.builtin_proto(ProtoKind::MapProto), "entries") + } else { + (vm.builtin_proto(ProtoKind::SetProto), "values") }; let anchor_obj = unsafe { &*anchor_ptr }; - let anchor_si = vm.kernel_core().perm_interner().intern(anchor_name).0; + let anchor_si = vm.perm_intern(anchor_name); let Ok(anchor) = vm.ordinary_get(anchor_obj, anchor_si, JsValue::from_js_object(anchor_ptr)) else { return false; }; @@ -1539,7 +1531,7 @@ fn get_iterator(vm: &mut H, value: JsValue) -> Result(vm: &mut H, value: JsValue) -> Result(vm: &mut H, value: JsValue) -> Result n, Err(err) => { @@ -1743,7 +1735,7 @@ pub fn builtin_iter_kind(vm: &mut H, wrapper: JsValue) -> Option<(Bui } // SAFETY: wrapper 刚判定为对象。 let wrapper_obj = unsafe { &*wrapper.as_js_object_ptr() }; - let inner_si = vm.kernel_core().perm_interner().intern(INNER_PROP).0; + let inner_si = vm.perm_intern(INNER_PROP); let inner = match vm.ordinary_get(wrapper_obj, inner_si, wrapper) { Ok(inner) if !inner.is_undefined() => inner, _ => return None, @@ -1900,10 +1892,10 @@ fn current_index(vm: &mut H, wrapper: &JsObject, index_si: u32) -> us /// 构造迭代器结果对象 `{value, done}`(生成器 next/return 结果复用)。 pub fn make_iter_result(vm: &mut H, value: JsValue, done: bool) -> JsValue { - let object_proto = vm.session().builtin_world().object_proto.as_ptr() as *mut JsObject; + let object_proto = vm.builtin_proto(ProtoKind::ObjectProto); let obj = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto))); - let value_si = vm.kernel_core().perm_interner().intern("value").0; - let done_si = vm.kernel_core().perm_interner().intern("done").0; + let value_si = vm.perm_intern("value"); + let done_si = vm.perm_intern("done"); let obj_ref = unsafe { &mut *obj }; vm.set_or_create_prop_value(obj_ref, value_si, value); vm.set_or_create_prop_value(obj_ref, done_si, JsValue::bool(done)); @@ -1913,14 +1905,14 @@ pub fn make_iter_result(vm: &mut H, value: JsValue, done: bool) -> Js /// 构造 native 函数对象并返回:设置函数标记、native 函数项、参数个数与 `name` /// 属性。供迭代器包装器把自己的 next/return 方法装到包装对象上,不经绑定层注册。 pub(crate) fn make_native_function(vm: &mut H, name: &str, native_fn: *const (), arg_count: u8) -> JsValue { - let function_proto = vm.session().builtin_world().function_proto.as_ptr() as *mut JsObject; + let function_proto = vm.builtin_proto(ProtoKind::FunctionProto); let mut func = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(function_proto)); func.set_function(true); // SAFETY: native_fn 来自 NativeFn 函数项。 func.set_native_fn(Some(unsafe { oxide_types::object::NativeFnPtr::from_raw(native_fn) })); func.set_native_arg_count(arg_count); let func = vm.alloc_object(func); - let name_si = vm.kernel_core().perm_interner().intern("name").0; + let name_si = vm.perm_intern("name"); let value = vm.new_string(name); let func_ref = unsafe { &mut *func }; vm.set_or_create_prop_value(func_ref, name_si, value); @@ -1966,7 +1958,7 @@ pub(crate) fn close_iterator(vm: &mut H, iterator: JsValue) { return; } let iter_obj = unsafe { &*iterator.as_js_object_ptr() }; - let return_si = vm.kernel_core().perm_interner().intern("return").0; + let return_si = vm.perm_intern("return"); if let Ok(ret) = vm.ordinary_get(iter_obj, return_si, iterator) { if is_callable(ret) { // return() 的抛错被忽略,其值不得外泄进槽覆盖在途异常。 @@ -2004,9 +1996,9 @@ pub fn iterate_iterator(vm: &mut H, iterator: JsValue, mut on_elem where F: FnMut(&mut H, JsValue) -> Result<(), JsValue>, { - let next_si = vm.kernel_core().perm_interner().intern("next").0; - let done_si = vm.kernel_core().perm_interner().intern("done").0; - let value_si = vm.kernel_core().perm_interner().intern("value").0; + let next_si = vm.perm_intern("next"); + let done_si = vm.perm_intern("done"); + let value_si = vm.perm_intern("value"); let run: Result<(), JsValue> = (|| { loop { let iter_obj = unsafe { &*iterator.as_js_object_ptr() }; @@ -2052,7 +2044,7 @@ fn is_set_value(value: JsValue) -> bool { } fn make_map_set_pair(vm: &mut H, a: JsValue, b: JsValue) -> JsValue { - let array_proto = vm.session().builtin_world().array_proto.as_ptr() as *mut JsObject; + let array_proto = vm.builtin_proto(ProtoKind::ArrayProto); let pair = vm.alloc_object(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(array_proto), 2)); // SAFETY: pair 是刚经统一入口分配的数组 JsObject。 unsafe { @@ -2176,9 +2168,9 @@ pub fn map_set_iterator_next(vm: &mut H, args: &[u8]) -> NativeResult return NativeResult::Err(crate::error::create_type_error(vm, "iterator next called on non-object")); } let wrapper = unsafe { &mut *this_val.as_js_object_ptr() }; - let inner_si = vm.kernel_core().perm_interner().intern(INNER_PROP).0; - let index_si = vm.kernel_core().perm_interner().intern(INDEX_PROP).0; - let mode_si = vm.kernel_core().perm_interner().intern(MODE_PROP).0; + let inner_si = vm.perm_intern(INNER_PROP); + let index_si = vm.perm_intern(INDEX_PROP); + let mode_si = vm.perm_intern(MODE_PROP); let inner = match vm.ordinary_get(wrapper, inner_si, this_val) { Ok(inner) if !inner.is_undefined() => inner, _ => return NativeResult::Err(crate::error::create_type_error(vm, "iterator has no inner collection")), @@ -2204,9 +2196,9 @@ pub(crate) fn make_collection_iterator( std::ptr::null_mut() }; let wrapper = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(proto_ptr))); - let inner_si = vm.kernel_core().perm_interner().intern(INNER_PROP).0; - let index_si = vm.kernel_core().perm_interner().intern(INDEX_PROP).0; - let mode_si = vm.kernel_core().perm_interner().intern(MODE_PROP).0; + let inner_si = vm.perm_intern(INNER_PROP); + let index_si = vm.perm_intern(INDEX_PROP); + let mode_si = vm.perm_intern(MODE_PROP); let wrapper_obj = unsafe { &mut *wrapper }; vm.set_or_create_prop_value(wrapper_obj, inner_si, inner); vm.set_or_create_prop_value(wrapper_obj, index_si, JsValue::int(0)); diff --git a/crates/oxide_builtins/src/json.rs b/crates/oxide_builtins/src/json.rs index f388ca7b..25f23738 100644 --- a/crates/oxide_builtins/src/json.rs +++ b/crates/oxide_builtins/src/json.rs @@ -7,7 +7,7 @@ use oxide_types::value::JsValue; use crate::object::walk_own_keys; -use oxide_runtime_api::{NativeResult, VmHost}; +use oxide_runtime_api::{NativeResult, ProtoKind, VmHost}; /// `JSON.parse(text, reviver)`:解析 JSON 文本为 JS 值(递归下降解析器, /// 逐原始值记录精确源文本切片)。提供 reviver 时以后序遍历逐属性调用 @@ -49,7 +49,7 @@ pub fn json_parse(vm: &mut H, args: &[u8]) -> NativeResult { if reviver_val.is_object() { let rptr = reviver_val.as_js_object_ptr(); if !rptr.is_null() && unsafe { (*rptr).is_function() } { - let empty_si = vm.kernel_core().perm_interner().intern("").0; + let empty_si = vm.perm_intern(""); let holder = create_wrapper(vm, result); let holder_ptr = holder.as_js_object_ptr(); result = match walk_reviver(vm, holder_ptr, empty_si, reviver_val, Some(&parsed)) { @@ -121,8 +121,8 @@ pub fn json_raw_json(vm: &mut H, args: &[u8]) -> NativeResult { // 建 null 原型对象:rawJSON 属性为唯一自身属性,frozen 形态收尾。 let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()); obj.type_tag = JsObject::OBJ_TYPE_RAW_JSON; - let raw_si = vm.kernel_core().perm_interner().intern("rawJSON").0; - let new_shape = vm.kernel_core().shape_forge().make_shape(obj.shape_id(), raw_si); + let raw_si = vm.perm_intern("rawJSON"); + let new_shape = vm.make_shape(obj.shape_id(), raw_si); obj.set_shape_id(new_shape); obj.ensure_hash_props().push(text_val); let obj_ptr = vm.alloc_object(obj); @@ -576,13 +576,13 @@ fn walk_reviver( /// 属性(w/e/c 全 true)——被 reviver 前向替换的值、array/object 节点 /// 与无节点处一律空 context。 fn build_context(vm: &mut H, val: JsValue, node: Option<&JsonNode>) -> JsValue { - let object_proto = vm.session().builtin_world().object_proto.as_ptr() as *mut JsObject; + let object_proto = vm.builtin_proto(ProtoKind::ObjectProto); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto)); if let Some(n) = node { if let Some(src) = n.source.as_ref() { if same_value_as(vm, val, n) { - let source_si = vm.kernel_core().perm_interner().intern("source").0; - let new_shape = vm.kernel_core().shape_forge().make_shape(obj.shape_id(), source_si); + let source_si = vm.perm_intern("source"); + let new_shape = vm.make_shape(obj.shape_id(), source_si); obj.set_shape_id(new_shape); obj.ensure_hash_props().push(vm.new_string(src)); } @@ -647,7 +647,7 @@ fn build_js_value(vm: &mut H, node: &JsonNode) -> JsValue { JsonKind::Number(n) => JsValue::float(*n), JsonKind::String(s) => vm.new_string(s), JsonKind::Array(items) => { - let array_proto = vm.session().builtin_world().array_proto.as_ptr() as *mut JsObject; + let array_proto = vm.builtin_proto(ProtoKind::ArrayProto); let n = items.len(); let array_obj = vm.alloc_object(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(array_proto), n)); @@ -670,13 +670,13 @@ fn build_js_value(vm: &mut H, node: &JsonNode) -> JsValue { } unique.sort_by(|a, b| a.0.cmp(b.0)); - let object_proto = vm.session().builtin_world().object_proto.as_ptr() as *mut JsObject; + let object_proto = vm.builtin_proto(ProtoKind::ObjectProto); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto)); for (key, val) in unique { // 键经字符串规范化:规范数字串("0"/"5")映射整数键,与属性访问统一。 let si = vm.string_key_si(key); let jsv = build_js_value(vm, val); - let new_shape = vm.kernel_core().shape_forge().make_shape(obj.shape_id(), si); + let new_shape = vm.make_shape(obj.shape_id(), si); obj.set_shape_id(new_shape); obj.ensure_hash_props().push(jsv); } @@ -687,10 +687,10 @@ fn build_js_value(vm: &mut H, node: &JsonNode) -> JsValue { } fn create_wrapper(vm: &mut H, value: JsValue) -> JsValue { - let object_proto = vm.session().builtin_world().object_proto.as_ptr() as *mut JsObject; - let empty_si = vm.kernel_core().perm_interner().intern("").0; + let object_proto = vm.builtin_proto(ProtoKind::ObjectProto); + let empty_si = vm.perm_intern(""); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto)); - let new_shape = vm.kernel_core().shape_forge().make_shape(obj.shape_id(), empty_si); + let new_shape = vm.make_shape(obj.shape_id(), empty_si); obj.set_shape_id(new_shape); obj.ensure_hash_props().push(value); let obj_ptr = vm.alloc_object(obj); @@ -764,9 +764,7 @@ fn key_si_to_units(vm: &H, si: u32) -> Vec { if is_int_key(si) { int_key_value(si).to_string().encode_utf16().collect() } else { - vm.kernel_core() - .perm_interner() - .lookup(si) + vm.perm_lookup(si) .map(oxide_kernel::string_forge::decode_key) .unwrap_or_default() } @@ -797,8 +795,8 @@ fn whitelist_element_name(vm: &mut H, elem: JsValue) -> Result