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:
parent
52b323e802
commit
cb0d2e3bec
6 changed files with 157 additions and 23 deletions
|
@ -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();
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue