diff options
Diffstat (limited to 'components/script')
72 files changed, 968 insertions, 1009 deletions
diff --git a/components/script/body.rs b/components/script/body.rs index 1e18bc565a6..728315bf1fa 100644 --- a/components/script/body.rs +++ b/components/script/body.rs @@ -13,8 +13,8 @@ use crate::dom::blob::{Blob, BlobImpl}; use crate::dom::formdata::FormData; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; +use crate::script_runtime::JSContext; use js::jsapi::Heap; -use js::jsapi::JSContext; use js::jsapi::JSObject; use js::jsapi::JS_ClearPendingException; use js::jsapi::Value as JSValue; @@ -122,7 +122,7 @@ fn run_package_data_algorithm<T: BodyOperations + DomObject>( BodyType::Json => run_json_data_algorithm(cx, bytes), BodyType::Blob => run_blob_data_algorithm(&global, bytes, mime), BodyType::FormData => run_form_data_algorithm(&global, bytes, mime), - BodyType::ArrayBuffer => unsafe { run_array_buffer_data_algorithm(cx, bytes) }, + BodyType::ArrayBuffer => run_array_buffer_data_algorithm(cx, bytes), } } @@ -133,20 +133,20 @@ fn run_text_data_algorithm(bytes: Vec<u8>) -> Fallible<FetchedData> { } #[allow(unsafe_code)] -fn run_json_data_algorithm(cx: *mut JSContext, bytes: Vec<u8>) -> Fallible<FetchedData> { +fn run_json_data_algorithm(cx: JSContext, bytes: Vec<u8>) -> Fallible<FetchedData> { let json_text = String::from_utf8_lossy(&bytes); let json_text: Vec<u16> = json_text.encode_utf16().collect(); - rooted!(in(cx) let mut rval = UndefinedValue()); + rooted!(in(*cx) let mut rval = UndefinedValue()); unsafe { if !JS_ParseJSON( - cx, + *cx, json_text.as_ptr(), json_text.len() as u32, rval.handle_mut(), ) { - rooted!(in(cx) let mut exception = UndefinedValue()); - assert!(JS_GetPendingException(cx, exception.handle_mut())); - JS_ClearPendingException(cx); + rooted!(in(*cx) let mut exception = UndefinedValue()); + assert!(JS_GetPendingException(*cx, exception.handle_mut())); + JS_ClearPendingException(*cx); return Ok(FetchedData::JSException(RootedTraceableBox::from_box( Heap::boxed(exception.get()), ))); @@ -200,13 +200,15 @@ fn run_form_data_algorithm( } #[allow(unsafe_code)] -unsafe fn run_array_buffer_data_algorithm( - cx: *mut JSContext, - bytes: Vec<u8>, -) -> Fallible<FetchedData> { - rooted!(in(cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); - let arraybuffer = - ArrayBuffer::create(cx, CreateWith::Slice(&bytes), array_buffer_ptr.handle_mut()); +fn run_array_buffer_data_algorithm(cx: JSContext, bytes: Vec<u8>) -> Fallible<FetchedData> { + rooted!(in(*cx) let mut array_buffer_ptr = ptr::null_mut::<JSObject>()); + let arraybuffer = unsafe { + ArrayBuffer::create( + *cx, + CreateWith::Slice(&bytes), + array_buffer_ptr.handle_mut(), + ) + }; if arraybuffer.is_err() { return Err(Error::JSFailed); } diff --git a/components/script/build.rs b/components/script/build.rs index 794e2fe3283..1b8ed578387 100644 --- a/components/script/build.rs +++ b/components/script/build.rs @@ -47,7 +47,7 @@ fn main() { let mut phf = File::create(&phf).unwrap(); write!( &mut phf, - "pub static MAP: phf::Map<&'static [u8], unsafe fn(*mut JSContext, HandleObject)> = " + "pub static MAP: phf::Map<&'static [u8], unsafe fn(JSContext, HandleObject)> = " ) .unwrap(); map.build(&mut phf).unwrap(); diff --git a/components/script/compartments.rs b/components/script/compartments.rs index cb8c973e70e..c26e72ccd1a 100644 --- a/components/script/compartments.rs +++ b/components/script/compartments.rs @@ -12,7 +12,7 @@ impl AlreadyInCompartment { #![allow(unsafe_code)] pub fn assert(global: &GlobalScope) -> AlreadyInCompartment { unsafe { - assert!(!GetCurrentRealmOrNull(global.get_cx()).is_null()); + assert!(!GetCurrentRealmOrNull(*global.get_cx()).is_null()); } AlreadyInCompartment(()) } @@ -43,7 +43,7 @@ impl<'a> InCompartment<'a> { pub fn enter_realm(object: &impl DomObject) -> JSAutoRealm { JSAutoRealm::new( - object.global().get_cx(), + *object.global().get_cx(), object.reflector().get_jsobject().get(), ) } diff --git a/components/script/devtools.rs b/components/script/devtools.rs index 5a0e1c9090c..7ae02dd3e1f 100644 --- a/components/script/devtools.rs +++ b/components/script/devtools.rs @@ -36,7 +36,7 @@ pub fn handle_evaluate_js(global: &GlobalScope, eval: String, reply: IpcSender<E let result = unsafe { let cx = global.get_cx(); let _ac = enter_realm(global); - rooted!(in(cx) let mut rval = UndefinedValue()); + rooted!(in(*cx) let mut rval = UndefinedValue()); global.evaluate_js_on_global_with_result(&eval, rval.handle_mut()); if rval.is_undefined() { @@ -45,20 +45,20 @@ pub fn handle_evaluate_js(global: &GlobalScope, eval: String, reply: IpcSender<E EvaluateJSReply::BooleanValue(rval.to_boolean()) } else if rval.is_double() || rval.is_int32() { EvaluateJSReply::NumberValue( - match FromJSValConvertible::from_jsval(cx, rval.handle(), ()) { + match FromJSValConvertible::from_jsval(*cx, rval.handle(), ()) { Ok(ConversionResult::Success(v)) => v, _ => unreachable!(), }, ) } else if rval.is_string() { - EvaluateJSReply::StringValue(String::from(jsstring_to_str(cx, rval.to_string()))) + EvaluateJSReply::StringValue(String::from(jsstring_to_str(*cx, rval.to_string()))) } else if rval.is_null() { EvaluateJSReply::NullValue } else { assert!(rval.is_object()); - rooted!(in(cx) let obj = rval.to_object()); - let class_name = CStr::from_ptr(ObjectClassName(cx, obj.handle())); + rooted!(in(*cx) let obj = rval.to_object()); + let class_name = CStr::from_ptr(ObjectClassName(*cx, obj.handle())); let class_name = str::from_utf8(class_name.to_bytes()).unwrap(); EvaluateJSReply::ActorValue { diff --git a/components/script/dom/audiobuffer.rs b/components/script/dom/audiobuffer.rs index b3f18f319ad..4b113a200fe 100644 --- a/components/script/dom/audiobuffer.rs +++ b/components/script/dom/audiobuffer.rs @@ -13,6 +13,7 @@ use crate::dom::bindings::num::Finite; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::DomRoot; use crate::dom::window::Window; +use crate::script_runtime::JSContext as SafeJSContext; use dom_struct::dom_struct; use js::jsapi::JS_GetArrayBufferViewBuffer; use js::jsapi::{Heap, JSContext, JSObject}; @@ -172,15 +173,15 @@ impl AudioBuffer { // Step 2. let channel_data = unsafe { - typedarray!(in(cx) let array: Float32Array = channel.get()); + typedarray!(in(*cx) let array: Float32Array = channel.get()); if let Ok(array) = array { let data = array.to_vec(); let mut is_shared = false; - rooted!(in (cx) let view_buffer = - JS_GetArrayBufferViewBuffer(cx, channel.handle(), &mut is_shared)); + rooted!(in (*cx) let view_buffer = + JS_GetArrayBufferViewBuffer(*cx, channel.handle(), &mut is_shared)); // This buffer is always created unshared debug_assert!(!is_shared); - let _ = DetachArrayBuffer(cx, view_buffer.handle()); + let _ = DetachArrayBuffer(*cx, view_buffer.handle()); data } else { return None; @@ -230,22 +231,20 @@ impl AudioBufferMethods for AudioBuffer { // https://webaudio.github.io/web-audio-api/#dom-audiobuffer-getchanneldata #[allow(unsafe_code)] - unsafe fn GetChannelData( - &self, - cx: *mut JSContext, - channel: u32, - ) -> Fallible<NonNull<JSObject>> { + fn GetChannelData(&self, cx: SafeJSContext, channel: u32) -> Fallible<NonNull<JSObject>> { if channel >= self.number_of_channels { return Err(Error::IndexSize); } - if !self.restore_js_channel_data(cx) { - return Err(Error::JSFailed); - } + unsafe { + if !self.restore_js_channel_data(*cx) { + return Err(Error::JSFailed); + } - Ok(NonNull::new_unchecked( - self.js_channels.borrow()[channel as usize].get(), - )) + Ok(NonNull::new_unchecked( + self.js_channels.borrow()[channel as usize].get(), + )) + } } // https://webaudio.github.io/web-audio-api/#dom-audiobuffer-copyfromchannel @@ -273,7 +272,7 @@ impl AudioBufferMethods for AudioBuffer { // We either copy form js_channels or shared_channels. let js_channel = self.js_channels.borrow()[channel_number].get(); if !js_channel.is_null() { - typedarray!(in(cx) let array: Float32Array = js_channel); + typedarray!(in(*cx) let array: Float32Array = js_channel); if let Ok(array) = array { let data = unsafe { array.as_slice() }; dest.extend_from_slice(&data[offset..offset + bytes_to_copy]); @@ -308,7 +307,7 @@ impl AudioBufferMethods for AudioBuffer { } let cx = self.global().get_cx(); - if unsafe { !self.restore_js_channel_data(cx) } { + if unsafe { !self.restore_js_channel_data(*cx) } { return Err(Error::JSFailed); } @@ -318,7 +317,7 @@ impl AudioBufferMethods for AudioBuffer { return Err(Error::IndexSize); } - typedarray!(in(cx) let js_channel: Float32Array = js_channel); + typedarray!(in(*cx) let js_channel: Float32Array = js_channel); if let Ok(mut js_channel) = js_channel { let bytes_to_copy = min(self.length - start_in_channel, source.len() as u32) as usize; let js_channel_data = unsafe { js_channel.as_mut_slice() }; diff --git a/components/script/dom/bindings/callback.rs b/components/script/dom/bindings/callback.rs index fd33be86546..03b8f326f55 100644 --- a/components/script/dom/bindings/callback.rs +++ b/components/script/dom/bindings/callback.rs @@ -13,6 +13,7 @@ use crate::dom::bindings::settings_stack::{AutoEntryScript, AutoIncumbentScript} use crate::dom::bindings::utils::AsCCharPtrPtr; use crate::dom::globalscope::GlobalScope; use crate::dom::window::Window; +use crate::script_runtime::JSContext as SafeJSContext; use js::jsapi::Heap; use js::jsapi::JSAutoRealm; use js::jsapi::{AddRawValueRoot, IsCallable, JSContext, JSObject}; @@ -112,7 +113,7 @@ impl PartialEq for CallbackObject { /// callback interface types. pub trait CallbackContainer { /// Create a new CallbackContainer object for the given `JSObject`. - unsafe fn new(cx: *mut JSContext, callback: *mut JSObject) -> Rc<Self>; + unsafe fn new(cx: SafeJSContext, callback: *mut JSObject) -> Rc<Self>; /// Returns the underlying `CallbackObject`. fn callback_holder(&self) -> &CallbackObject; /// Returns the underlying `JSObject`. @@ -151,8 +152,8 @@ impl CallbackFunction { /// Initialize the callback function with a value. /// Should be called once this object is done moving. - pub unsafe fn init(&mut self, cx: *mut JSContext, callback: *mut JSObject) { - self.object.init(cx, callback); + pub unsafe fn init(&mut self, cx: SafeJSContext, callback: *mut JSObject) { + self.object.init(*cx, callback); } } @@ -178,8 +179,8 @@ impl CallbackInterface { /// Initialize the callback function with a value. /// Should be called once this object is done moving. - pub unsafe fn init(&mut self, cx: *mut JSContext, callback: *mut JSObject) { - self.object.init(cx, callback); + pub unsafe fn init(&mut self, cx: SafeJSContext, callback: *mut JSObject) { + self.object.init(*cx, callback); } /// Returns the property with the given `name`, if it is a callable object, @@ -254,8 +255,8 @@ impl CallSetup { let ais = callback.incumbent().map(AutoIncumbentScript::new); CallSetup { exception_global: global, - cx: cx, - old_realm: unsafe { EnterRealm(cx, callback.callback()) }, + cx: *cx, + old_realm: unsafe { EnterRealm(*cx, callback.callback()) }, handling: handling, entry_script: Some(aes), incumbent_script: ais, diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 159ca3652b9..9700cb68191 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -323,7 +323,7 @@ class CGMethodCall(CGThing): if requiredArgs > 0: code = ( "if argc < %d {\n" - " throw_type_error(cx, \"Not enough arguments to %s.\");\n" + " throw_type_error(*cx, \"Not enough arguments to %s.\");\n" " return false;\n" "}" % (requiredArgs, methodName)) self.cgRoot.prepend( @@ -448,7 +448,7 @@ class CGMethodCall(CGThing): # XXXbz Now we're supposed to check for distinguishingArg being # an array or a platform object that supports indexed # properties... skip that last for now. It's a bit of a pain. - pickFirstSignature("%s.get().is_object() && is_array_like(cx, %s)" % + pickFirstSignature("%s.get().is_object() && is_array_like(*cx, %s)" % (distinguishingArg, distinguishingArg), lambda s: (s[1][distinguishingIndex].type.isSequence() or @@ -457,9 +457,9 @@ class CGMethodCall(CGThing): # Check for Date objects # XXXbz Do we need to worry about security wrappers around the Date? pickFirstSignature("%s.get().is_object() && " - "{ rooted!(in(cx) let obj = %s.get().to_object()); " + "{ rooted!(in(*cx) let obj = %s.get().to_object()); " "let mut is_date = false; " - "assert!(ObjectIsDate(cx, obj.handle(), &mut is_date)); " + "assert!(ObjectIsDate(*cx, obj.handle(), &mut is_date)); " "is_date }" % (distinguishingArg, distinguishingArg), lambda s: (s[1][distinguishingIndex].type.isDate() or @@ -467,7 +467,7 @@ class CGMethodCall(CGThing): # Check for vanilla JS objects # XXXbz Do we need to worry about security wrappers? - pickFirstSignature("%s.get().is_object() && !is_platform_object(%s.get().to_object(), cx)" % + pickFirstSignature("%s.get().is_object() && !is_platform_object(%s.get().to_object(), *cx)" % (distinguishingArg, distinguishingArg), lambda s: (s[1][distinguishingIndex].type.isCallback() or s[1][distinguishingIndex].type.isCallbackInterface() or @@ -492,7 +492,7 @@ class CGMethodCall(CGThing): else: # Just throw; we have no idea what we're supposed to # do with this. - caseBody.append(CGGeneric("throw_internal_error(cx, \"Could not convert JavaScript argument\");\n" + caseBody.append(CGGeneric("throw_internal_error(*cx, \"Could not convert JavaScript argument\");\n" "return false;")) argCountCases.append(CGCase(str(argCount), @@ -505,7 +505,7 @@ class CGMethodCall(CGThing): overloadCGThings.append( CGSwitch("argcount", argCountCases, - CGGeneric("throw_type_error(cx, \"Not enough arguments to %s.\");\n" + CGGeneric("throw_type_error(*cx, \"Not enough arguments to %s.\");\n" "return false;" % methodName))) # XXXjdm Avoid unreachable statement warnings # overloadCGThings.append( @@ -638,7 +638,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, exceptionCode = "return false;\n" if failureCode is None: - failOrPropagate = "throw_type_error(cx, &error);\n%s" % exceptionCode + failOrPropagate = "throw_type_error(*cx, &error);\n%s" % exceptionCode else: failOrPropagate = failureCode @@ -657,20 +657,20 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, return CGWrapper( CGGeneric( failureCode or - ('throw_type_error(cx, "%s is not an object.");\n' + ('throw_type_error(*cx, "%s is not an object.");\n' '%s' % (firstCap(sourceDescription), exceptionCode))), post="\n") def onFailureInvalidEnumValue(failureCode, passedVarName): return CGGeneric( failureCode or - ('throw_type_error(cx, &format!("\'{}\' is not a valid enum value for enumeration \'%s\'.", %s)); %s' + ('throw_type_error(*cx, &format!("\'{}\' is not a valid enum value for enumeration \'%s\'.", %s)); %s' % (type.name, passedVarName, exceptionCode))) def onFailureNotCallable(failureCode): return CGGeneric( failureCode or - ('throw_type_error(cx, \"%s is not callable.\");\n' + ('throw_type_error(*cx, \"%s is not callable.\");\n' '%s' % (firstCap(sourceDescription), exceptionCode))) # A helper function for handling default values. @@ -723,7 +723,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, if type.nullable(): declType = CGWrapper(declType, pre="Option<", post=" >") - templateBody = ("match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n" + templateBody = ("match FromJSValConvertible::from_jsval(*cx, ${val}, %s) {\n" " Ok(ConversionResult::Success(value)) => value,\n" " Ok(ConversionResult::Failure(error)) => {\n" "%s\n" @@ -738,7 +738,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, if type.nullable(): declType = CGWrapper(declType, pre="Option<", post=" >") - templateBody = ("match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n" + templateBody = ("match FromJSValConvertible::from_jsval(*cx, ${val}, ()) {\n" " Ok(ConversionResult::Success(value)) => value,\n" " Ok(ConversionResult::Failure(error)) => {\n" "%s\n" @@ -803,17 +803,17 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, """ { // Scope for our JSAutoRealm. - rooted!(in(cx) let globalObj = CurrentGlobalOrNull(cx)); - let promiseGlobal = GlobalScope::from_object_maybe_wrapped(globalObj.handle().get(), cx); + rooted!(in(*cx) let globalObj = CurrentGlobalOrNull(*cx)); + let promiseGlobal = GlobalScope::from_object_maybe_wrapped(globalObj.handle().get(), *cx); - rooted!(in(cx) let mut valueToResolve = $${val}.get()); - if !JS_WrapValue(cx, valueToResolve.handle_mut()) { + rooted!(in(*cx) let mut valueToResolve = $${val}.get()); + if !JS_WrapValue(*cx, valueToResolve.handle_mut()) { $*{exceptionCode} } - match Promise::new_resolved(&promiseGlobal, cx, valueToResolve.handle()) { + match Promise::new_resolved(&promiseGlobal, *cx, valueToResolve.handle()) { Ok(value) => value, Err(error) => { - throw_dom_exception(cx, &promiseGlobal, error); + throw_dom_exception(*cx, &promiseGlobal, error); $*{exceptionCode} } } @@ -864,7 +864,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, "exceptionCode": exceptionCode, } unwrapFailureCode = string.Template( - 'throw_type_error(cx, "${sourceDescription} does not ' + 'throw_type_error(*cx, "${sourceDescription} does not ' 'implement interface ${interface}.");\n' '${exceptionCode}').substitute(substitutions) else: @@ -872,7 +872,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, templateBody = fill( """ - match ${function}($${val}, cx) { + match ${function}($${val}, *cx) { Ok(val) => val, Err(()) => { $*{failureCode} @@ -899,7 +899,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, "exceptionCode": exceptionCode, } unwrapFailureCode = string.Template( - 'throw_type_error(cx, "${sourceDescription} is not a typed array.");\n' + 'throw_type_error(*cx, "${sourceDescription} is not a typed array.");\n' '${exceptionCode}').substitute(substitutions) else: unwrapFailureCode = failureCode @@ -942,7 +942,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, nullBehavior = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs) conversionCode = ( - "match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n" + "match FromJSValConvertible::from_jsval(*cx, ${val}, %s) {\n" " Ok(ConversionResult::Success(strval)) => strval,\n" " Ok(ConversionResult::Failure(error)) => {\n" "%s\n" @@ -971,7 +971,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, assert not isEnforceRange and not isClamp conversionCode = ( - "match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n" + "match FromJSValConvertible::from_jsval(*cx, ${val}, ()) {\n" " Ok(ConversionResult::Success(strval)) => strval,\n" " Ok(ConversionResult::Failure(error)) => {\n" "%s\n" @@ -1000,7 +1000,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, assert not isEnforceRange and not isClamp conversionCode = ( - "match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n" + "match FromJSValConvertible::from_jsval(*cx, ${val}, ()) {\n" " Ok(ConversionResult::Success(strval)) => strval,\n" " Ok(ConversionResult::Failure(error)) => {\n" "%s\n" @@ -1038,7 +1038,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, handleInvalidEnumValueCode = "return true;" template = ( - "match find_enum_value(cx, ${val}, %(pairs)s) {\n" + "match find_enum_value(*cx, ${val}, %(pairs)s) {\n" " Err(_) => { %(exceptionCode)s },\n" " Ok((None, search)) => { %(handleInvalidEnumValueCode)s },\n" " Ok((Some(&value), _)) => value,\n" @@ -1174,7 +1174,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, if type_needs_tracing(type): declType = CGTemplatedType("RootedTraceableBox", declType) - template = ("match FromJSValConvertible::from_jsval(cx, ${val}, ()) {\n" + template = ("match FromJSValConvertible::from_jsval(*cx, ${val}, ()) {\n" " Ok(ConversionResult::Success(dictionary)) => dictionary,\n" " Ok(ConversionResult::Failure(error)) => {\n" "%s\n" @@ -1202,7 +1202,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, declType = CGWrapper(declType, pre="Option<", post=">") template = ( - "match FromJSValConvertible::from_jsval(cx, ${val}, %s) {\n" + "match FromJSValConvertible::from_jsval(*cx, ${val}, %s) {\n" " Ok(ConversionResult::Success(v)) => v,\n" " Ok(ConversionResult::Failure(error)) => {\n" "%s\n" @@ -1260,7 +1260,7 @@ def instantiateJSToNativeConversionTemplate(templateBody, replacements, result.append(conversion) if needsAutoRoot: - result.append(CGGeneric("auto_root!(in(cx) let %s = %s);" % (declName, declName))) + result.append(CGGeneric("auto_root!(in(*cx) let %s = %s);" % (declName, declName))) # Add an empty CGGeneric to get an extra newline after the argument # conversion. result.append(CGGeneric("")) @@ -1383,7 +1383,7 @@ def wrapForType(jsvalRef, result='result', successCode='return true;', pre=''): * 'successCode': the code to run once we have done the conversion. * 'pre': code to run before the conversion if rooting is necessary """ - wrap = "%s\n(%s).to_jsval(cx, %s);" % (pre, result, jsvalRef) + wrap = "%s\n(%s).to_jsval(*cx, %s);" % (pre, result, jsvalRef) if successCode: wrap += "\n%s" % successCode return wrap @@ -2410,6 +2410,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config): 'crate::dom::bindings::str::USVString', 'crate::dom::bindings::trace::RootedTraceableBox', 'crate::dom::types::*', + 'crate::script_runtime::JSContext as SafeJSContext', 'js::error::throw_type_error', 'js::rust::HandleValue', 'js::jsapi::Heap', @@ -2586,7 +2587,7 @@ class CGConstructorEnabled(CGAbstractMethod): def __init__(self, descriptor): CGAbstractMethod.__init__(self, descriptor, 'ConstructorEnabled', 'bool', - [Argument("*mut JSContext", "aCx"), + [Argument("SafeJSContext", "aCx"), Argument("HandleObject", "aObj")], unsafe=True) @@ -2618,17 +2619,17 @@ def CreateBindingJSObject(descriptor): if descriptor.proxy: create += """ let handler = RegisterBindings::PROXY_HANDLERS[PrototypeList::Proxies::%s as usize]; -rooted!(in(cx) let private = PrivateValue(raw as *const libc::c_void)); -let obj = NewProxyObject(cx, handler, +rooted!(in(*cx) let private = PrivateValue(raw as *const libc::c_void)); +let obj = NewProxyObject(*cx, handler, Handle::from_raw(UndefinedHandleValue), proto.get()); assert!(!obj.is_null()); SetProxyReservedSlot(obj, 0, &private.get()); -rooted!(in(cx) let obj = obj);\ +rooted!(in(*cx) let obj = obj);\ """ % (descriptor.name) else: - create += ("rooted!(in(cx) let obj = JS_NewObjectWithGivenProto(\n" - " cx, &Class.base as *const JSClass, proto.handle()));\n" + create += ("rooted!(in(*cx) let obj = JS_NewObjectWithGivenProto(\n" + " *cx, &Class.base as *const JSClass, proto.handle()));\n" "assert!(!obj.is_null());\n" "\n" "let val = PrivateValue(raw as *const libc::c_void);\n" @@ -2650,8 +2651,8 @@ def InitUnforgeablePropertiesOnHolder(descriptor, properties): """ unforgeables = [] - defineUnforgeableAttrs = "define_guarded_properties(cx, unforgeable_holder.handle(), %s, global);" - defineUnforgeableMethods = "define_guarded_methods(cx, unforgeable_holder.handle(), %s, global);" + defineUnforgeableAttrs = "define_guarded_properties(*cx, unforgeable_holder.handle(), %s, global);" + defineUnforgeableMethods = "define_guarded_methods(*cx, unforgeable_holder.handle(), %s, global);" unforgeableMembers = [ (defineUnforgeableAttrs, properties.unforgeable_attrs), @@ -2676,8 +2677,8 @@ def CopyUnforgeablePropertiesToInstance(descriptor): # reflector, so we can make sure we don't get confused by named getters. if descriptor.proxy: copyCode += """\ -rooted!(in(cx) let mut expando = ptr::null_mut::<JSObject>()); -ensure_expando_object(cx, obj.handle().into(), expando.handle_mut()); +rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>()); +ensure_expando_object(*cx, obj.handle().into(), expando.handle_mut()); """ obj = "expando" else: @@ -2693,9 +2694,9 @@ ensure_expando_object(cx, obj.handle().into(), expando.handle_mut()); copyCode += """\ let mut slot = UndefinedValue(); JS_GetReservedSlot(proto.get(), DOM_PROTO_UNFORGEABLE_HOLDER_SLOT, &mut slot); -rooted!(in(cx) let mut unforgeable_holder = ptr::null_mut::<JSObject>()); +rooted!(in(*cx) let mut unforgeable_holder = ptr::null_mut::<JSObject>()); unforgeable_holder.handle_mut().set(slot.to_object()); -assert!(%(copyFunc)s(cx, %(obj)s.handle(), unforgeable_holder.handle())); +assert!(%(copyFunc)s(*cx, %(obj)s.handle(), unforgeable_holder.handle())); """ % {'copyFunc': copyFunc, 'obj': obj} return copyCode @@ -2709,7 +2710,7 @@ class CGWrapMethod(CGAbstractMethod): def __init__(self, descriptor): assert not descriptor.interface.isCallback() assert not descriptor.isGlobal() - args = [Argument('*mut JSContext', 'cx'), + args = [Argument('SafeJSContext', 'cx'), Argument('&GlobalScope', 'scope'), Argument("Box<%s>" % descriptor.concreteType, 'object')] retval = 'DomRoot<%s>' % descriptor.concreteType @@ -2724,8 +2725,8 @@ let scope = scope.reflector().get_jsobject(); assert!(!scope.get().is_null()); assert!(((*get_object_class(scope.get())).flags & JSCLASS_IS_GLOBAL) != 0); -rooted!(in(cx) let mut proto = ptr::null_mut::<JSObject>()); -let _ac = JSAutoRealm::new(cx, scope.get()); +rooted!(in(*cx) let mut proto = ptr::null_mut::<JSObject>()); +let _ac = JSAutoRealm::new(*cx, scope.get()); GetProtoObject(cx, scope, proto.handle_mut()); assert!(!proto.is_null()); @@ -2744,7 +2745,7 @@ class CGWrapGlobalMethod(CGAbstractMethod): def __init__(self, descriptor, properties): assert not descriptor.interface.isCallback() assert descriptor.isGlobal() - args = [Argument('*mut JSContext', 'cx'), + args = [Argument('SafeJSContext', 'cx'), Argument("Box<%s>" % descriptor.concreteType, 'object')] retval = 'DomRoot<%s>' % descriptor.concreteType CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args, @@ -2761,7 +2762,7 @@ class CGWrapGlobalMethod(CGAbstractMethod): ("define_guarded_methods", self.properties.methods), ("define_guarded_constants", self.properties.consts) ] - members = ["%s(cx, obj.handle(), %s, obj.handle());" % (function, array.variableName()) + members = ["%s(*cx, obj.handle(), %s, obj.handle());" % (function, array.variableName()) for (function, array) in pairs if array.length() > 0] values["members"] = "\n".join(members) @@ -2769,9 +2770,9 @@ class CGWrapGlobalMethod(CGAbstractMethod): let raw = Box::into_raw(object); let _rt = RootedTraceable::new(&*raw); -rooted!(in(cx) let mut obj = ptr::null_mut::<JSObject>()); +rooted!(in(*cx) let mut obj = ptr::null_mut::<JSObject>()); create_global_object( - cx, + *cx, &Class.base, raw as *const libc::c_void, _trace, @@ -2780,12 +2781,12 @@ assert!(!obj.is_null()); (*raw).init_reflector(obj.get()); -let _ac = JSAutoRealm::new(cx, obj.get()); -rooted!(in(cx) let mut proto = ptr::null_mut::<JSObject>()); +let _ac = JSAutoRealm::new(*cx, obj.get()); +rooted!(in(*cx) let mut proto = ptr::null_mut::<JSObject>()); GetProtoObject(cx, obj.handle(), proto.handle_mut()); -assert!(JS_SplicePrototype(cx, obj.handle(), proto.handle())); +assert!(JS_SplicePrototype(*cx, obj.handle(), proto.handle())); let mut immutable = false; -assert!(JS_SetImmutablePrototype(cx, obj.handle(), &mut immutable)); +assert!(JS_SetImmutablePrototype(*cx, obj.handle(), &mut immutable)); assert!(immutable); %(members)s @@ -2931,7 +2932,7 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): properties should be a PropertyArrays instance. """ def __init__(self, descriptor, properties, haveUnscopables): - args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'global'), + args = [Argument('SafeJSContext', 'cx'), Argument('HandleObject', 'global'), Argument('*mut ProtoOrIfaceArray', 'cache')] CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'void', args, unsafe=True) @@ -2942,18 +2943,18 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod): name = self.descriptor.interface.identifier.name if self.descriptor.interface.isNamespace(): if self.descriptor.interface.getExtendedAttribute("ProtoObjectHack"): - proto = "GetRealmObjectPrototype(cx)" + proto = "GetRealmObjectPrototype(*cx)" else: - proto = "JS_NewPlainObject(cx)" + proto = "JS_NewPlainObject(*cx)" if self.properties.static_methods.length(): methods = self.properties.static_methods.variableName() else: methods = "&[]" return CGGeneric("""\ -rooted!(in(cx) let proto = %(proto)s); +rooted!(in(*cx) let proto = %(proto)s); assert!(!proto.is_null()); -rooted!(in(cx) let mut namespace = ptr::null_mut::<JSObject>()); -create_namespace_object(cx, global, proto.handle(), &NAMESPACE_OBJECT_CLASS, +rooted!(in(*cx) let mut namespace = ptr::null_mut::<JSObject>()); +create_namespace_object(*cx, global, proto.handle(), &NAMESPACE_OBJECT_CLASS, %(methods)s, %(name)s, namespace.handle_mut()); assert!(!namespace.is_null()); assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null()); @@ -2965,8 +2966,8 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null()); if self.descriptor.interface.isCallback(): assert not self.descriptor.interface.ctor() and self.descriptor.interface.hasConstants() return CGGeneric("""\ -rooted!(in(cx) let mut interface = ptr::null_mut::<JSObject>()); -create_callback_interface_object(cx, global, sConstants, %(name)s, interface.handle_mut()); +rooted!(in(*cx) let mut interface = ptr::null_mut::<JSObject>()); +create_callback_interface_object(*cx, global, sConstants, %(name)s, interface.handle_mut()); assert!(!interface.is_null()); assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null()); (*cache)[PrototypeList::Constructor::%(id)s as usize] = interface.get(); @@ -2983,13 +2984,13 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null()); protoGetter = "GetRealmIteratorPrototype" else: protoGetter = "GetRealmObjectPrototype" - getPrototypeProto = "prototype_proto.set(%s(cx))" % protoGetter + getPrototypeProto = "prototype_proto.set(%s(*cx))" % protoGetter else: getPrototypeProto = ("%s::GetProtoObject(cx, global, prototype_proto.handle_mut())" % toBindingNamespace(parentName)) code = [CGGeneric("""\ -rooted!(in(cx) let mut prototype_proto = ptr::null_mut::<JSObject>()); +rooted!(in(*cx) let mut prototype_proto = ptr::null_mut::<JSObject>()); %s; assert!(!prototype_proto.is_null());""" % getPrototypeProto)] @@ -3017,8 +3018,8 @@ assert!(!prototype_proto.is_null());""" % getPrototypeProto)] proto_properties = properties code.append(CGGeneric(""" -rooted!(in(cx) let mut prototype = ptr::null_mut::<JSObject>()); -create_interface_prototype_object(cx, +rooted!(in(*cx) let mut prototype = ptr::null_mut::<JSObject>()); +create_interface_prototype_object(*cx, global.into(), prototype_proto.handle().into(), &PrototypeClass, @@ -3042,18 +3043,18 @@ assert!((*cache)[PrototypeList::ID::%(id)s as usize].is_null()); else: properties["length"] = 0 parentName = self.descriptor.getParentName() - code.append(CGGeneric("rooted!(in(cx) let mut interface_proto = ptr::null_mut::<JSObject>());")) + code.append(CGGeneric("rooted!(in(*cx) let mut interface_proto = ptr::null_mut::<JSObject>());")) if parentName: parentName = toBindingNamespace(parentName) code.append(CGGeneric(""" %s::GetConstructorObject(cx, global, interface_proto.handle_mut());""" % parentName)) else: - code.append(CGGeneric("interface_proto.set(GetRealmFunctionPrototype(cx));")) + code.append(CGGeneric("interface_proto.set(GetRealmFunctionPrototype(*cx));")) code.append(CGGeneric("""\ assert!(!interface_proto.is_null()); -rooted!(in(cx) let mut interface = ptr::null_mut::<JSObject>()); -create_noncallback_interface_object(cx, +rooted!(in(*cx) let mut interface = ptr::null_mut::<JSObject>()); +create_noncallback_interface_object(*cx, global.into(), interface_proto.handle(), &INTERFACE_OBJECT_CLASS, @@ -3078,8 +3079,8 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null()); if aliasedMembers: def defineAlias(alias): if alias == "@@iterator": - symbolJSID = "RUST_SYMBOL_TO_JSID(GetWellKnownSymbol(cx, SymbolCode::iterator))" - getSymbolJSID = CGGeneric(fill("rooted!(in(cx) let iteratorId = ${symbolJSID});", + symbolJSID = "RUST_SYMBOL_TO_JSID(GetWellKnownSymbol(*cx, SymbolCode::iterator))" + getSymbolJSID = CGGeneric(fill("rooted!(in(*cx) let iteratorId = ${symbolJSID});", symbolJSID=symbolJSID)) defineFn = "JS_DefinePropertyById2" prop = "iteratorId.handle()" @@ -3096,7 +3097,7 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null()); # match the enumerability of the property being aliased. CGGeneric(fill( """ - assert!(${defineFn}(cx, prototype.handle(), ${prop}, aliasedVal.handle(), + assert!(${defineFn}(*cx, prototype.handle(), ${prop}, aliasedVal.handle(), JSPROP_ENUMERATE as u32)); """, defineFn=defineFn, @@ -3107,7 +3108,7 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null()); return CGList([ CGGeneric(fill( """ - assert!(JS_GetProperty(cx, prototype.handle(), + assert!(JS_GetProperty(*cx, prototype.handle(), ${prop} as *const u8 as *const _, aliasedVal.handle_mut())); """, @@ -3119,7 +3120,7 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null()); // Set up aliases on the interface prototype object we just created. """)), - CGGeneric("rooted!(in(cx) let mut aliasedVal = UndefinedValue());\n\n") + CGGeneric("rooted!(in(*cx) let mut aliasedVal = UndefinedValue());\n\n") ] + [defineAliasesFor(m) for m in sorted(aliasedMembers)]) code.append(defineAliases) @@ -3134,7 +3135,7 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null()); specs.append(CGGeneric("(%s as ConstructorClassHook, %s, %d)" % (hook, name, length))) values = CGIndenter(CGList(specs, "\n"), 4) code.append(CGWrapper(values, pre="%s = [\n" % decl, post="\n];")) - code.append(CGGeneric("create_named_constructors(cx, global, &named_constructors, prototype.handle());")) + code.append(CGGeneric("create_named_constructors(*cx, global, &named_constructors, prototype.handle());")) if self.descriptor.hasUnforgeableMembers: # We want to use the same JSClass and prototype as the object we'll @@ -3155,9 +3156,9 @@ assert!((*cache)[PrototypeList::Constructor::%(id)s as usize].is_null()); holderClass = "&Class.base as *const JSClass" holderProto = "prototype.handle()" code.append(CGGeneric(""" -rooted!(in(cx) let mut unforgeable_holder = ptr::null_mut::<JSObject>()); +rooted!(in(*cx) let mut unforgeable_holder = ptr::null_mut::<JSObject>()); unforgeable_holder.handle_mut().set( - JS_NewObjectWithoutMetadata(cx, %(holderClass)s, %(holderProto)s)); + JS_NewObjectWithoutMetadata(*cx, %(holderClass)s, %(holderProto)s)); assert!(!unforgeable_holder.is_null()); """ % {'holderClass': holderClass, 'holderProto': holderProto})) code.append(InitUnforgeablePropertiesOnHolder(self.descriptor, self.properties)) @@ -3174,7 +3175,7 @@ class CGGetPerInterfaceObject(CGAbstractMethod): constructor object). """ def __init__(self, descriptor, name, idPrefix="", pub=False): - args = [Argument('*mut JSContext', 'cx'), + args = [Argument('SafeJSContext', 'cx'), Argument('HandleObject', 'global'), Argument('MutableHandleObject', 'mut rval')] CGAbstractMethod.__init__(self, descriptor, name, @@ -3311,7 +3312,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): def __init__(self, descriptor): assert descriptor.interface.hasInterfaceObject() args = [ - Argument('*mut JSContext', 'cx'), + Argument('SafeJSContext', 'cx'), Argument('HandleObject', 'global'), ] CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', @@ -3332,7 +3333,7 @@ if !ConstructorEnabled(cx, global) { return; } -rooted!(in(cx) let mut proto = ptr::null_mut::<JSObject>()); +rooted!(in(*cx) let mut proto = ptr::null_mut::<JSObject>()); %s(cx, global, proto.handle_mut()); assert!(!proto.is_null());""" % (function,)) @@ -3376,7 +3377,7 @@ class CGCallGenerator(CGThing): if "cx" not in argsPre and needsCx: args.prepend(CGGeneric("cx")) if nativeMethodName in descriptor.inCompartmentMethods: - args.append(CGGeneric("InCompartment::in_compartment(&AlreadyInCompartment::assert_for_cx(cx))")) + args.append(CGGeneric("InCompartment::in_compartment(&AlreadyInCompartment::assert_for_cx(*cx))")) # Build up our actual call self.cgRoot = CGList([], "\n") @@ -3412,7 +3413,7 @@ class CGCallGenerator(CGThing): "let result = match result {\n" " Ok(result) => result,\n" " Err(e) => {\n" - " throw_dom_exception(cx, %s, e);\n" + " throw_dom_exception(*cx, %s, e);\n" " return%s;\n" " },\n" "};" % (glob, errorResult))) @@ -3636,7 +3637,7 @@ class CGSpecializedMethod(CGAbstractExternMethod): def __init__(self, descriptor, method): self.method = method name = method.identifier.name - args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', '_obj'), + args = [Argument('SafeJSContext', 'cx'), Argument('HandleObject', '_obj'), Argument('*const %s' % descriptor.concreteType, 'this'), Argument('*const JSJitMethodCallArgs', 'args')] CGAbstractExternMethod.__init__(self, descriptor, name, 'bool', args) @@ -3707,9 +3708,10 @@ class CGStaticMethod(CGAbstractStaticBindingMethod): def generate_code(self): nativeName = CGSpecializedMethod.makeNativeName(self.descriptor, self.method) + safeContext = CGGeneric("let cx = SafeJSContext::from_ptr(cx);\n") setupArgs = CGGeneric("let args = CallArgs::from_vp(vp, argc);\n") call = CGMethodCall(["&global"], nativeName, True, self.descriptor, self.method) - return CGList([setupArgs, call]) + return CGList([safeContext, setupArgs, call]) class CGSpecializedGetter(CGAbstractExternMethod): @@ -3720,7 +3722,7 @@ class CGSpecializedGetter(CGAbstractExternMethod): def __init__(self, descriptor, attr): self.attr = attr name = 'get_' + descriptor.internalNameFor(attr.identifier.name) - args = [Argument('*mut JSContext', 'cx'), + args = [Argument('SafeJSContext', 'cx'), Argument('HandleObject', '_obj'), Argument('*const %s' % descriptor.concreteType, 'this'), Argument('JSJitGetterCallArgs', 'args')] @@ -3761,10 +3763,11 @@ class CGStaticGetter(CGAbstractStaticBindingMethod): def generate_code(self): nativeName = CGSpecializedGetter.makeNativeName(self.descriptor, self.attr) + safeContext = CGGeneric("let cx = SafeJSContext::from_ptr(cx);\n") setupArgs = CGGeneric("let args = CallArgs::from_vp(vp, argc);\n") call = CGGetterCall(["&global"], self.attr.type, nativeName, self.descriptor, self.attr) - return CGList([setupArgs, call]) + return CGList([safeContext, setupArgs, call]) class CGSpecializedSetter(CGAbstractExternMethod): @@ -3775,7 +3778,7 @@ class CGSpecializedSetter(CGAbstractExternMethod): def __init__(self, descriptor, attr): self.attr = attr name = 'set_' + descriptor.internalNameFor(attr.identifier.name) - args = [Argument('*mut JSContext', 'cx'), + args = [Argument('SafeJSContext', 'cx'), Argument('HandleObject', 'obj'), Argument('*const %s' % descriptor.concreteType, 'this'), Argument('JSJitSetterCallArgs', 'args')] @@ -3809,15 +3812,16 @@ class CGStaticSetter(CGAbstractStaticBindingMethod): def generate_code(self): nativeName = CGSpecializedSetter.makeNativeName(self.descriptor, self.attr) + safeContext = CGGeneric("let cx = SafeJSContext::from_ptr(cx);\n") checkForArg = CGGeneric( "let args = CallArgs::from_vp(vp, argc);\n" "if argc == 0 {\n" - " throw_type_error(cx, \"Not enough arguments to %s setter.\");\n" + " throw_type_error(*cx, \"Not enough arguments to %s setter.\");\n" " return false;\n" "}" % self.attr.identifier.name) call = CGSetterCall(["&global"], self.attr.type, nativeName, self.descriptor, self.attr) - return CGList([checkForArg, call]) + return CGList([safeContext, checkForArg, call]) class CGSpecializedForwardingSetter(CGSpecializedSetter): @@ -3834,16 +3838,16 @@ class CGSpecializedForwardingSetter(CGSpecializedSetter): assert all(ord(c) < 128 for c in attrName) assert all(ord(c) < 128 for c in forwardToAttrName) return CGGeneric("""\ -rooted!(in(cx) let mut v = UndefinedValue()); -if !JS_GetProperty(cx, obj, %s as *const u8 as *const libc::c_char, v.handle_mut()) { +rooted!(in(*cx) let mut v = UndefinedValue()); +if !JS_GetProperty(*cx, obj, %s as *const u8 as *const libc::c_char, v.handle_mut()) { return false; } if !v.is_object() { - throw_type_error(cx, "Value.%s is not an object."); + throw_type_error(*cx, "Value.%s is not an object."); return false; } -rooted!(in(cx) let target_obj = v.to_object()); -JS_SetProperty(cx, target_obj.handle(), %s as *const u8 as *const libc::c_char, HandleValue::from_raw(args.get(0))) +rooted!(in(*cx) let target_obj = v.to_object()); +JS_SetProperty(*cx, target_obj.handle(), %s as *const u8 as *const libc::c_char, HandleValue::from_raw(args.get(0))) """ % (str_to_const_array(attrName), attrName, str_to_const_array(forwardToAttrName))) @@ -3860,7 +3864,7 @@ class CGSpecializedReplaceableSetter(CGSpecializedSetter): # JS_DefineProperty can only deal with ASCII. assert all(ord(c) < 128 for c in name) return CGGeneric("""\ -JS_DefineProperty(cx, obj, %s as *const u8 as *const libc::c_char, +JS_DefineProperty(*cx, obj, %s as *const u8 as *const libc::c_char, HandleValue::from_raw(args.get(0)), JSPROP_ENUMERATE as u32)""" % name) @@ -4449,7 +4453,7 @@ class CGUnionConversionStruct(CGThing): def get_match(name): return ( - "match %s::TryConvertTo%s(cx, value) {\n" + "match %s::TryConvertTo%s(SafeJSContext::from_ptr(cx), value) {\n" " Err(_) => return Err(()),\n" " Ok(Some(value)) => return Ok(ConversionResult::Success(%s::%s(value))),\n" " Ok(None) => (),\n" @@ -4589,7 +4593,7 @@ class CGUnionConversionStruct(CGThing): return CGWrapper( CGIndenter(jsConversion, 4), - pre="unsafe fn TryConvertTo%s(cx: *mut JSContext, value: HandleValue) -> %s {\n" + pre="unsafe fn TryConvertTo%s(cx: SafeJSContext, value: HandleValue) -> %s {\n" % (t.name, returnType), post="\n}") @@ -4982,7 +4986,7 @@ class CGProxySpecialOperation(CGPerSignatureCall): } self.cgRoot.prepend(instantiateJSToNativeConversionTemplate( template, templateValues, declType, argument.identifier.name)) - self.cgRoot.prepend(CGGeneric("rooted!(in(cx) let value = desc.value);")) + self.cgRoot.prepend(CGGeneric("rooted!(in(*cx) let value = desc.value);")) def getArguments(self): args = [(a, process_arg(a.identifier.name, a)) for a in self.arguments] @@ -5025,7 +5029,7 @@ class CGProxyNamedOperation(CGProxySpecialOperation): def define(self): # Our first argument is the id we're getting. argName = self.arguments[0].identifier.name - return ("let %s = jsid_to_string(cx, Handle::from_raw(id)).expect(\"Not a string-convertible JSID?\");\n" + return ("let %s = jsid_to_string(*cx, Handle::from_raw(id)).expect(\"Not a string-convertible JSID?\");\n" "let this = UnwrapProxy(proxy);\n" "let this = &*this;\n" % argName + CGProxySpecialOperation.define(self)) @@ -5094,9 +5098,9 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): def getBody(self): indexedGetter = self.descriptor.operations['IndexedGetter'] - get = "" + get = "let cx = SafeJSContext::from_ptr(cx);\n" if indexedGetter: - get = "let index = get_array_index_from_id(cx, Handle::from_raw(id));\n" + get += "let index = get_array_index_from_id(*cx, Handle::from_raw(id));\n" attrs = "JSPROP_ENUMERATE" if self.descriptor.operations['IndexedSetter'] is None: @@ -5108,7 +5112,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): templateValues = { 'jsvalRef': 'result_root.handle_mut()', 'successCode': fillDescriptor, - 'pre': 'rooted!(in(cx) let mut result_root = UndefinedValue());' + 'pre': 'rooted!(in(*cx) let mut result_root = UndefinedValue());' } get += ("if let Some(index) = index {\n" + " let this = UnwrapProxy(proxy);\n" + @@ -5134,7 +5138,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): templateValues = { 'jsvalRef': 'result_root.handle_mut()', 'successCode': fillDescriptor, - 'pre': 'rooted!(in(cx) let mut result_root = UndefinedValue());' + 'pre': 'rooted!(in(*cx) let mut result_root = UndefinedValue());' } # See the similar-looking in CGDOMJSProxyHandler_get for the spec quote. @@ -5147,7 +5151,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod): namedGet = """ if %s { let mut has_on_proto = false; - if !has_property_on_prototype(cx, proxy_lt, id_lt, &mut has_on_proto) { + if !has_property_on_prototype(*cx, proxy_lt, id_lt, &mut has_on_proto) { return false; } if !has_on_proto { @@ -5159,13 +5163,13 @@ if %s { namedGet = "" return get + """\ -rooted!(in(cx) let mut expando = ptr::null_mut::<JSObject>()); +rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>()); get_expando_object(proxy, expando.handle_mut()); //if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) { let proxy_lt = Handle::from_raw(proxy); let id_lt = Handle::from_raw(id); if !expando.is_null() { - if !JS_GetPropertyDescriptorById(cx, expando.handle().into(), id, desc) { + if !JS_GetPropertyDescriptorById(*cx, expando.handle().into(), id, desc) { return false; } if !desc.obj.is_null() { @@ -5192,11 +5196,11 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): self.descriptor = descriptor def getBody(self): - set = "" + set = "let cx = SafeJSContext::from_ptr(cx);\n" indexedSetter = self.descriptor.operations['IndexedSetter'] if indexedSetter: - set += ("let index = get_array_index_from_id(cx, Handle::from_raw(id));\n" + + set += ("let index = get_array_index_from_id(*cx, Handle::from_raw(id));\n" + "if let Some(index) = index {\n" + " let this = UnwrapProxy(proxy);\n" + " let this = &*this;\n" + @@ -5204,7 +5208,7 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): " return (*opresult).succeed();\n" + "}\n") elif self.descriptor.operations['IndexedGetter']: - set += ("if get_array_index_from_id(cx, Handle::from_raw(id)).is_some() {\n" + + set += ("if get_array_index_from_id(*cx, Handle::from_raw(id)).is_some() {\n" + " return (*opresult).failNoIndexedSetter();\n" + "}\n") @@ -5224,7 +5228,7 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod): " return (*opresult).failNoNamedSetter();\n" " }\n" "}\n") - set += "return proxyhandler::define_property(%s);" % ", ".join(a.name for a in self.args) + set += "return proxyhandler::define_property(*cx, %s);" % ", ".join(a.name for a in self.args[1:]) return set def definition_body(self): @@ -5240,13 +5244,13 @@ class CGDOMJSProxyHandler_delete(CGAbstractExternMethod): self.descriptor = descriptor def getBody(self): - set = "" + set = "let cx = SafeJSContext::from_ptr(cx);\n" if self.descriptor.operations['NamedDeleter']: if self.descriptor.hasUnforgeableMembers: raise TypeError("Can't handle a deleter on an interface that has " "unforgeables. Figure out how that should work!") set += CGProxyNamedDeleter(self.descriptor).define() - set += "return proxyhandler::delete(%s);" % ", ".join(a.name for a in self.args) + set += "return proxyhandler::delete(*cx, %s);" % ", ".join(a.name for a in self.args[1:]) return set def definition_body(self): @@ -5264,6 +5268,7 @@ class CGDOMJSProxyHandler_ownPropertyKeys(CGAbstractExternMethod): def getBody(self): body = dedent( """ + let cx = SafeJSContext::from_ptr(cx); let unwrapped_proxy = UnwrapProxy(proxy); """) @@ -5271,7 +5276,7 @@ class CGDOMJSProxyHandler_ownPropertyKeys(CGAbstractExternMethod): body += dedent( """ for i in 0..(*unwrapped_proxy).Length() { - rooted!(in(cx) let rooted_jsid = int_to_jsid(i as i32)); + rooted!(in(*cx) let rooted_jsid = int_to_jsid(i as i32)); AppendToAutoIdVector(props, rooted_jsid.handle().get()); } """) @@ -5281,20 +5286,20 @@ class CGDOMJSProxyHandler_ownPropertyKeys(CGAbstractExternMethod): """ for name in (*unwrapped_proxy).SupportedPropertyNames() { let cstring = CString::new(name).unwrap(); - let jsstring = JS_AtomizeAndPinString(cx, cstring.as_ptr()); - rooted!(in(cx) let rooted = jsstring); - let jsid = INTERNED_STRING_TO_JSID(cx, rooted.handle().get()); - rooted!(in(cx) let rooted_jsid = jsid); + let jsstring = JS_AtomizeAndPinString(*cx, cstring.as_ptr()); + rooted!(in(*cx) let rooted = jsstring); + let jsid = INTERNED_STRING_TO_JSID(*cx, rooted.handle().get()); + rooted!(in(*cx) let rooted_jsid = jsid); AppendToAutoIdVector(props, rooted_jsid.handle().get()); } """) body += dedent( """ - rooted!(in(cx) let mut expando = ptr::null_mut::<JSObject>()); + rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>()); get_expando_object(proxy, expando.handle_mut()); if !expando.is_null() { - GetPropertyKeys(cx, expando.handle(), JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props); + GetPropertyKeys(*cx, expando.handle(), JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props); } return true; @@ -5320,6 +5325,7 @@ class CGDOMJSProxyHandler_getOwnEnumerablePropertyKeys(CGAbstractExternMethod): def getBody(self): body = dedent( """ + let cx = SafeJSContext::from_ptr(cx); let unwrapped_proxy = UnwrapProxy(proxy); """) @@ -5327,17 +5333,17 @@ class CGDOMJSProxyHandler_getOwnEnumerablePropertyKeys(CGAbstractExternMethod): body += dedent( """ for i in 0..(*unwrapped_proxy).Length() { - rooted!(in(cx) let rooted_jsid = int_to_jsid(i as i32)); + rooted!(in(*cx) let rooted_jsid = int_to_jsid(i as i32)); AppendToAutoIdVector(props, rooted_jsid.handle().get()); } """) body += dedent( """ - rooted!(in(cx) let mut expando = ptr::null_mut::<JSObject>()); + rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>()); get_expando_object(proxy, expando.handle_mut()); if !expando.is_null() { - GetPropertyKeys(cx, expando.handle(), JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props); + GetPropertyKeys(*cx, expando.handle(), JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, props); } return true; @@ -5358,17 +5364,16 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod): def getBody(self): indexedGetter = self.descriptor.operations['IndexedGetter'] + indexed = "let cx = SafeJSContext::from_ptr(cx);\n" if indexedGetter: - indexed = ("let index = get_array_index_from_id(cx, Handle::from_raw(id));\n" + - "if let Some(index) = index {\n" + - " let this = UnwrapProxy(proxy);\n" + - " let this = &*this;\n" + - CGIndenter(CGProxyIndexedGetter(self.descriptor)).define() + "\n" + - " *bp = result.is_some();\n" + - " return true;\n" + - "}\n\n") - else: - indexed = "" + indexed += ("let index = get_array_index_from_id(*cx, Handle::from_raw(id));\n" + + "if let Some(index) = index {\n" + + " let this = UnwrapProxy(proxy);\n" + + " let this = &*this;\n" + + CGIndenter(CGProxyIndexedGetter(self.descriptor)).define() + "\n" + + " *bp = result.is_some();\n" + + " return true;\n" + + "}\n\n") namedGetter = self.descriptor.operations['NamedGetter'] condition = "RUST_JSID_IS_STRING(id) || RUST_JSID_IS_INT(id)" @@ -5378,7 +5383,7 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod): named = """\ if %s { let mut has_on_proto = false; - if !has_property_on_prototype(cx, proxy_lt, id_lt, &mut has_on_proto) { + if !has_property_on_prototype(*cx, proxy_lt, id_lt, &mut has_on_proto) { return false; } if !has_on_proto { @@ -5393,12 +5398,12 @@ if %s { named = "" return indexed + """\ -rooted!(in(cx) let mut expando = ptr::null_mut::<JSObject>()); +rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>()); let proxy_lt = Handle::from_raw(proxy); let id_lt = Handle::from_raw(id); get_expando_object(proxy, expando.handle_mut()); if !expando.is_null() { - let ok = JS_HasPropertyById(cx, expando.handle().into(), id, bp); + let ok = JS_HasPropertyById(*cx, expando.handle().into(), id, bp); if !ok || *bp { return ok; } @@ -5422,16 +5427,16 @@ class CGDOMJSProxyHandler_get(CGAbstractExternMethod): # https://heycam.github.io/webidl/#LegacyPlatformObjectGetOwnProperty def getBody(self): getFromExpando = """\ -rooted!(in(cx) let mut expando = ptr::null_mut::<JSObject>()); +rooted!(in(*cx) let mut expando = ptr::null_mut::<JSObject>()); get_expando_object(proxy, expando.handle_mut()); if !expando.is_null() { let mut hasProp = false; - if !JS_HasPropertyById(cx, expando.handle().into(), id, &mut hasProp) { + if !JS_HasPropertyById(*cx, expando.handle().into(), id, &mut hasProp) { return false; } if hasProp { - return JS_ForwardGetPropertyTo(cx, expando.handle().into(), id, receiver, vp); + return JS_ForwardGetPropertyTo(*cx, expando.handle().into(), id, receiver, vp); } }""" @@ -5442,7 +5447,7 @@ if !expando.is_null() { indexedGetter = self.descriptor.operations['IndexedGetter'] if indexedGetter: - getIndexedOrExpando = ("let index = get_array_index_from_id(cx, id_lt);\n" + + getIndexedOrExpando = ("let index = get_array_index_from_id(*cx, id_lt);\n" + "if let Some(index) = index {\n" + " let this = UnwrapProxy(proxy);\n" + " let this = &*this;\n" + @@ -5475,6 +5480,7 @@ if !expando.is_null() { return """\ //MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy), //"Should not have a XrayWrapper here"); +let cx = SafeJSContext::from_ptr(cx); let proxy_lt = Handle::from_raw(proxy); let vp_lt = MutableHandle::from_raw(vp); let id_lt = Handle::from_raw(id); @@ -5482,7 +5488,7 @@ let receiver_lt = Handle::from_raw(receiver); %s let mut found = false; -if !get_property_on_prototype(cx, proxy_lt, receiver_lt, id_lt, &mut found, vp_lt) { +if !get_property_on_prototype(*cx, proxy_lt, receiver_lt, id_lt, &mut found, vp_lt) { return false; } @@ -5605,7 +5611,9 @@ class CGClassConstructHook(CGAbstractExternMethod): self.exposureSet = descriptor.interface.exposureSet def definition_body(self): - preamble = """let global = GlobalScope::from_object(JS_CALLEE(cx, vp).to_object());\n""" + preamble = """let cx = SafeJSContext::from_ptr(cx); +let global = GlobalScope::from_object(JS_CALLEE(*cx, vp).to_object()); +""" if len(self.exposureSet) == 1: preamble += """\ let global = DomRoot::downcast::<dom::types::%s>(global).unwrap(); @@ -5621,24 +5629,24 @@ let global = DomRoot::downcast::<dom::types::%s>(global).unwrap(); // The new_target might be a cross-compartment wrapper. Get the underlying object // so we can do the spec's object-identity checks. -rooted!(in(cx) let new_target = UnwrapObjectDynamic(args.new_target().to_object(), cx, 1)); +rooted!(in(*cx) let new_target = UnwrapObjectDynamic(args.new_target().to_object(), *cx, 1)); if new_target.is_null() { - throw_dom_exception(cx, global.upcast::<GlobalScope>(), Error::Type("new.target is null".to_owned())); + throw_dom_exception(*cx, global.upcast::<GlobalScope>(), Error::Type("new.target is null".to_owned())); return false; } if args.callee() == new_target.get() { - throw_dom_exception(cx, global.upcast::<GlobalScope>(), + throw_dom_exception(*cx, global.upcast::<GlobalScope>(), Error::Type("new.target must not be the active function object".to_owned())); return false; } // Step 6 -rooted!(in(cx) let mut prototype = ptr::null_mut::<JSObject>()); +rooted!(in(*cx) let mut prototype = ptr::null_mut::<JSObject>()); { - rooted!(in(cx) let mut proto_val = UndefinedValue()); - let _ac = JSAutoRealm::new(cx, new_target.get()); - if !JS_GetProperty(cx, new_target.handle(), b"prototype\\0".as_ptr() as *const _, proto_val.handle_mut()) { + rooted!(in(*cx) let mut proto_val = UndefinedValue()); + let _ac = JSAutoRealm::new(*cx, new_target.get()); + if !JS_GetProperty(*cx, new_target.handle(), b"prototype\\0".as_ptr() as *const _, proto_val.handle_mut()) { return false; } @@ -5652,7 +5660,7 @@ rooted!(in(cx) let mut prototype = ptr::null_mut::<JSObject>()); // whose target is not same-compartment with the proxy, or bound functions, etc). // https://bugzilla.mozilla.org/show_bug.cgi?id=1317658 - rooted!(in(cx) let global_object = CurrentGlobalOrNull(cx)); + rooted!(in(*cx) let global_object = CurrentGlobalOrNull(*cx)); GetProtoObject(cx, global_object.handle(), prototype.handle_mut()); } else { // Step 6 @@ -5661,7 +5669,7 @@ rooted!(in(cx) let mut prototype = ptr::null_mut::<JSObject>()); } // Wrap prototype in this context since it is from the newTarget compartment -if !JS_WrapObject(cx, prototype.handle_mut()) { +if !JS_WrapObject(*cx, prototype.handle_mut()) { return false; } @@ -5669,19 +5677,19 @@ let result: Result<DomRoot<%s>, Error> = html_constructor(&global, &args); let result = match result { Ok(result) => result, Err(e) => { - throw_dom_exception(cx, global.upcast::<GlobalScope>(), e); + throw_dom_exception(*cx, global.upcast::<GlobalScope>(), e); return false; }, }; -rooted!(in(cx) let mut element = result.reflector().get_jsobject().get()); -if !JS_WrapObject(cx, element.handle_mut()) { +rooted!(in(*cx) let mut element = result.reflector().get_jsobject().get()); +if !JS_WrapObject(*cx, element.handle_mut()) { return false; } -JS_SetPrototype(cx, element.handle(), prototype.handle()); +JS_SetPrototype(*cx, element.handle(), prototype.handle()); -(result).to_jsval(cx, MutableHandleValue::from_raw(args.rval())); +(result).to_jsval(*cx, MutableHandleValue::from_raw(args.rval())); return true; """ % self.descriptor.name) else: @@ -5720,7 +5728,7 @@ class CGInterfaceTrait(CGThing): def attribute_arguments(needCx, argument=None, inCompartment=False): if needCx: - yield "cx", "*mut JSContext" + yield "cx", "SafeJSContext" if argument: yield "value", argument_type(descriptor, argument) @@ -6088,6 +6096,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries 'crate::mem::malloc_size_of_including_raw_self', 'crate::compartments::InCompartment', 'crate::compartments::AlreadyInCompartment', + 'crate::script_runtime::JSContext as SafeJSContext', 'libc', 'servo_config::pref', 'servo_config::prefs', @@ -6103,6 +6112,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries 'std::rc::Rc', 'std::default::Default', 'std::ffi::CString', + 'std::ops::Deref', ], config) @@ -6380,7 +6390,7 @@ class CGDictionary(CGThing): " match r#try!(%s::%s::new(cx, val)) {\n" " ConversionResult::Success(v) => v,\n" " ConversionResult::Failure(error) => {\n" - " throw_type_error(cx, &error);\n" + " throw_type_error(*cx, &error);\n" " return Err(());\n" " }\n" " }\n" @@ -6434,7 +6444,7 @@ class CGDictionary(CGThing): return string.Template( "impl ${selfName} {\n" "${empty}\n" - " pub unsafe fn new(cx: *mut JSContext, val: HandleValue) \n" + " pub unsafe fn new(cx: SafeJSContext, val: HandleValue) \n" " -> Result<ConversionResult<${actualType}>, ()> {\n" " let object = if val.get().is_null_or_undefined() {\n" " ptr::null_mut()\n" @@ -6443,7 +6453,7 @@ class CGDictionary(CGThing): " } else {\n" " return Ok(ConversionResult::Failure(\"Value is not an object.\".into()));\n" " };\n" - " rooted!(in(cx) let object = object);\n" + " rooted!(in(*cx) let object = object);\n" "${preInitial}" "${initParent}" "${initMembers}" @@ -6456,7 +6466,7 @@ class CGDictionary(CGThing): " type Config = ();\n" " unsafe fn from_jsval(cx: *mut JSContext, value: HandleValue, _option: ())\n" " -> Result<ConversionResult<${actualType}>, ()> {\n" - " ${selfName}::new(cx, value)\n" + " ${selfName}::new(SafeJSContext::from_ptr(cx), value)\n" " }\n" "}\n" "\n" @@ -6514,7 +6524,7 @@ class CGDictionary(CGThing): assert (member.defaultValue is None) == (default is None) if not member.optional: assert default is None - default = ("throw_type_error(cx, \"Missing required member \\\"%s\\\".\");\n" + default = ("throw_type_error(*cx, \"Missing required member \\\"%s\\\".\");\n" "return Err(());") % member.identifier.name elif not default: default = "None" @@ -6522,8 +6532,8 @@ class CGDictionary(CGThing): conversion = ( "{\n" - " rooted!(in(cx) let mut rval = UndefinedValue());\n" - " if r#try!(get_dictionary_property(cx, object.handle(), \"%s\", rval.handle_mut()))" + " rooted!(in(*cx) let mut rval = UndefinedValue());\n" + " if r#try!(get_dictionary_property(*cx, object.handle(), \"%s\", rval.handle_mut()))" " && !rval.is_undefined() {\n" "%s\n" " } else {\n" @@ -6802,7 +6812,7 @@ def argument_type(descriptorProvider, ty, optional=False, defaultValue=None, var def method_arguments(descriptorProvider, returnType, arguments, passJSBits=True, trailing=None, inCompartment=False): if needCx(returnType, arguments, passJSBits): - yield "cx", "*mut JSContext" + yield "cx", "SafeJSContext" for argument in arguments: ty = argument_type(descriptorProvider, argument.type, argument.optional, @@ -6885,7 +6895,7 @@ class CGCallback(CGClass): def getConstructors(self): return [ClassConstructor( - [Argument("*mut JSContext", "aCx"), Argument("*mut JSObject", "aCallback")], + [Argument("SafeJSContext", "aCx"), Argument("*mut JSObject", "aCallback")], bodyInHeader=True, visibility="pub", explicit=False, @@ -6898,14 +6908,14 @@ class CGCallback(CGClass): args = list(method.args) # Strip out the JSContext*/JSObject* args # that got added. - assert args[0].name == "cx" and args[0].argType == "*mut JSContext" + assert args[0].name == "cx" and args[0].argType == "SafeJSContext" assert args[1].name == "aThisObj" and args[1].argType == "HandleObject" args = args[2:] # Record the names of all the arguments, so we can use them when we call # the private method. argnames = [arg.name for arg in args] - argnamesWithThis = ["s.get_context()", "thisObjJS.handle()"] + argnames - argnamesWithoutThis = ["s.get_context()", "thisObjJS.handle()"] + argnames + argnamesWithThis = ["SafeJSContext::from_ptr(s.get_context())", "thisObjJS.handle()"] + argnames + argnamesWithoutThis = ["SafeJSContext::from_ptr(s.get_context())", "thisObjJS.handle()"] + argnames # Now that we've recorded the argnames for our call to our private # method, insert our optional argument for deciding whether the # CallSetup should re-throw exceptions on aRv. @@ -6981,7 +6991,7 @@ class CGCallbackFunctionImpl(CGGeneric): def __init__(self, callback): impl = string.Template("""\ impl CallbackContainer for ${type} { - unsafe fn new(cx: *mut JSContext, callback: *mut JSObject) -> Rc<${type}> { + unsafe fn new(cx: SafeJSContext, callback: *mut JSObject) -> Rc<${type}> { ${type}::new(cx, callback) } @@ -7156,7 +7166,7 @@ class CallbackMember(CGNativeMember): "*arg = Heap::default();\n" + "arg.set(argv_root.get());\n" + "}") % jsvalIndex, - pre="rooted!(in(cx) let mut argv_root = UndefinedValue());") + pre="rooted!(in(*cx) let mut argv_root = UndefinedValue());") if arg.variadic: conversion = string.Template( "for idx in 0..${arg}.len() {\n" + @@ -7185,7 +7195,7 @@ class CallbackMember(CGNativeMember): return args # We want to allow the caller to pass in a "this" object, as # well as a JSContext. - return [Argument("*mut JSContext", "cx"), + return [Argument("SafeJSContext", "cx"), Argument("HandleObject", "aThisObj")] + args def getCallSetup(self): @@ -7226,7 +7236,7 @@ class CallbackMethod(CallbackMember): needThisHandling) def getRvalDecl(self): - return "rooted!(in(cx) let mut rval = UndefinedValue());\n" + return "rooted!(in(*cx) let mut rval = UndefinedValue());\n" def getCall(self): replacements = { @@ -7242,9 +7252,9 @@ class CallbackMethod(CallbackMember): replacements["argc"] = "0" return string.Template( "${getCallable}" - "rooted!(in(cx) let rootedThis = ${thisObj});\n" + "rooted!(in(*cx) let rootedThis = ${thisObj});\n" "let ok = ${callGuard}JS_CallFunctionValue(\n" - " cx, rootedThis.handle(), callable.handle(),\n" + " *cx, rootedThis.handle(), callable.handle(),\n" " &HandleValueArray {\n" " length_: ${argc} as ::libc::size_t,\n" " elements_: ${argv}\n" @@ -7265,7 +7275,7 @@ class CallCallback(CallbackMethod): return "aThisObj.get()" def getCallableDecl(self): - return "rooted!(in(cx) let callable = ObjectValue(self.callback()));\n" + return "rooted!(in(*cx) let callable = ObjectValue(self.callback()));\n" def getCallGuard(self): if self.callback._treatNonObjectAsNull: @@ -7295,13 +7305,13 @@ class CallbackOperationBase(CallbackMethod): "methodName": self.methodName } getCallableFromProp = string.Template( - 'r#try!(self.parent.get_callable_property(cx, "${methodName}"))' + 'r#try!(self.parent.get_callable_property(*cx, "${methodName}"))' ).substitute(replacements) if not self.singleOperation: - return 'rooted!(in(cx) let callable =\n' + getCallableFromProp + ');\n' + return 'rooted!(in(*cx) let callable =\n' + getCallableFromProp + ');\n' return ( 'let isCallable = IsCallable(self.callback());\n' - 'rooted!(in(cx) let callable =\n' + + 'rooted!(in(*cx) let callable =\n' + CGIndenter( CGIfElseWrapper('isCallable', CGGeneric('ObjectValue(self.callback())'), @@ -7336,21 +7346,21 @@ class CGIterableMethodGenerator(CGGeneric): CGGeneric.__init__(self, fill( """ if !IsCallable(arg0) { - throw_type_error(cx, "Argument 1 of ${ifaceName}.forEach is not callable."); + throw_type_error(*cx, "Argument 1 of ${ifaceName}.forEach is not callable."); return false; } - rooted!(in(cx) let arg0 = ObjectValue(arg0)); - rooted!(in(cx) let mut call_arg1 = UndefinedValue()); - rooted!(in(cx) let mut call_arg2 = UndefinedValue()); + rooted!(in(*cx) let arg0 = ObjectValue(arg0)); + rooted!(in(*cx) let mut call_arg1 = UndefinedValue()); + rooted!(in(*cx) let mut call_arg2 = UndefinedValue()); let mut call_args = vec![UndefinedValue(), UndefinedValue(), ObjectValue(*_obj)]; - rooted!(in(cx) let mut ignoredReturnVal = UndefinedValue()); + rooted!(in(*cx) let mut ignoredReturnVal = UndefinedValue()); for i in 0..(*this).get_iterable_length() { - (*this).get_value_at_index(i).to_jsval(cx, call_arg1.handle_mut()); - (*this).get_key_at_index(i).to_jsval(cx, call_arg2.handle_mut()); + (*this).get_value_at_index(i).to_jsval(*cx, call_arg1.handle_mut()); + (*this).get_key_at_index(i).to_jsval(*cx, call_arg2.handle_mut()); call_args[0] = call_arg1.handle().get(); call_args[1] = call_arg2.handle().get(); let call_args = HandleValueArray { length_: 3, elements_: call_args.as_ptr() }; - if !Call(cx, arg1, arg0.handle(), &call_args, + if !Call(*cx, arg1, arg0.handle(), &call_args, ignoredReturnVal.handle_mut()) { return false; } @@ -7402,7 +7412,7 @@ class GlobalGenRoots(): def InterfaceObjectMap(config): mods = [ "crate::dom::bindings::codegen", - "js::jsapi::JSContext", + "crate::script_runtime::JSContext", "js::rust::HandleObject", "phf", ] diff --git a/components/script/dom/bindings/htmlconstructor.rs b/components/script/dom/bindings/htmlconstructor.rs index 7e122ef6e29..6faa4f6211c 100644 --- a/components/script/dom/bindings/htmlconstructor.rs +++ b/components/script/dom/bindings/htmlconstructor.rs @@ -76,6 +76,7 @@ use crate::dom::customelementregistry::{ConstructionStackEntry, CustomElementSta use crate::dom::element::{Element, ElementCreator}; use crate::dom::htmlelement::HTMLElement; use crate::dom::window::Window; +use crate::script_runtime::JSContext as SafeJSContext; use crate::script_thread::ScriptThread; use html5ever::interface::QualName; use html5ever::LocalName; @@ -99,7 +100,7 @@ where // Step 2 is checked in the generated caller code // Step 3 - rooted!(in(window.get_cx()) let new_target = call_args.new_target().to_object()); + rooted!(in(*window.get_cx()) let new_target = call_args.new_target().to_object()); let definition = match registry.lookup_definition_by_constructor(new_target.handle()) { Some(definition) => definition, None => { @@ -109,15 +110,15 @@ where }, }; - rooted!(in(window.get_cx()) let callee = UnwrapObjectStatic(call_args.callee())); + rooted!(in(*window.get_cx()) let callee = UnwrapObjectStatic(call_args.callee())); if callee.is_null() { return Err(Error::Security); } { - let _ac = JSAutoRealm::new(window.get_cx(), callee.get()); - rooted!(in(window.get_cx()) let mut constructor = ptr::null_mut::<JSObject>()); - rooted!(in(window.get_cx()) let global_object = CurrentGlobalOrNull(window.get_cx())); + let _ac = JSAutoRealm::new(*window.get_cx(), callee.get()); + rooted!(in(*window.get_cx()) let mut constructor = ptr::null_mut::<JSObject>()); + rooted!(in(*window.get_cx()) let global_object = CurrentGlobalOrNull(*window.get_cx())); if definition.is_autonomous() { // Step 4 @@ -133,7 +134,7 @@ where // Step 5 get_constructor_object_from_local_name( definition.local_name.clone(), - window.get_cx(), + *window.get_cx(), global_object.handle(), constructor.handle_mut(), ); @@ -201,7 +202,7 @@ pub fn get_constructor_object_from_local_name( ) -> bool { macro_rules! get_constructor( ($binding:ident) => ({ - unsafe { $binding::GetConstructorObject(cx, global, rval); } + unsafe { $binding::GetConstructorObject(SafeJSContext::from_ptr(cx), global, rval); } true }) ); diff --git a/components/script/dom/bindings/iterable.rs b/components/script/dom/bindings/iterable.rs index 4e4963399c6..5ee790cf2d3 100644 --- a/components/script/dom/bindings/iterable.rs +++ b/components/script/dom/bindings/iterable.rs @@ -13,6 +13,7 @@ use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::trace::{JSTraceable, RootedTraceableBox}; use crate::dom::globalscope::GlobalScope; +use crate::script_runtime::JSContext as SafeJSContext; use dom_struct::dom_struct; use js::conversions::ToJSValConvertible; use js::jsapi::{Heap, JSContext, JSObject}; @@ -62,7 +63,7 @@ impl<T: DomObject + JSTraceable + Iterable> IterableIterator<T> { pub fn new( iterable: &T, type_: IteratorType, - wrap: unsafe fn(*mut JSContext, &GlobalScope, Box<IterableIterator<T>>) -> DomRoot<Self>, + wrap: unsafe fn(SafeJSContext, &GlobalScope, Box<IterableIterator<T>>) -> DomRoot<Self>, ) -> DomRoot<Self> { let iterator = Box::new(IterableIterator { reflector: Reflector::new(), @@ -75,41 +76,41 @@ impl<T: DomObject + JSTraceable + Iterable> IterableIterator<T> { /// Return the next value from the iterable object. #[allow(non_snake_case)] - pub fn Next(&self, cx: *mut JSContext) -> Fallible<NonNull<JSObject>> { + pub fn Next(&self, cx: SafeJSContext) -> Fallible<NonNull<JSObject>> { let index = self.index.get(); - rooted!(in(cx) let mut value = UndefinedValue()); - rooted!(in(cx) let mut rval = ptr::null_mut::<JSObject>()); + rooted!(in(*cx) let mut value = UndefinedValue()); + rooted!(in(*cx) let mut rval = ptr::null_mut::<JSObject>()); let result = if index >= self.iterable.get_iterable_length() { - dict_return(cx, rval.handle_mut(), true, value.handle()) + dict_return(*cx, rval.handle_mut(), true, value.handle()) } else { match self.type_ { IteratorType::Keys => { unsafe { self.iterable .get_key_at_index(index) - .to_jsval(cx, value.handle_mut()); + .to_jsval(*cx, value.handle_mut()); } - dict_return(cx, rval.handle_mut(), false, value.handle()) + dict_return(*cx, rval.handle_mut(), false, value.handle()) }, IteratorType::Values => { unsafe { self.iterable .get_value_at_index(index) - .to_jsval(cx, value.handle_mut()); + .to_jsval(*cx, value.handle_mut()); } - dict_return(cx, rval.handle_mut(), false, value.handle()) + dict_return(*cx, rval.handle_mut(), false, value.handle()) }, IteratorType::Entries => { - rooted!(in(cx) let mut key = UndefinedValue()); + rooted!(in(*cx) let mut key = UndefinedValue()); unsafe { self.iterable .get_key_at_index(index) - .to_jsval(cx, key.handle_mut()); + .to_jsval(*cx, key.handle_mut()); self.iterable .get_value_at_index(index) - .to_jsval(cx, value.handle_mut()); + .to_jsval(*cx, value.handle_mut()); } - key_and_value_return(cx, rval.handle_mut(), key.handle(), value.handle()) + key_and_value_return(*cx, rval.handle_mut(), key.handle(), value.handle()) }, } }; diff --git a/components/script/dom/bindings/reflector.rs b/components/script/dom/bindings/reflector.rs index 057dc8d3d9d..dc13fca77b0 100644 --- a/components/script/dom/bindings/reflector.rs +++ b/components/script/dom/bindings/reflector.rs @@ -7,7 +7,8 @@ use crate::dom::bindings::conversions::DerivedFrom; use crate::dom::bindings::root::DomRoot; use crate::dom::globalscope::GlobalScope; -use js::jsapi::{Heap, JSContext, JSObject}; +use crate::script_runtime::JSContext; +use js::jsapi::{Heap, JSObject}; use js::rust::HandleObject; use std::default::Default; @@ -16,7 +17,7 @@ use std::default::Default; pub fn reflect_dom_object<T, U>( obj: Box<T>, global: &U, - wrap_fn: unsafe fn(*mut JSContext, &GlobalScope, Box<T>) -> DomRoot<T>, + wrap_fn: unsafe fn(JSContext, &GlobalScope, Box<T>) -> DomRoot<T>, ) -> DomRoot<T> where T: DomObject, diff --git a/components/script/dom/bindings/structuredclone.rs b/components/script/dom/bindings/structuredclone.rs index 167b375dbc7..f35a4af7210 100644 --- a/components/script/dom/bindings/structuredclone.rs +++ b/components/script/dom/bindings/structuredclone.rs @@ -321,7 +321,7 @@ impl StructuredCloneData { WriteBytesToJSStructuredCloneData(data as *const u8, nbytes, scdata); assert!(JS_ReadStructuredClone( - cx, + *cx, scdata, JS_STRUCTURED_CLONE_VERSION, StructuredCloneScope::DifferentProcess, diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 54ff2a35eab..7146e1533b7 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -13,6 +13,7 @@ use crate::dom::bindings::inheritance::TopTypeId; use crate::dom::bindings::str::DOMString; use crate::dom::bindings::trace::trace_object; use crate::dom::windowproxy; +use crate::script_runtime::JSContext as SafeJSContext; use js::glue::{CallJitGetterOp, CallJitMethodOp, CallJitSetterOp, IsWrapper}; use js::glue::{GetCrossCompartmentWrapper, JS_GetReservedSlot, WrapperNew}; use js::glue::{UnwrapObjectDynamic, RUST_JSID_TO_INT, RUST_JSID_TO_STRING}; @@ -353,7 +354,7 @@ pub unsafe extern "C" fn enumerate_global( return false; } for init_fun in InterfaceObjectMap::MAP.values() { - init_fun(cx, Handle::from_raw(obj)); + init_fun(SafeJSContext::from_ptr(cx), Handle::from_raw(obj)); } true } @@ -388,7 +389,7 @@ pub unsafe extern "C" fn resolve_global( let bytes = slice::from_raw_parts(ptr, length as usize); if let Some(init_fun) = InterfaceObjectMap::MAP.get(bytes) { - init_fun(cx, Handle::from_raw(obj)); + init_fun(SafeJSContext::from_ptr(cx), Handle::from_raw(obj)); *rval = true; } else { *rval = false; diff --git a/components/script/dom/bluetooth.rs b/components/script/dom/bluetooth.rs index 7484e476416..4a5a9af9c43 100644 --- a/components/script/dom/bluetooth.rs +++ b/components/script/dom/bluetooth.rs @@ -30,6 +30,7 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::permissions::{get_descriptor_permission_state, PermissionAlgorithm}; use crate::dom::promise::Promise; +use crate::script_runtime::JSContext as SafeJSContext; use crate::task::TaskOnce; use dom_struct::dom_struct; use ipc_channel::ipc::{self, IpcSender}; @@ -625,7 +626,8 @@ impl PermissionAlgorithm for Bluetooth { .handle_mut() .set(ObjectValue(permission_descriptor_obj)); unsafe { - match BluetoothPermissionDescriptor::new(cx, property.handle()) { + match BluetoothPermissionDescriptor::new(SafeJSContext::from_ptr(cx), property.handle()) + { Ok(ConversionResult::Success(descriptor)) => Ok(descriptor), Ok(ConversionResult::Failure(error)) => Err(Error::Type(error.into_owned())), Err(_) => Err(Error::Type(String::from(BT_DESC_CONVERSION_ERROR))), diff --git a/components/script/dom/create.rs b/components/script/dom/create.rs index 5ca05d2f713..18c9504a245 100644 --- a/components/script/dom/create.rs +++ b/components/script/dom/create.rs @@ -157,9 +157,9 @@ fn create_html_element( // Step 6.1.1 unsafe { let _ac = - JSAutoRealm::new(cx, global.reflector().get_jsobject().get()); - throw_dom_exception(cx, &global, error); - report_pending_exception(cx, true); + JSAutoRealm::new(*cx, global.reflector().get_jsobject().get()); + throw_dom_exception(*cx, &global, error); + report_pending_exception(*cx, true); } // Step 6.1.2 diff --git a/components/script/dom/crypto.rs b/components/script/dom/crypto.rs index 76adb3a08b1..4891c022ed5 100644 --- a/components/script/dom/crypto.rs +++ b/components/script/dom/crypto.rs @@ -9,9 +9,10 @@ use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::DomRoot; use crate::dom::globalscope::GlobalScope; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; +use js::jsapi::JSObject; use js::jsapi::Type; -use js::jsapi::{JSContext, JSObject}; use js::rust::CustomAutoRooterGuard; use js::typedarray::ArrayBufferView; use servo_rand::{Rng, ServoRng}; @@ -47,9 +48,9 @@ impl Crypto { impl CryptoMethods for Crypto { #[allow(unsafe_code)] // https://dvcs.w3.org/hg/webcrypto-api/raw-file/tip/spec/Overview.html#Crypto-method-getRandomValues - unsafe fn GetRandomValues( + fn GetRandomValues( &self, - _cx: *mut JSContext, + _cx: JSContext, mut input: CustomAutoRooterGuard<ArrayBufferView>, ) -> Fallible<NonNull<JSObject>> { let array_type = input.get_array_type(); @@ -57,14 +58,14 @@ impl CryptoMethods for Crypto { if !is_integer_buffer(array_type) { return Err(Error::TypeMismatch); } else { - let mut data = input.as_mut_slice(); + let mut data = unsafe { input.as_mut_slice() }; if data.len() > 65536 { return Err(Error::QuotaExceeded); } self.rng.borrow_mut().fill_bytes(&mut data); } - Ok(NonNull::new_unchecked(*input.underlying_object())) + unsafe { Ok(NonNull::new_unchecked(*input.underlying_object())) } } } diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs index 913397cf780..2603768ed83 100644 --- a/components/script/dom/customelementregistry.rs +++ b/components/script/dom/customelementregistry.rs @@ -31,6 +31,7 @@ use crate::dom::node::{document_from_node, window_from_node, Node, ShadowIncludi use crate::dom::promise::Promise; use crate::dom::window::Window; use crate::microtask::Microtask; +use crate::script_runtime::JSContext as SafeJSContext; use crate::script_thread::ScriptThread; use dom_struct::dom_struct; use html5ever::{LocalName, Namespace, Prefix}; @@ -144,7 +145,7 @@ impl CustomElementRegistry { unsafe { // Step 10.1 if !JS_GetProperty( - global_scope.get_cx(), + *global_scope.get_cx(), constructor, b"prototype\0".as_ptr() as *const _, prototype, @@ -170,10 +171,14 @@ impl CustomElementRegistry { // Step 4 Ok(LifecycleCallbacks { - connected_callback: get_callback(cx, prototype, b"connectedCallback\0")?, - disconnected_callback: get_callback(cx, prototype, b"disconnectedCallback\0")?, - adopted_callback: get_callback(cx, prototype, b"adoptedCallback\0")?, - attribute_changed_callback: get_callback(cx, prototype, b"attributeChangedCallback\0")?, + connected_callback: get_callback(*cx, prototype, b"connectedCallback\0")?, + disconnected_callback: get_callback(*cx, prototype, b"disconnectedCallback\0")?, + adopted_callback: get_callback(*cx, prototype, b"adoptedCallback\0")?, + attribute_changed_callback: get_callback( + *cx, + prototype, + b"attributeChangedCallback\0", + )?, }) } @@ -182,10 +187,10 @@ impl CustomElementRegistry { #[allow(unsafe_code)] fn get_observed_attributes(&self, constructor: HandleObject) -> Fallible<Vec<DOMString>> { let cx = self.window.get_cx(); - rooted!(in(cx) let mut observed_attributes = UndefinedValue()); + rooted!(in(*cx) let mut observed_attributes = UndefinedValue()); if unsafe { !JS_GetProperty( - cx, + *cx, constructor, b"observedAttributes\0".as_ptr() as *const _, observed_attributes.handle_mut(), @@ -200,7 +205,7 @@ impl CustomElementRegistry { let conversion = unsafe { FromJSValConvertible::from_jsval( - cx, + *cx, observed_attributes.handle(), StringificationBehavior::Default, ) @@ -238,7 +243,10 @@ unsafe fn get_callback( if !callback.is_object() || !IsCallable(callback.to_object()) { return Err(Error::Type("Lifecycle callback is not callable".to_owned())); } - Ok(Some(Function::new(cx, callback.to_object()))) + Ok(Some(Function::new( + SafeJSContext::from_ptr(cx), + callback.to_object(), + ))) } else { Ok(None) } @@ -254,12 +262,12 @@ impl CustomElementRegistryMethods for CustomElementRegistry { options: &ElementDefinitionOptions, ) -> ErrorResult { let cx = self.window.get_cx(); - rooted!(in(cx) let constructor = constructor_.callback()); + rooted!(in(*cx) let constructor = constructor_.callback()); let name = LocalName::from(&*name); // Step 1 // We must unwrap the constructor as all wrappers are constructable if they are callable. - rooted!(in(cx) let unwrapped_constructor = unsafe { UnwrapObjectStatic(constructor.get()) }); + rooted!(in(*cx) let unwrapped_constructor = unsafe { UnwrapObjectStatic(constructor.get()) }); if unwrapped_constructor.is_null() { // We do not have permission to access the unwrapped constructor. @@ -322,9 +330,9 @@ impl CustomElementRegistryMethods for CustomElementRegistry { self.element_definition_is_running.set(true); // Steps 10.1 - 10.2 - rooted!(in(cx) let mut prototype = UndefinedValue()); + rooted!(in(*cx) let mut prototype = UndefinedValue()); { - let _ac = JSAutoRealm::new(cx, constructor.get()); + let _ac = JSAutoRealm::new(*cx, constructor.get()); if let Err(error) = self.check_prototype(constructor.handle(), prototype.handle_mut()) { self.element_definition_is_running.set(false); return Err(error); @@ -332,9 +340,9 @@ impl CustomElementRegistryMethods for CustomElementRegistry { }; // Steps 10.3 - 10.4 - rooted!(in(cx) let proto_object = prototype.to_object()); + rooted!(in(*cx) let proto_object = prototype.to_object()); let callbacks = { - let _ac = JSAutoRealm::new(cx, proto_object.get()); + let _ac = JSAutoRealm::new(*cx, proto_object.get()); match unsafe { self.get_callbacks(proto_object.handle()) } { Ok(callbacks) => callbacks, Err(error) => { @@ -346,7 +354,7 @@ impl CustomElementRegistryMethods for CustomElementRegistry { // Step 10.5 - 10.6 let observed_attributes = if callbacks.attribute_changed_callback.is_some() { - let _ac = JSAutoRealm::new(cx, constructor.get()); + let _ac = JSAutoRealm::new(*cx, constructor.get()); match self.get_observed_attributes(constructor.handle()) { Ok(attributes) => attributes, Err(error) => { @@ -401,13 +409,13 @@ impl CustomElementRegistryMethods for CustomElementRegistry { /// <https://html.spec.whatwg.org/multipage/#dom-customelementregistry-get> #[allow(unsafe_code)] - unsafe fn Get(&self, cx: *mut JSContext, name: DOMString) -> JSVal { + fn Get(&self, cx: SafeJSContext, name: DOMString) -> JSVal { match self.definitions.borrow().get(&LocalName::from(&*name)) { - Some(definition) => { - rooted!(in(cx) let mut constructor = UndefinedValue()); + Some(definition) => unsafe { + rooted!(in(*cx) let mut constructor = UndefinedValue()); definition .constructor - .to_jsval(cx, constructor.handle_mut()); + .to_jsval(*cx, constructor.handle_mut()); constructor.get() }, None => UndefinedValue(), @@ -519,20 +527,20 @@ impl CustomElementDefinition { let window = document.window(); let cx = window.get_cx(); // Step 2 - rooted!(in(cx) let constructor = ObjectValue(self.constructor.callback())); - rooted!(in(cx) let mut element = ptr::null_mut::<JSObject>()); + rooted!(in(*cx) let constructor = ObjectValue(self.constructor.callback())); + rooted!(in(*cx) let mut element = ptr::null_mut::<JSObject>()); { // Go into the constructor's compartment - let _ac = JSAutoRealm::new(cx, self.constructor.callback()); + let _ac = JSAutoRealm::new(*cx, self.constructor.callback()); let args = HandleValueArray::new(); - if unsafe { !Construct1(cx, constructor.handle(), &args, element.handle_mut()) } { + if unsafe { !Construct1(*cx, constructor.handle(), &args, element.handle_mut()) } { return Err(Error::JSFailed); } } - rooted!(in(cx) let element_val = ObjectValue(element.get())); + rooted!(in(*cx) let element_val = ObjectValue(element.get())); let element: DomRoot<Element> = - match unsafe { DomRoot::from_jsval(cx, element_val.handle(), ()) } { + match unsafe { DomRoot::from_jsval(*cx, element_val.handle(), ()) } { Ok(ConversionResult::Success(element)) => element, Ok(ConversionResult::Failure(..)) => { return Err(Error::Type( @@ -623,8 +631,8 @@ pub fn upgrade_element(definition: Rc<CustomElementDefinition>, element: &Elemen let global = GlobalScope::current().expect("No current global"); let cx = global.get_cx(); unsafe { - throw_dom_exception(cx, &global, error); - report_pending_exception(cx, true); + throw_dom_exception(*cx, &global, error); + report_pending_exception(*cx, true); } return; } @@ -645,20 +653,20 @@ fn run_upgrade_constructor( ) -> ErrorResult { let window = window_from_node(element); let cx = window.get_cx(); - rooted!(in(cx) let constructor_val = ObjectValue(constructor.callback())); - rooted!(in(cx) let mut element_val = UndefinedValue()); + rooted!(in(*cx) let constructor_val = ObjectValue(constructor.callback())); + rooted!(in(*cx) let mut element_val = UndefinedValue()); unsafe { - element.to_jsval(cx, element_val.handle_mut()); + element.to_jsval(*cx, element_val.handle_mut()); } - rooted!(in(cx) let mut construct_result = ptr::null_mut::<JSObject>()); + rooted!(in(*cx) let mut construct_result = ptr::null_mut::<JSObject>()); { // Go into the constructor's compartment - let _ac = JSAutoRealm::new(cx, constructor.callback()); + let _ac = JSAutoRealm::new(*cx, constructor.callback()); let args = HandleValueArray::new(); // Step 7.1 if unsafe { !Construct1( - cx, + *cx, constructor_val.handle(), &args, construct_result.handle_mut(), @@ -668,10 +676,10 @@ fn run_upgrade_constructor( } // Step 7.2 let mut same = false; - rooted!(in(cx) let construct_result_val = ObjectValue(construct_result.get())); + rooted!(in(*cx) let construct_result_val = ObjectValue(construct_result.get())); if unsafe { !SameValue( - cx, + *cx, construct_result_val.handle(), element_val.handle(), &mut same, @@ -859,30 +867,30 @@ impl CustomElementReactionStack { let cx = element.global().get_cx(); let local_name = DOMString::from(&*local_name); - rooted!(in(cx) let mut name_value = UndefinedValue()); + rooted!(in(*cx) let mut name_value = UndefinedValue()); unsafe { - local_name.to_jsval(cx, name_value.handle_mut()); + local_name.to_jsval(*cx, name_value.handle_mut()); } - rooted!(in(cx) let mut old_value = NullValue()); + rooted!(in(*cx) let mut old_value = NullValue()); if let Some(old_val) = old_val { unsafe { - old_val.to_jsval(cx, old_value.handle_mut()); + old_val.to_jsval(*cx, old_value.handle_mut()); } } - rooted!(in(cx) let mut value = NullValue()); + rooted!(in(*cx) let mut value = NullValue()); if let Some(val) = val { unsafe { - val.to_jsval(cx, value.handle_mut()); + val.to_jsval(*cx, value.handle_mut()); } } - rooted!(in(cx) let mut namespace_value = NullValue()); + rooted!(in(*cx) let mut namespace_value = NullValue()); if namespace != ns!() { let namespace = DOMString::from(&*namespace); unsafe { - namespace.to_jsval(cx, namespace_value.handle_mut()); + namespace.to_jsval(*cx, namespace_value.handle_mut()); } } diff --git a/components/script/dom/customevent.rs b/components/script/dom/customevent.rs index de07a55d4d4..91035f56e03 100644 --- a/components/script/dom/customevent.rs +++ b/components/script/dom/customevent.rs @@ -13,8 +13,9 @@ use crate::dom::bindings::str::DOMString; use crate::dom::bindings::trace::RootedTraceableBox; use crate::dom::event::Event; use crate::dom::globalscope::GlobalScope; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSContext}; +use js::jsapi::Heap; use js::jsval::JSVal; use js::rust::HandleValue; use servo_atoms::Atom; @@ -87,17 +88,15 @@ impl CustomEvent { } impl CustomEventMethods for CustomEvent { - #[allow(unsafe_code)] // https://dom.spec.whatwg.org/#dom-customevent-detail - unsafe fn Detail(&self, _cx: *mut JSContext) -> JSVal { + fn Detail(&self, _cx: JSContext) -> JSVal { self.detail.get() } - #[allow(unsafe_code)] // https://dom.spec.whatwg.org/#dom-customevent-initcustomevent - unsafe fn InitCustomEvent( + fn InitCustomEvent( &self, - _cx: *mut JSContext, + _cx: JSContext, type_: DOMString, can_bubble: bool, cancelable: bool, diff --git a/components/script/dom/dedicatedworkerglobalscope.rs b/components/script/dom/dedicatedworkerglobalscope.rs index 6a64b4fb544..a3adde75498 100644 --- a/components/script/dom/dedicatedworkerglobalscope.rs +++ b/components/script/dom/dedicatedworkerglobalscope.rs @@ -26,7 +26,9 @@ use crate::dom::worker::{TrustedWorkerAddress, Worker}; use crate::dom::workerglobalscope::WorkerGlobalScope; use crate::fetch::load_whole_resource; use crate::script_runtime::ScriptThreadEventCategory::WorkerEvent; -use crate::script_runtime::{new_child_runtime, CommonScriptMsg, Runtime, ScriptChan, ScriptPort}; +use crate::script_runtime::{ + new_child_runtime, CommonScriptMsg, JSContext as SafeJSContext, Runtime, ScriptChan, ScriptPort, +}; use crate::task_queue::{QueuedTask, QueuedTaskConversion, TaskQueue}; use crate::task_source::TaskSourceName; use crossbeam_channel::{unbounded, Receiver, Sender}; @@ -283,7 +285,7 @@ impl DedicatedWorkerGlobalScope { closing, image_cache, )); - unsafe { DedicatedWorkerGlobalScopeBinding::Wrap(cx, scope) } + unsafe { DedicatedWorkerGlobalScopeBinding::Wrap(SafeJSContext::from_ptr(cx), scope) } } #[allow(unsafe_code)] @@ -403,7 +405,7 @@ impl DedicatedWorkerGlobalScope { unsafe { // Handle interrupt requests - JS_AddInterruptCallback(scope.get_cx(), Some(interrupt_callback)); + JS_AddInterruptCallback(*scope.get_cx(), Some(interrupt_callback)); } if scope.is_closing() { @@ -464,7 +466,7 @@ impl DedicatedWorkerGlobalScope { let scope = self.upcast::<WorkerGlobalScope>(); let target = self.upcast(); let _ac = enter_realm(self); - rooted!(in(scope.get_cx()) let mut message = UndefinedValue()); + rooted!(in(*scope.get_cx()) let mut message = UndefinedValue()); data.read(scope.upcast(), message.handle_mut()); MessageEvent::dispatch_jsval(target, scope.upcast(), message.handle(), None, None); }, @@ -558,10 +560,9 @@ unsafe extern "C" fn interrupt_callback(cx: *mut JSContext) -> bool { } impl DedicatedWorkerGlobalScopeMethods for DedicatedWorkerGlobalScope { - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-dedicatedworkerglobalscope-postmessage - unsafe fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult { - let data = StructuredCloneData::write(cx, message)?; + fn PostMessage(&self, cx: SafeJSContext, message: HandleValue) -> ErrorResult { + let data = StructuredCloneData::write(*cx, message)?; let worker = self.worker.borrow().as_ref().unwrap().clone(); let pipeline_id = self.upcast::<GlobalScope>().pipeline_id(); let task = Box::new(task!(post_worker_message: move || { diff --git a/components/script/dom/dissimilaroriginwindow.rs b/components/script/dom/dissimilaroriginwindow.rs index 54523bb59ea..8f7eda58100 100644 --- a/components/script/dom/dissimilaroriginwindow.rs +++ b/components/script/dom/dissimilaroriginwindow.rs @@ -11,9 +11,9 @@ use crate::dom::bindings::structuredclone::StructuredCloneData; use crate::dom::dissimilaroriginlocation::DissimilarOriginLocation; use crate::dom::globalscope::GlobalScope; use crate::dom::windowproxy::WindowProxy; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; use ipc_channel::ipc; -use js::jsapi::JSContext; use js::jsval::{JSVal, UndefinedValue}; use js::rust::HandleValue; use msg::constellation_msg::PipelineId; @@ -133,14 +133,8 @@ impl DissimilarOriginWindowMethods for DissimilarOriginWindow { false } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-window-postmessage - unsafe fn PostMessage( - &self, - cx: *mut JSContext, - message: HandleValue, - origin: DOMString, - ) -> ErrorResult { + fn PostMessage(&self, cx: JSContext, message: HandleValue, origin: DOMString) -> ErrorResult { // Step 3-5. let origin = match &origin[..] { "*" => None, @@ -156,23 +150,21 @@ impl DissimilarOriginWindowMethods for DissimilarOriginWindow { // Step 1-2, 6-8. // TODO(#12717): Should implement the `transfer` argument. - let data = StructuredCloneData::write(cx, message)?; + let data = StructuredCloneData::write(*cx, message)?; // Step 9. self.post_message(origin, data); Ok(()) } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-opener - unsafe fn Opener(&self, _: *mut JSContext) -> JSVal { + fn Opener(&self, _: JSContext) -> JSVal { // TODO: Implement x-origin opener UndefinedValue() } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-opener - unsafe fn SetOpener(&self, _: *mut JSContext, _: HandleValue) { + fn SetOpener(&self, _: JSContext, _: HandleValue) { // TODO: Implement x-origin opener } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index d7e77ef9243..85639964710 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -102,6 +102,7 @@ use crate::dom::wheelevent::WheelEvent; use crate::dom::window::{ReflowReason, Window}; use crate::dom::windowproxy::WindowProxy; use crate::fetch::FetchCanceller; +use crate::script_runtime::JSContext; use crate::script_runtime::{CommonScriptMsg, ScriptThreadEventCategory}; use crate::script_thread::{MainThreadScriptMsg, ScriptThread}; use crate::stylesheet_set::StylesheetSetRef; @@ -117,7 +118,7 @@ use euclid::default::Point2D; use html5ever::{LocalName, Namespace, QualName}; use hyper_serde::Serde; use ipc_channel::ipc::{self, IpcSender}; -use js::jsapi::{JSContext, JSObject, JSRuntime}; +use js::jsapi::{JSObject, JSRuntime}; use keyboard_types::{Key, KeyState, Modifiers}; use metrics::{ InteractiveFlag, InteractiveMetrics, InteractiveWindow, ProfilerMetadataFactory, @@ -4218,11 +4219,7 @@ impl DocumentMethods for Document { #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-tree-accessors:dom-document-nameditem-filter - unsafe fn NamedGetter( - &self, - _cx: *mut JSContext, - name: DOMString, - ) -> Option<NonNull<JSObject>> { + fn NamedGetter(&self, _cx: JSContext, name: DOMString) -> Option<NonNull<JSObject>> { #[derive(JSTraceable, MallocSizeOf)] struct NamedElementFilter { name: Atom, @@ -4270,7 +4267,7 @@ impl DocumentMethods for Document { } let name = Atom::from(name); let root = self.upcast::<Node>(); - { + unsafe { // Step 1. let mut elements = root .traverse_preorder(ShadowIncluding::No) @@ -4291,9 +4288,11 @@ impl DocumentMethods for Document { // Step 4. let filter = NamedElementFilter { name: name }; let collection = HTMLCollection::create(self.window(), root, Box::new(filter)); - Some(NonNull::new_unchecked( - collection.reflector().get_jsobject().get(), - )) + unsafe { + Some(NonNull::new_unchecked( + collection.reflector().get_jsobject().get(), + )) + } } // https://html.spec.whatwg.org/multipage/#dom-tree-accessors:supported-property-names diff --git a/components/script/dom/documentorshadowroot.rs b/components/script/dom/documentorshadowroot.rs index 9b57dd32bf6..594801584c8 100644 --- a/components/script/dom/documentorshadowroot.rs +++ b/components/script/dom/documentorshadowroot.rs @@ -131,7 +131,7 @@ impl DocumentOrShadowRoot { .first() { Some(address) => { - let js_runtime = unsafe { JS_GetRuntime(self.window.get_cx()) }; + let js_runtime = unsafe { JS_GetRuntime(*self.window.get_cx()) }; let node = unsafe { node::from_untrusted_node_address(js_runtime, *address) }; let parent_node = node.GetParentNode().unwrap(); let element_ref = node @@ -167,7 +167,7 @@ impl DocumentOrShadowRoot { return vec![]; } - let js_runtime = unsafe { JS_GetRuntime(self.window.get_cx()) }; + let js_runtime = unsafe { JS_GetRuntime(*self.window.get_cx()) }; // Step 1 and Step 3 let nodes = self.nodes_from_point(point, NodesFromPointQueryType::All); diff --git a/components/script/dom/dommatrixreadonly.rs b/components/script/dom/dommatrixreadonly.rs index cde3dbc4031..f8d73f628c1 100644 --- a/components/script/dom/dommatrixreadonly.rs +++ b/components/script/dom/dommatrixreadonly.rs @@ -18,10 +18,11 @@ use crate::dom::dommatrix::DOMMatrix; use crate::dom::dompoint::DOMPoint; use crate::dom::globalscope::GlobalScope; use crate::dom::window::Window; +use crate::script_runtime::JSContext; use cssparser::{Parser, ParserInput}; use dom_struct::dom_struct; use euclid::{default::Transform3D, Angle}; -use js::jsapi::{JSContext, JSObject}; +use js::jsapi::JSObject; use js::rust::CustomAutoRooterGuard; use js::typedarray::CreateWith; use js::typedarray::{Float32Array, Float64Array}; @@ -667,7 +668,7 @@ impl DOMMatrixReadOnlyMethods for DOMMatrixReadOnly { // https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-tofloat32array #[allow(unsafe_code)] - unsafe fn ToFloat32Array(&self, cx: *mut JSContext) -> NonNull<JSObject> { + fn ToFloat32Array(&self, cx: JSContext) -> NonNull<JSObject> { let vec: Vec<f32> = self .matrix .borrow() @@ -675,18 +676,22 @@ impl DOMMatrixReadOnlyMethods for DOMMatrixReadOnly { .iter() .map(|&x| x as f32) .collect(); - rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>()); - let _ = Float32Array::create(cx, CreateWith::Slice(&vec), array.handle_mut()).unwrap(); - NonNull::new_unchecked(array.get()) + unsafe { + rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); + let _ = Float32Array::create(*cx, CreateWith::Slice(&vec), array.handle_mut()).unwrap(); + NonNull::new_unchecked(array.get()) + } } // https://drafts.fxtf.org/geometry-1/#dom-dommatrixreadonly-tofloat64array #[allow(unsafe_code)] - unsafe fn ToFloat64Array(&self, cx: *mut JSContext) -> NonNull<JSObject> { + fn ToFloat64Array(&self, cx: JSContext) -> NonNull<JSObject> { let arr = self.matrix.borrow().to_row_major_array(); - rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>()); - let _ = Float64Array::create(cx, CreateWith::Slice(&arr), array.handle_mut()).unwrap(); - NonNull::new_unchecked(array.get()) + unsafe { + rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); + let _ = Float64Array::create(*cx, CreateWith::Slice(&arr), array.handle_mut()).unwrap(); + NonNull::new_unchecked(array.get()) + } } } diff --git a/components/script/dom/errorevent.rs b/components/script/dom/errorevent.rs index 2894482161c..c306f6cf7f9 100644 --- a/components/script/dom/errorevent.rs +++ b/components/script/dom/errorevent.rs @@ -14,8 +14,9 @@ use crate::dom::bindings::str::DOMString; use crate::dom::bindings::trace::RootedTraceableBox; use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::globalscope::GlobalScope; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSContext}; +use js::jsapi::Heap; use js::jsval::JSVal; use js::rust::HandleValue; use servo_atoms::Atom; @@ -135,9 +136,8 @@ impl ErrorEventMethods for ErrorEvent { self.filename.borrow().clone() } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-errorevent-error - unsafe fn Error(&self, _cx: *mut JSContext) -> JSVal { + fn Error(&self, _cx: JSContext) -> JSVal { self.error.get() } diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs index 64c88496a46..02283a3c190 100644 --- a/components/script/dom/eventsource.rs +++ b/components/script/dom/eventsource.rs @@ -223,10 +223,10 @@ impl EventSourceContext { // Steps 4-5 let event = { let _ac = enter_realm(&*event_source); - rooted!(in(event_source.global().get_cx()) let mut data = UndefinedValue()); + rooted!(in(*event_source.global().get_cx()) let mut data = UndefinedValue()); unsafe { self.data - .to_jsval(event_source.global().get_cx(), data.handle_mut()) + .to_jsval(*event_source.global().get_cx(), data.handle_mut()) }; MessageEvent::new( &*event_source.global(), diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs index 02cd36bdd69..12cf7d0253b 100644 --- a/components/script/dom/eventtarget.rs +++ b/components/script/dom/eventtarget.rs @@ -150,7 +150,6 @@ pub enum CompiledEventListener { } impl CompiledEventListener { - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#the-event-handler-processing-algorithm pub fn call_or_handle_event<T: DomObject>( &self, @@ -168,7 +167,7 @@ impl CompiledEventListener { CommonEventHandler::ErrorEventHandler(ref handler) => { if let Some(event) = event.downcast::<ErrorEvent>() { let cx = object.global().get_cx(); - rooted!(in(cx) let error = unsafe { event.Error(cx) }); + rooted!(in(*cx) let error = event.Error(cx)); let return_value = handler.Call_( object, EventOrString::String(event.Message()), @@ -180,7 +179,7 @@ impl CompiledEventListener { ); // Step 4 if let Ok(return_value) = return_value { - rooted!(in(cx) let return_value = return_value); + rooted!(in(*cx) let return_value = return_value); if return_value.handle().is_boolean() && return_value.handle().to_boolean() == true { @@ -225,7 +224,7 @@ impl CompiledEventListener { CommonEventHandler::EventHandler(ref handler) => { if let Ok(value) = handler.Call_(object, event, exception_handle) { let cx = object.global().get_cx(); - rooted!(in(cx) let value = value); + rooted!(in(*cx) let value = value); let value = value.handle(); //Step 4 @@ -502,16 +501,16 @@ impl EventTarget { }; let cx = window.get_cx(); - let options = CompileOptionsWrapper::new(cx, url_serialized.as_ptr(), handler.line as u32); + let options = CompileOptionsWrapper::new(*cx, url_serialized.as_ptr(), handler.line as u32); // TODO step 1.10.1-3 (document, form owner, element in scope chain) - let scopechain = AutoObjectVectorWrapper::new(cx); + let scopechain = AutoObjectVectorWrapper::new(*cx); let _ac = enter_realm(&*window); - rooted!(in(cx) let mut handler = ptr::null_mut::<JSFunction>()); + rooted!(in(*cx) let mut handler = ptr::null_mut::<JSFunction>()); let rv = unsafe { CompileFunction( - cx, + *cx, scopechain.ptr, options.ptr, name.as_ptr(), @@ -529,9 +528,9 @@ impl EventTarget { if !rv || handler.get().is_null() { // Step 1.8.2 unsafe { - let _ac = JSAutoRealm::new(cx, self.reflector().get_jsobject().get()); + let _ac = JSAutoRealm::new(*cx, self.reflector().get_jsobject().get()); // FIXME(#13152): dispatch error event. - report_pending_exception(cx, false); + report_pending_exception(*cx, false); } // Step 1.8.1 / 1.8.3 return None; diff --git a/components/script/dom/extendableevent.rs b/components/script/dom/extendableevent.rs index 0cced82a384..6f1b9f322a0 100644 --- a/components/script/dom/extendableevent.rs +++ b/components/script/dom/extendableevent.rs @@ -11,8 +11,8 @@ use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::DOMString; use crate::dom::event::Event; use crate::dom::serviceworkerglobalscope::ServiceWorkerGlobalScope; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::JSContext; use js::rust::HandleValue; use servo_atoms::Atom; @@ -62,7 +62,7 @@ impl ExtendableEvent { } // https://w3c.github.io/ServiceWorker/#wait-until-method - pub fn WaitUntil(&self, _cx: *mut JSContext, _val: HandleValue) -> ErrorResult { + pub fn WaitUntil(&self, _cx: JSContext, _val: HandleValue) -> ErrorResult { // Step 1 if !self.extensions_allowed { return Err(Error::InvalidState); diff --git a/components/script/dom/extendablemessageevent.rs b/components/script/dom/extendablemessageevent.rs index 7fd16aafec4..c2ede65745a 100644 --- a/components/script/dom/extendablemessageevent.rs +++ b/components/script/dom/extendablemessageevent.rs @@ -15,8 +15,9 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::extendableevent::ExtendableEvent; use crate::dom::globalscope::GlobalScope; use crate::dom::serviceworkerglobalscope::ServiceWorkerGlobalScope; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSContext}; +use js::jsapi::Heap; use js::jsval::JSVal; use js::rust::HandleValue; use servo_atoms::Atom; @@ -91,9 +92,8 @@ impl ExtendableMessageEvent { } impl ExtendableMessageEventMethods for ExtendableMessageEvent { - #[allow(unsafe_code)] // https://w3c.github.io/ServiceWorker/#extendablemessage-event-data-attribute - unsafe fn Data(&self, _cx: *mut JSContext) -> JSVal { + fn Data(&self, _cx: JSContext) -> JSVal { self.data.get() } diff --git a/components/script/dom/filereader.rs b/components/script/dom/filereader.rs index 31a87c712d6..fdba0e0aa75 100644 --- a/components/script/dom/filereader.rs +++ b/components/script/dom/filereader.rs @@ -22,6 +22,7 @@ use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::progressevent::ProgressEvent; +use crate::script_runtime::JSContext as SafeJSContext; use crate::task::TaskCanceller; use crate::task_source::file_reading::{FileReadingTask, FileReadingTaskSource}; use crate::task_source::{TaskSource, TaskSourceName}; @@ -265,7 +266,7 @@ impl FileReader { let _ac = enter_realm(&*fr); FileReader::perform_readasarraybuffer( &fr.result, - fr.global().get_cx(), + *fr.global().get_cx(), data, &blob_contents, ) @@ -391,12 +392,14 @@ impl FileReaderMethods for FileReader { #[allow(unsafe_code)] // https://w3c.github.io/FileAPI/#dfn-result - unsafe fn GetResult(&self, _: *mut JSContext) -> Option<StringOrObject> { + fn GetResult(&self, _: SafeJSContext) -> Option<StringOrObject> { self.result.borrow().as_ref().map(|r| match *r { FileReaderResult::String(ref string) => StringOrObject::String(string.clone()), FileReaderResult::ArrayBuffer(ref arr_buffer) => { let result = RootedTraceableBox::new(Heap::default()); - result.set((*arr_buffer.ptr.get()).to_object()); + unsafe { + result.set((*arr_buffer.ptr.get()).to_object()); + } StringOrObject::Object(result) }, }) diff --git a/components/script/dom/filereadersync.rs b/components/script/dom/filereadersync.rs index 82f479b0b80..1ed9c6c8007 100644 --- a/components/script/dom/filereadersync.rs +++ b/components/script/dom/filereadersync.rs @@ -13,8 +13,9 @@ use crate::dom::bindings::str::DOMString; use crate::dom::blob::Blob; use crate::dom::filereader::FileReaderSharedFunctionality; use crate::dom::globalscope::GlobalScope; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{JSContext, JSObject}; +use js::jsapi::JSObject; use js::typedarray::{ArrayBuffer, CreateWith}; use std::ptr; use std::ptr::NonNull; @@ -87,23 +88,21 @@ impl FileReaderSyncMethods for FileReaderSync { #[allow(unsafe_code)] // https://w3c.github.io/FileAPI/#readAsArrayBufferSyncSection - unsafe fn ReadAsArrayBuffer( - &self, - cx: *mut JSContext, - blob: &Blob, - ) -> Fallible<NonNull<JSObject>> { + fn ReadAsArrayBuffer(&self, cx: JSContext, blob: &Blob) -> Fallible<NonNull<JSObject>> { // step 1 let blob_contents = FileReaderSync::get_blob_bytes(blob)?; // step 2 - rooted!(in(cx) let mut array_buffer = ptr::null_mut::<JSObject>()); - assert!(ArrayBuffer::create( - cx, - CreateWith::Slice(&blob_contents), - array_buffer.handle_mut() - ) - .is_ok()); - - Ok(NonNull::new_unchecked(array_buffer.get())) + unsafe { + rooted!(in(*cx) let mut array_buffer = ptr::null_mut::<JSObject>()); + assert!(ArrayBuffer::create( + *cx, + CreateWith::Slice(&blob_contents), + array_buffer.handle_mut() + ) + .is_ok()); + + Ok(NonNull::new_unchecked(array_buffer.get())) + } } } diff --git a/components/script/dom/gamepad.rs b/components/script/dom/gamepad.rs index fe86a3b2329..60a73a691fd 100644 --- a/components/script/dom/gamepad.rs +++ b/components/script/dom/gamepad.rs @@ -15,8 +15,9 @@ use crate::dom::gamepadbuttonlist::GamepadButtonList; use crate::dom::gamepadevent::{GamepadEvent, GamepadEventType}; use crate::dom::globalscope::GlobalScope; use crate::dom::vrpose::VRPose; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSContext, JSObject}; +use js::jsapi::{Heap, JSObject}; use js::typedarray::{CreateWith, Float64Array}; use std::cell::Cell; use std::ptr; @@ -98,9 +99,9 @@ impl Gamepad { ); let cx = global.get_cx(); - rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>()); + rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); unsafe { - let _ = Float64Array::create(cx, CreateWith::Slice(&state.axes), array.handle_mut()); + let _ = Float64Array::create(*cx, CreateWith::Slice(&state.axes), array.handle_mut()); } gamepad.axes.set(array.get()); @@ -136,8 +137,8 @@ impl GamepadMethods for Gamepad { #[allow(unsafe_code)] // https://w3c.github.io/gamepad/#dom-gamepad-axes - unsafe fn Axes(&self, _cx: *mut JSContext) -> NonNull<JSObject> { - NonNull::new_unchecked(self.axes.get()) + fn Axes(&self, _cx: JSContext) -> NonNull<JSObject> { + unsafe { NonNull::new_unchecked(self.axes.get()) } } // https://w3c.github.io/gamepad/#dom-gamepad-buttons @@ -172,7 +173,7 @@ impl Gamepad { self.timestamp.set(state.timestamp); unsafe { let cx = self.global().get_cx(); - typedarray!(in(cx) let axes: Float64Array = self.axes.get()); + typedarray!(in(*cx) let axes: Float64Array = self.axes.get()); if let Ok(mut array) = axes { array.update(&state.axes); } diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 385939000bc..ddf7dfc61cc 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -26,7 +26,7 @@ use crate::dom::window::Window; use crate::dom::workerglobalscope::WorkerGlobalScope; use crate::dom::workletglobalscope::WorkletGlobalScope; use crate::microtask::{Microtask, MicrotaskQueue}; -use crate::script_runtime::{CommonScriptMsg, ScriptChan, ScriptPort}; +use crate::script_runtime::{CommonScriptMsg, JSContext as SafeJSContext, ScriptChan, ScriptPort}; use crate::script_thread::{MainThreadScriptChan, ScriptThread}; use crate::task::TaskCanceller; use crate::task_source::dom_manipulation::DOMManipulationTaskSource; @@ -311,8 +311,8 @@ impl GlobalScope { } #[allow(unsafe_code)] - pub fn get_cx(&self) -> *mut JSContext { - Runtime::get() + pub fn get_cx(&self) -> SafeJSContext { + unsafe { SafeJSContext::from_ptr(Runtime::get()) } } pub fn crypto(&self) -> DomRoot<Crypto> { @@ -571,14 +571,14 @@ impl GlobalScope { let globalhandle = self.reflector().get_jsobject(); let filename = CString::new(filename).unwrap(); - let _ac = JSAutoRealm::new(cx, globalhandle.get()); + let _ac = JSAutoRealm::new(*cx, globalhandle.get()); let _aes = AutoEntryScript::new(self); - let options = CompileOptionsWrapper::new(cx, filename.as_ptr(), line_number); + let options = CompileOptionsWrapper::new(*cx, filename.as_ptr(), line_number); debug!("evaluating Dom string"); let result = unsafe { EvaluateUtf8( - cx, + *cx, options.ptr, code.as_ptr() as *const _, code.len() as libc::size_t, @@ -588,7 +588,7 @@ impl GlobalScope { if !result { debug!("error evaluating Dom string"); - unsafe { report_pending_exception(cx, true) }; + unsafe { report_pending_exception(*cx, true) }; } maybe_resume_unwind(); @@ -681,7 +681,7 @@ impl GlobalScope { pub fn perform_a_microtask_checkpoint(&self) { unsafe { self.microtask_queue.checkpoint( - self.get_cx(), + *self.get_cx(), |_| Some(DomRoot::from_ref(self)), vec![DomRoot::from_ref(self)], ); @@ -692,7 +692,7 @@ impl GlobalScope { #[allow(unsafe_code)] pub fn enqueue_microtask(&self, job: Microtask) { unsafe { - self.microtask_queue.enqueue(job, self.get_cx()); + self.microtask_queue.enqueue(job, *self.get_cx()); } } diff --git a/components/script/dom/history.rs b/components/script/dom/history.rs index 787591af8a3..583c58a00f1 100644 --- a/components/script/dom/history.rs +++ b/components/script/dom/history.rs @@ -18,6 +18,7 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::hashchangeevent::HashChangeEvent; use crate::dom::popstateevent::PopStateEvent; use crate::dom::window::Window; +use crate::script_runtime::JSContext as SafeJSContext; use dom_struct::dom_struct; use js::jsapi::{Heap, JSContext}; use js::jsval::{JSVal, NullValue, UndefinedValue}; @@ -116,7 +117,7 @@ impl History { match serialized_data { Some(serialized_data) => { let global_scope = self.window.upcast::<GlobalScope>(); - rooted!(in(global_scope.get_cx()) let mut state = UndefinedValue()); + rooted!(in(*global_scope.get_cx()) let mut state = UndefinedValue()); StructuredCloneData::Vector(serialized_data) .read(&global_scope, state.handle_mut()); self.state.set(state.get()); @@ -279,8 +280,7 @@ impl History { impl HistoryMethods for History { // https://html.spec.whatwg.org/multipage/#dom-history-state - #[allow(unsafe_code)] - unsafe fn GetState(&self, _cx: *mut JSContext) -> Fallible<JSVal> { + fn GetState(&self, _cx: SafeJSContext) -> Fallible<JSVal> { if !self.window.Document().is_fully_active() { return Err(Error::Security); } @@ -327,26 +327,24 @@ impl HistoryMethods for History { } // https://html.spec.whatwg.org/multipage/#dom-history-pushstate - #[allow(unsafe_code)] - unsafe fn PushState( + fn PushState( &self, - cx: *mut JSContext, + cx: SafeJSContext, data: HandleValue, title: DOMString, url: Option<USVString>, ) -> ErrorResult { - self.push_or_replace_state(cx, data, title, url, PushOrReplace::Push) + self.push_or_replace_state(*cx, data, title, url, PushOrReplace::Push) } // https://html.spec.whatwg.org/multipage/#dom-history-replacestate - #[allow(unsafe_code)] - unsafe fn ReplaceState( + fn ReplaceState( &self, - cx: *mut JSContext, + cx: SafeJSContext, data: HandleValue, title: DOMString, url: Option<USVString>, ) -> ErrorResult { - self.push_or_replace_state(cx, data, title, url, PushOrReplace::Replace) + self.push_or_replace_state(*cx, data, title, url, PushOrReplace::Replace) } } diff --git a/components/script/dom/htmlcanvaselement.rs b/components/script/dom/htmlcanvaselement.rs index 6376e9d9a64..4e9abe5f3c9 100644 --- a/components/script/dom/htmlcanvaselement.rs +++ b/components/script/dom/htmlcanvaselement.rs @@ -28,6 +28,7 @@ use crate::dom::webgl2renderingcontext::WebGL2RenderingContext; use crate::dom::webglrenderingcontext::{ LayoutCanvasWebGLRenderingContextHelpers, WebGLRenderingContext, }; +use crate::script_runtime::JSContext as SafeJSContext; use base64; use canvas_traits::canvas::{CanvasId, CanvasMsg, FromScriptMsg}; use canvas_traits::webgl::{GLContextAttributes, WebGLVersion}; @@ -263,7 +264,7 @@ impl HTMLCanvasElement { cx: *mut JSContext, options: HandleValue, ) -> Option<GLContextAttributes> { - match WebGLContextAttributes::new(cx, options) { + match WebGLContextAttributes::new(SafeJSContext::from_ptr(cx), options) { Ok(ConversionResult::Success(ref attrs)) => Some(From::from(attrs)), Ok(ConversionResult::Failure(ref error)) => { throw_type_error(cx, &error); @@ -329,9 +330,9 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement { // https://html.spec.whatwg.org/multipage/#dom-canvas-getcontext #[allow(unsafe_code)] - unsafe fn GetContext( + fn GetContext( &self, - cx: *mut JSContext, + cx: SafeJSContext, id: DOMString, options: HandleValue, ) -> Option<RenderingContext> { @@ -339,21 +340,22 @@ impl HTMLCanvasElementMethods for HTMLCanvasElement { "2d" => self .get_or_init_2d_context() .map(RenderingContext::CanvasRenderingContext2D), - "webgl" | "experimental-webgl" => self - .get_or_init_webgl_context(cx, options) - .map(RenderingContext::WebGLRenderingContext), - "webgl2" | "experimental-webgl2" => self - .get_or_init_webgl2_context(cx, options) - .map(RenderingContext::WebGL2RenderingContext), + "webgl" | "experimental-webgl" => unsafe { + self.get_or_init_webgl_context(*cx, options) + .map(RenderingContext::WebGLRenderingContext) + }, + "webgl2" | "experimental-webgl2" => unsafe { + self.get_or_init_webgl2_context(*cx, options) + .map(RenderingContext::WebGL2RenderingContext) + }, _ => None, } } // https://html.spec.whatwg.org/multipage/#dom-canvas-todataurl - #[allow(unsafe_code)] - unsafe fn ToDataURL( + fn ToDataURL( &self, - _context: *mut JSContext, + _context: SafeJSContext, _mime_type: Option<DOMString>, _quality: HandleValue, ) -> Fallible<USVString> { diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs index 4325add0212..1af49a42f79 100644 --- a/components/script/dom/htmlscriptelement.rs +++ b/components/script/dom/htmlscriptelement.rs @@ -654,7 +654,7 @@ impl HTMLScriptElement { } else { self.line_number as u32 }; - rooted!(in(window.get_cx()) let mut rval = UndefinedValue()); + rooted!(in(*window.get_cx()) let mut rval = UndefinedValue()); let global = window.upcast::<GlobalScope>(); global.evaluate_script_on_global_with_result( &script.text, diff --git a/components/script/dom/imagedata.rs b/components/script/dom/imagedata.rs index 460c827ab1a..52851fdce36 100644 --- a/components/script/dom/imagedata.rs +++ b/components/script/dom/imagedata.rs @@ -8,10 +8,11 @@ use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::DomRoot; use crate::dom::globalscope::GlobalScope; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; use euclid::default::{Rect, Size2D}; use ipc_channel::ipc::IpcSharedMemory; -use js::jsapi::{Heap, JSContext, JSObject}; +use js::jsapi::{Heap, JSObject}; use js::rust::Runtime; use js::typedarray::{CreateWith, Uint8ClampedArray}; use std::borrow::Cow; @@ -40,7 +41,7 @@ impl ImageData { let len = width * height * 4; unsafe { let cx = global.get_cx(); - rooted!(in (cx) let mut js_object = ptr::null_mut::<JSObject>()); + rooted!(in (*cx) let mut js_object = ptr::null_mut::<JSObject>()); let data = match data { Some(ref mut d) => { d.resize(len as usize, 0); @@ -48,7 +49,7 @@ impl ImageData { }, None => CreateWith::Length(len), }; - Uint8ClampedArray::create(cx, data, js_object.handle_mut()).unwrap(); + Uint8ClampedArray::create(*cx, data, js_object.handle_mut()).unwrap(); Self::new_with_jsobject(global, width, Some(height), Some(js_object.get())) } } @@ -69,7 +70,7 @@ impl ImageData { // checking jsobject type and verifying (height * width * 4 == jsobject.byte_len()) if let Some(jsobject) = opt_jsobject { let cx = global.get_cx(); - typedarray!(in(cx) let array_res: Uint8ClampedArray = jsobject); + typedarray!(in(*cx) let array_res: Uint8ClampedArray = jsobject); let array = array_res.map_err(|_| { Error::Type("Argument to Image data is not an Uint8ClampedArray".to_owned()) })?; @@ -109,8 +110,8 @@ impl ImageData { } else { let len = width * height * 4; let cx = global.get_cx(); - rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>()); - Uint8ClampedArray::create(cx, CreateWith::Length(len), array.handle_mut()).unwrap(); + rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); + Uint8ClampedArray::create(*cx, CreateWith::Length(len), array.handle_mut()).unwrap(); (*imagedata).data.set(array.get()); } @@ -131,7 +132,7 @@ impl ImageData { #[allow(unsafe_code)] #[allow(unused_variables)] pub unsafe fn Constructor_( - cx: *mut JSContext, + cx: JSContext, global: &GlobalScope, jsobject: *mut JSObject, width: u32, @@ -183,9 +184,8 @@ impl ImageDataMethods for ImageData { self.height } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-imagedata-data - unsafe fn Data(&self, _: *mut JSContext) -> NonNull<JSObject> { + fn Data(&self, _: JSContext) -> NonNull<JSObject> { NonNull::new(self.data.get()).expect("got a null pointer") } } diff --git a/components/script/dom/messageevent.rs b/components/script/dom/messageevent.rs index c02df1e8e61..52c0bd1acf1 100644 --- a/components/script/dom/messageevent.rs +++ b/components/script/dom/messageevent.rs @@ -15,8 +15,9 @@ use crate::dom::event::Event; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::windowproxy::WindowProxy; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSContext, JSObject}; +use js::jsapi::{Heap, JSObject}; use js::jsval::JSVal; use js::rust::HandleValue; use servo_atoms::Atom; @@ -127,9 +128,8 @@ impl MessageEvent { } impl MessageEventMethods for MessageEvent { - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-messageevent-data - unsafe fn Data(&self, _cx: *mut JSContext) -> JSVal { + fn Data(&self, _cx: JSContext) -> JSVal { self.data.get() } @@ -139,8 +139,7 @@ impl MessageEventMethods for MessageEvent { } // https://html.spec.whatwg.org/multipage/#dom-messageevent-source - #[allow(unsafe_code)] - unsafe fn GetSource(&self, _cx: *mut JSContext) -> Option<NonNull<JSObject>> { + fn GetSource(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { self.source .as_ref() .and_then(|source| NonNull::new(source.reflector().get_jsobject().get())) diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 75172c70717..b11b9e0786c 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -60,13 +60,14 @@ use crate::dom::svgsvgelement::{LayoutSVGSVGElementHelpers, SVGSVGElement}; use crate::dom::text::Text; use crate::dom::virtualmethods::{vtable_for, VirtualMethods}; use crate::dom::window::Window; +use crate::script_runtime::JSContext; use crate::script_thread::ScriptThread; use app_units::Au; use devtools_traits::NodeInfo; use dom_struct::dom_struct; use euclid::default::{Point2D, Rect, Size2D, Vector2D}; use html5ever::{Namespace, Prefix, QualName}; -use js::jsapi::{JSContext, JSObject, JSRuntime}; +use js::jsapi::{JSObject, JSRuntime}; use libc::{self, c_void, uintptr_t}; use malloc_size_of::{MallocSizeOf, MallocSizeOfOps}; use msg::constellation_msg::{BrowsingContextId, PipelineId}; @@ -1630,7 +1631,7 @@ impl Node { pub fn reflect_node<N>( node: Box<N>, document: &Document, - wrap_fn: unsafe fn(*mut JSContext, &GlobalScope, Box<N>) -> DomRoot<N>, + wrap_fn: unsafe fn(JSContext, &GlobalScope, Box<N>) -> DomRoot<N>, ) -> DomRoot<N> where N: DerivedFrom<Node> + DomObject, diff --git a/components/script/dom/offscreencanvas.rs b/components/script/dom/offscreencanvas.rs index 2087c47c91f..142379519fb 100644 --- a/components/script/dom/offscreencanvas.rs +++ b/components/script/dom/offscreencanvas.rs @@ -15,9 +15,9 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::htmlcanvaselement::HTMLCanvasElement; use crate::dom::offscreencanvasrenderingcontext2d::OffscreenCanvasRenderingContext2D; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; use euclid::default::Size2D; -use js::jsapi::JSContext; use js::rust::HandleValue; use ref_filter_map; use std::cell::Cell; @@ -108,10 +108,9 @@ impl OffscreenCanvas { impl OffscreenCanvasMethods for OffscreenCanvas { // https://html.spec.whatwg.org/multipage/#dom-offscreencanvas-getcontext - #[allow(unsafe_code)] - unsafe fn GetContext( + fn GetContext( &self, - _cx: *mut JSContext, + _cx: JSContext, id: DOMString, _options: HandleValue, ) -> Option<OffscreenRenderingContext> { diff --git a/components/script/dom/paintworkletglobalscope.rs b/components/script/dom/paintworkletglobalscope.rs index 2cd6ae19846..bc04ab63440 100644 --- a/components/script/dom/paintworkletglobalscope.rs +++ b/components/script/dom/paintworkletglobalscope.rs @@ -23,6 +23,7 @@ use crate::dom::worklet::WorkletExecutor; use crate::dom::workletglobalscope::WorkletGlobalScope; use crate::dom::workletglobalscope::WorkletGlobalScopeInit; use crate::dom::workletglobalscope::WorkletTask; +use crate::script_runtime::JSContext; use crossbeam_channel::{unbounded, Sender}; use dom_struct::dom_struct; use euclid::Scale; @@ -128,7 +129,7 @@ impl PaintWorkletGlobalScope { missing_image_urls: Vec::new(), }), }); - unsafe { PaintWorkletGlobalScopeBinding::Wrap(runtime.cx(), global) } + unsafe { PaintWorkletGlobalScopeBinding::Wrap(JSContext::from_ptr(runtime.cx()), global) } } pub fn image_cache(&self) -> Arc<dyn ImageCache> { @@ -252,12 +253,12 @@ impl PaintWorkletGlobalScope { ); let cx = self.worklet_global.get_cx(); - let _ac = JSAutoRealm::new(cx, self.worklet_global.reflector().get_jsobject().get()); + let _ac = JSAutoRealm::new(*cx, self.worklet_global.reflector().get_jsobject().get()); // TODO: Steps 1-2.1. // Step 2.2-5.1. - rooted!(in(cx) let mut class_constructor = UndefinedValue()); - rooted!(in(cx) let mut paint_function = UndefinedValue()); + rooted!(in(*cx) let mut class_constructor = UndefinedValue()); + rooted!(in(*cx) let mut paint_function = UndefinedValue()); let rendering_context = match self.paint_definitions.borrow().get(name) { None => { // Step 2.2. @@ -281,21 +282,21 @@ impl PaintWorkletGlobalScope { // prepopulate the paint instance in `RegisterPaint`, to avoid calling it in // the primary worklet thread. // https://github.com/servo/servo/issues/17377 - rooted!(in(cx) let mut paint_instance = UndefinedValue()); + rooted!(in(*cx) let mut paint_instance = UndefinedValue()); match self.paint_class_instances.borrow_mut().entry(name.clone()) { Entry::Occupied(entry) => paint_instance.set(entry.get().get()), Entry::Vacant(entry) => { // Step 5.2-5.3 let args = HandleValueArray::new(); - rooted!(in(cx) let mut result = null_mut::<JSObject>()); + rooted!(in(*cx) let mut result = null_mut::<JSObject>()); unsafe { - Construct1(cx, class_constructor.handle(), &args, result.handle_mut()); + Construct1(*cx, class_constructor.handle(), &args, result.handle_mut()); } paint_instance.set(ObjectValue(result.get())); - if unsafe { JS_IsExceptionPending(cx) } { + if unsafe { JS_IsExceptionPending(*cx) } { debug!("Paint constructor threw an exception {}.", name); unsafe { - JS_ClearPendingException(cx); + JS_ClearPendingException(*cx); } self.paint_definitions .borrow_mut() @@ -332,7 +333,7 @@ impl PaintWorkletGlobalScope { .collect(); let arguments_value_array = unsafe { HandleValueArray::from_rooted_slice(&*arguments_value_vec) }; - rooted!(in(cx) let argument_object = unsafe { JS_NewArrayObject(cx, &arguments_value_array) }); + rooted!(in(*cx) let argument_object = unsafe { JS_NewArrayObject(*cx, &arguments_value_array) }); let args_slice = [ ObjectValue(rendering_context.reflector().get_jsobject().get()), @@ -342,10 +343,10 @@ impl PaintWorkletGlobalScope { ]; let args = unsafe { HandleValueArray::from_rooted_slice(&args_slice) }; - rooted!(in(cx) let mut result = UndefinedValue()); + rooted!(in(*cx) let mut result = UndefinedValue()); unsafe { Call( - cx, + *cx, paint_instance.handle(), paint_function.handle(), &args, @@ -355,10 +356,10 @@ impl PaintWorkletGlobalScope { let missing_image_urls = rendering_context.take_missing_image_urls(); // Step 13. - if unsafe { JS_IsExceptionPending(cx) } { + if unsafe { JS_IsExceptionPending(*cx) } { debug!("Paint function threw an exception {}.", name); unsafe { - JS_ClearPendingException(cx); + JS_ClearPendingException(*cx); } return self.invalid_image(size_in_dpx, missing_image_urls); } @@ -517,8 +518,8 @@ impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobalScope { fn RegisterPaint(&self, name: DOMString, paint_ctor: Rc<VoidFunction>) -> Fallible<()> { let name = Atom::from(name); let cx = self.worklet_global.get_cx(); - rooted!(in(cx) let paint_obj = paint_ctor.callback_holder().get()); - rooted!(in(cx) let paint_val = ObjectValue(paint_obj.get())); + rooted!(in(*cx) let paint_obj = paint_ctor.callback_holder().get()); + rooted!(in(*cx) let paint_val = ObjectValue(paint_obj.get())); debug!("Registering paint image name {}.", name); @@ -534,20 +535,20 @@ impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobalScope { // Step 4-6. let mut property_names: Vec<String> = - unsafe { get_property(cx, paint_obj.handle(), "inputProperties", ()) }? + unsafe { get_property(*cx, paint_obj.handle(), "inputProperties", ()) }? .unwrap_or_default(); let properties = property_names.drain(..).map(Atom::from).collect(); // Step 7-9. let input_arguments: Vec<String> = - unsafe { get_property(cx, paint_obj.handle(), "inputArguments", ()) }? + unsafe { get_property(*cx, paint_obj.handle(), "inputArguments", ()) }? .unwrap_or_default(); // TODO: Steps 10-11. // Steps 12-13. let alpha: bool = - unsafe { get_property(cx, paint_obj.handle(), "alpha", ()) }?.unwrap_or(true); + unsafe { get_property(*cx, paint_obj.handle(), "alpha", ()) }?.unwrap_or(true); // Step 14 if unsafe { !IsConstructor(paint_obj.get()) } { @@ -555,19 +556,24 @@ impl PaintWorkletGlobalScopeMethods for PaintWorkletGlobalScope { } // Steps 15-16 - rooted!(in(cx) let mut prototype = UndefinedValue()); + rooted!(in(*cx) let mut prototype = UndefinedValue()); unsafe { - get_property_jsval(cx, paint_obj.handle(), "prototype", prototype.handle_mut())?; + get_property_jsval(*cx, paint_obj.handle(), "prototype", prototype.handle_mut())?; } if !prototype.is_object() { return Err(Error::Type(String::from("Prototype is not an object."))); } - rooted!(in(cx) let prototype = prototype.to_object()); + rooted!(in(*cx) let prototype = prototype.to_object()); // Steps 17-18 - rooted!(in(cx) let mut paint_function = UndefinedValue()); + rooted!(in(*cx) let mut paint_function = UndefinedValue()); unsafe { - get_property_jsval(cx, prototype.handle(), "paint", paint_function.handle_mut())?; + get_property_jsval( + *cx, + prototype.handle(), + "paint", + paint_function.handle_mut(), + )?; } if !paint_function.is_object() || unsafe { !IsCallable(paint_function.to_object()) } { return Err(Error::Type(String::from("Paint function is not callable."))); diff --git a/components/script/dom/permissions.rs b/components/script/dom/permissions.rs index 5c6d7b0aed0..419115d1240 100644 --- a/components/script/dom/permissions.rs +++ b/components/script/dom/permissions.rs @@ -17,6 +17,7 @@ use crate::dom::bluetoothpermissionresult::BluetoothPermissionResult; use crate::dom::globalscope::GlobalScope; use crate::dom::permissionstatus::PermissionStatus; use crate::dom::promise::Promise; +use crate::script_runtime::JSContext as SafeJSContext; use dom_struct::dom_struct; use js::conversions::ConversionResult; use js::jsapi::{JSContext, JSObject}; @@ -199,22 +200,19 @@ impl Permissions { } impl PermissionsMethods for Permissions { - #[allow(unsafe_code)] // https://w3c.github.io/permissions/#dom-permissions-query - unsafe fn Query(&self, cx: *mut JSContext, permissionDesc: *mut JSObject) -> Rc<Promise> { - self.manipulate(Operation::Query, cx, permissionDesc, None) + fn Query(&self, cx: SafeJSContext, permissionDesc: *mut JSObject) -> Rc<Promise> { + self.manipulate(Operation::Query, *cx, permissionDesc, None) } - #[allow(unsafe_code)] // https://w3c.github.io/permissions/#dom-permissions-request - unsafe fn Request(&self, cx: *mut JSContext, permissionDesc: *mut JSObject) -> Rc<Promise> { - self.manipulate(Operation::Request, cx, permissionDesc, None) + fn Request(&self, cx: SafeJSContext, permissionDesc: *mut JSObject) -> Rc<Promise> { + self.manipulate(Operation::Request, *cx, permissionDesc, None) } - #[allow(unsafe_code)] // https://w3c.github.io/permissions/#dom-permissions-revoke - unsafe fn Revoke(&self, cx: *mut JSContext, permissionDesc: *mut JSObject) -> Rc<Promise> { - self.manipulate(Operation::Revoke, cx, permissionDesc, None) + fn Revoke(&self, cx: SafeJSContext, permissionDesc: *mut JSObject) -> Rc<Promise> { + self.manipulate(Operation::Revoke, *cx, permissionDesc, None) } } @@ -232,7 +230,7 @@ impl PermissionAlgorithm for Permissions { .handle_mut() .set(ObjectValue(permission_descriptor_obj)); unsafe { - match PermissionDescriptor::new(cx, property.handle()) { + match PermissionDescriptor::new(SafeJSContext::from_ptr(cx), property.handle()) { Ok(ConversionResult::Success(descriptor)) => Ok(descriptor), Ok(ConversionResult::Failure(error)) => Err(Error::Type(error.into_owned())), Err(_) => Err(Error::JSFailed), diff --git a/components/script/dom/popstateevent.rs b/components/script/dom/popstateevent.rs index 35bba7dee9e..d5cb3c0ff3a 100644 --- a/components/script/dom/popstateevent.rs +++ b/components/script/dom/popstateevent.rs @@ -14,8 +14,9 @@ use crate::dom::bindings::trace::RootedTraceableBox; use crate::dom::event::Event; use crate::dom::eventtarget::EventTarget; use crate::dom::window::Window; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSContext}; +use js::jsapi::Heap; use js::jsval::JSVal; use js::rust::HandleValue; use servo_atoms::Atom; @@ -81,9 +82,8 @@ impl PopStateEvent { } impl PopStateEventMethods for PopStateEvent { - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-popstateevent-state - unsafe fn State(&self, _cx: *mut JSContext) -> JSVal { + fn State(&self, _cx: JSContext) -> JSVal { self.state.get() } diff --git a/components/script/dom/promise.rs b/components/script/dom/promise.rs index fc1e39406f0..4dd6f53e711 100644 --- a/components/script/dom/promise.rs +++ b/components/script/dom/promise.rs @@ -89,17 +89,17 @@ impl Promise { #[allow(unsafe_code)] pub fn new_in_current_compartment(global: &GlobalScope, _comp: InCompartment) -> Rc<Promise> { let cx = global.get_cx(); - rooted!(in(cx) let mut obj = ptr::null_mut::<JSObject>()); + rooted!(in(*cx) let mut obj = ptr::null_mut::<JSObject>()); unsafe { - Promise::create_js_promise(cx, HandleObject::null(), obj.handle_mut()); - Promise::new_with_js_promise(obj.handle(), cx) + Promise::create_js_promise(*cx, HandleObject::null(), obj.handle_mut()); + Promise::new_with_js_promise(obj.handle(), *cx) } } #[allow(unsafe_code)] pub fn duplicate(&self) -> Rc<Promise> { let cx = self.global().get_cx(); - unsafe { Promise::new_with_js_promise(self.reflector().get_jsobject(), cx) } + unsafe { Promise::new_with_js_promise(self.reflector().get_jsobject(), *cx) } } #[allow(unsafe_code, unrooted_must_root)] @@ -166,10 +166,10 @@ impl Promise { { let cx = self.global().get_cx(); let _ac = enter_realm(&*self); - rooted!(in(cx) let mut v = UndefinedValue()); + rooted!(in(*cx) let mut v = UndefinedValue()); unsafe { - val.to_jsval(cx, v.handle_mut()); - self.resolve(cx, v.handle()); + val.to_jsval(*cx, v.handle_mut()); + self.resolve(*cx, v.handle()); } } @@ -187,10 +187,10 @@ impl Promise { { let cx = self.global().get_cx(); let _ac = enter_realm(&*self); - rooted!(in(cx) let mut v = UndefinedValue()); + rooted!(in(*cx) let mut v = UndefinedValue()); unsafe { - val.to_jsval(cx, v.handle_mut()); - self.reject(cx, v.handle()); + val.to_jsval(*cx, v.handle_mut()); + self.reject(*cx, v.handle()); } } @@ -198,10 +198,10 @@ impl Promise { pub fn reject_error(&self, error: Error) { let cx = self.global().get_cx(); let _ac = enter_realm(&*self); - rooted!(in(cx) let mut v = UndefinedValue()); + rooted!(in(*cx) let mut v = UndefinedValue()); unsafe { - error.to_jsval(cx, &self.global(), v.handle_mut()); - self.reject(cx, v.handle()); + error.to_jsval(*cx, &self.global(), v.handle_mut()); + self.reject(*cx, v.handle()); } } @@ -233,19 +233,19 @@ impl Promise { #[allow(unsafe_code)] pub fn append_native_handler(&self, handler: &PromiseNativeHandler) { let cx = self.global().get_cx(); - rooted!(in(cx) let resolve_func = - create_native_handler_function(cx, + rooted!(in(*cx) let resolve_func = + create_native_handler_function(*cx, handler.reflector().get_jsobject(), NativeHandlerTask::Resolve)); - rooted!(in(cx) let reject_func = - create_native_handler_function(cx, + rooted!(in(*cx) let reject_func = + create_native_handler_function(*cx, handler.reflector().get_jsobject(), NativeHandlerTask::Reject)); unsafe { let ok = AddPromiseReactions( - cx, + *cx, self.promise_obj(), resolve_func.handle(), reject_func.handle(), diff --git a/components/script/dom/promiserejectionevent.rs b/components/script/dom/promiserejectionevent.rs index 4d69b63f564..4e4a148905a 100644 --- a/components/script/dom/promiserejectionevent.rs +++ b/components/script/dom/promiserejectionevent.rs @@ -14,8 +14,9 @@ use crate::dom::bindings::trace::RootedTraceableBox; use crate::dom::event::{Event, EventBubbles, EventCancelable}; use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSContext}; +use js::jsapi::Heap; use js::jsval::JSVal; use js::rust::HandleValue; use servo_atoms::Atom; @@ -100,9 +101,8 @@ impl PromiseRejectionEventMethods for PromiseRejectionEvent { self.promise.clone() } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-promiserejectionevent-reason - unsafe fn Reason(&self, _cx: *mut JSContext) -> JSVal { + fn Reason(&self, _cx: JSContext) -> JSVal { self.reason.get() } diff --git a/components/script/dom/rtcsessiondescription.rs b/components/script/dom/rtcsessiondescription.rs index 0ef79a321c6..6a2a70ebdbd 100644 --- a/components/script/dom/rtcsessiondescription.rs +++ b/components/script/dom/rtcsessiondescription.rs @@ -14,6 +14,7 @@ use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::DOMString; use crate::dom::globalscope::GlobalScope; use crate::dom::window::Window; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; #[dom_struct] diff --git a/components/script/dom/serviceworker.rs b/components/script/dom/serviceworker.rs index b0d7e4de42f..dd968c34d94 100644 --- a/components/script/dom/serviceworker.rs +++ b/components/script/dom/serviceworker.rs @@ -16,9 +16,9 @@ use crate::dom::bindings::str::USVString; use crate::dom::bindings::structuredclone::StructuredCloneData; use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; +use crate::script_runtime::JSContext; use crate::task::TaskOnce; use dom_struct::dom_struct; -use js::jsapi::JSContext; use js::rust::HandleValue; use script_traits::{DOMMessage, ScriptMsg}; use servo_url::ServoUrl; @@ -90,15 +90,14 @@ impl ServiceWorkerMethods for ServiceWorker { USVString(self.script_url.borrow().clone()) } - #[allow(unsafe_code)] // https://w3c.github.io/ServiceWorker/#service-worker-postmessage - unsafe fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult { + fn PostMessage(&self, cx: JSContext, message: HandleValue) -> ErrorResult { // Step 1 if let ServiceWorkerState::Redundant = self.state.get() { return Err(Error::InvalidState); } // Step 7 - let data = StructuredCloneData::write(cx, message)?; + let data = StructuredCloneData::write(*cx, message)?; let msg_vec = DOMMessage(data.move_to_arraybuffer()); let _ = self .global() diff --git a/components/script/dom/serviceworkerglobalscope.rs b/components/script/dom/serviceworkerglobalscope.rs index dce908c406a..5af7f07ab0f 100644 --- a/components/script/dom/serviceworkerglobalscope.rs +++ b/components/script/dom/serviceworkerglobalscope.rs @@ -21,7 +21,9 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::worker::TrustedWorkerAddress; use crate::dom::workerglobalscope::WorkerGlobalScope; use crate::fetch::load_whole_resource; -use crate::script_runtime::{new_rt_and_cx, CommonScriptMsg, Runtime, ScriptChan}; +use crate::script_runtime::{ + new_rt_and_cx, CommonScriptMsg, JSContext as SafeJSContext, Runtime, ScriptChan, +}; use crate::task_queue::{QueuedTask, QueuedTaskConversion, TaskQueue}; use crate::task_source::TaskSourceName; use crossbeam_channel::{unbounded, Receiver, Sender}; @@ -246,7 +248,7 @@ impl ServiceWorkerGlobalScope { swmanager_sender, scope_url, )); - unsafe { ServiceWorkerGlobalScopeBinding::Wrap(cx, scope) } + unsafe { ServiceWorkerGlobalScopeBinding::Wrap(SafeJSContext::from_ptr(cx), scope) } } #[allow(unsafe_code)] @@ -335,7 +337,7 @@ impl ServiceWorkerGlobalScope { unsafe { // Handle interrupt requests - JS_AddInterruptCallback(scope.get_cx(), Some(interrupt_callback)); + JS_AddInterruptCallback(*scope.get_cx(), Some(interrupt_callback)); } scope.execute_script(DOMString::from(source)); @@ -411,7 +413,7 @@ impl ServiceWorkerGlobalScope { let scope = self.upcast::<WorkerGlobalScope>(); let target = self.upcast(); let _ac = enter_realm(&*scope); - rooted!(in(scope.get_cx()) let mut message = UndefinedValue()); + rooted!(in(*scope.get_cx()) let mut message = UndefinedValue()); data.read(scope.upcast(), message.handle_mut()); ExtendableMessageEvent::dispatch_jsval(target, scope.upcast(), message.handle()); }, diff --git a/components/script/dom/testbinding.rs b/components/script/dom/testbinding.rs index 87280aa46e2..dfa148e5c11 100644 --- a/components/script/dom/testbinding.rs +++ b/components/script/dom/testbinding.rs @@ -49,6 +49,7 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::promise::Promise; use crate::dom::promisenativehandler::{Callback, PromiseNativeHandler}; use crate::dom::url::URL; +use crate::script_runtime::JSContext as SafeJSContext; use crate::timers::OneshotTimerCallback; use dom_struct::dom_struct; use js::jsapi::{Heap, JSContext, JSObject}; @@ -215,23 +216,24 @@ impl TestBindingMethods for TestBinding { } fn SetUnion9Attribute(&self, _: ByteStringOrLong) {} #[allow(unsafe_code)] - unsafe fn ArrayAttribute(&self, cx: *mut JSContext) -> NonNull<JSObject> { - rooted!(in(cx) let array = JS_NewUint8ClampedArray(cx, 16)); - NonNull::new(array.get()).expect("got a null pointer") + fn ArrayAttribute(&self, cx: SafeJSContext) -> NonNull<JSObject> { + unsafe { + rooted!(in(*cx) let array = JS_NewUint8ClampedArray(*cx, 16)); + NonNull::new(array.get()).expect("got a null pointer") + } } - #[allow(unsafe_code)] - unsafe fn AnyAttribute(&self, _: *mut JSContext) -> JSVal { + fn AnyAttribute(&self, _: SafeJSContext) -> JSVal { NullValue() } + fn SetAnyAttribute(&self, _: SafeJSContext, _: HandleValue) {} #[allow(unsafe_code)] - unsafe fn SetAnyAttribute(&self, _: *mut JSContext, _: HandleValue) {} - #[allow(unsafe_code)] - unsafe fn ObjectAttribute(&self, cx: *mut JSContext) -> NonNull<JSObject> { - rooted!(in(cx) let obj = JS_NewPlainObject(cx)); - NonNull::new(obj.get()).expect("got a null pointer") + fn ObjectAttribute(&self, cx: SafeJSContext) -> NonNull<JSObject> { + unsafe { + rooted!(in(*cx) let obj = JS_NewPlainObject(*cx)); + NonNull::new(obj.get()).expect("got a null pointer") + } } - #[allow(unsafe_code)] - unsafe fn SetObjectAttribute(&self, _: *mut JSContext, _: *mut JSObject) {} + fn SetObjectAttribute(&self, _: SafeJSContext, _: *mut JSObject) {} fn GetBooleanAttributeNullable(&self) -> Option<bool> { Some(false) @@ -329,12 +331,10 @@ impl TestBindingMethods for TestBinding { fn SetInterfaceAttributeWeak(&self, url: Option<&URL>) { self.url.set(url); } - #[allow(unsafe_code)] - unsafe fn GetObjectAttributeNullable(&self, _: *mut JSContext) -> Option<NonNull<JSObject>> { + fn GetObjectAttributeNullable(&self, _: SafeJSContext) -> Option<NonNull<JSObject>> { None } - #[allow(unsafe_code)] - unsafe fn SetObjectAttributeNullable(&self, _: *mut JSContext, _: *mut JSObject) {} + fn SetObjectAttributeNullable(&self, _: SafeJSContext, _: *mut JSObject) {} fn GetUnionAttributeNullable(&self) -> Option<HTMLElementOrLong> { Some(HTMLElementOrLong::Long(0)) } @@ -419,12 +419,10 @@ impl TestBindingMethods for TestBinding { "".to_owned(), ) } - #[allow(unsafe_code)] - unsafe fn ReceiveAny(&self, _: *mut JSContext) -> JSVal { + fn ReceiveAny(&self, _: SafeJSContext) -> JSVal { NullValue() } - #[allow(unsafe_code)] - unsafe fn ReceiveObject(&self, cx: *mut JSContext) -> NonNull<JSObject> { + fn ReceiveObject(&self, cx: SafeJSContext) -> NonNull<JSObject> { self.ObjectAttribute(cx) } fn ReceiveUnion(&self) -> HTMLElementOrLong { @@ -470,10 +468,9 @@ impl TestBindingMethods for TestBinding { "".to_owned(), )] } - #[allow(unsafe_code)] - unsafe fn ReceiveUnionIdentity( + fn ReceiveUnionIdentity( &self, - _: *mut JSContext, + _: SafeJSContext, arg: UnionTypes::StringOrObject, ) -> UnionTypes::StringOrObject { arg @@ -537,8 +534,7 @@ impl TestBindingMethods for TestBinding { "".to_owned(), )) } - #[allow(unsafe_code)] - unsafe fn ReceiveNullableObject(&self, cx: *mut JSContext) -> Option<NonNull<JSObject>> { + fn ReceiveNullableObject(&self, cx: SafeJSContext) -> Option<NonNull<JSObject>> { self.GetObjectAttributeNullable(cx) } fn ReceiveNullableUnion(&self) -> Option<HTMLElementOrLong> { @@ -666,35 +662,24 @@ impl TestBindingMethods for TestBinding { fn PassUnion7(&self, _: StringSequenceOrUnsignedLong) {} fn PassUnion8(&self, _: ByteStringSequenceOrLong) {} fn PassUnion9(&self, _: UnionTypes::TestDictionaryOrLong) {} - #[allow(unsafe_code)] - unsafe fn PassUnion10(&self, _: *mut JSContext, _: UnionTypes::StringOrObject) {} + fn PassUnion10(&self, _: SafeJSContext, _: UnionTypes::StringOrObject) {} fn PassUnion11(&self, _: UnionTypes::ArrayBufferOrArrayBufferView) {} fn PassUnionWithTypedef(&self, _: DocumentOrTestTypedef) {} fn PassUnionWithTypedef2(&self, _: LongSequenceOrTestTypedef) {} - #[allow(unsafe_code)] - unsafe fn PassAny(&self, _: *mut JSContext, _: HandleValue) {} - #[allow(unsafe_code)] - unsafe fn PassObject(&self, _: *mut JSContext, _: *mut JSObject) {} + fn PassAny(&self, _: SafeJSContext, _: HandleValue) {} + fn PassObject(&self, _: SafeJSContext, _: *mut JSObject) {} fn PassCallbackFunction(&self, _: Rc<Function>) {} fn PassCallbackInterface(&self, _: Rc<EventListener>) {} fn PassSequence(&self, _: Vec<i32>) {} - #[allow(unsafe_code)] - unsafe fn PassAnySequence(&self, _: *mut JSContext, _: CustomAutoRooterGuard<Vec<JSVal>>) {} - #[allow(unsafe_code)] - unsafe fn AnySequencePassthrough( + fn PassAnySequence(&self, _: SafeJSContext, _: CustomAutoRooterGuard<Vec<JSVal>>) {} + fn AnySequencePassthrough( &self, - _: *mut JSContext, + _: SafeJSContext, seq: CustomAutoRooterGuard<Vec<JSVal>>, ) -> Vec<JSVal> { (*seq).clone() } - #[allow(unsafe_code)] - unsafe fn PassObjectSequence( - &self, - _: *mut JSContext, - _: CustomAutoRooterGuard<Vec<*mut JSObject>>, - ) { - } + fn PassObjectSequence(&self, _: SafeJSContext, _: CustomAutoRooterGuard<Vec<*mut JSObject>>) {} fn PassStringSequence(&self, _: Vec<DOMString>) {} fn PassInterfaceSequence(&self, _: Vec<DomRoot<Blob>>) {} @@ -719,8 +704,7 @@ impl TestBindingMethods for TestBinding { fn PassNullableByteString(&self, _: Option<ByteString>) {} // fn PassNullableEnum(self, _: Option<TestEnum>) {} fn PassNullableInterface(&self, _: Option<&Blob>) {} - #[allow(unsafe_code)] - unsafe fn PassNullableObject(&self, _: *mut JSContext, _: *mut JSObject) {} + fn PassNullableObject(&self, _: SafeJSContext, _: *mut JSObject) {} fn PassNullableTypedArray(&self, _: CustomAutoRooterGuard<Option<typedarray::Int8Array>>) {} fn PassNullableUnion(&self, _: Option<HTMLElementOrLong>) {} fn PassNullableUnion2(&self, _: Option<EventOrString>) {} @@ -756,10 +740,8 @@ impl TestBindingMethods for TestBinding { fn PassOptionalUnion4(&self, _: Option<LongSequenceOrBoolean>) {} fn PassOptionalUnion5(&self, _: Option<UnsignedLongOrBoolean>) {} fn PassOptionalUnion6(&self, _: Option<ByteStringOrLong>) {} - #[allow(unsafe_code)] - unsafe fn PassOptionalAny(&self, _: *mut JSContext, _: HandleValue) {} - #[allow(unsafe_code)] - unsafe fn PassOptionalObject(&self, _: *mut JSContext, _: Option<*mut JSObject>) {} + fn PassOptionalAny(&self, _: SafeJSContext, _: HandleValue) {} + fn PassOptionalObject(&self, _: SafeJSContext, _: Option<*mut JSObject>) {} fn PassOptionalCallbackFunction(&self, _: Option<Rc<Function>>) {} fn PassOptionalCallbackInterface(&self, _: Option<Rc<EventListener>>) {} fn PassOptionalSequence(&self, _: Option<Vec<i32>>) {} @@ -782,8 +764,7 @@ impl TestBindingMethods for TestBinding { fn PassOptionalNullableByteString(&self, _: Option<Option<ByteString>>) {} // fn PassOptionalNullableEnum(self, _: Option<Option<TestEnum>>) {} fn PassOptionalNullableInterface(&self, _: Option<Option<&Blob>>) {} - #[allow(unsafe_code)] - unsafe fn PassOptionalNullableObject(&self, _: *mut JSContext, _: Option<*mut JSObject>) {} + fn PassOptionalNullableObject(&self, _: SafeJSContext, _: Option<*mut JSObject>) {} fn PassOptionalNullableUnion(&self, _: Option<Option<HTMLElementOrLong>>) {} fn PassOptionalNullableUnion2(&self, _: Option<Option<EventOrString>>) {} fn PassOptionalNullableUnion3(&self, _: Option<Option<StringOrLongSequence>>) {} @@ -827,14 +808,12 @@ impl TestBindingMethods for TestBinding { fn PassOptionalNullableByteStringWithDefault(&self, _: Option<ByteString>) {} // fn PassOptionalNullableEnumWithDefault(self, _: Option<TestEnum>) {} fn PassOptionalNullableInterfaceWithDefault(&self, _: Option<&Blob>) {} - #[allow(unsafe_code)] - unsafe fn PassOptionalNullableObjectWithDefault(&self, _: *mut JSContext, _: *mut JSObject) {} + fn PassOptionalNullableObjectWithDefault(&self, _: SafeJSContext, _: *mut JSObject) {} fn PassOptionalNullableUnionWithDefault(&self, _: Option<HTMLElementOrLong>) {} fn PassOptionalNullableUnion2WithDefault(&self, _: Option<EventOrString>) {} // fn PassOptionalNullableCallbackFunctionWithDefault(self, _: Option<Function>) {} fn PassOptionalNullableCallbackInterfaceWithDefault(&self, _: Option<Rc<EventListener>>) {} - #[allow(unsafe_code)] - unsafe fn PassOptionalAnyWithDefault(&self, _: *mut JSContext, _: HandleValue) {} + fn PassOptionalAnyWithDefault(&self, _: SafeJSContext, _: HandleValue) {} fn PassOptionalNullableBooleanWithNonNullDefault(&self, _: Option<bool>) {} fn PassOptionalNullableByteWithNonNullDefault(&self, _: Option<i8>) {} @@ -883,10 +862,8 @@ impl TestBindingMethods for TestBinding { fn PassVariadicUnion5(&self, _: Vec<StringOrUnsignedLong>) {} fn PassVariadicUnion6(&self, _: Vec<UnsignedLongOrBoolean>) {} fn PassVariadicUnion7(&self, _: Vec<ByteStringOrLong>) {} - #[allow(unsafe_code)] - unsafe fn PassVariadicAny(&self, _: *mut JSContext, _: Vec<HandleValue>) {} - #[allow(unsafe_code)] - unsafe fn PassVariadicObject(&self, _: *mut JSContext, _: Vec<*mut JSObject>) {} + fn PassVariadicAny(&self, _: SafeJSContext, _: Vec<HandleValue>) {} + fn PassVariadicObject(&self, _: SafeJSContext, _: Vec<*mut JSObject>) {} fn BooleanMozPreference(&self, pref_name: DOMString) -> bool { prefs::pref_map() .get(pref_name.as_ref()) @@ -965,32 +942,28 @@ impl TestBindingMethods for TestBinding { #[allow(unrooted_must_root)] #[allow(unsafe_code)] - unsafe fn ReturnResolvedPromise( - &self, - cx: *mut JSContext, - v: HandleValue, - ) -> Fallible<Rc<Promise>> { - Promise::new_resolved(&self.global(), cx, v) + fn ReturnResolvedPromise(&self, cx: SafeJSContext, v: HandleValue) -> Fallible<Rc<Promise>> { + unsafe { Promise::new_resolved(&self.global(), *cx, v) } } #[allow(unrooted_must_root)] #[allow(unsafe_code)] - unsafe fn ReturnRejectedPromise( - &self, - cx: *mut JSContext, - v: HandleValue, - ) -> Fallible<Rc<Promise>> { - Promise::new_rejected(&self.global(), cx, v) + fn ReturnRejectedPromise(&self, cx: SafeJSContext, v: HandleValue) -> Fallible<Rc<Promise>> { + unsafe { Promise::new_rejected(&self.global(), *cx, v) } } #[allow(unsafe_code)] - unsafe fn PromiseResolveNative(&self, cx: *mut JSContext, p: &Promise, v: HandleValue) { - p.resolve(cx, v); + fn PromiseResolveNative(&self, cx: SafeJSContext, p: &Promise, v: HandleValue) { + unsafe { + p.resolve(*cx, v); + } } #[allow(unsafe_code)] - unsafe fn PromiseRejectNative(&self, cx: *mut JSContext, p: &Promise, v: HandleValue) { - p.reject(cx, v); + fn PromiseRejectNative(&self, cx: SafeJSContext, p: &Promise, v: HandleValue) { + unsafe { + p.reject(*cx, v); + } } fn PromiseRejectWithTypeError(&self, p: &Promise, s: USVString) { diff --git a/components/script/dom/testworkletglobalscope.rs b/components/script/dom/testworkletglobalscope.rs index aa60fa3a960..c67e1536457 100644 --- a/components/script/dom/testworkletglobalscope.rs +++ b/components/script/dom/testworkletglobalscope.rs @@ -10,6 +10,7 @@ use crate::dom::bindings::str::DOMString; use crate::dom::worklet::WorkletExecutor; use crate::dom::workletglobalscope::WorkletGlobalScope; use crate::dom::workletglobalscope::WorkletGlobalScopeInit; +use crate::script_runtime::JSContext; use crossbeam_channel::Sender; use dom_struct::dom_struct; use js::rust::Runtime; @@ -49,7 +50,7 @@ impl TestWorkletGlobalScope { ), lookup_table: Default::default(), }); - unsafe { TestWorkletGlobalScopeBinding::Wrap(runtime.cx(), global) } + unsafe { TestWorkletGlobalScopeBinding::Wrap(JSContext::from_ptr(runtime.cx()), global) } } pub fn perform_a_worklet_task(&self, task: TestWorkletTask) { diff --git a/components/script/dom/textencoder.rs b/components/script/dom/textencoder.rs index 5f1fddf5d10..fae24beaf78 100644 --- a/components/script/dom/textencoder.rs +++ b/components/script/dom/textencoder.rs @@ -9,8 +9,9 @@ use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::str::{DOMString, USVString}; use crate::dom::globalscope::GlobalScope; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{JSContext, JSObject}; +use js::jsapi::JSObject; use js::typedarray::{CreateWith, Uint8Array}; use std::ptr; use std::ptr::NonNull; @@ -49,14 +50,17 @@ impl TextEncoderMethods for TextEncoder { #[allow(unsafe_code)] // https://encoding.spec.whatwg.org/#dom-textencoder-encode - unsafe fn Encode(&self, cx: *mut JSContext, input: USVString) -> NonNull<JSObject> { + fn Encode(&self, cx: JSContext, input: USVString) -> NonNull<JSObject> { let encoded = input.0.as_bytes(); - rooted!(in(cx) let mut js_object = ptr::null_mut::<JSObject>()); - assert!( - Uint8Array::create(cx, CreateWith::Slice(&encoded), js_object.handle_mut()).is_ok() - ); + unsafe { + rooted!(in(*cx) let mut js_object = ptr::null_mut::<JSObject>()); + assert!( + Uint8Array::create(*cx, CreateWith::Slice(&encoded), js_object.handle_mut()) + .is_ok() + ); - NonNull::new_unchecked(js_object.get()) + NonNull::new_unchecked(js_object.get()) + } } } diff --git a/components/script/dom/userscripts.rs b/components/script/dom/userscripts.rs index af7c2b6d3f1..4e9cc59d27f 100644 --- a/components/script/dom/userscripts.rs +++ b/components/script/dom/userscripts.rs @@ -22,7 +22,7 @@ pub fn load_script(head: &HTMLHeadElement) { doc.add_delayed_task(task!(UserScriptExecute: move || { let win = win.root(); let cx = win.get_cx(); - rooted!(in(cx) let mut rval = UndefinedValue()); + rooted!(in(*cx) let mut rval = UndefinedValue()); let path = PathBuf::from(&path_str); let mut files = read_dir(&path) diff --git a/components/script/dom/vreyeparameters.rs b/components/script/dom/vreyeparameters.rs index 2779989d0ae..a7463c34a28 100644 --- a/components/script/dom/vreyeparameters.rs +++ b/components/script/dom/vreyeparameters.rs @@ -9,8 +9,9 @@ use crate::dom::bindings::reflector::{reflect_dom_object, Reflector}; use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::globalscope::GlobalScope; use crate::dom::vrfieldofview::VRFieldOfView; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSContext, JSObject}; +use js::jsapi::{Heap, JSObject}; use js::typedarray::{CreateWith, Float32Array}; use std::default::Default; use std::ptr; @@ -44,10 +45,10 @@ impl VREyeParameters { let fov = VRFieldOfView::new(&global, parameters.field_of_view.clone()); let cx = global.get_cx(); - rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>()); + rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); unsafe { let _ = Float32Array::create( - cx, + *cx, CreateWith::Slice(¶meters.offset), array.handle_mut(), ); @@ -67,8 +68,8 @@ impl VREyeParameters { impl VREyeParametersMethods for VREyeParameters { #[allow(unsafe_code)] // https://w3c.github.io/webvr/#dom-vreyeparameters-offset - unsafe fn Offset(&self, _cx: *mut JSContext) -> NonNull<JSObject> { - NonNull::new_unchecked(self.offset.get()) + fn Offset(&self, _cx: JSContext) -> NonNull<JSObject> { + unsafe { NonNull::new_unchecked(self.offset.get()) } } // https://w3c.github.io/webvr/#dom-vreyeparameters-fieldofview diff --git a/components/script/dom/vrframedata.rs b/components/script/dom/vrframedata.rs index 25f6af821a7..b7b8c743080 100644 --- a/components/script/dom/vrframedata.rs +++ b/components/script/dom/vrframedata.rs @@ -11,8 +11,9 @@ use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::globalscope::GlobalScope; use crate::dom::vrpose::VRPose; use crate::dom::window::Window; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSContext, JSObject}; +use js::jsapi::{Heap, JSObject}; use js::typedarray::{CreateWith, Float32Array}; use std::cell::Cell; use std::ptr; @@ -62,12 +63,10 @@ impl VRFrameData { VRFrameDataBinding::Wrap, ); let cx = global.get_cx(); - unsafe { - create_typed_array(cx, &matrix, &root.left_proj); - create_typed_array(cx, &matrix, &root.left_view); - create_typed_array(cx, &matrix, &root.right_proj); - create_typed_array(cx, &matrix, &root.right_view); - } + create_typed_array(cx, &matrix, &root.left_proj); + create_typed_array(cx, &matrix, &root.left_view); + create_typed_array(cx, &matrix, &root.right_proj); + create_typed_array(cx, &matrix, &root.right_view); root } @@ -79,9 +78,11 @@ impl VRFrameData { /// FIXME(#22526) this should be in a better place #[allow(unsafe_code)] -pub unsafe fn create_typed_array(cx: *mut JSContext, src: &[f32], dst: &Heap<*mut JSObject>) { - rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>()); - let _ = Float32Array::create(cx, CreateWith::Slice(src), array.handle_mut()); +pub fn create_typed_array(cx: JSContext, src: &[f32], dst: &Heap<*mut JSObject>) { + rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); + unsafe { + let _ = Float32Array::create(*cx, CreateWith::Slice(src), array.handle_mut()); + } (*dst).set(array.get()); } @@ -90,27 +91,27 @@ impl VRFrameData { pub fn update(&self, data: &WebVRFrameData) { unsafe { let cx = self.global().get_cx(); - typedarray!(in(cx) let left_proj_array: Float32Array = self.left_proj.get()); + typedarray!(in(*cx) let left_proj_array: Float32Array = self.left_proj.get()); if let Ok(mut array) = left_proj_array { array.update(&data.left_projection_matrix); } - typedarray!(in(cx) let left_view_array: Float32Array = self.left_view.get()); + typedarray!(in(*cx) let left_view_array: Float32Array = self.left_view.get()); if let Ok(mut array) = left_view_array { array.update(&data.left_view_matrix); } - typedarray!(in(cx) let right_proj_array: Float32Array = self.right_proj.get()); + typedarray!(in(*cx) let right_proj_array: Float32Array = self.right_proj.get()); if let Ok(mut array) = right_proj_array { array.update(&data.right_projection_matrix); } - typedarray!(in(cx) let right_view_array: Float32Array = self.right_view.get()); + typedarray!(in(*cx) let right_view_array: Float32Array = self.right_view.get()); if let Ok(mut array) = right_view_array { array.update(&data.right_view_matrix); } - } - self.pose.update(&data.pose); - self.timestamp.set(data.timestamp); - if self.first_timestamp.get() == 0.0 { - self.first_timestamp.set(data.timestamp); + self.pose.update(&data.pose); + self.timestamp.set(data.timestamp); + if self.first_timestamp.get() == 0.0 { + self.first_timestamp.set(data.timestamp); + } } } } @@ -123,26 +124,26 @@ impl VRFrameDataMethods for VRFrameData { #[allow(unsafe_code)] // https://w3c.github.io/webvr/#dom-vrframedata-leftprojectionmatrix - unsafe fn LeftProjectionMatrix(&self, _cx: *mut JSContext) -> NonNull<JSObject> { - NonNull::new_unchecked(self.left_proj.get()) + fn LeftProjectionMatrix(&self, _cx: JSContext) -> NonNull<JSObject> { + unsafe { NonNull::new_unchecked(self.left_proj.get()) } } #[allow(unsafe_code)] // https://w3c.github.io/webvr/#dom-vrframedata-leftviewmatrix - unsafe fn LeftViewMatrix(&self, _cx: *mut JSContext) -> NonNull<JSObject> { - NonNull::new_unchecked(self.left_view.get()) + fn LeftViewMatrix(&self, _cx: JSContext) -> NonNull<JSObject> { + unsafe { NonNull::new_unchecked(self.left_view.get()) } } #[allow(unsafe_code)] // https://w3c.github.io/webvr/#dom-vrframedata-rightprojectionmatrix - unsafe fn RightProjectionMatrix(&self, _cx: *mut JSContext) -> NonNull<JSObject> { - NonNull::new_unchecked(self.right_proj.get()) + fn RightProjectionMatrix(&self, _cx: JSContext) -> NonNull<JSObject> { + unsafe { NonNull::new_unchecked(self.right_proj.get()) } } #[allow(unsafe_code)] // https://w3c.github.io/webvr/#dom-vrframedata-rightviewmatrix - unsafe fn RightViewMatrix(&self, _cx: *mut JSContext) -> NonNull<JSObject> { - NonNull::new_unchecked(self.right_view.get()) + fn RightViewMatrix(&self, _cx: JSContext) -> NonNull<JSObject> { + unsafe { NonNull::new_unchecked(self.right_view.get()) } } // https://w3c.github.io/webvr/#dom-vrframedata-pose diff --git a/components/script/dom/vrpose.rs b/components/script/dom/vrpose.rs index 90bca0956ee..2303641d6eb 100644 --- a/components/script/dom/vrpose.rs +++ b/components/script/dom/vrpose.rs @@ -7,8 +7,9 @@ use crate::dom::bindings::codegen::Bindings::VRPoseBinding::VRPoseMethods; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::DomRoot; use crate::dom::globalscope::GlobalScope; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSContext, JSObject}; +use js::jsapi::{Heap, JSObject}; use js::typedarray::{CreateWith, Float32Array}; use std::ptr; use std::ptr::NonNull; @@ -32,21 +33,19 @@ pub struct VRPose { } #[allow(unsafe_code)] -unsafe fn update_or_create_typed_array( - cx: *mut JSContext, - src: Option<&[f32]>, - dst: &Heap<*mut JSObject>, -) { +fn update_or_create_typed_array(cx: JSContext, src: Option<&[f32]>, dst: &Heap<*mut JSObject>) { match src { Some(data) => { if dst.get().is_null() { - rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>()); - let _ = Float32Array::create(cx, CreateWith::Slice(data), array.handle_mut()); + rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); + let _ = unsafe { + Float32Array::create(*cx, CreateWith::Slice(data), array.handle_mut()) + }; (*dst).set(array.get()); } else { - typedarray!(in(cx) let array: Float32Array = dst.get()); + typedarray!(in(*cx) let array: Float32Array = dst.get()); if let Ok(mut array) = array { - array.update(data); + unsafe { array.update(data) }; } } }, @@ -95,75 +94,63 @@ impl VRPose { #[allow(unsafe_code)] pub fn update(&self, pose: &webvr::VRPose) { let cx = self.global().get_cx(); - unsafe { - update_or_create_typed_array( - cx, - pose.position.as_ref().map(|v| &v[..]), - &self.position, - ); - update_or_create_typed_array( - cx, - pose.orientation.as_ref().map(|v| &v[..]), - &self.orientation, - ); - update_or_create_typed_array( - cx, - pose.linear_velocity.as_ref().map(|v| &v[..]), - &self.linear_vel, - ); - update_or_create_typed_array( - cx, - pose.angular_velocity.as_ref().map(|v| &v[..]), - &self.angular_vel, - ); - update_or_create_typed_array( - cx, - pose.linear_acceleration.as_ref().map(|v| &v[..]), - &self.linear_acc, - ); - update_or_create_typed_array( - cx, - pose.angular_acceleration.as_ref().map(|v| &v[..]), - &self.angular_acc, - ); - } + update_or_create_typed_array(cx, pose.position.as_ref().map(|v| &v[..]), &self.position); + update_or_create_typed_array( + cx, + pose.orientation.as_ref().map(|v| &v[..]), + &self.orientation, + ); + update_or_create_typed_array( + cx, + pose.linear_velocity.as_ref().map(|v| &v[..]), + &self.linear_vel, + ); + update_or_create_typed_array( + cx, + pose.angular_velocity.as_ref().map(|v| &v[..]), + &self.angular_vel, + ); + update_or_create_typed_array( + cx, + pose.linear_acceleration.as_ref().map(|v| &v[..]), + &self.linear_acc, + ); + update_or_create_typed_array( + cx, + pose.angular_acceleration.as_ref().map(|v| &v[..]), + &self.angular_acc, + ); } } impl VRPoseMethods for VRPose { - #[allow(unsafe_code)] // https://w3c.github.io/webvr/#dom-vrpose-position - unsafe fn GetPosition(&self, _cx: *mut JSContext) -> Option<NonNull<JSObject>> { + fn GetPosition(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { heap_to_option(&self.position) } - #[allow(unsafe_code)] // https://w3c.github.io/webvr/#dom-vrpose-linearvelocity - unsafe fn GetLinearVelocity(&self, _cx: *mut JSContext) -> Option<NonNull<JSObject>> { + fn GetLinearVelocity(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { heap_to_option(&self.linear_vel) } - #[allow(unsafe_code)] // https://w3c.github.io/webvr/#dom-vrpose-linearacceleration - unsafe fn GetLinearAcceleration(&self, _cx: *mut JSContext) -> Option<NonNull<JSObject>> { + fn GetLinearAcceleration(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { heap_to_option(&self.linear_acc) } - #[allow(unsafe_code)] // https://w3c.github.io/webvr/#dom-vrpose-orientation - unsafe fn GetOrientation(&self, _cx: *mut JSContext) -> Option<NonNull<JSObject>> { + fn GetOrientation(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { heap_to_option(&self.orientation) } - #[allow(unsafe_code)] // https://w3c.github.io/webvr/#dom-vrpose-angularvelocity - unsafe fn GetAngularVelocity(&self, _cx: *mut JSContext) -> Option<NonNull<JSObject>> { + fn GetAngularVelocity(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { heap_to_option(&self.angular_vel) } - #[allow(unsafe_code)] // https://w3c.github.io/webvr/#dom-vrpose-angularacceleration - unsafe fn GetAngularAcceleration(&self, _cx: *mut JSContext) -> Option<NonNull<JSObject>> { + fn GetAngularAcceleration(&self, _cx: JSContext) -> Option<NonNull<JSObject>> { heap_to_option(&self.angular_acc) } } diff --git a/components/script/dom/vrstageparameters.rs b/components/script/dom/vrstageparameters.rs index 41184091232..747608763e9 100644 --- a/components/script/dom/vrstageparameters.rs +++ b/components/script/dom/vrstageparameters.rs @@ -9,8 +9,9 @@ use crate::dom::bindings::num::Finite; use crate::dom::bindings::reflector::{reflect_dom_object, DomObject, Reflector}; use crate::dom::bindings::root::DomRoot; use crate::dom::globalscope::GlobalScope; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSContext, JSObject}; +use js::jsapi::{Heap, JSObject}; use js::typedarray::{CreateWith, Float32Array}; use std::ptr; use std::ptr::NonNull; @@ -42,10 +43,10 @@ impl VRStageParameters { global: &GlobalScope, ) -> DomRoot<VRStageParameters> { let cx = global.get_cx(); - rooted!(in (cx) let mut array = ptr::null_mut::<JSObject>()); + rooted!(in (*cx) let mut array = ptr::null_mut::<JSObject>()); unsafe { let _ = Float32Array::create( - cx, + *cx, CreateWith::Slice(¶meters.sitting_to_standing_transform), array.handle_mut(), ); @@ -66,7 +67,7 @@ impl VRStageParameters { pub fn update(&self, parameters: &WebVRStageParameters) { unsafe { let cx = self.global().get_cx(); - typedarray!(in(cx) let array: Float32Array = self.transform.get()); + typedarray!(in(*cx) let array: Float32Array = self.transform.get()); if let Ok(mut array) = array { array.update(¶meters.sitting_to_standing_transform); } @@ -78,8 +79,8 @@ impl VRStageParameters { impl VRStageParametersMethods for VRStageParameters { #[allow(unsafe_code)] // https://w3c.github.io/webvr/#dom-vrstageparameters-sittingtostandingtransform - unsafe fn SittingToStandingTransform(&self, _cx: *mut JSContext) -> NonNull<JSObject> { - NonNull::new_unchecked(self.transform.get()) + fn SittingToStandingTransform(&self, _cx: JSContext) -> NonNull<JSObject> { + unsafe { NonNull::new_unchecked(self.transform.get()) } } // https://w3c.github.io/webvr/#dom-vrstageparameters-sizex diff --git a/components/script/dom/webgl2renderingcontext.rs b/components/script/dom/webgl2renderingcontext.rs index 3b068caafca..26b81f8ad3a 100644 --- a/components/script/dom/webgl2renderingcontext.rs +++ b/components/script/dom/webgl2renderingcontext.rs @@ -29,11 +29,12 @@ use crate::dom::webglshaderprecisionformat::WebGLShaderPrecisionFormat; use crate::dom::webgltexture::WebGLTexture; use crate::dom::webgluniformlocation::WebGLUniformLocation; use crate::dom::window::Window; +use crate::script_runtime::JSContext; /// https://www.khronos.org/registry/webgl/specs/latest/2.0/webgl.idl use canvas_traits::webgl::{GLContextAttributes, WebGLVersion}; use dom_struct::dom_struct; use euclid::default::Size2D; -use js::jsapi::{JSContext, JSObject}; +use js::jsapi::JSObject; use js::jsval::JSVal; use js::rust::CustomAutoRooterGuard; use js::typedarray::ArrayBufferView; @@ -109,21 +110,19 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { self.base.DrawingBufferHeight() } - #[allow(unsafe_code)] /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - unsafe fn GetBufferParameter(&self, _cx: *mut JSContext, target: u32, parameter: u32) -> JSVal { - self.base.GetBufferParameter(_cx, target, parameter) + fn GetBufferParameter(&self, cx: JSContext, target: u32, parameter: u32) -> JSVal { + self.base.GetBufferParameter(cx, target, parameter) } #[allow(unsafe_code)] /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 - unsafe fn GetParameter(&self, cx: *mut JSContext, parameter: u32) -> JSVal { + fn GetParameter(&self, cx: JSContext, parameter: u32) -> JSVal { self.base.GetParameter(cx, parameter) } - #[allow(unsafe_code)] /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 - unsafe fn GetTexParameter(&self, cx: *mut JSContext, target: u32, pname: u32) -> JSVal { + fn GetTexParameter(&self, cx: JSContext, target: u32, pname: u32) -> JSVal { self.base.GetTexParameter(cx, target, pname) } @@ -142,21 +141,15 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { self.base.GetSupportedExtensions() } - #[allow(unsafe_code)] /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.14 - unsafe fn GetExtension( - &self, - cx: *mut JSContext, - name: DOMString, - ) -> Option<NonNull<JSObject>> { + fn GetExtension(&self, cx: JSContext, name: DOMString) -> Option<NonNull<JSObject>> { self.base.GetExtension(cx, name) } - #[allow(unsafe_code)] /// https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.4 - unsafe fn GetFramebufferAttachmentParameter( + fn GetFramebufferAttachmentParameter( &self, - cx: *mut JSContext, + cx: JSContext, target: u32, attachment: u32, pname: u32, @@ -165,14 +158,8 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { .GetFramebufferAttachmentParameter(cx, target, attachment, pname) } - #[allow(unsafe_code)] /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 - unsafe fn GetRenderbufferParameter( - &self, - cx: *mut JSContext, - target: u32, - pname: u32, - ) -> JSVal { + fn GetRenderbufferParameter(&self, cx: JSContext, target: u32, pname: u32) -> JSVal { self.base.GetRenderbufferParameter(cx, target, pname) } @@ -505,14 +492,8 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { self.base.GetProgramInfoLog(program) } - #[allow(unsafe_code)] /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - unsafe fn GetProgramParameter( - &self, - cx: *mut JSContext, - program: &WebGLProgram, - param_id: u32, - ) -> JSVal { + fn GetProgramParameter(&self, cx: JSContext, program: &WebGLProgram, param_id: u32) -> JSVal { self.base.GetProgramParameter(cx, program, param_id) } @@ -521,14 +502,8 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { self.base.GetShaderInfoLog(shader) } - #[allow(unsafe_code)] /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - unsafe fn GetShaderParameter( - &self, - cx: *mut JSContext, - shader: &WebGLShader, - param_id: u32, - ) -> JSVal { + fn GetShaderParameter(&self, cx: JSContext, shader: &WebGLShader, param_id: u32) -> JSVal { self.base.GetShaderParameter(cx, shader, param_id) } @@ -551,9 +526,8 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { self.base.GetUniformLocation(program, name) } - #[allow(unsafe_code)] /// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - unsafe fn GetVertexAttrib(&self, cx: *mut JSContext, index: u32, pname: u32) -> JSVal { + fn GetVertexAttrib(&self, cx: JSContext, index: u32, pname: u32) -> JSVal { self.base.GetVertexAttrib(cx, index, pname) } @@ -815,10 +789,9 @@ impl WebGL2RenderingContextMethods for WebGL2RenderingContext { } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 - #[allow(unsafe_code)] - unsafe fn GetUniform( + fn GetUniform( &self, - cx: *mut JSContext, + cx: JSContext, program: &WebGLProgram, location: &WebGLUniformLocation, ) -> JSVal { diff --git a/components/script/dom/webglrenderingcontext.rs b/components/script/dom/webglrenderingcontext.rs index 21927e6bf44..1240caccf7c 100644 --- a/components/script/dom/webglrenderingcontext.rs +++ b/components/script/dom/webglrenderingcontext.rs @@ -48,6 +48,7 @@ use crate::dom::webgltexture::{TexParameterValue, WebGLTexture}; use crate::dom::webgluniformlocation::WebGLUniformLocation; use crate::dom::webglvertexarrayobjectoes::WebGLVertexArrayObjectOES; use crate::dom::window::Window; +use crate::script_runtime::JSContext as SafeJSContext; #[cfg(feature = "webgl_backtrace")] use backtrace::Backtrace; use canvas_traits::webgl::WebGLError::*; @@ -1148,9 +1149,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { receiver.recv().unwrap() } - #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.5 - unsafe fn GetBufferParameter(&self, _cx: *mut JSContext, target: u32, parameter: u32) -> JSVal { + fn GetBufferParameter(&self, _cx: SafeJSContext, target: u32, parameter: u32) -> JSVal { let buffer = handle_potential_webgl_error!( self, self.bound_buffer(target) @@ -1170,7 +1170,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3 - unsafe fn GetParameter(&self, cx: *mut JSContext, parameter: u32) -> JSVal { + fn GetParameter(&self, cx: SafeJSContext, parameter: u32) -> JSVal { if !self .extension_manager .is_get_parameter_name_enabled(parameter) @@ -1180,41 +1180,41 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } match parameter { - constants::ARRAY_BUFFER_BINDING => { - return optional_root_object_to_js_or_null!(cx, &self.bound_buffer_array.get()); + constants::ARRAY_BUFFER_BINDING => unsafe { + return optional_root_object_to_js_or_null!(*cx, &self.bound_buffer_array.get()); }, - constants::CURRENT_PROGRAM => { - return optional_root_object_to_js_or_null!(cx, &self.current_program.get()); + constants::CURRENT_PROGRAM => unsafe { + return optional_root_object_to_js_or_null!(*cx, &self.current_program.get()); }, - constants::ELEMENT_ARRAY_BUFFER_BINDING => { + constants::ELEMENT_ARRAY_BUFFER_BINDING => unsafe { let buffer = self.current_vao().element_array_buffer().get(); - return optional_root_object_to_js_or_null!(cx, buffer); + return optional_root_object_to_js_or_null!(*cx, buffer); }, - constants::FRAMEBUFFER_BINDING => { - return optional_root_object_to_js_or_null!(cx, &self.bound_framebuffer.get()); + constants::FRAMEBUFFER_BINDING => unsafe { + return optional_root_object_to_js_or_null!(*cx, &self.bound_framebuffer.get()); }, - constants::RENDERBUFFER_BINDING => { - return optional_root_object_to_js_or_null!(cx, &self.bound_renderbuffer.get()); + constants::RENDERBUFFER_BINDING => unsafe { + return optional_root_object_to_js_or_null!(*cx, &self.bound_renderbuffer.get()); }, - constants::TEXTURE_BINDING_2D => { + constants::TEXTURE_BINDING_2D => unsafe { let texture = self .textures .active_texture_slot(constants::TEXTURE_2D) .unwrap() .get(); - return optional_root_object_to_js_or_null!(cx, texture); + return optional_root_object_to_js_or_null!(*cx, texture); }, - constants::TEXTURE_BINDING_CUBE_MAP => { + constants::TEXTURE_BINDING_CUBE_MAP => unsafe { let texture = self .textures .active_texture_slot(constants::TEXTURE_CUBE_MAP) .unwrap() .get(); - return optional_root_object_to_js_or_null!(cx, texture); + return optional_root_object_to_js_or_null!(*cx, texture); }, - OESVertexArrayObjectConstants::VERTEX_ARRAY_BINDING_OES => { + OESVertexArrayObjectConstants::VERTEX_ARRAY_BINDING_OES => unsafe { let vao = self.current_vao.get().filter(|vao| vao.id().is_some()); - return optional_root_object_to_js_or_null!(cx, vao); + return optional_root_object_to_js_or_null!(*cx, vao); }, // In readPixels we currently support RGBA/UBYTE only. If // we wanted to support other formats, we could ask the @@ -1227,27 +1227,27 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { constants::IMPLEMENTATION_COLOR_READ_TYPE => { return Int32Value(constants::UNSIGNED_BYTE as i32); }, - constants::COMPRESSED_TEXTURE_FORMATS => { + constants::COMPRESSED_TEXTURE_FORMATS => unsafe { let format_ids = self.extension_manager.get_tex_compression_ids(); - rooted!(in(cx) let mut rval = ptr::null_mut::<JSObject>()); - let _ = Uint32Array::create(cx, CreateWith::Slice(&format_ids), rval.handle_mut()) + rooted!(in(*cx) let mut rval = ptr::null_mut::<JSObject>()); + let _ = Uint32Array::create(*cx, CreateWith::Slice(&format_ids), rval.handle_mut()) .unwrap(); return ObjectValue(rval.get()); }, - constants::VERSION => { - rooted!(in(cx) let mut rval = UndefinedValue()); - "WebGL 1.0".to_jsval(cx, rval.handle_mut()); + constants::VERSION => unsafe { + rooted!(in(*cx) let mut rval = UndefinedValue()); + "WebGL 1.0".to_jsval(*cx, rval.handle_mut()); return rval.get(); }, - constants::RENDERER | constants::VENDOR => { - rooted!(in(cx) let mut rval = UndefinedValue()); - "Mozilla/Servo".to_jsval(cx, rval.handle_mut()); + constants::RENDERER | constants::VENDOR => unsafe { + rooted!(in(*cx) let mut rval = UndefinedValue()); + "Mozilla/Servo".to_jsval(*cx, rval.handle_mut()); return rval.get(); }, - constants::SHADING_LANGUAGE_VERSION => { - rooted!(in(cx) let mut rval = UndefinedValue()); - "WebGL GLSL ES 1.0".to_jsval(cx, rval.handle_mut()); + constants::SHADING_LANGUAGE_VERSION => unsafe { + rooted!(in(*cx) let mut rval = UndefinedValue()); + "WebGL GLSL ES 1.0".to_jsval(*cx, rval.handle_mut()); return rval.get(); }, constants::UNPACK_FLIP_Y_WEBGL => { @@ -1314,11 +1314,11 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { self.send_command(WebGLCommand::GetParameterBool(param, sender)); BooleanValue(receiver.recv().unwrap()) }, - Parameter::Bool4(param) => { + Parameter::Bool4(param) => unsafe { let (sender, receiver) = webgl_channel().unwrap(); self.send_command(WebGLCommand::GetParameterBool4(param, sender)); - rooted!(in(cx) let mut rval = UndefinedValue()); - receiver.recv().unwrap().to_jsval(cx, rval.handle_mut()); + rooted!(in(*cx) let mut rval = UndefinedValue()); + receiver.recv().unwrap().to_jsval(*cx, rval.handle_mut()); rval.get() }, Parameter::Int(param) => { @@ -1326,24 +1326,24 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { self.send_command(WebGLCommand::GetParameterInt(param, sender)); Int32Value(receiver.recv().unwrap()) }, - Parameter::Int2(param) => { + Parameter::Int2(param) => unsafe { let (sender, receiver) = webgl_channel().unwrap(); self.send_command(WebGLCommand::GetParameterInt2(param, sender)); - rooted!(in(cx) let mut rval = ptr::null_mut::<JSObject>()); + rooted!(in(*cx) let mut rval = ptr::null_mut::<JSObject>()); let _ = Int32Array::create( - cx, + *cx, CreateWith::Slice(&receiver.recv().unwrap()), rval.handle_mut(), ) .unwrap(); ObjectValue(rval.get()) }, - Parameter::Int4(param) => { + Parameter::Int4(param) => unsafe { let (sender, receiver) = webgl_channel().unwrap(); self.send_command(WebGLCommand::GetParameterInt4(param, sender)); - rooted!(in(cx) let mut rval = ptr::null_mut::<JSObject>()); + rooted!(in(*cx) let mut rval = ptr::null_mut::<JSObject>()); let _ = Int32Array::create( - cx, + *cx, CreateWith::Slice(&receiver.recv().unwrap()), rval.handle_mut(), ) @@ -1355,24 +1355,24 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { self.send_command(WebGLCommand::GetParameterFloat(param, sender)); DoubleValue(receiver.recv().unwrap() as f64) }, - Parameter::Float2(param) => { + Parameter::Float2(param) => unsafe { let (sender, receiver) = webgl_channel().unwrap(); self.send_command(WebGLCommand::GetParameterFloat2(param, sender)); - rooted!(in(cx) let mut rval = ptr::null_mut::<JSObject>()); + rooted!(in(*cx) let mut rval = ptr::null_mut::<JSObject>()); let _ = Float32Array::create( - cx, + *cx, CreateWith::Slice(&receiver.recv().unwrap()), rval.handle_mut(), ) .unwrap(); ObjectValue(rval.get()) }, - Parameter::Float4(param) => { + Parameter::Float4(param) => unsafe { let (sender, receiver) = webgl_channel().unwrap(); self.send_command(WebGLCommand::GetParameterFloat4(param, sender)); - rooted!(in(cx) let mut rval = ptr::null_mut::<JSObject>()); + rooted!(in(*cx) let mut rval = ptr::null_mut::<JSObject>()); let _ = Float32Array::create( - cx, + *cx, CreateWith::Slice(&receiver.recv().unwrap()), rval.handle_mut(), ) @@ -1382,9 +1382,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } } - #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.8 - unsafe fn GetTexParameter(&self, _cx: *mut JSContext, target: u32, pname: u32) -> JSVal { + fn GetTexParameter(&self, _cx: SafeJSContext, target: u32, pname: u32) -> JSVal { let texture_slot = handle_potential_webgl_error!( self, self.textures.active_texture_slot(target), @@ -1484,13 +1483,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { ) } - #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.14 - unsafe fn GetExtension( - &self, - _cx: *mut JSContext, - name: DOMString, - ) -> Option<NonNull<JSObject>> { + fn GetExtension(&self, _cx: SafeJSContext, name: DOMString) -> Option<NonNull<JSObject>> { self.extension_manager .init_once(|| self.get_gl_extensions()); self.extension_manager.get_or_init_extension(&name, self) @@ -2326,9 +2320,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 - unsafe fn GetFramebufferAttachmentParameter( + fn GetFramebufferAttachmentParameter( &self, - cx: *mut JSContext, + cx: SafeJSContext, target: u32, attachment: u32, pname: u32, @@ -2411,14 +2405,14 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { let fb = self.bound_framebuffer.get().unwrap(); if let Some(webgl_attachment) = fb.attachment(attachment) { match webgl_attachment { - WebGLFramebufferAttachmentRoot::Renderbuffer(rb) => { - rooted!(in(cx) let mut rval = NullValue()); - rb.to_jsval(cx, rval.handle_mut()); + WebGLFramebufferAttachmentRoot::Renderbuffer(rb) => unsafe { + rooted!(in(*cx) let mut rval = NullValue()); + rb.to_jsval(*cx, rval.handle_mut()); return rval.get(); }, - WebGLFramebufferAttachmentRoot::Texture(texture) => { - rooted!(in(cx) let mut rval = NullValue()); - texture.to_jsval(cx, rval.handle_mut()); + WebGLFramebufferAttachmentRoot::Texture(texture) => unsafe { + rooted!(in(*cx) let mut rval = NullValue()); + texture.to_jsval(*cx, rval.handle_mut()); return rval.get(); }, } @@ -2435,14 +2429,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { Int32Value(receiver.recv().unwrap()) } - #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.7 - unsafe fn GetRenderbufferParameter( - &self, - _cx: *mut JSContext, - target: u32, - pname: u32, - ) -> JSVal { + fn GetRenderbufferParameter(&self, _cx: SafeJSContext, target: u32, pname: u32) -> JSVal { let target_matches = target == constants::RENDERBUFFER; let pname_matches = match pname { @@ -2494,14 +2482,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { } } - #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - unsafe fn GetProgramParameter( - &self, - _: *mut JSContext, - program: &WebGLProgram, - param: u32, - ) -> JSVal { + fn GetProgramParameter(&self, _: SafeJSContext, program: &WebGLProgram, param: u32) -> JSVal { handle_potential_webgl_error!(self, self.validate_ownership(program), return NullValue()); if program.is_deleted() { self.webgl_error(InvalidOperation); @@ -2541,14 +2523,8 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { Some(shader.info_log()) } - #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - unsafe fn GetShaderParameter( - &self, - _: *mut JSContext, - shader: &WebGLShader, - param: u32, - ) -> JSVal { + fn GetShaderParameter(&self, _: SafeJSContext, shader: &WebGLShader, param: u32) -> JSVal { handle_potential_webgl_error!(self, self.validate_ownership(shader), return NullValue()); if shader.is_deleted() { self.webgl_error(InvalidValue); @@ -2620,7 +2596,7 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { #[allow(unsafe_code)] // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.9 - unsafe fn GetVertexAttrib(&self, cx: *mut JSContext, index: u32, param: u32) -> JSVal { + fn GetVertexAttrib(&self, cx: SafeJSContext, index: u32, param: u32) -> JSVal { let current_vao = self.current_vao(); let data = handle_potential_webgl_error!( self, @@ -2636,10 +2612,12 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { self.send_command(WebGLCommand::GetCurrentVertexAttrib(index, sender)); receiver.recv().unwrap() }; - rooted!(in(cx) let mut result = ptr::null_mut::<JSObject>()); - let _ = - Float32Array::create(cx, CreateWith::Slice(&value), result.handle_mut()).unwrap(); - return ObjectValue(result.get()); + unsafe { + rooted!(in(*cx) let mut result = ptr::null_mut::<JSObject>()); + let _ = Float32Array::create(*cx, CreateWith::Slice(&value), result.handle_mut()) + .unwrap(); + return ObjectValue(result.get()); + } } if !self @@ -2656,10 +2634,10 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { constants::VERTEX_ATTRIB_ARRAY_TYPE => Int32Value(data.type_ as i32), constants::VERTEX_ATTRIB_ARRAY_NORMALIZED => BooleanValue(data.normalized), constants::VERTEX_ATTRIB_ARRAY_STRIDE => Int32Value(data.stride as i32), - constants::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING => { - rooted!(in(cx) let mut jsval = NullValue()); + constants::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING => unsafe { + rooted!(in(*cx) let mut jsval = NullValue()); if let Some(buffer) = data.buffer() { - buffer.to_jsval(cx, jsval.handle_mut()); + buffer.to_jsval(*cx, jsval.handle_mut()); } jsval.get() }, @@ -3432,9 +3410,9 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.10 #[allow(unsafe_code)] - unsafe fn GetUniform( + fn GetUniform( &self, - cx: *mut JSContext, + cx: SafeJSContext, program: &WebGLProgram, location: &WebGLUniformLocation, ) -> JSVal { @@ -3477,42 +3455,48 @@ impl WebGLRenderingContextMethods for WebGLRenderingContext { match location.type_() { constants::BOOL => BooleanValue(get(triple, WebGLCommand::GetUniformBool)), - constants::BOOL_VEC2 => { - rooted!(in(cx) let mut rval = NullValue()); - get(triple, WebGLCommand::GetUniformBool2).to_jsval(cx, rval.handle_mut()); + constants::BOOL_VEC2 => unsafe { + rooted!(in(*cx) let mut rval = NullValue()); + get(triple, WebGLCommand::GetUniformBool2).to_jsval(*cx, rval.handle_mut()); rval.get() }, - constants::BOOL_VEC3 => { - rooted!(in(cx) let mut rval = NullValue()); - get(triple, WebGLCommand::GetUniformBool3).to_jsval(cx, rval.handle_mut()); + constants::BOOL_VEC3 => unsafe { + rooted!(in(*cx) let mut rval = NullValue()); + get(triple, WebGLCommand::GetUniformBool3).to_jsval(*cx, rval.handle_mut()); rval.get() }, - constants::BOOL_VEC4 => { - rooted!(in(cx) let mut rval = NullValue()); - get(triple, WebGLCommand::GetUniformBool4).to_jsval(cx, rval.handle_mut()); + constants::BOOL_VEC4 => unsafe { + rooted!(in(*cx) let mut rval = NullValue()); + get(triple, WebGLCommand::GetUniformBool4).to_jsval(*cx, rval.handle_mut()); rval.get() }, constants::INT | constants::SAMPLER_2D | constants::SAMPLER_CUBE => { Int32Value(get(triple, WebGLCommand::GetUniformInt)) }, - constants::INT_VEC2 => typed::<Int32>(cx, &get(triple, WebGLCommand::GetUniformInt2)), - constants::INT_VEC3 => typed::<Int32>(cx, &get(triple, WebGLCommand::GetUniformInt3)), - constants::INT_VEC4 => typed::<Int32>(cx, &get(triple, WebGLCommand::GetUniformInt4)), + constants::INT_VEC2 => unsafe { + typed::<Int32>(*cx, &get(triple, WebGLCommand::GetUniformInt2)) + }, + constants::INT_VEC3 => unsafe { + typed::<Int32>(*cx, &get(triple, WebGLCommand::GetUniformInt3)) + }, + constants::INT_VEC4 => unsafe { + typed::<Int32>(*cx, &get(triple, WebGLCommand::GetUniformInt4)) + }, constants::FLOAT => DoubleValue(get(triple, WebGLCommand::GetUniformFloat) as f64), - constants::FLOAT_VEC2 => { - typed::<Float32>(cx, &get(triple, WebGLCommand::GetUniformFloat2)) + constants::FLOAT_VEC2 => unsafe { + typed::<Float32>(*cx, &get(triple, WebGLCommand::GetUniformFloat2)) }, - constants::FLOAT_VEC3 => { - typed::<Float32>(cx, &get(triple, WebGLCommand::GetUniformFloat3)) + constants::FLOAT_VEC3 => unsafe { + typed::<Float32>(*cx, &get(triple, WebGLCommand::GetUniformFloat3)) }, - constants::FLOAT_VEC4 | constants::FLOAT_MAT2 => { - typed::<Float32>(cx, &get(triple, WebGLCommand::GetUniformFloat4)) + constants::FLOAT_VEC4 | constants::FLOAT_MAT2 => unsafe { + typed::<Float32>(*cx, &get(triple, WebGLCommand::GetUniformFloat4)) }, - constants::FLOAT_MAT3 => { - typed::<Float32>(cx, &get(triple, WebGLCommand::GetUniformFloat9)) + constants::FLOAT_MAT3 => unsafe { + typed::<Float32>(*cx, &get(triple, WebGLCommand::GetUniformFloat9)) }, - constants::FLOAT_MAT4 => { - typed::<Float32>(cx, &get(triple, WebGLCommand::GetUniformFloat16)) + constants::FLOAT_MAT4 => unsafe { + typed::<Float32>(*cx, &get(triple, WebGLCommand::GetUniformFloat16)) }, _ => panic!("wrong uniform type"), } diff --git a/components/script/dom/websocket.rs b/components/script/dom/websocket.rs index 5f783ab5a30..3051cc0ff33 100644 --- a/components/script/dom/websocket.rs +++ b/components/script/dom/websocket.rs @@ -569,26 +569,26 @@ impl TaskOnce for MessageReceivedTask { // global.get_cx() returns a valid `JSContext` pointer, so this is safe. unsafe { let cx = global.get_cx(); - let _ac = JSAutoRealm::new(cx, ws.reflector().get_jsobject().get()); - rooted!(in(cx) let mut message = UndefinedValue()); + let _ac = JSAutoRealm::new(*cx, ws.reflector().get_jsobject().get()); + rooted!(in(*cx) let mut message = UndefinedValue()); match self.message { - MessageData::Text(text) => text.to_jsval(cx, message.handle_mut()), + MessageData::Text(text) => text.to_jsval(*cx, message.handle_mut()), MessageData::Binary(data) => match ws.binary_type.get() { BinaryType::Blob => { let blob = Blob::new(&global, BlobImpl::new_from_bytes(data), "".to_owned()); - blob.to_jsval(cx, message.handle_mut()); + blob.to_jsval(*cx, message.handle_mut()); }, BinaryType::Arraybuffer => { - rooted!(in(cx) let mut array_buffer = ptr::null_mut::<JSObject>()); + rooted!(in(*cx) let mut array_buffer = ptr::null_mut::<JSObject>()); assert!(ArrayBuffer::create( - cx, + *cx, CreateWith::Slice(&data), array_buffer.handle_mut() ) .is_ok()); - (*array_buffer).to_jsval(cx, message.handle_mut()); + (*array_buffer).to_jsval(*cx, message.handle_mut()); }, }, } diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs index 4d1ea5e80d4..ccbd08e1ef7 100644 --- a/components/script/dom/window.rs +++ b/components/script/dom/window.rs @@ -57,7 +57,7 @@ use crate::fetch; use crate::layout_image::fetch_image_for_layout; use crate::microtask::MicrotaskQueue; use crate::script_runtime::{ - CommonScriptMsg, Runtime, ScriptChan, ScriptPort, ScriptThreadEventCategory, + CommonScriptMsg, JSContext, Runtime, ScriptChan, ScriptPort, ScriptThreadEventCategory, }; use crate::script_thread::{ImageCacheMsg, MainThreadScriptChan, MainThreadScriptMsg}; use crate::script_thread::{ScriptThread, SendableMainThreadScriptChan}; @@ -79,7 +79,6 @@ use euclid::{Point2D, Rect, Scale, Size2D, Vector2D}; use ipc_channel::ipc::{channel, IpcSender}; use ipc_channel::router::ROUTER; use js::jsapi::JSAutoRealm; -use js::jsapi::JSContext; use js::jsapi::JSPROP_ENUMERATE; use js::jsapi::{GCReason, JS_GC}; use js::jsval::JSVal; @@ -371,8 +370,9 @@ impl Window { self.globalscope.origin() } - pub fn get_cx(&self) -> *mut JSContext { - self.js_runtime.borrow().as_ref().unwrap().cx() + #[allow(unsafe_code)] + pub fn get_cx(&self) -> JSContext { + unsafe { JSContext::from_ptr(self.js_runtime.borrow().as_ref().unwrap().cx()) } } pub fn main_thread_script_chan(&self) -> &Sender<MainThreadScriptMsg> { @@ -614,26 +614,28 @@ impl WindowMethods for Window { #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-opener - unsafe fn Opener(&self, cx: *mut JSContext) -> JSVal { - self.window_proxy().opener(cx) + fn Opener(&self, cx: JSContext) -> JSVal { + unsafe { self.window_proxy().opener(*cx) } } #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-opener - unsafe fn SetOpener(&self, cx: *mut JSContext, value: HandleValue) { + fn SetOpener(&self, cx: JSContext, value: HandleValue) { // Step 1. if value.is_null() { return self.window_proxy().disown(); } // Step 2. let obj = self.reflector().get_jsobject(); - assert!(JS_DefineProperty( - cx, - obj, - "opener\0".as_ptr() as *const libc::c_char, - value, - JSPROP_ENUMERATE as u32 - )); + unsafe { + assert!(JS_DefineProperty( + *cx, + obj, + "opener\0".as_ptr() as *const libc::c_char, + value, + JSPROP_ENUMERATE as u32 + )); + } } // https://html.spec.whatwg.org/multipage/#dom-window-closed @@ -738,11 +740,10 @@ impl WindowMethods for Window { self.navigator.or_init(|| Navigator::new(self)) } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout - unsafe fn SetTimeout( + fn SetTimeout( &self, - _cx: *mut JSContext, + _cx: JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>, @@ -755,11 +756,10 @@ impl WindowMethods for Window { ) } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout - unsafe fn SetTimeout_( + fn SetTimeout_( &self, - _cx: *mut JSContext, + _cx: JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>, @@ -778,11 +778,10 @@ impl WindowMethods for Window { .clear_timeout_or_interval(handle); } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval - unsafe fn SetInterval( + fn SetInterval( &self, - _cx: *mut JSContext, + _cx: JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>, @@ -795,11 +794,10 @@ impl WindowMethods for Window { ) } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval - unsafe fn SetInterval_( + fn SetInterval_( &self, - _cx: *mut JSContext, + _cx: JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>, @@ -902,14 +900,8 @@ impl WindowMethods for Window { doc.cancel_animation_frame(ident); } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-window-postmessage - unsafe fn PostMessage( - &self, - cx: *mut JSContext, - message: HandleValue, - origin: DOMString, - ) -> ErrorResult { + fn PostMessage(&self, cx: JSContext, message: HandleValue, origin: DOMString) -> ErrorResult { let source_global = GlobalScope::incumbent().expect("no incumbent global??"); let source = source_global.as_window(); @@ -925,7 +917,7 @@ impl WindowMethods for Window { // Step 1-2, 6-8. // TODO(#12717): Should implement the `transfer` argument. - let data = StructuredCloneData::write(cx, message)?; + let data = StructuredCloneData::write(*cx, message)?; // Step 9. self.post_message(origin, &*source.window_proxy(), data); @@ -950,7 +942,7 @@ impl WindowMethods for Window { #[allow(unsafe_code)] fn Gc(&self) { unsafe { - JS_GC(self.get_cx(), GCReason::API); + JS_GC(*self.get_cx(), GCReason::API); } } @@ -960,8 +952,8 @@ impl WindowMethods for Window { } #[allow(unsafe_code)] - unsafe fn WebdriverCallback(&self, cx: *mut JSContext, val: HandleValue) { - let rv = jsval_to_webdriver(cx, val); + fn WebdriverCallback(&self, cx: JSContext, val: HandleValue) { + let rv = unsafe { jsval_to_webdriver(*cx, val) }; let opt_chan = self.webdriver_script_chan.borrow_mut().take(); if let Some(chan) = opt_chan { chan.send(rv).unwrap(); @@ -2179,7 +2171,7 @@ impl Window { player_context, }); - unsafe { WindowBinding::Wrap(runtime.cx(), win) } + unsafe { WindowBinding::Wrap(JSContext::from_ptr(runtime.cx()), win) } } pub fn pipeline_id(&self) -> Option<PipelineId> { @@ -2281,8 +2273,8 @@ impl Window { // Steps 7.2.-7.5. let cx = this.get_cx(); let obj = this.reflector().get_jsobject(); - let _ac = JSAutoRealm::new(cx, obj.get()); - rooted!(in(cx) let mut message_clone = UndefinedValue()); + let _ac = JSAutoRealm::new(*cx, obj.get()); + rooted!(in(*cx) let mut message_clone = UndefinedValue()); serialize_with_transfer_result.read( this.upcast(), message_clone.handle_mut(), diff --git a/components/script/dom/windowproxy.rs b/components/script/dom/windowproxy.rs index d527a73c86f..0c7a00978bc 100644 --- a/components/script/dom/windowproxy.rs +++ b/components/script/dom/windowproxy.rs @@ -152,10 +152,10 @@ impl WindowProxy { ((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0 ); - let _ac = JSAutoRealm::new(cx, window_jsobject.get()); + let _ac = JSAutoRealm::new(*cx, window_jsobject.get()); // Create a new window proxy. - rooted!(in(cx) let js_proxy = NewWindowProxy(cx, window_jsobject, handler)); + rooted!(in(*cx) let js_proxy = NewWindowProxy(*cx, window_jsobject, handler)); assert!(!js_proxy.is_null()); // Create a new browsing context. @@ -178,7 +178,7 @@ impl WindowProxy { ); // Notify the JS engine about the new window proxy binding. - SetWindowProxy(cx, window_jsobject, js_proxy.handle()); + SetWindowProxy(*cx, window_jsobject, js_proxy.handle()); // Set the reflector. debug!( @@ -223,10 +223,10 @@ impl WindowProxy { ((*get_object_class(window_jsobject.get())).flags & JSCLASS_IS_GLOBAL), 0 ); - let _ac = JSAutoRealm::new(cx, window_jsobject.get()); + let _ac = JSAutoRealm::new(*cx, window_jsobject.get()); // Create a new window proxy. - rooted!(in(cx) let js_proxy = NewWindowProxy(cx, window_jsobject, handler)); + rooted!(in(*cx) let js_proxy = NewWindowProxy(*cx, window_jsobject, handler)); assert!(!js_proxy.is_null()); // The window proxy owns the browsing context. @@ -238,7 +238,7 @@ impl WindowProxy { ); // Notify the JS engine about the new window proxy binding. - SetWindowProxy(cx, window_jsobject, js_proxy.handle()); + SetWindowProxy(*cx, window_jsobject, js_proxy.handle()); // Set the reflector. debug!( @@ -576,20 +576,20 @@ impl WindowProxy { // of the old window proxy to the new window proxy, then // making the old window proxy a cross-compartment wrapper // pointing to the new window proxy. - rooted!(in(cx) let new_js_proxy = NewWindowProxy(cx, window_jsobject, handler)); + rooted!(in(*cx) let new_js_proxy = NewWindowProxy(*cx, window_jsobject, handler)); debug!( "Transplanting proxy from {:p} to {:p}.", old_js_proxy.get(), new_js_proxy.get() ); - rooted!(in(cx) let new_js_proxy = JS_TransplantObject(cx, old_js_proxy, new_js_proxy.handle())); + rooted!(in(*cx) let new_js_proxy = JS_TransplantObject(*cx, old_js_proxy, new_js_proxy.handle())); debug!("Transplanted proxy is {:p}.", new_js_proxy.get()); // Transfer ownership of this browsing context from the old window proxy to the new one. SetProxyReservedSlot(new_js_proxy.get(), 0, &PrivateValue(self.as_void_ptr())); // Notify the JS engine about the new window proxy binding. - SetWindowProxy(cx, window_jsobject, new_js_proxy.handle()); + SetWindowProxy(*cx, window_jsobject, new_js_proxy.handle()); // Update the reflector. debug!( diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs index 46288e6947e..1ae17571fbb 100644 --- a/components/script/dom/worker.rs +++ b/components/script/dom/worker.rs @@ -21,12 +21,13 @@ use crate::dom::eventtarget::EventTarget; use crate::dom::globalscope::GlobalScope; use crate::dom::messageevent::MessageEvent; use crate::dom::workerglobalscope::prepare_workerscope_init; +use crate::script_runtime::JSContext; use crate::task::TaskOnce; use crossbeam_channel::{unbounded, Sender}; use devtools_traits::{DevtoolsPageInfo, ScriptToDevtoolsControlMsg}; use dom_struct::dom_struct; use ipc_channel::ipc; -use js::jsapi::{JSContext, JS_RequestInterruptCallback}; +use js::jsapi::JS_RequestInterruptCallback; use js::jsval::UndefinedValue; use js::rust::HandleValue; use script_traits::WorkerScriptLoadOrigin; @@ -146,7 +147,7 @@ impl Worker { let global = worker.global(); let target = worker.upcast(); let _ac = enter_realm(target); - rooted!(in(global.get_cx()) let mut message = UndefinedValue()); + rooted!(in(*global.get_cx()) let mut message = UndefinedValue()); data.read(&global, message.handle_mut()); MessageEvent::dispatch_jsval(target, &global, message.handle(), None, None); } @@ -158,10 +159,9 @@ impl Worker { } impl WorkerMethods for Worker { - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-worker-postmessage - unsafe fn PostMessage(&self, cx: *mut JSContext, message: HandleValue) -> ErrorResult { - let data = StructuredCloneData::write(cx, message)?; + fn PostMessage(&self, cx: JSContext, message: HandleValue) -> ErrorResult { + let data = StructuredCloneData::write(*cx, message)?; let address = Trusted::new(self); // NOTE: step 9 of https://html.spec.whatwg.org/multipage/#dom-messageport-postmessage @@ -186,7 +186,7 @@ impl WorkerMethods for Worker { // Step 3 let cx = self.global().get_cx(); - unsafe { JS_RequestInterruptCallback(cx) }; + unsafe { JS_RequestInterruptCallback(*cx) }; } // https://html.spec.whatwg.org/multipage/#handler-worker-onmessage diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs index 04aabe6db17..2e5a199a08f 100644 --- a/components/script/dom/workerglobalscope.rs +++ b/components/script/dom/workerglobalscope.rs @@ -26,6 +26,7 @@ use crate::dom::window::{base64_atob, base64_btoa}; use crate::dom::workerlocation::WorkerLocation; use crate::dom::workernavigator::WorkerNavigator; use crate::fetch; +use crate::script_runtime::JSContext; use crate::script_runtime::{get_reports, CommonScriptMsg, Runtime, ScriptChan, ScriptPort}; use crate::task::TaskCanceller; use crate::task_source::dom_manipulation::DOMManipulationTaskSource; @@ -39,7 +40,7 @@ use crossbeam_channel::Receiver; use devtools_traits::{DevtoolScriptControlMsg, WorkerId}; use dom_struct::dom_struct; use ipc_channel::ipc::IpcSender; -use js::jsapi::{JSAutoRealm, JSContext}; +use js::jsapi::JSAutoRealm; use js::jsval::UndefinedValue; use js::panic::maybe_resume_unwind; use js::rust::{HandleValue, ParentRuntime}; @@ -164,8 +165,9 @@ impl WorkerGlobalScope { &self.from_devtools_receiver } - pub fn get_cx(&self) -> *mut JSContext { - self.runtime.cx() + #[allow(unsafe_code)] + pub fn get_cx(&self) -> JSContext { + unsafe { JSContext::from_ptr(self.runtime.cx()) } } pub fn is_closing(&self) -> bool { @@ -288,11 +290,10 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { base64_atob(atob) } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout - unsafe fn SetTimeout( + fn SetTimeout( &self, - _cx: *mut JSContext, + _cx: JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>, @@ -305,11 +306,10 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { ) } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-settimeout - unsafe fn SetTimeout_( + fn SetTimeout_( &self, - _cx: *mut JSContext, + _cx: JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>, @@ -328,11 +328,10 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { .clear_timeout_or_interval(handle); } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval - unsafe fn SetInterval( + fn SetInterval( &self, - _cx: *mut JSContext, + _cx: JSContext, callback: Rc<Function>, timeout: i32, args: Vec<HandleValue>, @@ -345,11 +344,10 @@ impl WorkerGlobalScopeMethods for WorkerGlobalScope { ) } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-windowtimers-setinterval - unsafe fn SetInterval_( + fn SetInterval_( &self, - _cx: *mut JSContext, + _cx: JSContext, callback: DOMString, timeout: i32, args: Vec<HandleValue>, @@ -480,7 +478,7 @@ impl WorkerGlobalScope { CommonScriptMsg::CollectReports(reports_chan) => { let cx = self.get_cx(); let path_seg = format!("url({})", self.get_url()); - let reports = get_reports(cx, path_seg); + let reports = get_reports(*cx, path_seg); reports_chan.send(reports); }, } diff --git a/components/script/dom/workletglobalscope.rs b/components/script/dom/workletglobalscope.rs index 20f99c76ee2..90fa5bd0115 100644 --- a/components/script/dom/workletglobalscope.rs +++ b/components/script/dom/workletglobalscope.rs @@ -10,13 +10,13 @@ use crate::dom::paintworkletglobalscope::PaintWorkletTask; use crate::dom::testworkletglobalscope::TestWorkletGlobalScope; use crate::dom::testworkletglobalscope::TestWorkletTask; use crate::dom::worklet::WorkletExecutor; +use crate::script_runtime::JSContext; use crate::script_thread::MainThreadScriptMsg; use crossbeam_channel::Sender; use devtools_traits::ScriptToDevtoolsControlMsg; use dom_struct::dom_struct; use ipc_channel::ipc; use ipc_channel::ipc::IpcSender; -use js::jsapi::JSContext; use js::jsval::UndefinedValue; use js::rust::Runtime; use msg::constellation_msg::PipelineId; @@ -83,14 +83,14 @@ impl WorkletGlobalScope { } /// Get the JS context. - pub fn get_cx(&self) -> *mut JSContext { + pub fn get_cx(&self) -> JSContext { self.globalscope.get_cx() } /// Evaluate a JS script in this global. pub fn evaluate_js(&self, script: &str) -> bool { debug!("Evaluating Dom."); - rooted!(in (self.globalscope.get_cx()) let mut rval = UndefinedValue()); + rooted!(in (*self.globalscope.get_cx()) let mut rval = UndefinedValue()); self.globalscope .evaluate_js_on_global_with_result(&*script, rval.handle_mut()) } diff --git a/components/script/dom/xmldocument.rs b/components/script/dom/xmldocument.rs index aeb088a6c77..73d7eee89c5 100644 --- a/components/script/dom/xmldocument.rs +++ b/components/script/dom/xmldocument.rs @@ -13,8 +13,8 @@ use crate::dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLD use crate::dom::location::Location; use crate::dom::node::Node; use crate::dom::window::Window; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::JSContext; use js::jsapi::JSObject; use mime::Mime; use script_traits::DocumentActivity; @@ -106,13 +106,8 @@ impl XMLDocumentMethods for XMLDocument { self.upcast::<Document>().SupportedPropertyNames() } - #[allow(unsafe_code)] // https://html.spec.whatwg.org/multipage/#dom-tree-accessors:dom-document-nameditem-filter - unsafe fn NamedGetter( - &self, - _cx: *mut JSContext, - name: DOMString, - ) -> Option<NonNull<JSObject>> { + fn NamedGetter(&self, _cx: JSContext, name: DOMString) -> Option<NonNull<JSObject>> { self.upcast::<Document>().NamedGetter(_cx, name) } } diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs index 443a0711815..082973345c9 100644 --- a/components/script/dom/xmlhttprequest.rs +++ b/components/script/dom/xmlhttprequest.rs @@ -38,6 +38,7 @@ use crate::dom::xmlhttprequesteventtarget::XMLHttpRequestEventTarget; use crate::dom::xmlhttprequestupload::XMLHttpRequestUpload; use crate::fetch::FetchCanceller; use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener}; +use crate::script_runtime::JSContext as SafeJSContext; use crate::task_source::networking::NetworkingTaskSource; use crate::task_source::TaskSourceName; use crate::timers::{OneshotTimerCallback, OneshotTimerHandle}; @@ -877,19 +878,19 @@ impl XMLHttpRequestMethods for XMLHttpRequest { #[allow(unsafe_code)] // https://xhr.spec.whatwg.org/#the-response-attribute - unsafe fn Response(&self, cx: *mut JSContext) -> JSVal { - rooted!(in(cx) let mut rval = UndefinedValue()); + fn Response(&self, cx: SafeJSContext) -> JSVal { + rooted!(in(*cx) let mut rval = UndefinedValue()); match self.response_type.get() { - XMLHttpRequestResponseType::_empty | XMLHttpRequestResponseType::Text => { + XMLHttpRequestResponseType::_empty | XMLHttpRequestResponseType::Text => unsafe { let ready_state = self.ready_state.get(); // Step 2 if ready_state == XMLHttpRequestState::Done || ready_state == XMLHttpRequestState::Loading { - self.text_response().to_jsval(cx, rval.handle_mut()); + self.text_response().to_jsval(*cx, rval.handle_mut()); } else { // Step 1 - "".to_jsval(cx, rval.handle_mut()); + "".to_jsval(*cx, rval.handle_mut()); } }, // Step 1 @@ -897,18 +898,20 @@ impl XMLHttpRequestMethods for XMLHttpRequest { return NullValue(); }, // Step 2 - XMLHttpRequestResponseType::Document => { - self.document_response().to_jsval(cx, rval.handle_mut()); + XMLHttpRequestResponseType::Document => unsafe { + self.document_response().to_jsval(*cx, rval.handle_mut()); }, - XMLHttpRequestResponseType::Json => { - self.json_response(cx).to_jsval(cx, rval.handle_mut()); + XMLHttpRequestResponseType::Json => unsafe { + self.json_response(*cx).to_jsval(*cx, rval.handle_mut()); }, - XMLHttpRequestResponseType::Blob => { - self.blob_response().to_jsval(cx, rval.handle_mut()); + XMLHttpRequestResponseType::Blob => unsafe { + self.blob_response().to_jsval(*cx, rval.handle_mut()); }, - XMLHttpRequestResponseType::Arraybuffer => match self.arraybuffer_response(cx) { - Some(js_object) => js_object.to_jsval(cx, rval.handle_mut()), - None => return NullValue(), + XMLHttpRequestResponseType::Arraybuffer => unsafe { + match self.arraybuffer_response(*cx) { + Some(js_object) => js_object.to_jsval(*cx, rval.handle_mut()), + None => return NullValue(), + } }, } rval.get() diff --git a/components/script/dom/xrrigidtransform.rs b/components/script/dom/xrrigidtransform.rs index 887b54f688c..2b09b89e096 100644 --- a/components/script/dom/xrrigidtransform.rs +++ b/components/script/dom/xrrigidtransform.rs @@ -15,9 +15,10 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::vrframedata::create_typed_array; use crate::dom::window::Window; use crate::dom::xrsession::ApiRigidTransform; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; use euclid::{RigidTransform3D, Rotation3D, Vector3D}; -use js::jsapi::{Heap, JSContext, JSObject}; +use js::jsapi::{Heap, JSObject}; use std::ptr::NonNull; #[dom_struct] @@ -118,8 +119,7 @@ impl XRRigidTransformMethods for XRRigidTransform { }) } // https://immersive-web.github.io/webxr/#dom-xrrigidtransform-matrix - #[allow(unsafe_code)] - unsafe fn Matrix(&self, _cx: *mut JSContext) -> NonNull<JSObject> { + fn Matrix(&self, _cx: JSContext) -> NonNull<JSObject> { if self.matrix.get().is_null() { let cx = self.global().get_cx(); // According to the spec all matrices are column-major, diff --git a/components/script/dom/xrview.rs b/components/script/dom/xrview.rs index 807217945a6..04a4a2b66c8 100644 --- a/components/script/dom/xrview.rs +++ b/components/script/dom/xrview.rs @@ -10,8 +10,9 @@ use crate::dom::globalscope::GlobalScope; use crate::dom::vrframedata::create_typed_array; use crate::dom::xrrigidtransform::XRRigidTransform; use crate::dom::xrsession::{cast_transform, ApiViewerPose, XRSession}; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; -use js::jsapi::{Heap, JSContext, JSObject}; +use js::jsapi::{Heap, JSObject}; use std::ptr::NonNull; use webxr_api::View; @@ -39,7 +40,6 @@ impl XRView { } } - #[allow(unsafe_code)] pub fn new<V: Copy>( global: &GlobalScope, session: &XRSession, @@ -65,9 +65,7 @@ impl XRView { // row_major since euclid uses row vectors let proj = view.projection.to_row_major_array(); let cx = global.get_cx(); - unsafe { - create_typed_array(cx, &proj, &ret.proj); - } + create_typed_array(cx, &proj, &ret.proj); ret } @@ -82,9 +80,8 @@ impl XRViewMethods for XRView { self.eye } - #[allow(unsafe_code)] /// https://immersive-web.github.io/webxr/#dom-xrview-projectionmatrix - unsafe fn ProjectionMatrix(&self, _cx: *mut JSContext) -> NonNull<JSObject> { + fn ProjectionMatrix(&self, _cx: JSContext) -> NonNull<JSObject> { NonNull::new(self.proj.get()).unwrap() } diff --git a/components/script/dom/xrviewerpose.rs b/components/script/dom/xrviewerpose.rs index ca47b2de390..8ebabc0781f 100644 --- a/components/script/dom/xrviewerpose.rs +++ b/components/script/dom/xrviewerpose.rs @@ -12,9 +12,10 @@ use crate::dom::xrpose::XRPose; use crate::dom::xrrigidtransform::XRRigidTransform; use crate::dom::xrsession::{cast_transform, ApiViewerPose, XRSession}; use crate::dom::xrview::XRView; +use crate::script_runtime::JSContext; use dom_struct::dom_struct; use js::conversions::ToJSValConvertible; -use js::jsapi::{Heap, JSContext}; +use js::jsapi::Heap; use js::jsval::{JSVal, UndefinedValue}; use webxr_api::Views; @@ -56,10 +57,10 @@ impl XRViewerPose { XRViewerPoseBinding::Wrap, ); + let cx = global.get_cx(); unsafe { - let cx = global.get_cx(); - rooted!(in(cx) let mut jsval = UndefinedValue()); - views.to_jsval(cx, jsval.handle_mut()); + rooted!(in(*cx) let mut jsval = UndefinedValue()); + views.to_jsval(*cx, jsval.handle_mut()); pose.views.set(jsval.get()); } @@ -69,8 +70,7 @@ impl XRViewerPose { impl XRViewerPoseMethods for XRViewerPose { /// https://immersive-web.github.io/webxr/#dom-xrviewerpose-views - #[allow(unsafe_code)] - unsafe fn Views(&self, _cx: *mut JSContext) -> JSVal { + fn Views(&self, _cx: JSContext) -> JSVal { self.views.get() } } diff --git a/components/script/dom/xrwebgllayer.rs b/components/script/dom/xrwebgllayer.rs index a5f06df0e52..148d773fe6f 100644 --- a/components/script/dom/xrwebgllayer.rs +++ b/components/script/dom/xrwebgllayer.rs @@ -115,7 +115,7 @@ impl XRWebGLLayer { 0, constants::RGBA, constants::UNSIGNED_BYTE, - pixels.root(cx), + pixels.root(*cx), ); // Bind the new texture to the framebuffer diff --git a/components/script/script_runtime.rs b/components/script/script_runtime.rs index b5119949193..fb94d30fafd 100644 --- a/components/script/script_runtime.rs +++ b/components/script/script_runtime.rs @@ -29,7 +29,7 @@ use js::glue::{CollectServoSizes, CreateJobQueue, DeleteJobQueue, JobQueueTraps, use js::jsapi::ContextOptionsRef; use js::jsapi::{BuildIdCharVector, DisableIncrementalGC, GCDescription, GCProgress}; use js::jsapi::{HandleObject, Heap, JobQueue}; -use js::jsapi::{JSContext, JSTracer, SetDOMCallbacks, SetGCSliceCallback}; +use js::jsapi::{JSContext as RawJSContext, JSTracer, SetDOMCallbacks, SetGCSliceCallback}; use js::jsapi::{JSGCInvocationKind, JSGCStatus, JS_AddExtraGCRootsTracer, JS_SetGCCallback}; use js::jsapi::{JSGCMode, JSGCParamKey, JS_SetGCParameter, JS_SetGlobalJitCompilerOption}; use js::jsapi::{ @@ -139,7 +139,7 @@ pub trait ScriptPort { } #[allow(unsafe_code)] -unsafe extern "C" fn get_incumbent_global(_: *const c_void, _: *mut JSContext) -> *mut JSObject { +unsafe extern "C" fn get_incumbent_global(_: *const c_void, _: *mut RawJSContext) -> *mut JSObject { wrap_panic( AssertUnwindSafe(|| { GlobalScope::incumbent() @@ -166,7 +166,7 @@ unsafe extern "C" fn empty(extra: *const c_void) -> bool { #[allow(unsafe_code)] unsafe extern "C" fn enqueue_promise_job( extra: *const c_void, - cx: *mut JSContext, + cx: *mut RawJSContext, _promise: HandleObject, job: HandleObject, _allocation_site: HandleObject, @@ -179,7 +179,7 @@ unsafe extern "C" fn enqueue_promise_job( let pipeline = global.pipeline_id(); microtask_queue.enqueue( Microtask::Promise(EnqueuedPromiseCallback { - callback: PromiseJobCallback::new(cx, job.get()), + callback: PromiseJobCallback::new(JSContext::from_ptr(cx), job.get()), pipeline, }), cx, @@ -193,7 +193,7 @@ unsafe extern "C" fn enqueue_promise_job( #[allow(unsafe_code, unrooted_must_root)] /// https://html.spec.whatwg.org/multipage/#the-hostpromiserejectiontracker-implementation unsafe extern "C" fn promise_rejection_tracker( - cx: *mut JSContext, + cx: *mut RawJSContext, promise: HandleObject, state: PromiseRejectionHandlingState, _data: *mut c_void, @@ -245,7 +245,7 @@ unsafe extern "C" fn promise_rejection_tracker( let cx = target.global().get_cx(); let root_promise = trusted_promise.root(); - rooted!(in(cx) let reason = GetPromiseResult(root_promise.reflector().get_jsobject())); + rooted!(in(*cx) let reason = GetPromiseResult(root_promise.reflector().get_jsobject())); let event = PromiseRejectionEvent::new( &target.global(), @@ -270,9 +270,8 @@ unsafe extern "C" fn promise_rejection_tracker( #[allow(unsafe_code, unrooted_must_root)] /// https://html.spec.whatwg.org/multipage/#notify-about-rejected-promises pub fn notify_about_rejected_promises(global: &GlobalScope) { + let cx = global.get_cx(); unsafe { - let cx = global.get_cx(); - // Step 2. if global.get_uncaught_rejections().borrow().len() > 0 { // Step 1. @@ -282,7 +281,7 @@ pub fn notify_about_rejected_promises(global: &GlobalScope) { .iter() .map(|promise| { let promise = - Promise::new_with_js_promise(Handle::from_raw(promise.handle()), cx); + Promise::new_with_js_promise(Handle::from_raw(promise.handle()), *cx); TrustedPromise::new(promise) }) @@ -309,7 +308,7 @@ pub fn notify_about_rejected_promises(global: &GlobalScope) { } // Step 4-2. - rooted!(in(cx) let reason = GetPromiseResult(promise.reflector().get_jsobject())); + rooted!(in(*cx) let reason = GetPromiseResult(promise.reflector().get_jsobject())); let event = PromiseRejectionEvent::new( &target.global(), @@ -401,7 +400,7 @@ unsafe fn new_rt_and_cx_with_parent(parent: Option<ParentRuntime>) -> Runtime { SetGCSliceCallback(cx, Some(gc_slice_callback)); } - unsafe extern "C" fn empty_wrapper_callback(_: *mut JSContext, _: HandleObject) -> bool { + unsafe extern "C" fn empty_wrapper_callback(_: *mut RawJSContext, _: HandleObject) -> bool { true } SetDOMCallbacks(cx, &DOM_CALLBACKS); @@ -589,7 +588,7 @@ unsafe extern "C" fn get_size(obj: *mut JSObject) -> usize { } #[allow(unsafe_code)] -pub fn get_reports(cx: *mut JSContext, path_seg: String) -> Vec<Report> { +pub fn get_reports(cx: *mut RawJSContext, path_seg: String) -> Vec<Report> { let mut reports = vec![]; unsafe { @@ -655,7 +654,7 @@ thread_local!(static GC_SLICE_START: Cell<Option<Tm>> = Cell::new(None)); #[allow(unsafe_code)] unsafe extern "C" fn gc_slice_callback( - _cx: *mut JSContext, + _cx: *mut RawJSContext, progress: GCProgress, desc: *const GCDescription, ) { @@ -695,7 +694,7 @@ unsafe extern "C" fn gc_slice_callback( #[allow(unsafe_code)] unsafe extern "C" fn debug_gc_callback( - _cx: *mut JSContext, + _cx: *mut RawJSContext, status: JSGCStatus, _data: *mut os::raw::c_void, ) { @@ -731,7 +730,7 @@ unsafe extern "C" fn servo_build_id(build_id: *mut BuildIdCharVector) -> bool { #[allow(unsafe_code)] #[cfg(feature = "debugmozjs")] -unsafe fn set_gc_zeal_options(cx: *mut JSContext) { +unsafe fn set_gc_zeal_options(cx: *mut RawJSContext) { use js::jsapi::{JS_SetGCZeal, JS_DEFAULT_ZEAL_FREQ}; let level = match pref!(js.mem.gc.zeal.level) { @@ -747,4 +746,23 @@ unsafe fn set_gc_zeal_options(cx: *mut JSContext) { #[allow(unsafe_code)] #[cfg(not(feature = "debugmozjs"))] -unsafe fn set_gc_zeal_options(_: *mut JSContext) {} +unsafe fn set_gc_zeal_options(_: *mut RawJSContext) {} + +#[derive(Clone, Copy)] +pub struct JSContext(*mut RawJSContext); + +#[allow(unsafe_code)] +impl JSContext { + pub unsafe fn from_ptr(raw_js_context: *mut RawJSContext) -> Self { + JSContext(raw_js_context) + } +} + +#[allow(unsafe_code)] +impl Deref for JSContext { + type Target = *mut RawJSContext; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs index 0ceed35db57..81ef7d9493c 100644 --- a/components/script/script_thread.rs +++ b/components/script/script_thread.rs @@ -70,7 +70,7 @@ use crate::dom::worklet::WorkletThreadPool; use crate::dom::workletglobalscope::WorkletGlobalScopeInit; use crate::fetch::FetchCanceller; use crate::microtask::{Microtask, MicrotaskQueue}; -use crate::script_runtime::{get_reports, new_rt_and_cx, Runtime, ScriptPort}; +use crate::script_runtime::{get_reports, new_rt_and_cx, JSContext, Runtime, ScriptPort}; use crate::script_runtime::{CommonScriptMsg, ScriptChan, ScriptThreadEventCategory}; use crate::serviceworkerjob::{Job, JobQueue}; use crate::task_manager::TaskManager; @@ -102,7 +102,7 @@ use hyper_serde::Serde; use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; use js::glue::GetWindowProxyClass; -use js::jsapi::{JSContext, JS_SetWrapObjectCallbacks}; +use js::jsapi::JS_SetWrapObjectCallbacks; use js::jsapi::{JSTracer, SetWindowProxyClass}; use js::jsval::UndefinedValue; use js::rust::ParentRuntime; @@ -915,7 +915,7 @@ impl ScriptThread { let script_thread = &*script_thread; script_thread .microtask_queue - .enqueue(task, script_thread.get_cx()); + .enqueue(task, *script_thread.get_cx()); } } }); @@ -1317,8 +1317,9 @@ impl ScriptThread { } } - pub fn get_cx(&self) -> *mut JSContext { - self.js_runtime.cx() + #[allow(unsafe_code)] + pub fn get_cx(&self) -> JSContext { + unsafe { JSContext::from_ptr(self.js_runtime.cx()) } } /// Starts the script thread. After calling this method, the script thread will loop receiving @@ -2349,7 +2350,7 @@ impl ScriptThread { let path_seg = format!("url({})", urls); let mut reports = vec![]; - reports.extend(get_reports(self.get_cx(), path_seg)); + reports.extend(get_reports(*self.get_cx(), path_seg)); reports_chan.send(reports); } @@ -3540,13 +3541,13 @@ impl ScriptThread { // Script source is ready to be evaluated (11.) let _ac = enter_realm(global_scope); - rooted!(in(global_scope.get_cx()) let mut jsval = UndefinedValue()); + rooted!(in(*global_scope.get_cx()) let mut jsval = UndefinedValue()); global_scope.evaluate_js_on_global_with_result(&script_source, jsval.handle_mut()); load_data.js_eval_result = if jsval.get().is_string() { unsafe { let strval = DOMString::from_jsval( - global_scope.get_cx(), + *global_scope.get_cx(), jsval.handle(), StringificationBehavior::Empty, ); @@ -3776,7 +3777,7 @@ impl ScriptThread { let script_thread = &*root.get().unwrap(); script_thread .microtask_queue - .enqueue(job, script_thread.get_cx()); + .enqueue(job, *script_thread.get_cx()); }); } @@ -3791,7 +3792,7 @@ impl ScriptThread { unsafe { self.microtask_queue.checkpoint( - self.get_cx(), + *self.get_cx(), |id| self.documents.borrow().find_global(id), globals, ) diff --git a/components/script/timers.rs b/components/script/timers.rs index 45c809394a1..5534df60d45 100644 --- a/components/script/timers.rs +++ b/components/script/timers.rs @@ -517,7 +517,7 @@ impl JsTimerTask { InternalTimerCallback::StringTimerCallback(ref code_str) => { let global = this.global(); let cx = global.get_cx(); - rooted!(in(cx) let mut rval = UndefinedValue()); + rooted!(in(*cx) let mut rval = UndefinedValue()); global.evaluate_js_on_global_with_result(code_str, rval.handle_mut()); }, diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs index ab08c0efe7d..c8aad9a6b4c 100644 --- a/components/script/webdriver_handlers.rs +++ b/components/script/webdriver_handlers.rs @@ -145,11 +145,11 @@ pub fn handle_execute_script( Some(window) => { let result = unsafe { let cx = window.get_cx(); - rooted!(in(cx) let mut rval = UndefinedValue()); + rooted!(in(*cx) let mut rval = UndefinedValue()); window .upcast::<GlobalScope>() .evaluate_js_on_global_with_result(&eval, rval.handle_mut()); - jsval_to_webdriver(cx, rval.handle()) + jsval_to_webdriver(*cx, rval.handle()) }; reply.send(result).unwrap(); @@ -171,7 +171,7 @@ pub fn handle_execute_async_script( Some(window) => { let cx = window.get_cx(); window.set_webdriver_script_chan(Some(reply)); - rooted!(in(cx) let mut rval = UndefinedValue()); + rooted!(in(*cx) let mut rval = UndefinedValue()); window .upcast::<GlobalScope>() .evaluate_js_on_global_with_result(&eval, rval.handle_mut()); @@ -725,21 +725,21 @@ pub fn handle_get_property( Some(node) => { let cx = documents.find_document(pipeline).unwrap().window().get_cx(); - rooted!(in(cx) let mut property = UndefinedValue()); + rooted!(in(*cx) let mut property = UndefinedValue()); match unsafe { get_property_jsval( - cx, + *cx, node.reflector().get_jsobject(), &name, property.handle_mut(), ) } { - Ok(_) => match unsafe { jsval_to_webdriver(cx, property.handle()) } { + Ok(_) => match unsafe { jsval_to_webdriver(*cx, property.handle()) } { Ok(property) => Ok(property), Err(_) => Ok(WebDriverJSValue::Undefined), }, Err(error) => { - unsafe { throw_dom_exception(cx, &node.reflector().global(), error) }; + unsafe { throw_dom_exception(*cx, &node.reflector().global(), error) }; Ok(WebDriverJSValue::Undefined) }, } |