aboutsummaryrefslogtreecommitdiffstats
path: root/src/components/script/dom/bindings/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/script/dom/bindings/codegen')
-rw-r--r--src/components/script/dom/bindings/codegen/CodegenRust.py205
1 files changed, 29 insertions, 176 deletions
diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py
index 7c6b7bed88a..c1d4ac46aaa 100644
--- a/src/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/src/components/script/dom/bindings/codegen/CodegenRust.py
@@ -1038,120 +1038,18 @@ class CGArgumentConverter(CGThing):
self.replacementVariables,
self.argcAndIndex).define()
-def getWrapTemplateForType(type, descriptorProvider, result, successCode,
- isCreator, exceptionCode):
- """
- Reflect a C++ value stored in "result", of IDL type "type" into JS. The
- "successCode" is the code to run once we have successfully done the
- conversion. The resulting string should be used with string.Template, it
- needs the following keys when substituting: jsvalPtr/jsvalRef/obj.
- Returns (templateString, infallibility of conversion template)
+def wrapForType(jsvalRef, result='result', successCode='return 1;'):
"""
- haveSuccessCode = successCode is not None
- if not haveSuccessCode:
- successCode = "return 1;"
-
- # We often want exceptionCode to be indented, since it often appears in an
- # if body.
- exceptionCodeIndented = CGIndenter(CGGeneric(exceptionCode))
-
- def setValue(value, callWrapValue=False):
- """
- Returns the code to set the jsval to value. If "callWrapValue" is true
- JS_WrapValue will be called on the jsval.
- """
- if not callWrapValue:
- tail = successCode
- elif haveSuccessCode:
- tail = ("if JS_WrapValue(cx, ${jsvalPtr}) == 0 {\n" +
- " return 0;\n" +
- "}\n" +
- successCode)
- else:
- tail = "return JS_WrapValue(cx, ${jsvalPtr} as *JSVal);"
- return ("${jsvalRef} = %s;\n" +
- tail) % (value)
-
- if type is None or type.isVoid():
- return (setValue("UndefinedValue()"), True)
-
- if type.isArray():
- raise TypeError("Can't handle array return values yet")
-
- if type.isSequence():
- raise TypeError("Can't handle sequence return values yet")
-
- if type.isGeckoInterface():
- return (setValue("(%s).to_jsval(cx)" % result), True)
-
- if type.isString():
- return (setValue("(%s).to_jsval(cx)" % result), True)
+ Reflect a Rust value into JS.
- if type.isEnum():
- return (setValue("(%s).to_jsval(cx)" % result), True)
-
- if type.isCallback():
- assert not type.isInterface()
- # XXXbz we're going to assume that callback types are always
- # nullable and always have [TreatNonCallableAsNull] for now.
- # See comments in WrapNewBindingObject explaining why we need
- # to wrap here.
- # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
- return (setValue("JS::ObjectOrNullValue(%s)" % result, True), False)
-
- if type.tag() == IDLType.Tags.any:
- # See comments in WrapNewBindingObject explaining why we need
- # to wrap here.
- # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
- return (setValue(result, True), False)
-
- if type.isObject() or type.isSpiderMonkeyInterface():
- # See comments in WrapNewBindingObject explaining why we need
- # to wrap here.
- if type.nullable():
- toValue = "ObjectOrNullValue(%s)"
- else:
- toValue = "ObjectValue(&*(%s))"
- # NB: setValue(..., True) calls JS_WrapValue(), so is fallible
- return (setValue(toValue % result, True), False)
-
- if not type.isPrimitive():
- raise TypeError("Need to learn to wrap %s" % type)
-
- return (setValue("(%s).to_jsval(cx)" % result), True)
-
-
-def wrapForType(type, descriptorProvider, templateValues):
+ * 'jsvalRef': a Rust reference to the JSVal in which to store the result
+ of the conversion;
+ * 'result': the name of the variable in which the Rust value is stored;
+ * 'successCode': the code to run once we have done the conversion.
"""
- Reflect a C++ value of IDL type "type" into JS. TemplateValues is a dict
- that should contain:
-
- * 'jsvalRef': a C++ reference to the jsval in which to store the result of
- the conversion
- * 'jsvalPtr': a C++ pointer to the jsval in which to store the result of
- the conversion
- * 'obj' (optional): the name of the variable that contains the JSObject to
- use as a scope when wrapping, if not supplied 'obj'
- will be used as the name
- * 'result' (optional): the name of the variable in which the C++ value is
- stored, if not supplied 'result' will be used as
- the name
- * 'successCode' (optional): the code to run once we have successfully done
- the conversion, if not supplied 'return true;'
- will be used as the code
- * 'isCreator' (optional): If true, we're wrapping for the return value of
- a [Creator] method. Assumed false if not set.
- """
- wrap = getWrapTemplateForType(type, descriptorProvider,
- templateValues.get('result', 'result'),
- templateValues.get('successCode', None),
- templateValues.get('isCreator', False),
- templateValues.get('exceptionCode',
- "return 0;"),)[0]
+ return "%s = (%s).to_jsval(cx);\n%s" % (jsvalRef, result, successCode)
- defaultValues = {'obj': 'obj'}
- return string.Template(wrap).substitute(defaultValues, **templateValues)
def typeNeedsCx(type, retVal=False):
if type is None:
@@ -1959,12 +1857,6 @@ class CGAbstractMethod(CGThing):
def definition_body(self):
assert(False) # Override me!
-def DOMObjectPointerType(descriptor):
- return "~"
-
-def DOMObjectPointerArg(descriptor):
- return DOMObjectPointerType(descriptor) + descriptor.concreteType
-
def CreateBindingJSObject(descriptor, parent=None):
create = " let mut raw: JS<%s> = JS::from_raw(&mut *aObject);\n" % descriptor.concreteType
if descriptor.proxy:
@@ -1997,10 +1889,10 @@ class CGWrapMethod(CGAbstractMethod):
assert descriptor.interface.hasInterfacePrototypeObject()
if not descriptor.createGlobal:
args = [Argument('*JSContext', 'aCx'), Argument('&JS<Window>', 'aScope'),
- Argument(DOMObjectPointerArg(descriptor), 'aObject', mutable=True)]
+ Argument("~" + descriptor.concreteType, 'aObject', mutable=True)]
else:
args = [Argument('*JSContext', 'aCx'),
- Argument(DOMObjectPointerArg(descriptor), 'aObject', mutable=True)]
+ Argument("~" + descriptor.concreteType, 'aObject', mutable=True)]
retval = 'JS<%s>' % descriptor.concreteType
CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args, pub=True)
@@ -2444,18 +2336,7 @@ class CGPerSignatureCall(CGThing):
return not 'infallible' in self.extendedAttributes
def wrap_return_value(self):
- isCreator = memberIsCreator(self.idlNode)
- resultTemplateValues = { 'jsvalRef': '*vp', 'jsvalPtr': 'vp',
- 'isCreator': isCreator}
- try:
- return wrapForType(self.returnType, self.descriptor,
- resultTemplateValues)
- except MethodNotCreatorError, err:
- assert not isCreator
- raise TypeError("%s being returned from non-creator method or property %s.%s" %
- (err.typename,
- self.descriptor.interface.identifier.name,
- self.idlNode.identifier.name))
+ return wrapForType('*vp')
def getErrorReport(self):
return CGGeneric(
@@ -2757,19 +2638,6 @@ class CGSpecializedSetter(CGAbstractExternMethod):
" let obj = *obj.unnamed;\n" +
" let this = &mut *this;\n").define()
-def infallibleForMember(member, type, descriptorProvider):
- """
- Determine the fallibility of changing a C++ value of IDL type "type" into
- JS for the given attribute. Apart from isCreator, all the defaults are used,
- since the fallbility does not change based on the boolean values,
- and the template will be discarded.
-
- CURRENT ASSUMPTIONS:
- We assume that successCode for wrapping up return values cannot contain
- failure conditions.
- """
- return getWrapTemplateForType(type, descriptorProvider, 'result', None,\
- memberIsCreator(member), "return false;",)[1]
class CGMemberJITInfo(CGThing):
"""
@@ -2798,7 +2666,6 @@ class CGMemberJITInfo(CGThing):
getterinfo = ("%s_getterinfo" % self.member.identifier.name)
getter = ("get_%s" % self.member.identifier.name)
getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)
- getterinfal = getterinfal and infallibleForMember(self.member, self.member.type, self.descriptor)
result = self.defineJitInfo(getterinfo, getter, getterinfal)
if not self.member.readonly:
setterinfo = ("%s_setterinfo" % self.member.identifier.name)
@@ -2820,7 +2687,7 @@ class CGMemberJITInfo(CGThing):
# Don't handle overloading. If there's more than one signature,
# one of them must take arguments.
sig = sigs[0]
- if len(sig[1]) == 0 and infallibleForMember(self.member, sig[0], self.descriptor):
+ if len(sig[1]) == 0:
# No arguments and infallible return boxing
methodInfal = True
@@ -3692,7 +3559,7 @@ class CGProxySpecialOperation(CGPerSignatureCall):
if not self.idlNode.isGetter() or self.templateValues is None:
return ""
- wrap = CGGeneric(wrapForType(self.returnType, self.descriptor, self.templateValues))
+ wrap = CGGeneric(wrapForType(**self.templateValues))
wrap = CGIfWrapper(wrap, "found")
return "\n" + wrap.define()
@@ -3760,8 +3627,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
if indexedGetter:
readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None)
fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn 1;" % readonly
- templateValues = {'jsvalRef': '(*desc).value', 'jsvalPtr': '&mut (*desc).value',
- 'obj': 'proxy', 'successCode': fillDescriptor}
+ templateValues = {'jsvalRef': '(*desc).value', 'successCode': fillDescriptor}
get = ("if index.is_some() {\n" +
" let index = index.unwrap();\n" +
" let this: *%s = UnwrapProxy(proxy);\n" +
@@ -3802,8 +3668,7 @@ class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
if namedGetter:
readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None)
fillDescriptor = "FillPropertyDescriptor(&mut *desc, proxy, %s);\nreturn 1;" % readonly
- templateValues = {'jsvalRef': '(*desc).value', 'jsvalPtr': '&mut(*desc).value',
- 'obj': 'proxy', 'successCode': fillDescriptor}
+ templateValues = {'jsvalRef': '(*desc).value', 'successCode': fillDescriptor}
# Once we start supporting OverrideBuiltins we need to make
# ResolveOwnProperty or EnumerateOwnProperties filter out named
# properties that shadow prototype properties.
@@ -3957,7 +3822,7 @@ if expando.is_not_null() {
}
}"""
- templateValues = {'jsvalRef': '*vp', 'jsvalPtr': 'vp', 'obj': 'proxy'}
+ templateValues = {'jsvalRef': '*vp'}
indexedGetter = self.descriptor.operations['IndexedGetter']
if indexedGetter:
@@ -4060,9 +3925,9 @@ class CGAbstractClassHook(CGAbstractExternMethod):
def finalizeHook(descriptor, hookName, context):
release = """let val = JS_GetReservedSlot(obj, dom_object_slot(obj));
-let _: %s %s = cast::transmute(val.to_private());
+let _: ~%s = cast::transmute(val.to_private());
debug!("%s finalize: {:p}", this);
-""" % (DOMObjectPointerType(descriptor), descriptor.concreteType, descriptor.concreteType)
+""" % (descriptor.concreteType, descriptor.concreteType)
return release
class CGClassTraceHook(CGAbstractClassHook):
@@ -5293,21 +5158,9 @@ class CallbackMember(CGNativeMember):
result = argval
prepend = ""
- conversion = prepend + wrapForType(
- arg.type, self.descriptorProvider,
- {
- 'result' : result,
- 'successCode' : "continue;" if arg.variadic else "break;",
- 'jsvalRef' : "argv[%s]" % jsvalIndex,
- 'jsvalHandle' : "argv.handleAt(%s)" % jsvalIndex,
- 'jsvalPtr': "&mut argv[%s]" % jsvalIndex,
- # XXXbz we don't have anything better to use for 'obj',
- # really... It's OK to use CallbackPreserveColor because
- # CallSetup already handled the unmark-gray bits for us.
- 'obj' : 'ptr::null() /*XXXjdm proper scope*/', #XXXjdm 'CallbackPreserveColor()',
- 'returnsNewObject': False,
- 'exceptionCode' : self.exceptionCode
- })
+ conversion = prepend + wrapForType("argv[%s]" % jsvalIndex,
+ result=result,
+ successCode="continue;" if arg.variadic else "break;")
if arg.variadic:
conversion = string.Template(
"for (uint32_t idx = 0; idx < ${arg}.Length(); ++idx) {\n" +
@@ -5453,19 +5306,19 @@ class CallbackOperationBase(CallbackMethod):
"methodName": self.methodName
}
getCallableFromProp = string.Template(
- 'if "${methodName}".to_c_str().with_ref(|name| !self.parent.GetCallableProperty(cx, name, &mut callable)) {\n'
- ' return${errorReturn};\n'
- '}\n').substitute(replacements)
+ 'match self.parent.GetCallableProperty(cx, "${methodName}") {\n'
+ ' Err(_) => return${errorReturn},\n'
+ ' Ok(callable) => callable,\n'
+ '}').substitute(replacements)
if not self.singleOperation:
return 'JS::Rooted<JS::Value> callable(cx);\n' + getCallableFromProp
return (
'let isCallable = unsafe { JS_ObjectIsCallable(cx, self.parent.callback) != 0 };\n'
- 'let mut callable = UndefinedValue();\n'
- 'if isCallable {\n'
- ' callable = unsafe { ObjectValue(&*self.parent.callback) };\n'
- '} else {\n'
- '%s'
- '}\n' % CGIndenter(CGGeneric(getCallableFromProp)).define())
+ 'let callable =\n' +
+ CGIndenter(
+ CGIfElseWrapper('isCallable',
+ CGGeneric('unsafe { ObjectValue(&*self.parent.callback) }'),
+ CGGeneric(getCallableFromProp))).define() + ';\n')
class CallbackOperation(CallbackOperationBase):
"""