mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Implement console.trace
(#34629)
* Include unimplemented console methods in idl file Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Fix console.assert signature The condition is optional and there can be multiple messages. Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Implement console.trace Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * ./mach fmt Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Log stack trace when calling console.trace Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Update wpt expectations Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Include line/column info in console.trace logs Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Move option out of constant Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> * Update mozjs Signed-off-by: Simon Wülker <simon.wuelker@arcor.de> --------- Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
parent
ba56494eec
commit
28e330c9b6
7 changed files with 143 additions and 45 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -429,7 +429,7 @@ dependencies = [
|
||||||
"bitflags 2.6.0",
|
"bitflags 2.6.0",
|
||||||
"cexpr",
|
"cexpr",
|
||||||
"clang-sys",
|
"clang-sys",
|
||||||
"itertools 0.13.0",
|
"itertools 0.10.5",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
"regex",
|
"regex",
|
||||||
|
@ -1868,7 +1868,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -4449,7 +4449,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mozjs"
|
name = "mozjs"
|
||||||
version = "0.14.1"
|
version = "0.14.1"
|
||||||
source = "git+https://github.com/servo/mozjs#8ac195873f25c66c891478a291d762998fb151fe"
|
source = "git+https://github.com/servo/mozjs#bb560b6276cc587b4706b3162160cf945210335a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"cc",
|
"cc",
|
||||||
|
@ -4462,7 +4462,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mozjs_sys"
|
name = "mozjs_sys"
|
||||||
version = "0.128.3-8"
|
version = "0.128.3-8"
|
||||||
source = "git+https://github.com/servo/mozjs#8ac195873f25c66c891478a291d762998fb151fe"
|
source = "git+https://github.com/servo/mozjs#bb560b6276cc587b4706b3162160cf945210335a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bindgen",
|
"bindgen",
|
||||||
"cc",
|
"cc",
|
||||||
|
@ -5892,7 +5892,7 @@ dependencies = [
|
||||||
"errno",
|
"errno",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-raw-sys",
|
"linux-raw-sys",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -7157,7 +7157,7 @@ dependencies = [
|
||||||
"fastrand",
|
"fastrand",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"rustix",
|
"rustix",
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -8416,7 +8416,7 @@ version = "0.1.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -278,20 +278,22 @@ impl ConsoleActor {
|
||||||
LogLevel::Warn => "warn",
|
LogLevel::Warn => "warn",
|
||||||
LogLevel::Error => "error",
|
LogLevel::Error => "error",
|
||||||
LogLevel::Clear => "clear",
|
LogLevel::Clear => "clear",
|
||||||
_ => "log",
|
LogLevel::Trace => "trace",
|
||||||
|
LogLevel::Log => "log",
|
||||||
}
|
}
|
||||||
.to_owned();
|
.to_owned();
|
||||||
|
|
||||||
let console_api = ConsoleLog {
|
let console_api = ConsoleLog {
|
||||||
level: level.clone(),
|
level,
|
||||||
filename: console_message.filename.clone(),
|
filename: console_message.filename,
|
||||||
line_number: console_message.line_number as u32,
|
line_number: console_message.line_number as u32,
|
||||||
column_number: console_message.column_number as u32,
|
column_number: console_message.column_number as u32,
|
||||||
time_stamp: SystemTime::now()
|
time_stamp: SystemTime::now()
|
||||||
.duration_since(UNIX_EPOCH)
|
.duration_since(UNIX_EPOCH)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.as_millis() as u64,
|
.as_millis() as u64,
|
||||||
arguments: vec![console_message.message.clone()],
|
arguments: vec![console_message.message],
|
||||||
|
stacktrace: console_message.stacktrace,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.cached_events
|
self.cached_events
|
||||||
|
|
|
@ -694,6 +694,7 @@ fn run_server(
|
||||||
filename: css_error.filename,
|
filename: css_error.filename,
|
||||||
line_number: css_error.line as usize,
|
line_number: css_error.line as usize,
|
||||||
column_number: css_error.column as usize,
|
column_number: css_error.column as usize,
|
||||||
|
stacktrace: vec![],
|
||||||
};
|
};
|
||||||
handle_console_message(
|
handle_console_message(
|
||||||
actors.clone(),
|
actors.clone(),
|
||||||
|
|
|
@ -3,16 +3,16 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::io;
|
use std::{io, ptr};
|
||||||
|
|
||||||
use devtools_traits::{ConsoleMessage, LogLevel, ScriptToDevtoolsControlMsg};
|
use devtools_traits::{ConsoleMessage, LogLevel, ScriptToDevtoolsControlMsg, StackFrame};
|
||||||
use js::jsapi::{self, ESClass, PropertyDescriptor};
|
use js::jsapi::{self, ESClass, PropertyDescriptor};
|
||||||
use js::jsval::UndefinedValue;
|
use js::jsval::UndefinedValue;
|
||||||
use js::rust::wrappers::{
|
use js::rust::wrappers::{
|
||||||
GetBuiltinClass, GetPropertyKeys, JS_GetOwnPropertyDescriptorById, JS_GetPropertyById,
|
GetBuiltinClass, GetPropertyKeys, JS_GetOwnPropertyDescriptorById, JS_GetPropertyById,
|
||||||
JS_IdToValue, JS_ValueToSource,
|
JS_IdToValue, JS_ValueToSource,
|
||||||
};
|
};
|
||||||
use js::rust::{describe_scripted_caller, HandleValue, IdVector};
|
use js::rust::{describe_scripted_caller, CapturedJSStack, HandleValue, IdVector};
|
||||||
|
|
||||||
use crate::dom::bindings::codegen::Bindings::ConsoleBinding::consoleMethods;
|
use crate::dom::bindings::codegen::Bindings::ConsoleBinding::consoleMethods;
|
||||||
use crate::dom::bindings::conversions::jsstring_to_str;
|
use crate::dom::bindings::conversions::jsstring_to_str;
|
||||||
|
@ -27,8 +27,8 @@ const MAX_LOG_DEPTH: usize = 10;
|
||||||
/// The maximum elements in an object logged by console methods.
|
/// The maximum elements in an object logged by console methods.
|
||||||
const MAX_LOG_CHILDREN: usize = 15;
|
const MAX_LOG_CHILDREN: usize = 15;
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Console
|
/// <https://developer.mozilla.org/en-US/docs/Web/API/Console>
|
||||||
pub struct Console(());
|
pub struct Console;
|
||||||
|
|
||||||
impl Console {
|
impl Console {
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
|
@ -36,12 +36,14 @@ impl Console {
|
||||||
if let Some(chan) = global.devtools_chan() {
|
if let Some(chan) = global.devtools_chan() {
|
||||||
let caller =
|
let caller =
|
||||||
unsafe { describe_scripted_caller(*GlobalScope::get_cx()) }.unwrap_or_default();
|
unsafe { describe_scripted_caller(*GlobalScope::get_cx()) }.unwrap_or_default();
|
||||||
|
|
||||||
let console_message = ConsoleMessage {
|
let console_message = ConsoleMessage {
|
||||||
message,
|
message,
|
||||||
log_level: level,
|
log_level: level,
|
||||||
filename: caller.filename,
|
filename: caller.filename,
|
||||||
line_number: caller.line as usize,
|
line_number: caller.line as usize,
|
||||||
column_number: caller.col as usize,
|
column_number: caller.col as usize,
|
||||||
|
stacktrace: get_js_stack(*GlobalScope::get_cx()),
|
||||||
};
|
};
|
||||||
let worker_id = global
|
let worker_id = global
|
||||||
.downcast::<WorkerGlobalScope>()
|
.downcast::<WorkerGlobalScope>()
|
||||||
|
@ -259,17 +261,20 @@ impl consoleMethods<crate::DomTypeHolder> for Console {
|
||||||
console_messages(global, messages, LogLevel::Error)
|
console_messages(global, messages, LogLevel::Error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <https://console.spec.whatwg.org/#trace>
|
||||||
|
fn Trace(_cx: JSContext, global: &GlobalScope, messages: Vec<HandleValue>) {
|
||||||
|
console_messages(global, messages, LogLevel::Trace)
|
||||||
|
}
|
||||||
|
|
||||||
// https://developer.mozilla.org/en-US/docs/Web/API/Console/assert
|
// https://developer.mozilla.org/en-US/docs/Web/API/Console/assert
|
||||||
fn Assert(_cx: JSContext, global: &GlobalScope, condition: bool, message: HandleValue) {
|
fn Assert(_cx: JSContext, global: &GlobalScope, condition: bool, messages: Vec<HandleValue>) {
|
||||||
if !condition {
|
if !condition {
|
||||||
let message = if message.is_undefined() {
|
let message = DOMString::from(format!(
|
||||||
DOMString::from("no message")
|
"Assertion failed: {}",
|
||||||
} else {
|
stringify_handle_values(messages)
|
||||||
stringify_handle_value(message)
|
));
|
||||||
};
|
console_message(global, message, LogLevel::Error);
|
||||||
let message = DOMString::from(format!("Assertion failed: {}", message));
|
}
|
||||||
console_message(global, message, LogLevel::Error)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://console.spec.whatwg.org/#time
|
// https://console.spec.whatwg.org/#time
|
||||||
|
@ -331,3 +336,85 @@ impl consoleMethods<crate::DomTypeHolder> for Console {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unsafe_code)]
|
||||||
|
fn get_js_stack(cx: *mut jsapi::JSContext) -> Vec<StackFrame> {
|
||||||
|
const MAX_FRAME_COUNT: u32 = 128;
|
||||||
|
|
||||||
|
let mut frames = vec![];
|
||||||
|
rooted!(in(cx) let mut handle = ptr::null_mut());
|
||||||
|
let captured_js_stack = unsafe { CapturedJSStack::new(cx, handle, Some(MAX_FRAME_COUNT)) };
|
||||||
|
let Some(captured_js_stack) = captured_js_stack else {
|
||||||
|
return frames;
|
||||||
|
};
|
||||||
|
|
||||||
|
captured_js_stack.for_each_stack_frame(|frame| {
|
||||||
|
rooted!(in(cx) let mut result: *mut jsapi::JSString = ptr::null_mut());
|
||||||
|
|
||||||
|
// Get function name
|
||||||
|
unsafe {
|
||||||
|
jsapi::GetSavedFrameFunctionDisplayName(
|
||||||
|
cx,
|
||||||
|
ptr::null_mut(),
|
||||||
|
frame.into(),
|
||||||
|
result.handle_mut().into(),
|
||||||
|
jsapi::SavedFrameSelfHosted::Include,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let function_name = if let Some(nonnull_result) = ptr::NonNull::new(*result) {
|
||||||
|
unsafe { jsstring_to_str(cx, nonnull_result) }.into()
|
||||||
|
} else {
|
||||||
|
"<anonymous>".into()
|
||||||
|
};
|
||||||
|
|
||||||
|
// Get source file name
|
||||||
|
result.set(ptr::null_mut());
|
||||||
|
unsafe {
|
||||||
|
jsapi::GetSavedFrameSource(
|
||||||
|
cx,
|
||||||
|
ptr::null_mut(),
|
||||||
|
frame.into(),
|
||||||
|
result.handle_mut().into(),
|
||||||
|
jsapi::SavedFrameSelfHosted::Include,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let filename = if let Some(nonnull_result) = ptr::NonNull::new(*result) {
|
||||||
|
unsafe { jsstring_to_str(cx, nonnull_result) }.into()
|
||||||
|
} else {
|
||||||
|
"<anonymous>".into()
|
||||||
|
};
|
||||||
|
|
||||||
|
// get line/column number
|
||||||
|
let mut line_number = 0;
|
||||||
|
unsafe {
|
||||||
|
jsapi::GetSavedFrameLine(
|
||||||
|
cx,
|
||||||
|
ptr::null_mut(),
|
||||||
|
frame.into(),
|
||||||
|
&mut line_number,
|
||||||
|
jsapi::SavedFrameSelfHosted::Include,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut column_number = jsapi::JS::TaggedColumnNumberOneOrigin { value_: 0 };
|
||||||
|
unsafe {
|
||||||
|
jsapi::GetSavedFrameColumn(
|
||||||
|
cx,
|
||||||
|
ptr::null_mut(),
|
||||||
|
frame.into(),
|
||||||
|
&mut column_number,
|
||||||
|
jsapi::SavedFrameSelfHosted::Include,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
let frame = StackFrame {
|
||||||
|
filename,
|
||||||
|
function_name,
|
||||||
|
line_number,
|
||||||
|
column_number: column_number.value_,
|
||||||
|
};
|
||||||
|
|
||||||
|
frames.push(frame);
|
||||||
|
});
|
||||||
|
|
||||||
|
frames
|
||||||
|
}
|
||||||
|
|
|
@ -5,16 +5,20 @@
|
||||||
// https://console.spec.whatwg.org/
|
// https://console.spec.whatwg.org/
|
||||||
|
|
||||||
[ClassString="Console",
|
[ClassString="Console",
|
||||||
Exposed=(Window,Worker,Worklet)]
|
Exposed=*]
|
||||||
namespace console {
|
namespace console {
|
||||||
// Logging
|
// Logging
|
||||||
undefined log(any... messages);
|
undefined assert(optional boolean condition = false, any... data);
|
||||||
undefined debug(any... messages);
|
|
||||||
undefined info(any... messages);
|
|
||||||
undefined warn(any... messages);
|
|
||||||
undefined error(any... messages);
|
|
||||||
undefined assert(boolean condition, optional any message);
|
|
||||||
undefined clear();
|
undefined clear();
|
||||||
|
undefined debug(any... messages);
|
||||||
|
undefined error(any... messages);
|
||||||
|
undefined info(any... messages);
|
||||||
|
undefined log(any... messages);
|
||||||
|
// undefined table(optional any tabularData, optional sequence<DOMString> properties);
|
||||||
|
undefined trace(any... data);
|
||||||
|
undefined warn(any... messages);
|
||||||
|
// undefined dir(optional any item, optional object? options);
|
||||||
|
// undefined dirxml(any... data);
|
||||||
|
|
||||||
// Counting
|
// Counting
|
||||||
undefined count(optional DOMString label = "default");
|
undefined count(optional DOMString label = "default");
|
||||||
|
|
|
@ -280,6 +280,7 @@ pub enum LogLevel {
|
||||||
Warn,
|
Warn,
|
||||||
Error,
|
Error,
|
||||||
Clear,
|
Clear,
|
||||||
|
Trace,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
@ -290,6 +291,21 @@ pub struct ConsoleMessage {
|
||||||
pub filename: String,
|
pub filename: String,
|
||||||
pub line_number: usize,
|
pub line_number: usize,
|
||||||
pub column_number: usize,
|
pub column_number: usize,
|
||||||
|
pub stacktrace: Vec<StackFrame>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct StackFrame {
|
||||||
|
pub filename: String,
|
||||||
|
|
||||||
|
#[serde(rename = "functionName")]
|
||||||
|
pub function_name: String,
|
||||||
|
|
||||||
|
#[serde(rename = "columnNumber")]
|
||||||
|
pub column_number: u32,
|
||||||
|
|
||||||
|
#[serde(rename = "lineNumber")]
|
||||||
|
pub line_number: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
@ -327,7 +343,7 @@ pub struct ConsoleLog {
|
||||||
pub column_number: u32,
|
pub column_number: u32,
|
||||||
pub time_stamp: u64,
|
pub time_stamp: u64,
|
||||||
pub arguments: Vec<String>,
|
pub arguments: Vec<String>,
|
||||||
// pub stacktrace: Vec<...>,
|
pub stacktrace: Vec<StackFrame>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize)]
|
#[derive(Debug, Deserialize, Serialize)]
|
||||||
|
|
12
tests/wpt/meta/console/idlharness.any.js.ini
vendored
12
tests/wpt/meta/console/idlharness.any.js.ini
vendored
|
@ -1,13 +1,7 @@
|
||||||
[idlharness.any.html]
|
[idlharness.any.html]
|
||||||
[console namespace: operation assert(optional boolean, any...)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[console namespace: operation table(optional any, optional sequence<DOMString>)]
|
[console namespace: operation table(optional any, optional sequence<DOMString>)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[console namespace: operation trace(any...)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[console namespace: operation dir(optional any, optional object?)]
|
[console namespace: operation dir(optional any, optional object?)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -16,15 +10,9 @@
|
||||||
|
|
||||||
|
|
||||||
[idlharness.any.worker.html]
|
[idlharness.any.worker.html]
|
||||||
[console namespace: operation assert(optional boolean, any...)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[console namespace: operation table(optional any, optional sequence<DOMString>)]
|
[console namespace: operation table(optional any, optional sequence<DOMString>)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[console namespace: operation trace(any...)]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[console namespace: operation dir(optional any, optional object?)]
|
[console namespace: operation dir(optional any, optional object?)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue