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,
|
static_assert(sizeof(HandleScope) == sizeof(size_t) * 3,
|
||||||
"HandleScope size mismatch");
|
"HandleScope size mismatch");
|
||||||
|
|
||||||
|
static_assert(sizeof(v8::PromiseRejectMessage) == sizeof(size_t) * 3,
|
||||||
|
"PromiseRejectMessage size mismatch");
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
void v8__V8__SetFlagsFromCommandLine(int* argc, char** argv) {
|
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__Exit(Isolate& isolate) { isolate.Exit(); }
|
||||||
|
|
||||||
|
void v8__Isolate__SetPromiseRejectCallback(Isolate& isolate,
|
||||||
|
v8::PromiseRejectCallback callback) {
|
||||||
|
isolate.SetPromiseRejectCallback(callback);
|
||||||
|
}
|
||||||
|
|
||||||
void v8__Isolate__SetCaptureStackTraceForUncaughtExceptions(Isolate& isolate,
|
void v8__Isolate__SetCaptureStackTraceForUncaughtExceptions(Isolate& isolate,
|
||||||
bool capture,
|
bool capture,
|
||||||
int frame_limit) {
|
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::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) {
|
Number* v8__Number__New(Isolate* isolate, double value) {
|
||||||
return *Number::New(isolate, 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));
|
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() {
|
v8::Platform* v8__platform__NewDefaultPlatform() {
|
||||||
// TODO: support optional arguments.
|
// TODO: support optional arguments.
|
||||||
return v8::platform::NewDefaultPlatform().release();
|
return v8::platform::NewDefaultPlatform().release();
|
||||||
|
|
|
@ -2,10 +2,13 @@ use std::ops::Deref;
|
||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
|
|
||||||
use crate::array_buffer::Allocator;
|
use crate::array_buffer::Allocator;
|
||||||
|
use crate::promise::PromiseRejectMessage;
|
||||||
use crate::support::Delete;
|
use crate::support::Delete;
|
||||||
use crate::support::Opaque;
|
use crate::support::Opaque;
|
||||||
use crate::support::UniqueRef;
|
use crate::support::UniqueRef;
|
||||||
|
|
||||||
|
type PromiseRejectCallback = extern "C" fn(PromiseRejectMessage);
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn v8__Isolate__New(params: *mut CreateParams) -> &'static mut CxxIsolate;
|
fn v8__Isolate__New(params: *mut CreateParams) -> &'static mut CxxIsolate;
|
||||||
fn v8__Isolate__Dispose(this: &mut CxxIsolate) -> ();
|
fn v8__Isolate__Dispose(this: &mut CxxIsolate) -> ();
|
||||||
|
@ -16,6 +19,10 @@ extern "C" {
|
||||||
caputre: bool,
|
caputre: bool,
|
||||||
frame_limit: i32,
|
frame_limit: i32,
|
||||||
);
|
);
|
||||||
|
fn v8__Isolate__SetPromiseRejectCallback(
|
||||||
|
isolate: &mut CxxIsolate,
|
||||||
|
callback: PromiseRejectCallback,
|
||||||
|
) -> ();
|
||||||
|
|
||||||
fn v8__Isolate__CreateParams__NEW() -> *mut CreateParams;
|
fn v8__Isolate__CreateParams__NEW() -> *mut CreateParams;
|
||||||
fn v8__Isolate__CreateParams__DELETE(this: &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 {
|
impl Drop for Isolate {
|
||||||
|
|
|
@ -47,7 +47,10 @@ pub use locker::Locker;
|
||||||
pub use number::{Integer, Number};
|
pub use number::{Integer, Number};
|
||||||
pub use object::Object;
|
pub use object::Object;
|
||||||
pub use primitives::*;
|
pub use primitives::*;
|
||||||
pub use promise::{Promise, PromiseResolver, PromiseState};
|
pub use promise::{
|
||||||
|
Promise, PromiseRejectEvent, PromiseRejectMessage, PromiseResolver,
|
||||||
|
PromiseState,
|
||||||
|
};
|
||||||
pub use script::{Script, ScriptOrigin};
|
pub use script::{Script, ScriptOrigin};
|
||||||
pub use string::NewStringType;
|
pub use string::NewStringType;
|
||||||
pub use string::String;
|
pub use string::String;
|
||||||
|
|
|
@ -20,7 +20,7 @@ extern "C" {
|
||||||
values: *mut *mut Value,
|
values: *mut *mut Value,
|
||||||
length: usize,
|
length: usize,
|
||||||
) -> *mut Object;
|
) -> *mut Object;
|
||||||
|
fn v8__Object__GetIsolate(object: &Object) -> &mut CxxIsolate;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Object {
|
impl Object {
|
||||||
|
@ -59,6 +59,11 @@ impl Object {
|
||||||
.unwrap()
|
.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 {
|
impl Deref for Object {
|
||||||
|
|
|
@ -40,6 +40,16 @@ extern "C" {
|
||||||
on_fulfilled: *mut Function,
|
on_fulfilled: *mut Function,
|
||||||
on_rejected: *mut Function,
|
on_rejected: *mut Function,
|
||||||
) -> *mut Promise;
|
) -> *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)]
|
#[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]
|
#[test]
|
||||||
fn promise_rejected() {
|
fn promise_rejected() {
|
||||||
setup();
|
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]
|
#[test]
|
||||||
fn function() {
|
fn function() {
|
||||||
setup();
|
setup();
|
||||||
|
@ -466,14 +466,14 @@ fn function() {
|
||||||
let global = context.global();
|
let global = context.global();
|
||||||
let recv: Local<v8::Value> = global.into();
|
let recv: Local<v8::Value> = global.into();
|
||||||
// create function using template
|
// 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
|
let mut function = fn_template
|
||||||
.get_function(context)
|
.get_function(context)
|
||||||
.expect("Unable to create function");
|
.expect("Unable to create function");
|
||||||
let _value = v8::Function::call(&mut *function, context, recv, 0, vec![]);
|
let _value = v8::Function::call(&mut *function, context, recv, 0, vec![]);
|
||||||
// create function without a template
|
// create function without a template
|
||||||
let mut function =
|
let mut function = v8::Function::new(context, fn_callback)
|
||||||
v8::Function::new(context, callback).expect("Unable to create function");
|
.expect("Unable to create function");
|
||||||
let maybe_value =
|
let maybe_value =
|
||||||
v8::Function::call(&mut *function, context, recv, 0, vec![]);
|
v8::Function::call(&mut *function, context, recv, 0, vec![]);
|
||||||
let value = maybe_value.unwrap();
|
let value = maybe_value.unwrap();
|
||||||
|
@ -483,3 +483,43 @@ fn function() {
|
||||||
context.exit();
|
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