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.py1454
1 files changed, 905 insertions, 549 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index aa1b1ae14d3..f9e929c68da 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -8,12 +8,15 @@ import operator
import os
import re
import string
+import textwrap
+import functools
from WebIDL import (
BuiltinTypes,
IDLBuiltinType,
IDLNullValue,
IDLType,
+ IDLInterfaceMember,
IDLUndefinedValue,
)
@@ -103,15 +106,16 @@ class CastableObjectUnwrapper():
codeOnFailure is the code to run if unwrapping fails.
"""
- def __init__(self, descriptor, source, codeOnFailure):
+ def __init__(self, descriptor, source, codeOnFailure, handletype):
self.substitution = {
"source": source,
"codeOnFailure": CGIndenter(CGGeneric(codeOnFailure), 8).define(),
+ "handletype": handletype,
}
def __str__(self):
return string.Template("""\
-match native_from_reflector_jsmanaged(${source}) {
+match native_from_handle${handletype}(${source}) {
Ok(val) => val,
Err(()) => {
${codeOnFailure}
@@ -119,6 +123,136 @@ ${codeOnFailure}
}""").substitute(self.substitution)
+# We'll want to insert the indent at the beginnings of lines, but we
+# don't want to indent empty lines. So only indent lines that have a
+# non-newline character on them.
+lineStartDetector = re.compile("^(?=[^\n#])", re.MULTILINE)
+
+
+def indent(s, indentLevel=2):
+ """
+ Indent C++ code.
+
+ Weird secret feature: this doesn't indent lines that start with # (such as
+ #include lines or #ifdef/#endif).
+ """
+ if s == "":
+ return s
+ return re.sub(lineStartDetector, indentLevel * " ", s)
+
+
+# dedent() and fill() are often called on the same string multiple
+# times. We want to memoize their return values so we don't keep
+# recomputing them all the time.
+def memoize(fn):
+ """
+ Decorator to memoize a function of one argument. The cache just
+ grows without bound.
+ """
+ cache = {}
+ @functools.wraps(fn)
+ def wrapper(arg):
+ retval = cache.get(arg)
+ if retval is None:
+ retval = cache[arg] = fn(arg)
+ return retval
+ return wrapper
+
+@memoize
+def dedent(s):
+ """
+ Remove all leading whitespace from s, and remove a blank line
+ at the beginning.
+ """
+ if s.startswith('\n'):
+ s = s[1:]
+ return textwrap.dedent(s)
+
+
+# This works by transforming the fill()-template to an equivalent
+# string.Template.
+fill_multiline_substitution_re = re.compile(r"( *)\$\*{(\w+)}(\n)?")
+
+
+@memoize
+def compile_fill_template(template):
+ """
+ Helper function for fill(). Given the template string passed to fill(),
+ do the reusable part of template processing and return a pair (t,
+ argModList) that can be used every time fill() is called with that
+ template argument.
+
+ argsModList is list of tuples that represent modifications to be
+ made to args. Each modification has, in order: i) the arg name,
+ ii) the modified name, iii) the indent depth.
+ """
+ t = dedent(template)
+ assert t.endswith("\n") or "\n" not in t
+ argModList = []
+
+ def replace(match):
+ """
+ Replaces a line like ' $*{xyz}\n' with '${xyz_n}',
+ where n is the indent depth, and add a corresponding entry to
+ argModList.
+
+ Note that this needs to close over argModList, so it has to be
+ defined inside compile_fill_template().
+ """
+ indentation, name, nl = match.groups()
+ depth = len(indentation)
+
+ # Check that $*{xyz} appears by itself on a line.
+ prev = match.string[:match.start()]
+ if (prev and not prev.endswith("\n")) or nl is None:
+ raise ValueError("Invalid fill() template: $*{%s} must appear by itself on a line" % name)
+
+ # Now replace this whole line of template with the indented equivalent.
+ modified_name = name + "_" + str(depth)
+ argModList.append((name, modified_name, depth))
+ return "${" + modified_name + "}"
+
+ t = re.sub(fill_multiline_substitution_re, replace, t)
+ return (string.Template(t), argModList)
+
+def fill(template, **args):
+ """
+ Convenience function for filling in a multiline template.
+
+ `fill(template, name1=v1, name2=v2)` is a lot like
+ `string.Template(template).substitute({"name1": v1, "name2": v2})`.
+
+ However, it's shorter, and has a few nice features:
+
+ * If `template` is indented, fill() automatically dedents it!
+ This makes code using fill() with Python's multiline strings
+ much nicer to look at.
+
+ * If `template` starts with a blank line, fill() strips it off.
+ (Again, convenient with multiline strings.)
+
+ * fill() recognizes a special kind of substitution
+ of the form `$*{name}`.
+
+ Use this to paste in, and automatically indent, multiple lines.
+ (Mnemonic: The `*` is for "multiple lines").
+
+ A `$*` substitution must appear by itself on a line, with optional
+ preceding indentation (spaces only). The whole line is replaced by the
+ corresponding keyword argument, indented appropriately. If the
+ argument is an empty string, no output is generated, not even a blank
+ line.
+ """
+
+ t, argModList = compile_fill_template(template)
+ # Now apply argModList to args
+ for (name, modified_name, depth) in argModList:
+ if not (args[name] == "" or args[name].endswith("\n")):
+ raise ValueError("Argument %s with value %r is missing a newline" % (name, args[name]))
+ args[modified_name] = indent(args[name], depth)
+
+ return t.substitute(args)
+
class CGThing():
"""
Abstract base class for things that spit out code.
@@ -232,14 +366,13 @@ class CGMethodCall(CGThing):
# Doesn't matter which of the possible signatures we use, since
# they all have the same types up to that point; just use
# possibleSignatures[0]
- caseBody = [CGGeneric("let argv_start = JS_ARGV(cx, vp);")]
- caseBody.extend([ CGArgumentConverter(possibleSignatures[0][1][i],
- i, "argv_start", "argc",
+ caseBody = [ CGArgumentConverter(possibleSignatures[0][1][i],
+ i, "args", "argc",
descriptor) for i in
- range(0, distinguishingIndex) ])
+ range(0, distinguishingIndex) ]
# Select the right overload from our set.
- distinguishingArg = "(*argv_start.offset(%d))" % distinguishingIndex
+ distinguishingArg = "args.get(%d)" % distinguishingIndex
def pickFirstSignature(condition, filterLambda):
sigs = filter(filterLambda, possibleSignatures)
@@ -282,7 +415,7 @@ class CGMethodCall(CGThing):
# also allow the unwrapping test to skip having to do codegen
# for the null-or-undefined case, which we already handled
# above.
- caseBody.append(CGGeneric("if (%s).is_object() {" %
+ caseBody.append(CGGeneric("if %s.get().is_object() {" %
(distinguishingArg)))
for idx, sig in enumerate(interfacesSigs):
caseBody.append(CGIndenter(CGGeneric("loop {")));
@@ -319,7 +452,7 @@ class CGMethodCall(CGThing):
# XXXbz Now we're supposed to check for distinguishingArg being
# an array or a platform object that supports indexed
# properties... skip that last for now. It's a bit of a pain.
- pickFirstSignature("%s.isObject() && IsArrayLike(cx, &%s.toObject())" %
+ pickFirstSignature("%s.get().isObject() && IsArrayLike(cx, &%s.get().toObject())" %
(distinguishingArg, distinguishingArg),
lambda s:
(s[1][distinguishingIndex].type.isArray() or
@@ -328,14 +461,14 @@ class CGMethodCall(CGThing):
# Check for Date objects
# XXXbz Do we need to worry about security wrappers around the Date?
- pickFirstSignature("%s.isObject() && JS_ObjectIsDate(cx, &%s.toObject())" %
+ pickFirstSignature("%s.get().isObject() && JS_ObjectIsDate(cx, &%s.get().toObject())" %
(distinguishingArg, distinguishingArg),
lambda s: (s[1][distinguishingIndex].type.isDate() or
s[1][distinguishingIndex].type.isObject()))
# Check for vanilla JS objects
# XXXbz Do we need to worry about security wrappers?
- pickFirstSignature("%s.is_object() && !is_platform_object(%s.to_object())" %
+ pickFirstSignature("%s.get().is_object() && !is_platform_object(%s.get().to_object())" %
(distinguishingArg, distinguishingArg),
lambda s: (s[1][distinguishingIndex].type.isCallback() or
s[1][distinguishingIndex].type.isCallbackInterface() or
@@ -524,7 +657,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
# failureCode will prevent pending exceptions from being set in cases when
# they really should be!
if exceptionCode is None:
- exceptionCode = "return 0;"
+ exceptionCode = "return JSFalse;"
needsRooting = typeNeedsRooting(type, descriptorProvider)
@@ -581,11 +714,11 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
# Handle the non-object cases by wrapping up the whole
# thing in an if cascade.
templateBody = (
- "if (${val}).is_object() {\n" +
+ "if ${val}.get().is_object() {\n" +
CGIndenter(CGGeneric(templateBody)).define() + "\n")
if type.nullable():
templateBody += (
- "} else if (${val}).is_null_or_undefined() {\n"
+ "} else if ${val}.get().is_null_or_undefined() {\n"
" %s\n") % nullValue
templateBody += (
"} else {\n" +
@@ -621,8 +754,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
if descriptor.interface.isCallback():
name = descriptor.nativeType
- declType = CGGeneric(name)
- template = "%s::new((${val}).to_object())" % name
+ declType = CGWrapper(CGGeneric(name), pre="Rc<", post=">")
+ template = "%s::new(${val}.get().to_object())" % name
if type.nullable():
declType = CGWrapper(declType, pre="Option<", post=">")
template = wrapObjectTemplate("Some(%s)" % template, "None",
@@ -658,17 +791,15 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
templateBody = str(CastableObjectUnwrapper(
descriptor,
- "(${val}).to_object()",
- unwrapFailureCode))
+ "${val}",
+ unwrapFailureCode,
+ "value"))
declType = CGGeneric(descriptorType)
if type.nullable():
templateBody = "Some(%s)" % templateBody
declType = CGWrapper(declType, pre="Option<", post=">")
- if isMember:
- templateBody += ".root()"
-
templateBody = wrapObjectTemplate(templateBody, "None",
isDefinitelyObject, type, failureCode)
@@ -681,8 +812,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
assert not isEnforceRange and not isClamp
treatAs = {
- "Default": "Default",
- "EmptyString": "Empty",
+ "Default": "StringificationBehavior::Default",
+ "EmptyString": "StringificationBehavior::Empty",
}
if treatNullAs not in treatAs:
raise TypeError("We don't support [TreatNullAs=%s]" % treatNullAs)
@@ -794,23 +925,25 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
assert not type.treatNonObjectAsNull() or not type.treatNonCallableAsNull()
declType = CGGeneric('%s::%s' % (type.unroll().module(), type.unroll().identifier.name))
+ finalDeclType = CGTemplatedType("Rc", declType)
conversion = CGCallbackTempRoot(declType.define())
if type.nullable():
declType = CGTemplatedType("Option", declType)
+ finalDeclType = CGTemplatedType("Option", finalDeclType)
conversion = CGWrapper(conversion, pre="Some(", post=")")
if allowTreatNonObjectAsNull and type.treatNonObjectAsNull():
if not isDefinitelyObject:
- haveObject = "${val}.is_object()"
+ haveObject = "${val}.get().is_object()"
template = CGIfElseWrapper(haveObject,
conversion,
CGGeneric("None")).define()
else:
template = conversion
else:
- template = CGIfElseWrapper("JS_ObjectIsCallable(cx, ${val}.to_object()) != 0",
+ template = CGIfElseWrapper("IsCallable(${val}.get().to_object()) != 0",
conversion,
onFailureNotCallable(failureCode)).define()
template = wrapObjectTemplate(
@@ -829,29 +962,47 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
else:
default = None
- return JSToNativeConversionInfo(template, default, declType, needsRooting=needsRooting)
+ return JSToNativeConversionInfo(template, default, finalDeclType, needsRooting=needsRooting)
if type.isAny():
assert not isEnforceRange and not isClamp
- declType = CGGeneric("JSVal")
-
- if defaultValue is None:
- default = None
- elif isinstance(defaultValue, IDLNullValue):
- default = "NullValue()"
- elif isinstance(defaultValue, IDLUndefinedValue):
- default = "UndefinedValue()"
+ declType = ""
+ default = ""
+ if isMember == "Dictionary":
+ # TODO: Need to properly root dictionaries
+ # https://github.com/servo/servo/issues/6381
+ declType = CGGeneric("JSVal")
+
+ if defaultValue is None:
+ default = None
+ elif isinstance(defaultValue, IDLNullValue):
+ default = "NullValue()"
+ elif isinstance(defaultValue, IDLUndefinedValue):
+ default = "UndefinedValue()"
+ else:
+ raise TypeError("Can't handle non-null, non-undefined default value here")
else:
- raise TypeError("Can't handle non-null, non-undefined default value here")
+ declType = CGGeneric("HandleValue")
+
+ if defaultValue is None:
+ default = None
+ elif isinstance(defaultValue, IDLNullValue):
+ default = "HandleValue::null()"
+ elif isinstance(defaultValue, IDLUndefinedValue):
+ default = "HandleValue::undefined()"
+ else:
+ raise TypeError("Can't handle non-null, non-undefined default value here")
return handleOptional("${val}", declType, default)
if type.isObject():
assert not isEnforceRange and not isClamp
+ # TODO: Need to root somehow
+ # https://github.com/servo/servo/issues/6382
declType = CGGeneric("*mut JSObject")
- templateBody = wrapObjectTemplate("${val}.to_object()",
+ templateBody = wrapObjectTemplate("${val}.get().to_object()",
"ptr::null_mut()",
isDefinitelyObject, type, failureCode)
@@ -871,7 +1022,7 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
" Err(_) => return 0,\n"
"}" % typeName)
- return handleOptional(template, declType, handleDefaultNull("%s::empty()" % typeName))
+ return handleOptional(template, declType, handleDefaultNull("%s::empty(cx)" % typeName))
if type.isVoid():
# This one only happens for return values, and its easy: Just
@@ -948,11 +1099,6 @@ def instantiateJSToNativeConversionTemplate(templateBody, replacements,
# conversion.
result.append(CGGeneric(""))
- if needsRooting:
- rootBody = "let %s = %s.root();" % (declName, declName)
- result.append(CGGeneric(rootBody))
- result.append(CGGeneric(""))
-
return result;
def convertConstIDLValueToJSVal(value):
@@ -979,7 +1125,7 @@ class CGArgumentConverter(CGThing):
argument list, and the argv and argc strings and generates code to
unwrap the argument to the right native type.
"""
- def __init__(self, argument, index, argv, argc, descriptorProvider,
+ def __init__(self, argument, index, args, argc, descriptorProvider,
invalidEnumValueFatal=True):
CGThing.__init__(self)
assert(not argument.defaultValue or argument.optional)
@@ -987,12 +1133,12 @@ class CGArgumentConverter(CGThing):
replacer = {
"index": index,
"argc": argc,
- "argv": argv
+ "args": args
}
condition = string.Template("${index} < ${argc}").substitute(replacer)
replacementVariables = {
- "val": string.Template("(*${argv}.offset(${index}))").substitute(replacer),
+ "val": string.Template("${args}.get(${index})").substitute(replacer),
}
info = getJSToNativeConversionInfo(
@@ -1032,7 +1178,7 @@ class CGArgumentConverter(CGThing):
else:
assert argument.optional
variadicConversion = {
- "val": string.Template("(*${argv}.offset(variadicArg as isize))").substitute(replacer),
+ "val": string.Template("${args}.get(variadicArg)").substitute(replacer),
}
innerConverter = instantiateJSToNativeConversionTemplate(
template, variadicConversion, declType, "slot",
@@ -1066,16 +1212,17 @@ class CGArgumentConverter(CGThing):
return self.converter.define()
-def wrapForType(jsvalRef, result='result', successCode='return 1;'):
+def wrapForType(jsvalRef, result='result', successCode='return 1;', pre=''):
"""
Reflect a Rust value into JS.
- * 'jsvalRef': a Rust reference to the JSVal in which to store the result
+ * 'jsvalRef': a MutableHandleValue 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.
+ * 'pre': code to run before the conversion if rooting is necessary
"""
- wrap = "%s = (%s).to_jsval(cx);" % (jsvalRef, result)
+ wrap = "%s\n(%s).to_jsval(cx, %s);" % (pre, result, jsvalRef)
if successCode:
wrap += "\n%s" % successCode
return wrap
@@ -1142,8 +1289,8 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
result = CGWrapper(result, pre="Option<", post=">")
return result
if returnType.isCallback():
- result = CGGeneric('%s::%s' % (returnType.unroll().module(),
- returnType.unroll().identifier.name))
+ result = CGGeneric('Rc<%s::%s>' % (returnType.unroll().module(),
+ returnType.unroll().identifier.name))
if returnType.nullable():
result = CGWrapper(result, pre="Option<", post=">")
return result
@@ -1152,6 +1299,8 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
if returnType.nullable():
result = CGWrapper(result, pre="Option<", post=">")
return result
+ # TODO: Return the value through a MutableHandleValue outparam
+ # https://github.com/servo/servo/issues/6307
if returnType.isAny():
return CGGeneric("JSVal")
if returnType.isObject() or returnType.isSpiderMonkeyInterface():
@@ -1258,9 +1407,9 @@ class MethodDefiner(PropertyDefiner):
# FIXME Check for an existing iterator on the interface first.
if any(m.isGetter() and m.isIndexed() for m in methods):
- self.regular.append({"name": 'iterator',
+ self.regular.append({"name": '@@iterator',
"methodInfo": False,
- "nativeName": "JS_ArrayIterator",
+ "selfHostedName": "ArrayValues",
"length": 0,
"flags": "JSPROP_ENUMERATE" })
@@ -1280,21 +1429,31 @@ class MethodDefiner(PropertyDefiner):
return ""
def specData(m):
- if m.get("methodInfo", True):
- identifier = m.get("nativeName", m["name"])
- jitinfo = "&%s_methodinfo" % identifier
- accessor = "genericMethod as NonNullJSNative"
- else:
+ # TODO: Use something like JS_FNSPEC
+ # https://github.com/servo/servo/issues/6391
+ if "selfHostedName" in m:
+ selfHostedName = '%s as *const u8 as *const i8' % str_to_const_array(m["selfHostedName"])
+ assert not m.get("methodInfo", True)
+ accessor = "None"
jitinfo = "0 as *const JSJitInfo"
- accessor = m.get("nativeName", m["name"])
- if accessor[0:3] != 'JS_':
- accessor = "%s as NonNullJSNative" % accessor
- return (str_to_const_array(m["name"]), accessor, jitinfo, m["length"], m["flags"])
+ else:
+ selfHostedName = "0 as *const i8"
+ if m.get("methodInfo", True):
+ identifier = m.get("nativeName", m["name"])
+ jitinfo = "&%s_methodinfo" % identifier
+ accessor = "Some(genericMethod)"
+ else:
+ jitinfo = "0 as *const JSJitInfo"
+ accessor = 'Some(%s)' % m.get("nativeName", m["name"])
+ if m["name"].startswith("@@"):
+ return ('(SymbolCode::%s as i32 + 1)' % m["name"][2:], accessor, jitinfo, m["length"], m["flags"], selfHostedName)
+ return (str_to_const_array(m["name"]), accessor, jitinfo, m["length"], m["flags"], selfHostedName)
+
return self.generatePrefableArray(
array, name,
- ' JSFunctionSpec { name: %s as *const u8 as *const libc::c_char, call: JSNativeWrapper {op: Some(%s), info: %s}, nargs: %s, flags: %s as u16, selfHostedName: 0 as *const libc::c_char }',
- ' JSFunctionSpec { name: 0 as *const libc::c_char, call: JSNativeWrapper {op: None, info: 0 as *const JSJitInfo}, nargs: 0, flags: 0, selfHostedName: 0 as *const libc::c_char }',
+ ' JSFunctionSpec { name: %s as *const u8 as *const libc::c_char, call: JSNativeWrapper {op: %s, info: %s}, nargs: %s, flags: %s as u16, selfHostedName: %s }',
+ ' JSFunctionSpec { name: 0 as *const i8, call: JSNativeWrapper { op: None, info: 0 as *const JSJitInfo }, nargs: 0, flags: 0, selfHostedName: 0 as *const i8 }',
'JSFunctionSpec',
specData)
@@ -1314,12 +1473,12 @@ class AttrDefiner(PropertyDefiner):
return ""
def flags(attr):
- return "JSPROP_SHARED | JSPROP_ENUMERATE | JSPROP_NATIVE_ACCESSORS"
+ return "JSPROP_SHARED | JSPROP_ENUMERATE"
def getter(attr):
if self.static:
accessor = 'get_' + attr.identifier.name
- jitinfo = "0"
+ jitinfo = "0 as *const JSJitInfo"
else:
if attr.hasLenientThis():
accessor = "genericLenientGetter"
@@ -1327,17 +1486,17 @@ class AttrDefiner(PropertyDefiner):
accessor = "genericGetter"
jitinfo = "&%s_getterinfo" % attr.identifier.name
- return ("JSPropertyOpWrapper {op: Some(%(native)s as NonNullJSNative), info: %(info)s as *const JSJitInfo}"
+ return ("JSNativeWrapper { op: Some(%(native)s), info: %(info)s }"
% {"info" : jitinfo,
"native" : accessor})
def setter(attr):
if attr.readonly and not attr.getExtendedAttribute("PutForwards"):
- return "JSStrictPropertyOpWrapper {op: None, info: 0 as *const JSJitInfo}"
+ return "JSNativeWrapper { op: None, info: 0 as *const JSJitInfo }"
if self.static:
accessor = 'set_' + attr.identifier.name
- jitinfo = "0"
+ jitinfo = "0 as *const JSJitInfo"
else:
if attr.hasLenientThis():
accessor = "genericLenientSetter"
@@ -1345,7 +1504,7 @@ class AttrDefiner(PropertyDefiner):
accessor = "genericSetter"
jitinfo = "&%s_setterinfo" % attr.identifier.name
- return ("JSStrictPropertyOpWrapper {op: Some(%(native)s as NonNullJSNative), info: %(info)s as *const JSJitInfo}"
+ return ("JSNativeWrapper { op: Some(%(native)s), info: %(info)s }"
% {"info" : jitinfo,
"native" : accessor})
@@ -1355,8 +1514,8 @@ class AttrDefiner(PropertyDefiner):
return self.generatePrefableArray(
array, name,
- ' JSPropertySpec { name: %s as *const u8 as *const libc::c_char, tinyid: 0, flags: ((%s) & 0xFF) as u8, getter: %s, setter: %s }',
- ' JSPropertySpec { name: 0 as *const libc::c_char, tinyid: 0, flags: 0, getter: JSPropertyOpWrapper {op: None, info: 0 as *const JSJitInfo}, setter: JSStrictPropertyOpWrapper {op: None, info: 0 as *const JSJitInfo} }',
+ ' JSPropertySpec { name: %s as *const u8 as *const libc::c_char, flags: ((%s) & 0xFF) as u8, getter: %s, setter: %s }',
+ ' JSPropertySpec { name: 0 as *const i8, flags: 0, getter: JSNativeWrapper { op: None, info: 0 as *const JSJitInfo }, setter: JSNativeWrapper { op: None, info: 0 as *const JSJitInfo } }',
'JSPropertySpec',
specData)
@@ -1562,8 +1721,9 @@ class CGDOMJSClass(CGThing):
self.descriptor = descriptor
def define(self):
- traceHook = 'Some(%s as unsafe extern "C" fn(*mut JSTracer, *mut JSObject))' % TRACE_HOOK_NAME
+ traceHook = 'Some(%s)' % TRACE_HOOK_NAME
if self.descriptor.isGlobal():
+ traceHook = "Some(js::jsapi::_Z24JS_GlobalObjectTraceHookP8JSTracerP8JSObject)"
flags = "JSCLASS_IS_GLOBAL | JSCLASS_DOM_GLOBAL"
slots = "JSCLASS_GLOBAL_SLOT_COUNT + 1"
else:
@@ -1571,66 +1731,54 @@ class CGDOMJSClass(CGThing):
slots = "1"
return """\
static Class: DOMJSClass = DOMJSClass {
- base: js::Class {
+ base: js::jsapi::Class {
name: %s as *const u8 as *const libc::c_char,
- flags: JSCLASS_IS_DOMJSCLASS | %s | (((%s) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT), //JSCLASS_HAS_RESERVED_SLOTS(%s),
- addProperty: Some(JS_PropertyStub),
- delProperty: Some(JS_PropertyStub),
- getProperty: Some(JS_PropertyStub),
- setProperty: Some(JS_StrictPropertyStub),
- enumerate: Some(JS_EnumerateStub),
- resolve: Some(JS_ResolveStub),
- convert: Some(JS_ConvertStub),
- finalize: Some(%s as unsafe extern "C" fn(*mut JSFreeOp, *mut JSObject)),
- checkAccess: None,
+ flags: JSCLASS_IS_DOMJSCLASS | JSCLASS_IMPLEMENTS_BARRIERS | %s | (((%s) & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT), //JSCLASS_HAS_RESERVED_SLOTS(%s),
+ addProperty: None,
+ delProperty: None,
+ getProperty: None,
+ setProperty: None,
+ enumerate: None,
+ resolve: None,
+ convert: None,
+ finalize: Some(%s),
call: None,
hasInstance: None,
construct: None,
trace: %s,
- ext: js::ClassExtension {
- equality: 0 as *const u8,
+ spec: js::jsapi::ClassSpec {
+ createConstructor: None,
+ createPrototype: None,
+ constructorFunctions: 0 as *const js::jsapi::JSFunctionSpec,
+ constructorProperties: 0 as *const js::jsapi::JSPropertySpec,
+ prototypeFunctions: 0 as *const js::jsapi::JSFunctionSpec,
+ prototypeProperties: 0 as *const js::jsapi::JSPropertySpec,
+ finishInit: None,
+ flags: 0,
+ },
+
+ ext: js::jsapi::ClassExtension {
outerObject: %s,
innerObject: None,
- iteratorObject: 0 as *const u8,
- unused: 0 as *const u8,
- isWrappedNative: 0 as *const u8,
+ isWrappedNative: 0,
+ weakmapKeyDelegateOp: None,
+ objectMovedOp: None,
},
- ops: js::ObjectOps {
- lookupGeneric: 0 as *const u8,
- lookupProperty: 0 as *const u8,
- lookupElement: 0 as *const u8,
- lookupSpecial: 0 as *const u8,
- defineGeneric: 0 as *const u8,
- defineProperty: 0 as *const u8,
- defineElement: 0 as *const u8,
- defineSpecial: 0 as *const u8,
- getGeneric: 0 as *const u8,
- getProperty: 0 as *const u8,
- getElement: 0 as *const u8,
- getElementIfPresent: 0 as *const u8,
- getSpecial: 0 as *const u8,
- setGeneric: 0 as *const u8,
- setProperty: 0 as *const u8,
- setElement: 0 as *const u8,
- setSpecial: 0 as *const u8,
- getGenericAttributes: 0 as *const u8,
- getPropertyAttributes: 0 as *const u8,
- getElementAttributes: 0 as *const u8,
- getSpecialAttributes: 0 as *const u8,
- setGenericAttributes: 0 as *const u8,
- setPropertyAttributes: 0 as *const u8,
- setElementAttributes: 0 as *const u8,
- setSpecialAttributes: 0 as *const u8,
- deleteProperty: 0 as *const u8,
- deleteElement: 0 as *const u8,
- deleteSpecial: 0 as *const u8,
-
- enumerate: 0 as *const u8,
- typeOf: 0 as *const u8,
+ ops: js::jsapi::ObjectOps {
+ lookupProperty: None,
+ defineProperty: None,
+ hasProperty: None,
+ getProperty: None,
+ setProperty: None,
+ getOwnPropertyDescriptor: None,
+ deleteProperty: None,
+ watch: None,
+ unwatch: None,
+ getElements: None,
+ enumerate: None,
thisObject: %s,
- clear: 0 as *const u8,
},
},
dom_class: %s
@@ -1640,7 +1788,7 @@ static Class: DOMJSClass = DOMJSClass {
FINALIZE_HOOK_NAME, traceHook,
self.descriptor.outerObjectHook,
self.descriptor.outerObjectHook,
- CGIndenter(CGGeneric(DOMClass(self.descriptor))).define())
+ CGGeneric(DOMClass(self.descriptor)).define())
def str_to_const_array(s):
return "b\"%s\\0\"" % s
@@ -1655,20 +1803,19 @@ class CGPrototypeJSClass(CGThing):
static PrototypeClass: JSClass = JSClass {
name: %s as *const u8 as *const libc::c_char,
flags: (1 & JSCLASS_RESERVED_SLOTS_MASK) << JSCLASS_RESERVED_SLOTS_SHIFT, //JSCLASS_HAS_RESERVED_SLOTS(1)
- addProperty: Some(JS_PropertyStub),
- delProperty: Some(JS_PropertyStub),
- getProperty: Some(JS_PropertyStub),
- setProperty: Some(JS_StrictPropertyStub),
- enumerate: Some(JS_EnumerateStub),
- resolve: Some(JS_ResolveStub),
- convert: Some(JS_ConvertStub),
+ addProperty: None,
+ delProperty: None,
+ getProperty: None,
+ setProperty: None,
+ enumerate: None,
+ resolve: None,
+ convert: None,
finalize: None,
- checkAccess: None,
call: None,
hasInstance: None,
construct: None,
trace: None,
- reserved: [0 as *mut libc::c_void; 40]
+ reserved: [0 as *mut libc::c_void; 25]
};
""" % str_to_const_array(self.descriptor.interface.identifier.name + "Prototype")
@@ -1742,13 +1889,7 @@ class CGGeneric(CGThing):
class CGCallbackTempRoot(CGGeneric):
def __init__(self, name):
- val = "%s::new(tempRoot)" % name
- define = """\
-{
- let tempRoot = ${val}.to_object();
- %s
-}""" % val
- CGGeneric.__init__(self, define)
+ CGGeneric.__init__(self, "%s::new(${val}.get().to_object())" % name)
def getAllTypes(descriptors, dictionaries, callbacks):
@@ -1792,12 +1933,13 @@ def UnionTypes(descriptors, dictionaries, callbacks, config):
'dom::bindings::codegen::PrototypeList',
'dom::bindings::conversions::FromJSValConvertible',
'dom::bindings::conversions::ToJSValConvertible',
- 'dom::bindings::conversions::native_from_reflector_jsmanaged',
- 'dom::bindings::conversions::StringificationBehavior::Default',
+ 'dom::bindings::conversions::native_from_handlevalue',
+ 'dom::bindings::conversions::StringificationBehavior',
'dom::bindings::error::throw_not_in_union',
- 'dom::bindings::js::Unrooted',
+ 'dom::bindings::js::Root',
'dom::types::*',
'js::jsapi::JSContext',
+ 'js::jsapi::{HandleValue, MutableHandleValue}',
'js::jsval::JSVal',
'util::str::DOMString',
]
@@ -1917,32 +2059,36 @@ class CGAbstractMethod(CGThing):
assert(False) # Override me!
def CreateBindingJSObject(descriptor, parent=None):
- create = "let mut raw: Unrooted<%s> = Unrooted::from_raw(&*object);\n" % descriptor.concreteType
+ create = "let mut raw = boxed::into_raw(object);\nlet _rt = RootedTraceable::new(&*raw);\n"
if descriptor.proxy:
assert not descriptor.isGlobal()
create += """
let handler = RegisterBindings::proxy_handlers[PrototypeList::Proxies::%s as usize];
-let mut private = PrivateValue(boxed::into_raw(object) as *const libc::c_void);
-let obj = with_compartment(cx, proto, || {
+let private = RootedValue::new(cx, PrivateValue(raw as *const libc::c_void));
+let obj = {
+ let _ac = JSAutoCompartment::new(cx, proto.ptr);
NewProxyObject(cx, handler,
- &private,
- proto, %s,
+ private.handle(),
+ proto.ptr, %s.get(),
ptr::null_mut(), ptr::null_mut())
-});
-assert!(!obj.is_null());\
+};
+assert!(!obj.is_null());
+let obj = RootedObject::new(cx, obj);\
""" % (descriptor.name, parent)
else:
if descriptor.isGlobal():
- create += "let obj = create_dom_global(cx, &Class.base as *const js::Class as *const JSClass);\n"
+ create += "let obj = RootedObject::new(cx, create_dom_global(cx, &Class.base as *const js::jsapi::Class as *const JSClass, Some(%s)));\n" % TRACE_HOOK_NAME
else:
- create += ("let obj = with_compartment(cx, proto, || {\n"
- " JS_NewObject(cx, &Class.base as *const js::Class as *const JSClass, &*proto, &*%s)\n"
- "});\n" % parent)
+ create += ("let obj = {\n"
+ " let _ac = JSAutoCompartment::new(cx, proto.ptr);\n"
+ " JS_NewObjectWithGivenProto(cx, &Class.base as *const js::jsapi::Class as *const JSClass, proto.handle())\n"
+ "};\n"
+ "let obj = RootedObject::new(cx, obj);\n")
create += """\
-assert!(!obj.is_null());
+assert!(!obj.ptr.is_null());
-JS_SetReservedSlot(obj, DOM_OBJECT_SLOT,
- PrivateValue(boxed::into_raw(object) as *const libc::c_void));"""
+JS_SetReservedSlot(obj.ptr, DOM_OBJECT_SLOT,
+ PrivateValue(raw as *const libc::c_void));"""
return create
class CGWrapMethod(CGAbstractMethod):
@@ -1958,37 +2104,46 @@ class CGWrapMethod(CGAbstractMethod):
else:
args = [Argument('*mut JSContext', 'cx'),
Argument("Box<%s>" % descriptor.concreteType, 'object', mutable=True)]
- retval = 'Temporary<%s>' % descriptor.concreteType
+ retval = 'Root<%s>' % descriptor.concreteType
CGAbstractMethod.__init__(self, descriptor, 'Wrap', retval, args, pub=True)
def definition_body(self):
if not self.descriptor.isGlobal():
return CGGeneric("""\
+let _ar = JSAutoRequest::new(cx);
let scope = scope.reflector().get_jsobject();
-assert!(!scope.is_null());
-assert!(((*JS_GetClass(scope)).flags & JSCLASS_IS_GLOBAL) != 0);
+assert!(!scope.get().is_null());
+assert!(((*JS_GetClass(scope.get())).flags & JSCLASS_IS_GLOBAL) != 0);
-let proto = with_compartment(cx, scope, || GetProtoObject(cx, scope, scope));
-assert!(!proto.is_null());
+let mut proto = RootedObject::new(cx, ptr::null_mut());
+{
+ let _ac = JSAutoCompartment::new(cx, scope.get());
+ GetProtoObject(cx, scope, scope, proto.handle_mut())
+}
+assert!(!proto.ptr.is_null());
%s
-raw.reflector().set_jsobject(obj);
+(*raw).init_reflector(obj.ptr);
-Temporary::from_unrooted(raw)""" % CreateBindingJSObject(self.descriptor, "scope"))
+Root::from_ref(&*raw)""" % CreateBindingJSObject(self.descriptor, "scope"))
else:
return CGGeneric("""\
+let _ar = JSAutoRequest::new(cx);
%s
-with_compartment(cx, obj, || {
- let proto = GetProtoObject(cx, obj, obj);
- JS_SetPrototype(cx, obj, proto);
- raw.reflector().set_jsobject(obj);
+let _ac = JSAutoCompartment::new(cx, obj.ptr);
+let mut proto = RootedObject::new(cx, ptr::null_mut());
+GetProtoObject(cx, obj.handle(), obj.handle(), proto.handle_mut());
+JS_SetPrototype(cx, obj.handle(), proto.handle());
+
+(*raw).init_reflector(obj.ptr);
- RegisterBindings::Register(cx, obj);
-});
+let ret = Root::from_ref(&*raw);
-Temporary::from_unrooted(raw)""" % CreateBindingJSObject(self.descriptor))
+RegisterBindings::Register(cx, obj.handle());
+
+ret""" % CreateBindingJSObject(self.descriptor))
class CGIDLInterface(CGThing):
@@ -2083,21 +2238,23 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
properties should be a PropertyArrays instance.
"""
def __init__(self, descriptor, properties):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'global'),
- Argument('*mut JSObject', 'receiver')]
- CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', '*mut JSObject', args)
+ args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'global'),
+ Argument('HandleObject', 'receiver'),
+ Argument('MutableHandleObject', 'rval')]
+ CGAbstractMethod.__init__(self, descriptor, 'CreateInterfaceObjects', 'void', args)
self.properties = properties
def definition_body(self):
protoChain = self.descriptor.prototypeChain
if len(protoChain) == 1:
- getParentProto = "JS_GetObjectPrototype(cx, global)"
+ getParentProto = "parent_proto.ptr = JS_GetObjectPrototype(cx, global)"
else:
parentProtoName = self.descriptor.prototypeChain[-2]
- getParentProto = ("%s::GetProtoObject(cx, global, receiver)" %
+ getParentProto = ("%s::GetProtoObject(cx, global, receiver, parent_proto.handle_mut())" %
toBindingNamespace(parentProtoName))
- getParentProto = ("let parent_proto: *mut JSObject = %s;\n"
- "assert!(!parent_proto.is_null());\n") % getParentProto
+ getParentProto = ("let mut parent_proto = RootedObject::new(cx, ptr::null_mut());\n"
+ "%s;\n"
+ "assert!(!parent_proto.ptr.is_null());\n") % getParentProto
if self.descriptor.interface.isCallback():
protoClass = "None"
@@ -2127,10 +2284,10 @@ class CGCreateInterfaceObjectsMethod(CGAbstractMethod):
constructor = 'None'
call = """\
-return do_create_interface_objects(cx, global, receiver, parent_proto,
- %s, %s,
- %s,
- &sNativeProperties);""" % (protoClass, constructor, domClass)
+do_create_interface_objects(cx, receiver, parent_proto.handle(),
+ %s, %s,
+ %s,
+ &sNativeProperties, rval);""" % (protoClass, constructor, domClass)
return CGList([
CGGeneric(getParentProto),
@@ -2143,10 +2300,11 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
constructor object).
"""
def __init__(self, descriptor, name, idPrefix="", pub=False):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'global'),
- Argument('*mut JSObject', 'receiver')]
+ args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'global'),
+ Argument('HandleObject', 'receiver'),
+ Argument('MutableHandleObject', 'rval')]
CGAbstractMethod.__init__(self, descriptor, name,
- '*mut JSObject', args, pub=pub)
+ 'void', args, pub=pub)
self.id = idPrefix + "ID::" + self.descriptor.name
def definition_body(self):
return CGGeneric("""
@@ -2157,19 +2315,22 @@ class CGGetPerInterfaceObject(CGAbstractMethod):
wrapper and global is the sandbox's global.
*/
-assert!(((*JS_GetClass(global)).flags & JSCLASS_DOM_GLOBAL) != 0);
+assert!(((*JS_GetClass(global.get())).flags & JSCLASS_DOM_GLOBAL) != 0);
/* Check to see whether the interface objects are already installed */
-let proto_or_iface_array = get_proto_or_iface_array(global);
-let cached_object: *mut JSObject = (*proto_or_iface_array)[%s as usize];
-if cached_object.is_null() {
- let tmp: *mut JSObject = CreateInterfaceObjects(cx, global, receiver);
- assert!(!tmp.is_null());
- (*proto_or_iface_array)[%s as usize] = tmp;
- tmp
-} else {
- cached_object
-}""" % (self.id, self.id))
+let proto_or_iface_array = get_proto_or_iface_array(global.get());
+rval.set((*proto_or_iface_array)[%s as usize]);
+if !rval.get().is_null() {
+ return;
+}
+
+CreateInterfaceObjects(cx, global, receiver, rval);
+assert!(!rval.get().is_null());
+(*proto_or_iface_array)[%s as usize] = rval.get();
+if <*mut JSObject>::needs_post_barrier(rval.get()) {
+ <*mut JSObject>::post_barrier((*proto_or_iface_array).as_mut_ptr().offset(%s as isize))
+}
+""" % (self.id, self.id, self.id))
class CGGetProtoObjectMethod(CGGetPerInterfaceObject):
"""
@@ -2224,40 +2385,39 @@ class CGDefineProxyHandler(CGAbstractMethod):
body = """\
let traps = ProxyTraps {
- getPropertyDescriptor: Some(get_property_descriptor as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, bool, *mut JSPropertyDescriptor) -> bool),
- getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, bool, *mut JSPropertyDescriptor) -> bool),
- defineProperty: Some(%s as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut JSPropertyDescriptor) -> bool),
- getOwnPropertyNames: Some(proxyhandler::get_own_property_names as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut AutoIdVector) -> bool),
- delete_: Some(%s as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut bool) -> bool),
- enumerate: Some(proxyhandler::enumerate as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut AutoIdVector) -> bool),
-
+ enter: None,
+ getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor),
+ defineProperty: Some(%s),
+ ownPropertyKeys: Some(proxyhandler::own_property_keys),
+ delete_: Some(%s),
+ enumerate: None,
+ preventExtensions: Some(proxyhandler::prevent_extensions),
+ isExtensible: Some(proxyhandler::is_extensible),
has: None,
- hasOwn: Some(hasOwn as unsafe extern "C" fn(*mut JSContext, *mut JSObject, jsid, *mut bool) -> bool),
- get: Some(get as unsafe extern "C" fn(*mut JSContext, *mut JSObject, *mut JSObject, jsid, *mut JSVal) -> bool),
+ get: Some(get),
set: None,
- keys: None,
- iterate: None,
-
call: None,
construct: None,
- nativeCall: ptr::null(),
+ getPropertyDescriptor: Some(get_property_descriptor),
+ hasOwn: Some(hasOwn),
+ getOwnEnumerablePropertyKeys: None,
+ nativeCall: None,
hasInstance: None,
- typeOf: None,
objectClassIs: None,
- obj_toString: Some(obj_toString as unsafe extern "C" fn(*mut JSContext, *mut JSObject) -> *mut js::jsapi::JSString),
+ className: Some(className),
fun_toString: None,
- //regexp_toShared: ptr::null(),
+ boxedValue_unbox: None,
defaultValue: None,
- iteratorNext: None,
- finalize: Some(%s as unsafe extern "C" fn(*mut JSFreeOp, *mut JSObject)),
- getElementIfPresent: None,
- getPrototypeOf: None,
- trace: Some(%s as unsafe extern "C" fn(*mut JSTracer, *mut JSObject))
+ trace: Some(%s),
+ finalize: Some(%s),
+ objectMoved: None,
+ isCallable: None,
+ isConstructor: None,
};
CreateProxyHandler(&traps, &Class as *const _ as *const _)\
-""" % (customDefineProperty, customDelete, FINALIZE_HOOK_NAME,
- TRACE_HOOK_NAME)
+""" % (customDefineProperty, customDelete, TRACE_HOOK_NAME,
+ FINALIZE_HOOK_NAME)
return CGGeneric(body)
@@ -2270,7 +2430,7 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
assert descriptor.interface.hasInterfaceObject()
args = [
Argument('*mut JSContext', 'cx'),
- Argument('*mut JSObject', 'global'),
+ Argument('HandleObject', 'global'),
]
CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'void', args, pub=True)
@@ -2279,10 +2439,17 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
def definition_body(self):
if self.descriptor.interface.isCallback():
- code = "CreateInterfaceObjects(cx, global, global);"
+ code = """\
+let mut obj = RootedObject::new(cx, ptr::null_mut());
+CreateInterfaceObjects(cx, global, global, obj.handle_mut());
+"""
else:
- code = "assert!(!GetProtoObject(cx, global, global).is_null());"
- return CGGeneric("assert!(!global.is_null());\n" + code)
+ code = """\
+let mut proto = RootedObject::new(cx, ptr::null_mut());
+GetProtoObject(cx, global, global, proto.handle_mut());
+assert!(!proto.ptr.is_null());
+"""
+ return CGGeneric("assert!(!global.get().is_null());\n" + code)
def needCx(returnType, arguments, considerTypes):
return (considerTypes and
@@ -2329,7 +2496,7 @@ class CGCallGenerator(CGThing):
if static:
call = CGWrapper(call, pre="%s::" % descriptorProvider.interface.identifier.name)
else:
- call = CGWrapper(call, pre="%s.r()." % object)
+ call = CGWrapper(call, pre="%s." % object)
call = CGList([call, CGWrapper(args, pre="(", post=")")])
self.cgRoot.append(CGList([
@@ -2344,8 +2511,7 @@ class CGCallGenerator(CGThing):
if static:
glob = ""
else:
- glob = " let global = global_object_for_js_object(this.r().reflector().get_jsobject());\n"\
- " let global = global.root();\n"
+ glob = " let global = global_object_for_js_object(this.reflector().get_jsobject().get());\n"
self.cgRoot.append(CGGeneric(
"let result = match result {\n"
@@ -2357,9 +2523,6 @@ class CGCallGenerator(CGThing):
" },\n"
"};" % (glob, errorResult)))
- if typeRetValNeedsRooting(returnType):
- self.cgRoot.append(CGGeneric("let result = result.root();"))
-
def define(self):
return self.cgRoot.define()
@@ -2403,22 +2566,15 @@ class CGPerSignatureCall(CGThing):
self.argsPre = argsPre
self.arguments = arguments
self.argCount = len(arguments)
- if self.argCount > argConversionStartsAt:
- # Insert our argv in there
- cgThings = [CGGeneric(self.getArgvDecl())]
- else:
- cgThings = []
- cgThings.extend([CGArgumentConverter(arguments[i], i, self.getArgv(),
+ cgThings = []
+ cgThings.extend([CGArgumentConverter(arguments[i], i, self.getArgs(),
self.getArgc(), self.descriptor,
invalidEnumValueFatal=not setter) for
i in range(argConversionStartsAt, self.argCount)])
errorResult = None
if self.isFallible():
- if nativeMethodName == "NamedSetter":
- errorResult = " false"
- else:
- errorResult = " false as JSBool"
+ errorResult = " JSFalse"
cgThings.append(CGCallGenerator(
errorResult,
@@ -2427,10 +2583,8 @@ class CGPerSignatureCall(CGThing):
static))
self.cgRoot = CGList(cgThings, "\n")
- def getArgv(self):
- return "argv" if self.argCount > 0 else ""
- def getArgvDecl(self):
- return "\nlet argv = JS_ARGV(cx, vp);\n"
+ def getArgs(self):
+ return "args" if self.argCount > 0 else ""
def getArgc(self):
return "argc"
def getArguments(self):
@@ -2445,7 +2599,7 @@ class CGPerSignatureCall(CGThing):
return not 'infallible' in self.extendedAttributes
def wrap_return_value(self):
- return wrapForType('*vp')
+ return wrapForType('args.rval()')
def define(self):
return (self.cgRoot.define() + "\n" + self.wrap_return_value())
@@ -2551,7 +2705,7 @@ class CGAbstractBindingMethod(CGAbstractExternMethod):
CGThing which is already properly indented.
"""
def __init__(self, descriptor, name, args, unwrapFailureCode=None):
- CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
+ CGAbstractExternMethod.__init__(self, descriptor, name, "u8", args)
if unwrapFailureCode is None:
self.unwrapFailureCode = (
@@ -2568,14 +2722,20 @@ class CGAbstractBindingMethod(CGAbstractExternMethod):
# consumption by FailureFatalCastableObjectUnwrapper.
unwrapThis = str(CastableObjectUnwrapper(
FakeCastableDescriptor(self.descriptor),
- "obj", self.unwrapFailureCode))
+ "obj.handle()", self.unwrapFailureCode, "object"))
unwrapThis = CGGeneric(
- "let obj: *mut JSObject = JS_THIS_OBJECT(cx, vp as *mut JSVal);\n"
- "if obj.is_null() {\n"
- " return false as JSBool;\n"
+ "let args = CallArgs::from_vp(vp, argc);\n"
+ "let thisobj = args.thisv();\n"
+ "if !thisobj.get().is_null_or_undefined() && !thisobj.get().is_object() {\n"
+ " return JSFalse;\n"
"}\n"
+ "let obj = if thisobj.get().is_object() {\n"
+ " RootedObject::new(cx, thisobj.get().to_object())\n"
+ "} else {\n"
+ " RootedObject::new(cx, GetGlobalForObjectCrossCompartment(JS_CALLEE(cx, vp).to_object_or_null()))\n"
+ "};\n"
"\n"
- "let this: Unrooted<%s> = %s;\n" % (self.descriptor.concreteType, unwrapThis))
+ "let this: Root<%s> = %s;\n" % (self.descriptor.concreteType, unwrapThis))
return CGList([ unwrapThis, self.generate_code() ], "\n")
def generate_code(self):
@@ -2596,12 +2756,11 @@ class CGAbstractStaticBindingMethod(CGAbstractMethod):
Argument('libc::c_uint', 'argc'),
Argument('*mut JSVal', 'vp'),
]
- CGAbstractMethod.__init__(self, descriptor, name, "JSBool", args, extern=True)
+ CGAbstractMethod.__init__(self, descriptor, name, "u8", args, extern=True)
def definition_body(self):
preamble = CGGeneric("""\
let global = global_object_for_js_object(JS_CALLEE(cx, vp).to_object());
-let global = global.root();
""")
return CGList([preamble, self.generate_code()])
@@ -2621,7 +2780,7 @@ class CGGenericMethod(CGAbstractBindingMethod):
def generate_code(self):
return CGGeneric(
"let _info: *const JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
- "return CallJitMethodOp(_info, cx, obj, this.unsafe_get() as *mut libc::c_void, argc, vp);")
+ "return CallJitMethodOp(_info, cx, obj.handle(), this.r() as *const _ as *const libc::c_void as *mut libc::c_void, argc, vp);")
class CGSpecializedMethod(CGAbstractExternMethod):
"""
@@ -2631,18 +2790,19 @@ class CGSpecializedMethod(CGAbstractExternMethod):
def __init__(self, descriptor, method):
self.method = method
name = method.identifier.name
- args = [Argument('*mut JSContext', 'cx'), Argument('JSHandleObject', '_obj'),
+ args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', '_obj'),
Argument('*const %s' % descriptor.concreteType, 'this'),
- Argument('libc::c_uint', 'argc'), Argument('*mut JSVal', 'vp')]
- CGAbstractExternMethod.__init__(self, descriptor, name, 'JSBool', args)
+ Argument('*const JSJitMethodCallArgs', 'args')]
+ CGAbstractExternMethod.__init__(self, descriptor, name, 'u8', args)
def definition_body(self):
nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
self.method)
return CGWrapper(CGMethodCall([], nativeName, self.method.isStatic(),
self.descriptor, self.method),
- pre="let this = Unrooted::from_raw(this);\n"
- "let this = this.root();\n")
+ pre="let this = &*this;\n"
+ "let args = &*args;\n"
+ "let argc = args.argc_;\n")
@staticmethod
def makeNativeName(descriptor, method):
@@ -2661,14 +2821,16 @@ class CGStaticMethod(CGAbstractStaticBindingMethod):
def generate_code(self):
nativeName = CGSpecializedMethod.makeNativeName(self.descriptor,
self.method)
- return CGMethodCall(["global.r()"], nativeName, True, self.descriptor, self.method)
+ setupArgs = CGGeneric("let mut args = CallArgs::from_vp(vp, argc);\n")
+ call = CGMethodCall(["global.r()"], nativeName, True, self.descriptor, self.method)
+ return CGList([setupArgs, call])
class CGGenericGetter(CGAbstractBindingMethod):
"""
A class for generating the C++ code for an IDL attribute getter.
"""
def __init__(self, descriptor, lenientThis=False):
- args = [Argument('*mut JSContext', 'cx'), Argument('libc::c_uint', '_argc'),
+ args = [Argument('*mut JSContext', 'cx'), Argument('libc::c_uint', 'argc'),
Argument('*mut JSVal', 'vp')]
if lenientThis:
name = "genericLenientGetter"
@@ -2685,7 +2847,7 @@ class CGGenericGetter(CGAbstractBindingMethod):
def generate_code(self):
return CGGeneric(
"let info: *const JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
- "return CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *mut libc::c_void, vp);")
+ "return CallJitGetterOp(info, cx, obj.handle(), this.r() as *const _ as *const libc::c_void as *mut libc::c_void, argc, vp);")
class CGSpecializedGetter(CGAbstractExternMethod):
"""
@@ -2696,10 +2858,10 @@ class CGSpecializedGetter(CGAbstractExternMethod):
self.attr = attr
name = 'get_' + attr.identifier.name
args = [ Argument('*mut JSContext', 'cx'),
- Argument('JSHandleObject', '_obj'),
+ Argument('HandleObject', '_obj'),
Argument('*const %s' % descriptor.concreteType, 'this'),
- Argument('*mut JSVal', 'vp') ]
- CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
+ Argument('JSJitGetterCallArgs', 'args') ]
+ CGAbstractExternMethod.__init__(self, descriptor, name, "u8", args)
def definition_body(self):
nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
@@ -2707,8 +2869,7 @@ class CGSpecializedGetter(CGAbstractExternMethod):
return CGWrapper(CGGetterCall([], self.attr.type, nativeName,
self.descriptor, self.attr),
- pre="let this = Unrooted::from_raw(this);\n"
- "let this = this.root();\n")
+ pre="let this = &*this;\n")
@staticmethod
def makeNativeName(descriptor, attr):
@@ -2734,8 +2895,10 @@ class CGStaticGetter(CGAbstractStaticBindingMethod):
def generate_code(self):
nativeName = CGSpecializedGetter.makeNativeName(self.descriptor,
self.attr)
- return CGGetterCall(["global.r()"], self.attr.type, nativeName, self.descriptor,
+ setupArgs = CGGeneric("let mut args = CallArgs::from_vp(vp, argc);\n")
+ call = CGGetterCall(["global.r()"], self.attr.type, nativeName, self.descriptor,
self.attr)
+ return CGList([setupArgs, call])
class CGGenericSetter(CGAbstractBindingMethod):
@@ -2758,10 +2921,8 @@ class CGGenericSetter(CGAbstractBindingMethod):
def generate_code(self):
return CGGeneric(
- "let mut undef = UndefinedValue();\n"
- "let argv: *mut JSVal = if argc != 0 { JS_ARGV(cx, vp) } else { &mut undef as *mut JSVal };\n"
"let info: *const JSJitInfo = RUST_FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
- "if CallJitPropertyOp(info, cx, obj, this.unsafe_get() as *mut libc::c_void, argv) == 0 {\n"
+ "if CallJitSetterOp(info, cx, obj.handle(), this.r() as *const _ as *const libc::c_void as *mut libc::c_void, argc, vp) == 0 {\n"
" return 0;\n"
"}\n"
"*vp = UndefinedValue();\n"
@@ -2776,18 +2937,17 @@ class CGSpecializedSetter(CGAbstractExternMethod):
self.attr = attr
name = 'set_' + attr.identifier.name
args = [ Argument('*mut JSContext', 'cx'),
- Argument('JSHandleObject', 'obj'),
+ Argument('HandleObject', 'obj'),
Argument('*const %s' % descriptor.concreteType, 'this'),
- Argument('*mut JSVal', 'argv')]
- CGAbstractExternMethod.__init__(self, descriptor, name, "JSBool", args)
+ Argument('JSJitSetterCallArgs', 'args')]
+ CGAbstractExternMethod.__init__(self, descriptor, name, "u8", args)
def definition_body(self):
nativeName = CGSpecializedSetter.makeNativeName(self.descriptor,
self.attr)
return CGWrapper(CGSetterCall([], self.attr.type, nativeName,
self.descriptor, self.attr),
- pre="let this = Unrooted::from_raw(this);\n"
- "let this = this.root();\n")
+ pre="let this = &*this;\n")
@staticmethod
def makeNativeName(descriptor, attr):
@@ -2808,7 +2968,7 @@ class CGStaticSetter(CGAbstractStaticBindingMethod):
nativeName = CGSpecializedSetter.makeNativeName(self.descriptor,
self.attr)
checkForArg = CGGeneric(
- "let argv = JS_ARGV(cx, vp);\n"
+ "let args = CallArgs::from_vp(vp, argc);\n"
"if (argc == 0) {\n"
" throw_type_error(cx, \"Not enough arguments to %s setter.\");\n"
" return 0;\n"
@@ -2831,17 +2991,17 @@ class CGSpecializedForwardingSetter(CGSpecializedSetter):
assert all(ord(c) < 128 for c in attrName)
assert all(ord(c) < 128 for c in forwardToAttrName)
return CGGeneric("""\
-let mut v = UndefinedValue();
-if JS_GetProperty(cx, *obj.unnamed_field1, b"%s".as_ptr() as *const i8, &mut v) == 0 {
- return 0;
+let mut v = RootedValue::new(cx, UndefinedValue());
+if JS_GetProperty(cx, obj, %s as *const u8 as *const i8, v.handle_mut()) == 0 {
+ return JSFalse;
}
-if !v.is_object() {
+if !v.ptr.is_object() {
throw_type_error(cx, "Value.%s is not an object.");
- return 0;
+ return JSFalse;
}
-let target_obj = v.to_object();
-JS_SetProperty(cx, target_obj, b"%s".as_ptr() as *const i8, argv.offset(0))
-""" % (attrName, attrName, forwardToAttrName))
+let target_obj = RootedObject::new(cx, v.ptr.to_object());
+JS_SetProperty(cx, target_obj.handle(), %s as *const u8 as *const i8, args.get(0))
+""" % (str_to_const_array(attrName), attrName, str_to_const_array(forwardToAttrName)))
class CGMemberJITInfo(CGThing):
"""
@@ -2852,52 +3012,253 @@ class CGMemberJITInfo(CGThing):
self.member = member
self.descriptor = descriptor
- def defineJitInfo(self, infoName, opName, infallible):
- protoID = "PrototypeList::ID::%s as u32" % self.descriptor.name
- depth = self.descriptor.interface.inheritanceDepth()
- failstr = "true" if infallible else "false"
- return ("const %s: JSJitInfo = JSJitInfo {\n"
- " op: %s as *const u8,\n"
- " protoID: %s,\n"
- " depth: %s,\n"
- " isInfallible: %s, /* False in setters. */\n"
- " isConstant: false /* Only relevant for getters. */\n"
- "};\n" % (infoName, opName, protoID, depth, failstr))
+ def defineJitInfo(self, infoName, opName, opType, infallible, movable,
+ aliasSet, alwaysInSlot, lazilyInSlot, slotIndex,
+ returnTypes, args):
+ """
+ aliasSet is a JSJitInfo::AliasSet value, without the "JSJitInfo::" bit.
+
+ args is None if we don't want to output argTypes for some
+ reason (e.g. we have overloads or we're not a method) and
+ otherwise an iterable of the arguments for this method.
+ """
+ assert(not movable or aliasSet != "AliasEverything") # Can't move write-aliasing things
+ assert(not alwaysInSlot or movable) # Things always in slots had better be movable
+
+ def jitInfoInitializer(isTypedMethod):
+ initializer = fill(
+ """
+ JSJitInfo {
+ _bindgen_data_1_: ${opName} as *const ::libc::c_void,
+ protoID: PrototypeList::ID::${name} as u16,
+ depth: ${depth},
+ _bitfield_1: ((JSJitInfo_OpType::${opType} as u32) << 0) |
+ ((JSJitInfo_AliasSet::${aliasSet} as u32) << 4) |
+ ((JSValueType::${returnType} as u32) << 8) |
+ ((${isInfallible} as u32) << 16) |
+ ((${isMovable} as u32) << 17) |
+ ((${isAlwaysInSlot} as u32) << 18) |
+ ((${isLazilyCachedInSlot} as u32) << 19) |
+ ((${isTypedMethod} as u32) << 20) |
+ ((${slotIndex} as u32) << 21)
+ }
+ """,
+ opName=opName,
+ name=self.descriptor.name,
+ depth=self.descriptor.interface.inheritanceDepth(),
+ opType=opType,
+ aliasSet=aliasSet,
+ returnType=reduce(CGMemberJITInfo.getSingleReturnType, returnTypes,
+ ""),
+ isInfallible=toStringBool(infallible),
+ isMovable=toStringBool(movable),
+ isAlwaysInSlot=toStringBool(alwaysInSlot),
+ isLazilyCachedInSlot=toStringBool(lazilyInSlot),
+ isTypedMethod=toStringBool(isTypedMethod),
+ slotIndex=slotIndex)
+ return initializer.rstrip()
+
+ return ("\n"
+ "const %s: JSJitInfo = %s;\n"
+ % (infoName, jitInfoInitializer(False)))
def define(self):
if self.member.isAttr():
getterinfo = ("%s_getterinfo" % self.member.identifier.name)
getter = ("get_%s" % self.member.identifier.name)
getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)
- result = self.defineJitInfo(getterinfo, getter, getterinfal)
- if not self.member.readonly or self.member.getExtendedAttribute("PutForwards"):
+
+ movable = self.mayBeMovable() and getterinfal
+ aliasSet = self.aliasSet()
+
+ isAlwaysInSlot = self.member.getExtendedAttribute("StoreInSlot")
+ if self.member.slotIndex is not None:
+ assert isAlwaysInSlot or self.member.getExtendedAttribute("Cached")
+ isLazilyCachedInSlot = not isAlwaysInSlot
+ slotIndex = memberReservedSlot(self.member)
+ # We'll statically assert that this is not too big in
+ # CGUpdateMemberSlotsMethod, in the case when
+ # isAlwaysInSlot is true.
+ else:
+ isLazilyCachedInSlot = False
+ slotIndex = "0"
+
+ result = self.defineJitInfo(getterinfo, getter, "Getter",
+ getterinfal, movable, aliasSet,
+ isAlwaysInSlot, isLazilyCachedInSlot,
+ slotIndex,
+ [self.member.type], None)
+ if (not self.member.readonly or
+ self.member.getExtendedAttribute("PutForwards")):
setterinfo = ("%s_setterinfo" % self.member.identifier.name)
setter = ("set_%s" % self.member.identifier.name)
# Setters are always fallible, since they have to do a typed unwrap.
- result += "\n" + self.defineJitInfo(setterinfo, setter, False)
+ result += self.defineJitInfo(setterinfo, setter, "Setter",
+ False, False, "AliasEverything",
+ False, False, "0",
+ [BuiltinTypes[IDLBuiltinType.Types.void]],
+ None)
return result
if self.member.isMethod():
methodinfo = ("%s_methodinfo" % self.member.identifier.name)
- # Actually a JSJitMethodOp, but JSJitPropertyOp by struct definition.
method = ("%s" % self.member.identifier.name)
# Methods are infallible if they are infallible, have no arguments
# to unwrap, and have a return type that's infallible to wrap up for
# return.
- methodInfal = False
sigs = self.member.signatures()
- if len(sigs) == 1:
+ if len(sigs) != 1:
# Don't handle overloading. If there's more than one signature,
# one of them must take arguments.
+ methodInfal = False
+ args = None
+ movable = False
+ else:
sig = sigs[0]
- if len(sig[1]) == 0:
- # No arguments and infallible return boxing
- methodInfal = True
+ # For methods that affect nothing, it's OK to set movable to our
+ # notion of infallible on the C++ side, without considering
+ # argument conversions, since argument conversions that can
+ # reliably throw would be effectful anyway and the jit doesn't
+ # move effectful things.
+ hasInfallibleImpl = "infallible" in self.descriptor.getExtendedAttributes(self.member)
+ movable = self.mayBeMovable() and hasInfallibleImpl
+ # XXXbz can we move the smarts about fallibility due to arg
+ # conversions into the JIT, using our new args stuff?
+ if (len(sig[1]) != 0):
+ # We have arguments or our return-value boxing can fail
+ methodInfal = False
+ else:
+ methodInfal = hasInfallibleImpl
+ # For now, only bother to output args if we're side-effect-free.
+ if self.member.affects == "Nothing":
+ args = sig[1]
+ else:
+ args = None
- result = self.defineJitInfo(methodinfo, method, methodInfal)
+ aliasSet = self.aliasSet()
+ result = self.defineJitInfo(methodinfo, method, "Method",
+ methodInfal, movable, aliasSet,
+ False, False, "0",
+ [s[0] for s in sigs], args)
return result
raise TypeError("Illegal member type to CGPropertyJITInfo")
+ def mayBeMovable(self):
+ """
+ Returns whether this attribute or method may be movable, just
+ based on Affects/DependsOn annotations.
+ """
+ affects = self.member.affects
+ dependsOn = self.member.dependsOn
+ assert affects in IDLInterfaceMember.AffectsValues
+ assert dependsOn in IDLInterfaceMember.DependsOnValues
+ # Things that are DependsOn=DeviceState are not movable, because we
+ # don't want them coalesced with each other or loop-hoisted, since
+ # their return value can change even if nothing is going on from our
+ # point of view.
+ return (affects == "Nothing" and
+ (dependsOn != "Everything" and dependsOn != "DeviceState"))
+
+ def aliasSet(self):
+ """Returns the alias set to store in the jitinfo. This may not be the
+ effective alias set the JIT uses, depending on whether we have enough
+ information about our args to allow the JIT to prove that effectful
+ argument conversions won't happen.
+
+ """
+ dependsOn = self.member.dependsOn
+ assert dependsOn in IDLInterfaceMember.DependsOnValues
+
+ if dependsOn == "Nothing" or dependsOn == "DeviceState":
+ assert self.member.affects == "Nothing"
+ return "AliasNone"
+
+ if dependsOn == "DOMState":
+ assert self.member.affects == "Nothing"
+ return "AliasDOMSets"
+
+ return "AliasEverything"
+
+ @staticmethod
+ def getJSReturnTypeTag(t):
+ if t.nullable():
+ # Sometimes it might return null, sometimes not
+ return "JSVAL_TYPE_UNKNOWN"
+ if t.isVoid():
+ # No return, every time
+ return "JSVAL_TYPE_UNDEFINED"
+ if t.isArray():
+ # No idea yet
+ assert False
+ if t.isSequence():
+ return "JSVAL_TYPE_OBJECT"
+ if t.isMozMap():
+ return "JSVAL_TYPE_OBJECT"
+ if t.isGeckoInterface():
+ return "JSVAL_TYPE_OBJECT"
+ if t.isString():
+ return "JSVAL_TYPE_STRING"
+ if t.isEnum():
+ return "JSVAL_TYPE_STRING"
+ if t.isCallback():
+ return "JSVAL_TYPE_OBJECT"
+ if t.isAny():
+ # The whole point is to return various stuff
+ return "JSVAL_TYPE_UNKNOWN"
+ if t.isObject():
+ return "JSVAL_TYPE_OBJECT"
+ if t.isSpiderMonkeyInterface():
+ return "JSVAL_TYPE_OBJECT"
+ if t.isUnion():
+ u = t.unroll()
+ if u.hasNullableType:
+ # Might be null or not
+ return "JSVAL_TYPE_UNKNOWN"
+ return reduce(CGMemberJITInfo.getSingleReturnType,
+ u.flatMemberTypes, "")
+ if t.isDictionary():
+ return "JSVAL_TYPE_OBJECT"
+ if t.isDate():
+ return "JSVAL_TYPE_OBJECT"
+ if not t.isPrimitive():
+ raise TypeError("No idea what type " + str(t) + " is.")
+ tag = t.tag()
+ if tag == IDLType.Tags.bool:
+ return "JSVAL_TYPE_BOOLEAN"
+ if tag in [IDLType.Tags.int8, IDLType.Tags.uint8,
+ IDLType.Tags.int16, IDLType.Tags.uint16,
+ IDLType.Tags.int32]:
+ return "JSVAL_TYPE_INT32"
+ if tag in [IDLType.Tags.int64, IDLType.Tags.uint64,
+ IDLType.Tags.unrestricted_float, IDLType.Tags.float,
+ IDLType.Tags.unrestricted_double, IDLType.Tags.double]:
+ # These all use JS_NumberValue, which can return int or double.
+ # But TI treats "double" as meaning "int or double", so we're
+ # good to return JSVAL_TYPE_DOUBLE here.
+ return "JSVAL_TYPE_DOUBLE"
+ if tag != IDLType.Tags.uint32:
+ raise TypeError("No idea what type " + str(t) + " is.")
+ # uint32 is sometimes int and sometimes double.
+ return "JSVAL_TYPE_DOUBLE"
+
+ @staticmethod
+ def getSingleReturnType(existingType, t):
+ type = CGMemberJITInfo.getJSReturnTypeTag(t)
+ if existingType == "":
+ # First element of the list; just return its type
+ return type
+
+ if type == existingType:
+ return existingType
+ if ((type == "JSVAL_TYPE_DOUBLE" and
+ existingType == "JSVAL_TYPE_INT32") or
+ (existingType == "JSVAL_TYPE_DOUBLE" and
+ type == "JSVAL_TYPE_INT32")):
+ # Promote INT32 to DOUBLE as needed
+ return "JSVAL_TYPE_DOUBLE"
+ # Different types
+ return "JSVAL_TYPE_UNKNOWN"
+
def getEnumValueName(value):
# Some enum values can be empty strings. Others might have weird
# characters in them. Deal with the former by returning "_empty",
@@ -2933,7 +3294,7 @@ pub enum %s {
inner = """\
use dom::bindings::conversions::ToJSValConvertible;
-use js::jsapi::JSContext;
+use js::jsapi::{JSContext, MutableHandleValue};
use js::jsval::JSVal;
pub const strings: &'static [&'static str] = &[
@@ -2941,8 +3302,8 @@ pub const strings: &'static [&'static str] = &[
];
impl ToJSValConvertible for super::%s {
- fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
- strings[*self as usize].to_jsval(cx)
+ fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
+ strings[*self as usize].to_jsval(cx, rval);
}
}
""" % (",\n ".join(['"%s"' % val for val in enum.values()]), enum.identifier.name)
@@ -3047,7 +3408,7 @@ class CGUnionStruct(CGThing):
" e%s(%s)," % (v["name"], v["typeName"]) for v in templateVars
]
enumConversions = [
- " %s::e%s(ref inner) => inner.to_jsval(cx)," % (self.type, v["name"]) for v in templateVars
+ " %s::e%s(ref inner) => inner.to_jsval(cx, rval)," % (self.type, v["name"]) for v in templateVars
]
# XXXManishearth The following should be #[must_root],
# however we currently allow it till #2661 is fixed
@@ -3058,7 +3419,7 @@ pub enum %s {
}
impl ToJSValConvertible for %s {
- fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
+ fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
match *self {
%s
}
@@ -3147,7 +3508,7 @@ class CGUnionConversionStruct(CGThing):
if hasObjectTypes:
assert interfaceObject
templateBody = CGList([interfaceObject], "\n")
- conversions.append(CGIfWrapper(templateBody, "value.is_object()"))
+ conversions.append(CGIfWrapper(templateBody, "value.get().is_object()"))
otherMemberTypes = [
t for t in memberTypes if t.isPrimitive() or t.isString() or t.isEnum()
@@ -3173,7 +3534,7 @@ class CGUnionConversionStruct(CGThing):
"Err(())" % ", ".join(names)))
method = CGWrapper(
CGIndenter(CGList(conversions, "\n\n")),
- pre="fn from_jsval(cx: *mut JSContext, value: JSVal, _option: ()) -> Result<%s, ()> {\n" % self.type,
+ pre="fn from_jsval(cx: *mut JSContext, value: HandleValue, _option: ()) -> Result<%s, ()> {\n" % self.type,
post="\n}")
return CGWrapper(
CGIndenter(CGList([
@@ -3190,7 +3551,7 @@ class CGUnionConversionStruct(CGThing):
return CGWrapper(
CGIndenter(jsConversion, 4),
- pre="fn TryConvertTo%s(cx: *mut JSContext, value: JSVal) -> %s {\n" % (t.name, returnType),
+ pre="fn TryConvertTo%s(cx: *mut JSContext, value: HandleValue) -> %s {\n" % (t.name, returnType),
post="\n}")
def define(self):
@@ -3236,6 +3597,7 @@ class ClassMethod(ClassItem):
override indicates whether to flag the method as MOZ_OVERRIDE
"""
assert not override or virtual
+ assert not (override and static)
self.returnType = returnType
self.args = args
self.inline = False
@@ -3378,9 +3740,14 @@ class ClassConstructor(ClassItem):
def getBody(self, cgClass):
initializers = [" parent: %s" % str(self.baseConstructors[0])]
return (self.body + (
- "%s {\n"
+ "let mut ret = Rc::new(%s {\n"
"%s\n"
- "}") % (cgClass.name, '\n'.join(initializers)))
+ "});\n"
+ "match rc::get_mut(&mut ret) {\n"
+ " Some(ref mut callback) => callback.parent.init(%s),\n"
+ " None => unreachable!(),\n"
+ "};\n"
+ "ret") % (cgClass.name, '\n'.join(initializers), self.args[0].name))
def declare(self, cgClass):
args = ', '.join([a.declare() for a in self.args])
@@ -3391,7 +3758,7 @@ class ClassConstructor(ClassItem):
body = ' {\n' + body + '}'
return string.Template("""\
-pub fn ${decorators}new(${args}) -> ${className}${body}
+pub fn ${decorators}new(${args}) -> Rc<${className}>${body}
""").substitute({ 'decorators': self.getDecorators(True),
'className': cgClass.getNameString(),
'args': args,
@@ -3692,17 +4059,18 @@ class CGProxySpecialOperation(CGPerSignatureCall):
argument = arguments[1]
info = getJSToNativeConversionInfo(
argument.type, descriptor, treatNullAs=argument.treatNullAs,
- exceptionCode="return false;")
+ exceptionCode="return JSFalse;")
template = info.template
declType = info.declType
needsRooting = info.needsRooting
templateValues = {
- "val": "(*desc).value",
+ "val": "value.handle()",
}
self.cgRoot.prepend(instantiateJSToNativeConversionTemplate(
template, templateValues, declType, argument.identifier.name,
needsRooting))
+ self.cgRoot.prepend(CGGeneric("let value = RootedValue::new(cx, desc.get().value);"))
elif operation.isGetter():
self.cgRoot.prepend(CGGeneric("let mut found = false;"))
@@ -3777,7 +4145,7 @@ class CGProxyNamedDeleter(CGProxySpecialOperation):
class CGProxyUnwrap(CGAbstractMethod):
def __init__(self, descriptor):
- args = [Argument('*mut JSObject', 'obj')]
+ args = [Argument('HandleObject', 'obj')]
CGAbstractMethod.__init__(self, descriptor, "UnwrapProxy", '*const ' + descriptor.concreteType, args, alwaysInline=True)
def definition_body(self):
@@ -3786,103 +4154,78 @@ class CGProxyUnwrap(CGAbstractMethod):
obj = js::UnwrapObject(obj);
}*/
//MOZ_ASSERT(IsProxy(obj));
-let box_ = GetProxyPrivate(obj).to_private() as *const %s;
+let box_ = GetProxyPrivate(*obj.ptr).to_private() as *const %s;
return box_;""" % self.descriptor.concreteType)
class CGDOMJSProxyHandler_getOwnPropertyDescriptor(CGAbstractExternMethod):
def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'),
- Argument('jsid', 'id'), Argument('bool', 'set'),
- Argument('*mut JSPropertyDescriptor', 'desc')]
+ args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'),
+ Argument('HandleId', 'id'),
+ Argument('MutableHandle<JSPropertyDescriptor>', 'desc')]
CGAbstractExternMethod.__init__(self, descriptor, "getOwnPropertyDescriptor",
- "bool", args)
+ "u8", args)
self.descriptor = descriptor
def getBody(self):
indexedGetter = self.descriptor.operations['IndexedGetter']
indexedSetter = self.descriptor.operations['IndexedSetter']
- setOrIndexedGet = ""
+ get = ""
if indexedGetter or indexedSetter:
- setOrIndexedGet += "let index = get_array_index_from_id(cx, id);\n"
+ get = "let index = get_array_index_from_id(cx, id);\n"
if indexedGetter:
readonly = toStringBool(self.descriptor.operations['IndexedSetter'] is None)
- fillDescriptor = "fill_property_descriptor(&mut *desc, proxy, %s);\nreturn true;" % readonly
- templateValues = {'jsvalRef': '(*desc).value', 'successCode': fillDescriptor}
- get = ("if index.is_some() {\n" +
- " let index = index.unwrap();\n" +
- " let this = UnwrapProxy(proxy);\n" +
- " let this = Unrooted::from_raw(this);\n" +
- " let this = this.root();\n" +
- CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define() + "\n" +
- "}\n")
-
- if indexedSetter or self.descriptor.operations['NamedSetter']:
- setOrIndexedGet += "if set {\n"
- if indexedSetter:
- setOrIndexedGet += (" if index.is_some() {\n" +
- " let index = index.unwrap();\n")
- if not 'IndexedCreator' in self.descriptor.operations:
- # FIXME need to check that this is a 'supported property index'
- assert False
- setOrIndexedGet += (" fill_property_descriptor(&mut *desc, proxy, false);\n" +
- " return true;\n" +
- " }\n")
- if self.descriptor.operations['NamedSetter']:
- setOrIndexedGet += " if RUST_JSID_IS_STRING(id) != 0 {\n"
- if not 'NamedCreator' in self.descriptor.operations:
- # FIXME need to check that this is a 'supported property name'
- assert False
- setOrIndexedGet += (" fill_property_descriptor(&mut *desc, proxy, false);\n" +
- " return true;\n" +
- " }\n")
- setOrIndexedGet += "}"
- if indexedGetter:
- setOrIndexedGet += (" else {\n" +
- CGIndenter(CGGeneric(get)).define() +
- "}")
- setOrIndexedGet += "\n\n"
- elif indexedGetter:
- setOrIndexedGet += ("if !set {\n" +
- CGIndenter(CGGeneric(get)).define() +
- "}\n\n")
+ fillDescriptor = "desc.get().value = result_root.ptr;\nfill_property_descriptor(&mut *desc.ptr, *proxy.ptr, %s);\nreturn JSTrue;" % readonly
+ templateValues = {
+ 'jsvalRef': 'result_root.handle_mut()',
+ 'successCode': fillDescriptor,
+ 'pre': 'let mut result_root = RootedValue::new(cx, UndefinedValue());'
+ }
+ get += ("if index.is_some() {\n" +
+ " let index = index.unwrap();\n" +
+ " let this = UnwrapProxy(proxy);\n" +
+ " let this = &*this;\n" +
+ CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define() + "\n" +
+ "}\n")
namedGetter = self.descriptor.operations['NamedGetter']
if namedGetter:
readonly = toStringBool(self.descriptor.operations['NamedSetter'] is None)
- fillDescriptor = "fill_property_descriptor(&mut *desc, proxy, %s);\nreturn true;" % readonly
- templateValues = {'jsvalRef': '(*desc).value', 'successCode': fillDescriptor}
+ fillDescriptor = "desc.get().value = result_root.ptr;\nfill_property_descriptor(&mut *desc.ptr, *proxy.ptr, %s);\nreturn JSTrue;" % readonly
+ templateValues = {
+ 'jsvalRef': 'result_root.handle_mut()',
+ 'successCode': fillDescriptor,
+ 'pre': 'let mut result_root = RootedValue::new(cx, UndefinedValue());'
+ }
# Once we start supporting OverrideBuiltins we need to make
# ResolveOwnProperty or EnumerateOwnProperties filter out named
# properties that shadow prototype properties.
namedGet = ("\n" +
- "if !set && RUST_JSID_IS_STRING(id) != 0 && !has_property_on_prototype(cx, proxy, id) {\n" +
+ "if RUST_JSID_IS_STRING(id) != 0 && !has_property_on_prototype(cx, proxy, id) {\n" +
" let name = jsid_to_str(cx, id);\n" +
" let this = UnwrapProxy(proxy);\n" +
- " let this = Unrooted::from_raw(this);\n" +
- " let this = this.root();\n" +
+ " let this = &*this;\n" +
CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() + "\n" +
"}\n")
else:
namedGet = ""
- return setOrIndexedGet + """\
-let expando: *mut JSObject = get_expando_object(proxy);
+ return get + """\
+let expando = RootedObject::new(cx, get_expando_object(proxy));
//if (!xpc::WrapperFactory::IsXrayWrapper(proxy) && (expando = GetExpandoObject(proxy))) {
-if !expando.is_null() {
- let flags = if set { JSRESOLVE_ASSIGNING } else { 0 } | JSRESOLVE_QUALIFIED;
- if JS_GetPropertyDescriptorById(cx, expando, id, flags, desc) == 0 {
- return false;
+if !expando.ptr.is_null() {
+ if JS_GetPropertyDescriptorById(cx, expando.handle(), id, desc) == 0 {
+ return JSFalse;
}
- if !(*desc).obj.is_null() {
+ if !desc.get().obj.is_null() {
// Pretend the property lives on the wrapper.
- (*desc).obj = proxy;
- return true;
+ desc.get().obj = *proxy.ptr;
+ return JSTrue;
}
}
""" + namedGet + """\
-(*desc).obj = ptr::null_mut();
-return true;"""
+desc.get().obj = ptr::null_mut();
+return JSTrue;"""
def definition_body(self):
return CGGeneric(self.getBody())
@@ -3890,10 +4233,11 @@ return true;"""
# TODO(Issue 5876)
class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod):
def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'),
- Argument('jsid', 'id'),
- Argument('*mut JSPropertyDescriptor', 'desc')]
- CGAbstractExternMethod.__init__(self, descriptor, "defineProperty", "bool", args)
+ args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'),
+ Argument('HandleId', 'id'),
+ Argument('Handle<JSPropertyDescriptor>', 'desc'),
+ Argument('*mut ObjectOpResult', 'opresult')]
+ CGAbstractExternMethod.__init__(self, descriptor, "defineProperty", "u8", args)
self.descriptor = descriptor
def getBody(self):
set = ""
@@ -3906,14 +4250,13 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod):
"if index.is_some() {\n" +
" let index = index.unwrap();\n" +
" let this = UnwrapProxy(proxy);\n" +
- " let this = Unrooted::from_raw(this);\n" +
- " let this = this.root();\n" +
+ " let this = &*this;\n" +
CGIndenter(CGProxyIndexedSetter(self.descriptor)).define() +
- " return true;\n" +
+ " return JSTrue;\n" +
"}\n")
elif self.descriptor.operations['IndexedGetter']:
set += ("if get_array_index_from_id(cx, id).is_some() {\n" +
- " return false;\n" +
+ " return JSFalse;\n" +
" //return ThrowErrorMessage(cx, MSG_NO_PROPERTY_SETTER, \"%s\");\n" +
"}\n") % self.descriptor.name
@@ -3924,30 +4267,30 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod):
set += ("if RUST_JSID_IS_STRING(id) != 0 {\n" +
" let name = jsid_to_str(cx, id);\n" +
" let this = UnwrapProxy(proxy);\n" +
- " let this = Unrooted::from_raw(this);\n" +
- " let this = this.root();\n" +
+ " let this = &*this;\n" +
CGIndenter(CGProxyNamedSetter(self.descriptor)).define() +
- " return true;\n" +
+ " (*opresult).code_ = 0; /* SpecialCodes::OkCode */\n" +
+ " return JSTrue;\n" +
"} else {\n" +
- " return false;\n" +
+ " return JSFalse;\n" +
"}\n")
else:
- if self.descriptor.operations['NamedGetter']:
- set += ("if RUST_JSID_IS_STRING(id) != 0 {\n" +
- " let name = jsid_to_str(cx, id);\n" +
- " let this = UnwrapProxy(proxy);\n" +
- " let this = Unrooted::from_raw(this);\n" +
- " let this = this.root();\n" +
- CGProxyNamedPresenceChecker(self.descriptor).define() +
- " if (found) {\n" +
- # TODO(Issue 5876)
- " //return js::IsInNonStrictPropertySet(cx)\n" +
- " // ? opresult.succeed()\n" +
- " // : ThrowErrorMessage(cx, MSG_NO_NAMED_SETTER, \"${name}\");\n" +
- " return true;\n" +
- " }\n" +
- "}"
- ) % (self.descriptor.name, self.descriptor.name)
+ set += ("if RUST_JSID_IS_STRING(id) != 0 {\n" +
+ " let name = jsid_to_str(cx, id);\n" +
+ " let this = UnwrapProxy(proxy);\n" +
+ " let this = &*this;\n" +
+ CGIndenter(CGProxyNamedGetter(self.descriptor)).define() +
+ " if (found) {\n"
+ # TODO(Issue 5876)
+ " //return js::IsInNonStrictPropertySet(cx)\n" +
+ " // ? opresult.succeed()\n" +
+ " // : ThrowErrorMessage(cx, MSG_NO_NAMED_SETTER, \"${name}\");\n" +
+ " (*opresult).code_ = 0; /* SpecialCodes::OkCode */\n" +
+ " return JSTrue;\n" +
+ " }\n" +
+ " (*opresult).code_ = 0; /* SpecialCodes::OkCode */\n" +
+ " return JSTrue;\n"
+ "}\n") % (self.descriptor.name, self.descriptor.name)
set += "return proxyhandler::define_property(%s);" % ", ".join(a.name for a in self.args)
return set
@@ -3956,10 +4299,10 @@ class CGDOMJSProxyHandler_defineProperty(CGAbstractExternMethod):
class CGDOMJSProxyHandler_delete(CGAbstractExternMethod):
def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'),
- Argument('jsid', 'id'),
- Argument('*mut bool', 'bp')]
- CGAbstractExternMethod.__init__(self, descriptor, "delete", "bool", args)
+ args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'),
+ Argument('HandleId', 'id'),
+ Argument('*mut ObjectOpResult', 'res')]
+ CGAbstractExternMethod.__init__(self, descriptor, "delete", "u8", args)
self.descriptor = descriptor
def getBody(self):
@@ -3967,10 +4310,9 @@ class CGDOMJSProxyHandler_delete(CGAbstractExternMethod):
if self.descriptor.operations['NamedDeleter']:
set += ("let name = jsid_to_str(cx, id);\n" +
"let this = UnwrapProxy(proxy);\n" +
- "let this = Unrooted::from_raw(this);\n" +
- "let this = this.root();\n" +
+ "let this = &*this;\n" +
"%s") % (CGProxyNamedDeleter(self.descriptor).define())
- set += "return proxyhandler::delete(%s);" % ", ".join(a.name for a in self.args)
+ set += "return proxyhandler::delete(%s) as u8;" % ", ".join(a.name for a in self.args)
return set
def definition_body(self):
@@ -3978,9 +4320,9 @@ class CGDOMJSProxyHandler_delete(CGAbstractExternMethod):
class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod):
def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'),
- Argument('jsid', 'id'), Argument('*mut bool', 'bp')]
- CGAbstractExternMethod.__init__(self, descriptor, "hasOwn", "bool", args)
+ args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'),
+ Argument('HandleId', 'id'), Argument('*mut u8', 'bp')]
+ CGAbstractExternMethod.__init__(self, descriptor, "hasOwn", "u8", args)
self.descriptor = descriptor
def getBody(self):
indexedGetter = self.descriptor.operations['IndexedGetter']
@@ -3989,11 +4331,10 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod):
"if index.is_some() {\n" +
" let index = index.unwrap();\n" +
" let this = UnwrapProxy(proxy);\n" +
- " let this = Unrooted::from_raw(this);\n" +
- " let this = this.root();\n" +
+ " let this = &*this;\n" +
CGIndenter(CGProxyIndexedGetter(self.descriptor)).define() + "\n" +
- " *bp = found;\n" +
- " return true;\n" +
+ " *bp = found as u8;\n" +
+ " return JSTrue;\n" +
"}\n\n")
else:
indexed = ""
@@ -4003,57 +4344,56 @@ class CGDOMJSProxyHandler_hasOwn(CGAbstractExternMethod):
named = ("if RUST_JSID_IS_STRING(id) != 0 && !has_property_on_prototype(cx, proxy, id) {\n" +
" let name = jsid_to_str(cx, id);\n" +
" let this = UnwrapProxy(proxy);\n" +
- " let this = Unrooted::from_raw(this);\n" +
- " let this = this.root();\n" +
+ " let this = &*this;\n" +
CGIndenter(CGProxyNamedGetter(self.descriptor)).define() + "\n" +
- " *bp = found;\n"
- " return true;\n"
+ " *bp = found as u8;\n"
+ " return JSTrue;\n"
"}\n" +
"\n")
else:
named = ""
return indexed + """\
-let expando: *mut JSObject = get_expando_object(proxy);
-if !expando.is_null() {
- let mut b: JSBool = 1;
- let ok = JS_HasPropertyById(cx, expando, id, &mut b) != 0;
- *bp = b != 0;
- if !ok || *bp {
- return ok;
+let expando = RootedObject::new(cx, get_expando_object(proxy));
+if !expando.ptr.is_null() {
+ let mut b: u8 = 1;
+ let ok = JS_HasPropertyById(cx, expando.handle(), id, &mut b) != 0;
+ *bp = (b != 0) as u8;
+ if !ok || *bp != 0 {
+ return ok as u8;
}
}
""" + named + """\
-*bp = false;
-return true;"""
+*bp = JSFalse;
+return JSTrue;"""
def definition_body(self):
return CGGeneric(self.getBody())
class CGDOMJSProxyHandler_get(CGAbstractExternMethod):
def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', 'proxy'),
- Argument('*mut JSObject', '_receiver'), Argument('jsid', 'id'),
- Argument('*mut JSVal', 'vp')]
- CGAbstractExternMethod.__init__(self, descriptor, "get", "bool", args)
+ args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', 'proxy'),
+ Argument('HandleObject', '_receiver'), Argument('HandleId', 'id'),
+ Argument('MutableHandleValue', 'vp')]
+ CGAbstractExternMethod.__init__(self, descriptor, "get", "u8", args)
self.descriptor = descriptor
def getBody(self):
getFromExpando = """\
-let expando = get_expando_object(proxy);
-if !expando.is_null() {
+let expando = RootedObject::new(cx, get_expando_object(proxy));
+if !expando.ptr.is_null() {
let mut hasProp = 0;
- if JS_HasPropertyById(cx, expando, id, &mut hasProp) == 0 {
- return false;
+ if JS_HasPropertyById(cx, expando.handle(), id, &mut hasProp) == 0 {
+ return JSFalse;
}
if hasProp != 0 {
- return JS_GetPropertyById(cx, expando, id, vp) != 0;
+ return (JS_GetPropertyById(cx, expando.handle(), id, vp) != 0) as u8;
}
}"""
templateValues = {
- 'jsvalRef': '*vp',
- 'successCode': 'return true;',
+ 'jsvalRef': 'vp',
+ 'successCode': 'return JSTrue;',
}
indexedGetter = self.descriptor.operations['IndexedGetter']
@@ -4062,8 +4402,7 @@ if !expando.is_null() {
"if index.is_some() {\n" +
" let index = index.unwrap();\n" +
" let this = UnwrapProxy(proxy);\n" +
- " let this = Unrooted::from_raw(this);\n" +
- " let this = this.root();\n" +
+ " let this = &*this;\n" +
CGIndenter(CGProxyIndexedGetter(self.descriptor, templateValues)).define())
getIndexedOrExpando += """\
// Even if we don't have this index, we don't forward the
@@ -4080,8 +4419,7 @@ if !expando.is_null() {
getNamed = ("if (RUST_JSID_IS_STRING(id) != 0) {\n" +
" let name = jsid_to_str(cx, id);\n" +
" let this = UnwrapProxy(proxy);\n" +
- " let this = Unrooted::from_raw(this);\n" +
- " let this = this.root();\n" +
+ " let this = &*this;\n" +
CGIndenter(CGProxyNamedGetter(self.descriptor, templateValues)).define() +
"}\n")
else:
@@ -4094,26 +4432,26 @@ if !expando.is_null() {
%s
let mut found = false;
if !get_property_on_prototype(cx, proxy, id, &mut found, vp) {
- return false;
+ return JSFalse;
}
if found {
- return true;
+ return JSTrue;
}
%s
-*vp = UndefinedValue();
-return true;""" % (getIndexedOrExpando, getNamed)
+*vp.ptr = UndefinedValue();
+return JSTrue;""" % (getIndexedOrExpando, getNamed)
def definition_body(self):
return CGGeneric(self.getBody())
-class CGDOMJSProxyHandler_obj_toString(CGAbstractExternMethod):
+class CGDOMJSProxyHandler_className(CGAbstractExternMethod):
def __init__(self, descriptor):
- args = [Argument('*mut JSContext', 'cx'), Argument('*mut JSObject', '_proxy')]
- CGAbstractExternMethod.__init__(self, descriptor, "obj_toString", "*mut JSString", args)
+ args = [Argument('*mut JSContext', 'cx'), Argument('HandleObject', '_proxy')]
+ CGAbstractExternMethod.__init__(self, descriptor, "className", "*const i8", args)
self.descriptor = descriptor
def getBody(self):
- return """proxyhandler::object_to_string(cx, "%s")""" % self.descriptor.name
+ return '%s as *const u8 as *const i8' % str_to_const_array(self.descriptor.name)
def definition_body(self):
return CGGeneric(self.getBody())
@@ -4165,7 +4503,8 @@ class CGClassTraceHook(CGAbstractClassHook):
self.traceGlobal = descriptor.isGlobal()
def generate_code(self):
- body = [CGGeneric("(*this).trace(%s);" % self.args[0].name)]
+ body = [CGGeneric("if this.is_null() { return; } // GC during obj creation\n"
+ "(*this).trace(%s);" % self.args[0].name)]
if self.traceGlobal:
body += [CGGeneric("trace_global(trc, obj);")]
return CGList(body, "\n")
@@ -4177,7 +4516,7 @@ class CGClassConstructHook(CGAbstractExternMethod):
def __init__(self, descriptor):
args = [Argument('*mut JSContext', 'cx'), Argument('u32', 'argc'), Argument('*mut JSVal', 'vp')]
CGAbstractExternMethod.__init__(self, descriptor, CONSTRUCT_HOOK_NAME,
- 'JSBool', args)
+ 'u8', args)
self._ctor = self.descriptor.interface.ctor()
def define(self):
@@ -4188,7 +4527,7 @@ class CGClassConstructHook(CGAbstractExternMethod):
def definition_body(self):
preamble = CGGeneric("""\
let global = global_object_for_js_object(JS_CALLEE(cx, vp).to_object());
-let global = global.root();
+let args = CallArgs::from_vp(vp, argc);
""")
name = self._ctor.identifier.name
nativeName = MakeNativeName(self.descriptor.binaryNameFor(name))
@@ -4201,7 +4540,7 @@ class CGClassFinalizeHook(CGAbstractClassHook):
A hook for finalize, used to release our native object.
"""
def __init__(self, descriptor):
- args = [Argument('*mut JSFreeOp', '_fop'), Argument('*mut JSObject', 'obj')]
+ args = [Argument('*mut FreeOp', '_fop'), Argument('*mut JSObject', 'obj')]
CGAbstractClassHook.__init__(self, descriptor, FINALIZE_HOOK_NAME,
'void', args)
@@ -4391,7 +4730,7 @@ class CGDescriptor(CGThing):
cgThings.append(CGProxyUnwrap(descriptor))
cgThings.append(CGDOMJSProxyHandlerDOMClass(descriptor))
cgThings.append(CGDOMJSProxyHandler_getOwnPropertyDescriptor(descriptor))
- cgThings.append(CGDOMJSProxyHandler_obj_toString(descriptor))
+ cgThings.append(CGDOMJSProxyHandler_className(descriptor))
cgThings.append(CGDOMJSProxyHandler_get(descriptor))
cgThings.append(CGDOMJSProxyHandler_hasOwn(descriptor))
@@ -4427,7 +4766,7 @@ class CGDescriptor(CGThing):
return self.cgRoot.define()
class CGNonNamespacedEnum(CGThing):
- def __init__(self, enumName, names, values, comment="", deriving=""):
+ def __init__(self, enumName, names, values, comment="", deriving="", repr=""):
if not values:
values = []
@@ -4449,6 +4788,8 @@ class CGNonNamespacedEnum(CGThing):
# Build the enum body.
enumstr = comment + 'pub enum %s {\n%s\n}\n' % (enumName, ',\n'.join(entries))
+ if repr:
+ enumstr = ('#[repr(%s)]\n' % repr) + enumstr
if deriving:
enumstr = ('#[derive(%s)]\n' % deriving) + enumstr
curr = CGGeneric(enumstr)
@@ -4523,13 +4864,13 @@ class CGDictionary(CGThing):
def memberInit(memberInfo):
member, _ = memberInfo
name = self.makeMemberName(member.identifier.name)
- conversion = self.getMemberConversion(memberInfo)
+ conversion = self.getMemberConversion(memberInfo, member.type)
return CGGeneric("%s: %s,\n" % (name, conversion.define()))
def memberInsert(memberInfo):
member, _ = memberInfo
name = self.makeMemberName(member.identifier.name)
- insertion = ("set_dictionary_property(cx, obj, \"%s\", &mut self.%s.to_jsval(cx)).unwrap();" % (name, name))
+ insertion = ("let mut %s = RootedValue::new(cx, UndefinedValue());\nself.%s.to_jsval(cx, %s.handle_mut());\nset_dictionary_property(cx, obj.handle(), \"%s\", %s.handle()).unwrap();" % (name, name, name, name, name))
return CGGeneric("%s\n" % insertion)
memberInits = CGList([memberInit(m) for m in self.memberInfo])
@@ -4537,14 +4878,14 @@ class CGDictionary(CGThing):
return string.Template(
"impl ${selfName} {\n"
- " pub fn empty() -> ${selfName} {\n"
- " ${selfName}::new(ptr::null_mut(), NullValue()).unwrap()\n"
+ " pub fn empty(cx: *mut JSContext) -> ${selfName} {\n"
+ " ${selfName}::new(cx, HandleValue::null()).unwrap()\n"
" }\n"
- " pub fn new(cx: *mut JSContext, val: JSVal) -> Result<${selfName}, ()> {\n"
- " let object = if val.is_null_or_undefined() {\n"
- " ptr::null_mut()\n"
- " } else if val.is_object() {\n"
- " val.to_object()\n"
+ " pub fn new(cx: *mut JSContext, val: HandleValue) -> Result<${selfName}, ()> {\n"
+ " let object = if val.get().is_null_or_undefined() {\n"
+ " RootedObject::new(cx, ptr::null_mut())\n"
+ " } else if val.get().is_object() {\n"
+ " RootedObject::new(cx, val.get().to_object())\n"
" } else {\n"
" throw_type_error(cx, \"Value not an object.\");\n"
" return Err(());\n"
@@ -4557,10 +4898,10 @@ class CGDictionary(CGThing):
"}\n"
"\n"
"impl ToJSValConvertible for ${selfName} {\n"
- " fn to_jsval(&self, cx: *mut JSContext) -> JSVal {\n"
- " let obj = unsafe { JS_NewObject(cx, 0 as *const JSClass, 0 as *const JSObject, 0 as *const JSObject) };\n"
+ " fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {\n"
+ " let obj = unsafe { RootedObject::new(cx, JS_NewObject(cx, ptr::null())) };\n"
"${insertMembers}"
- " ObjectOrNullValue(obj)\n"
+ " rval.set(ObjectOrNullValue(obj.ptr))\n"
" }\n"
"}\n").substitute({
"selfName": self.makeClassName(d),
@@ -4587,7 +4928,7 @@ class CGDictionary(CGThing):
declType = CGWrapper(info.declType, pre="Option<", post=">")
return declType.define()
- def getMemberConversion(self, memberInfo):
+ def getMemberConversion(self, memberInfo, memberType):
def indent(s):
return CGIndenter(CGGeneric(s), 8).define()
@@ -4595,8 +4936,10 @@ class CGDictionary(CGThing):
templateBody = info.template
default = info.default
declType = info.declType
- replacements = { "val": "value" }
+ replacements = { "val": "rval.handle()" }
conversion = string.Template(templateBody).substitute(replacements)
+ if memberType.isAny():
+ conversion = "%s.get()" % conversion
assert (member.defaultValue is None) == (default is None)
if not default:
@@ -4604,14 +4947,16 @@ class CGDictionary(CGThing):
conversion = "Some(%s)" % conversion
conversion = (
- "match try!(get_dictionary_property(cx, object, \"%s\")) {\n"
- " Some(value) => {\n"
+ "{\n"
+ "let mut rval = RootedValue::new(cx, UndefinedValue());\n"
+ "match try!(get_dictionary_property(cx, object.handle(), \"%s\", rval.handle_mut())) {\n"
+ " true => {\n"
"%s\n"
" },\n"
- " None => {\n"
+ " false => {\n"
"%s\n"
" },\n"
- "}") % (member.identifier.name, indent(conversion), indent(default))
+ "}\n}") % (member.identifier.name, indent(conversion), indent(default))
return CGGeneric(conversion)
@@ -4641,7 +4986,7 @@ class CGRegisterProtos(CGAbstractMethod):
def __init__(self, config):
arguments = [
Argument('*mut JSContext', 'cx'),
- Argument('*mut JSObject', 'global'),
+ Argument('HandleObject', 'global'),
]
CGAbstractMethod.__init__(self, None, 'Register', 'void', arguments,
unsafe=False, pub=True)
@@ -4732,38 +5077,41 @@ class CGBindingRoot(CGThing):
# Add imports
curr = CGImports(curr, descriptors + callbackDescriptors, mainCallbacks, [
'js',
- 'js::{JS_ARGV, JS_CALLEE, JS_THIS_OBJECT}',
- 'js::{JSCLASS_GLOBAL_SLOT_COUNT, JSCLASS_IS_DOMJSCLASS}',
+ 'js::JS_CALLEE',
+ 'js::{JSCLASS_GLOBAL_SLOT_COUNT, JSCLASS_IS_DOMJSCLASS, JSCLASS_IMPLEMENTS_BARRIERS}',
'js::{JSCLASS_IS_GLOBAL, JSCLASS_RESERVED_SLOTS_SHIFT}',
- 'js::{JSCLASS_RESERVED_SLOTS_MASK, JSID_VOID, JSJitInfo}',
- 'js::{JSPROP_ENUMERATE, JSPROP_NATIVE_ACCESSORS, JSPROP_SHARED}',
- 'js::{JSRESOLVE_ASSIGNING, JSRESOLVE_QUALIFIED}',
+ 'js::{JSCLASS_RESERVED_SLOTS_MASK}',
+ 'js::{JSPROP_ENUMERATE, JSPROP_SHARED}',
'js::jsapi::{JS_CallFunctionValue, JS_GetClass, JS_GetGlobalForObject}',
'js::jsapi::{JS_GetObjectPrototype, JS_GetProperty, JS_GetPropertyById}',
'js::jsapi::{JS_GetPropertyDescriptorById, JS_GetReservedSlot}',
'js::jsapi::{JS_HasProperty, JS_HasPropertyById, JS_IsExceptionPending}',
- 'js::jsapi::{JS_NewObject, JS_ObjectIsCallable, JS_SetProperty, JS_SetPrototype}',
- 'js::jsapi::{JS_SetReservedSlot, JS_WrapValue, JSBool, JSContext}',
- 'js::jsapi::{JSClass, JSFreeOp, JSFunctionSpec, JSHandleObject, jsid}',
- 'js::jsapi::{JSNativeWrapper, JSObject, JSPropertyDescriptor, JS_ArrayIterator}',
- 'js::jsapi::{JSPropertyOpWrapper, JSPropertySpec, JS_PropertyStub}',
- 'js::jsapi::{JSStrictPropertyOpWrapper, JSString, JSTracer, JS_ConvertStub}',
- 'js::jsapi::{JS_StrictPropertyStub, JS_EnumerateStub, JS_ResolveStub}',
- 'js::jsapi::{JSMutableHandleValue, JSHandleId, JSType}',
+ 'js::jsapi::{JS_NewObjectWithGivenProto, JS_NewObject, IsCallable, JS_SetProperty, JS_SetPrototype}',
+ 'js::jsapi::{JS_SetReservedSlot, JS_WrapValue, JSContext}',
+ 'js::jsapi::{JSClass, FreeOp, JSFreeOp, JSFunctionSpec, jsid}',
+ 'js::jsapi::{MutableHandleValue, MutableHandleObject, HandleObject, HandleValue, RootedObject, RootedValue}',
+ 'js::jsapi::{JSNativeWrapper, JSNative, JSObject, JSPropertyDescriptor}',
+ 'js::jsapi::{JSPropertySpec}',
+ 'js::jsapi::{JSString, JSTracer, JSJitInfo, JSJitInfo_OpType, JSJitInfo_AliasSet}',
+ 'js::jsapi::{MutableHandle, Handle, HandleId, JSType, JSValueType}',
+ 'js::jsapi::{SymbolCode, ObjectOpResult, HandleValueArray}',
+ 'js::jsapi::{JSJitGetterCallArgs, JSJitSetterCallArgs, JSJitMethodCallArgs, CallArgs}',
+ 'js::jsapi::{JSAutoCompartment, JSAutoRequest, JS_ComputeThis}',
+ 'js::jsapi::GetGlobalForObjectCrossCompartment',
'js::jsval::JSVal',
'js::jsval::{ObjectValue, ObjectOrNullValue, PrivateValue}',
'js::jsval::{NullValue, UndefinedValue}',
- 'js::glue::{CallJitMethodOp, CallJitPropertyOp, CreateProxyHandler}',
- 'js::glue::{GetProxyPrivate, NewProxyObject, ProxyTraps, AutoIdVector}',
+ 'js::glue::{CallJitMethodOp, CallJitGetterOp, CallJitSetterOp, CreateProxyHandler}',
+ 'js::glue::{GetProxyPrivate, NewProxyObject, ProxyTraps}',
'js::glue::{RUST_FUNCTION_VALUE_TO_JITINFO}',
'js::glue::{RUST_JS_NumberValue, RUST_JSID_IS_STRING}',
- 'js::rust::with_compartment',
+ 'js::rust::GCMethods',
+ 'js::{JSTrue, JSFalse}',
'dom::bindings',
'dom::bindings::global::GlobalRef',
'dom::bindings::global::global_object_for_js_object',
- 'dom::bindings::js::{JS, JSRef, Root, RootedReference, Temporary, Unrooted}',
- 'dom::bindings::js::{OptionalOptionalRootable, OptionalRootable}',
- 'dom::bindings::js::{OptionalRootedReference, ResultRootable, Rootable}',
+ 'dom::bindings::js::{JS, Root, RootedReference}',
+ 'dom::bindings::js::{OptionalRootedReference}',
'dom::bindings::utils::{create_dom_global, do_create_interface_objects}',
'dom::bindings::utils::ConstantSpec',
'dom::bindings::utils::{DOMClass}',
@@ -4780,16 +5128,16 @@ class CGBindingRoot(CGThing):
'dom::bindings::utils::{NativeProperties, NativePropertyHooks}',
'dom::bindings::utils::ConstantVal::{IntVal, UintVal}',
'dom::bindings::utils::NonNullJSNative',
- 'dom::bindings::trace::JSTraceable',
+ 'dom::bindings::trace::{JSTraceable, RootedTraceable}',
'dom::bindings::callback::{CallbackContainer,CallbackInterface,CallbackFunction}',
'dom::bindings::callback::{CallSetup,ExceptionHandling}',
'dom::bindings::callback::wrap_call_this_object',
'dom::bindings::conversions::{FromJSValConvertible, ToJSValConvertible}',
- 'dom::bindings::conversions::{native_from_reflector, native_from_reflector_jsmanaged}',
+ 'dom::bindings::conversions::{native_from_reflector, native_from_handlevalue, native_from_handleobject}',
'dom::bindings::conversions::DOM_OBJECT_SLOT',
'dom::bindings::conversions::IDLInterface',
'dom::bindings::conversions::jsid_to_str',
- 'dom::bindings::conversions::StringificationBehavior::{Default, Empty}',
+ 'dom::bindings::conversions::StringificationBehavior',
'dom::bindings::codegen::{PrototypeList, RegisterBindings, UnionTypes}',
'dom::bindings::codegen::Bindings::*',
'dom::bindings::error::{Fallible, Error, ErrorResult}',
@@ -4812,6 +5160,10 @@ class CGBindingRoot(CGThing):
'std::num',
'std::ptr',
'std::str',
+ 'std::rc',
+ 'std::rc::Rc',
+ 'std::default::Default',
+ 'std::ffi::CString',
])
# Add the auto-generated comment.
@@ -4918,7 +5270,7 @@ class CGCallback(CGClass):
bases=[ClassBase(baseName)],
constructors=self.getConstructors(),
methods=realMethods+getters+setters,
- decorators="#[derive(PartialEq,Copy,Clone)]#[jstraceable]")
+ decorators="#[derive(PartialEq)]#[jstraceable]")
def getConstructors(self):
return [ClassConstructor(
@@ -4927,7 +5279,7 @@ class CGCallback(CGClass):
visibility="pub",
explicit=False,
baseConstructors=[
- "%s::new(aCallback)" % self.baseName
+ "%s::new()" % self.baseName
])]
def getMethodImpls(self, method):
@@ -4936,13 +5288,13 @@ class CGCallback(CGClass):
# Strip out the JSContext*/JSObject* args
# that got added.
assert args[0].name == "cx" and args[0].argType == "*mut JSContext"
- assert args[1].name == "aThisObj" and args[1].argType == "*mut JSObject"
+ assert args[1].name == "aThisObj" and args[1].argType == "HandleObject"
args = args[2:]
# Record the names of all the arguments, so we can use them when we call
# the private method.
argnames = [arg.name for arg in args]
- argnamesWithThis = ["s.get_context()", "thisObjJS"] + argnames
- argnamesWithoutThis = ["s.get_context()", "ptr::null_mut()"] + argnames
+ argnamesWithThis = ["s.get_context()", "thisObjJS.handle()"] + argnames
+ argnamesWithoutThis = ["s.get_context()", "thisObjJS.handle()"] + argnames
# Now that we've recorded the argnames for our call to our private
# method, insert our optional argument for deciding whether the
# CallSetup should re-throw exceptions on aRv.
@@ -4951,12 +5303,12 @@ class CGCallback(CGClass):
# And now insert our template argument.
argsWithoutThis = list(args)
- args.insert(0, Argument("JSRef<T>", "thisObj"))
+ args.insert(0, Argument("&T", "thisObj"))
# And the self argument
- method.args.insert(0, Argument(None, "self"))
- args.insert(0, Argument(None, "self"))
- argsWithoutThis.insert(0, Argument(None, "self"))
+ method.args.insert(0, Argument(None, "&self"))
+ args.insert(0, Argument(None, "&self"))
+ argsWithoutThis.insert(0, Argument(None, "&self"))
setupCall = ("let s = CallSetup::new(self, aExceptionHandling);\n"
"if s.get_context().is_null() {\n"
@@ -4965,8 +5317,9 @@ class CGCallback(CGClass):
bodyWithThis = string.Template(
setupCall+
- "let thisObjJS = wrap_call_this_object(s.get_context(), thisObj);\n"
- "if thisObjJS.is_null() {\n"
+ "let mut thisObjJS = RootedObject::new(s.get_context(), ptr::null_mut());\n"
+ "wrap_call_this_object(s.get_context(), thisObj, thisObjJS.handle_mut());\n"
+ "if thisObjJS.ptr.is_null() {\n"
" return Err(JSFailed);\n"
"}\n"
"return ${methodName}(${callArgs});").substitute({
@@ -4975,6 +5328,7 @@ class CGCallback(CGClass):
})
bodyWithoutThis = string.Template(
setupCall +
+ "let thisObjJS = RootedObject::new(s.get_context(), ptr::null_mut());"
"return ${methodName}(${callArgs});").substitute({
"callArgs" : ", ".join(argnamesWithoutThis),
"methodName": 'self.' + method.name,
@@ -5017,7 +5371,7 @@ class CGCallbackFunctionImpl(CGGeneric):
def __init__(self, callback):
impl = string.Template("""\
impl CallbackContainer for ${type} {
- fn new(callback: *mut JSObject) -> ${type} {
+ fn new(callback: *mut JSObject) -> Rc<${type}> {
${type}::new(callback)
}
@@ -5027,8 +5381,8 @@ impl CallbackContainer for ${type} {
}
impl ToJSValConvertible for ${type} {
- fn to_jsval(&self, cx: *mut JSContext) -> JSVal {
- self.callback().to_jsval(cx)
+ fn to_jsval(&self, cx: *mut JSContext, rval: MutableHandleValue) {
+ self.callback().to_jsval(cx, rval);
}
}\
""").substitute({"type": callback.name})
@@ -5127,14 +5481,12 @@ class CallbackMember(CGNativeMember):
"${returnResult}").substitute(replacements)
return CGList([
CGGeneric(pre),
- CGWrapper(CGIndenter(CGGeneric(body)),
- pre="with_compartment(cx, self.parent.callback(), || {\n",
- post="})")
+ CGGeneric(body),
], "\n").define()
def getResultConversion(self):
replacements = {
- "val": "rval",
+ "val": "rval.handle()",
}
info = getJSToNativeConversionInfo(
@@ -5153,6 +5505,8 @@ class CallbackMember(CGNativeMember):
if self.retvalType is None or self.retvalType.isVoid():
retval = "()"
+ elif self.retvalType.isAny():
+ retval = "rvalDecl.get()"
else:
retval = "rvalDecl"
@@ -5177,16 +5531,17 @@ class CallbackMember(CGNativeMember):
argval = arg.identifier.name
if arg.variadic:
- argval = argval + "[idx]"
+ argval = argval + "[idx].get()"
jsvalIndex = "%d + idx" % i
else:
jsvalIndex = "%d" % i
if arg.optional and not arg.defaultValue:
argval += ".clone().unwrap()"
- conversion = wrapForType("argv[%s]" % jsvalIndex,
- result=argval,
- successCode="")
+ conversion = wrapForType(
+ "argv_root.handle_mut()", result=argval,
+ successCode="argv[%s] = argv_root.ptr;" % jsvalIndex,
+ pre="let mut argv_root = RootedValue::new(cx, UndefinedValue());")
if arg.variadic:
conversion = string.Template(
"for idx in 0..${arg}.len() {\n" +
@@ -5216,7 +5571,7 @@ class CallbackMember(CGNativeMember):
# We want to allow the caller to pass in a "this" object, as
# well as a JSContext.
return [Argument("*mut JSContext", "cx"),
- Argument("*mut JSObject", "aThisObj")] + args
+ Argument("HandleObject", "aThisObj")] + args
def getCallSetup(self):
if self.needThisHandling:
@@ -5230,7 +5585,7 @@ class CallbackMember(CGNativeMember):
"}\n")
def getArgcDecl(self):
- return CGGeneric("let mut argc = %s as u32;" % self.argCountStr);
+ return CGGeneric("let mut argc = %s;" % self.argCountStr);
@staticmethod
def ensureASCIIName(idlObject):
@@ -5252,7 +5607,7 @@ class CallbackMethod(CallbackMember):
CallbackMember.__init__(self, sig, name, descriptorProvider,
needThisHandling)
def getRvalDecl(self):
- return "let mut rval = UndefinedValue();\n"
+ return "let mut rval = RootedValue::new(cx, UndefinedValue());\n"
def getCall(self):
replacements = {
@@ -5260,15 +5615,16 @@ class CallbackMethod(CallbackMember):
"getCallable": self.getCallableDecl()
}
if self.argCount > 0:
- replacements["argv"] = "argv.as_mut_ptr()"
+ replacements["argv"] = "argv.as_ptr()"
replacements["argc"] = "argc"
else:
replacements["argv"] = "ptr::null_mut()"
replacements["argc"] = "0"
return string.Template("${getCallable}"
"let ok = unsafe {\n"
- " JS_CallFunctionValue(cx, ${thisObj}, callable,\n"
- " ${argc}, ${argv}, &mut rval)\n"
+ " let rootedThis = RootedObject::new(cx, ${thisObj});\n"
+ " JS_CallFunctionValue(cx, rootedThis.handle(), callable.handle(),\n"
+ " &HandleValueArray { length_: ${argc} as ::libc::size_t, elements_: ${argv} }, rval.handle_mut())\n"
"};\n"
"if ok == 0 {\n"
" return Err(JSFailed);\n"
@@ -5280,10 +5636,10 @@ class CallCallback(CallbackMethod):
descriptorProvider, needThisHandling=True)
def getThisObj(self):
- return "aThisObj"
+ return "aThisObj.get()"
def getCallableDecl(self):
- return "let callable = ObjectValue(unsafe {&*self.parent.callback()});\n"
+ return "let callable = RootedValue::new(cx, ObjectValue(unsafe {&*self.parent.callback()}));\n"
class CallbackOperationBase(CallbackMethod):
"""
@@ -5300,23 +5656,23 @@ class CallbackOperationBase(CallbackMethod):
# This relies on getCallableDecl declaring a boolean
# isCallable in the case when we're a single-operation
# interface.
- return "if isCallable { aThisObj } else { self.parent.callback() }"
+ return "if isCallable { aThisObj.get() } else { self.parent.callback() }"
def getCallableDecl(self):
replacements = {
"methodName": self.methodName
}
getCallableFromProp = string.Template(
- 'try!(self.parent.get_callable_property(cx, "${methodName}"))'
+ 'RootedValue::new(cx, try!(self.parent.get_callable_property(cx, "${methodName}")))'
).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 isCallable = unsafe { IsCallable(self.parent.callback()) != 0 };\n'
'let callable =\n' +
CGIndenter(
CGIfElseWrapper('isCallable',
- CGGeneric('unsafe { ObjectValue(&*self.parent.callback()) }'),
+ CGGeneric('unsafe { RootedValue::new(cx, ObjectValue(&*self.parent.callback())) }'),
CGGeneric(getCallableFromProp))).define() + ';\n')
class CallbackOperation(CallbackOperationBase):
@@ -5399,7 +5755,7 @@ class GlobalGenRoots():
return CGList([
CGGeneric(AUTOGENERATED_WARNING_COMMENT),
CGGeneric("pub const MAX_PROTO_CHAIN_LENGTH: usize = %d;\n\n" % config.maxProtoChainLength),
- CGNonNamespacedEnum('ID', protos, [0], deriving="PartialEq, Copy, Clone"),
+ CGNonNamespacedEnum('ID', protos, [0], deriving="PartialEq, Copy, Clone", repr="u16"),
CGNonNamespacedEnum('Proxies', proxies, [0], deriving="PartialEq, Copy, Clone"),
])
@@ -5416,7 +5772,7 @@ class GlobalGenRoots():
'dom::bindings::codegen',
'dom::bindings::codegen::PrototypeList::Proxies',
'js::jsapi::JSContext',
- 'js::jsapi::JSObject',
+ 'js::jsapi::HandleObject',
'libc',
], ignored_warnings=[])
@@ -5442,7 +5798,7 @@ class GlobalGenRoots():
descriptors = config.getDescriptors(register=True, isCallback=False)
allprotos = [CGGeneric("use dom::types::*;\n"),
- CGGeneric("use dom::bindings::js::{JS, JSRef, LayoutJS, Rootable, Temporary};\n"),
+ CGGeneric("use dom::bindings::js::{JS, LayoutJS, Root};\n"),
CGGeneric("use dom::bindings::trace::JSTraceable;\n"),
CGGeneric("use dom::bindings::utils::Reflectable;\n"),
CGGeneric("use js::jsapi::JSTracer;\n\n"),
@@ -5476,7 +5832,7 @@ impl ${selfName} for ${baseName} {
pub struct ${name}Cast;
impl ${name}Cast {
#[inline]
- pub fn to_ref<'a, T: ${toBound}+Reflectable>(base: JSRef<'a, T>) -> Option<JSRef<'a, ${name}>> {
+ pub fn to_ref<'a, T: ${toBound}+Reflectable>(base: &'a T) -> Option<&'a ${name}> {
match base.${checkFn}() {
true => Some(unsafe { mem::transmute(base) }),
false => None
@@ -5484,7 +5840,7 @@ impl ${name}Cast {
}
#[inline]
- pub fn to_borrowed_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a JSRef<'b, T>) -> Option<&'a JSRef<'b, ${name}>> {
+ pub fn to_borrowed_ref<'a, 'b, T: ${toBound}+Reflectable>(base: &'a &'b T) -> Option<&'a &'b ${name}> {
match base.${checkFn}() {
true => Some(unsafe { mem::transmute(base) }),
false => None
@@ -5503,20 +5859,20 @@ impl ${name}Cast {
}
#[inline]
- pub fn to_temporary<T: ${toBound}+Reflectable>(base: Temporary<T>) -> Option<Temporary<${name}>> {
- match base.root().r().${checkFn}() {
+ pub fn to_root<T: ${toBound}+Reflectable>(base: Root<T>) -> Option<Root<${name}>> {
+ match base.r().${checkFn}() {
true => Some(unsafe { mem::transmute(base) }),
false => None
}
}
#[inline]
- pub fn from_ref<'a, T: ${fromBound}+Reflectable>(derived: JSRef<'a, T>) -> JSRef<'a, ${name}> {
+ pub fn from_ref<'a, T: ${fromBound}+Reflectable>(derived: &'a T) -> &'a ${name} {
unsafe { mem::transmute(derived) }
}
#[inline]
- pub fn from_borrowed_ref<'a, 'b, T: ${fromBound}+Reflectable>(derived: &'a JSRef<'b, T>) -> &'a JSRef<'b, ${name}> {
+ pub fn from_borrowed_ref<'a, 'b, T: ${fromBound}+Reflectable>(derived: &'a &'b T) -> &'a &'b ${name} {
unsafe { mem::transmute(derived) }
}
@@ -5527,7 +5883,7 @@ impl ${name}Cast {
}
#[inline]
- pub fn from_temporary<T: ${fromBound}+Reflectable>(derived: Temporary<T>) -> Temporary<${name}> {
+ pub fn from_root<T: ${fromBound}+Reflectable>(derived: Root<T>) -> Root<${name}> {
unsafe { mem::transmute(derived) }
}