mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-12-24 08:09:16 -05:00
add test for schedule_pause_on_next_statement (#258)
This commit is contained in:
parent
9e14f18347
commit
2e61735f44
6 changed files with 189 additions and 61 deletions
|
@ -1326,9 +1326,9 @@ void v8_inspector__V8InspectorSession__dispatchProtocolMessage(
|
|||
}
|
||||
|
||||
void v8_inspector__V8InspectorSession__schedulePauseOnNextStatement(
|
||||
v8_inspector::V8InspectorSession& self, v8_inspector::StringBuffer& reason,
|
||||
v8_inspector::StringBuffer& detail) {
|
||||
self.schedulePauseOnNextStatement(reason.string(), detail.string());
|
||||
v8_inspector::V8InspectorSession& self, v8_inspector::StringView& reason,
|
||||
v8_inspector::StringView& detail) {
|
||||
self.schedulePauseOnNextStatement(reason, detail);
|
||||
}
|
||||
} // extern "C"
|
||||
|
||||
|
@ -1386,9 +1386,8 @@ 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);
|
||||
const v8_inspector::StringView& url, unsigned lineNumber,
|
||||
unsigned columnNumber, v8_inspector::V8StackTrace* stackTrace);
|
||||
} // extern "C"
|
||||
|
||||
struct v8_inspector__V8InspectorClient__BASE
|
||||
|
@ -1406,16 +1405,15 @@ struct v8_inspector__V8InspectorClient__BASE
|
|||
v8_inspector__V8InspectorClient__BASE__runIfWaitingForDebugger(
|
||||
*this, contextGroupId);
|
||||
}
|
||||
void consoleAPIMessage(
|
||||
int 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);
|
||||
*this, contextGroupId, level, message, url, lineNumber, columnNumber,
|
||||
stackTrace);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1442,11 +1440,10 @@ 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);
|
||||
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) {
|
||||
|
|
14
src/inspector/README.md
Normal file
14
src/inspector/README.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
Bindings to the V8 Inspector API
|
||||
|
||||
https://medium.com/@hyperandroid/v8-inspector-from-an-embedder-standpoint-7f9c0472e2b7
|
||||
|
||||
https://v8.dev/docs/inspector
|
||||
|
||||
https://chromedevtools.github.io/debugger-protocol-viewer/tot/
|
||||
|
||||
https://cs.chromium.org/chromium/src/v8/include/v8-inspector.h
|
||||
|
||||
https://github.com/nodejs/node/blob/v13.7.0/src/inspector_agent.cc
|
||||
https://github.com/nodejs/node/blob/v13.7.0/src/inspector_agent.h
|
||||
https://github.com/nodejs/node/tree/v13.7.0/src/inspector
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
use super::StringBuffer;
|
||||
use super::StringView;
|
||||
use crate::support::Delete;
|
||||
use crate::support::Opaque;
|
||||
|
@ -13,8 +12,8 @@ extern "C" {
|
|||
);
|
||||
fn v8_inspector__V8InspectorSession__schedulePauseOnNextStatement(
|
||||
session: *mut V8InspectorSession,
|
||||
break_reason: *mut StringBuffer,
|
||||
break_details: *mut StringBuffer,
|
||||
break_reason: &StringView,
|
||||
break_details: &StringView,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -30,14 +29,12 @@ impl V8InspectorSession {
|
|||
|
||||
pub fn schedule_pause_on_next_statement(
|
||||
&mut self,
|
||||
reason: &mut StringBuffer,
|
||||
detail: &mut StringBuffer,
|
||||
reason: &StringView,
|
||||
detail: &StringView,
|
||||
) {
|
||||
unsafe {
|
||||
v8_inspector__V8InspectorSession__schedulePauseOnNextStatement(
|
||||
self,
|
||||
&mut *reason,
|
||||
&mut *detail,
|
||||
self, reason, detail,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,6 @@ use crate::support::CxxVTable;
|
|||
use crate::support::Delete;
|
||||
use crate::support::UniquePtr;
|
||||
|
||||
// class StringBuffer {
|
||||
// public:
|
||||
// virtual ~StringBuffer() = default;
|
||||
// virtual const StringView& string() = 0;
|
||||
// // This method copies contents.
|
||||
// static std::unique_ptr<StringBuffer> create(const StringView&);
|
||||
// };
|
||||
|
||||
// TODO: in C++, this class is intended to be user-extensible, just like
|
||||
// like `Task`, `Client`, `Channel`. In Rust this would ideally also be the
|
||||
// case, but currently to obtain a `UniquePtr<StringBuffer>` is by making a
|
||||
|
|
|
@ -8,31 +8,6 @@ use std::ptr::NonNull;
|
|||
use std::slice;
|
||||
use std::string;
|
||||
|
||||
// class StringView {
|
||||
// public:
|
||||
// StringView() : m_is8Bit(true), m_length(0), m_characters8(nullptr) {}
|
||||
//
|
||||
// StringView(const uint8_t* characters, size_t length)
|
||||
// : m_is8Bit(true), m_length(length), m_characters8(characters) {}
|
||||
//
|
||||
// StringView(const uint16_t* characters, size_t length)
|
||||
// : m_is8Bit(false), m_length(length), m_characters16(characters) {}
|
||||
//
|
||||
// bool is8Bit() const { return m_is8Bit; }
|
||||
// size_t length() const { return m_length; }
|
||||
//
|
||||
// const uint8_t* characters8() const { return m_characters8; }
|
||||
// const uint16_t* characters16() const { return m_characters16; }
|
||||
//
|
||||
// private:
|
||||
// bool m_is8Bit;
|
||||
// size_t m_length;
|
||||
// union {
|
||||
// const uint8_t* m_characters8;
|
||||
// const uint16_t* m_characters16;
|
||||
// };
|
||||
// };
|
||||
|
||||
// Notes:
|
||||
// * This class is ported, not wrapped using bindings.
|
||||
// * Since Rust `repr(bool)` is not allowed, we're assuming that `bool` and
|
||||
|
|
|
@ -2359,6 +2359,159 @@ fn inspector_dispatch_protocol_message() {
|
|||
assert_eq!(channel.flush_protocol_notifications_count, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inspector_schedule_pause_on_next_statement() {
|
||||
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,
|
||||
count_run_message_loop_on_pause: usize,
|
||||
count_quit_message_loop_on_pause: usize,
|
||||
count_run_if_waiting_for_debugger: usize,
|
||||
}
|
||||
|
||||
impl Client {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
base: V8InspectorClientBase::new::<Self>(),
|
||||
count_run_message_loop_on_pause: 0,
|
||||
count_quit_message_loop_on_pause: 0,
|
||||
count_run_if_waiting_for_debugger: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use std::os::raw::c_int as int;
|
||||
|
||||
impl V8InspectorClientImpl for Client {
|
||||
fn base(&self) -> &V8InspectorClientBase {
|
||||
&self.base
|
||||
}
|
||||
fn base_mut(&mut self) -> &mut V8InspectorClientBase {
|
||||
&mut self.base
|
||||
}
|
||||
|
||||
fn run_message_loop_on_pause(&mut self, context_group_id: int) {
|
||||
assert_eq!(context_group_id, 1);
|
||||
self.count_run_message_loop_on_pause += 1;
|
||||
}
|
||||
fn quit_message_loop_on_pause(&mut self) {
|
||||
self.count_quit_message_loop_on_pause += 1;
|
||||
}
|
||||
fn run_if_waiting_for_debugger(&mut self, context_group_id: int) {
|
||||
assert_eq!(context_group_id, 1);
|
||||
self.count_run_message_loop_on_pause += 1;
|
||||
}
|
||||
}
|
||||
|
||||
struct TestChannel {
|
||||
base: ChannelBase,
|
||||
send_response_count: usize,
|
||||
send_notification_count: usize,
|
||||
flush_protocol_notifications_count: usize,
|
||||
}
|
||||
|
||||
impl TestChannel {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
base: ChannelBase::new::<Self>(),
|
||||
send_response_count: 0,
|
||||
send_notification_count: 0,
|
||||
flush_protocol_notifications_count: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ChannelImpl for TestChannel {
|
||||
fn base(&self) -> &ChannelBase {
|
||||
&self.base
|
||||
}
|
||||
fn base_mut(&mut self) -> &mut ChannelBase {
|
||||
&mut self.base
|
||||
}
|
||||
fn send_response(
|
||||
&mut self,
|
||||
call_id: i32,
|
||||
message: v8::UniquePtr<StringBuffer>,
|
||||
) {
|
||||
println!(
|
||||
"send_response call_id {} message {}",
|
||||
call_id,
|
||||
message.unwrap().string()
|
||||
);
|
||||
self.send_response_count += 1;
|
||||
}
|
||||
fn send_notification(&mut self, message: v8::UniquePtr<StringBuffer>) {
|
||||
println!("send_notificatio message {}", message.unwrap().string());
|
||||
self.send_notification_count += 1;
|
||||
}
|
||||
fn flush_protocol_notifications(&mut self) {
|
||||
self.flush_protocol_notifications_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
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 mut channel = TestChannel::new();
|
||||
let state = b"{}";
|
||||
let state_view = StringView::from(&state[..]);
|
||||
let mut session = inspector.connect(1, &mut channel, &state_view);
|
||||
|
||||
let name = b"";
|
||||
let name_view = StringView::from(&name[..]);
|
||||
inspector.context_created(context, 1, &name_view);
|
||||
|
||||
// In order for schedule_pause_on_next_statement to work, it seems you need
|
||||
// to first enable the debugger.
|
||||
let message = String::from(r#"{"id":1,"method":"Debugger.enable"}"#);
|
||||
let message = &message.into_bytes()[..];
|
||||
let message = StringView::from(message);
|
||||
session.dispatch_protocol_message(&message);
|
||||
|
||||
// The following commented out block seems to act similarly to
|
||||
// schedule_pause_on_next_statement. I'm not sure if they have the exact same
|
||||
// effect tho.
|
||||
// let message = String::from(r#"{"id":2,"method":"Debugger.pause"}"#);
|
||||
// let message = &message.into_bytes()[..];
|
||||
// let message = StringView::from(message);
|
||||
// session.dispatch_protocol_message(&message);
|
||||
let reason = b"";
|
||||
let reason = StringView::from(&reason[..]);
|
||||
let detail = b"";
|
||||
let detail = StringView::from(&detail[..]);
|
||||
session.schedule_pause_on_next_statement(&reason, &detail);
|
||||
|
||||
assert_eq!(channel.send_response_count, 1);
|
||||
assert_eq!(channel.send_notification_count, 0);
|
||||
assert_eq!(channel.flush_protocol_notifications_count, 0);
|
||||
assert_eq!(client.count_run_message_loop_on_pause, 0);
|
||||
assert_eq!(client.count_quit_message_loop_on_pause, 0);
|
||||
assert_eq!(client.count_run_if_waiting_for_debugger, 0);
|
||||
|
||||
let r = eval(scope, context, "1+2").unwrap();
|
||||
assert!(r.is_number());
|
||||
|
||||
assert_eq!(channel.send_response_count, 1);
|
||||
assert_eq!(channel.send_notification_count, 3);
|
||||
assert_eq!(channel.flush_protocol_notifications_count, 0);
|
||||
assert_eq!(client.count_run_message_loop_on_pause, 1);
|
||||
assert_eq!(client.count_quit_message_loop_on_pause, 0);
|
||||
assert_eq!(client.count_run_if_waiting_for_debugger, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn inspector_console_api_message() {
|
||||
let _setup_guard = setup();
|
||||
|
|
Loading…
Reference in a new issue