refactor: 添加辅助宏

This commit is contained in:
2026-06-07 15:46:38 +08:00
parent 3b3d9c224a
commit 30b4c5a25a
2 changed files with 173 additions and 126 deletions
+7
View File
@@ -5,6 +5,13 @@ use oxide_types::value::JsValue;
use crate::shape_forge::{ShapeForge, EMPTY_SHAPE_ID}; use crate::shape_forge::{ShapeForge, EMPTY_SHAPE_ID};
use crate::string_forge::StringForge; use crate::string_forge::StringForge;
#[macro_export]
macro_rules! bind_method {
($world:expr, $target:expr, $sf:expr, $sh:expr, $name:literal, $func:path, $nargs:literal) => {
let _ = $world.bind_method($target, $sh, $sf, $name, $func as *const (), $nargs);
};
}
pub struct ObjectMethods { pub struct ObjectMethods {
pub keys: *const (), pub keys: *const (),
pub create: *const (), pub create: *const (),
+166 -126
View File
@@ -8,6 +8,7 @@ use oxide_compiler::opcode::{self, OpCode};
use crate::coercion; use crate::coercion;
use crate::native::NativeFn; use crate::native::NativeFn;
use oxide_kernel::bind_method;
use oxide_kernel::builtin::{ use oxide_kernel::builtin::{
ArrayMethods, ErrorMethods, FunctionMethods, NumberMethods, ObjectMethods, StringMethods, ArrayMethods, ErrorMethods, FunctionMethods, NumberMethods, ObjectMethods, StringMethods,
}; };
@@ -18,6 +19,23 @@ use oxide_types::mem::{Epoch, P};
use oxide_types::object::JsObject; use oxide_types::object::JsObject;
use oxide_types::value::JsValue; use oxide_types::value::JsValue;
/// Invoke a native function via CALL_NATIVE dispatch.
/// args[0] = this_reg, args[1..=n] = contiguous arg registers.
#[allow(unused_macros)]
macro_rules! native_call {
($vm:ident, $callee:expr, $this_reg:expr, $first_arg_reg:expr, $arg_count:expr) => {{
let mut args_buf = [0u8; 257];
args_buf[0] = $this_reg;
for i in 0..($arg_count as usize).min(256) {
args_buf[i + 1] = $first_arg_reg.wrapping_add(i as u8);
}
let args_slice = &args_buf[..($arg_count as usize).min(256) + 1];
let func: NativeFn = unsafe { std::mem::transmute($callee.native_fn().unwrap()) };
$vm.regs[254] = JsValue::from_js_object($callee as *const JsObject as *mut JsObject);
func($vm, args_slice)
}};
}
pub struct CallFrame { pub struct CallFrame {
pub return_addr: usize, pub return_addr: usize,
pub n_locals: u8, pub n_locals: u8,
@@ -196,21 +214,23 @@ pub fn init_kernel_builtins(kernel: &Arc<OxideKernel>) {
let pi_fn = crate::builtins::number::number_parse_int as *const (); let pi_fn = crate::builtins::number::number_parse_int as *const ();
let pf_fn = crate::builtins::number::number_parse_float as *const (); let pf_fn = crate::builtins::number::number_parse_float as *const ();
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
global, global,
kernel.shape_forge().as_ref(),
kernel.string_forge().as_ref(), kernel.string_forge().as_ref(),
kernel.shape_forge().as_ref(),
"parseInt", "parseInt",
pi_fn, pi_fn,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
global, global,
kernel.shape_forge().as_ref(),
kernel.string_forge().as_ref(), kernel.string_forge().as_ref(),
kernel.shape_forge().as_ref(),
"parseFloat", "parseFloat",
pf_fn, pf_fn,
1, 1
); );
let math_ptr = kernel.builtin_world().math_object.as_ptr() as *mut JsObject; let math_ptr = kernel.builtin_world().math_object.as_ptr() as *mut JsObject;
@@ -218,229 +238,257 @@ pub fn init_kernel_builtins(kernel: &Arc<OxideKernel>) {
let sf = kernel.string_forge().as_ref(); let sf = kernel.string_forge().as_ref();
let sh = kernel.shape_forge().as_ref(); let sh = kernel.shape_forge().as_ref();
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"abs", "abs",
crate::builtins::math::math_abs as *const (), crate::builtins::math::math_abs,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"acos", "acos",
crate::builtins::math::math_acos as *const (), crate::builtins::math::math_acos,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"asin", "asin",
crate::builtins::math::math_asin as *const (), crate::builtins::math::math_asin,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"atan", "atan",
crate::builtins::math::math_atan as *const (), crate::builtins::math::math_atan,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"atan2", "atan2",
crate::builtins::math::math_atan2 as *const (), crate::builtins::math::math_atan2,
2, 2
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"cbrt", "cbrt",
crate::builtins::math::math_cbrt as *const (), crate::builtins::math::math_cbrt,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"ceil", "ceil",
crate::builtins::math::math_ceil as *const (), crate::builtins::math::math_ceil,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"cos", "cos",
crate::builtins::math::math_cos as *const (), crate::builtins::math::math_cos,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"cosh", "cosh",
crate::builtins::math::math_cosh as *const (), crate::builtins::math::math_cosh,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"exp", "exp",
crate::builtins::math::math_exp as *const (), crate::builtins::math::math_exp,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"floor", "floor",
crate::builtins::math::math_floor as *const (), crate::builtins::math::math_floor,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"hypot", "hypot",
crate::builtins::math::math_hypot as *const (), crate::builtins::math::math_hypot,
2, 2
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"imul", "imul",
crate::builtins::math::math_imul as *const (), crate::builtins::math::math_imul,
2, 2
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"log", "log",
crate::builtins::math::math_log as *const (), crate::builtins::math::math_log,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"log10", "log10",
crate::builtins::math::math_log10 as *const (), crate::builtins::math::math_log10,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"log2", "log2",
crate::builtins::math::math_log2 as *const (), crate::builtins::math::math_log2,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"max", "max",
crate::builtins::math::math_max as *const (), crate::builtins::math::math_max,
2, 2
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"min", "min",
crate::builtins::math::math_min as *const (), crate::builtins::math::math_min,
2, 2
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"pow", "pow",
crate::builtins::math::math_pow as *const (), crate::builtins::math::math_pow,
2, 2
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"random", "random",
crate::builtins::math::math_random as *const (), crate::builtins::math::math_random,
0, 0
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"round", "round",
crate::builtins::math::math_round as *const (), crate::builtins::math::math_round,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"sign", "sign",
crate::builtins::math::math_sign as *const (), crate::builtins::math::math_sign,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"sin", "sin",
crate::builtins::math::math_sin as *const (), crate::builtins::math::math_sin,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"sinh", "sinh",
crate::builtins::math::math_sinh as *const (), crate::builtins::math::math_sinh,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"sqrt", "sqrt",
crate::builtins::math::math_sqrt as *const (), crate::builtins::math::math_sqrt,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"tan", "tan",
crate::builtins::math::math_tan as *const (), crate::builtins::math::math_tan,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"tanh", "tanh",
crate::builtins::math::math_tanh as *const (), crate::builtins::math::math_tanh,
1, 1
); );
let _ = kernel.builtin_world().bind_method( bind_method!(
kernel.builtin_world(),
math, math,
sh,
sf, sf,
sh,
"trunc", "trunc",
crate::builtins::math::math_trunc as *const (), crate::builtins::math::math_trunc,
1, 1
); );
let pi_val = JsValue::float(std::f64::consts::PI); let pi_val = JsValue::float(std::f64::consts::PI);
@@ -1325,7 +1373,6 @@ impl Vm {
self.kernel.prop_forge().get_template(obj.shape_id()) self.kernel.prop_forge().get_template(obj.shape_id())
{ {
if let Some(ptr) = self.template_prop_ptr(obj, &template) { if let Some(ptr) = self.template_prop_ptr(obj, &template) {
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF; self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32; self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32; self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
@@ -1419,7 +1466,6 @@ impl Vm {
self.kernel.prop_forge().get_template(obj.shape_id()) self.kernel.prop_forge().get_template(obj.shape_id())
{ {
if let Some(ptr) = self.template_prop_ptr(obj, &template) { if let Some(ptr) = self.template_prop_ptr(obj, &template) {
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF; self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32; self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32; self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
@@ -1583,7 +1629,6 @@ impl Vm {
self.kernel.prop_forge().get_template(obj.shape_id()) self.kernel.prop_forge().get_template(obj.shape_id())
{ {
if let Some(ptr) = self.template_prop_ptr(obj, &template) { if let Some(ptr) = self.template_prop_ptr(obj, &template) {
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF; self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32; self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32; self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
@@ -1647,7 +1692,6 @@ impl Vm {
self.kernel.prop_forge().get_template(obj.shape_id()) self.kernel.prop_forge().get_template(obj.shape_id())
{ {
if let Some(ptr) = self.template_prop_ptr(obj, &template) { if let Some(ptr) = self.template_prop_ptr(obj, &template) {
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF; self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32; self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32; self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
@@ -1702,7 +1746,6 @@ impl Vm {
self.kernel.prop_forge().get_template(obj.shape_id()) self.kernel.prop_forge().get_template(obj.shape_id())
{ {
if let Some(ptr) = self.template_prop_ptr(obj, &template) { if let Some(ptr) = self.template_prop_ptr(obj, &template) {
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF; self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32; self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32; self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
@@ -1757,7 +1800,6 @@ impl Vm {
self.kernel.prop_forge().get_template(obj.shape_id()) self.kernel.prop_forge().get_template(obj.shape_id())
{ {
if let Some(ptr) = self.template_prop_ptr(obj, &template) { if let Some(ptr) = self.template_prop_ptr(obj, &template) {
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF; self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32; self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32; self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
@@ -1812,7 +1854,6 @@ impl Vm {
self.kernel.prop_forge().get_template(obj.shape_id()) self.kernel.prop_forge().get_template(obj.shape_id())
{ {
if let Some(ptr) = self.template_prop_ptr(obj, &template) { if let Some(ptr) = self.template_prop_ptr(obj, &template) {
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF; self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32; self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32; self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;
@@ -1867,7 +1908,6 @@ impl Vm {
self.kernel.prop_forge().get_template(obj.shape_id()) self.kernel.prop_forge().get_template(obj.shape_id())
{ {
if let Some(ptr) = self.template_prop_ptr(obj, &template) { if let Some(ptr) = self.template_prop_ptr(obj, &template) {
self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF; self.bytecode[self.pc - 3] = obj.shape_id() & 0x00FF_FFFF;
self.bytecode[self.pc - 2] = ptr as u32; self.bytecode[self.pc - 2] = ptr as u32;
self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32; self.bytecode[self.pc - 1] = (ptr as u64 >> 32) as u32;