mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
codegen: use FromJSValConvertible
trait for Promise
(#36966)
Before it was only used when converting to a `Record`, using it all the times allow us to remove two methods. Plus added a helper method in CodegenRust.py to avoid repeated code. Testing: a successful build and existing tests should cover the changes. Fixes: #36410 --------- Signed-off-by: Gae24 <96017547+Gae24@users.noreply.github.com>
This commit is contained in:
parent
d780fb7695
commit
c37d5572fd
6 changed files with 27 additions and 118 deletions
|
@ -3562,10 +3562,6 @@ impl GlobalScopeHelpers<crate::DomTypeHolder> for GlobalScope {
|
||||||
GlobalScope::from_reflector(reflector, realm)
|
GlobalScope::from_reflector(reflector, realm)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn from_object_maybe_wrapped(obj: *mut JSObject, cx: *mut JSContext) -> DomRoot<Self> {
|
|
||||||
GlobalScope::from_object_maybe_wrapped(obj, cx)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn origin(&self) -> &MutableOrigin {
|
fn origin(&self) -> &MutableOrigin {
|
||||||
GlobalScope::origin(self)
|
GlobalScope::origin(self)
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,6 @@ use js::rust::wrappers::{
|
||||||
ResolvePromise, SetAnyPromiseIsHandled, SetPromiseUserInputEventHandlingState,
|
ResolvePromise, SetAnyPromiseIsHandled, SetPromiseUserInputEventHandlingState,
|
||||||
};
|
};
|
||||||
use js::rust::{HandleObject, HandleValue, MutableHandleObject, Runtime};
|
use js::rust::{HandleObject, HandleValue, MutableHandleObject, Runtime};
|
||||||
use script_bindings::interfaces::PromiseHelpers;
|
|
||||||
|
|
||||||
use crate::dom::bindings::conversions::root_from_object;
|
use crate::dom::bindings::conversions::root_from_object;
|
||||||
use crate::dom::bindings::error::{Error, ErrorToJsval};
|
use crate::dom::bindings::error::{Error, ErrorToJsval};
|
||||||
|
@ -388,16 +387,6 @@ fn create_native_handler_function(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PromiseHelpers<crate::DomTypeHolder> for Promise {
|
|
||||||
fn new_resolved(
|
|
||||||
global: &GlobalScope,
|
|
||||||
cx: SafeJSContext,
|
|
||||||
value: impl ToJSValConvertible,
|
|
||||||
) -> Rc<Promise> {
|
|
||||||
Promise::new_resolved(global, cx, value, CanGc::note())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FromJSValConvertibleRc for Promise {
|
impl FromJSValConvertibleRc for Promise {
|
||||||
#[allow(unsafe_code)]
|
#[allow(unsafe_code)]
|
||||||
unsafe fn from_jsval(
|
unsafe fn from_jsval(
|
||||||
|
@ -407,16 +396,12 @@ impl FromJSValConvertibleRc for Promise {
|
||||||
if value.get().is_null() {
|
if value.get().is_null() {
|
||||||
return Ok(ConversionResult::Failure("null not allowed".into()));
|
return Ok(ConversionResult::Failure("null not allowed".into()));
|
||||||
}
|
}
|
||||||
if !value.get().is_object() {
|
|
||||||
return Ok(ConversionResult::Failure("not an object".into()));
|
|
||||||
}
|
|
||||||
rooted!(in(cx) let obj = value.get().to_object());
|
|
||||||
|
|
||||||
let cx = SafeJSContext::from_ptr(cx);
|
let cx = SafeJSContext::from_ptr(cx);
|
||||||
let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
|
let in_realm_proof = AlreadyInRealm::assert_for_cx(cx);
|
||||||
let global_scope = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));
|
let global_scope = GlobalScope::from_context(*cx, InRealm::Already(&in_realm_proof));
|
||||||
|
|
||||||
let promise = Promise::new_resolved(&global_scope, cx, *obj, CanGc::note());
|
let promise = Promise::new_resolved(&global_scope, cx, value, CanGc::note());
|
||||||
Ok(ConversionResult::Success(promise))
|
Ok(ConversionResult::Success(promise))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -538,7 +538,7 @@ DOMInterfaces = {
|
||||||
|
|
||||||
'Promise': {
|
'Promise': {
|
||||||
'spiderMonkeyInterface': True,
|
'spiderMonkeyInterface': True,
|
||||||
'additionalTraits': ["crate::interfaces::PromiseHelpers<Self>", "js::conversions::FromJSValConvertibleRc"]
|
'additionalTraits': ["js::conversions::FromJSValConvertibleRc"]
|
||||||
},
|
},
|
||||||
|
|
||||||
'Range': {
|
'Range': {
|
||||||
|
|
|
@ -742,6 +742,19 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
"}")
|
"}")
|
||||||
return templateBody
|
return templateBody
|
||||||
|
|
||||||
|
# A helper function for types that implement FromJSValConvertible trait
|
||||||
|
def fromJSValTemplate(config, errorHandler, exceptionCode):
|
||||||
|
return f"""match FromJSValConvertible::from_jsval(*cx, ${{val}}, {config}) {{
|
||||||
|
Ok(ConversionResult::Success(value)) => value,
|
||||||
|
Ok(ConversionResult::Failure(error)) => {{
|
||||||
|
{errorHandler}
|
||||||
|
}}
|
||||||
|
_ => {{
|
||||||
|
{exceptionCode}
|
||||||
|
}},
|
||||||
|
}}
|
||||||
|
"""
|
||||||
|
|
||||||
assert not (isEnforceRange and isClamp) # These are mutually exclusive
|
assert not (isEnforceRange and isClamp) # These are mutually exclusive
|
||||||
|
|
||||||
if type.isSequence() or type.isRecord():
|
if type.isSequence() or type.isRecord():
|
||||||
|
@ -755,13 +768,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
if type.nullable():
|
if type.nullable():
|
||||||
declType = CGWrapper(declType, pre="Option<", post=" >")
|
declType = CGWrapper(declType, pre="Option<", post=" >")
|
||||||
|
|
||||||
templateBody = (f"match FromJSValConvertible::from_jsval(*cx, ${{val}}, {config}) {{\n"
|
templateBody = fromJSValTemplate(config, failOrPropagate, exceptionCode)
|
||||||
" Ok(ConversionResult::Success(value)) => value,\n"
|
|
||||||
" Ok(ConversionResult::Failure(error)) => {\n"
|
|
||||||
f"{indent(failOrPropagate, 8)}\n"
|
|
||||||
" }\n"
|
|
||||||
f" _ => {{ {exceptionCode} }},\n"
|
|
||||||
"}")
|
|
||||||
|
|
||||||
return handleOptional(templateBody, declType, handleDefault("None"))
|
return handleOptional(templateBody, declType, handleDefault("None"))
|
||||||
|
|
||||||
|
@ -770,13 +777,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
if type.nullable():
|
if type.nullable():
|
||||||
declType = CGWrapper(declType, pre="Option<", post=" >")
|
declType = CGWrapper(declType, pre="Option<", post=" >")
|
||||||
|
|
||||||
templateBody = ("match FromJSValConvertible::from_jsval(*cx, ${val}, ()) {\n"
|
templateBody = fromJSValTemplate("()", failOrPropagate, exceptionCode)
|
||||||
" Ok(ConversionResult::Success(value)) => value,\n"
|
|
||||||
" Ok(ConversionResult::Failure(error)) => {\n"
|
|
||||||
f"{indent(failOrPropagate, 8)}\n"
|
|
||||||
" }\n"
|
|
||||||
f" _ => {{ {exceptionCode} }},\n"
|
|
||||||
"}")
|
|
||||||
|
|
||||||
dictionaries = [
|
dictionaries = [
|
||||||
memberType
|
memberType
|
||||||
|
@ -836,21 +837,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
# once again be providing a Promise to signal completion of an
|
# once again be providing a Promise to signal completion of an
|
||||||
# operation, which would then not be exposed to anyone other than
|
# operation, which would then not be exposed to anyone other than
|
||||||
# our own implementation code.
|
# our own implementation code.
|
||||||
templateBody = fill(
|
templateBody = fromJSValTemplate("()", failOrPropagate, exceptionCode)
|
||||||
"""
|
|
||||||
{ // Scope for our JSAutoRealm.
|
|
||||||
|
|
||||||
rooted!(in(*cx) let globalObj = CurrentGlobalOrNull(*cx));
|
|
||||||
let promiseGlobal = D::GlobalScope::from_object_maybe_wrapped(globalObj.handle().get(), *cx);
|
|
||||||
|
|
||||||
rooted!(in(*cx) let mut valueToResolve = $${val}.get());
|
|
||||||
if !JS_WrapValue(*cx, valueToResolve.handle_mut()) {
|
|
||||||
$*{exceptionCode}
|
|
||||||
}
|
|
||||||
D::Promise::new_resolved(&promiseGlobal, cx, valueToResolve.handle())
|
|
||||||
}
|
|
||||||
""",
|
|
||||||
exceptionCode=exceptionCode)
|
|
||||||
|
|
||||||
if isArgument:
|
if isArgument:
|
||||||
declType = CGGeneric("&D::Promise")
|
declType = CGGeneric("&D::Promise")
|
||||||
|
@ -960,14 +947,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
if type.isDOMString():
|
if type.isDOMString():
|
||||||
nullBehavior = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs)
|
nullBehavior = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs)
|
||||||
|
|
||||||
conversionCode = (
|
conversionCode = fromJSValTemplate(nullBehavior, failOrPropagate, exceptionCode)
|
||||||
f"match FromJSValConvertible::from_jsval(*cx, ${{val}}, {nullBehavior}) {{\n"
|
|
||||||
" Ok(ConversionResult::Success(strval)) => strval,\n"
|
|
||||||
" Ok(ConversionResult::Failure(error)) => {\n"
|
|
||||||
f"{indent(failOrPropagate, 8)}\n"
|
|
||||||
" }\n"
|
|
||||||
f" _ => {{ {exceptionCode} }},\n"
|
|
||||||
"}")
|
|
||||||
|
|
||||||
if defaultValue is None:
|
if defaultValue is None:
|
||||||
default = None
|
default = None
|
||||||
|
@ -989,14 +969,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
if type.isUSVString():
|
if type.isUSVString():
|
||||||
assert not isEnforceRange and not isClamp
|
assert not isEnforceRange and not isClamp
|
||||||
|
|
||||||
conversionCode = (
|
conversionCode = fromJSValTemplate("()", failOrPropagate, exceptionCode)
|
||||||
"match FromJSValConvertible::from_jsval(*cx, ${val}, ()) {\n"
|
|
||||||
" Ok(ConversionResult::Success(strval)) => strval,\n"
|
|
||||||
" Ok(ConversionResult::Failure(error)) => {\n"
|
|
||||||
f"{indent(failOrPropagate, 8)}\n"
|
|
||||||
" }\n"
|
|
||||||
f" _ => {{ {exceptionCode} }},\n"
|
|
||||||
"}")
|
|
||||||
|
|
||||||
if defaultValue is None:
|
if defaultValue is None:
|
||||||
default = None
|
default = None
|
||||||
|
@ -1018,14 +991,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
if type.isByteString():
|
if type.isByteString():
|
||||||
assert not isEnforceRange and not isClamp
|
assert not isEnforceRange and not isClamp
|
||||||
|
|
||||||
conversionCode = (
|
conversionCode = fromJSValTemplate("()", failOrPropagate, exceptionCode)
|
||||||
"match FromJSValConvertible::from_jsval(*cx, ${val}, ()) {\n"
|
|
||||||
" Ok(ConversionResult::Success(strval)) => strval,\n"
|
|
||||||
" Ok(ConversionResult::Failure(error)) => {\n"
|
|
||||||
f"{indent(failOrPropagate, 8)}\n"
|
|
||||||
" }\n"
|
|
||||||
f" _ => {{ {exceptionCode} }},\n"
|
|
||||||
"}")
|
|
||||||
|
|
||||||
if defaultValue is None:
|
if defaultValue is None:
|
||||||
default = None
|
default = None
|
||||||
|
@ -1056,12 +1022,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
else:
|
else:
|
||||||
handleInvalidEnumValueCode = "return true;"
|
handleInvalidEnumValueCode = "return true;"
|
||||||
|
|
||||||
template = (
|
template = fromJSValTemplate("()", handleInvalidEnumValueCode, exceptionCode)
|
||||||
"match FromJSValConvertible::from_jsval(*cx, ${val}, ()) {"
|
|
||||||
f" Err(_) => {{ {exceptionCode} }},\n"
|
|
||||||
" Ok(ConversionResult::Success(v)) => v,\n"
|
|
||||||
f" Ok(ConversionResult::Failure(error)) => {{ {handleInvalidEnumValueCode} }},\n"
|
|
||||||
"}")
|
|
||||||
|
|
||||||
if defaultValue is not None:
|
if defaultValue is not None:
|
||||||
assert defaultValue.type.tag() == IDLType.Tags.domstring
|
assert defaultValue.type.tag() == IDLType.Tags.domstring
|
||||||
|
@ -1192,14 +1153,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
if type_needs_tracing(type):
|
if type_needs_tracing(type):
|
||||||
declType = CGTemplatedType("RootedTraceableBox", declType)
|
declType = CGTemplatedType("RootedTraceableBox", declType)
|
||||||
|
|
||||||
template = (
|
template = fromJSValTemplate("()", failOrPropagate, exceptionCode)
|
||||||
"match FromJSValConvertible::from_jsval(*cx, ${val}, ()) {\n"
|
|
||||||
" Ok(ConversionResult::Success(dictionary)) => dictionary,\n"
|
|
||||||
" Ok(ConversionResult::Failure(error)) => {\n"
|
|
||||||
f"{indent(failOrPropagate, 8)}\n"
|
|
||||||
" }\n"
|
|
||||||
f" _ => {{ {exceptionCode} }},\n"
|
|
||||||
"}")
|
|
||||||
|
|
||||||
return handleOptional(template, declType, handleDefault(empty))
|
return handleOptional(template, declType, handleDefault(empty))
|
||||||
|
|
||||||
|
@ -1220,14 +1174,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
|
||||||
if type.nullable():
|
if type.nullable():
|
||||||
declType = CGWrapper(declType, pre="Option<", post=">")
|
declType = CGWrapper(declType, pre="Option<", post=">")
|
||||||
|
|
||||||
template = (
|
template = fromJSValTemplate(conversionBehavior, failOrPropagate, exceptionCode)
|
||||||
f"match FromJSValConvertible::from_jsval(*cx, ${{val}}, {conversionBehavior}) {{\n"
|
|
||||||
" Ok(ConversionResult::Success(v)) => v,\n"
|
|
||||||
" Ok(ConversionResult::Failure(error)) => {\n"
|
|
||||||
f"{indent(failOrPropagate, 8)}\n"
|
|
||||||
" }\n"
|
|
||||||
f" _ => {{ {exceptionCode} }}\n"
|
|
||||||
"}")
|
|
||||||
|
|
||||||
if defaultValue is not None:
|
if defaultValue is not None:
|
||||||
if isinstance(defaultValue, IDLNullValue):
|
if isinstance(defaultValue, IDLNullValue):
|
||||||
|
|
|
@ -11,12 +11,12 @@ pub(crate) mod base {
|
||||||
};
|
};
|
||||||
pub(crate) use js::error::throw_type_error;
|
pub(crate) use js::error::throw_type_error;
|
||||||
pub(crate) use js::jsapi::{
|
pub(crate) use js::jsapi::{
|
||||||
CurrentGlobalOrNull, HandleValue as RawHandleValue, HandleValueArray, Heap, IsCallable,
|
HandleValue as RawHandleValue, HandleValueArray, Heap, IsCallable, JS_NewObject, JSContext,
|
||||||
JS_NewObject, JSContext, JSObject,
|
JSObject,
|
||||||
};
|
};
|
||||||
pub(crate) use js::jsval::{JSVal, NullValue, ObjectOrNullValue, ObjectValue, UndefinedValue};
|
pub(crate) use js::jsval::{JSVal, NullValue, ObjectOrNullValue, ObjectValue, UndefinedValue};
|
||||||
pub(crate) use js::panic::maybe_resume_unwind;
|
pub(crate) use js::panic::maybe_resume_unwind;
|
||||||
pub(crate) use js::rust::wrappers::{Call, JS_WrapValue};
|
pub(crate) use js::rust::wrappers::Call;
|
||||||
pub(crate) use js::rust::{HandleObject, HandleValue, MutableHandleObject, MutableHandleValue};
|
pub(crate) use js::rust::{HandleObject, HandleValue, MutableHandleObject, MutableHandleValue};
|
||||||
|
|
||||||
pub(crate) use crate::callback::{
|
pub(crate) use crate::callback::{
|
||||||
|
|
|
@ -3,10 +3,8 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::rc::Rc;
|
|
||||||
use std::thread::LocalKey;
|
use std::thread::LocalKey;
|
||||||
|
|
||||||
use js::conversions::ToJSValConvertible;
|
|
||||||
use js::glue::JSPrincipalsCallbacks;
|
use js::glue::JSPrincipalsCallbacks;
|
||||||
use js::jsapi::{CallArgs, HandleObject as RawHandleObject, JSContext as RawJSContext, JSObject};
|
use js::jsapi::{CallArgs, HandleObject as RawHandleObject, JSContext as RawJSContext, JSObject};
|
||||||
use js::rust::{HandleObject, MutableHandleObject};
|
use js::rust::{HandleObject, MutableHandleObject};
|
||||||
|
@ -78,14 +76,6 @@ pub trait GlobalScopeHelpers<D: DomTypes> {
|
||||||
unsafe fn from_object(obj: *mut JSObject) -> DomRoot<D::GlobalScope>;
|
unsafe fn from_object(obj: *mut JSObject) -> DomRoot<D::GlobalScope>;
|
||||||
fn from_reflector(reflector: &impl DomObject, realm: InRealm) -> DomRoot<D::GlobalScope>;
|
fn from_reflector(reflector: &impl DomObject, realm: InRealm) -> DomRoot<D::GlobalScope>;
|
||||||
|
|
||||||
/// # Safety
|
|
||||||
/// `obj` must point to a valid, non-null JSObject.
|
|
||||||
/// `cx` must point to a valid, non-null RawJSContext.
|
|
||||||
unsafe fn from_object_maybe_wrapped(
|
|
||||||
obj: *mut JSObject,
|
|
||||||
cx: *mut RawJSContext,
|
|
||||||
) -> DomRoot<D::GlobalScope>;
|
|
||||||
|
|
||||||
fn origin(&self) -> &MutableOrigin;
|
fn origin(&self) -> &MutableOrigin;
|
||||||
|
|
||||||
fn incumbent() -> Option<DomRoot<D::GlobalScope>>;
|
fn incumbent() -> Option<DomRoot<D::GlobalScope>>;
|
||||||
|
@ -101,15 +91,6 @@ pub trait DocumentHelpers {
|
||||||
fn ensure_safe_to_run_script_or_layout(&self);
|
fn ensure_safe_to_run_script_or_layout(&self);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Operations that must be invoked from the generated bindings.
|
|
||||||
pub trait PromiseHelpers<D: crate::DomTypes> {
|
|
||||||
fn new_resolved(
|
|
||||||
global: &D::GlobalScope,
|
|
||||||
cx: JSContext,
|
|
||||||
value: impl ToJSValConvertible,
|
|
||||||
) -> Rc<D::Promise>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait ServoInternalsHelpers {
|
pub trait ServoInternalsHelpers {
|
||||||
fn is_servo_internal(cx: JSContext, global: HandleObject) -> bool;
|
fn is_servo_internal(cx: JSContext, global: HandleObject) -> bool;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue