script: further use of safe to jsval (#38099)

Remove size bound from safe to jsval trait, apply to script/dom, with
the exception of windowproxy.

Second part of https://github.com/servo/servo/issues/37951

Signed-off-by: gterzian <2792687+gterzian@users.noreply.github.com>

*Describe the changes that this pull request makes here. This will be
the commit message.*

Testing: *Describe how this pull request is tested or why it doesn't
require tests*
Fixes: *Link to an issue this pull requests fixes or remove this line if
there is no issue*
This commit is contained in:
Gregory Terzian 2025-07-16 21:46:10 +07:00 committed by GitHub
parent 72a9f36c43
commit b821377771
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 114 additions and 128 deletions

View file

@ -16,13 +16,12 @@ use js::jsval::UndefinedValue;
use js::rust::wrappers::{JS_ErrorFromException, JS_GetPendingException, JS_SetPendingException}; use js::rust::wrappers::{JS_ErrorFromException, JS_GetPendingException, JS_SetPendingException};
use js::rust::{HandleObject, HandleValue, MutableHandleValue}; use js::rust::{HandleObject, HandleValue, MutableHandleValue};
use libc::c_uint; use libc::c_uint;
use script_bindings::conversions::SafeToJSValConvertible;
pub(crate) use script_bindings::error::*; pub(crate) use script_bindings::error::*;
#[cfg(feature = "js_backtrace")] #[cfg(feature = "js_backtrace")]
use crate::dom::bindings::cell::DomRefCell; use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::conversions::{ use crate::dom::bindings::conversions::{ConversionResult, FromJSValConvertible, root_from_object};
ConversionResult, FromJSValConvertible, ToJSValConvertible, root_from_object,
};
use crate::dom::bindings::str::USVString; use crate::dom::bindings::str::USVString;
use crate::dom::domexception::{DOMErrorName, DOMException}; use crate::dom::domexception::{DOMErrorName, DOMException};
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
@ -80,7 +79,7 @@ pub(crate) fn throw_dom_exception(
can_gc, can_gc,
); );
rooted!(in(*cx) let mut thrown = UndefinedValue()); rooted!(in(*cx) let mut thrown = UndefinedValue());
exception.to_jsval(*cx, thrown.handle_mut()); exception.safe_to_jsval(cx, thrown.handle_mut());
JS_SetPendingException(*cx, thrown.handle(), ExceptionStackBehavior::Capture); JS_SetPendingException(*cx, thrown.handle(), ExceptionStackBehavior::Capture);
return; return;
}, },
@ -119,7 +118,7 @@ pub(crate) fn throw_dom_exception(
assert!(!JS_IsExceptionPending(*cx)); assert!(!JS_IsExceptionPending(*cx));
let exception = DOMException::new(global, code, can_gc); let exception = DOMException::new(global, code, can_gc);
rooted!(in(*cx) let mut thrown = UndefinedValue()); rooted!(in(*cx) let mut thrown = UndefinedValue());
exception.to_jsval(*cx, thrown.handle_mut()); exception.safe_to_jsval(cx, thrown.handle_mut());
JS_SetPendingException(*cx, thrown.handle(), ExceptionStackBehavior::Capture); JS_SetPendingException(*cx, thrown.handle(), ExceptionStackBehavior::Capture);
} }
} }

View file

