diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index 5ee0a608772..49aefd24d4b 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -1947,9 +1947,10 @@ InterfaceHasInstance(JSContext* cx, int prototypeID, int depth, } bool -ReportLenientThisUnwrappingFailure(JSContext* cx, JS::Handle obj) +ReportLenientThisUnwrappingFailure(JSContext* cx, JSObject* obj) { - GlobalObject global(cx, obj); + JS::Rooted rootedObj(cx, obj); + GlobalObject global(cx, rootedObj); if (global.Failed()) { return false; } diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index f07565c29f5..c383e156f5a 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -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 obj); +ReportLenientThisUnwrappingFailure(JSContext* cx, JSObject* obj); inline JSObject* GetUnforgeableHolder(JSObject* aGlobal, prototypes::ID aId) diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 341d7eca50c..ff653942ebf 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -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"