refactor: 内置八文件续迁内核访问器调用至 VmHost 能力方法

This commit is contained in:
2026-10-08 07:37:24 +00:00
parent 376a2a1e9e
commit 8a67117497
10 changed files with 101 additions and 104 deletions
Generated
+19 -19
View File
@@ -1160,7 +1160,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_builtins" name = "oxide_builtins"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"chrono", "chrono",
"fast-float", "fast-float",
@@ -1185,7 +1185,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_bytecode" name = "oxide_bytecode"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"num-bigint", "num-bigint",
"oxide_log", "oxide_log",
@@ -1193,7 +1193,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_cfg" name = "oxide_cfg"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_emit", "oxide_emit",
@@ -1204,7 +1204,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_cli" name = "oxide_cli"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"ansi_term", "ansi_term",
"bumpalo", "bumpalo",
@@ -1226,7 +1226,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_code_cache" name = "oxide_code_cache"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"lru", "lru",
"oxide_bytecode", "oxide_bytecode",
@@ -1235,7 +1235,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_compiler" name = "oxide_compiler"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_cfg", "oxide_cfg",
@@ -1255,7 +1255,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_dce" name = "oxide_dce"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_cfg", "oxide_cfg",
@@ -1269,7 +1269,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_emit" name = "oxide_emit"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"num-bigint", "num-bigint",
"oxc_allocator", "oxc_allocator",
@@ -1284,7 +1284,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_engine" name = "oxide_engine"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_compiler", "oxide_compiler",
@@ -1296,7 +1296,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_ir" name = "oxide_ir"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_log", "oxide_log",
@@ -1305,7 +1305,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_kernel" name = "oxide_kernel"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"dashmap", "dashmap",
@@ -1319,7 +1319,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_liveness" name = "oxide_liveness"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_cfg", "oxide_cfg",
@@ -1331,7 +1331,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_log" name = "oxide_log"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"tracing", "tracing",
"tracing-appender", "tracing-appender",
@@ -1340,7 +1340,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_parser" name = "oxide_parser"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"oxc_allocator", "oxc_allocator",
"oxc_ast", "oxc_ast",
@@ -1355,7 +1355,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_regalloc" name = "oxide_regalloc"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_cfg", "oxide_cfg",
@@ -1371,7 +1371,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_runtime_api" name = "oxide_runtime_api"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"num-bigint", "num-bigint",
"num-traits", "num-traits",
@@ -1384,7 +1384,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_test262" name = "oxide_test262"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"oxide_bytecode", "oxide_bytecode",
"oxide_compiler", "oxide_compiler",
@@ -1402,7 +1402,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_types" name = "oxide_types"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"dashmap", "dashmap",
@@ -1415,7 +1415,7 @@ dependencies = [
[[package]] [[package]]
name = "oxide_vm" name = "oxide_vm"
version = "0.8.73" version = "0.8.74"
dependencies = [ dependencies = [
"bumpalo", "bumpalo",
"chrono", "chrono",
+1 -1
View File
@@ -23,7 +23,7 @@ members = [
] ]
[workspace.package] [workspace.package]
version = "0.8.73" version = "0.8.74"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
rust-version = "1.80" rust-version = "1.80"
+9 -9
View File
@@ -5,7 +5,7 @@ use oxide_types::object::{JsObject, PropAttributes, MAX_DENSE_PROPS};
use oxide_types::private_key::encode_symbol_key; use oxide_types::private_key::encode_symbol_key;
use oxide_types::value::JsValue; use oxide_types::value::JsValue;
use oxide_runtime_api::{NativeResult, VmHost}; use oxide_runtime_api::{NativeResult, ProtoKind, VmHost};
use super::common::{ use super::common::{
array_length_arg, array_type_error, arraylike_get, arraylike_get_or_err, create_new_array, invoke_native_callback, array_length_arg, array_type_error, arraylike_get, arraylike_get_or_err, create_new_array, invoke_native_callback,
@@ -15,7 +15,7 @@ use super::common::{
/// JS `Array()` 构造逻辑:单个数字参数创建指定长度空数组,其余情况把参数作为元素。 /// JS `Array()` 构造逻辑:单个数字参数创建指定长度空数组,其余情况把参数作为元素。
pub fn array_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult { pub fn array_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let proto = vm.session().builtin_world().array_proto.as_ptr() as *mut JsObject; let proto = vm.builtin_proto(ProtoKind::ArrayProto);
let proto_val = JsValue::from_js_object(proto); let proto_val = JsValue::from_js_object(proto);
if args.len() == 2 { if args.len() == 2 {
@@ -65,7 +65,7 @@ pub fn array_is_array<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
if ptr.is_null() { if ptr.is_null() {
return NativeResult::Ok(JsValue::bool(false)); return NativeResult::Ok(JsValue::bool(false));
} }
let array_proto = vm.session().builtin_world().array_proto.as_ptr(); let array_proto = vm.builtin_proto(ProtoKind::ArrayProto);
NativeResult::Ok(JsValue::bool(unsafe { &*ptr }.is_array() || std::ptr::eq(ptr, array_proto))) NativeResult::Ok(JsValue::bool(unsafe { &*ptr }.is_array() || std::ptr::eq(ptr, array_proto)))
} }
@@ -159,9 +159,9 @@ pub fn array_from<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
Ok(it) => it, Ok(it) => it,
Err(err) => return NativeResult::Err(err), Err(err) => return NativeResult::Err(err),
}; };
let next_si = vm.kernel_core().perm_interner().intern("next").0; let next_si = vm.perm_intern("next");
let done_si = vm.kernel_core().perm_interner().intern("done").0; let done_si = vm.perm_intern("done");
let value_si = vm.kernel_core().perm_interner().intern("value").0; let value_si = vm.perm_intern("value");
let mut k = 0usize; let mut k = 0usize;
let iter_result: Result<(), JsValue> = (|| { let iter_result: Result<(), JsValue> = (|| {
loop { loop {
@@ -289,7 +289,7 @@ pub(crate) fn from_engine_error<H: VmHost>(vm: &mut H, err: &str) -> JsValue {
fn construct_array_from_result<H: VmHost>( fn construct_array_from_result<H: VmHost>(
vm: &mut H, c: JsValue, args: &[JsValue], vm: &mut H, c: JsValue, args: &[JsValue],
) -> Result<(*mut JsObject, bool), JsValue> { ) -> Result<(*mut JsObject, bool), JsValue> {
let proto = vm.session().builtin_world().array_proto.as_ptr() as *mut JsObject; let proto = vm.builtin_proto(ProtoKind::ArrayProto);
let proto_val = JsValue::from_js_object(proto); let proto_val = JsValue::from_js_object(proto);
let mut fallback_array = || { let mut fallback_array = || {
let arr = vm.alloc_object(JsObject::new_array(EMPTY_SHAPE_ID, proto_val, 0)); let arr = vm.alloc_object(JsObject::new_array(EMPTY_SHAPE_ID, proto_val, 0));
@@ -319,7 +319,7 @@ pub(crate) fn array_species_create<H: VmHost>(
} }
let o_ptr = o_val.as_js_object_ptr(); let o_ptr = o_val.as_js_object_ptr();
let o_obj = unsafe { &*o_ptr }; let o_obj = unsafe { &*o_ptr };
let ctor_key = vm.kernel_core().perm_interner().intern("constructor").0; let ctor_key = vm.perm_intern("constructor");
let c = match vm.ordinary_get(o_obj, ctor_key, o_val) { let c = match vm.ordinary_get(o_obj, ctor_key, o_val) {
Ok(v) => v, Ok(v) => v,
Err(msg) => return Err(from_engine_error(vm, &msg)), Err(msg) => return Err(from_engine_error(vm, &msg)),
@@ -417,7 +417,7 @@ fn close_iterator<H: VmHost>(vm: &mut H, iterator: JsValue) {
return; return;
} }
let iter_obj = unsafe { &*iterator.as_js_object_ptr() }; 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 let Ok(ret) = vm.ordinary_get(iter_obj, return_si, iterator) {
if ret.is_object() && unsafe { &*ret.as_js_object_ptr() }.is_function() { if ret.is_object() && unsafe { &*ret.as_js_object_ptr() }.is_function() {
// return() 的抛错被忽略,其值不得外泄进槽覆盖在途异常。 // return() 的抛错被忽略,其值不得外泄进槽覆盖在途异常。
@@ -4,7 +4,7 @@ use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
use oxide_types::value::JsValue; use oxide_types::value::JsValue;
use oxide_runtime_api::{NativeResult, VmHost}; use oxide_runtime_api::{NativeResult, ProtoKind, VmHost};
use crate::builtins_debug; use crate::builtins_debug;
use crate::builtins_error; use crate::builtins_error;
@@ -150,11 +150,11 @@ pub(crate) fn make_array_iterator<H: VmHost>(vm: &mut H, this_val: JsValue, kind
Ok(v) => v, Ok(v) => v,
Err(msg) => return Err(array_type_error(vm, &msg)), Err(msg) => return Err(array_type_error(vm, &msg)),
}; };
let array_iter_proto = vm.session().builtin_world().array_iterator_proto.as_ptr() as *mut JsObject; let array_iter_proto = vm.builtin_proto(ProtoKind::ArrayIteratorProto);
let iter = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(array_iter_proto))); let iter = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(array_iter_proto)));
let target_si = vm.kernel_core().perm_interner().intern(ARRAY_ITER_TARGET_PROP).0; let target_si = vm.perm_intern(ARRAY_ITER_TARGET_PROP);
let index_si = vm.kernel_core().perm_interner().intern(ARRAY_ITER_INDEX_PROP).0; let index_si = vm.perm_intern(ARRAY_ITER_INDEX_PROP);
let kind_si = vm.kernel_core().perm_interner().intern(ARRAY_ITER_KIND_PROP).0; let kind_si = vm.perm_intern(ARRAY_ITER_KIND_PROP);
let iter_ref = unsafe { &mut *iter }; let iter_ref = unsafe { &mut *iter };
vm.set_or_create_prop_value(iter_ref, target_si, target); vm.set_or_create_prop_value(iter_ref, target_si, target);
vm.set_or_create_prop_value(iter_ref, index_si, JsValue::int(0)); vm.set_or_create_prop_value(iter_ref, index_si, JsValue::int(0));
@@ -189,9 +189,9 @@ pub fn array_iterator_next<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
return NativeResult::Err(array_type_error(vm, "Array Iterator next called on non-object")); return NativeResult::Err(array_type_error(vm, "Array Iterator next called on non-object"));
} }
let iter = unsafe { &mut *this_val.as_js_object_ptr() }; let iter = unsafe { &mut *this_val.as_js_object_ptr() };
let target_si = vm.kernel_core().perm_interner().intern(ARRAY_ITER_TARGET_PROP).0; let target_si = vm.perm_intern(ARRAY_ITER_TARGET_PROP);
let index_si = vm.kernel_core().perm_interner().intern(ARRAY_ITER_INDEX_PROP).0; let index_si = vm.perm_intern(ARRAY_ITER_INDEX_PROP);
let kind_si = vm.kernel_core().perm_interner().intern(ARRAY_ITER_KIND_PROP).0; let kind_si = vm.perm_intern(ARRAY_ITER_KIND_PROP);
// 内部槽守卫:无 own __target__ 槽的对象(如 Object.create 产物)不是数组 // 内部槽守卫:无 own __target__ 槽的对象(如 Object.create 产物)不是数组
// 迭代器,不得沿原型链读底层迭代器的槽;三槽同批写入,查一槽即全查。 // 迭代器,不得沿原型链读底层迭代器的槽;三槽同批写入,查一槽即全查。
if vm.get_own_property_slot(&*iter, target_si).is_none() { if vm.get_own_property_slot(&*iter, target_si).is_none() {
+13 -16
View File
@@ -5,7 +5,7 @@ use oxide_types::object::{JsObject, NativeFnPtr};
use oxide_types::private_key::{encode_symbol_key, WELL_KNOWN_SYMBOL_SPECIES}; use oxide_types::private_key::{encode_symbol_key, WELL_KNOWN_SYMBOL_SPECIES};
use oxide_types::value::JsValue; use oxide_types::value::JsValue;
use oxide_runtime_api::{NativeResult, VmHost}; use oxide_runtime_api::{NativeResult, ProtoKind, VmHost};
use crate::array::to_integer_or_infinity_bounded; use crate::array::to_integer_or_infinity_bounded;
@@ -89,7 +89,7 @@ fn normalize_index<H: VmHost>(vm: &mut H, value: JsValue, len: usize) -> Result<
/// 默认缓冲区原型 %ArrayBuffer.prototype%(构造器回落路径与各定长建点共用)。 /// 默认缓冲区原型 %ArrayBuffer.prototype%(构造器回落路径与各定长建点共用)。
pub(crate) fn default_array_buffer_proto<H: VmHost>(vm: &H) -> JsValue { pub(crate) fn default_array_buffer_proto<H: VmHost>(vm: &H) -> JsValue {
JsValue::from_js_object(vm.session().builtin_world().array_buffer_proto.as_ptr() as *mut JsObject) JsValue::from_js_object(vm.builtin_proto(ProtoKind::ArrayBufferProto))
} }
/// 分配携给定 proto 与载荷形态(`max_byte_length` 为存储态:0 定长,非 0 可 /// 分配携给定 proto 与载荷形态(`max_byte_length` 为存储态:0 定长,非 0 可
@@ -150,7 +150,7 @@ pub fn drop_array_buffer_native(obj: &mut JsObject) -> u64 {
/// 默认缓冲区原型 %SharedArrayBuffer.prototype%(构造器回落路径与各定长建点共用)。 /// 默认缓冲区原型 %SharedArrayBuffer.prototype%(构造器回落路径与各定长建点共用)。
pub(crate) fn default_shared_array_buffer_proto<H: VmHost>(vm: &H) -> JsValue { pub(crate) fn default_shared_array_buffer_proto<H: VmHost>(vm: &H) -> JsValue {
JsValue::from_js_object(vm.session().builtin_world().shared_array_buffer_proto.as_ptr() as *mut JsObject) JsValue::from_js_object(vm.builtin_proto(ProtoKind::SharedArrayBufferProto))
} }
/// 分配携给定 proto 与载荷形态(`max_byte_length` 为存储态:0 定长,非 0 可 /// 分配携给定 proto 与载荷形态(`max_byte_length` 为存储态:0 定长,非 0 可
@@ -281,7 +281,7 @@ pub fn shared_array_buffer_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> Na
let options_ptr = options.as_js_object_ptr(); let options_ptr = options.as_js_object_ptr();
// SAFETY: is_object 保证指针非空且对象本 session 存活。 // SAFETY: is_object 保证指针非空且对象本 session 存活。
let options_obj = unsafe { &*options_ptr }; let options_obj = unsafe { &*options_ptr };
let si = vm.kernel_core().perm_interner().intern("maxByteLength").0; let si = vm.perm_intern("maxByteLength");
let max_val = match vm.ordinary_get(options_obj, si, options) { let max_val = match vm.ordinary_get(options_obj, si, options) {
Ok(v) => v, Ok(v) => v,
Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)), Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)),
@@ -308,7 +308,7 @@ pub fn shared_array_buffer_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> Na
let nt_ptr = new_target.as_js_object_ptr(); let nt_ptr = new_target.as_js_object_ptr();
// SAFETY: is_object 保证指针非空且对象本 session 存活。 // SAFETY: is_object 保证指针非空且对象本 session 存活。
let nt_obj = unsafe { &*nt_ptr }; let nt_obj = unsafe { &*nt_ptr };
let proto_si = vm.kernel_core().perm_interner().intern("prototype").0; let proto_si = vm.perm_intern("prototype");
let proto_val = match vm.ordinary_get(nt_obj, proto_si, new_target) { let proto_val = match vm.ordinary_get(nt_obj, proto_si, new_target) {
Ok(v) => v, Ok(v) => v,
Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)), Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)),
@@ -482,8 +482,7 @@ pub fn shared_array_buffer_slice<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeRe
let new_len = final_.saturating_sub(first); let new_len = final_.saturating_sub(first);
// 物种读与构造各是 JS 调用窗口:getter/构造器可晋升源。 // 物种读与构造各是 JS 调用窗口:getter/构造器可晋升源。
let default_ctor = let default_ctor = JsValue::from_js_object(vm.builtin_proto(ProtoKind::SharedArrayBufferConstructor));
JsValue::from_js_object(vm.session().builtin_world().shared_array_buffer_constructor.as_ptr() as *mut JsObject);
let ctor = native_try!(ab_species_constructor(vm, this_val, default_ctor)); let ctor = native_try!(ab_species_constructor(vm, this_val, default_ctor));
let new_val = match vm.construct_ctor(ctor, &[JsValue::int(new_len as i32)]) { let new_val = match vm.construct_ctor(ctor, &[JsValue::int(new_len as i32)]) {
Ok(v) => v, Ok(v) => v,
@@ -593,7 +592,7 @@ pub fn array_buffer_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeRes
let options_ptr = options.as_js_object_ptr(); let options_ptr = options.as_js_object_ptr();
// SAFETY: is_object 保证指针非空且对象本 session 存活。 // SAFETY: is_object 保证指针非空且对象本 session 存活。
let options_obj = unsafe { &*options_ptr }; let options_obj = unsafe { &*options_ptr };
let si = vm.kernel_core().perm_interner().intern("maxByteLength").0; let si = vm.perm_intern("maxByteLength");
let max_val = match vm.ordinary_get(options_obj, si, options) { let max_val = match vm.ordinary_get(options_obj, si, options) {
Ok(v) => v, Ok(v) => v,
Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)), Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)),
@@ -620,7 +619,7 @@ pub fn array_buffer_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeRes
let nt_ptr = new_target.as_js_object_ptr(); let nt_ptr = new_target.as_js_object_ptr();
// SAFETY: is_object 保证指针非空且对象本 session 存活。 // SAFETY: is_object 保证指针非空且对象本 session 存活。
let nt_obj = unsafe { &*nt_ptr }; let nt_obj = unsafe { &*nt_ptr };
let proto_si = vm.kernel_core().perm_interner().intern("prototype").0; let proto_si = vm.perm_intern("prototype");
let proto_val = match vm.ordinary_get(nt_obj, proto_si, new_target) { let proto_val = match vm.ordinary_get(nt_obj, proto_si, new_target) {
Ok(v) => v, Ok(v) => v,
Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)), Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)),
@@ -642,7 +641,7 @@ pub fn array_buffer_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeRes
// SAFETY: obj_ptr 为 alloc_object 新建对象,无别名。 // SAFETY: obj_ptr 为 alloc_object 新建对象,无别名。
let obj = unsafe { &mut *obj_ptr }; let obj = unsafe { &mut *obj_ptr };
if let Some(max) = max_opt { if let Some(max) = max_opt {
let si = vm.kernel_core().perm_interner().intern("maxByteLength").0; let si = vm.perm_intern("maxByteLength");
if let Err(err) = vm.define_data_property( if let Err(err) = vm.define_data_property(
obj, obj,
si, si,
@@ -811,7 +810,7 @@ fn ab_resolve_bounds<H: VmHost>(
/// 构造器,非构造器抛 TypeError。 /// 构造器,非构造器抛 TypeError。
fn ab_species_constructor<H: VmHost>(vm: &mut H, o_val: JsValue, default_ctor: JsValue) -> Result<JsValue, JsValue> { fn ab_species_constructor<H: VmHost>(vm: &mut H, o_val: JsValue, default_ctor: JsValue) -> Result<JsValue, JsValue> {
let o_obj = unsafe { &*o_val.as_js_object_ptr() }; let o_obj = unsafe { &*o_val.as_js_object_ptr() };
let ctor_key = vm.kernel_core().perm_interner().intern("constructor").0; let ctor_key = vm.perm_intern("constructor");
let c = match vm.ordinary_get(o_obj, ctor_key, o_val) { let c = match vm.ordinary_get(o_obj, ctor_key, o_val) {
Ok(v) => v, Ok(v) => v,
Err(msg) => return Err(crate::iterator::engine_error(vm, &msg)), Err(msg) => return Err(crate::iterator::engine_error(vm, &msg)),
@@ -873,8 +872,7 @@ pub fn array_buffer_slice<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let new_len = final_.saturating_sub(first); let new_len = final_.saturating_sub(first);
// 物种读与构造各是 JS 调用窗口:getter/构造器可 detach、resize、晋升源。 // 物种读与构造各是 JS 调用窗口:getter/构造器可 detach、resize、晋升源。
let default_ctor = let default_ctor = JsValue::from_js_object(vm.builtin_proto(ProtoKind::ArrayBufferConstructor));
JsValue::from_js_object(vm.session().builtin_world().array_buffer_constructor.as_ptr() as *mut JsObject);
let ctor = native_try!(ab_species_constructor(vm, this_val, default_ctor)); let ctor = native_try!(ab_species_constructor(vm, this_val, default_ctor));
let new_val = match vm.construct_ctor(ctor, &[JsValue::int(new_len as i32)]) { let new_val = match vm.construct_ctor(ctor, &[JsValue::int(new_len as i32)]) {
Ok(v) => v, Ok(v) => v,
@@ -982,10 +980,9 @@ pub fn array_buffer_slice_to_immutable<H: VmHost>(vm: &mut H, args: &[u8]) -> Na
} }
// GetPrototypeFromConstructor(%ArrayBuffer%):prototype 读为 JS 窗口 // GetPrototypeFromConstructor(%ArrayBuffer%):prototype 读为 JS 窗口
// (访问器可被用户重定义),抛错传播;非对象回落默认原型。 // (访问器可被用户重定义),抛错传播;非对象回落默认原型。
let ctor_val = let ctor_val = JsValue::from_js_object(vm.builtin_proto(ProtoKind::ArrayBufferConstructor));
JsValue::from_js_object(vm.session().builtin_world().array_buffer_constructor.as_ptr() as *mut JsObject);
let ctor_obj = unsafe { &*ctor_val.as_js_object_ptr() }; let ctor_obj = unsafe { &*ctor_val.as_js_object_ptr() };
let proto_si = vm.kernel_core().perm_interner().intern("prototype").0; let proto_si = vm.perm_intern("prototype");
let proto_val = match vm.ordinary_get(ctor_obj, proto_si, ctor_val) { let proto_val = match vm.ordinary_get(ctor_obj, proto_si, ctor_val) {
Ok(v) => v, Ok(v) => v,
Err(msg) => return NativeResult::Err(crate::iterator::engine_error(vm, &msg)), Err(msg) => return NativeResult::Err(crate::iterator::engine_error(vm, &msg)),
+9 -9
View File
@@ -2,7 +2,7 @@ use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes}; use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes};
use oxide_types::value::JsValue; use oxide_types::value::JsValue;
use oxide_runtime_api::{to_integer_or_infinity, to_length, to_units_full, NativeResult, VmHost}; use oxide_runtime_api::{to_integer_or_infinity, to_length, to_units_full, NativeResult, ProtoKind, VmHost};
fn invoke_target<H: VmHost>(vm: &mut H, target_val: JsValue, this_val: JsValue, arg_regs: &[u8]) -> NativeResult { fn invoke_target<H: VmHost>(vm: &mut H, target_val: JsValue, this_val: JsValue, arg_regs: &[u8]) -> NativeResult {
let args: Vec<JsValue> = arg_regs.iter().map(|&r| vm.reg(r)).collect(); let args: Vec<JsValue> = arg_regs.iter().map(|&r| vm.reg(r)).collect();
@@ -130,7 +130,7 @@ pub fn function_symbol_has_instance<H: VmHost>(vm: &mut H, args: &[u8]) -> Nativ
} }
// prototype 非对象 → TypeError(OrdinaryHasInstance 唯一抛错点)。 // prototype 非对象 → TypeError(OrdinaryHasInstance 唯一抛错点)。
let proto_si = vm.kernel_core().perm_interner().intern("prototype").0; let proto_si = vm.perm_intern("prototype");
let Some(proto_val) = vm.resolve_property(c_obj, proto_si) else { let Some(proto_val) = vm.resolve_property(c_obj, proto_si) else {
return NativeResult::Err(crate::error::create_type_error( return NativeResult::Err(crate::error::create_type_error(
vm, vm,
@@ -229,7 +229,7 @@ pub fn function_apply<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
if !arr_ptr.is_null() { if !arr_ptr.is_null() {
// SAFETY: is_object 与非空守卫保证存活对象;length/下标读取即时消费,不跨 GC/reset。 // SAFETY: is_object 与非空守卫保证存活对象;length/下标读取即时消费,不跨 GC/reset。
let arr = unsafe { &*arr_ptr }; let arr = unsafe { &*arr_ptr };
let length_si = vm.kernel_core().perm_interner().intern("length").0; let length_si = vm.perm_intern("length");
let count = match vm.ordinary_get(arr, length_si, arr_val) { let count = match vm.ordinary_get(arr, length_si, arr_val) {
Ok(v) => to_length(v).min(oxide_types::private_key::INT_KEY_COUNT as u64) as u32, Ok(v) => to_length(v).min(oxide_types::private_key::INT_KEY_COUNT as u64) as u32,
Err(e) => return NativeResult::Err(to_string_error_value(vm, &e)), Err(e) => return NativeResult::Err(to_string_error_value(vm, &e)),
@@ -279,7 +279,7 @@ pub fn function_bind<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let bound_arg_count = args.len().saturating_sub(2); let bound_arg_count = args.len().saturating_sub(2);
// bound 函数 [[Prototype]] 为 Function.prototype(BoundFunctionCreate 语义)。 // bound 函数 [[Prototype]] 为 Function.prototype(BoundFunctionCreate 语义)。
let fn_proto_val = JsValue::from_js_object(vm.session().builtin_world().function_proto.as_ptr() as *mut JsObject); let fn_proto_val = JsValue::from_js_object(vm.builtin_proto(ProtoKind::FunctionProto));
let wrapper = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, fn_proto_val)); let wrapper = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, fn_proto_val));
unsafe { unsafe {
(*wrapper).set_function(true); (*wrapper).set_function(true);
@@ -295,8 +295,8 @@ pub fn function_bind<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
// 第 2 号 shape 属性(保留键),不与用户 own 属性共享下标空间。bound 函数 // 第 2 号 shape 属性(保留键),不与用户 own 属性共享下标空间。bound 函数
// 无 own caller/arguments(BoundFunctionCreate 语义),经原型链继承 FP // 无 own caller/arguments(BoundFunctionCreate 语义),经原型链继承 FP
// 受限访问器,访问即抛 TypeError。 // 受限访问器,访问即抛 TypeError。
let length_si = vm.kernel_core().perm_interner().intern("length").0; let length_si = vm.perm_intern("length");
let name_si = vm.kernel_core().perm_interner().intern("name").0; let name_si = vm.perm_intern("name");
let attrs = PropAttributes::new(false, false, true); let attrs = PropAttributes::new(false, false, true);
// 全部 shape 属性(length/name)须先于状态数据定义完成,保证 shape 槽位 // 全部 shape 属性(length/name)须先于状态数据定义完成,保证 shape 槽位
@@ -350,7 +350,7 @@ pub fn function_bind<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
// shape 槽位共享下标,状态值若直接裸推包装器存储槽 2+,用户新增 own 属性时 // shape 槽位共享下标,状态值若直接裸推包装器存储槽 2+,用户新增 own 属性时
// shape 槽位与存储下标错位(读写互串)。状态对象内部存储不占 shape 槽位, // shape 槽位与存储下标错位(读写互串)。状态对象内部存储不占 shape 槽位,
// 经保留键作为包装器固定第 2 号 shape 属性暴露,用户代码不可见。 // 经保留键作为包装器固定第 2 号 shape 属性暴露,用户代码不可见。
let object_proto = vm.session().builtin_world().object_proto.as_ptr() as *mut JsObject; let object_proto = vm.builtin_proto(ProtoKind::ObjectProto);
let state = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto))); let state = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(object_proto)));
unsafe { unsafe {
let state_props = (*state).ensure_hash_props(); let state_props = (*state).ensure_hash_props();
@@ -360,7 +360,7 @@ pub fn function_bind<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
state_props.push(vm.reg(r)); state_props.push(vm.reg(r));
} }
} }
let state_si = vm.kernel_core().perm_interner().intern("\u{0}bound-state").0; let state_si = vm.perm_intern("\u{0}bound-state");
if let Err(e) = vm.define_data_property(unsafe { &mut *wrapper }, state_si, JsValue::from_js_object(state), attrs) { if let Err(e) = vm.define_data_property(unsafe { &mut *wrapper }, state_si, JsValue::from_js_object(state), attrs) {
return NativeResult::Err(crate::error::create_type_error(vm, &e)); return NativeResult::Err(crate::error::create_type_error(vm, &e));
} }
@@ -408,7 +408,7 @@ pub fn function_to_string<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
)); ));
} }
let name_si = vm.kernel_core().perm_interner().intern("name").0; let name_si = vm.perm_intern("name");
let name = vm let name = vm
.resolve_property(func, name_si) .resolve_property(func, name_si)
.and_then(|v| vm.lookup_str(v)) .and_then(|v| vm.lookup_str(v))
+13 -13
View File
@@ -6,7 +6,7 @@ use oxide_types::value::JsValue;
use crate::set::SetKey; use crate::set::SetKey;
use oxide_runtime_api::{NativeResult, VmHost}; use oxide_runtime_api::{NativeResult, ProtoKind, VmHost};
use crate::builtins_debug; use crate::builtins_debug;
@@ -143,7 +143,7 @@ fn new_map_inner() -> *mut MapInner {
} }
fn alloc_map<H: VmHost>(vm: &mut H) -> *mut JsObject { fn alloc_map<H: VmHost>(vm: &mut H) -> *mut JsObject {
let map_proto = vm.session().builtin_world().map_proto.as_ptr() as *mut JsObject; let map_proto = vm.builtin_proto(ProtoKind::MapProto);
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(map_proto)); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(map_proto));
obj.set_map(true); obj.set_map(true);
let inner = new_map_inner(); let inner = new_map_inner();
@@ -213,7 +213,7 @@ pub fn drop_map_native(obj: &mut JsObject) -> u64 {
pub fn map_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult { pub fn map_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] }); let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let is_new_call = this_val.is_object() && { let is_new_call = this_val.is_object() && {
let map_proto = vm.session().builtin_world().map_proto.as_ptr() as *mut JsObject; let map_proto = vm.builtin_proto(ProtoKind::MapProto);
// 沿原型链查找 Map.prototype:`new Map()` 直接命中,子类 `super()` 经 // 沿原型链查找 Map.prototype:`new Map()` 直接命中,子类 `super()` 经
// 子类 prototype 链命中;普通调用(global/undefined)不命中。 // 子类 prototype 链命中;普通调用(global/undefined)不命中。
let this_ptr = this_val.as_js_object_ptr(); let this_ptr = this_val.as_js_object_ptr();
@@ -250,7 +250,7 @@ pub fn map_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let iterable = vm.reg(args[1]); let iterable = vm.reg(args[1]);
if !iterable.is_undefined() && !iterable.is_null() { if !iterable.is_undefined() && !iterable.is_null() {
let map_ref = unsafe { &*map_obj }; let map_ref = unsafe { &*map_obj };
let set_si = vm.kernel_core().perm_interner().intern("set").0; let set_si = vm.perm_intern("set");
let adder = match vm.ordinary_get(map_ref, set_si, map_val) { let adder = match vm.ordinary_get(map_ref, set_si, map_val) {
Ok(v) => v, Ok(v) => v,
Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)), Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)),
@@ -455,7 +455,7 @@ pub fn map_size<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
pub fn map_entries<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult { pub fn map_entries<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] }); let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let _inner = native_try!(get_map_inner(vm, this_val)); let _inner = native_try!(get_map_inner(vm, this_val));
let proto_ptr = vm.session().builtin_world().map_iterator_proto.as_ptr() as *mut JsObject; let proto_ptr = vm.builtin_proto(ProtoKind::MapIteratorProto);
NativeResult::Ok(crate::iterator::make_collection_iterator( NativeResult::Ok(crate::iterator::make_collection_iterator(
vm, vm,
this_val, this_val,
@@ -468,7 +468,7 @@ pub fn map_entries<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
pub fn map_values<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult { pub fn map_values<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] }); let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let _inner = native_try!(get_map_inner(vm, this_val)); let _inner = native_try!(get_map_inner(vm, this_val));
let proto_ptr = vm.session().builtin_world().map_iterator_proto.as_ptr() as *mut JsObject; let proto_ptr = vm.builtin_proto(ProtoKind::MapIteratorProto);
NativeResult::Ok(crate::iterator::make_collection_iterator( NativeResult::Ok(crate::iterator::make_collection_iterator(
vm, vm,
this_val, this_val,
@@ -481,7 +481,7 @@ pub fn map_values<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
pub fn map_keys<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult { pub fn map_keys<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] }); let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let _inner = native_try!(get_map_inner(vm, this_val)); let _inner = native_try!(get_map_inner(vm, this_val));
let proto_ptr = vm.session().builtin_world().map_iterator_proto.as_ptr() as *mut JsObject; let proto_ptr = vm.builtin_proto(ProtoKind::MapIteratorProto);
NativeResult::Ok(crate::iterator::make_collection_iterator( NativeResult::Ok(crate::iterator::make_collection_iterator(
vm, vm,
this_val, this_val,
@@ -536,19 +536,19 @@ pub fn map_group_by<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
return NativeResult::Err(crate::error::create_type_error(vm, "Map.groupBy: iterator is not an object")); return NativeResult::Err(crate::error::create_type_error(vm, "Map.groupBy: iterator is not an object"));
} }
let iter_obj = unsafe { &*iter_val.as_js_object_ptr() }; let iter_obj = unsafe { &*iter_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_fn = match vm.ordinary_get(iter_obj, next_si, iter_val) { let next_fn = match vm.ordinary_get(iter_obj, next_si, iter_val) {
Ok(f) => f, Ok(f) => f,
Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)), Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)),
}; };
// 读取 Map.set / Map.get 方法。 // 读取 Map.set / Map.get 方法。
let map_ref = unsafe { &*map_obj }; let map_ref = unsafe { &*map_obj };
let set_si = vm.kernel_core().perm_interner().intern("set").0; let set_si = vm.perm_intern("set");
let adder = match vm.ordinary_get(map_ref, set_si, map_val) { let adder = match vm.ordinary_get(map_ref, set_si, map_val) {
Ok(v) => v, Ok(v) => v,
Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)), Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)),
}; };
let get_si = vm.kernel_core().perm_interner().intern("get").0; let get_si = vm.perm_intern("get");
let getter = match vm.ordinary_get(map_ref, get_si, map_val) { let getter = match vm.ordinary_get(map_ref, get_si, map_val) {
Ok(v) => v, Ok(v) => v,
Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)), Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)),
@@ -574,7 +574,7 @@ pub fn map_group_by<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
)); ));
} }
let nr = unsafe { &*next_result.as_js_object_ptr() }; let nr = unsafe { &*next_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 = match vm.ordinary_get(nr, done_si, next_result) { let done = match vm.ordinary_get(nr, done_si, next_result) {
Ok(v) => oxide_runtime_api::to_boolean(v), Ok(v) => oxide_runtime_api::to_boolean(v),
Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)), Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)),
@@ -582,7 +582,7 @@ pub fn map_group_by<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
if done { if done {
break; break;
} }
let value_si = vm.kernel_core().perm_interner().intern("value").0; let value_si = vm.perm_intern("value");
let element = match vm.ordinary_get(nr, value_si, next_result) { let element = match vm.ordinary_get(nr, value_si, next_result) {
Ok(v) => v, Ok(v) => v,
Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)), Err(e) => return NativeResult::Err(crate::iterator::engine_error(vm, &e)),
@@ -614,7 +614,7 @@ pub fn map_group_by<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
{ {
existing existing
} else { } else {
let arr_proto = vm.session().builtin_world().array_proto.as_ptr() as *mut JsObject; let arr_proto = vm.builtin_proto(ProtoKind::ArrayProto);
let arr = vm.alloc_object(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(arr_proto), 0)); let arr = vm.alloc_object(JsObject::new_array(EMPTY_SHAPE_ID, JsValue::from_js_object(arr_proto), 0));
let new_arr_val = JsValue::from_js_object(arr); let new_arr_val = JsValue::from_js_object(arr);
if let Err(e) = vm.call_function_sync(adder, map_val, &[group_key, new_arr_val]) { if let Err(e) = vm.call_function_sync(adder, map_val, &[group_key, new_arr_val]) {
+6 -6
View File
@@ -422,7 +422,7 @@ fn remove_export_slot<H: VmHost>(vm: &mut H, obj: &mut JsObject, name_si: u32) {
obj.set_shape_id(EMPTY_SHAPE_ID); obj.set_shape_id(EMPTY_SHAPE_ID);
obj.clear_props(); obj.clear_props();
for (si, value, meta) in retained.drain(..).chain(symbols) { for (si, value, meta) in retained.drain(..).chain(symbols) {
let shape = vm.kernel_core().shape_forge().make_shape(obj.shape_id(), si); let shape = vm.make_shape(obj.shape_id(), si);
obj.set_shape_id(shape); obj.set_shape_id(shape);
let pos = obj.push_prop(value); let pos = obj.push_prop(value);
if let Some(meta) = meta { if let Some(meta) = meta {
@@ -548,8 +548,8 @@ pub fn module_set_reexport<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
if ns_table_ptr(obj).is_null() { if ns_table_ptr(obj).is_null() {
install_ns_table(obj); install_ns_table(obj);
} }
let path_id = vm.kernel_core().perm_interner().intern(&dep_path).0; let path_id = vm.perm_intern(&dep_path);
let binding_id = vm.kernel_core().perm_interner().intern(&imported).0; let binding_id = vm.perm_intern(&imported);
let origin = ModuleNsOrigin::Reexport { let origin = ModuleNsOrigin::Reexport {
path_id, path_id,
binding_id, binding_id,
@@ -706,9 +706,9 @@ pub fn module_star<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let Some(src_path) = vm.lookup_str(src_path_val) else { let Some(src_path) = vm.lookup_str(src_path_val) else {
return type_error(vm, "__moduleStar: source path is not a string"); return type_error(vm, "__moduleStar: source path is not a string");
}; };
let src_path_id = vm.kernel_core().perm_interner().intern(&src_path).0; let src_path_id = vm.perm_intern(&src_path);
let src = unsafe { &*src_ptr }; let src = unsafe { &*src_ptr };
let default_si = vm.kernel_core().perm_interner().intern("default").0; let default_si = vm.perm_intern("default");
let keys = crate::object::walk_own_keys(vm, src); let keys = crate::object::walk_own_keys(vm, src);
let dst = unsafe { &mut *dst_ptr }; let dst = unsafe { &mut *dst_ptr };
for (name_si, pos) in keys { for (name_si, pos) in keys {
@@ -844,7 +844,7 @@ pub fn module_data<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
_ => return type_error(vm, "__moduleData: unsupported data kind"), _ => return type_error(vm, "__moduleData: unsupported data kind"),
}; };
let obj = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null())); let obj = vm.alloc_object(JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::null()));
let default_si = vm.kernel_core().perm_interner().intern("default").0; let default_si = vm.perm_intern("default");
let obj_ref = unsafe { &mut *obj }; let obj_ref = unsafe { &mut *obj };
if let Err(e) = vm.define_data_property(obj_ref, default_si, default_val, ns_attrs()) { if let Err(e) = vm.define_data_property(obj_ref, default_si, default_val, ns_attrs()) {
return NativeResult::Err(crate::error::create_error(vm, &e)); return NativeResult::Err(crate::error::create_error(vm, &e));
+14 -14
View File
@@ -4,7 +4,7 @@ use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
use oxide_types::value::{JsType, JsValue}; use oxide_types::value::{JsType, JsValue};
use oxide_runtime_api::{bigint_data, same_value_zero, NativeResult, VmHost}; use oxide_runtime_api::{bigint_data, same_value_zero, NativeResult, ProtoKind, VmHost};
macro_rules! native_try { macro_rules! native_try {
($expr:expr) => { ($expr:expr) => {
@@ -120,7 +120,7 @@ fn new_set_inner() -> *mut SetInner {
} }
fn alloc_set<H: VmHost>(vm: &mut H) -> *mut JsObject { fn alloc_set<H: VmHost>(vm: &mut H) -> *mut JsObject {
let set_proto = vm.session().builtin_world().set_proto.as_ptr() as *mut JsObject; let set_proto = vm.builtin_proto(ProtoKind::SetProto);
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(set_proto)); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(set_proto));
obj.set_set(true); obj.set_set(true);
let inner = new_set_inner(); let inner = new_set_inner();
@@ -183,7 +183,7 @@ pub fn drop_set_native(obj: &mut JsObject) -> u64 {
pub fn set_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult { pub fn set_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] }); let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let is_new_call = this_val.is_object() && { let is_new_call = this_val.is_object() && {
let set_proto = vm.session().builtin_world().set_proto.as_ptr() as *mut JsObject; let set_proto = vm.builtin_proto(ProtoKind::SetProto);
// 沿原型链查找 Set.prototype:`new Set()` 直接命中,子类 `super()` 经 // 沿原型链查找 Set.prototype:`new Set()` 直接命中,子类 `super()` 经
// 子类 prototype 链命中;普通调用(global/undefined)不命中。 // 子类 prototype 链命中;普通调用(global/undefined)不命中。
let this_ptr = this_val.as_js_object_ptr(); let this_ptr = this_val.as_js_object_ptr();
@@ -220,7 +220,7 @@ pub fn set_constructor<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let iterable = vm.reg(args[1]); let iterable = vm.reg(args[1]);
if !iterable.is_undefined() && !iterable.is_null() { if !iterable.is_undefined() && !iterable.is_null() {
let set_ref = unsafe { &*set_obj }; let set_ref = unsafe { &*set_obj };
let add_si = vm.kernel_core().perm_interner().intern("add").0; let add_si = vm.perm_intern("add");
let adder = match vm.ordinary_get(set_ref, add_si, set_val) { let adder = match vm.ordinary_get(set_ref, add_si, set_val) {
Ok(v) => v, Ok(v) => v,
Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)), Err(err) => return NativeResult::Err(crate::iterator::engine_error(vm, &err)),
@@ -315,7 +315,7 @@ pub fn set_size<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
pub fn set_entries<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult { pub fn set_entries<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] }); let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let _inner = native_try!(get_set_inner(vm, this_val)); let _inner = native_try!(get_set_inner(vm, this_val));
let proto_ptr = vm.session().builtin_world().set_iterator_proto.as_ptr() as *mut JsObject; let proto_ptr = vm.builtin_proto(ProtoKind::SetIteratorProto);
NativeResult::Ok(crate::iterator::make_collection_iterator( NativeResult::Ok(crate::iterator::make_collection_iterator(
vm, vm,
this_val, this_val,
@@ -328,7 +328,7 @@ pub fn set_entries<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
pub fn set_values<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult { pub fn set_values<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] }); let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let _inner = native_try!(get_set_inner(vm, this_val)); let _inner = native_try!(get_set_inner(vm, this_val));
let proto_ptr = vm.session().builtin_world().set_iterator_proto.as_ptr() as *mut JsObject; let proto_ptr = vm.builtin_proto(ProtoKind::SetIteratorProto);
NativeResult::Ok(crate::iterator::make_collection_iterator( NativeResult::Ok(crate::iterator::make_collection_iterator(
vm, vm,
this_val, this_val,
@@ -342,7 +342,7 @@ pub fn set_keys<H: VmHost>(vm: &mut H, args: &[u8]) -> NativeResult {
let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] }); let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] });
let _inner = native_try!(get_set_inner(vm, this_val)); let _inner = native_try!(get_set_inner(vm, this_val));
// Set 的 keys() 是 values() 的别名——返回同样的逐元素迭代器。 // Set 的 keys() 是 values() 的别名——返回同样的逐元素迭代器。
let proto_ptr = vm.session().builtin_world().set_iterator_proto.as_ptr() as *mut JsObject; let proto_ptr = vm.builtin_proto(ProtoKind::SetIteratorProto);
NativeResult::Ok(crate::iterator::make_collection_iterator( NativeResult::Ok(crate::iterator::make_collection_iterator(
vm, vm,
this_val, this_val,
@@ -365,7 +365,7 @@ fn get_set_record<H: VmHost>(vm: &mut H, other: JsValue) -> Result<(JsValue, f64
return Err(crate::error::create_type_error(vm, "argument is not an object")); return Err(crate::error::create_type_error(vm, "argument is not an object"));
} }
let obj = unsafe { &*other.as_js_object_ptr() }; let obj = unsafe { &*other.as_js_object_ptr() };
let size_si = vm.kernel_core().perm_interner().intern("size").0; let size_si = vm.perm_intern("size");
let raw_size = vm let raw_size = vm
.ordinary_get(obj, size_si, other) .ordinary_get(obj, size_si, other)
.map_err(|e| crate::iterator::engine_error(vm, &e))?; .map_err(|e| crate::iterator::engine_error(vm, &e))?;
@@ -376,14 +376,14 @@ fn get_set_record<H: VmHost>(vm: &mut H, other: JsValue) -> Result<(JsValue, f64
if num_size.is_nan() { if num_size.is_nan() {
return Err(crate::error::create_type_error(vm, "size must be a number")); return Err(crate::error::create_type_error(vm, "size must be a number"));
} }
let has_si = vm.kernel_core().perm_interner().intern("has").0; let has_si = vm.perm_intern("has");
let has = vm let has = vm
.ordinary_get(obj, has_si, other) .ordinary_get(obj, has_si, other)
.map_err(|e| crate::iterator::engine_error(vm, &e))?; .map_err(|e| crate::iterator::engine_error(vm, &e))?;
if !crate::iterator::is_callable(has) { if !crate::iterator::is_callable(has) {
return Err(crate::error::create_type_error(vm, "has must be callable")); return Err(crate::error::create_type_error(vm, "has must be callable"));
} }
let keys_si = vm.kernel_core().perm_interner().intern("keys").0; let keys_si = vm.perm_intern("keys");
let keys = vm let keys = vm
.ordinary_get(obj, keys_si, other) .ordinary_get(obj, keys_si, other)
.map_err(|e| crate::iterator::engine_error(vm, &e))?; .map_err(|e| crate::iterator::engine_error(vm, &e))?;
@@ -406,7 +406,7 @@ fn normalize_neg_zero(value: JsValue) -> JsValue {
/// 用一个已填充的 `SetInner` 创建普通 Set 对象(原型为 Set.prototype)。 /// 用一个已填充的 `SetInner` 创建普通 Set 对象(原型为 Set.prototype)。
fn alloc_set_with_inner<H: VmHost>(vm: &mut H, inner: SetInner) -> JsValue { fn alloc_set_with_inner<H: VmHost>(vm: &mut H, inner: SetInner) -> JsValue {
let set_proto = vm.session().builtin_world().set_proto.as_ptr() as *mut JsObject; let set_proto = vm.builtin_proto(ProtoKind::SetProto);
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(set_proto)); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, JsValue::from_js_object(set_proto));
obj.set_set(true); obj.set_set(true);
obj.set_native_data(Box::into_raw(Box::new(inner)) as *mut u8); obj.set_native_data(Box::into_raw(Box::new(inner)) as *mut u8);
@@ -441,9 +441,9 @@ where
if !iter.is_object() { if !iter.is_object() {
return Err(crate::error::create_type_error(vm, "keys() result is not an object")); return Err(crate::error::create_type_error(vm, "keys() result is not an object"));
} }
let next_si = vm.kernel_core().perm_interner().intern("next").0; let next_si = vm.perm_intern("next");
let done_si = vm.kernel_core().perm_interner().intern("done").0; let done_si = vm.perm_intern("done");
let value_si = vm.kernel_core().perm_interner().intern("value").0; let value_si = vm.perm_intern("value");
let mut flow = KeysFlow::Continue; let mut flow = KeysFlow::Continue;
let run: Result<(), JsValue> = (|| { let run: Result<(), JsValue> = (|| {
loop { loop {
+9 -9
View File
@@ -16,7 +16,7 @@
use num_traits::ToPrimitive; use num_traits::ToPrimitive;
use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
use oxide_runtime_api::{to_number, to_string, NativeResult, VmHost}; use oxide_runtime_api::{to_number, to_string, NativeResult, ProtoKind, VmHost};
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
use oxide_types::value::JsValue; use oxide_types::value::JsValue;
@@ -166,7 +166,7 @@ pub(crate) fn is_ctor_call<H: VmHost>(vm: &mut H, args: &[u8], proto_ptr: *const
} }
pub(crate) fn make_instant<H: VmHost>(vm: &mut H, epoch_ns: i128) -> NativeResult { pub(crate) fn make_instant<H: VmHost>(vm: &mut H, epoch_ns: i128) -> NativeResult {
let proto = JsValue::from_js_object(vm.session().builtin_world().instant_proto.as_ptr() as *mut JsObject); let proto = JsValue::from_js_object(vm.builtin_proto(ProtoKind::InstantProto));
let epoch_value = vm.new_bigint(num_bigint::BigInt::from(epoch_ns)); let epoch_value = vm.new_bigint(num_bigint::BigInt::from(epoch_ns));
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto);
obj.type_tag = JsObject::OBJ_TYPE_INSTANT; obj.type_tag = JsObject::OBJ_TYPE_INSTANT;
@@ -177,7 +177,7 @@ pub(crate) fn make_instant<H: VmHost>(vm: &mut H, epoch_ns: i128) -> NativeResul
pub(crate) fn make_zoned_date_time<H: VmHost>( pub(crate) fn make_zoned_date_time<H: VmHost>(
vm: &mut H, epoch_ns: i128, time_zone_id: &str, calendar: &str, vm: &mut H, epoch_ns: i128, time_zone_id: &str, calendar: &str,
) -> NativeResult { ) -> NativeResult {
let proto = JsValue::from_js_object(vm.session().builtin_world().zoned_date_time_proto.as_ptr() as *mut JsObject); let proto = JsValue::from_js_object(vm.builtin_proto(ProtoKind::ZonedDateTimeProto));
let epoch_value = vm.new_bigint(num_bigint::BigInt::from(epoch_ns)); let epoch_value = vm.new_bigint(num_bigint::BigInt::from(epoch_ns));
let time_zone_value = vm.new_string(time_zone_id); let time_zone_value = vm.new_string(time_zone_id);
let calendar_value = vm.new_string(calendar); let calendar_value = vm.new_string(calendar);
@@ -1332,7 +1332,7 @@ pub(crate) fn local_to_epoch_ns(year: i32, month: u32, day: u32, time_ns: f64, o
} }
pub(crate) fn make_plain_date<H: VmHost>(vm: &mut H, year: i32, month: u32, day: u32, calendar: &str) -> NativeResult { pub(crate) fn make_plain_date<H: VmHost>(vm: &mut H, year: i32, month: u32, day: u32, calendar: &str) -> NativeResult {
let proto = JsValue::from_js_object(vm.session().builtin_world().plain_date_proto.as_ptr() as *mut JsObject); let proto = JsValue::from_js_object(vm.builtin_proto(ProtoKind::PlainDateProto));
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto);
obj.type_tag = JsObject::OBJ_TYPE_PLAIN_DATE; obj.type_tag = JsObject::OBJ_TYPE_PLAIN_DATE;
obj.set_prop_at(0, JsValue::float(year as f64)); obj.set_prop_at(0, JsValue::float(year as f64));
@@ -1343,7 +1343,7 @@ pub(crate) fn make_plain_date<H: VmHost>(vm: &mut H, year: i32, month: u32, day:
} }
pub(crate) fn make_plain_time<H: VmHost>(vm: &mut H, total_ns: f64) -> NativeResult { pub(crate) fn make_plain_time<H: VmHost>(vm: &mut H, total_ns: f64) -> NativeResult {
let proto = JsValue::from_js_object(vm.session().builtin_world().plain_time_proto.as_ptr() as *mut JsObject); let proto = JsValue::from_js_object(vm.builtin_proto(ProtoKind::PlainTimeProto));
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto);
obj.type_tag = JsObject::OBJ_TYPE_PLAIN_TIME; obj.type_tag = JsObject::OBJ_TYPE_PLAIN_TIME;
obj.set_prop_at(0, JsValue::float(total_ns)); obj.set_prop_at(0, JsValue::float(total_ns));
@@ -1353,7 +1353,7 @@ pub(crate) fn make_plain_time<H: VmHost>(vm: &mut H, total_ns: f64) -> NativeRes
pub(crate) fn make_plain_date_time<H: VmHost>( pub(crate) fn make_plain_date_time<H: VmHost>(
vm: &mut H, year: i32, month: u32, day: u32, total_ns: f64, calendar: &str, vm: &mut H, year: i32, month: u32, day: u32, total_ns: f64, calendar: &str,
) -> NativeResult { ) -> NativeResult {
let proto = JsValue::from_js_object(vm.session().builtin_world().plain_date_time_proto.as_ptr() as *mut JsObject); let proto = JsValue::from_js_object(vm.builtin_proto(ProtoKind::PlainDateTimeProto));
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto);
obj.type_tag = JsObject::OBJ_TYPE_PLAIN_DATE_TIME; obj.type_tag = JsObject::OBJ_TYPE_PLAIN_DATE_TIME;
obj.set_prop_at(0, JsValue::float(year as f64)); obj.set_prop_at(0, JsValue::float(year as f64));
@@ -1365,7 +1365,7 @@ pub(crate) fn make_plain_date_time<H: VmHost>(
} }
pub(crate) fn make_duration<H: VmHost>(vm: &mut H, values: [f64; 10]) -> NativeResult { pub(crate) fn make_duration<H: VmHost>(vm: &mut H, values: [f64; 10]) -> NativeResult {
let proto = JsValue::from_js_object(vm.session().builtin_world().duration_proto.as_ptr() as *mut JsObject); let proto = JsValue::from_js_object(vm.builtin_proto(ProtoKind::DurationProto));
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto);
obj.type_tag = JsObject::OBJ_TYPE_DURATION; obj.type_tag = JsObject::OBJ_TYPE_DURATION;
for (index, value) in values.into_iter().enumerate() { for (index, value) in values.into_iter().enumerate() {
@@ -1382,7 +1382,7 @@ pub(crate) fn make_duration<H: VmHost>(vm: &mut H, values: [f64; 10]) -> NativeR
pub(crate) fn make_plain_month_day<H: VmHost>( pub(crate) fn make_plain_month_day<H: VmHost>(
vm: &mut H, month: u32, day: u32, ref_year: i32, calendar: &str, vm: &mut H, month: u32, day: u32, ref_year: i32, calendar: &str,
) -> NativeResult { ) -> NativeResult {
let proto = JsValue::from_js_object(vm.session().builtin_world().plain_month_day_proto.as_ptr() as *mut JsObject); let proto = JsValue::from_js_object(vm.builtin_proto(ProtoKind::PlainMonthDayProto));
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto);
obj.type_tag = JsObject::OBJ_TYPE_PLAIN_MONTH_DAY; obj.type_tag = JsObject::OBJ_TYPE_PLAIN_MONTH_DAY;
obj.set_prop_at(0, JsValue::float(month as f64)); obj.set_prop_at(0, JsValue::float(month as f64));
@@ -1397,7 +1397,7 @@ pub(crate) fn make_plain_month_day<H: VmHost>(
pub(crate) fn make_plain_year_month<H: VmHost>( pub(crate) fn make_plain_year_month<H: VmHost>(
vm: &mut H, year: i32, month: u32, ref_day: u32, calendar: &str, vm: &mut H, year: i32, month: u32, ref_day: u32, calendar: &str,
) -> NativeResult { ) -> NativeResult {
let proto = JsValue::from_js_object(vm.session().builtin_world().plain_year_month_proto.as_ptr() as *mut JsObject); let proto = JsValue::from_js_object(vm.builtin_proto(ProtoKind::PlainYearMonthProto));
let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto); let mut obj = JsObject::new_empty(EMPTY_SHAPE_ID, proto);
obj.type_tag = JsObject::OBJ_TYPE_PLAIN_YEAR_MONTH; obj.type_tag = JsObject::OBJ_TYPE_PLAIN_YEAR_MONTH;
obj.set_prop_at(0, JsValue::float(year as f64)); obj.set_prop_at(0, JsValue::float(year as f64));