@ -32,10 +32,10 @@ use js::jsapi::{
use js::jsval::UndefinedValue; use js::jsval::UndefinedValue;
use js::rust::wrappers::{JS_ReadStructuredClone, JS_WriteStructuredClone}; use js::rust::wrappers::{JS_ReadStructuredClone, JS_WriteStructuredClone};
use js::rust::{CustomAutoRooterGuard, HandleValue, MutableHandleValue}; use js::rust::{CustomAutoRooterGuard, HandleValue, MutableHandleValue};
use script_bindings::conversions::IDLInterface; use script_bindings::conversions::{IDLInterface, SafeToJSValConvertible};
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::dom::bindings::conversions::{ToJSValConvertible, root_from_object}; use crate::dom::bindings::conversions::root_from_object;
use crate::dom::bindings::error::{Error, Fallible}; use crate::dom::bindings::error::{Error, Fallible};
use crate::dom::bindings::root::DomRoot; use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::serializable::{Serializable, StorageKey}; use crate::dom::bindings::serializable::{Serializable, StorageKey};
@ -594,7 +594,7 @@ pub(crate) fn write(
unsafe { unsafe {
rooted!(in(*cx) let mut val = UndefinedValue()); rooted!(in(*cx) let mut val = UndefinedValue());
if let Some(transfer) = transfer { if let Some(transfer) = transfer {
transfer.to_jsval(*cx, val.handle_mut()); transfer.safe_to_jsval(cx, val.handle_mut());
} }
let mut sc_writer = StructuredDataWriter::default(); let mut sc_writer = StructuredDataWriter::default();
let sc_writer_ptr = &mut sc_writer as *mut _; let sc_writer_ptr = &mut sc_writer as *mut _;

View file

@ -13,6 +13,7 @@ use js::jsapi::{
CallArgs, DOMCallbacks, HandleObject as RawHandleObject, JS_FreezeObject, JSContext, JSObject, CallArgs, DOMCallbacks, HandleObject as RawHandleObject, JS_FreezeObject, JSContext, JSObject,
}; };
use js::rust::{HandleObject, MutableHandleValue, get_object_class, is_dom_class}; use js::rust::{HandleObject, MutableHandleValue, get_object_class, is_dom_class};
use script_bindings::conversions::SafeToJSValConvertible;
use script_bindings::interfaces::{DomHelpers, Interface}; use script_bindings::interfaces::{DomHelpers, Interface};
use script_bindings::settings_stack::StackEntry; use script_bindings::settings_stack::StackEntry;
@ -59,7 +60,7 @@ pub(crate) fn to_frozen_array<T: ToJSValConvertible>(
mut rval: MutableHandleValue, mut rval: MutableHandleValue,
_can_gc: CanGc, _can_gc: CanGc,
) { ) {
unsafe { convertibles.to_jsval(*cx, rval.reborrow()) }; convertibles.safe_to_jsval(cx, rval.reborrow());
rooted!(in(*cx) let obj = rval.to_object()); rooted!(in(*cx) let obj = rval.to_object());
unsafe { JS_FreezeObject(*cx, RawHandleObject::from(obj.handle())) }; unsafe { JS_FreezeObject(*cx, RawHandleObject::from(obj.handle())) };

View file

@ -8,7 +8,6 @@ use std::iter::repeat;
use constellation_traits::StructuredSerializedData; use constellation_traits::StructuredSerializedData;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use ipc_channel::router::ROUTER; use ipc_channel::router::ROUTER;
use js::conversions::ToJSValConvertible;
use js::gc::MutableHandle; use js::gc::MutableHandle;
use js::jsapi::Heap; use js::jsapi::Heap;
use js::jsval::{DoubleValue, JSVal, UndefinedValue}; use js::jsval::{DoubleValue, JSVal, UndefinedValue};
@ -18,6 +17,7 @@ use net_traits::indexeddb_thread::{
AsyncOperation, IdbResult, IndexedDBKeyType, IndexedDBThreadMsg, IndexedDBTxnMode, AsyncOperation, IdbResult, IndexedDBKeyType, IndexedDBThreadMsg, IndexedDBTxnMode,
}; };
use profile_traits::ipc; use profile_traits::ipc;
use script_bindings::conversions::SafeToJSValConvertible;
use stylo_atoms::Atom; use stylo_atoms::Atom;
use crate::dom::bindings::codegen::Bindings::IDBRequestBinding::{ use crate::dom::bindings::codegen::Bindings::IDBRequestBinding::{
@ -48,22 +48,22 @@ struct RequestListener {
fn key_type_to_jsval(cx: SafeJSContext, key: &IndexedDBKeyType, mut result: MutableHandleValue) { fn key_type_to_jsval(cx: SafeJSContext, key: &IndexedDBKeyType, mut result: MutableHandleValue) {
match key { match key {
IndexedDBKeyType::Number(n) => result.set(DoubleValue(*n)), IndexedDBKeyType::Number(n) => result.set(DoubleValue(*n)),
IndexedDBKeyType::String(s) => unsafe { s.to_jsval(*cx, result) }, IndexedDBKeyType::String(s) => s.safe_to_jsval(cx, result),
IndexedDBKeyType::Binary(b) => unsafe { b.to_jsval(*cx, result) }, IndexedDBKeyType::Binary(b) => b.safe_to_jsval(cx, result),
IndexedDBKeyType::Date(_d) => { IndexedDBKeyType::Date(_d) => {
// TODO: implement this when Date's representation is finalized. // TODO: implement this when Date's representation is finalized.
result.set(UndefinedValue()); result.set(UndefinedValue());
}, },
IndexedDBKeyType::Array(a) => unsafe { IndexedDBKeyType::Array(a) => {
rooted_vec!(let mut values <- repeat(UndefinedValue()).take(a.len())); rooted_vec!(let mut values <- repeat(UndefinedValue()).take(a.len()));
for (key, value) in a.iter().zip( for (key, value) in a.iter().zip(unsafe {
values values
.iter_mut() .iter_mut()
.map(|v| MutableHandle::from_marked_location(v)), .map(|v| MutableHandle::from_marked_location(v))
) { }) {
key_type_to_jsval(cx, key, value); key_type_to_jsval(cx, key, value);
} }
values.to_jsval(*cx, result); values.safe_to_jsval(cx, result);
}, },
} }
} }

View file

@ -13,6 +13,7 @@ use dom_struct::dom_struct;
use js::jsapi::{Heap, JS_NewObject, JSObject}; use js::jsapi::{Heap, JS_NewObject, JSObject};
use js::jsval::UndefinedValue; use js::jsval::UndefinedValue;
use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue}; use js::rust::{CustomAutoRooter, CustomAutoRooterGuard, HandleValue};
use script_bindings::conversions::SafeToJSValConvertible;
use crate::dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull; use crate::dom::bindings::codegen::Bindings::EventHandlerBinding::EventHandlerNonNull;
use crate::dom::bindings::codegen::Bindings::MessagePortBinding::{ use crate::dom::bindings::codegen::Bindings::MessagePortBinding::{
@ -29,7 +30,6 @@ use crate::dom::bindings::transferable::Transferable;
use crate::dom::bindings::utils::set_dictionary_property; use crate::dom::bindings::utils::set_dictionary_property;
use crate::dom::eventtarget::EventTarget; use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope; use crate::dom::globalscope::GlobalScope;
use crate::js::conversions::ToJSValConvertible;
use crate::script_runtime::{CanGc, JSContext as SafeJSContext}; use crate::script_runtime::{CanGc, JSContext as SafeJSContext};
#[dom_struct] #[dom_struct]
@ -219,9 +219,7 @@ impl MessagePort {
// Let message be OrdinaryObjectCreate(null). // Let message be OrdinaryObjectCreate(null).
rooted!(in(*cx) let mut message = unsafe { JS_NewObject(*cx, ptr::null()) }); rooted!(in(*cx) let mut message = unsafe { JS_NewObject(*cx, ptr::null()) });
rooted!(in(*cx) let mut type_string = UndefinedValue()); rooted!(in(*cx) let mut type_string = UndefinedValue());
unsafe { type_.safe_to_jsval(cx, type_string.handle_mut());
type_.to_jsval(*cx, type_string.handle_mut());
}
// Perform ! CreateDataProperty(message, "type", type). // Perform ! CreateDataProperty(message, "type", type).
unsafe { unsafe {
@ -244,9 +242,7 @@ impl MessagePort {
// Run the message port post message steps providing targetPort, message, and options. // Run the message port post message steps providing targetPort, message, and options.
rooted!(in(*cx) let mut message_val = UndefinedValue()); rooted!(in(*cx) let mut message_val = UndefinedValue());
unsafe { message.safe_to_jsval(cx, message_val.handle_mut());
message.to_jsval(*cx, message_val.handle_mut());
}
self.post_message_impl(cx, message_val.handle(), transfer) self.post_message_impl(cx, message_val.handle(), transfer)
} }
} }

View file

@ -7,6 +7,7 @@ use dom_struct::dom_struct;
use html5ever::{LocalName, Namespace, QualName, local_name, ns}; use html5ever::{LocalName, Namespace, QualName, local_name, ns};
use js::jsval::NullValue; use js::jsval::NullValue;
use js::rust::HandleValue; use js::rust::HandleValue;
use script_bindings::conversions::SafeToJSValConvertible;
use crate::dom::bindings::codegen::Bindings::TrustedTypePolicyFactoryBinding::{ use crate::dom::bindings::codegen::Bindings::TrustedTypePolicyFactoryBinding::{
TrustedTypePolicyFactoryMethods, TrustedTypePolicyOptions, TrustedTypePolicyFactoryMethods, TrustedTypePolicyOptions,
@ -22,7 +23,6 @@ use crate::dom::trustedhtml::TrustedHTML;
use crate::dom::trustedscript::TrustedScript; use crate::dom::trustedscript::TrustedScript;
use crate::dom::trustedscripturl::TrustedScriptURL; use crate::dom::trustedscripturl::TrustedScriptURL;
use crate::dom::trustedtypepolicy::{TrustedType, TrustedTypePolicy}; use crate::dom::trustedtypepolicy::{TrustedType, TrustedTypePolicy};
use crate::js::conversions::ToJSValConvertible;
use crate::script_runtime::{CanGc, JSContext}; use crate::script_runtime::{CanGc, JSContext};
#[dom_struct] #[dom_struct]
@ -137,7 +137,6 @@ impl TrustedTypePolicyFactory {
data data
} }
/// <https://w3c.github.io/trusted-types/dist/spec/#process-value-with-a-default-policy-algorithm> /// <https://w3c.github.io/trusted-types/dist/spec/#process-value-with-a-default-policy-algorithm>
#[allow(unsafe_code)]
pub(crate) fn process_value_with_default_policy( pub(crate) fn process_value_with_default_policy(
expected_type: TrustedType, expected_type: TrustedType,
global: &GlobalScope, global: &GlobalScope,
@ -155,15 +154,11 @@ impl TrustedTypePolicyFactory {
// Step 2: Let policyValue be the result of executing Get Trusted Type policy value, // Step 2: Let policyValue be the result of executing Get Trusted Type policy value,
// with the following arguments: // with the following arguments:
rooted!(in(*cx) let mut trusted_type_name_value = NullValue()); rooted!(in(*cx) let mut trusted_type_name_value = NullValue());
unsafe {
let trusted_type_name: &'static str = expected_type.clone().into(); let trusted_type_name: &'static str = expected_type.clone().into();
trusted_type_name.to_jsval(*cx, trusted_type_name_value.handle_mut()); trusted_type_name.safe_to_jsval(cx, trusted_type_name_value.handle_mut());
}
rooted!(in(*cx) let mut sink_value = NullValue()); rooted!(in(*cx) let mut sink_value = NullValue());
unsafe { sink.safe_to_jsval(cx, sink_value.handle_mut());
sink.to_jsval(*cx, sink_value.handle_mut());
}
let arguments = vec![trusted_type_name_value.handle(), sink_value.handle()]; let arguments = vec![trusted_type_name_value.handle(), sink_value.handle()];
let policy_value = default_policy.get_trusted_type_policy_value( let policy_value = default_policy.get_trusted_type_policy_value(

View file

@ -22,6 +22,7 @@ use js::jsval::{BooleanValue, DoubleValue, Int32Value, NullValue, ObjectValue, U
use js::rust::{CustomAutoRooterGuard, HandleObject, MutableHandleValue}; use js::rust::{CustomAutoRooterGuard, HandleObject, MutableHandleValue};
use js::typedarray::{ArrayBufferView, CreateWith, Float32, Int32Array, Uint32, Uint32Array}; use js::typedarray::{ArrayBufferView, CreateWith, Float32, Int32Array, Uint32, Uint32Array};
use pixels::{Alpha, Snapshot}; use pixels::{Alpha, Snapshot};
use script_bindings::conversions::SafeToJSValConvertible;
use script_bindings::interfaces::WebGL2RenderingContextHelpers; use script_bindings::interfaces::WebGL2RenderingContextHelpers;
use servo_config::pref; use servo_config::pref;
use url::Host; use url::Host;
@ -72,7 +73,6 @@ use crate::dom::webgltransformfeedback::WebGLTransformFeedback;
use crate::dom::webgluniformlocation::WebGLUniformLocation; use crate::dom::webgluniformlocation::WebGLUniformLocation;
use crate::dom::webglvertexarrayobject::WebGLVertexArrayObject; use crate::dom::webglvertexarrayobject::WebGLVertexArrayObject;
use crate::dom::window::Window; use crate::dom::window::Window;
use crate::js::conversions::ToJSValConvertible;
use crate::script_runtime::{CanGc, JSContext}; use crate::script_runtime::{CanGc, JSContext};
#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)] #[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
@ -647,7 +647,6 @@ impl WebGL2RenderingContext {
Ok(()) Ok(())
} }
#[allow(unsafe_code)]
fn get_specific_fb_attachment_param( fn get_specific_fb_attachment_param(
&self, &self,
cx: JSContext, cx: JSContext,
@ -692,11 +691,11 @@ impl WebGL2RenderingContext {
if pname == constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME { if pname == constants::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME {
match fb.attachment(attachment) { match fb.attachment(attachment) {
Some(Renderbuffer(rb)) => unsafe { Some(Renderbuffer(rb)) => {
rb.to_jsval(*cx, rval); rb.safe_to_jsval(cx, rval);
}, },
Some(Texture(texture)) => unsafe { Some(Texture(texture)) => {
texture.to_jsval(*cx, rval); texture.safe_to_jsval(cx, rval);
}, },
_ => rval.set(NullValue()), _ => rval.set(NullValue()),
} }
@ -1033,16 +1032,15 @@ impl WebGL2RenderingContextMethods<crate::DomTypeHolder> for WebGL2RenderingCont
self.base.get_buffer_param(buffer, parameter, retval) self.base.get_buffer_param(buffer, parameter, retval)
} }
#[allow(unsafe_code)]
/// <https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3> /// <https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.3>
fn GetParameter(&self, cx: JSContext, parameter: u32, mut rval: MutableHandleValue) { fn GetParameter(&self, cx: JSContext, parameter: u32, mut rval: MutableHandleValue) {
match parameter { match parameter {
constants::VERSION => unsafe { constants::VERSION => {
"WebGL 2.0".to_jsval(*cx, rval); "WebGL 2.0".safe_to_jsval(cx, rval);
return; return;
}, },
constants::SHADING_LANGUAGE_VERSION => unsafe { constants::SHADING_LANGUAGE_VERSION => {
"WebGL GLSL ES 3.00".to_jsval(*cx, rval); "WebGL GLSL ES 3.00".safe_to_jsval(cx, rval);
return; return;
}, },
constants::MAX_CLIENT_WAIT_TIMEOUT_WEBGL => { constants::MAX_CLIENT_WAIT_TIMEOUT_WEBGL => {
@ -1057,60 +1055,62 @@ impl WebGL2RenderingContextMethods<crate::DomTypeHolder> for WebGL2RenderingCont
)); ));
return; return;
}, },
constants::SAMPLER_BINDING => unsafe { constants::SAMPLER_BINDING => {
let idx = (self.base.textures().active_unit_enum() - constants::TEXTURE0) as usize; let idx = (self.base.textures().active_unit_enum() - constants::TEXTURE0) as usize;
assert!(idx < self.samplers.len()); assert!(idx < self.samplers.len());
let sampler = self.samplers[idx].get(); let sampler = self.samplers[idx].get();
sampler.to_jsval(*cx, rval); sampler.safe_to_jsval(cx, rval);
return; return;
}, },
constants::COPY_READ_BUFFER_BINDING => unsafe { constants::COPY_READ_BUFFER_BINDING => {
self.bound_copy_read_buffer.get().to_jsval(*cx, rval); self.bound_copy_read_buffer.get().safe_to_jsval(cx, rval);
return; return;
}, },
constants::COPY_WRITE_BUFFER_BINDING => unsafe { constants::COPY_WRITE_BUFFER_BINDING => {
self.bound_copy_write_buffer.get().to_jsval(*cx, rval); self.bound_copy_write_buffer.get().safe_to_jsval(cx, rval);
return; return;
}, },
constants::PIXEL_PACK_BUFFER_BINDING => unsafe { constants::PIXEL_PACK_BUFFER_BINDING => {
self.bound_pixel_pack_buffer.get().to_jsval(*cx, rval); self.bound_pixel_pack_buffer.get().safe_to_jsval(cx, rval);
return; return;
}, },
constants::PIXEL_UNPACK_BUFFER_BINDING => unsafe { constants::PIXEL_UNPACK_BUFFER_BINDING => {
self.bound_pixel_unpack_buffer.get().to_jsval(*cx, rval); self.bound_pixel_unpack_buffer.get().safe_to_jsval(cx, rval);
return; return;
}, },
constants::TRANSFORM_FEEDBACK_BUFFER_BINDING => unsafe { constants::TRANSFORM_FEEDBACK_BUFFER_BINDING => {
self.bound_transform_feedback_buffer self.bound_transform_feedback_buffer
.get() .get()
.to_jsval(*cx, rval); .safe_to_jsval(cx, rval);
return; return;
}, },
constants::UNIFORM_BUFFER_BINDING => unsafe { constants::UNIFORM_BUFFER_BINDING => {
self.bound_uniform_buffer.get().to_jsval(*cx, rval); self.bound_uniform_buffer.get().safe_to_jsval(cx, rval);
return; return;
}, },
constants::TRANSFORM_FEEDBACK_BINDING => unsafe { constants::TRANSFORM_FEEDBACK_BINDING => {
self.current_transform_feedback.get().to_jsval(*cx, rval); self.current_transform_feedback
.get()
.safe_to_jsval(cx, rval);
return; return;
}, },
constants::ELEMENT_ARRAY_BUFFER_BINDING => unsafe { constants::ELEMENT_ARRAY_BUFFER_BINDING => {
let buffer = self.current_vao().element_array_buffer().get(); let buffer = self.current_vao().element_array_buffer().get();
buffer.to_jsval(*cx, rval); buffer.safe_to_jsval(cx, rval);
return; return;
}, },
constants::VERTEX_ARRAY_BINDING => unsafe { constants::VERTEX_ARRAY_BINDING => {
let vao = self.current_vao(); let vao = self.current_vao();
let vao = vao.id().map(|_| &*vao); let vao = vao.id().map(|_| &*vao);
vao.to_jsval(*cx, rval); vao.safe_to_jsval(cx, rval);
return; return;
}, },
// NOTE: DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING, handled on the WebGL1 side // NOTE: DRAW_FRAMEBUFFER_BINDING is the same as FRAMEBUFFER_BINDING, handled on the WebGL1 side
constants::READ_FRAMEBUFFER_BINDING => unsafe { constants::READ_FRAMEBUFFER_BINDING => {
self.base self.base
.get_read_framebuffer_slot() .get_read_framebuffer_slot()
.get() .get()
.to_jsval(*cx, rval); .safe_to_jsval(cx, rval);
return; return;
}, },
constants::READ_BUFFER => { constants::READ_BUFFER => {
@ -2034,7 +2034,6 @@ impl WebGL2RenderingContextMethods<crate::DomTypeHolder> for WebGL2RenderingCont
} }
/// <https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.2> /// <https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.2>
#[allow(unsafe_code)]
fn GetIndexedParameter( fn GetIndexedParameter(
&self, &self,
cx: JSContext, cx: JSContext,
@ -2066,8 +2065,8 @@ impl WebGL2RenderingContextMethods<crate::DomTypeHolder> for WebGL2RenderingCont
}; };
match target { match target {
constants::TRANSFORM_FEEDBACK_BUFFER_BINDING | constants::UNIFORM_BUFFER_BINDING => unsafe { constants::TRANSFORM_FEEDBACK_BUFFER_BINDING | constants::UNIFORM_BUFFER_BINDING => {
binding.buffer.get().to_jsval(*cx, retval) binding.buffer.get().safe_to_jsval(cx, retval)
}, },
constants::TRANSFORM_FEEDBACK_BUFFER_START | constants::UNIFORM_BUFFER_START => { constants::TRANSFORM_FEEDBACK_BUFFER_START | constants::UNIFORM_BUFFER_START => {
retval.set(Int32Value(binding.start.get() as _)) retval.set(Int32Value(binding.start.get() as _))
@ -4494,7 +4493,6 @@ impl WebGL2RenderingContextMethods<crate::DomTypeHolder> for WebGL2RenderingCont
} }
/// <https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.16> /// <https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.16>
#[allow(unsafe_code)]
fn GetActiveUniforms( fn GetActiveUniforms(
&self, &self,
cx: JSContext, cx: JSContext,
@ -4520,12 +4518,12 @@ impl WebGL2RenderingContextMethods<crate::DomTypeHolder> for WebGL2RenderingCont
constants::UNIFORM_BLOCK_INDEX | constants::UNIFORM_BLOCK_INDEX |
constants::UNIFORM_OFFSET | constants::UNIFORM_OFFSET |
constants::UNIFORM_ARRAY_STRIDE | constants::UNIFORM_ARRAY_STRIDE |
constants::UNIFORM_MATRIX_STRIDE => unsafe { constants::UNIFORM_MATRIX_STRIDE => {
values.to_jsval(*cx, rval); values.safe_to_jsval(cx, rval);
}, },
constants::UNIFORM_IS_ROW_MAJOR => unsafe { constants::UNIFORM_IS_ROW_MAJOR => {
let values = values.iter().map(|&v| v != 0).collect::<Vec<_>>(); let values = values.iter().map(|&v| v != 0).collect::<Vec<_>>();
values.to_jsval(*cx, rval); values.safe_to_jsval(cx, rval);
}, },
_ => unreachable!(), _ => unreachable!(),
} }

View file

@ -30,6 +30,7 @@ use js::typedarray::{
TypedArrayElementCreator, Uint32Array, TypedArrayElementCreator, Uint32Array,
}; };
use pixels::{self, Alpha, PixelFormat, Snapshot, SnapshotPixelFormat}; use pixels::{self, Alpha, PixelFormat, Snapshot, SnapshotPixelFormat};
use script_bindings::conversions::SafeToJSValConvertible;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use servo_config::pref; use servo_config::pref;
use webrender_api::ImageKey; use webrender_api::ImageKey;
@ -48,7 +49,7 @@ use crate::dom::bindings::codegen::UnionTypes::{
ArrayBufferViewOrArrayBuffer, Float32ArrayOrUnrestrictedFloatSequence, ArrayBufferViewOrArrayBuffer, Float32ArrayOrUnrestrictedFloatSequence,
HTMLCanvasElementOrOffscreenCanvas, Int32ArrayOrLongSequence, HTMLCanvasElementOrOffscreenCanvas, Int32ArrayOrLongSequence,
}; };
use crate::dom::bindings::conversions::{DerivedFrom, ToJSValConvertible}; use crate::dom::bindings::conversions::DerivedFrom;
use crate::dom::bindings::error::{Error, ErrorResult, Fallible}; use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{DomGlobal, DomObject, Reflector, reflect_dom_object}; use crate::dom::bindings::reflector::{DomGlobal, DomObject, Reflector, reflect_dom_object};
@ -2128,37 +2129,37 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
} }
match parameter { match parameter {
constants::ARRAY_BUFFER_BINDING => unsafe { constants::ARRAY_BUFFER_BINDING => {
self.bound_buffer_array.get().to_jsval(*cx, retval); self.bound_buffer_array.get().safe_to_jsval(cx, retval);
return; return;
}, },
constants::CURRENT_PROGRAM => unsafe { constants::CURRENT_PROGRAM => {
self.current_program.get().to_jsval(*cx, retval); self.current_program.get().safe_to_jsval(cx, retval);
return; return;
}, },
constants::ELEMENT_ARRAY_BUFFER_BINDING => unsafe { constants::ELEMENT_ARRAY_BUFFER_BINDING => {
let buffer = self.current_vao().element_array_buffer().get(); let buffer = self.current_vao().element_array_buffer().get();
buffer.to_jsval(*cx, retval); buffer.safe_to_jsval(cx, retval);
return; return;
}, },
constants::FRAMEBUFFER_BINDING => unsafe { constants::FRAMEBUFFER_BINDING => {
self.bound_draw_framebuffer.get().to_jsval(*cx, retval); self.bound_draw_framebuffer.get().safe_to_jsval(cx, retval);
return; return;
}, },
constants::RENDERBUFFER_BINDING => unsafe { constants::RENDERBUFFER_BINDING => {
self.bound_renderbuffer.get().to_jsval(*cx, retval); self.bound_renderbuffer.get().safe_to_jsval(cx, retval);
return; return;
}, },
constants::TEXTURE_BINDING_2D => unsafe { constants::TEXTURE_BINDING_2D => {
let texture = self let texture = self
.textures .textures
.active_texture_slot(constants::TEXTURE_2D, self.webgl_version()) .active_texture_slot(constants::TEXTURE_2D, self.webgl_version())
.unwrap() .unwrap()
.get(); .get();
texture.to_jsval(*cx, retval); texture.safe_to_jsval(cx, retval);
return; return;
}, },
WebGL2RenderingContextConstants::TEXTURE_BINDING_2D_ARRAY => unsafe { WebGL2RenderingContextConstants::TEXTURE_BINDING_2D_ARRAY => {
let texture = self let texture = self
.textures .textures
.active_texture_slot( .active_texture_slot(
@ -2167,10 +2168,10 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
) )
.unwrap() .unwrap()
.get(); .get();
texture.to_jsval(*cx, retval); texture.safe_to_jsval(cx, retval);
return; return;
}, },
WebGL2RenderingContextConstants::TEXTURE_BINDING_3D => unsafe { WebGL2RenderingContextConstants::TEXTURE_BINDING_3D => {
let texture = self let texture = self
.textures .textures
.active_texture_slot( .active_texture_slot(
@ -2179,21 +2180,21 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
) )
.unwrap() .unwrap()
.get(); .get();
texture.to_jsval(*cx, retval); texture.safe_to_jsval(cx, retval);
return; return;
}, },
constants::TEXTURE_BINDING_CUBE_MAP => unsafe { constants::TEXTURE_BINDING_CUBE_MAP => {
let texture = self let texture = self
.textures .textures
.active_texture_slot(constants::TEXTURE_CUBE_MAP, self.webgl_version()) .active_texture_slot(constants::TEXTURE_CUBE_MAP, self.webgl_version())
.unwrap() .unwrap()
.get(); .get();
texture.to_jsval(*cx, retval); texture.safe_to_jsval(cx, retval);
return; return;
}, },
OESVertexArrayObjectConstants::VERTEX_ARRAY_BINDING_OES => unsafe { OESVertexArrayObjectConstants::VERTEX_ARRAY_BINDING_OES => {
let vao = self.current_vao.get().filter(|vao| vao.id().is_some()); let vao = self.current_vao.get().filter(|vao| vao.id().is_some());
vao.to_jsval(*cx, retval); vao.safe_to_jsval(cx, retval);
return; return;
}, },
// In readPixels we currently support RGBA/UBYTE only. If // In readPixels we currently support RGBA/UBYTE only. If
@ -2223,16 +2224,16 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
.unwrap(); .unwrap();
return retval.set(ObjectValue(rval.get())); return retval.set(ObjectValue(rval.get()));
}, },
constants::VERSION => unsafe { constants::VERSION => {
"WebGL 1.0".to_jsval(*cx, retval); "WebGL 1.0".safe_to_jsval(cx, retval);
return; return;
}, },
constants::RENDERER | constants::VENDOR => unsafe { constants::RENDERER | constants::VENDOR => {
"Mozilla/Servo".to_jsval(*cx, retval); "Mozilla/Servo".safe_to_jsval(cx, retval);
return; return;
}, },
constants::SHADING_LANGUAGE_VERSION => unsafe { constants::SHADING_LANGUAGE_VERSION => {
"WebGL GLSL ES 1.0".to_jsval(*cx, retval); "WebGL GLSL ES 1.0".safe_to_jsval(cx, retval);
return; return;
}, },
constants::UNPACK_FLIP_Y_WEBGL => { constants::UNPACK_FLIP_Y_WEBGL => {
@ -2310,10 +2311,10 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
self.send_command(WebGLCommand::GetParameterBool(param, sender)); self.send_command(WebGLCommand::GetParameterBool(param, sender));
retval.set(BooleanValue(receiver.recv().unwrap())) retval.set(BooleanValue(receiver.recv().unwrap()))
}, },
Parameter::Bool4(param) => unsafe { Parameter::Bool4(param) => {
let (sender, receiver) = webgl_channel().unwrap(); let (sender, receiver) = webgl_channel().unwrap();
self.send_command(WebGLCommand::GetParameterBool4(param, sender)); self.send_command(WebGLCommand::GetParameterBool4(param, sender));
receiver.recv().unwrap().to_jsval(*cx, retval); receiver.recv().unwrap().safe_to_jsval(cx, retval);
}, },
Parameter::Int(param) => { Parameter::Int(param) => {
let (sender, receiver) = webgl_channel().unwrap(); let (sender, receiver) = webgl_channel().unwrap();
@ -3255,7 +3256,6 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
handle_potential_webgl_error!(self, program.get_attrib_location(name), -1) handle_potential_webgl_error!(self, program.get_attrib_location(name), -1)
} }
#[allow(unsafe_code)]
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6 // https://www.khronos.org/registry/webgl/specs/latest/1.0/#5.14.6
fn GetFramebufferAttachmentParameter( fn GetFramebufferAttachmentParameter(
&self, &self,
@ -3352,12 +3352,12 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
let fb = self.bound_draw_framebuffer.get().unwrap(); let fb = self.bound_draw_framebuffer.get().unwrap();
if let Some(webgl_attachment) = fb.attachment(attachment) { if let Some(webgl_attachment) = fb.attachment(attachment) {
match webgl_attachment { match webgl_attachment {
WebGLFramebufferAttachmentRoot::Renderbuffer(rb) => unsafe { WebGLFramebufferAttachmentRoot::Renderbuffer(rb) => {
rb.to_jsval(*cx, retval); rb.safe_to_jsval(cx, retval);
return; return;
}, },
WebGLFramebufferAttachmentRoot::Texture(texture) => unsafe { WebGLFramebufferAttachmentRoot::Texture(texture) => {
texture.to_jsval(*cx, retval); texture.safe_to_jsval(cx, retval);
return; return;
}, },
} }
@ -3640,9 +3640,9 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
retval.set(BooleanValue(data.normalized)) retval.set(BooleanValue(data.normalized))
}, },
constants::VERTEX_ATTRIB_ARRAY_STRIDE => retval.set(Int32Value(data.stride as i32)), constants::VERTEX_ATTRIB_ARRAY_STRIDE => retval.set(Int32Value(data.stride as i32)),
constants::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING => unsafe { constants::VERTEX_ATTRIB_ARRAY_BUFFER_BINDING => {
if let Some(buffer) = data.buffer() { if let Some(buffer) = data.buffer() {
buffer.to_jsval(*cx, retval.reborrow()); buffer.safe_to_jsval(cx, retval.reborrow());
} else { } else {
retval.set(NullValue()); retval.set(NullValue());
} }
@ -4264,14 +4264,14 @@ impl WebGLRenderingContextMethods<crate::DomTypeHolder> for WebGLRenderingContex
triple, triple,
WebGLCommand::GetUniformBool, WebGLCommand::GetUniformBool,
))), ))),
constants::BOOL_VEC2 => unsafe { constants::BOOL_VEC2 => {
uniform_get(triple, WebGLCommand::GetUniformBool2).to_jsval(*cx, rval); uniform_get(triple, WebGLCommand::GetUniformBool2).safe_to_jsval(cx, rval)
}, },
constants::BOOL_VEC3 => unsafe { constants::BOOL_VEC3 => {
uniform_get(triple, WebGLCommand::GetUniformBool3).to_jsval(*cx, rval); uniform_get(triple, WebGLCommand::GetUniformBool3).safe_to_jsval(cx, rval)
}, },
constants::BOOL_VEC4 => unsafe { constants::BOOL_VEC4 => {
uniform_get(triple, WebGLCommand::GetUniformBool4).to_jsval(*cx, rval); uniform_get(triple, WebGLCommand::GetUniformBool4).safe_to_jsval(cx, rval)
}, },
constants::INT | constants::INT |
constants::SAMPLER_2D | constants::SAMPLER_2D |

View file

@ -32,6 +32,7 @@ use net_traits::{
FetchMetadata, FetchResponseListener, FilteredMetadata, NetworkError, ReferrerPolicy, FetchMetadata, FetchResponseListener, FilteredMetadata, NetworkError, ReferrerPolicy,
ResourceFetchTiming, ResourceTimingType, trim_http_whitespace, ResourceFetchTiming, ResourceTimingType, trim_http_whitespace,
}; };
use script_bindings::conversions::SafeToJSValConvertible;
use script_bindings::num::Finite; use script_bindings::num::Finite;
use script_traits::DocumentActivity; use script_traits::DocumentActivity;
use servo_url::ServoUrl; use servo_url::ServoUrl;
@ -47,7 +48,6 @@ use crate::dom::bindings::codegen::Bindings::XMLHttpRequestBinding::{
XMLHttpRequestMethods, XMLHttpRequestResponseType, XMLHttpRequestMethods, XMLHttpRequestResponseType,
}; };
use crate::dom::bindings::codegen::UnionTypes::DocumentOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrStringOrURLSearchParams as DocumentOrXMLHttpRequestBodyInit; use crate::dom::bindings::codegen::UnionTypes::DocumentOrBlobOrArrayBufferViewOrArrayBufferOrFormDataOrStringOrURLSearchParams as DocumentOrXMLHttpRequestBodyInit;
use crate::dom::bindings::conversions::ToJSValConvertible;
use crate::dom::bindings::error::{Error, ErrorResult, Fallible}; use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::Trusted; use crate::dom::bindings::refcounted::Trusted;
@ -919,20 +919,19 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
} }
} }
#[allow(unsafe_code)]
/// <https://xhr.spec.whatwg.org/#the-response-attribute> /// <https://xhr.spec.whatwg.org/#the-response-attribute>
fn Response(&self, cx: JSContext, can_gc: CanGc, mut rval: MutableHandleValue) { fn Response(&self, cx: JSContext, can_gc: CanGc, mut rval: MutableHandleValue) {
match self.response_type.get() { match self.response_type.get() {
XMLHttpRequestResponseType::_empty | XMLHttpRequestResponseType::Text => unsafe { XMLHttpRequestResponseType::_empty | XMLHttpRequestResponseType::Text => {
let ready_state = self.ready_state.get(); let ready_state = self.ready_state.get();
// Step 2 // Step 2
if ready_state == XMLHttpRequestState::Done || if ready_state == XMLHttpRequestState::Done ||
ready_state == XMLHttpRequestState::Loading ready_state == XMLHttpRequestState::Loading
{ {
self.text_response().to_jsval(*cx, rval); self.text_response().safe_to_jsval(cx, rval);
} else { } else {
// Step 1 // Step 1
"".to_jsval(*cx, rval); "".safe_to_jsval(cx, rval);
} }
}, },
// Step 1 // Step 1
@ -940,16 +939,14 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
rval.set(NullValue()); rval.set(NullValue());
}, },
// Step 2 // Step 2
XMLHttpRequestResponseType::Document => unsafe { XMLHttpRequestResponseType::Document => {
self.document_response(can_gc).to_jsval(*cx, rval); self.document_response(can_gc).safe_to_jsval(cx, rval)
}, },
XMLHttpRequestResponseType::Json => self.json_response(cx, rval), XMLHttpRequestResponseType::Json => self.json_response(cx, rval),
XMLHttpRequestResponseType::Blob => unsafe { XMLHttpRequestResponseType::Blob => self.blob_response(can_gc).safe_to_jsval(cx, rval),
self.blob_response(can_gc).to_jsval(*cx, rval);
},
XMLHttpRequestResponseType::Arraybuffer => { XMLHttpRequestResponseType::Arraybuffer => {
match self.arraybuffer_response(cx, can_gc) { match self.arraybuffer_response(cx, can_gc) {
Some(array_buffer) => unsafe { array_buffer.to_jsval(*cx, rval) }, Some(array_buffer) => array_buffer.safe_to_jsval(cx, rval),
None => rval.set(NullValue()), None => rval.set(NullValue()),
} }
}, },

View file

@ -41,7 +41,7 @@ pub trait SafeToJSValConvertible {
fn safe_to_jsval(&self, cx: SafeJSContext, rval: MutableHandleValue); fn safe_to_jsval(&self, cx: SafeJSContext, rval: MutableHandleValue);
} }
impl<T: ToJSValConvertible> SafeToJSValConvertible for T { impl<T: ToJSValConvertible + ?Sized> SafeToJSValConvertible for T {
fn safe_to_jsval(&self, cx: SafeJSContext, rval: MutableHandleValue) { fn safe_to_jsval(&self, cx: SafeJSContext, rval: MutableHandleValue) {
unsafe { self.to_jsval(*cx, rval) }; unsafe { self.to_jsval(*cx, rval) };
} }