diff --git a/content/canvas/src/CanvasRenderingContext2D.cpp b/content/canvas/src/CanvasRenderingContext2D.cpp index 8419a0ed8e5..32d6970f4c4 100644 --- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -1254,7 +1254,7 @@ CanvasRenderingContext2D::GetMozCurrentTransformInverse(JSContext* cx, void CanvasRenderingContext2D::SetStyleFromJSValue(JSContext* cx, - JS::Value& value, + JS::Handle value, Style whichStyle) { if (value.isString()) { @@ -1269,9 +1269,10 @@ CanvasRenderingContext2D::SetStyleFromJSValue(JSContext* cx, nsCOMPtr holder; CanvasGradient* gradient; + JS::Rooted rootedVal(cx, value); nsresult rv = xpc_qsUnwrapArg(cx, value, &gradient, static_cast(getter_AddRefs(holder)), - &value); + rootedVal.address()); if (NS_SUCCEEDED(rv)) { SetStyleFromGradient(gradient, whichStyle); return; @@ -1280,7 +1281,7 @@ CanvasRenderingContext2D::SetStyleFromJSValue(JSContext* cx, CanvasPattern* pattern; rv = xpc_qsUnwrapArg(cx, value, &pattern, static_cast(getter_AddRefs(holder)), - &value); + rootedVal.address()); if (NS_SUCCEEDED(rv)) { SetStyleFromPattern(pattern, whichStyle); return; diff --git a/content/canvas/src/CanvasRenderingContext2D.h b/content/canvas/src/CanvasRenderingContext2D.h index 7ef8f4640aa..ad9f71cfa7e 100644 --- a/content/canvas/src/CanvasRenderingContext2D.h +++ b/content/canvas/src/CanvasRenderingContext2D.h @@ -92,14 +92,14 @@ public: mozilla::ErrorResult& error); JS::Value GetStrokeStyle(JSContext* cx, mozilla::ErrorResult& error); - void SetStrokeStyle(JSContext* cx, JS::Value& value) + void SetStrokeStyle(JSContext* cx, JS::Handle value) { SetStyleFromJSValue(cx, value, STYLE_STROKE); } JS::Value GetFillStyle(JSContext* cx, mozilla::ErrorResult& error); - void SetFillStyle(JSContext* cx, JS::Value& value) + void SetFillStyle(JSContext* cx, JS::Handle value) { SetStyleFromJSValue(cx, value, STYLE_FILL); } @@ -471,7 +471,8 @@ protected: static mozilla::gfx::DrawTarget* sErrorTarget; // Some helpers. Doesn't modify a color on failure. - void SetStyleFromJSValue(JSContext* cx, JS::Value& value, Style whichStyle); + void SetStyleFromJSValue(JSContext* cx, JS::Handle value, + Style whichStyle); void SetStyleFromString(const nsAString& str, Style whichStyle); void SetStyleFromGradient(CanvasGradient *gradient, Style whichStyle) diff --git a/content/events/src/nsDOMMessageEvent.h b/content/events/src/nsDOMMessageEvent.h index bbdcc6ee631..72c17bf663f 100644 --- a/content/events/src/nsDOMMessageEvent.h +++ b/content/events/src/nsDOMMessageEvent.h @@ -54,7 +54,7 @@ public: const nsAString& aType, bool aCanBubble, bool aCancelable, - JS::Value& aData, + JS::Value aData, const nsAString& aOrigin, const nsAString& aLastEventId, nsIDOMWindow* aSource, diff --git a/content/html/content/public/HTMLCanvasElement.h b/content/html/content/public/HTMLCanvasElement.h index 0a7ee639de3..fab95d8b100 100644 --- a/content/html/content/public/HTMLCanvasElement.h +++ b/content/html/content/public/HTMLCanvasElement.h @@ -92,7 +92,7 @@ public: } already_AddRefed GetContext(JSContext* aCx, const nsAString& aContextId, - const Optional& aContextOptions, ErrorResult& aRv) + const Optional& aContextOptions, ErrorResult& aRv) { JS::Value contextOptions = aContextOptions.WasPassed() ? aContextOptions.Value() @@ -102,7 +102,7 @@ public: return context.forget(); } void ToDataURL(JSContext* aCx, const nsAString& aType, - const Optional& aParams, nsAString& aDataURL, + const Optional& aParams, nsAString& aDataURL, ErrorResult& aRv) { JS::Value params = aParams.WasPassed() diff --git a/dom/bindings/BindingDeclarations.h b/dom/bindings/BindingDeclarations.h index af141cfd826..1ff48fe36ca 100644 --- a/dom/bindings/BindingDeclarations.h +++ b/dom/bindings/BindingDeclarations.h @@ -515,6 +515,34 @@ public: } }; +class LazyRootedValue : public Maybe > +{ +public: + operator JS::Value() const + { + // Assert if we're empty, on purpose + return ref(); + } + + operator JS::Rooted& () + { + // Assert if we're empty, on purpose + return ref(); + } + + operator JS::Handle() + { + // Assert if we're empty, on purpose + return ref(); + } + + JS::Value* operator&() + { + // Assert if we're empty, on purpose + return ref().address(); + } +}; + } // namespace dom } // namespace mozilla diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index c1c148fae1a..57f259f4db6 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -3222,20 +3222,19 @@ for (uint32_t i = 0; i < length; ++i) { if type.isAny(): assert not isEnforceRange and not isClamp - if isMember == "Dictionary": - declType = "RootedJSValue" - templateBody = ("if (!${declName}.SetValue(cx, ${val})) {\n" - " return false;\n" - "}") - nullHandling = "${declName}.SetValue(nullptr, JS::NullValue())" - elif isMember and isMember != "Variadic": - # Variadic arguments are rooted by being in argv + if isMember == "Dictionary" or not isMember: + declType = "LazyRootedValue" + templateBody = "${declName}.construct(cx, ${val});" + nullHandling = "${declName}.construct(cx, JS::NullValue());" + elif isMember != "Variadic": raise TypeError("Can't handle sequence member 'any'; need to sort " "out rooting issues") else: + # Variadic arguments are rooted by being in argv declType = "JS::Value" templateBody = "${declName} = ${val};" nullHandling = "${declName} = JS::NullValue()" + templateBody = handleDefaultNull(templateBody, nullHandling) return (templateBody, CGGeneric(declType), None, isOptional) @@ -8115,7 +8114,7 @@ class CGNativeMember(ClassMethod): args.insert(0, Argument("const %s&" % globalObjectType, "global")) return args - def doGetArgType(self, type, optional, isMember): + def doGetArgType(self, type, optional, variadic, isMember): """ The main work of getArgType. Returns a string type decl, whether this is a const ref, as well as whether the type should be wrapped in @@ -8204,7 +8203,12 @@ class CGNativeMember(ClassMethod): return declType % name, False, False if type.isAny(): - return "JS::Value", False, False + # Don't do the rooting stuff for variadics for now + if optional and not variadic: + declType = "LazyRootedValue" + else: + declType = "JS::Value" + return declType, False, False if type.isObject(): if optional: @@ -8235,7 +8239,7 @@ class CGNativeMember(ClassMethod): Get the type of an argument declaration. Returns the type CGThing, and whether this should be a const ref. """ - (decl, ref, handleNullable) = self.doGetArgType(type, optional, + (decl, ref, handleNullable) = self.doGetArgType(type, optional, variadic, isMember or variadic) decl = CGGeneric(decl) if handleNullable and type.nullable(): diff --git a/dom/bindings/test/TestBindingHeader.h b/dom/bindings/test/TestBindingHeader.h index 22719574655..97d2f5d7a8e 100644 --- a/dom/bindings/test/TestBindingHeader.h +++ b/dom/bindings/test/TestBindingHeader.h @@ -140,7 +140,7 @@ public: JSObject&, JSObject*, const Sequence&, - const Optional&, + const Optional&, const Optional&, const Optional&, ErrorResult&); @@ -429,7 +429,7 @@ public: // Any types void PassAny(JSContext*, JS::Value); - void PassOptionalAny(JSContext*, const Optional&); + void PassOptionalAny(JSContext*, const Optional&); void PassAnyDefaultNull(JSContext*, JS::Value); JS::Value ReceiveAny(JSContext*);