0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2025-01-12 17:09:28 -05:00

add v8::PromiseRejectMessage (#65)

This commit is contained in:
Bartek Iwańczuk 2019-12-19 14:13:33 +01:00 committed by GitHub
parent 52b323e802
commit cb0d2e3bec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 157 additions and 23 deletions

View file

@ -18,6 +18,9 @@ static_assert(sizeof(ScriptOrigin) == sizeof(size_t) * 7,
static_assert(sizeof(HandleScope) == sizeof(size_t) * 3,
"HandleScope size mismatch");
static_assert(sizeof(v8::PromiseRejectMessage) == sizeof(size_t) * 3,
"PromiseRejectMessage size mismatch");
extern "C" {
void v8__V8__SetFlagsFromCommandLine(int* argc, char** argv) {
@ -54,6 +57,11 @@ void v8__Isolate__Enter(Isolate& isolate) { isolate.Enter(); }
void v8__Isolate__Exit(Isolate& isolate) { isolate.Exit(); }
void v8__Isolate__SetPromiseRejectCallback(Isolate& isolate,
v8::PromiseRejectCallback callback) {
isolate.SetPromiseRejectCallback(callback);
}
void v8__Isolate__SetCaptureStackTraceForUncaughtExceptions(Isolate& isolate,
bool capture,
int frame_limit) {
@ -143,6 +151,10 @@ v8::Object* v8__Object__New(v8::Isolate* isolate,
v8::Object::New(isolate, prototype_or_null, names, values, length));
}
v8::Isolate* v8__Object__GetIsolate(v8::Object& self) {
return self.GetIsolate();
}
Number* v8__Number__New(Isolate* isolate, double value) {
return *Number::New(isolate, value);
}
@ -354,6 +366,24 @@ v8::Promise* v8__Promise__Then2(v8::Promise* self,
return maybe_local_to_ptr(self->Then(context, on_fulfilled, on_rejected));
}
v8::PromiseRejectEvent
v8__PromiseRejectMessage__GetEvent(const v8::PromiseRejectMessage &self)
{
return self.GetEvent();
}
v8::Promise*
v8__PromiseRejectMessage__GetPromise(const v8::PromiseRejectMessage &self)
{
return local_to_ptr(self.GetPromise());
}
v8::Value*
v8__PromiseRejectMessage__GetValue(const v8::PromiseRejectMessage &self)
{
return local_to_ptr(self.GetValue());
}
v8::Platform* v8__platform__NewDefaultPlatform() {
// TODO: support optional arguments.
return v8::platform::NewDefaultPlatform().release();

View file

@ -2,10 +2,13 @@ use std::ops::Deref;
use std::ops::DerefMut;
use crate::array_buffer::Allocator;
use crate::promise::PromiseRejectMessage;
use crate::support::Delete;
use crate::support::Opaque;
use crate::support::UniqueRef;
type PromiseRejectCallback = extern "C" fn(PromiseRejectMessage);
extern "C" {
fn v8__Isolate__New(params: *mut CreateParams) -> &'static mut CxxIsolate;
fn v8__Isolate__Dispose(this: &mut CxxIsolate) -> ();
@ -16,6 +19,10 @@ extern "C" {
caputre: bool,
frame_limit: i32,
);
fn v8__Isolate__SetPromiseRejectCallback(
isolate: &mut CxxIsolate,
callback: PromiseRejectCallback,
) -> ();
fn v8__Isolate__CreateParams__NEW() -> *mut CreateParams;
fn v8__Isolate__CreateParams__DELETE(this: &mut CreateParams);
@ -85,6 +92,15 @@ impl Isolate {
)
}
}
/// Set callback to notify about promise reject with no handler, or
/// revocation of such a previous notification once the handler is added.
pub fn set_promise_reject_callback(
&mut self,
callback: PromiseRejectCallback,
) {
unsafe { v8__Isolate__SetPromiseRejectCallback(self.0, callback) }
}
}
impl Drop for Isolate {

View file

@ -47,7 +47,10 @@ pub use locker::Locker;
pub use number::{Integer, Number};
pub use object::Object;
pub use primitives::*;
pub use promise::{Promise, PromiseResolver, PromiseState};
pub use promise::{
Promise, PromiseRejectEvent, PromiseRejectMessage, PromiseResolver,
PromiseState,
};
pub use script::{Script, ScriptOrigin};
pub use string::NewStringType;
pub use string::String;

View file

@ -20,7 +20,7 @@ extern "C" {
values: *mut *mut Value,
length: usize,
) -> *mut Object;
fn v8__Object__GetIsolate(object: &Object) -> &mut CxxIsolate;
}
impl Object {
@ -59,6 +59,11 @@ impl Object {
.unwrap()
}
}
/// Return the isolate to which the Object belongs to.
pub fn get_isolate(&self) -> &mut CxxIsolate {
unsafe { v8__Object__GetIsolate(self) }
}
}
impl Deref for Object {

View file

@ -40,6 +40,16 @@ extern "C" {
on_fulfilled: *mut Function,
on_rejected: *mut Function,
) -> *mut Promise;
fn v8__PromiseRejectMessage__GetPromise(
this: &PromiseRejectMessage,
) -> *mut Promise;
fn v8__PromiseRejectMessage__GetValue(
this: &PromiseRejectMessage,
) -> *mut Value;
fn v8__PromiseRejectMessage__GetEvent(
this: &PromiseRejectMessage,
) -> PromiseRejectEvent;
}
#[derive(Debug, PartialEq)]
@ -179,3 +189,33 @@ impl PromiseResolver {
}
}
}
#[derive(Debug, Clone, Copy, PartialEq)]
#[repr(C)]
pub enum PromiseRejectEvent {
PromiseRejectWithNoHandler,
PromiseHandlerAddedAfterReject,
PromiseRejectAfterResolved,
PromiseResolveAfterResolved,
}
#[repr(C)]
pub struct PromiseRejectMessage([usize; 3]);
impl PromiseRejectMessage {
pub fn get_promise(&self) -> Local<'_, Promise> {
unsafe {
Local::from_raw(v8__PromiseRejectMessage__GetPromise(self)).unwrap()
}
}
pub fn get_event(&self) -> PromiseRejectEvent {
unsafe { v8__PromiseRejectMessage__GetEvent(self) }
}
pub fn get_value(&self) -> Local<'_, Value> {
unsafe {
Local::from_raw(v8__PromiseRejectMessage__GetValue(self)).unwrap()
}
}
}

