diff --git a/src/binding.cc b/src/binding.cc index 5facaf7a..b045972f 100644 --- a/src/binding.cc +++ b/src/binding.cc @@ -1378,6 +1378,13 @@ void v8_inspector__V8InspectorClient__BASE__quitMessageLoopOnPause( v8_inspector::V8InspectorClient& self); void v8_inspector__V8InspectorClient__BASE__runIfWaitingForDebugger( v8_inspector::V8InspectorClient& self, int contextGroupId); +void v8_inspector__V8InspectorClient__BASE__consoleAPIMessage( + v8_inspector::V8InspectorClient& self, int contextGroupId, + v8::Isolate::MessageErrorLevel level, + const v8_inspector::StringView& message, + const v8_inspector::StringView& url, + unsigned lineNumber, unsigned columnNumber, + v8_inspector::V8StackTrace* stackTrace); } // extern "C" struct v8_inspector__V8InspectorClient__BASE @@ -1395,6 +1402,17 @@ struct v8_inspector__V8InspectorClient__BASE v8_inspector__V8InspectorClient__BASE__runIfWaitingForDebugger( *this, contextGroupId); } + void consoleAPIMessage( + int contextGroupId, + v8::Isolate::MessageErrorLevel level, + const v8_inspector::StringView& message, + const v8_inspector::StringView& url, + unsigned lineNumber, unsigned columnNumber, + v8_inspector::V8StackTrace* stackTrace) override { + v8_inspector__V8InspectorClient__BASE__consoleAPIMessage( + *this, contextGroupId, level, message, url, + lineNumber, columnNumber, stackTrace); + } }; extern "C" { @@ -1416,6 +1434,17 @@ void v8_inspector__V8InspectorClient__runIfWaitingForDebugger( self.runIfWaitingForDebugger(contextGroupId); } +void v8_inspector__V8InspectorClient__consoleAPIMessage( + v8_inspector::V8InspectorClient& self, int contextGroupId, + v8::Isolate::MessageErrorLevel level, + const v8_inspector::StringView& message, + const v8_inspector::StringView& url, + unsigned lineNumber, unsigned columnNumber, + v8_inspector::V8StackTrace* stackTrace) { + self.consoleAPIMessage(contextGroupId, level, message, url, + lineNumber, columnNumber, stackTrace); +} + void v8_inspector__StringBuffer__DELETE(v8_inspector::StringBuffer& self) { delete &self; } diff --git a/src/inspector/client.rs b/src/inspector/client.rs index 6ac7e507..93e1e22b 100644 --- a/src/inspector/client.rs +++ b/src/inspector/client.rs @@ -1,3 +1,4 @@ +use super::{StringView, V8StackTrace}; use crate::support::int; use crate::support::CxxVTable; use crate::support::FieldOffset; @@ -20,6 +21,16 @@ extern "C" { this: &mut V8InspectorClient, context_group_id: int, ) -> (); + fn v8_inspector__V8InspectorClient__consoleAPIMessage( + this: &mut V8InspectorClient, + context_group_id: int, + level: int, + message: &StringView, + url: &StringView, + line_number: u32, + column_number: u32, + stack_trace: &mut V8StackTrace, + ) -> (); } #[no_mangle] @@ -47,6 +58,28 @@ pub unsafe extern "C" fn v8_inspector__V8InspectorClient__BASE__runIfWaitingForD .run_if_waiting_for_debugger(context_group_id) } +#[no_mangle] +pub unsafe extern "C" fn v8_inspector__V8InspectorClient__BASE__consoleAPIMessage( + this: &mut V8InspectorClient, + context_group_id: int, + level: int, + message: &StringView, + url: &StringView, + line_number: u32, + column_number: u32, + stack_trace: &mut V8StackTrace, +) { + V8InspectorClientBase::dispatch_mut(this).console_api_message( + context_group_id, + level, + message, + url, + line_number, + column_number, + stack_trace, + ) +} + #[repr(C)] pub struct V8InspectorClient { _cxx_vtable: CxxVTable, @@ -61,9 +94,11 @@ impl V8InspectorClient { ) } } + pub fn quit_message_loop_on_pause(&mut self) { unsafe { v8_inspector__V8InspectorClient__quitMessageLoopOnPause(self) } } + pub fn run_if_waiting_for_debugger(&mut self, context_group_id: int) { unsafe { v8_inspector__V8InspectorClient__runIfWaitingForDebugger( @@ -72,6 +107,31 @@ impl V8InspectorClient { ) } } + + #[allow(clippy::too_many_arguments)] + pub fn console_api_message( + &mut self, + context_group_id: int, + level: int, + message: &StringView, + url: &StringView, + line_number: u32, + column_number: u32, + stack_trace: &mut V8StackTrace, + ) { + unsafe { + v8_inspector__V8InspectorClient__consoleAPIMessage( + self, + context_group_id, + level, + message, + url, + line_number, + column_number, + stack_trace, + ) + } + } } pub trait AsV8InspectorClient { @@ -108,6 +168,19 @@ pub trait V8InspectorClientImpl: AsV8InspectorClient { fn run_message_loop_on_pause(&mut self, context_group_id: int) {} fn quit_message_loop_on_pause(&mut self) {} fn run_if_waiting_for_debugger(&mut self, context_group_id: int) {} + + #[allow(clippy::too_many_arguments)] + fn console_api_message( + &mut self, + context_group_id: int, + level: int, + message: &StringView, + url: &StringView, + line_number: u32, + column_number: u32, + stack_trace: &mut V8StackTrace, + ) { + } } pub struct V8InspectorClientBase { diff --git a/src/inspector/mod.rs b/src/inspector/mod.rs index c4e8b3b6..817c7fae 100644 --- a/src/inspector/mod.rs +++ b/src/inspector/mod.rs @@ -4,6 +4,7 @@ mod session; mod string_buffer; mod string_view; mod v8_inspector; +mod v8_stack_trace; pub use channel::{AsChannel, Channel, ChannelBase, ChannelImpl}; pub use client::AsV8InspectorClient; @@ -14,3 +15,4 @@ pub use session::V8InspectorSession; pub use string_buffer::StringBuffer; pub use string_view::StringView; pub use v8_inspector::V8Inspector; +pub use v8_stack_trace::V8StackTrace; diff --git a/src/inspector/v8_stack_trace.rs b/src/inspector/v8_stack_trace.rs new file mode 100644 index 00000000..5fb15a48 --- /dev/null +++ b/src/inspector/v8_stack_trace.rs @@ -0,0 +1,9 @@ +use crate::support::CxxVTable; + +#[repr(C)] +pub struct V8StackTrace { + _cxx_vtable: CxxVTable, +} + +// TODO(bnoordhuis) This needs to be fleshed out more but that can wait +// until it's actually needed. diff --git a/tests/test_api.rs b/tests/test_api.rs index 7b4a383e..aabbac7d 100644 --- a/tests/test_api.rs +++ b/tests/test_api.rs @@ -2350,6 +2350,75 @@ fn inspector_dispatch_protocol_message() { assert_eq!(channel.flush_protocol_notifications_count, 0); } +#[test] +fn inspector_console_api_message() { + let _setup_guard = setup(); + let mut params = v8::Isolate::create_params(); + params.set_array_buffer_allocator(v8::new_default_allocator()); + let mut isolate = v8::Isolate::new(params); + let mut locker = v8::Locker::new(&isolate); + let scope = locker.enter(); + + use v8::inspector::*; + + struct Client { + base: V8InspectorClientBase, + messages: Vec, + } + + impl Client { + fn new() -> Self { + Self { + base: V8InspectorClientBase::new::(), + messages: Vec::new(), + } + } + } + + impl V8InspectorClientImpl for Client { + fn base(&self) -> &V8InspectorClientBase { + &self.base + } + + fn base_mut(&mut self) -> &mut V8InspectorClientBase { + &mut self.base + } + + fn console_api_message( + &mut self, + _context_group_id: i32, + _level: i32, + message: &StringView, + _url: &StringView, + _line_number: u32, + _column_number: u32, + _stack_trace: &mut V8StackTrace, + ) { + self.messages.push(message.to_string()); + } + } + + let mut hs = v8::HandleScope::new(scope); + let scope = hs.enter(); + let context = v8::Context::new(scope); + let mut cs = v8::ContextScope::new(scope, context); + let scope = cs.enter(); + + let mut client = Client::new(); + let mut inspector = V8Inspector::create(&mut isolate, &mut client); + let name = b""; + let name_view = StringView::from(&name[..]); + inspector.context_created(context, 1, &name_view); + + let source = r#" + console.log("one"); + console.error("two"); + console.trace("three"); + "#; + let _ = eval(scope, context, source).unwrap(); + assert_eq!(client.messages, vec!["one", "two", "three"]); +} + #[test] fn context_from_object_template() { let _setup_guard = setup();