diff --git a/src/binding.cc b/src/binding.cc index 19d57ae2..0b9589cb 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -21,6 +21,9 @@ static_assert(sizeof(v8::PromiseRejectMessage) == sizeof(size_t) * 3, static_assert(sizeof(v8::Locker) == sizeof(size_t) * 2, "Locker size mismatch"); +static_assert(sizeof(v8::ReturnValue) == sizeof(size_t) * 1, + "ReturnValue size mismatch"); + extern "C" { void v8__V8__SetFlagsFromCommandLine(int* argc, char** argv) { @@ -272,11 +275,10 @@ v8::Isolate* v8__FunctionCallbackInfo__GetIsolate( return self->GetIsolate(); } -v8::ReturnValue* v8__FunctionCallbackInfo__GetReturnValue( - v8::FunctionCallbackInfo* self) { - v8::ReturnValue* rv = - new v8::ReturnValue(self->GetReturnValue()); - return rv; +void v8__FunctionCallbackInfo__GetReturnValue( + v8::FunctionCallbackInfo* self, + v8::ReturnValue* out) { + *out = self->GetReturnValue(); } void v8__ReturnValue__Set(v8::ReturnValue* self, @@ -395,6 +397,22 @@ v8::Value* v8__PromiseRejectMessage__GetValue( return local_to_ptr(self.GetValue()); } +v8::Isolate* v8__PropertyCallbackInfo__GetIsolate( + const v8::PropertyCallbackInfo* self) { + return self->GetIsolate(); +} + +v8::Object* v8__PropertyCallbackInfo__This( + const v8::PropertyCallbackInfo* self) { + return local_to_ptr(self->This()); +} + +void v8__PropertyCallbackInfo__GetReturnValue( + const v8::PropertyCallbackInfo* self, + v8::ReturnValue* out) { + *out = self->GetReturnValue(); +} + v8::Platform* v8__platform__NewDefaultPlatform() { // TODO: support optional arguments. return v8::platform::NewDefaultPlatform().release(); diff --git a/src/function.rs b/src/function.rs index e7d35d65..a7624afa 100644 --- a/src/function.rs +++ b/src/function.rs @@ -3,6 +3,7 @@ use crate::Context; use crate::Isolate; use crate::Local; use crate::Value; +use std::mem::MaybeUninit; extern "C" { fn v8__Function__New( @@ -32,7 +33,8 @@ extern "C" { fn v8__FunctionCallbackInfo__Length(info: &FunctionCallbackInfo) -> int; fn v8__FunctionCallbackInfo__GetReturnValue( info: &FunctionCallbackInfo, - ) -> *mut ReturnValue; + out: *mut ReturnValue, + ); fn v8__ReturnValue__Set(rv: *mut ReturnValue, value: *mut Value) -> (); fn v8__ReturnValue__Get(rv: *mut ReturnValue) -> *mut Value; @@ -40,7 +42,7 @@ extern "C" { } #[repr(C)] -pub struct ReturnValue(Opaque); +pub struct ReturnValue([usize; 1]); /// In V8 ReturnValue<> has a type parameter, but /// it turns out that in most of the APIs it's ReturnValue @@ -76,8 +78,12 @@ pub struct FunctionCallbackInfo(Opaque); impl FunctionCallbackInfo { /// The ReturnValue for the call. #[allow(clippy::mut_from_ref)] - pub fn get_return_value(&self) -> &mut ReturnValue { - unsafe { &mut *v8__FunctionCallbackInfo__GetReturnValue(&*self) } + pub fn get_return_value(&self) -> ReturnValue { + let mut rv = MaybeUninit::::uninit(); + unsafe { + v8__FunctionCallbackInfo__GetReturnValue(&*self, rv.as_mut_ptr()); + rv.assume_init() + } } /// The current Isolate. diff --git a/src/lib.rs b/src/lib.rs index e436e23e..ad0c7fb6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -21,6 +21,7 @@ mod number; mod object; mod primitives; mod promise; +mod property; mod script; mod string; mod support; @@ -37,7 +38,9 @@ pub mod V8; pub use context::Context; pub use exception::*; -pub use function::{Function, FunctionCallbackInfo, FunctionTemplate}; +pub use function::{ + Function, FunctionCallbackInfo, FunctionTemplate, ReturnValue, +}; pub use handle_scope::HandleScope; pub use isolate::Isolate; pub use isolate::OwnedIsolate; @@ -51,6 +54,7 @@ pub use promise::{ Promise, PromiseRejectEvent, PromiseRejectMessage, PromiseResolver, PromiseState, }; +pub use property::PropertyCallbackInfo; pub use script::{Script, ScriptOrigin}; pub use string::NewStringType; pub use string::String; diff --git a/src/property.rs b/src/property.rs new file mode 100644 index 00000000..6ea8990b --- /dev/null +++ b/src/property.rs @@ -0,0 +1,39 @@ +use crate::isolate::Isolate; +use crate::support::Opaque; +use crate::Local; +use crate::Object; +use crate::ReturnValue; +use std::mem::MaybeUninit; + +extern "C" { + fn v8__PropertyCallbackInfo__GetIsolate( + info: &PropertyCallbackInfo, + ) -> &mut Isolate; + fn v8__PropertyCallbackInfo__This(info: &PropertyCallbackInfo) + -> *mut Object; + fn v8__PropertyCallbackInfo__GetReturnValue( + info: &PropertyCallbackInfo, + out: *mut ReturnValue, + ); +} + +#[repr(C)] +pub struct PropertyCallbackInfo(Opaque); + +impl PropertyCallbackInfo { + pub fn get_return_value(&self) -> ReturnValue { + let mut rv = MaybeUninit::::uninit(); + unsafe { + v8__PropertyCallbackInfo__GetReturnValue(self, rv.as_mut_ptr()); + rv.assume_init() + } + } + + pub fn get_isolate(&self) -> &Isolate { + unsafe { v8__PropertyCallbackInfo__GetIsolate(self) } + } + + pub fn this(&self) -> Local { + unsafe { Local::from_raw(v8__PropertyCallbackInfo__This(self)).unwrap() } + } +} diff --git a/tests/test_api.rs b/tests/test_api.rs index 34d3a109..61d80d1f 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -483,7 +483,7 @@ extern "C" fn fn_callback(info: &FunctionCallbackInfo) { context.enter(); let s = v8_str(&isolate, "Hello callback!"); let value: Local = s.into(); - let rv = info.get_return_value(); + let rv = &mut info.get_return_value(); let rv_value = rv.get(); assert!(rv_value.is_undefined()); rv.set(value);