pub mod bind_array; pub mod bind_boolean; pub mod bind_date; pub mod bind_error; pub mod bind_function; pub mod bind_json; pub mod bind_map; pub mod bind_math; pub mod bind_number; pub mod bind_object; pub mod bind_regexp; pub mod bind_set; pub mod bind_string; pub mod bind_symbol; use std::sync::Arc; use oxide_kernel::builtin::BuiltinWorld; use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_types::object::{JsObject, NativeFnPtr}; use oxide_types::value::JsValue; #[macro_export] macro_rules! bind_constructor { ($core:expr, $global:expr, $name:literal, $ctor_ptr:expr, $ctor_fn:path, $nargs:literal) => {{ let si = $core.string_forge().intern($name).0; let shape = $core.shape_forge().make_shape($global.shape_id(), si); let val = $crate::JsValue::from_js_object($ctor_ptr); $global.set_shape_id(shape); $global.push_prop(val); let ctor = unsafe { &mut *$ctor_ptr }; // SAFETY: $ctor_fn is a fn-item expression; casting to *const () preserves validity. ctor.set_native_fn(Some(unsafe { oxide_types::object::NativeFnPtr::from_raw($ctor_fn as *const ()) })); ctor.set_native_arg_count($nargs); }}; } #[macro_export] macro_rules! bind_constructor_hash { ($core:expr, $global:expr, $name:literal, $ctor_ptr:expr, $ctor_fn:path, $nargs:literal) => {{ let si = $core.string_forge().intern($name).0; let shape = $core.shape_forge().make_shape($global.shape_id(), si); let val = $crate::JsValue::from_js_object($ctor_ptr); $global.set_shape_id(shape); $global.ensure_hash_props().push(val); $global.bump_generation(); let ctor = unsafe { &mut *$ctor_ptr }; // SAFETY: $ctor_fn is a fn-item expression; casting to *const () preserves validity. ctor.set_native_fn(Some(unsafe { oxide_types::object::NativeFnPtr::from_raw($ctor_fn as *const ()) })); ctor.set_native_arg_count($nargs); }}; } pub(crate) fn configure_native_constructor(ctor: &mut JsObject, native_fn: *const (), arg_count: u8) { // SAFETY: native_fn is always a valid NativeFn fn-item pointer cast to *const () by callers. ctor.set_native_fn(Some(unsafe { NativeFnPtr::from_raw(native_fn) })); ctor.set_native_arg_count(arg_count); } pub(crate) fn apply_binding_table( world: &BuiltinWorld, target: &mut JsObject, core: &Arc, bindings: &[(&'static str, *const (), u8)], ) { let shape_forge = core.shape_forge().as_ref(); let string_forge = core.string_forge().as_ref(); for (name, func, nargs) in bindings { // SAFETY: all entries in the binding table are NativeFn fn-item pointers cast to *const (). let fn_ptr = unsafe { oxide_types::object::NativeFnPtr::from_raw(*func) }; let _ = world.bind_method(target, shape_forge, string_forge, name, fn_ptr, *nargs); } } pub(crate) fn bind_global_value(core: &Arc, global: &mut JsObject, name: &str, value: JsValue) { let si = core.string_forge().intern(name).0; let shape = core.shape_forge().make_shape(global.shape_id(), si); global.set_shape_id(shape); global.ensure_hash_props().push(value); global.bump_generation(); } pub fn init_kernel_builtins(core: &Arc, session: &KernelSession) { let global_ptr = session.global_object().as_ptr() as *mut oxide_types::object::JsObject; let global = unsafe { &mut *global_ptr }; bind_object::bind_object(core, session, global); bind_array::bind_array(core, session, global); bind_error::bind_error(core, session, global); bind_string::bind_string(core, session, global); bind_number::bind_number(core, session, global); bind_math::bind_math(core, session, global); bind_json::bind_json(core, session, global); bind_date::bind_date(core, session, global); bind_set::bind_set(core, session, global); bind_map::bind_map(core, session, global); bind_boolean::bind_boolean(core, session, global); bind_function::bind_function(core, session, global); bind_regexp::bind_regexp(core, session, global); bind_symbol::bind_symbol(core, session, global); bind_global_value(core, global, "globalThis", JsValue::from_js_object(global_ptr)); }