0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-12-25 08:39:15 -05:00

Add v8::Isolate::add_message_listener (#89)

This commit is contained in:
Ry Dahl 2019-12-19 21:34:07 -05:00 committed by GitHub
parent 887af28790
commit b610e7cda9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 69 additions and 5 deletions

View file

@ -72,6 +72,11 @@ void v8__Isolate__SetCaptureStackTraceForUncaughtExceptions(Isolate* isolate,
isolate->SetCaptureStackTraceForUncaughtExceptions(capture, frame_limit);
}
bool v8__Isolate__AddMessageListener(Isolate& isolate,
v8::MessageCallback callback) {
return isolate.AddMessageListener(callback);
}
Isolate::CreateParams* v8__Isolate__CreateParams__NEW() {
return new Isolate::CreateParams();
}
@ -195,10 +200,14 @@ Isolate* v8__Context__GetIsolate(Context& self) { return self.GetIsolate(); }
Object* v8__Context__Global(Context& self) { return *self.Global(); }
v8::String* v8__Message__Get(v8::Message* self) {
v8::String* v8__Message__Get(const v8::Message* self) {
return local_to_ptr(self->Get());
}
v8::Isolate* v8__Message__GetIsolate(const v8::Message* self) {
return self->GetIsolate();
}
v8::Value* v8__Exception__RangeError(v8::Local<v8::String> message) {
return local_to_ptr(v8::Exception::RangeError(message));
}

View file

@ -8,7 +8,9 @@ use crate::String;
use crate::Value;
extern "C" {
fn v8__Message__Get(message: *mut Message) -> *mut String;
fn v8__Message__Get(message: *const Message) -> *mut String;
fn v8__Message__GetIsolate(message: &Message) -> &mut Isolate;
fn v8__StackTrace__GetFrameCount(stack_trace: *mut StackTrace) -> int;
fn v8__Exception__RangeError(message: *mut String) -> *mut Value;
@ -43,9 +45,13 @@ impl StackTrace {
pub struct Message(Opaque);
impl Message {
pub fn get(&mut self) -> Local<'_, String> {
pub fn get(&self) -> Local<'_, String> {
unsafe { Local::from_raw(v8__Message__Get(self)) }.unwrap()
}
pub fn get_isolate(&self) -> &Isolate {
unsafe { v8__Message__GetIsolate(self) }
}
}
/// Create new error objects by calling the corresponding error object

View file

@ -3,10 +3,15 @@ use std::ops::DerefMut;
use std::ptr::NonNull;
use crate::array_buffer::Allocator;
use crate::exception::Message;
use crate::promise::PromiseRejectMessage;
use crate::support::Delete;
use crate::support::Opaque;
use crate::support::UniqueRef;
use crate::Local;
use crate::Value;
type MessageCallback = extern "C" fn(Local<'_, Message>, Local<'_, Value>);
type PromiseRejectCallback = extern "C" fn(PromiseRejectMessage);
@ -20,6 +25,10 @@ extern "C" {
caputre: bool,
frame_limit: i32,
);
fn v8__Isolate__AddMessageListener(
this: &mut Isolate,
callback: MessageCallback,
) -> bool;
fn v8__Isolate__SetPromiseRejectCallback(
isolate: *mut Isolate,
callback: PromiseRejectCallback,
@ -31,6 +40,7 @@ extern "C" {
this: &mut CreateParams,
value: *mut Allocator,
);
}
#[repr(C)]
@ -89,6 +99,16 @@ impl Isolate {
}
}
/// Adds a message listener (errors only).
///
/// The same message listener can be added more than once and in that
/// case it will be called more than once for each message.
///
/// The exception object will be passed to the callback.
pub fn add_message_listener(&mut self, callback: MessageCallback) -> bool {
unsafe { v8__Isolate__AddMessageListener(self, callback) }
}
/// 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(

View file

@ -38,6 +38,7 @@ pub mod V8;
pub use context::Context;
pub use exception::Exception;
pub use exception::Message;
pub use function::{Function, FunctionCallbackInfo, FunctionTemplate};
pub use handle_scope::HandleScope;
pub use isolate::Isolate;

View file

@ -4,6 +4,7 @@ use std::ops::Deref;
use std::ops::DerefMut;
use std::ptr::NonNull;
#[repr(C)]
/// An object reference managed by the v8 garbage collector.
///
/// All objects returned from v8 have to be tracked by the garbage

View file

@ -101,7 +101,7 @@ fn test_string() {
}
#[test]
fn isolate_new() {
fn isolate_add_message_listener() {
let g = setup();
let mut params = v8::Isolate::create_params();
params.set_array_buffer_allocator(
@ -109,6 +109,33 @@ fn isolate_new() {
);
let mut isolate = v8::Isolate::new(params);
isolate.set_capture_stack_trace_for_uncaught_exceptions(true, 32);
use std::sync::atomic::{AtomicUsize, Ordering};
static CALL_COUNT: AtomicUsize = AtomicUsize::new(0);
extern "C" fn check_message_0(
message: Local<'_, v8::Message>,
_exception: Local<'_, v8::Value>,
) {
CALL_COUNT.fetch_add(1, Ordering::SeqCst);
let isolate = message.get_isolate();
let message_str = message.get();
assert_eq!(message_str.to_rust_string_lossy(&isolate), "Uncaught foo");
}
isolate.add_message_listener(check_message_0);
let locker = v8::Locker::new(&isolate);
v8::HandleScope::enter(&isolate, |_s| {
let mut context = v8::Context::new(&isolate);
context.enter();
let source =
v8::String::new(&isolate, "throw 'foo'", Default::default()).unwrap();
let mut script = v8::Script::compile(context, source, None).unwrap();
assert!(script.run(context).is_none());
assert_eq!(CALL_COUNT.load(Ordering::SeqCst), 1);
context.exit();
});
drop(locker);
drop(g);
}
@ -291,7 +318,7 @@ fn exception() {
v8::Exception::SyntaxError(local);
v8::Exception::TypeError(local);
let exception = v8::Exception::Error(local);
let mut msg = v8::Exception::CreateMessage(&isolate, exception);
let msg = v8::Exception::CreateMessage(&isolate, exception);
let msg_string = msg.get();
let rust_msg_string = msg_string.to_rust_string_lossy(&isolate);
assert_eq!(