diff --git a/Cargo.lock b/Cargo.lock index 67ada84c..5b2773f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1101,6 +1101,14 @@ dependencies = [ "oxc_syntax", ] +[[package]] +name = "oxide_runtime_api" +version = "0.1.0" +dependencies = [ + "oxide_kernel", + "oxide_types", +] + [[package]] name = "oxide_test262" version = "0.1.0" @@ -1139,6 +1147,7 @@ dependencies = [ "oxide_compiler", "oxide_kernel", "oxide_parser", + "oxide_runtime_api", "oxide_types", "proptest", "regex", diff --git a/Cargo.toml b/Cargo.toml index 6e83ad8a..71a4b20b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ members = [ "crates/oxide_types", "crates/oxide_vm", "crates/oxide_kernel", + "crates/oxide_runtime_api", "crates/oxide_api", "crates/oxide_cli", "crates/oxide_test262", diff --git a/crates/oxide_runtime_api/Cargo.toml b/crates/oxide_runtime_api/Cargo.toml new file mode 100644 index 00000000..8d10ca32 --- /dev/null +++ b/crates/oxide_runtime_api/Cargo.toml @@ -0,0 +1,11 @@ +[package] +name = "oxide_runtime_api" +version.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true +description = "OxideJS - VmHost trait: the abstract Vm interface builtins are written against" + +[dependencies] +oxide_types = { path = "../oxide_types" } +oxide_kernel = { path = "../oxide_kernel" } diff --git a/crates/oxide_runtime_api/src/lib.rs b/crates/oxide_runtime_api/src/lib.rs new file mode 100644 index 00000000..26fe8342 --- /dev/null +++ b/crates/oxide_runtime_api/src/lib.rs @@ -0,0 +1,108 @@ +//! `oxide_runtime_api` — the abstract interface between builtins and the VM. +//! +//! Builtins are written generically against the [`VmHost`] trait +//! (`fn xxx(host: &mut H, args: &[u8]) -> NativeResult`); `Vm` +//! implements `VmHost`. This breaks what would otherwise be a circular +//! dependency between the builtins crate and `oxide_vm`: +//! +//! `oxide_types ← oxide_kernel ← oxide_runtime_api ← oxide_builtins ← oxide_vm` +//! +//! The trait is GENERIC-friendly, not object-safe: monomorphizing `H = Vm` +//! inlines every `host.*()` call, so there is zero runtime overhead versus +//! builtins living inside `oxide_vm`. + +use std::sync::Arc; + +use oxide_kernel::kernel::{KernelCore, KernelSession}; +use oxide_types::mem::Epoch; +use oxide_types::object::{JsObject, PropAttributes}; +use oxide_types::value::JsValue; + +/// Return value of every builtin native function. +pub enum NativeResult { + Ok(JsValue), + Err(JsValue), + TailCall { callee: JsValue, this: JsValue, args: Vec }, +} + +impl NativeResult { + pub fn ok(val: JsValue) -> Self { + Self::Ok(val) + } + + pub fn err(val: JsValue) -> Self { + Self::Err(val) + } + + pub fn unwrap(self) -> JsValue { + match self { + Self::Ok(val) => val, + Self::Err(_) => panic!("called `NativeResult::unwrap()` on an `Err` value"), + Self::TailCall { .. } => panic!("called `NativeResult::unwrap()` on a `TailCall` value"), + } + } + + pub fn map_err(self, op: F) -> Result + where + F: FnOnce(JsValue) -> E, + { + match self { + Self::Ok(val) => Ok(val), + Self::Err(err) => Err(op(err)), + Self::TailCall { .. } => panic!("TailCall cannot be converted to Result"), + } + } +} + +/// The set of `Vm` capabilities that builtins depend on. +/// +/// Signatures are byte-for-byte copies of the corresponding inherent methods on +/// `Vm`; `impl VmHost for Vm` delegates to them. The trait is intentionally +/// flat and not object-safe — builtins always take `&mut impl VmHost`. +pub trait VmHost { + // Register access + fn reg(&self, idx: u8) -> JsValue; + fn set_reg(&mut self, idx: u8, val: JsValue); + + // Object allocation / string creation + fn alloc_object(&mut self, obj: JsObject) -> *mut JsObject; + fn new_string(&mut self, s: &str) -> JsValue; + + // Kernel accessors + fn kernel_core(&self) -> &Arc; + fn session(&self) -> &KernelSession; + fn epoch(&self) -> &Epoch; + + // Property resolution + fn property_key_si(&mut self, val: JsValue) -> u32; + fn resolve_property(&self, obj: &JsObject, prop_name_si: u32) -> Option; + fn get_own_property_slot(&self, obj: &JsObject, prop_name_si: u32) -> Option; + + // Property access + fn ordinary_get(&mut self, obj: &JsObject, prop_name_si: u32, receiver: JsValue) -> Result; + fn ordinary_set( + &mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, receiver: JsValue, + ) -> Result<(), String>; + + // Property definition + fn define_data_property( + &mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue, attributes: PropAttributes, + ) -> Result<(), String>; + fn define_accessor_property( + &mut self, obj: &mut JsObject, prop_name_si: u32, get: JsValue, set: JsValue, attributes: PropAttributes, + ) -> Result<(), String>; + fn set_or_create_prop_value(&mut self, obj: &mut JsObject, prop_name_si: u32, val: JsValue); + + // Lookup / coercion + fn lookup_str(&self, val: JsValue) -> Option; + fn coerce_primitive_bounded(&mut self, value: JsValue, prefer_string: bool) -> Result; + fn coerce_number_bounded(&mut self, value: JsValue) -> Result; + + // Call infrastructure + fn call_function_sync(&mut self, callee: JsValue, receiver: JsValue, args: &[JsValue]) -> Result; + + // Error handling + fn checked_object_ptr(&mut self, val: JsValue, error_msg: &str) -> Result, String>; + fn raise_type_error(&mut self, msg: &str) -> Result<(), String>; + fn error_message_text(&self, kind: &str, msg: &str) -> String; +} diff --git a/crates/oxide_vm/Cargo.toml b/crates/oxide_vm/Cargo.toml index 9807b34d..700b1e43 100644 --- a/crates/oxide_vm/Cargo.toml +++ b/crates/oxide_vm/Cargo.toml @@ -9,6 +9,7 @@ description = "OxideJS - Register-based VM with epoch arena memory" [dependencies] oxide_bytecode = { path = "../oxide_bytecode" } oxide_kernel = { path = "../oxide_kernel" } +oxide_runtime_api = { path = "../oxide_runtime_api" } oxide_types = { path = "../oxide_types" } bumpalo.workspace = true fast-float.workspace = true diff --git a/crates/oxide_vm/src/builtins/array.rs b/crates/oxide_vm/src/builtins/array.rs index b10051cb..44632516 100644 --- a/crates/oxide_vm/src/builtins/array.rs +++ b/crates/oxide_vm/src/builtins/array.rs @@ -3,8 +3,8 @@ use oxide_types::object::{JsObject, MAX_DENSE_PROPS}; use oxide_types::value::JsValue; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; macro_rules! array_ptr { ($vm:expr, $args:expr) => {{ diff --git a/crates/oxide_vm/src/builtins/array_buffer.rs b/crates/oxide_vm/src/builtins/array_buffer.rs index 001dde2f..13059c43 100644 --- a/crates/oxide_vm/src/builtins/array_buffer.rs +++ b/crates/oxide_vm/src/builtins/array_buffer.rs @@ -3,8 +3,8 @@ use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes}; use oxide_types::value::JsValue; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; pub(crate) const MAX_ARRAY_BUFFER_LENGTH: usize = 1 << 30; diff --git a/crates/oxide_vm/src/builtins/boolean.rs b/crates/oxide_vm/src/builtins/boolean.rs index 07adbf3f..41db5b94 100644 --- a/crates/oxide_vm/src/builtins/boolean.rs +++ b/crates/oxide_vm/src/builtins/boolean.rs @@ -1,8 +1,8 @@ use oxide_types::object::JsObject; use oxide_types::value::JsValue; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; pub fn boolean_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult { let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] }); diff --git a/crates/oxide_vm/src/builtins/data_view.rs b/crates/oxide_vm/src/builtins/data_view.rs index b431c9f1..23481e63 100644 --- a/crates/oxide_vm/src/builtins/data_view.rs +++ b/crates/oxide_vm/src/builtins/data_view.rs @@ -4,8 +4,8 @@ use oxide_types::value::JsValue; use crate::builtins::array_buffer::array_buffer_data_ptr; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; #[derive(Clone, Copy)] pub(crate) struct DataViewData { diff --git a/crates/oxide_vm/src/builtins/date.rs b/crates/oxide_vm/src/builtins/date.rs index 1436ff2d..7be0eacc 100644 --- a/crates/oxide_vm/src/builtins/date.rs +++ b/crates/oxide_vm/src/builtins/date.rs @@ -5,8 +5,8 @@ use oxide_types::object::JsObject; use oxide_types::value::JsValue; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; fn get_timestamp(obj: &JsObject) -> f64 { let v = obj.get_prop_at(0); diff --git a/crates/oxide_vm/src/builtins/error.rs b/crates/oxide_vm/src/builtins/error.rs index 27024dd3..2cb12967 100644 --- a/crates/oxide_vm/src/builtins/error.rs +++ b/crates/oxide_vm/src/builtins/error.rs @@ -6,8 +6,8 @@ use oxide_types::object::JsObject; use oxide_types::value::JsValue; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; fn create_error_object(vm: &mut Vm, error_proto_ptr: *mut JsObject, name: &str, message: &str) -> JsValue { let obj = vm diff --git a/crates/oxide_vm/src/builtins/function.rs b/crates/oxide_vm/src/builtins/function.rs index a69579d5..aa8d6ae9 100644 --- a/crates/oxide_vm/src/builtins/function.rs +++ b/crates/oxide_vm/src/builtins/function.rs @@ -2,8 +2,8 @@ use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; use oxide_types::object::{JsObject, NativeFnPtr}; use oxide_types::value::JsValue; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; fn invoke_target(vm: &mut Vm, target_val: JsValue, this_val: JsValue, arg_regs: &[u8]) -> NativeResult { let args: Vec = arg_regs.iter().map(|&r| vm.reg(r)).collect(); diff --git a/crates/oxide_vm/src/builtins/global/annex_b.rs b/crates/oxide_vm/src/builtins/global/annex_b.rs index 7e4950ab..dc7553c4 100644 --- a/crates/oxide_vm/src/builtins/global/annex_b.rs +++ b/crates/oxide_vm/src/builtins/global/annex_b.rs @@ -1,5 +1,5 @@ -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; const ESCAPE_SAFE: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./"; diff --git a/crates/oxide_vm/src/builtins/global/uri.rs b/crates/oxide_vm/src/builtins/global/uri.rs index a37b7838..1c5344f8 100644 --- a/crates/oxide_vm/src/builtins/global/uri.rs +++ b/crates/oxide_vm/src/builtins/global/uri.rs @@ -1,5 +1,5 @@ -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; const URI_UNESCAPED: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.!~*'()"; const URI_RESERVED: &str = ";/?:@&=+$,#"; diff --git a/crates/oxide_vm/src/builtins/iterator.rs b/crates/oxide_vm/src/builtins/iterator.rs index 4e561ef7..3f71ddc9 100644 --- a/crates/oxide_vm/src/builtins/iterator.rs +++ b/crates/oxide_vm/src/builtins/iterator.rs @@ -3,8 +3,8 @@ use oxide_types::object::JsObject; use oxide_types::value::JsValue; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; const INNER_PROP: &str = "__inner__"; const INDEX_PROP: &str = "__index__"; diff --git a/crates/oxide_vm/src/builtins/json.rs b/crates/oxide_vm/src/builtins/json.rs index a0485c6e..3fda8733 100644 --- a/crates/oxide_vm/src/builtins/json.rs +++ b/crates/oxide_vm/src/builtins/json.rs @@ -6,8 +6,8 @@ use oxide_types::object::JsObject; use oxide_types::value::JsValue; use crate::builtins::object::walk_own_keys; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; pub fn json_parse(vm: &mut Vm, args: &[u8]) -> NativeResult { if args.len() < 2 { diff --git a/crates/oxide_vm/src/builtins/map.rs b/crates/oxide_vm/src/builtins/map.rs index b679350b..0f54d263 100644 --- a/crates/oxide_vm/src/builtins/map.rs +++ b/crates/oxide_vm/src/builtins/map.rs @@ -3,8 +3,8 @@ use oxide_types::object::JsObject; use oxide_types::value::JsValue; use crate::builtins::set::SetKey; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; macro_rules! native_try { ($expr:expr) => { diff --git a/crates/oxide_vm/src/builtins/math.rs b/crates/oxide_vm/src/builtins/math.rs index d1e3949b..c4b709f2 100644 --- a/crates/oxide_vm/src/builtins/math.rs +++ b/crates/oxide_vm/src/builtins/math.rs @@ -1,8 +1,8 @@ use oxide_types::value::JsValue; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; fn num(vm: &Vm, reg: u8) -> f64 { coercion::to_number(vm.reg(reg)) diff --git a/crates/oxide_vm/src/builtins/number.rs b/crates/oxide_vm/src/builtins/number.rs index c6aa6760..0912c074 100644 --- a/crates/oxide_vm/src/builtins/number.rs +++ b/crates/oxide_vm/src/builtins/number.rs @@ -1,8 +1,8 @@ use oxide_types::value::JsValue; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; pub fn number_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult { let n = if args.len() > 1 { coercion::to_number(vm.reg(args[1])) } else { 0.0 }; diff --git a/crates/oxide_vm/src/builtins/object.rs b/crates/oxide_vm/src/builtins/object.rs index a2c5f2d0..aeaf671c 100644 --- a/crates/oxide_vm/src/builtins/object.rs +++ b/crates/oxide_vm/src/builtins/object.rs @@ -5,8 +5,8 @@ use oxide_types::private_key::is_private_name_key; use oxide_types::value::JsValue; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; pub(crate) fn walk_own_keys(vm: &Vm, obj: &JsObject) -> Vec<(u32, u32)> { let mut keys: Vec<(u32, u32)> = Vec::new(); diff --git a/crates/oxide_vm/src/builtins/reflect.rs b/crates/oxide_vm/src/builtins/reflect.rs index 10b123b7..c8fc1f9f 100644 --- a/crates/oxide_vm/src/builtins/reflect.rs +++ b/crates/oxide_vm/src/builtins/reflect.rs @@ -4,8 +4,8 @@ use oxide_types::value::JsValue; use crate::builtins::object::walk_own_keys; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; pub fn reflect_apply(vm: &mut Vm, args: &[u8]) -> NativeResult { let target = arg(vm, args, 1); diff --git a/crates/oxide_vm/src/builtins/regexp.rs b/crates/oxide_vm/src/builtins/regexp.rs index f5293441..453b6389 100644 --- a/crates/oxide_vm/src/builtins/regexp.rs +++ b/crates/oxide_vm/src/builtins/regexp.rs @@ -3,8 +3,8 @@ use oxide_types::object::{JsObject, NativeFnPtr}; use oxide_types::value::JsValue; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; fn get_regexp_ptr(vm: &mut Vm, args: &[u8]) -> Result<*mut JsObject, JsValue> { let this_val = vm.reg(args[0]); diff --git a/crates/oxide_vm/src/builtins/set.rs b/crates/oxide_vm/src/builtins/set.rs index 05f8e3bd..c1862a88 100644 --- a/crates/oxide_vm/src/builtins/set.rs +++ b/crates/oxide_vm/src/builtins/set.rs @@ -4,8 +4,8 @@ use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; use oxide_types::object::JsObject; use oxide_types::value::JsValue; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; macro_rules! native_try { ($expr:expr) => { diff --git a/crates/oxide_vm/src/builtins/string.rs b/crates/oxide_vm/src/builtins/string.rs index dbc7fdfc..3b7782a9 100644 --- a/crates/oxide_vm/src/builtins/string.rs +++ b/crates/oxide_vm/src/builtins/string.rs @@ -3,9 +3,9 @@ use oxide_types::object::JsObject; use oxide_types::value::JsValue; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; use memchr::memchr; +use oxide_runtime_api::NativeResult; fn this_string(vm: &Vm, args: &[u8]) -> String { coercion::to_string(vm.reg(args[0])) diff --git a/crates/oxide_vm/src/builtins/stubs.rs b/crates/oxide_vm/src/builtins/stubs.rs index 3769ae84..02307a8b 100644 --- a/crates/oxide_vm/src/builtins/stubs.rs +++ b/crates/oxide_vm/src/builtins/stubs.rs @@ -1,5 +1,5 @@ -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; fn stub_error(vm: &mut Vm, name: &str) -> NativeResult { NativeResult::Err(crate::builtins::error::create_type_error(vm, &format!("{name} is not implemented"))) diff --git a/crates/oxide_vm/src/builtins/symbol.rs b/crates/oxide_vm/src/builtins/symbol.rs index aedf0e67..266ba839 100644 --- a/crates/oxide_vm/src/builtins/symbol.rs +++ b/crates/oxide_vm/src/builtins/symbol.rs @@ -2,8 +2,8 @@ use oxide_types::object::JsObject; use oxide_types::value::JsValue; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; pub fn symbol_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult { let this_val = vm.reg(if args.is_empty() { 0 } else { args[0] }); diff --git a/crates/oxide_vm/src/builtins/typed_array.rs b/crates/oxide_vm/src/builtins/typed_array.rs index 04b6f159..26d87792 100644 --- a/crates/oxide_vm/src/builtins/typed_array.rs +++ b/crates/oxide_vm/src/builtins/typed_array.rs @@ -4,8 +4,8 @@ use oxide_types::value::JsValue; use crate::builtins::array_buffer::{array_buffer_data_ptr, new_array_buffer, MAX_ARRAY_BUFFER_LENGTH}; use crate::coercion; -use crate::native::NativeResult; use crate::vm::Vm; +use oxide_runtime_api::NativeResult; #[derive(Clone, Copy)] pub(crate) struct TypedArrayData { diff --git a/crates/oxide_vm/src/dispatch/call.rs b/crates/oxide_vm/src/dispatch/call.rs index b2729c01..76c918ad 100644 --- a/crates/oxide_vm/src/dispatch/call.rs +++ b/crates/oxide_vm/src/dispatch/call.rs @@ -1,6 +1,7 @@ -use crate::native::{NativeFn, NativeResult}; +use crate::native::NativeFn; use crate::vm::{native_fn_ptr_to_fn, FrameContinuation, Vm}; use oxide_kernel::{builtins_debug, builtins_trace}; +use oxide_runtime_api::NativeResult; use oxide_types::object::JsObject; use oxide_types::value::JsValue; diff --git a/crates/oxide_vm/src/native.rs b/crates/oxide_vm/src/native.rs index c693b389..0a8ad198 100644 --- a/crates/oxide_vm/src/native.rs +++ b/crates/oxide_vm/src/native.rs @@ -1,38 +1,3 @@ -use oxide_types::value::JsValue; - -pub enum NativeResult { - Ok(JsValue), - Err(JsValue), - TailCall { callee: JsValue, this: JsValue, args: Vec }, -} - -impl NativeResult { - pub fn ok(val: JsValue) -> Self { - Self::Ok(val) - } - - pub fn err(val: JsValue) -> Self { - Self::Err(val) - } - - pub fn unwrap(self) -> JsValue { - match self { - Self::Ok(val) => val, - Self::Err(_) => panic!("called `NativeResult::unwrap()` on an `Err` value"), - Self::TailCall { .. } => panic!("called `NativeResult::unwrap()` on a `TailCall` value"), - } - } - - pub fn map_err(self, op: F) -> Result - where - F: FnOnce(JsValue) -> E, - { - match self { - Self::Ok(val) => Ok(val), - Self::Err(err) => Err(op(err)), - Self::TailCall { .. } => panic!("TailCall cannot be converted to Result"), - } - } -} +use oxide_runtime_api::NativeResult; pub type NativeFn = fn(&mut crate::vm::Vm, args: &[u8]) -> NativeResult; diff --git a/crates/oxide_vm/src/session_gc.rs b/crates/oxide_vm/src/session_gc.rs index a831b17c..e1169c9b 100644 --- a/crates/oxide_vm/src/session_gc.rs +++ b/crates/oxide_vm/src/session_gc.rs @@ -503,8 +503,8 @@ mod tests { use super::*; use crate::builtins::{array_buffer, data_view, map, set, typed_array}; - use crate::native::NativeResult; use crate::vm::{CallFrame, FrameContinuation}; + use oxide_runtime_api::NativeResult; fn plain_object(vm: &mut Vm) -> *mut JsObject { let proto_ptr = vm.session.builtin_world().object_proto.as_ptr() as *mut JsObject; diff --git a/crates/oxide_vm/src/vm.rs b/crates/oxide_vm/src/vm.rs index fb77a0cd..0b5f1039 100644 --- a/crates/oxide_vm/src/vm.rs +++ b/crates/oxide_vm/src/vm.rs @@ -9,10 +9,11 @@ use smallvec::SmallVec; pub use crate::bindings::init_kernel_builtins; use crate::coercion; -use crate::native::{NativeFn, NativeResult}; +use crate::native::NativeFn; use crate::session_gc::SessionGc; use oxide_kernel::kernel::{KernelCore, KernelSession}; use oxide_kernel::shape_forge::EMPTY_SHAPE_ID; +use oxide_runtime_api::NativeResult; use oxide_types::error::{JsError, JsErrorKind}; use oxide_types::mem::{Epoch, P}; use oxide_types::object::{JsObject, JsString, NativeFnPtr}; @@ -785,11 +786,11 @@ impl Vm { self.regs[2] = flags_val; let func = unsafe { crate::vm::native_fn_ptr_to_fn(native_fn) }; let result = match func(self, &[0, 1, 2]) { - crate::native::NativeResult::Ok(v) => v, - crate::native::NativeResult::Err(e) => { + oxide_runtime_api::NativeResult::Ok(v) => v, + oxide_runtime_api::NativeResult::Err(e) => { return Err(self.error_message_text("TypeError", &self.error_text(e))); } - crate::native::NativeResult::TailCall { .. } => { + oxide_runtime_api::NativeResult::TailCall { .. } => { return Err(self.error_message_text("TypeError", "unexpected tail call")); } }; @@ -1412,8 +1413,8 @@ impl Default for Vm { #[cfg(test)] mod tests { use super::{opcode, JsValue, TryHandler, Vm}; - use crate::native::NativeResult; use oxide_bytecode::module::CompiledModule; + use oxide_runtime_api::NativeResult; use oxide_types::object::NativeFnPtr; use oxide_types::object::{JsObject, PropAttributes}; diff --git a/crates/oxide_vm/src/vm_dispatch_misc.rs b/crates/oxide_vm/src/vm_dispatch_misc.rs index 45fdfa08..ceb1749d 100644 --- a/crates/oxide_vm/src/vm_dispatch_misc.rs +++ b/crates/oxide_vm/src/vm_dispatch_misc.rs @@ -1,7 +1,8 @@ use std::sync::Arc; -use crate::native::{NativeFn, NativeResult}; +use crate::native::NativeFn; use crate::vm::{native_fn_ptr_to_fn, CallFrame, ForInIter, FrameContinuation, Vm, MAX_PROTO_CHAIN_DEPTH}; +use oxide_runtime_api::NativeResult; use oxide_types::object::{JsObject, PropAttributes}; use oxide_types::private_key::is_private_name_key; use oxide_types::value::JsValue;