diff --git a/src/binding.cc b/src/binding.cc index 21d216d8..6894bbb2 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -528,6 +528,54 @@ v8::String* v8__Message__Get(const v8::Message* self) { return local_to_ptr(self->Get()); } +v8::String* v8__Message__GetSourceLine(const v8::Message& self, + v8::Context* context) { + return maybe_local_to_ptr(self.GetSourceLine(ptr_to_local(context))); +} + +v8::Value* v8__Message__GetScriptResourceName(const v8::Message& self) { + return local_to_ptr(self.GetScriptResourceName()); +} + +int v8__Message__GetLineNumber(const v8::Message& self, v8::Context* context) { + v8::Maybe maybe = self.GetLineNumber(ptr_to_local(context)); + if (maybe.IsJust()) { + return maybe.ToChecked(); + } else { + return -1; + } +} + +int v8__Message__GetStartPosition(const v8::Message& self) { + return self.GetStartPosition(); +} + +int v8__Message__GetEndPosition(const v8::Message& self) { + return self.GetEndPosition(); +} + +int v8__Message__GetWasmFunctionIndex(const v8::Message& self) { + return self.GetWasmFunctionIndex(); +} + +int v8__Message__ErrorLevel(const v8::Message& self) { + return self.ErrorLevel(); +} + +int v8__Message__GetStartColumn(const v8::Message& self) { + return self.GetStartColumn(); +} + +int v8__Message__GetEndColumn(const v8::Message& self) { + return self.GetEndColumn(); +} + +bool v8__Message__IsSharedCrossOrigin(const v8::Message& self) { + return self.IsSharedCrossOrigin(); +} + +bool v8__Message__IsOpaque(const v8::Message& self) { return self.IsOpaque(); } + v8::Isolate* v8__Message__GetIsolate(const v8::Message* self) { return self->GetIsolate(); } diff --git a/src/exception.rs b/src/exception.rs index 5059aec6..4fbe7733 100644 --- a/src/exception.rs +++ b/src/exception.rs @@ -3,6 +3,7 @@ use crate::isolate::Isolate; use crate::support::int; use crate::support::Opaque; +use crate::Context; use crate::Local; use crate::String; use crate::ToLocal; @@ -11,6 +12,23 @@ use crate::Value; extern "C" { fn v8__Message__Get(message: *const Message) -> *mut String; fn v8__Message__GetIsolate(message: &Message) -> &mut Isolate; + fn v8__Message__GetSourceLine( + message: &Message, + context: *mut Context, + ) -> *mut String; + fn v8__Message__GetScriptResourceName(message: &Message) -> *mut Value; + fn v8__Message__GetLineNumber( + message: &Message, + context: *mut Context, + ) -> int; + fn v8__Message__GetStartPosition(message: &Message) -> int; + fn v8__Message__GetEndPosition(message: &Message) -> int; + fn v8__Message__GetWasmFunctionIndex(message: &Message) -> int; + fn v8__Message__ErrorLevel(message: &Message) -> int; + fn v8__Message__GetStartColumn(message: &Message) -> int; + fn v8__Message__GetEndColumn(message: &Message) -> int; + fn v8__Message__IsSharedCrossOrigin(message: &Message) -> bool; + fn v8__Message__IsOpaque(message: &Message) -> bool; fn v8__StackTrace__GetFrameCount(stack_trace: *mut StackTrace) -> int; @@ -53,6 +71,78 @@ impl Message { pub fn get_isolate(&mut self) -> &mut Isolate { unsafe { v8__Message__GetIsolate(self) } } + + pub fn get_source_line<'s>( + &self, + scope: &mut impl ToLocal<'s>, + mut context: Local, + ) -> Option> { + unsafe { scope.to_local(v8__Message__GetSourceLine(self, &mut *context)) } + } + + /// Returns the resource name for the script from where the function causing + /// the error originates. + pub fn get_script_resource_name<'s>( + &self, + scope: &mut impl ToLocal<'s>, + ) -> Option> { + unsafe { scope.to_local(v8__Message__GetScriptResourceName(self)) } + } + + /// Returns the number, 1-based, of the line where the error occurred. + pub fn get_line_number(&self, mut context: Local) -> Option { + let i = unsafe { v8__Message__GetLineNumber(self, &mut *context) }; + if i < 0 { + None + } else { + Some(i as usize) + } + } + + /// Returns the index within the script of the first character where + /// the error occurred. + pub fn get_start_position(&self) -> int { + unsafe { v8__Message__GetStartPosition(self) } + } + + /// Returns the index within the script of the last character where + /// the error occurred. + pub fn get_end_position(&self) -> int { + unsafe { v8__Message__GetEndPosition(self) } + } + + /// Returns the Wasm function index where the error occurred. Returns -1 if + /// message is not from a Wasm script. + pub fn get_wasm_function_index(&self) -> int { + unsafe { v8__Message__GetWasmFunctionIndex(self) } + } + + /// Returns the error level of the message. + pub fn error_level(&self) -> int { + unsafe { v8__Message__ErrorLevel(self) } + } + + /// Returns the index within the line of the first character where + /// the error occurred. + pub fn get_start_column(&self) -> usize { + unsafe { v8__Message__GetStartColumn(self) as usize } + } + + /// Returns the index within the line of the last character where + /// the error occurred. + pub fn get_end_column(&self) -> usize { + unsafe { v8__Message__GetEndColumn(self) as usize } + } + + /// Passes on the value set by the embedder when it fed the script from which + /// this Message was generated to V8. + pub fn is_shared_cross_origin(&self) -> bool { + unsafe { v8__Message__IsSharedCrossOrigin(self) } + } + + pub fn is_opaque(&self) -> bool { + unsafe { v8__Message__IsOpaque(self) } + } } /// Creates an error message for the given exception. diff --git a/tests/test_api.rs b/tests/test_api.rs index 646f1591..f9a12d9a 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -447,18 +447,29 @@ fn add_message_listener() { static CALL_COUNT: AtomicUsize = AtomicUsize::new(0); extern "C" fn check_message_0( - message: Local, + mut message: Local, _exception: Local, ) { - CALL_COUNT.fetch_add(1, Ordering::SeqCst); + let isolate = message.get_isolate(); + let context = isolate.get_current_context(); let mut cbs = v8::CallbackScope::new(message); let scope = cbs.enter(); - { - let mut hs = v8::HandleScope::new(scope); - let scope = hs.enter(); - let message_str = message.get(scope); - assert_eq!(message_str.to_rust_string_lossy(scope), "Uncaught foo"); - } + let mut hs = v8::HandleScope::new(scope); + let scope = hs.enter(); + let message_str = message.get(scope); + assert_eq!(message_str.to_rust_string_lossy(scope), "Uncaught foo"); + assert_eq!(Some(1), message.get_line_number(context)); + assert!(message.get_script_resource_name(scope).is_some()); + assert!(message.get_source_line(scope, context).is_some()); + assert_eq!(message.get_start_position(), 0); + assert_eq!(message.get_end_position(), 1); + assert_eq!(message.get_wasm_function_index(), -1); + assert!(message.error_level() >= 0); + assert_eq!(message.get_start_column(), 0); + assert_eq!(message.get_end_column(), 1); + assert!(!message.is_shared_cross_origin()); + assert!(!message.is_opaque()); + CALL_COUNT.fetch_add(1, Ordering::SeqCst); } isolate.add_message_listener(check_message_0);