aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen/CodegenRust.py
diff options
context:
space:
mode:
Diffstat (limited to 'components/script/dom/bindings/codegen/CodegenRust.py')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py109
1 files changed, 85 insertions, 24 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index d2d090f8350..24054de8e95 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -870,8 +870,51 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
return handleOptional(templateBody, declType, handleDefaultNull("None"))
- if type.isSpiderMonkeyInterface():
- raise TypeError("Can't handle SpiderMonkey interface arguments yet")
+ if is_typed_array(type):
+ if failureCode is None:
+ substitutions = {
+ "sourceDescription": sourceDescription,
+ "exceptionCode": exceptionCode,
+ }
+ unwrapFailureCode = string.Template(
+ 'throw_type_error(cx, "${sourceDescription} is not a typed array.");\n'
+ '${exceptionCode}').substitute(substitutions)
+ else:
+ unwrapFailureCode = failureCode
+
+ typeName = type.unroll().name # unroll because it may be nullable
+
+ if isMember == "Union":
+ typeName = "Heap" + typeName
+
+ templateBody = fill(
+ """
+ match typedarray::${ty}::from($${val}.get().to_object()) {
+ Ok(val) => val,
+ Err(()) => {
+ $*{failureCode}
+ }
+ }
+ """,
+ ty=typeName,
+ failureCode=unwrapFailureCode + "\n",
+ )
+
+ if isMember == "Union":
+ templateBody = "RootedTraceableBox::new(%s)" % templateBody
+
+ declType = CGGeneric("typedarray::%s" % typeName)
+ if type.nullable():
+ templateBody = "Some(%s)" % templateBody
+ declType = CGWrapper(declType, pre="Option<", post=">")
+
+ templateBody = wrapObjectTemplate(templateBody, "None",
+ isDefinitelyObject, type, failureCode)
+
+ return handleOptional(templateBody, declType, handleDefaultNull("None"))
+
+ elif type.isSpiderMonkeyInterface():
+ raise TypeError("Can't handle SpiderMonkey interface arguments other than typed arrays yet")
if type.isDOMString():
nullBehavior = getConversionConfigForType(type, isEnforceRange, isClamp, treatNullAs)
@@ -1041,13 +1084,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
assert isMember != "Union"
if isMember == "Dictionary" or isAutoRooted:
- # TODO: Need to properly root dictionaries
- # https://github.com/servo/servo/issues/6381
- if isMember == "Dictionary":
- declType = CGGeneric("Heap<JSVal>")
- # AutoRooter can trace properly inner raw GC thing pointers
- else:
- declType = CGGeneric("JSVal")
+ templateBody = "${val}.get()"
if defaultValue is None:
default = None
@@ -1057,7 +1094,17 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
default = "UndefinedValue()"
else:
raise TypeError("Can't handle non-null, non-undefined default value here")
- return handleOptional("${val}.get()", declType, default)
+
+ if isMember == "Dictionary":
+ templateBody = "RootedTraceableBox::from_box(Heap::boxed(%s))" % templateBody
+ if default is not None:
+ default = "RootedTraceableBox::from_box(Heap::boxed(%s))" % default
+ declType = CGGeneric("RootedTraceableBox<Heap<JSVal>>")
+ # AutoRooter can trace properly inner raw GC thing pointers
+ else:
+ declType = CGGeneric("JSVal")
+
+ return handleOptional(templateBody, declType, default)
declType = CGGeneric("HandleValue")
@@ -1075,20 +1122,21 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if type.isObject():
assert not isEnforceRange and not isClamp
- # TODO: Need to root somehow
- # https://github.com/servo/servo/issues/6382
+ templateBody = "${val}.get().to_object()"
default = "ptr::null_mut()"
- templateBody = wrapObjectTemplate("${val}.get().to_object()",
- default,
- isDefinitelyObject, type, failureCode)
if isMember in ("Dictionary", "Union"):
- declType = CGGeneric("Heap<*mut JSObject>")
+ templateBody = "RootedTraceableBox::from_box(Heap::boxed(%s))" % templateBody
+ default = "RootedTraceableBox::new(Heap::default())"
+ declType = CGGeneric("RootedTraceableBox<Heap<*mut JSObject>>")
else:
# TODO: Need to root somehow
# https://github.com/servo/servo/issues/6382
declType = CGGeneric("*mut JSObject")
+ templateBody = wrapObjectTemplate(templateBody, default,
+ isDefinitelyObject, type, failureCode)
+
return handleOptional(templateBody, declType,
handleDefaultNull(default))
@@ -2283,6 +2331,7 @@ def UnionTypes(descriptors, dictionaries, callbacks, typedefs, config):
'js::jsapi::JSObject',
'js::jsapi::MutableHandleValue',
'js::jsval::JSVal',
+ 'js::typedarray'
]
# Now find all the things we'll need as arguments and return values because
@@ -4134,6 +4183,9 @@ def getUnionTypeTemplateVars(type, descriptorProvider):
elif type.isObject():
name = type.name
typeName = "Heap<*mut JSObject>"
+ elif is_typed_array(type):
+ name = type.name
+ typeName = "typedarray::Heap" + name
else:
raise TypeError("Can't handle %s in unions yet" % type)
@@ -4291,11 +4343,13 @@ class CGUnionConversionStruct(CGThing):
else:
mozMapObject = None
- hasObjectTypes = interfaceObject or arrayObject or dateObject or object or mozMapObject
+ hasObjectTypes = object or interfaceObject or arrayObject or dateObject or mozMapObject
if hasObjectTypes:
# "object" is not distinguishable from other types
assert not object or not (interfaceObject or arrayObject or dateObject or callbackObject or mozMapObject)
templateBody = CGList([], "\n")
+ if object:
+ templateBody.append(object)
if interfaceObject:
templateBody.append(interfaceObject)
if arrayObject:
@@ -4363,11 +4417,6 @@ class CGUnionConversionStruct(CGThing):
returnType = "Result<Option<%s>, ()>" % actualType
jsConversion = templateVars["jsConversion"]
- # Any code to convert to Object is unused, since we're already converting
- # from an Object value.
- if t.name == 'Object':
- return CGGeneric('')
-
return CGWrapper(
CGIndenter(jsConversion, 4),
pre="unsafe fn TryConvertTo%s(cx: *mut JSContext, value: HandleValue) -> %s {\n"
@@ -5687,6 +5736,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'js::jsapi::MutableHandleValue',
'js::jsapi::ObjectOpResult',
'js::jsapi::PropertyDescriptor',
+ 'js::jsapi::Rooted',
'js::jsapi::RootedId',
'js::jsapi::RootedObject',
'js::jsapi::RootedString',
@@ -5718,6 +5768,7 @@ def generate_imports(config, cgthings, descriptors, callbacks=None, dictionaries
'js::rust::define_methods',
'js::rust::define_properties',
'js::rust::get_object_class',
+ 'js::typedarray',
'dom',
'dom::bindings',
'dom::bindings::codegen::InterfaceObjectMap',
@@ -6118,8 +6169,6 @@ class CGDictionary(CGThing):
conversion = self.getMemberConversion(memberInfo, member.type)
if isInitial:
return CGGeneric("%s: %s,\n" % (name, conversion.define()))
- if member.type.isAny() or member.type.isObject():
- return CGGeneric("dictionary.%s.set(%s);\n" % (name, conversion.define()))
return CGGeneric("dictionary.%s = %s;\n" % (name, conversion.define()))
def varInsert(varName, dictionaryName):
@@ -6418,6 +6467,9 @@ def type_needs_tracing(t):
if t.isUnion():
return any(type_needs_tracing(member) for member in t.flatMemberTypes)
+ if is_typed_array(t):
+ return True
+
return False
if t.isDictionary():
@@ -6438,6 +6490,12 @@ def type_needs_tracing(t):
assert False, (t, type(t))
+def is_typed_array(t):
+ assert isinstance(t, IDLObject), (t, type(t))
+
+ return t.isTypedArray() or t.isArrayBuffer() or t.isArrayBufferView() or t.isSharedArrayBuffer()
+
+
def type_needs_auto_root(t):
"""
Certain IDL types, such as `sequence<any>` or `sequence<object>` need to be
@@ -6448,6 +6506,9 @@ def type_needs_auto_root(t):
if t.isType():
if t.isSequence() and (t.inner.isAny() or t.inner.isObject()):
return True
+ # SpiderMonkey interfaces, we currently don't support any other except typed arrays
+ if is_typed_array(t):
+ return True
return False