Bug 1023520 - Add support for Promise returning methods on globals. r=bz

This commit is contained in:
Nikhil Marathe 2014-06-11 09:05:22 -07:00
Родитель ef353be5a0
Коммит b9757dfad4
1 изменённых файлов: 56 добавлений и 5 удалений

Просмотреть файл

@ -2143,10 +2143,9 @@ class MethodDefiner(PropertyDefiner):
accessor = "genericCrossOriginMethod" accessor = "genericCrossOriginMethod"
elif self.descriptor.needsSpecialGenericOps(): elif self.descriptor.needsSpecialGenericOps():
if m.get("returnsPromise", False): if m.get("returnsPromise", False):
raise TypeError("%s returns a Promise but needs " accessor = "genericPromiseReturningMethod"
"special generic ops?" % else:
accessor) accessor = "genericMethod"
accessor = "genericMethod"
elif m.get("returnsPromise", False): elif m.get("returnsPromise", False):
accessor = "GenericPromiseReturningBindingMethod" accessor = "GenericPromiseReturningBindingMethod"
else: else:
@ -6904,6 +6903,53 @@ class CGGenericMethod(CGAbstractBindingMethod):
return ok; return ok;
""")) """))
class CGGenericPromiseReturningMethod(CGAbstractBindingMethod):
"""
A class for generating the C++ code for an IDL method that returns a Promise.
Does not handle cross-origin this.
"""
def __init__(self, descriptor):
args = [Argument('JSContext*', 'cx'),
Argument('unsigned', 'argc'),
Argument('JS::Value*', 'vp')]
unwrapFailureCode = dedent("""
ThrowInvalidThis(cx, args, GetInvalidThisErrorForMethod(%%(securityError)s), "%s");\n
return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
args.rval());\n""" %
descriptor.interface.identifier.name)
name = "genericPromiseReturningMethod"
customCallArgs = dedent("""
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
// Make sure to save the callee before someone maybe messes with rval().
JS::Rooted<JSObject*> callee(cx, &args.callee());
""")
CGAbstractBindingMethod.__init__(self, descriptor, name,
args,
callArgs=customCallArgs,
unwrapFailureCode=unwrapFailureCode)
def generate_code(self):
return CGGeneric(dedent("""
const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(args.calleev());
MOZ_ASSERT(info->type() == JSJitInfo::Method);
JSJitMethodOp method = info->method;
bool ok = method(cx, obj, self, JSJitMethodCallArgs(args));
if (ok) {
#ifdef DEBUG
AssertReturnTypeMatchesJitinfo(info, args.rval());
#endif
return true;
}
MOZ_ASSERT(info->returnType() == JSVAL_TYPE_OBJECT);
return ConvertExceptionToPromise(cx, xpc::XrayAwareCalleeGlobal(callee),
args.rval());
"""))
class CGSpecializedMethod(CGAbstractStaticMethod): class CGSpecializedMethod(CGAbstractStaticMethod):
""" """
@ -10153,7 +10199,8 @@ class CGDescriptor(CGThing):
# These are set to true if at least one non-static # These are set to true if at least one non-static
# method/getter/setter or jsonifier exist on the interface. # method/getter/setter or jsonifier exist on the interface.
(hasMethod, hasGetter, hasLenientGetter, hasSetter, hasJsonifier, (hasMethod, hasGetter, hasLenientGetter, hasSetter, hasJsonifier,
hasLenientSetter) = False, False, False, False, False, False hasLenientSetter,
hasPromiseReturningMethod) = False, False, False, False, False, False, False
crossOriginMethods, crossOriginGetters, crossOriginSetters = set(), set(), set() crossOriginMethods, crossOriginGetters, crossOriginSetters = set(), set(), set()
for n in descriptor.interface.namedConstructors: for n in descriptor.interface.namedConstructors:
cgThings.append(CGClassConstructor(descriptor, n, cgThings.append(CGClassConstructor(descriptor, n,
@ -10176,6 +10223,8 @@ class CGDescriptor(CGThing):
specializedMethod = CGSpecializedMethod(descriptor, m) specializedMethod = CGSpecializedMethod(descriptor, m)
cgThings.append(specializedMethod) cgThings.append(specializedMethod)
if m.returnsPromise(): if m.returnsPromise():
if descriptor.needsSpecialGenericOps():
hasPromiseReturningMethod = True
cgThings.append(CGMethodPromiseWrapper(descriptor, specializedMethod)) cgThings.append(CGMethodPromiseWrapper(descriptor, specializedMethod))
cgThings.append(CGMemberJITInfo(descriptor, m)) cgThings.append(CGMemberJITInfo(descriptor, m))
if m.getExtendedAttribute("CrossOriginCallable"): if m.getExtendedAttribute("CrossOriginCallable"):
@ -10234,6 +10283,8 @@ class CGDescriptor(CGThing):
cgThings.append(CGMemberJITInfo(descriptor, jsonifierMethod)) cgThings.append(CGMemberJITInfo(descriptor, jsonifierMethod))
if hasMethod: if hasMethod:
cgThings.append(CGGenericMethod(descriptor)) cgThings.append(CGGenericMethod(descriptor))
if hasPromiseReturningMethod:
cgThings.append(CGGenericPromiseReturningMethod(descriptor))
if len(crossOriginMethods): if len(crossOriginMethods):
cgThings.append(CGGenericMethod(descriptor, cgThings.append(CGGenericMethod(descriptor,
allowCrossOriginThis=True)) allowCrossOriginThis=True))