From 000ebfc5660028b3b63ae67671b6adbca0ddd5eb Mon Sep 17 00:00:00 2001 From: PerfectLaugh <20559490+PerfectLaugh@users.noreply.github.com> Date: Thu, 19 May 2022 10:43:38 +0800 Subject: [PATCH] feat, fix: enable running on 32 bits and several minor fixes --- src/isolate.rs | 22 ++++++++++++++-------- src/module.rs | 41 ++++++++++++++++++++++++++++------------- tests/test_api.rs | 7 ++++++- 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/src/isolate.rs b/src/isolate.rs index 33d8db7802..2264179f79 100644 --- a/src/isolate.rs +++ b/src/isolate.rs @@ -195,12 +195,18 @@ pub type PrepareStackTraceCallback<'s> = extern "C" fn( ) -> *mut *const Value; // System V ABI: MaybeLocal returned in a register. +// System V i386 ABI: Local returned in hidden pointer (struct). #[cfg(not(target_os = "windows"))] -pub type PrepareStackTraceCallback<'s> = extern "C" fn( - Local<'s, Context>, - Local<'s, Value>, - Local<'s, Array>, -) -> *const Value; +#[repr(C)] +pub struct PrepareStackTraceCallbackRet(*const Value); + +#[cfg(not(target_os = "windows"))] +pub type PrepareStackTraceCallback<'s> = + extern "C" fn( + Local<'s, Context>, + Local<'s, Value>, + Local<'s, Array>, + ) -> PrepareStackTraceCallbackRet; extern "C" { fn v8__Isolate__New(params: *const raw::CreateParams) -> *mut Isolate; @@ -1228,13 +1234,13 @@ where f.to_c_fn() } - // System V ABI: MaybeLocal returned in a register. + // System V ABI #[cfg(not(target_os = "windows"))] fn mapping() -> Self { let f = |context, error, sites| { let mut scope: CallbackScope = unsafe { CallbackScope::new(context) }; let r = (F::get())(&mut scope, error, sites); - &*r as *const _ + PrepareStackTraceCallbackRet(&*r as *const _) }; f.to_c_fn() } @@ -1282,7 +1288,7 @@ impl BuildHasher for BuildTypeIdHasher { const _: () = { assert!(size_of::() == size_of::()); - assert!(align_of::() == size_of::()); + assert!(align_of::() == align_of::()); }; pub(crate) struct RawSlot { diff --git a/src/module.rs b/src/module.rs index e5f2ca14c0..420d9b8461 100644 --- a/src/module.rs +++ b/src/module.rs @@ -38,14 +38,18 @@ use crate::Value; /// } /// ``` -// System V AMD64 ABI: Local returned in a register. +// System V ABI +#[cfg(not(target_os = "windows"))] +#[repr(C)] +pub struct ResolveModuleCallbackRet(*const Module); + #[cfg(not(target_os = "windows"))] pub type ResolveModuleCallback<'a> = extern "C" fn( Local<'a, Context>, Local<'a, String>, Local<'a, FixedArray>, Local<'a, Module>, -) -> *const Module; +) -> ResolveModuleCallbackRet; // Windows x64 ABI: Local returned on the stack. #[cfg(target_os = "windows")] @@ -70,9 +74,11 @@ where #[cfg(not(target_os = "windows"))] fn mapping() -> Self { let f = |context, specifier, import_assertions, referrer| { - (F::get())(context, specifier, import_assertions, referrer) - .map(|r| -> *const Module { &*r }) - .unwrap_or(null()) + ResolveModuleCallbackRet( + (F::get())(context, specifier, import_assertions, referrer) + .map(|r| -> *const Module { &*r }) + .unwrap_or(null()), + ) }; f.to_c_fn() } @@ -90,10 +96,17 @@ where } } -// System V AMD64 ABI: Local returned in a register. +// System V ABI. +#[cfg(not(target_os = "windows"))] +#[repr(C)] +pub struct SyntheticModuleEvaluationStepsRet(*const Value); + #[cfg(not(target_os = "windows"))] pub type SyntheticModuleEvaluationSteps<'a> = - extern "C" fn(Local<'a, Context>, Local<'a, Module>) -> *const Value; + extern "C" fn( + Local<'a, Context>, + Local<'a, Module>, + ) -> SyntheticModuleEvaluationStepsRet; // Windows x64 ABI: Local returned on the stack. #[cfg(target_os = "windows")] @@ -112,9 +125,11 @@ where #[cfg(not(target_os = "windows"))] fn mapping() -> Self { let f = |context, module| { - (F::get())(context, module) - .map(|r| -> *const Value { &*r }) - .unwrap_or(null()) + SyntheticModuleEvaluationStepsRet( + (F::get())(context, module) + .map(|r| -> *const Value { &*r }) + .unwrap_or(null()), + ) }; f.to_c_fn() } @@ -139,8 +154,8 @@ extern "C" { fn v8__Module__SourceOffsetToLocation( this: *const Module, offset: int, - out: *mut MaybeUninit, - ) -> Location; + out: *mut Location, + ); fn v8__Module__GetModuleNamespace(this: *const Module) -> *const Value; fn v8__Module__GetIdentityHash(this: *const Module) -> int; fn v8__Module__ScriptId(this: *const Module) -> int; @@ -240,7 +255,7 @@ impl Module { pub fn source_offset_to_location(&self, offset: int) -> Location { let mut out = MaybeUninit::::uninit(); unsafe { - v8__Module__SourceOffsetToLocation(self, offset, &mut out); + v8__Module__SourceOffsetToLocation(self, offset, out.as_mut_ptr()); out.assume_init() } } diff --git a/tests/test_api.rs b/tests/test_api.rs index a1e83d06b4..6f92e75124 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -4012,9 +4012,14 @@ fn typed_array_constructors() { let t = v8::BigInt64Array::new(scope, ab, 0, 0).unwrap(); assert!(t.is_big_int64_array()); - // TypedArray::max_length() ought to be >= 2^30 < 2^32 + // TypedArray::max_length() ought to be >= 2^30 < 2^32 in 64 bits + #[cfg(target_pointer_width = "64")] assert!(((2 << 30)..(2 << 32)).contains(&v8::TypedArray::max_length())); + // TypedArray::max_length() ought to be >= 2^28 < 2^30 in 32 bits + #[cfg(target_pointer_width = "32")] + assert!(((2 << 28)..(2 << 30)).contains(&v8::TypedArray::max_length())); + // v8::ArrayBuffer::new raises a fatal if the length is > kMaxLength, so we test this behavior // through the JS side of things, where a non-fatal RangeError is thrown in such cases. {