Add type specialized setters for v8::ReturnValue (#1015)

This commit is contained in:
Divy Srivastava 2022-06-27 08:12:06 +05:30 committed by GitHub
parent ccf181a8b3
commit f5d275f622
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 211 additions and 4 deletions

View File

@ -1846,6 +1846,35 @@ void v8__ReturnValue__Set(v8::ReturnValue<v8::Value>* self,
self->Set(ptr_to_local(&value));
}
void v8__ReturnValue__Set__Int32(v8::ReturnValue<v8::Value>* self, int32_t i) {
self->Set(i);
}
void v8__ReturnValue__Set__Uint32(v8::ReturnValue<v8::Value>* self,
uint32_t i) {
self->Set(i);
}
void v8__ReturnValue__Set__Double(v8::ReturnValue<v8::Value>* self, double i) {
self->Set(i);
}
void v8__ReturnValue__Set__Bool(v8::ReturnValue<v8::Value>* self, bool value) {
self->Set(value);
}
void v8__ReturnValue__SetNull(v8::ReturnValue<v8::Value>* self) {
self->SetNull();
}
void v8__ReturnValue__SetUndefined(v8::ReturnValue<v8::Value>* self) {
self->SetUndefined();
}
void v8__ReturnValue__SetEmptyString(v8::ReturnValue<v8::Value>* self) {
self->SetEmptyString();
}
const v8::Value* v8__ReturnValue__Get(const v8::ReturnValue<v8::Value>& self) {
return local_to_ptr(self.Get());
}

View File

@ -78,6 +78,13 @@ extern "C" {
) -> *const Object;
fn v8__ReturnValue__Set(this: *mut ReturnValue, value: *const Value);
fn v8__ReturnValue__Set__Int32(this: *mut ReturnValue, value: i32);
fn v8__ReturnValue__Set__Uint32(this: *mut ReturnValue, value: u32);
fn v8__ReturnValue__Set__Double(this: *mut ReturnValue, value: f64);
fn v8__ReturnValue__SetNull(this: *mut ReturnValue);
fn v8__ReturnValue__SetUndefined(this: *mut ReturnValue);
fn v8__ReturnValue__SetEmptyString(this: *mut ReturnValue);
fn v8__ReturnValue__Get(this: *const ReturnValue) -> *const Value;
}
@ -135,12 +142,34 @@ impl<'cb> ReturnValue<'cb> {
Self(slot, PhantomData)
}
// NOTE: simplest setter, possibly we'll need to add
// more setters specialized per type
pub fn set(&mut self, value: Local<Value>) {
unsafe { v8__ReturnValue__Set(&mut *self, &*value) }
}
pub fn set_int32(&mut self, value: i32) {
unsafe { v8__ReturnValue__Set__Int32(&mut *self, value) }
}
pub fn set_uint32(&mut self, value: u32) {
unsafe { v8__ReturnValue__Set__Uint32(&mut *self, value) }
}
pub fn set_double(&mut self, value: f64) {
unsafe { v8__ReturnValue__Set__Double(&mut *self, value) }
}
pub fn set_null(&mut self) {
unsafe { v8__ReturnValue__SetNull(&mut *self) }
}
pub fn set_undefined(&mut self) {
unsafe { v8__ReturnValue__SetUndefined(&mut *self) }
}
pub fn set_empty_string(&mut self) {
unsafe { v8__ReturnValue__SetEmptyString(&mut *self) }
}
/// Getter. Creates a new Local<> so it comes with a certain performance
/// hit. If the ReturnValue was not yet set, this will return the undefined
/// value.

View File

@ -2244,11 +2244,11 @@ fn fn_callback2(
}
fn fortytwo_callback(
scope: &mut v8::HandleScope,
_: &mut v8::HandleScope,
_: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue,
) {
rv.set(v8::Integer::new(scope, 42).into());
rv.set_int32(42);
}
fn data_is_true_callback(
@ -2277,6 +2277,155 @@ fn nested_builder<'a>(
.build(scope);
}
#[test]
fn return_value() {
let _setup_guard = setup();
let isolate = &mut v8::Isolate::new(Default::default());
{
let scope = &mut v8::HandleScope::new(isolate);
let context = v8::Context::new(scope);
let scope = &mut v8::ContextScope::new(scope, context);
let global = context.global(scope);
let recv: v8::Local<v8::Value> = global.into();
// set_int32
{
let template = v8::FunctionTemplate::new(
scope,
|scope: &mut v8::HandleScope,
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue| {
assert_eq!(args.length(), 0);
assert!(rv.get(scope).is_undefined());
rv.set_int32(69);
},
);
let function = template
.get_function(scope)
.expect("Unable to create function");
let value = function
.call(scope, recv, &[])
.expect("Function call failed");
assert!(value.is_int32());
assert_eq!(value.int32_value(scope).unwrap(), 69);
}
// set_uint32
{
let template = v8::FunctionTemplate::new(
scope,
|scope: &mut v8::HandleScope,
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue| {
assert_eq!(args.length(), 0);
assert!(rv.get(scope).is_undefined());
rv.set_uint32(69);
},
);
let function = template
.get_function(scope)
.expect("Unable to create function");
let value = function
.call(scope, recv, &[])
.expect("Function call failed");
assert!(value.is_uint32());
assert_eq!(value.uint32_value(scope).unwrap(), 69);
}
// set_null
{
let template = v8::FunctionTemplate::new(
scope,
|scope: &mut v8::HandleScope,
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue| {
assert_eq!(args.length(), 0);
assert!(rv.get(scope).is_undefined());
rv.set_null();
},
);
let function = template
.get_function(scope)
.expect("Unable to create function");
let value = function
.call(scope, recv, &[])
.expect("Function call failed");
assert!(value.is_null());
}
// set_undefined
{
let template = v8::FunctionTemplate::new(
scope,
|scope: &mut v8::HandleScope,
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue| {
assert_eq!(args.length(), 0);
assert!(rv.get(scope).is_undefined());
rv.set_undefined();
},
);
let function = template
.get_function(scope)
.expect("Unable to create function");
let value = function
.call(scope, recv, &[])
.expect("Function call failed");
assert!(value.is_undefined());
}
// set_double
{
let template = v8::FunctionTemplate::new(
scope,
|scope: &mut v8::HandleScope,
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue| {
assert_eq!(args.length(), 0);
assert!(rv.get(scope).is_undefined());
rv.set_double(69.420);
},
);
let function = template
.get_function(scope)
.expect("Unable to create function");
let value = function
.call(scope, recv, &[])
.expect("Function call failed");
assert!(value.is_number());
assert_eq!(value.number_value(scope).unwrap(), 69.420);
}
// set_empty_string
{
let template = v8::FunctionTemplate::new(
scope,
|scope: &mut v8::HandleScope,
args: v8::FunctionCallbackArguments,
mut rv: v8::ReturnValue| {
assert_eq!(args.length(), 0);
assert!(rv.get(scope).is_undefined());
rv.set_empty_string();
},
);
let function = template
.get_function(scope)
.expect("Unable to create function");
let value = function
.call(scope, recv, &[])
.expect("Function call failed");
assert!(value.is_string());
assert_eq!(value.to_rust_string_lossy(scope), "");
}
}
}
#[test]
fn function() {
let _setup_guard = setup();