View file

@ -393,24 +393,6 @@ fn promise_resolved() {
});
}
extern "C" fn callback(info: &FunctionCallbackInfo) {
assert_eq!(info.length(), 0);
let mut locker = v8::Locker::new(info.get_isolate());
v8::HandleScope::enter(&mut locker, |scope| {
let mut context = v8::Context::new(scope);
context.enter();
let s =
v8::String::new(scope, "Hello callback!", v8::NewStringType::Normal)
.unwrap();
let value: Local<v8::Value> = s.into();
let rv = info.get_return_value();
let rv_value = rv.get(scope);
assert!(rv_value.is_undefined());
rv.set(value);
context.exit();
});
}
#[test]
fn promise_rejected() {
setup();
@ -451,6 +433,24 @@ fn promise_rejected() {
});
}
extern "C" fn fn_callback(info: &FunctionCallbackInfo) {
assert_eq!(info.length(), 0);
let mut locker = v8::Locker::new(info.get_isolate());
v8::HandleScope::enter(&mut locker, |scope| {
let mut context = v8::Context::new(scope);
context.enter();
let s =
v8::String::new(scope, "Hello callback!", v8::NewStringType::Normal)
.unwrap();
let value: Local<v8::Value> = s.into();
let rv = info.get_return_value();
let rv_value = rv.get(scope);
assert!(rv_value.is_undefined());
rv.set(value);
context.exit();
});
}
#[test]
fn function() {
setup();
@ -466,14 +466,14 @@ fn function() {
let global = context.global();
let recv: Local<v8::Value> = global.into();
// create function using template
let mut fn_template = v8::FunctionTemplate::new(scope, callback);
let mut fn_template = v8::FunctionTemplate::new(scope, fn_callback);
let mut function = fn_template
.get_function(context)
.expect("Unable to create function");
let _value = v8::Function::call(&mut *function, context, recv, 0, vec![]);
// create function without a template
let mut function =
v8::Function::new(context, callback).expect("Unable to create function");
let mut function = v8::Function::new(context, fn_callback)
.expect("Unable to create function");
let maybe_value =
v8::Function::call(&mut *function, context, recv, 0, vec![]);
let value = maybe_value.unwrap();
@ -483,3 +483,43 @@ fn function() {
context.exit();
});
}
extern "C" fn promise_reject_callback(msg: v8::PromiseRejectMessage) {
let event = msg.get_event();
assert_eq!(event, v8::PromiseRejectEvent::PromiseRejectWithNoHandler);
let mut promise = msg.get_promise();
assert_eq!(promise.state(), v8::PromiseState::Rejected);
let promise_obj: v8::Local<v8::Object> = cast(promise);
let isolate = promise_obj.get_isolate();
let value = msg.get_value();
let mut locker = v8::Locker::new(isolate);
v8::HandleScope::enter(&mut locker, |scope| {
let value_str: v8::Local<v8::String> = cast(value);
let rust_str = value_str.to_rust_string_lossy(scope);
assert_eq!(rust_str, "promise rejected".to_string());
});
}
#[test]
fn set_promise_reject_callback() {
setup();
let mut params = v8::Isolate::create_params();
params.set_array_buffer_allocator(
v8::array_buffer::Allocator::new_default_allocator(),
);
let mut isolate = v8::Isolate::new(params);
isolate.set_promise_reject_callback(promise_reject_callback);
isolate.enter();
let mut locker = v8::Locker::new(&mut isolate);
v8::HandleScope::enter(&mut locker, |scope| {
let mut context = v8::Context::new(scope);
context.enter();
let mut resolver = v8::PromiseResolver::new(context).unwrap();
let str_ =
v8::String::new(scope, "promise rejected", v8::NewStringType::Normal).unwrap();
let value: Local<v8::Value> = cast(str_);
resolver.reject(context, value);
context.exit();
});
isolate.exit();
}