script: Add can_gc to WebIDL dictionary constructors (#39195)

More progress on can_gc!

Testing: Internal change only, shouldn't change behavior.
Fixes: #38708

---------

Signed-off-by: lumiscosity <averyrudelphe@gmail.com>
This commit is contained in:
lumiscosity 2025-09-08 11:21:42 +02:00 committed by GitHub
parent 1b9dc3e672
commit 9584b9e57d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 26 additions and 17 deletions

View file

@ -635,12 +635,13 @@ impl PermissionAlgorithm for Bluetooth {
fn create_descriptor(
cx: JSContext,
permission_descriptor_obj: *mut JSObject,
can_gc: CanGc,
) -> Result<BluetoothPermissionDescriptor, Error> {
rooted!(in(*cx) let mut property = UndefinedValue());
property
.handle_mut()
.set(ObjectValue(permission_descriptor_obj));
match BluetoothPermissionDescriptor::new(cx, property.handle()) {
match BluetoothPermissionDescriptor::new(cx, property.handle(), can_gc) {
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))),

View file

@ -260,7 +260,7 @@ impl HTMLCanvasElement {
let canvas =
RootedHTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(DomRoot::from_ref(self));
let size = self.get_size();
let attrs = Self::get_gl_attributes(cx, options)?;
let attrs = Self::get_gl_attributes(cx, options, can_gc)?;
let context = WebGLRenderingContext::new(
&window,
&canvas,
@ -293,7 +293,7 @@ impl HTMLCanvasElement {
let canvas =
RootedHTMLCanvasElementOrOffscreenCanvas::HTMLCanvasElement(DomRoot::from_ref(self));
let size = self.get_size();
let attrs = Self::get_gl_attributes(cx, options)?;
let attrs = Self::get_gl_attributes(cx, options, can_gc)?;
let context = WebGL2RenderingContext::new(&window, &canvas, size, attrs, can_gc)?;
*self.context_mode.borrow_mut() = Some(RenderingContext::WebGL2(Dom::from_ref(&*context)));
Some(context)
@ -338,9 +338,13 @@ impl HTMLCanvasElement {
}
#[allow(unsafe_code)]
fn get_gl_attributes(cx: JSContext, options: HandleValue) -> Option<GLContextAttributes> {
fn get_gl_attributes(
cx: JSContext,
options: HandleValue,
can_gc: CanGc,
) -> Option<GLContextAttributes> {
unsafe {
match WebGLContextAttributes::new(cx, options) {
match WebGLContextAttributes::new(cx, options, can_gc) {
Ok(ConversionResult::Success(attrs)) => Some(attrs.convert()),
Ok(ConversionResult::Failure(error)) => {
throw_type_error(*cx, &error);

View file

@ -40,6 +40,7 @@ pub(crate) trait PermissionAlgorithm {
fn create_descriptor(
cx: JSContext,
permission_descriptor_obj: *mut JSObject,
can_gc: CanGc,
) -> Result<Self::Descriptor, Error>;
fn permission_query(
cx: JSContext,
@ -101,7 +102,7 @@ impl Permissions {
};
// (Query, Request, Revoke) Step 1.
let root_desc = match Permissions::create_descriptor(cx, permissionDesc) {
let root_desc = match Permissions::create_descriptor(cx, permissionDesc, can_gc) {
Ok(descriptor) => descriptor,
Err(error) => {
p.reject_error(error, can_gc);
@ -116,7 +117,8 @@ impl Permissions {
match root_desc.name {
#[cfg(feature = "bluetooth")]
PermissionName::Bluetooth => {
let bluetooth_desc = match Bluetooth::create_descriptor(cx, permissionDesc) {
let bluetooth_desc = match Bluetooth::create_descriptor(cx, permissionDesc, can_gc)
{
Ok(descriptor) => descriptor,
Err(error) => {
p.reject_error(error, can_gc);
@ -221,12 +223,13 @@ impl PermissionAlgorithm for Permissions {
fn create_descriptor(
cx: JSContext,
permission_descriptor_obj: *mut JSObject,
can_gc: CanGc,
) -> Result<PermissionDescriptor, Error> {
rooted!(in(*cx) let mut property = UndefinedValue());
property
.handle_mut()
.set(ObjectValue(permission_descriptor_obj));
match PermissionDescriptor::new(cx, property.handle()) {
match PermissionDescriptor::new(cx, property.handle(), can_gc) {
Ok(ConversionResult::Success(descriptor)) => Ok(descriptor),
Ok(ConversionResult::Failure(error)) => Err(Error::Type(error.into_owned())),
Err(_) => Err(Error::JSFailed),

View file

@ -1973,7 +1973,7 @@ impl ReadableStreamMethods<crate::DomTypeHolder> for ReadableStream {
// converted to an IDL value of type UnderlyingSource.
let underlying_source_dict = if !underlying_source_obj.is_null() {
rooted!(in(*cx) let obj_val = ObjectValue(underlying_source_obj.get()));
match JsUnderlyingSource::new(cx, obj_val.handle()) {
match JsUnderlyingSource::new(cx, obj_val.handle(), can_gc) {
Ok(ConversionResult::Success(val)) => val,
Ok(ConversionResult::Failure(error)) => return Err(Error::Type(error.to_string())),
_ => {

View file

@ -1405,7 +1405,8 @@ enum KeyWrapAlgorithm {
macro_rules! value_from_js_object {
($t: ty, $cx: ident, $value: ident) => {{
let params_result = <$t>::new($cx, $value.handle()).map_err(|_| Error::JSFailed)?;
let params_result =
<$t>::new($cx, $value.handle(), CanGc::note()).map_err(|_| Error::JSFailed)?;
let ConversionResult::Success(params) = params_result else {
return Err(Error::Syntax(None));
};
@ -3218,7 +3219,7 @@ impl JsonWebKeyExt for JsonWebKey {
}
// Step 5. Let key be the result of converting result to the IDL dictionary type of JsonWebKey.
let key = match JsonWebKey::new(cx, result.handle()) {
let key = match JsonWebKey::new(cx, result.handle(), CanGc::note()) {
Ok(ConversionResult::Success(key)) => key,
Ok(ConversionResult::Failure(error)) => {
return Err(Error::Type(error.to_string()));

View file

@ -968,7 +968,7 @@ impl TransformStreamMethods<crate::DomTypeHolder> for TransformStream {
// converted to an IDL value of type UnderlyingSink.
let transformer_dict = if !transformer_obj.is_null() {
rooted!(in(*cx) let obj_val = ObjectValue(transformer_obj.get()));
match Transformer::new(cx, obj_val.handle()) {
match Transformer::new(cx, obj_val.handle(), can_gc) {
Ok(ConversionResult::Success(val)) => val,
Ok(ConversionResult::Failure(error)) => return Err(Error::Type(error.to_string())),
_ => {

View file

@ -1025,7 +1025,7 @@ impl WritableStreamMethods<crate::DomTypeHolder> for WritableStream {
// converted to an IDL value of type UnderlyingSink.
let underlying_sink_dict = if !underlying_sink_obj.is_null() {
rooted!(in(*cx) let obj_val = ObjectValue(underlying_sink_obj.get()));
match UnderlyingSink::new(cx, obj_val.handle()) {
match UnderlyingSink::new(cx, obj_val.handle(), can_gc) {
Ok(ConversionResult::Success(val)) => val,
Ok(ConversionResult::Failure(error)) => return Err(Error::Type(error.to_string())),
_ => {