refactor: 统一调用调度并安全化 IC 缓存

This commit is contained in:
爱特每羊队
2026-06-10 16:17:35 +08:00
parent 3787bc336e
commit 625647e489
27 changed files with 1284 additions and 847 deletions
+17 -15
View File
@@ -1,5 +1,5 @@
use oxide_types::mem::P;
use oxide_types::object::{JsObject, PropAttributes};
use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes};
use oxide_types::value::JsValue;
use crate::shape_forge::{ShapeForge, EMPTY_SHAPE_ID};
@@ -7,9 +7,12 @@ use crate::string_forge::StringForge;
#[macro_export]
macro_rules! bind_method {
($world:expr, $target:expr, $sf:expr, $sh:expr, $name:literal, $func:expr, $nargs:expr) => {
let _ = $world.bind_method($target, $sh, $sf, $name, $func as *const (), $nargs);
};
($world:expr, $target:expr, $sf:expr, $sh:expr, $name:literal, $func:expr, $nargs:expr) => {{
let _raw: *const () = $func as *const ();
// SAFETY: $func is a NativeFn fn-item; a fn-item coerced to *const () is always valid.
let _func_ptr = unsafe { oxide_types::object::NativeFnPtr::from_raw(_raw) };
let _ = $world.bind_method($target, $sh, $sf, $name, _func_ptr, $nargs);
}};
}
#[macro_export]
@@ -24,17 +27,14 @@ macro_rules! bind_methods {
macro_rules! bind_methods_static {
($target:expr, $sf:expr, $sh:expr, $wrapper_proto:expr,
$(($name:literal, $func:expr, $nargs:expr)),* $(,)?) => {
$(
$({
let _raw: *const () = $func as *const ();
// SAFETY: $func is a NativeFn fn-item; valid to coerce and wrap.
let _func_ptr = unsafe { oxide_types::object::NativeFnPtr::from_raw(_raw) };
let _ = $crate::builtin::BuiltinWorld::bind_method_static(
$target,
$sh,
$sf,
$name,
$func,
$nargs,
$wrapper_proto,
$target, $sh, $sf, $name, _func_ptr, $nargs, $wrapper_proto,
);
)*
})*
};
}
@@ -589,7 +589,7 @@ impl BuiltinWorld {
pub fn bind_method(
&self, proto: &mut JsObject, shape_forge: &ShapeForge, string_forge: &StringForge, method_name: &str,
native_fn_ptr: *const (), arg_count: u8,
native_fn_ptr: NativeFnPtr, arg_count: u8,
) -> Result<(), String> {
Self::bind_method_static(
proto,
@@ -604,7 +604,7 @@ impl BuiltinWorld {
pub fn bind_method_static(
proto: &mut JsObject, shape_forge: &ShapeForge, string_forge: &StringForge, method_name: &str,
native_fn_ptr: *const (), arg_count: u8, wrapper_proto: JsValue,
native_fn_ptr: NativeFnPtr, arg_count: u8, wrapper_proto: JsValue,
) -> Result<(), String> {
let si = string_forge.intern(method_name).0;
let wrapper_proto_ptr = if wrapper_proto.is_object() {
@@ -617,6 +617,8 @@ impl BuiltinWorld {
wrapper.set_proto(wrapper_proto).ok();
}
wrapper.set_function(true);
// The NativeFnPtr invariant is upheld by callers (see bind_method / bind_method_static
// callers, all of which use fn-item expressions).
wrapper.set_native_fn(Some(native_fn_ptr));
wrapper.set_native_arg_count(arg_count);
let si_name = string_forge.intern("name").0;
+6 -4
View File
@@ -100,16 +100,18 @@ impl ShapeForge {
pub fn lookup_position(&self, shape_id: ShapeId, prop_name: StringIndex) -> Option<u32> {
let shapes = self.shapes.read().unwrap();
let total_depth = Self::compute_depth(shape_id, &shapes);
let mut step: u32 = 0;
let mut prop_steps: u32 = 0;
let mut cursor = Some(shape_id);
while let Some(id) = cursor {
match shapes.get((id - 1) as usize).and_then(|s| s.clone()) {
Some(s) => {
if s.property_name == prop_name && s.property_name != EMPTY_SENTINEL {
return Some(total_depth - step - 1);
if s.property_name != EMPTY_SENTINEL {
if s.property_name == prop_name {
return total_depth.checked_sub(prop_steps + 1);
}
prop_steps += 1;
}
cursor = s.parent;
step += 1;
}
None => return None,
}