Skip to content

Commit

Permalink
Added Heap-based Rooting Mechanism
Browse files Browse the repository at this point in the history
Added Error Reporting for Conversions when Getting Object Properties
Removed Lifetimes from Rooted Types and Conversion Traits
Removed typed-arena Dependency
Removed Property Descriptor Support Temporarily
Rewrote Conversion Test
  • Loading branch information
Redfire75369 committed Nov 30, 2023
1 parent 6b7f57d commit 52bb5dc
Show file tree
Hide file tree
Showing 65 changed files with 1,057 additions and 1,255 deletions.
2 changes: 0 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ dunce = "1.0.4"
futures = "0.3.29"
indent = "0.1.1"
mozjs = { package = "mozjs", git = "https://github.com/servo/mozjs" }
mozjs_sys = { package = "mozjs_sys", git = "https://github.com/servo/mozjs" }
sourcemap = "6.4.1"
url = "2.5.0"

Expand Down
2 changes: 1 addition & 1 deletion ion-proc/src/class/impl/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub(super) fn impl_js_class_impl(r#impl: &mut ItemImpl) -> Result<[ItemImpl; 2]>
return Err(Error::new(
r#impl.span(),
"Native Class Impls must contain a constructor.",
))
));
}
};

Expand Down
2 changes: 1 addition & 1 deletion ion-proc/src/function/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,6 @@ pub(crate) fn impl_fn_body(ion: &TokenStream, wrapper: &ItemFn) -> Result<Block>

#wrapper
let result = ::std::panic::catch_unwind(::std::panic::AssertUnwindSafe(|| wrapper(cx, args)));
#ion::functions::__handle_native_function_result(cx, result)
#ion::functions::handle_native_function_result(cx, result)
}))
}
2 changes: 1 addition & 1 deletion ion-proc/src/function/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use syn::spanned::Spanned;
use syn::visit_mut::visit_type_mut;

use crate::attribute::function::ParameterAttribute;
use crate::utils::{format_pat, path_ends_with, pat_is_ident};
use crate::utils::{format_pat, pat_is_ident, path_ends_with};
use crate::visitors::{LifetimeRemover, SelfRenamer};

