0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-12-26 09:13:46 -05:00

feat: Add v8::StackTrace::current_script_name_or_source_url (#1211)

This commit is contained in:
Bartek Iwańczuk 2023-04-21 19:09:56 +02:00 committed by GitHub
parent 9394983d15
commit 48c2ac89db
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 88 additions and 0 deletions

View file

@ -2039,6 +2039,11 @@ const v8::StackTrace* v8__StackTrace__CurrentStackTrace(v8::Isolate* isolate,
return local_to_ptr(v8::StackTrace::CurrentStackTrace(isolate, frame_limit));
}
const v8::String* v8__StackTrace__CurrentScriptNameOrSourceURL(
v8::Isolate* isolate) {
return local_to_ptr(v8::StackTrace::CurrentScriptNameOrSourceURL(isolate));
}
int v8__StackTrace__GetFrameCount(const v8::StackTrace& self) {
return self.GetFrameCount();
}

View file

@ -38,6 +38,9 @@ extern "C" {
isolate: *mut Isolate,
frame_limit: int,
) -> *const StackTrace;
fn v8__StackTrace__CurrentScriptNameOrSourceURL(
isolate: *mut Isolate,
) -> *const String;
fn v8__StackTrace__GetFrameCount(this: *const StackTrace) -> int;
fn v8__StackTrace__GetFrame(
this: *const StackTrace,
@ -87,6 +90,26 @@ impl StackTrace {
}
}
/// Returns the first valid script name or source URL starting at the top of
/// the JS stack. The returned string is either an empty handle if no script
/// name/url was found or a non-zero-length string.
///
/// This method is equivalent to calling StackTrace::CurrentStackTrace and
/// walking the resulting frames from the beginning until a non-empty script
/// name/url is found. The difference is that this method won't allocate
/// a stack trace.
///
#[inline(always)]
pub fn current_script_name_or_source_url<'s>(
scope: &mut HandleScope<'s>,
) -> Option<Local<'s, String>> {
unsafe {
scope.cast_local(|sd| {
v8__StackTrace__CurrentScriptNameOrSourceURL(sd.get_isolate_ptr())
})
}
}
/// Returns the number of StackFrames.
#[inline(always)]
pub fn get_frame_count(&self) -> usize {

View file

@ -7768,6 +7768,66 @@ fn current_stack_trace() {
assert_eq!(too_deep, 5);
}
#[test]
fn current_script_name_or_source_url() {
let _setup_guard = setup::parallel_test();
static mut USED: u32 = 0;
fn analyze_script_url_in_stack(
scope: &mut v8::HandleScope,
_args: v8::FunctionCallbackArguments,
_rv: v8::ReturnValue,
) {
let maybe_name = v8::StackTrace::current_script_name_or_source_url(scope);
assert!(maybe_name.is_some());
unsafe { USED = 1 };
assert_eq!(maybe_name.unwrap().to_rust_string_lossy(scope), "foo.js")
}
// Setup isolate
let isolate = &mut v8::Isolate::new(Default::default());
let scope = &mut v8::HandleScope::new(isolate);
let key = v8::String::new(scope, "analyzeScriptURLInStack").unwrap();
let tmpl = v8::FunctionTemplate::new(scope, analyze_script_url_in_stack);
let obj_template = v8::ObjectTemplate::new(scope);
obj_template.set(key.into(), tmpl.into());
let context = v8::Context::new_from_template(scope, obj_template);
let scope = &mut v8::ContextScope::new(scope, context);
let src = r#"function foo() {
analyzeScriptURLInStack();
}
foo();"#;
let resource_name = v8::String::new(scope, "foo.js").unwrap();
let resource_line_offset = 4;
let resource_column_offset = 5;
let resource_is_shared_cross_origin = true;
let script_id = 123;
let source_map_url = v8::String::new(scope, "source_map_url").unwrap();
let resource_is_opaque = true;
let is_wasm = false;
let is_module = false;
let script_origin = v8::ScriptOrigin::new(
scope,
resource_name.into(),
resource_line_offset,
resource_column_offset,
resource_is_shared_cross_origin,
script_id,
source_map_url.into(),
resource_is_opaque,
is_wasm,
is_module,
);
let source = v8::String::new(scope, src).unwrap();
let script =
v8::Script::compile(scope, source, Some(&script_origin)).unwrap();
script.run(scope).unwrap();
unsafe { assert_eq!(USED, 1) };
}
#[test]
fn instance_of() {
let _setup_guard = setup::parallel_test();