Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 8 additions & 30 deletions components/script/dom/bindings/constructor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,21 +79,11 @@ fn html_constructor(
UnwrapObjectDynamic(call_args.new_target().to_object(), cx.raw_cx(), true)
});
if new_target_unwrapped.is_null() {
throw_dom_exception(
cx.into(),
global,
Error::Type(c"new.target is null".to_owned()),
CanGc::from_cx(cx),
);
throw_dom_exception(cx, global, Error::Type(c"new.target is null".to_owned()));
return Err(());
}
if call_args.callee() == new_target_unwrapped.get() {
throw_dom_exception(
cx.into(),
global,
Error::Type(c"Illegal constructor.".to_owned()),
CanGc::from_cx(cx),
);
throw_dom_exception(cx, global, Error::Type(c"Illegal constructor.".to_owned()));
return Err(());
}

Expand All @@ -104,10 +94,9 @@ fn html_constructor(
Some(definition) => definition,
None => {
throw_dom_exception(
cx.into(),
cx,
global,
Error::Type(c"No custom element definition found for new.target".to_owned()),
CanGc::from_cx(cx),
);
return Err(());
},
Expand All @@ -118,7 +107,7 @@ fn html_constructor(

rooted!(&in(cx) let callee = unsafe { UnwrapObjectStatic(call_args.callee()) });
if callee.is_null() {
throw_dom_exception(cx.into(), global, Error::Security(None), CanGc::from_cx(cx));
throw_dom_exception(cx, global, Error::Security(None));
return Err(());
}

Expand Down Expand Up @@ -149,10 +138,9 @@ fn html_constructor(
// Callee must be the same as the element interface's constructor object.
if constructor.get() != callee.get() {
throw_dom_exception(
cx.into(),
cx,
global,
Error::Type(c"Custom element does not extend the proper interface".to_owned()),
CanGc::from_cx(cx),
);
return Err(());
}
Expand Down Expand Up @@ -197,12 +185,7 @@ fn html_constructor(
}

if !check_type(&element) {
throw_dom_exception(
cx.into(),
global,
Error::InvalidState(None),
CanGc::from_cx(cx),
);
throw_dom_exception(cx, global, Error::InvalidState(None));
return Err(());
} else {
// Step 7.9 Return element.
Expand All @@ -220,12 +203,7 @@ fn html_constructor(

// Step 13
if !check_type(&element) {
throw_dom_exception(
cx.into(),
global,
Error::InvalidState(None),
CanGc::from_cx(cx),
);
throw_dom_exception(cx, global, Error::InvalidState(None));
return Err(());
} else {
element
Expand All @@ -236,7 +214,7 @@ fn html_constructor(
let s = c"Top of construction stack marked AlreadyConstructed due to \
a custom element constructor constructing itself after super()"
.to_owned();
throw_dom_exception(cx.into(), global, Error::Type(s), CanGc::from_cx(cx));
throw_dom_exception(cx, global, Error::Type(s));
return Err(());
},
};
Expand Down
86 changes: 35 additions & 51 deletions components/script/dom/bindings/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ use js::context::JSContext;
use js::conversions::jsstr_to_string;
use js::error::{throw_range_error, throw_type_error};
use js::gc::{HandleObject, HandleValue, MutableHandleValue};
use js::jsapi::ExceptionStackBehavior;
#[cfg(feature = "js_backtrace")]
use js::jsapi::StackFormat as JSStackFormat;
use js::jsapi::{ExceptionStackBehavior, JS_IsExceptionPending};
use js::jsval::UndefinedValue;
use js::realm::CurrentRealm;
use js::rust::wrappers::{JS_ErrorFromException, JS_SetPendingException};
use js::rust::wrappers2::{JS_ClearPendingException, JS_GetPendingException, JS_GetProperty};
use js::rust::wrappers::JS_ErrorFromException;
use js::rust::wrappers2::{
JS_ClearPendingException, JS_GetPendingException, JS_GetProperty, JS_IsExceptionPending,
JS_SetPendingException,
};
use js::rust::{describe_scripted_caller, error_info_from_exception_stack};
use libc::c_uint;
#[cfg(feature = "js_backtrace")]
Expand All @@ -36,7 +39,6 @@ use crate::dom::bindings::str::USVString;
use crate::dom::domexception::{DOMErrorName, DOMException};
use crate::dom::globalscope::GlobalScope;
use crate::dom::types::QuotaExceededError;
use crate::realms::InRealm;
use crate::script_runtime::{CanGc, JSContext as SafeJSContext};

#[cfg(feature = "js_backtrace")]
Expand All @@ -57,42 +59,37 @@ pub(crate) enum JsEngineError {
}

/// Set a pending exception for the given `result` on `cx`.
pub(crate) fn throw_dom_exception(
cx: SafeJSContext,
global: &GlobalScope,
result: Error,
can_gc: CanGc,
) {
pub(crate) fn throw_dom_exception(cx: &mut JSContext, global: &GlobalScope, result: Error) {
#[cfg(feature = "js_backtrace")]
unsafe {
capture_stack!(in(*cx) let stack);
capture_stack!(&in(cx) let stack);
let js_stack = stack.and_then(|stack| stack.as_string(None, JSStackFormat::Default));
let rust_stack = Backtrace::new();
LAST_EXCEPTION_BACKTRACE.with(|backtrace| {
*backtrace.borrow_mut() = Some((js_stack, format!("{:?}", rust_stack)));
});
}

match create_dom_exception(global, result, can_gc) {
match create_dom_exception(global, result, CanGc::from_cx(cx)) {
Ok(exception) => unsafe {
assert!(!JS_IsExceptionPending(*cx));
rooted!(in(*cx) let mut thrown = UndefinedValue());
exception.safe_to_jsval(cx, thrown.handle_mut(), can_gc);
JS_SetPendingException(*cx, thrown.handle(), ExceptionStackBehavior::Capture);
assert!(!JS_IsExceptionPending(cx));
rooted!(&in(cx) let mut thrown = UndefinedValue());
exception.safe_to_jsval(cx.into(), thrown.handle_mut(), CanGc::from_cx(cx));
JS_SetPendingException(cx, thrown.handle(), ExceptionStackBehavior::Capture);
},

Err(JsEngineError::Type(message)) => unsafe {
assert!(!JS_IsExceptionPending(*cx));
throw_type_error(*cx, &message);
assert!(!JS_IsExceptionPending(cx));
throw_type_error(cx.raw_cx(), &message);
},

Err(JsEngineError::Range(message)) => unsafe {
assert!(!JS_IsExceptionPending(*cx));
throw_range_error(*cx, &message);
assert!(!JS_IsExceptionPending(cx));
throw_range_error(cx.raw_cx(), &message);
},

Err(JsEngineError::JSFailed) => unsafe {
assert!(JS_IsExceptionPending(*cx));
assert!(JS_IsExceptionPending(cx));
},
}
}
Expand Down Expand Up @@ -348,32 +345,27 @@ impl ErrorInfo {
/// Report a pending exception, thereby clearing it.
pub(crate) fn report_pending_exception(cx: &mut CurrentRealm) {
rooted!(&in(cx) let mut value = UndefinedValue());
if let Some(error_info) =
error_info_from_pending_exception(cx.into(), value.handle_mut(), CanGc::from_cx(cx))
{
if let Some(error_info) = error_info_from_pending_exception(cx, value.handle_mut()) {
GlobalScope::from_current_realm(cx).report_an_error(cx, error_info, value.handle());
}
}

fn error_info_from_pending_exception(
cx: SafeJSContext,
cx: &mut JSContext,
value: MutableHandleValue,
_can_gc: CanGc,
) -> Option<ErrorInfo> {
unsafe {
if !JS_IsExceptionPending(*cx) {
return None;
}
if unsafe { !JS_IsExceptionPending(cx) } {
return None;
}

let error_info = error_info_from_exception_stack(*cx, value.into())?;
let error_info = unsafe { error_info_from_exception_stack(cx.raw_cx(), value.into())? };

Some(ErrorInfo {
message: error_info.message,
filename: error_info.filename,
lineno: error_info.line,
column: error_info.col,
})
}
Some(ErrorInfo {
message: error_info.message,
filename: error_info.filename,
lineno: error_info.line,
column: error_info.col,
})
}

pub(crate) fn javascript_error_info_from_error_info(
Expand Down Expand Up @@ -417,19 +409,11 @@ pub(crate) fn javascript_error_info_from_error_info(
pub(crate) fn take_and_report_pending_exception_for_api(
cx: &mut CurrentRealm,
) -> Option<JavaScriptErrorInfo> {
let in_realm_proof = cx.into();
let in_realm = InRealm::Already(&in_realm_proof);

rooted!(&in(cx) let mut value = UndefinedValue());
let error_info =
error_info_from_pending_exception(cx.into(), value.handle_mut(), CanGc::from_cx(cx))?;
let error_info = error_info_from_pending_exception(cx, value.handle_mut())?;

let return_value = javascript_error_info_from_error_info(cx, &error_info, value.handle());
GlobalScope::from_safe_context(cx.into(), in_realm).report_an_error(
cx,
error_info,
value.handle(),
);
GlobalScope::from_current_realm(cx).report_an_error(cx, error_info, value.handle());

Some(return_value)
}
Expand All @@ -443,11 +427,11 @@ impl ErrorToJsval for Error {
fn to_jsval(self, cx: &mut JSContext, global: &GlobalScope, rval: MutableHandleValue) {
match self {
Error::JSFailed => (),
_ => unsafe { assert!(!JS_IsExceptionPending(cx.raw_cx())) },
_ => unsafe { assert!(!JS_IsExceptionPending(cx)) },
}
throw_dom_exception(cx.into(), global, self, CanGc::from_cx(cx));
throw_dom_exception(cx, global, self);
unsafe {
assert!(JS_IsExceptionPending(cx.raw_cx()));
assert!(JS_IsExceptionPending(cx));
assert!(JS_GetPendingException(cx, rval));
JS_ClearPendingException(cx);
}
Expand Down
2 changes: 1 addition & 1 deletion components/script/dom/bindings/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ impl DomHelpers<crate::DomTypeHolder> for crate::DomTypeHolder {
global: &<crate::DomTypeHolder as DomTypes>::GlobalScope,
result: Error,
) {
throw_dom_exception(cx.into(), global, result, CanGc::from_cx(cx))
throw_dom_exception(cx, global, result)
}

fn call_html_constructor<
Expand Down
3 changes: 1 addition & 2 deletions components/script/dom/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ use crate::dom::svg::svgelement::SVGElement;
use crate::dom::svg::svgimageelement::SVGImageElement;
use crate::dom::svg::svgsvgelement::SVGSVGElement;
use crate::realms::enter_auto_realm;
use crate::script_runtime::CanGc;
use crate::script_thread::ScriptThread;

fn create_svg_element(
Expand Down Expand Up @@ -194,7 +193,7 @@ fn create_html_element(

// Substep 1. Report exception for definition’s constructor’s corresponding
// JavaScript object’s associated realm’s global object.
throw_dom_exception(cx.into(), &global, error, CanGc::from_cx(cx));
throw_dom_exception(cx, &global, error);
report_pending_exception(cx);

// Substep 2. Set result to the result of creating an element internal given document,
Expand Down
2 changes: 1 addition & 1 deletion components/script/dom/customelementregistry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,7 @@ pub(crate) fn upgrade_element(
let mut realm = enter_auto_realm(cx, &*global);
let cx = &mut realm.current_realm();

throw_dom_exception(cx.into(), &global, error, CanGc::from_cx(cx));
throw_dom_exception(cx, &global, error);
report_pending_exception(cx);

return;
Expand Down
6 changes: 2 additions & 4 deletions components/script/dom/encoding/textencoderstream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,9 @@ fn jsval_to_primitive(
unsafe {
if !JS_IsExceptionPending(cx) {
throw_dom_exception(
cx.into(),
cx,
global,
Error::Type(c"Cannot convert JSObject to primitive".to_owned()),
CanGc::from_cx(cx),
);
}
}
Expand Down Expand Up @@ -227,10 +226,9 @@ pub(crate) fn encode_and_enqueue_a_chunk(
unsafe {
if !JS_IsExceptionPending(cx) {
throw_dom_exception(
cx.into(),
cx,
global,
Error::Type(c"Cannot convert JS primitive to string".to_owned()),
CanGc::from_cx(cx),
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ impl ReadableStreamDefaultController {
// First, throw the exception.
// Note: this must be done manually here,
// because `enqueue_value_with_size` does not call into JS.
throw_dom_exception(cx.into(), &self.global(), error, CanGc::from_cx(cx));
throw_dom_exception(cx, &self.global(), error);

// Then, get a handle to the JS val for the exception,
// and use that to error the stream.
Expand Down
7 changes: 1 addition & 6 deletions components/script/dom/windowproxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1267,12 +1267,7 @@ impl Drop for WindowProxyHandler {
fn throw_security_error(realm: &mut CurrentRealm) -> bool {
if !unsafe { JS_IsExceptionPending(realm) } {
let global = GlobalScope::from_current_realm(realm);
throw_dom_exception(
realm.into(),
&global,
Error::Security(None),
CanGc::from_cx(realm),
);
throw_dom_exception(realm, &global, Error::Security(None));
}
false
}
Expand Down
2 changes: 1 addition & 1 deletion components/script/script_module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1701,7 +1701,7 @@ pub(crate) fn register_import_map(

// Step 1. If result's error to rethrow is not null, then report
// an exception given by result's error to rethrow for global and return.
throw_dom_exception(cx.into(), global, exception, CanGc::from_cx(cx));
throw_dom_exception(cx, global, exception);
report_pending_exception(cx);
},
}
Expand Down
Loading