pub(crate) enum Parameter {
Expand Down
11 changes: 8 additions & 3 deletions ion-proc/src/function/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,17 @@ pub(crate) fn impl_wrapper_fn(
parse_quote!(__cx: &'cx #ion::Context),
parse_quote!(__args: &'a mut #ion::Arguments<'cx>),
];
let wrapper_output = if is_constructor {
parse_quote!(-> #ion::ResultExc<()>)
} else {
parse_quote!(-> #ion::ResultExc<::core::primitive::bool>)
};

let argument_checker = argument_checker(ion, &function.sig.ident, parameters.nargs.0);

let mut this_statements = parameters.to_this_statement(ion, class_ty.is_some())?.map(ToTokens::into_token_stream);
if is_constructor {
wrapper_args.push(parse_quote!(__this: &mut #ion::Object<'cx>));
wrapper_args.push(parse_quote!(__this: &mut #ion::Object));
} else {
this_statements = this_statements.map(|statement| {
quote!(
Expand All @@ -66,7 +71,7 @@ pub(crate) fn impl_wrapper_fn(
};
let result = quote!(#result.map(Box::new));
let result = if !is_constructor {
quote!(#result.map(|__result| #ion::conversions::IntoValue::into_value(__result, __cx, __args.rval())))
quote!(Ok(#ion::functions::handle_result(__cx, #result, __args.rval())))
} else {
quote!(#result.map(|__result| #ion::ClassDefinition::set_private(__this.handle().get(), __result)))
};
Expand Down Expand Up @@ -103,7 +108,7 @@ pub(crate) fn impl_wrapper_fn(
function.sig.ident = format_ident!("wrapper", span = function.sig.ident.span());
function.sig.inputs = Punctuated::from_iter(wrapper_args);
function.sig.generics.params = Punctuated::from_iter(wrapper_generics);
function.sig.output = parse_quote!(-> #ion::ResultExc<()>);
function.sig.output = wrapper_output;
function.sig.unsafety = Some(<Token![unsafe]>::default());

function.attrs.clear();
Expand Down
4 changes: 2 additions & 2 deletions ion-proc/src/value/from.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ pub(crate) fn impl_from_value(mut input: DeriveInput) -> Result<ItemImpl> {
impl #impl_generics #ion::conversions::FromValue<'cx> for #name #ty_generics #where_clause {
type Config = ();

fn from_value<'v>(cx: &'cx #ion::Context, value: &#ion::Value<'v>, strict: bool, _: ()) -> #ion::Result<Self> {
fn from_value(cx: &'cx #ion::Context, value: &#ion::Value, strict: bool, _: ()) -> #ion::Result<Self> {
#object
#body
}
Expand Down Expand Up @@ -372,7 +372,7 @@ fn map_fields(
} else {
requires_object = true;
let error = format!("Expected Value at key {} of Type {}", key, format_type(ty));
quote_spanned!(field.span() => let #ident: #ty = __object.get_as(cx, #key, #strict || strict, #convert)
quote_spanned!(field.span() => let #ident: #ty = __object.get_as(cx, #key, #strict || strict, #convert).transpose()?
.ok_or_else(|| #ion::Error::new(#error, #ion::ErrorKind::Type)))
};

Expand Down
2 changes: 0 additions & 2 deletions ion/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,12 @@ byteorder = "1.5.0"
bytemuck = "1.14.0"
itoa = "1.0.9"
libffi = "3.2.0"
typed-arena = "2.0.2"
utf16string = "0.2.0"

colored.workspace = true
chrono.workspace = true
indent.workspace = true
mozjs.workspace = true
mozjs_sys.workspace = true

[dependencies.futures]
workspace = true
Expand Down
4 changes: 2 additions & 2 deletions ion/examples/macros/from_value/structure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ use ion::{Context, FromValue, Object, Result, Value};
use ion::conversions::{ConversionBehavior, FromValue};

#[derive(FromValue)]
pub struct Complex<'cx> {
pub struct Complex {
#[ion(inherit)]
pub raw: Object<'cx>,
pub raw: Object,
pub truth: bool,
#[ion(convert = ConversionBehavior::EnforceRange, strict)]
pub mode: u32,
Expand Down
24 changes: 12 additions & 12 deletions ion/src/bigint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ use std::ops::{Deref, DerefMut};

use mozjs::jsapi::{
BigIntFitsNumber, BigIntFromBool, BigIntFromInt64, BigIntFromUint64, BigIntIsInt64, BigIntIsNegative,
BigIntIsUint64, BigIntToNumber, BigIntToString, NumberToBigInt, StringToBigInt1,
BigIntIsUint64, BigIntToNumber, BigIntToString, Heap, NumberToBigInt, StringToBigInt1,
};
use mozjs::jsapi::BigInt as JSBigInt;
use mozjs::jsapi::mozilla::{Range, RangedPtr};

use crate::{Context, Exception, Local, String};
use crate::{Context, Exception, Root, String};

pub struct BigInt<'b> {
bi: Local<'b, *mut JSBigInt>,
pub struct BigInt {
bi: Root<Box<Heap<*mut JSBigInt>>>,
}

impl<'b> BigInt<'b> {
impl BigInt {
/// Creates a [BigInt] from a boolean.
pub fn from_bool(cx: &Context, boolean: bool) -> BigInt {
BigInt::from(cx.root_bigint(unsafe { BigIntFromBool(cx.as_ptr(), boolean) }))
Expand Down Expand Up @@ -48,7 +48,7 @@ impl<'b> BigInt<'b> {
}

/// Creates a [BigInt] from a string.
pub fn from_string(cx: &'b Context, string: &str) -> Result<BigInt<'b>, Option<Exception>> {
pub fn from_string(cx: &Context, string: &str) -> Result<BigInt, Option<Exception>> {
let mut string: Vec<u16> = string.encode_utf16().collect();
let range = string.as_mut_ptr_range();
let chars = Range {
Expand Down Expand Up @@ -104,7 +104,7 @@ impl<'b> BigInt<'b> {

/// Converts a [BigInt] to a string.
/// Returns `None` if the radix is not within the range (2..=36).
pub fn to_string<'cx>(&self, cx: &'cx Context, radix: u8) -> Option<String<'cx>> {
pub fn to_string(&self, cx: &Context, radix: u8) -> Option<String> {
if !(2..=36).contains(&radix) {
None
} else {
Expand All @@ -119,21 +119,21 @@ impl<'b> BigInt<'b> {
}
}

impl<'b> From<Local<'b, *mut JSBigInt>> for BigInt<'b> {
fn from(bi: Local<'b, *mut JSBigInt>) -> BigInt<'b> {
impl From<Root<Box<Heap<*mut JSBigInt>>>> for BigInt {
fn from(bi: Root<Box<Heap<*mut JSBigInt>>>) -> BigInt {
BigInt { bi }
}
}

impl<'o> Deref for BigInt<'o> {
type Target = Local<'o, *mut JSBigInt>;
impl Deref for BigInt {
type Target = Root<Box<Heap<*mut JSBigInt>>>;

fn deref(&self) -> &Self::Target {
&self.bi
}
}

impl<'o> DerefMut for BigInt<'o> {
impl DerefMut for BigInt {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.bi
}
Expand Down
12 changes: 6 additions & 6 deletions ion/src/class/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ use std::ptr;

use mozjs::glue::JS_GetReservedSlot;
use mozjs::jsapi::{
Handle, JS_GetConstructor, JS_InitClass, JS_InstanceOf, JS_NewObjectWithGivenProto, JS_SetReservedSlot, JSFunction,
JSFunctionSpec, JSObject, JSPropertySpec,
Handle, Heap, JS_GetConstructor, JS_InitClass, JS_InstanceOf, JS_NewObjectWithGivenProto, JS_SetReservedSlot,
JSFunction, JSFunctionSpec, JSObject, JSPropertySpec,
};
use mozjs::jsval::{PrivateValue, UndefinedValue};

use crate::{Arguments, Context, Function, Local, Object};
use crate::{Arguments, Context, Function, Object, Root};
pub use crate::class::native::{MAX_PROTO_CHAIN_LENGTH, NativeClass, PrototypeChain, TypeIdWrapper};
pub use crate::class::reflect::{Castable, DerivedFrom, NativeObject, Reflector};
use crate::functions::NativeFunction;
Expand All @@ -38,7 +38,7 @@ pub trait ClassDefinition: NativeObject {

fn class() -> &'static NativeClass;

fn parent_class_info(_: &Context) -> Option<(&'static NativeClass, Local<*mut JSObject>)> {
fn parent_class_info(_: &Context) -> Option<(&'static NativeClass, Root<Box<Heap<*mut JSObject>>>)> {
None
}

Expand Down Expand Up @@ -130,15 +130,15 @@ pub trait ClassDefinition: NativeObject {
object
}

fn get_private<'a>(object: &Object<'a>) -> &'a Self {
fn get_private(object: &Object) -> &Self {
unsafe {
let mut value = UndefinedValue();
JS_GetReservedSlot(object.handle().get(), 0, &mut value);
&*(value.to_private() as *const Self)
}
}

fn get_mut_private<'a>(object: &mut Object<'a>) -> &'a mut Self {
fn get_mut_private(object: &mut Object) -> &mut Self {
unsafe {
let mut value = UndefinedValue();
JS_GetReservedSlot(object.handle().get(), 0, &mut value);
Expand Down
Loading

0 comments on commit 52bb5dc

Please sign in to comment.