feat: 迁移 NativeResult
This commit is contained in:
Generated
+9
@@ -1101,6 +1101,14 @@ dependencies = [
|
|||||||
"oxc_syntax",
|
"oxc_syntax",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "oxide_runtime_api"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"oxide_kernel",
|
||||||
|
"oxide_types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "oxide_test262"
|
name = "oxide_test262"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
@@ -1139,6 +1147,7 @@ dependencies = [
|
|||||||
"oxide_compiler",
|
"oxide_compiler",
|
||||||
"oxide_kernel",
|
"oxide_kernel",
|
||||||
"oxide_parser",
|
"oxide_parser",
|
||||||
|
"oxide_runtime_api",
|
||||||
"oxide_types",
|
"oxide_types",
|
||||||
"proptest",
|
"proptest",
|
||||||
"regex",
|
"regex",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ members = [
|
|||||||
"crates/oxide_types",
|
"crates/oxide_types",
|
||||||
"crates/oxide_vm",
|
"crates/oxide_vm",
|
||||||
"crates/oxide_kernel",
|
"crates/oxide_kernel",
|
||||||
|
"crates/oxide_runtime_api",
|
||||||
"crates/oxide_api",
|
"crates/oxide_api",
|
||||||
"crates/oxide_cli",
|
"crates/oxide_cli",
|
||||||
"crates/oxide_test262",
|
"crates/oxide_test262",
|
||||||
|
|||||||
@@ -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" }
|
||||||
@@ -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<H: VmHost>(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<JsValue> },
|
||||||
|
}
|
||||||
|
|
||||||
|
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<E, F>(self, op: F) -> Result<JsValue, E>
|
||||||
|
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<KernelCore>;
|
||||||
|
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<JsValue>;
|
||||||
|
fn get_own_property_slot(&self, obj: &JsObject, prop_name_si: u32) -> Option<u32>;
|
||||||
|
|
||||||
|
// Property access
|
||||||
|
fn ordinary_get(&mut self, obj: &JsObject, prop_name_si: u32, receiver: JsValue) -> Result<JsValue, String>;
|
||||||
|
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<String>;
|
||||||
|
fn coerce_primitive_bounded(&mut self, value: JsValue, prefer_string: bool) -> Result<JsValue, String>;
|
||||||
|
fn coerce_number_bounded(&mut self, value: JsValue) -> Result<f64, String>;
|
||||||
|
|
||||||
|
// Call infrastructure
|
||||||
|
fn call_function_sync(&mut self, callee: JsValue, receiver: JsValue, args: &[JsValue]) -> Result<JsValue, String>;
|
||||||
|
|
||||||
|
// Error handling
|
||||||
|
fn checked_object_ptr(&mut self, val: JsValue, error_msg: &str) -> Result<Option<*mut JsObject>, String>;
|
||||||
|
fn raise_type_error(&mut self, msg: &str) -> Result<(), String>;
|
||||||
|
fn error_message_text(&self, kind: &str, msg: &str) -> String;
|
||||||
|
}
|
||||||
@@ -9,6 +9,7 @@ description = "OxideJS - Register-based VM with epoch arena memory"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
oxide_bytecode = { path = "../oxide_bytecode" }
|
oxide_bytecode = { path = "../oxide_bytecode" }
|
||||||
oxide_kernel = { path = "../oxide_kernel" }
|
oxide_kernel = { path = "../oxide_kernel" }
|
||||||
|
oxide_runtime_api = { path = "../oxide_runtime_api" }
|
||||||
oxide_types = { path = "../oxide_types" }
|
oxide_types = { path = "../oxide_types" }
|
||||||
bumpalo.workspace = true
|
bumpalo.workspace = true
|
||||||
fast-float.workspace = true
|
fast-float.workspace = true
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ use oxide_types::object::{JsObject, MAX_DENSE_PROPS};
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
macro_rules! array_ptr {
|
macro_rules! array_ptr {
|
||||||
($vm:expr, $args:expr) => {{
|
($vm:expr, $args:expr) => {{
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ use oxide_types::object::{JsObject, NativeFnPtr, PropAttributes};
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
pub(crate) const MAX_ARRAY_BUFFER_LENGTH: usize = 1 << 30;
|
pub(crate) const MAX_ARRAY_BUFFER_LENGTH: usize = 1 << 30;
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use oxide_types::object::JsObject;
|
use oxide_types::object::JsObject;
|
||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
pub fn boolean_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
pub fn boolean_constructor(vm: &mut Vm, 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] });
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ use oxide_types::value::JsValue;
|
|||||||
|
|
||||||
use crate::builtins::array_buffer::array_buffer_data_ptr;
|
use crate::builtins::array_buffer::array_buffer_data_ptr;
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub(crate) struct DataViewData {
|
pub(crate) struct DataViewData {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ use oxide_types::object::JsObject;
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
fn get_timestamp(obj: &JsObject) -> f64 {
|
fn get_timestamp(obj: &JsObject) -> f64 {
|
||||||
let v = obj.get_prop_at(0);
|
let v = obj.get_prop_at(0);
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use oxide_types::object::JsObject;
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
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 {
|
fn create_error_object(vm: &mut Vm, error_proto_ptr: *mut JsObject, name: &str, message: &str) -> JsValue {
|
||||||
let obj = vm
|
let obj = vm
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
|
|||||||
use oxide_types::object::{JsObject, NativeFnPtr};
|
use oxide_types::object::{JsObject, NativeFnPtr};
|
||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
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 {
|
fn invoke_target(vm: &mut Vm, 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();
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
const ESCAPE_SAFE: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./";
|
const ESCAPE_SAFE: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789@*_+-./";
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
const URI_UNESCAPED: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.!~*'()";
|
const URI_UNESCAPED: &str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.!~*'()";
|
||||||
const URI_RESERVED: &str = ";/?:@&=+$,#";
|
const URI_RESERVED: &str = ";/?:@&=+$,#";
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ use oxide_types::object::JsObject;
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
const INNER_PROP: &str = "__inner__";
|
const INNER_PROP: &str = "__inner__";
|
||||||
const INDEX_PROP: &str = "__index__";
|
const INDEX_PROP: &str = "__index__";
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use oxide_types::object::JsObject;
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::builtins::object::walk_own_keys;
|
use crate::builtins::object::walk_own_keys;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
pub fn json_parse(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
pub fn json_parse(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
if args.len() < 2 {
|
if args.len() < 2 {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ use oxide_types::object::JsObject;
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::builtins::set::SetKey;
|
use crate::builtins::set::SetKey;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
macro_rules! native_try {
|
macro_rules! native_try {
|
||||||
($expr:expr) => {
|
($expr:expr) => {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
fn num(vm: &Vm, reg: u8) -> f64 {
|
fn num(vm: &Vm, reg: u8) -> f64 {
|
||||||
coercion::to_number(vm.reg(reg))
|
coercion::to_number(vm.reg(reg))
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
pub fn number_constructor(vm: &mut Vm, args: &[u8]) -> 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 };
|
let n = if args.len() > 1 { coercion::to_number(vm.reg(args[1])) } else { 0.0 };
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ use oxide_types::private_key::is_private_name_key;
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
pub(crate) fn walk_own_keys(vm: &Vm, obj: &JsObject) -> Vec<(u32, u32)> {
|
pub(crate) fn walk_own_keys(vm: &Vm, obj: &JsObject) -> Vec<(u32, u32)> {
|
||||||
let mut keys: Vec<(u32, u32)> = Vec::new();
|
let mut keys: Vec<(u32, u32)> = Vec::new();
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ use oxide_types::value::JsValue;
|
|||||||
|
|
||||||
use crate::builtins::object::walk_own_keys;
|
use crate::builtins::object::walk_own_keys;
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
pub fn reflect_apply(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
pub fn reflect_apply(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
||||||
let target = arg(vm, args, 1);
|
let target = arg(vm, args, 1);
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ use oxide_types::object::{JsObject, NativeFnPtr};
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
fn get_regexp_ptr(vm: &mut Vm, args: &[u8]) -> Result<*mut JsObject, JsValue> {
|
fn get_regexp_ptr(vm: &mut Vm, args: &[u8]) -> Result<*mut JsObject, JsValue> {
|
||||||
let this_val = vm.reg(args[0]);
|
let this_val = vm.reg(args[0]);
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ 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 crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
macro_rules! native_try {
|
macro_rules! native_try {
|
||||||
($expr:expr) => {
|
($expr:expr) => {
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ use oxide_types::object::JsObject;
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
use memchr::memchr;
|
use memchr::memchr;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
fn this_string(vm: &Vm, args: &[u8]) -> String {
|
fn this_string(vm: &Vm, args: &[u8]) -> String {
|
||||||
coercion::to_string(vm.reg(args[0]))
|
coercion::to_string(vm.reg(args[0]))
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
fn stub_error(vm: &mut Vm, name: &str) -> NativeResult {
|
fn stub_error(vm: &mut Vm, name: &str) -> NativeResult {
|
||||||
NativeResult::Err(crate::builtins::error::create_type_error(vm, &format!("{name} is not implemented")))
|
NativeResult::Err(crate::builtins::error::create_type_error(vm, &format!("{name} is not implemented")))
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ use oxide_types::object::JsObject;
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
pub fn symbol_constructor(vm: &mut Vm, args: &[u8]) -> NativeResult {
|
pub fn symbol_constructor(vm: &mut Vm, 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] });
|
||||||
|
|||||||
@@ -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::builtins::array_buffer::{array_buffer_data_ptr, new_array_buffer, MAX_ARRAY_BUFFER_LENGTH};
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::Vm;
|
use crate::vm::Vm;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub(crate) struct TypedArrayData {
|
pub(crate) struct TypedArrayData {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::native::{NativeFn, NativeResult};
|
use crate::native::NativeFn;
|
||||||
use crate::vm::{native_fn_ptr_to_fn, FrameContinuation, Vm};
|
use crate::vm::{native_fn_ptr_to_fn, FrameContinuation, Vm};
|
||||||
use oxide_kernel::{builtins_debug, builtins_trace};
|
use oxide_kernel::{builtins_debug, builtins_trace};
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
use oxide_types::object::JsObject;
|
use oxide_types::object::JsObject;
|
||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|
||||||
|
|||||||
@@ -1,38 +1,3 @@
|
|||||||
use oxide_types::value::JsValue;
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
pub enum NativeResult {
|
|
||||||
Ok(JsValue),
|
|
||||||
Err(JsValue),
|
|
||||||
TailCall { callee: JsValue, this: JsValue, args: Vec<JsValue> },
|
|
||||||
}
|
|
||||||
|
|
||||||
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<E, F>(self, op: F) -> Result<JsValue, E>
|
|
||||||
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"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type NativeFn = fn(&mut crate::vm::Vm, args: &[u8]) -> NativeResult;
|
pub type NativeFn = fn(&mut crate::vm::Vm, args: &[u8]) -> NativeResult;
|
||||||
|
|||||||
@@ -503,8 +503,8 @@ mod tests {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::builtins::{array_buffer, data_view, map, set, typed_array};
|
use crate::builtins::{array_buffer, data_view, map, set, typed_array};
|
||||||
use crate::native::NativeResult;
|
|
||||||
use crate::vm::{CallFrame, FrameContinuation};
|
use crate::vm::{CallFrame, FrameContinuation};
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
|
|
||||||
fn plain_object(vm: &mut Vm) -> *mut JsObject {
|
fn plain_object(vm: &mut Vm) -> *mut JsObject {
|
||||||
let proto_ptr = vm.session.builtin_world().object_proto.as_ptr() as *mut JsObject;
|
let proto_ptr = vm.session.builtin_world().object_proto.as_ptr() as *mut JsObject;
|
||||||
|
|||||||
@@ -9,10 +9,11 @@ use smallvec::SmallVec;
|
|||||||
|
|
||||||
pub use crate::bindings::init_kernel_builtins;
|
pub use crate::bindings::init_kernel_builtins;
|
||||||
use crate::coercion;
|
use crate::coercion;
|
||||||
use crate::native::{NativeFn, NativeResult};
|
use crate::native::NativeFn;
|
||||||
use crate::session_gc::SessionGc;
|
use crate::session_gc::SessionGc;
|
||||||
use oxide_kernel::kernel::{KernelCore, KernelSession};
|
use oxide_kernel::kernel::{KernelCore, KernelSession};
|
||||||
use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
|
use oxide_kernel::shape_forge::EMPTY_SHAPE_ID;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
use oxide_types::error::{JsError, JsErrorKind};
|
use oxide_types::error::{JsError, JsErrorKind};
|
||||||
use oxide_types::mem::{Epoch, P};
|
use oxide_types::mem::{Epoch, P};
|
||||||
use oxide_types::object::{JsObject, JsString, NativeFnPtr};
|
use oxide_types::object::{JsObject, JsString, NativeFnPtr};
|
||||||
@@ -785,11 +786,11 @@ impl Vm {
|
|||||||
self.regs[2] = flags_val;
|
self.regs[2] = flags_val;
|
||||||
let func = unsafe { crate::vm::native_fn_ptr_to_fn(native_fn) };
|
let func = unsafe { crate::vm::native_fn_ptr_to_fn(native_fn) };
|
||||||
let result = match func(self, &[0, 1, 2]) {
|
let result = match func(self, &[0, 1, 2]) {
|
||||||
crate::native::NativeResult::Ok(v) => v,
|
oxide_runtime_api::NativeResult::Ok(v) => v,
|
||||||
crate::native::NativeResult::Err(e) => {
|
oxide_runtime_api::NativeResult::Err(e) => {
|
||||||
return Err(self.error_message_text("TypeError", &self.error_text(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"));
|
return Err(self.error_message_text("TypeError", "unexpected tail call"));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1412,8 +1413,8 @@ impl Default for Vm {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{opcode, JsValue, TryHandler, Vm};
|
use super::{opcode, JsValue, TryHandler, Vm};
|
||||||
use crate::native::NativeResult;
|
|
||||||
use oxide_bytecode::module::CompiledModule;
|
use oxide_bytecode::module::CompiledModule;
|
||||||
|
use oxide_runtime_api::NativeResult;
|
||||||
use oxide_types::object::NativeFnPtr;
|
use oxide_types::object::NativeFnPtr;
|
||||||
use oxide_types::object::{JsObject, PropAttributes};
|
use oxide_types::object::{JsObject, PropAttributes};
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use std::sync::Arc;
|
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 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::object::{JsObject, PropAttributes};
|
||||||
use oxide_types::private_key::is_private_name_key;
|
use oxide_types::private_key::is_private_name_key;
|
||||||
use oxide_types::value::JsValue;
|
use oxide_types::value::JsValue;
|
||||||
|
|||||||
Reference in New Issue
Block a user