Bug 919603 part 2. Change this-handling in codegen to only do the special global object stuff on interfaces where it might matter. r=peterv

This commit is contained in:
Boris Zbarsky 2013-09-25 14:38:30 -04:00
parent d27335bc59
commit 6201a817fb
3 changed files with 37 additions and 11 deletions

View File

@ -1947,9 +1947,10 @@ InterfaceHasInstance(JSContext* cx, int prototypeID, int depth,
}
bool
ReportLenientThisUnwrappingFailure(JSContext* cx, JS::Handle<JSObject*> obj)
ReportLenientThisUnwrappingFailure(JSContext* cx, JSObject* obj)
{
GlobalObject global(cx, obj);
JS::Rooted<JSObject*> rootedObj(cx, obj);
GlobalObject global(cx, rootedObj);
if (global.Failed()) {
return false;
}

View File

@ -2062,7 +2062,7 @@ InterfaceHasInstance(JSContext* cx, int prototypeID, int depth,
// Helper for lenient getters/setters to report to console. If this
// returns false, we couldn't even get a global.
bool
ReportLenientThisUnwrappingFailure(JSContext* cx, JS::Handle<JSObject*> obj);
ReportLenientThisUnwrappingFailure(JSContext* cx, JSObject* obj);
inline JSObject*
GetUnforgeableHolder(JSObject* aGlobal, prototypes::ID aId)

View File

@ -5321,9 +5321,18 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
|this| object. Subclasses are expected to override the generate_code
function to do the rest of the work. This function should return a
CGThing which is already properly indented.
getThisObj should be code for getting a JSObject* for the binding
object. If this is None, we will auto-generate code based on
descriptor to do the right thing. "" can be passed in if the
binding object is already stored in 'obj'.
callArgs should be code for getting a JS::CallArgs into a variable
called 'args'. This can be "" if there is already such a variable
around.
"""
def __init__(self, descriptor, name, args, unwrapFailureCode=None,
getThisObj="args.computeThis(cx).toObjectOrNull()",
getThisObj=None,
callArgs="JS::CallArgs args = JS::CallArgsFromVp(argc, vp);"):
CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
@ -5331,7 +5340,26 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
self.unwrapFailureCode = 'return ThrowErrorMessage(cx, MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "Value", "%s");' % descriptor.interface.identifier.name
else:
self.unwrapFailureCode = unwrapFailureCode
self.getThisObj = getThisObj
if getThisObj == "":
self.getThisObj = None
else:
if getThisObj is None:
if descriptor.interface.isOnGlobalProtoChain():
ensureCondition = "!args.thisv().isNullOrUndefined() && !args.thisv().isObject()"
getThisObj = "args.thisv().isObject() ? &args.thisv().toObject() : js::GetGlobalForObjectCrossCompartment(&args.callee())"
else:
ensureCondition = "!args.thisv().isObject()"
getThisObj = "&args.thisv().toObject()"
ensureThisObj = CGIfWrapper(CGGeneric(self.unwrapFailureCode),
ensureCondition)
else:
ensureThisObj = None
self.getThisObj = CGList(
[ensureThisObj,
CGGeneric("JS::RootedObject obj(cx, %s);\n" %
getThisObj)],
"\n")
self.callArgs = callArgs
def definition_body(self):
@ -5341,10 +5369,7 @@ class CGAbstractBindingMethod(CGAbstractStaticMethod):
# consumption by CastableObjectUnwrapper.
getThis = CGList([
CGGeneric(self.callArgs) if self.callArgs != "" else None,
CGGeneric("JS::RootedObject obj(cx, %s);\n"
"if (!obj) {\n"
" return false;\n"
"}" % self.getThisObj) if self.getThisObj else None,
self.getThisObj,
CGGeneric("%s* self;" % self.descriptor.nativeType)
], "\n")
unwrapThis = CGGeneric(
@ -5585,7 +5610,7 @@ class CGGenericGetter(CGAbstractBindingMethod):
name = "genericLenientGetter"
unwrapFailureCode = (
"MOZ_ASSERT(!JS_IsExceptionPending(cx));\n"
"if (!ReportLenientThisUnwrappingFailure(cx, obj)) {\n"
"if (!ReportLenientThisUnwrappingFailure(cx, &args.callee())) {\n"
" return false;\n"
"}\n"
"args.rval().set(JS::UndefinedValue());\n"
@ -5665,7 +5690,7 @@ class CGGenericSetter(CGAbstractBindingMethod):
name = "genericLenientSetter"
unwrapFailureCode = (
"MOZ_ASSERT(!JS_IsExceptionPending(cx));\n"
"if (!ReportLenientThisUnwrappingFailure(cx, obj)) {\n"
"if (!ReportLenientThisUnwrappingFailure(cx, &args.callee())) {\n"
" return false;\n"
"}\n"
"args.rval().set(JS::UndefinedValue());\n"