diff --git a/content/canvas/src/CanvasRenderingContext2D.cpp b/content/canvas/src/CanvasRenderingContext2D.cpp index f6cf06b0a29..e6b64ebe2f4 100644 --- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -1199,10 +1199,9 @@ ObjectToMatrix(JSContext* cx, JS::Handle obj, Matrix& matrix, void CanvasRenderingContext2D::SetMozCurrentTransform(JSContext* cx, - JSObject& currentTransform_, + JS::Handle currentTransform, ErrorResult& error) { - JS::Rooted currentTransform(cx, ¤tTransform_); EnsureTarget(); if (!IsTargetValid()) { error.Throw(NS_ERROR_FAILURE); @@ -1224,10 +1223,9 @@ CanvasRenderingContext2D::GetMozCurrentTransform(JSContext* cx, void CanvasRenderingContext2D::SetMozCurrentTransformInverse(JSContext* cx, - JSObject& currentTransform_, + JS::Handle currentTransform, ErrorResult& error) { - JS::Rooted currentTransform(cx, ¤tTransform_); EnsureTarget(); if (!IsTargetValid()) { error.Throw(NS_ERROR_FAILURE); diff --git a/content/canvas/src/CanvasRenderingContext2D.h b/content/canvas/src/CanvasRenderingContext2D.h index 86b306e9ada..1a352288803 100644 --- a/content/canvas/src/CanvasRenderingContext2D.h +++ b/content/canvas/src/CanvasRenderingContext2D.h @@ -307,11 +307,13 @@ public: JSObject* GetMozCurrentTransform(JSContext* cx, mozilla::ErrorResult& error) const; - void SetMozCurrentTransform(JSContext* cx, JSObject& currentTransform, + void SetMozCurrentTransform(JSContext* cx, + JS::Handle currentTransform, mozilla::ErrorResult& error); JSObject* GetMozCurrentTransformInverse(JSContext* cx, mozilla::ErrorResult& error) const; - void SetMozCurrentTransformInverse(JSContext* cx, JSObject& currentTransform, + void SetMozCurrentTransformInverse(JSContext* cx, + JS::Handle currentTransform, mozilla::ErrorResult& error); void GetFillRule(nsAString& fillRule); void SetFillRule(const nsAString& fillRule); @@ -472,7 +474,7 @@ protected: // Some helpers. Doesn't modify a color on failure. void SetStyleFromJSValue(JSContext* cx, JS::Handle value, - Style whichStyle); + Style whichStyle); void SetStyleFromString(const nsAString& str, Style whichStyle); void SetStyleFromGradient(CanvasGradient *gradient, Style whichStyle) diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 0342c873cf4..c3ceebfd8b6 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -1564,6 +1564,12 @@ public: new (storage.addr()) T(); return *storage.addr(); } + template + T& SetValue(const T1 &t1, const T2 &t2) + { + new (storage.addr()) T(t1, t2); + return *storage.addr(); + } const T& Value() const { return *storage.addr(); } diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index 04bfc09a269..d22a77fd83f 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -2616,9 +2616,18 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None, return templateBody - # A helper function for converting things that look like JSObject* - # when nullable and JSObject& when not nullable. + # A helper function for converting things that look like a JSObject*. def handleJSObjectType(type, isMember, failureCode): + if not isMember: + declType = CGGeneric("JS::Rooted") + templateBody = "${declName} = &${valHandle}.toObject();" + setToNullCode = "${declName} = nullptr;" + template = wrapObjectTemplate(templateBody, type, setToNullCode, + failureCode) + return JSToNativeConversionInfo(template, declType=declType, + dealWithOptional=isOptional, + declArgs="cx") + if type.nullable(): declType = CGGeneric("LazyRootedObject") else: @@ -4200,9 +4209,6 @@ class CGCallGenerator(CGThing): args = CGList([CGGeneric(arg) for arg in argsPre], ", ") for (a, name) in arguments: - # This is a workaround for a bug in Apple's clang. - if a.type.isObject() and not a.type.nullable() and not a.optional: - name = "(JSObject&)" + name arg = CGGeneric(name) # Now constify the things that need it def needsConst(a): @@ -4210,7 +4216,12 @@ class CGCallGenerator(CGThing): return True if a.type.isSequence(): return True - if a.type.nullable(): + # isObject() types are always a JS::Rooted, whether + # nullable or not, and it turns out a const JS::Rooted + # is not very helpful at all (in particular, it won't + # even convert to a JS::Handle). + # XXX bz Well, why not??? + if a.type.nullable() and not a.type.isObject(): return True if a.type.isString(): return True @@ -4284,7 +4295,9 @@ def wrapTypeIntoCurrentCompartment(type, value, isMember=True): "}" % value) if type.isObject(): - if not type.nullable(): + if not isMember: + value = value + ".address()" + elif not type.nullable(): value = "%s.Slot()" % value else: value = "&%s" % value @@ -5592,12 +5605,7 @@ def getUnionAccessorSignatureType(type, descriptorProvider): return CGGeneric("JS::Value") if type.isObject(): - typeName = CGGeneric("JSObject") - if type.nullable(): - typeName = CGWrapper(typeName, post="*") - else: - typeName = CGWrapper(typeName, post="&") - return typeName + return CGGeneric("JSObject*") if not type.isPrimitive(): raise TypeError("Need native type for argument type '%s'" % str(type)) @@ -5644,7 +5652,7 @@ return true;""" if type.isObject(): setter = CGGeneric("void SetToObject(JSContext* cx, JSObject* obj)\n" "{\n" - " mUnion.mValue.mObject.SetValue().construct(cx, obj);\n" + " mUnion.mValue.mObject.SetValue(cx, obj);\n" " mUnion.mType = mUnion.eObject;\n" "}") else: @@ -5723,13 +5731,17 @@ class CGUnionStruct(CGThing): { MOZ_ASSERT(Is${name}(), "Wrong type!"); return const_cast<${structType}&>(mValue.m${name}.Value()); - } - ${structType}& SetAs${name}() + }""" + methods.extend(mapTemplate(methodTemplate, templateVars)) + # Now have to be careful: we do not want the SetAsObject() method! + setterTemplate = """ ${structType}& SetAs${name}() { mType = e${name}; return mValue.m${name}.SetValue(); }""" - methods.extend(mapTemplate(methodTemplate, templateVars)) + methods.extend(mapTemplate(setterTemplate, + filter(lambda v: v["name"] != "Object", + templateVars))) values = mapTemplate("UnionMember<${structType} > m${name};", templateVars) return string.Template(""" class ${structName} { @@ -5812,12 +5824,7 @@ ${doConversionsToJS} (templateVars, type) = arg assert not type.nullable() # flatMemberTypes never has nullable types val = "mValue.m%(name)s.Value()" % templateVars - if type.isObject(): - # We'll have a NonNullLazyRootedObject while the wrapping code wants - # a JSObject*. But our .ref() is a JS::Rooted, which can - # convert to a JSObject*. - val = "%s.ref()" % val - elif type.isSpiderMonkeyInterface(): + if type.isSpiderMonkeyInterface(): # We have a NonNull object while the wrapping code # wants a JSObject*. Cheat with .get() so we don't have to # figure out the right reference type to cast to. @@ -5859,11 +5866,14 @@ class CGUnionConversionStruct(CGThing): structName = self.type.__str__() setters.extend(mapTemplate("${setter}", templateVars)) + # Don't generate a SetAsObject, since we don't use it private = "\n".join(mapTemplate(""" ${structType}& SetAs${name}() { mUnion.mType = mUnion.e${name}; return mUnion.mValue.m${name}.SetValue(); - }""", templateVars)) + }""", + filter(lambda v: v["name"] != "Object", + templateVars))) private += "\n\n" holders = filter(lambda v: v["holderType"] is not None, templateVars) if len(holders) > 0: @@ -8236,11 +8246,7 @@ class CGNativeMember(ClassMethod): if type.isAny(): return "JS::Value", "JS::UndefinedValue()", "return ${declName};" if type.isObject(): - if type.nullable(): - returnCode = "return ${declName};" - else: - returnCode = "return ${declName}.ref();" - return "JSObject*", "nullptr", returnCode + return "JSObject*", "nullptr", "return ${declName};" if type.isSpiderMonkeyInterface(): if type.nullable(): returnCode = "return ${declName} ? ${declName}->Obj() : nullptr;" @@ -8408,15 +8414,12 @@ class CGNativeMember(ClassMethod): return declType, False, False if type.isObject(): - if optional: - if type.nullable(): - declType = "LazyRootedObject" - else: - declType = "NonNullLazyRootedObject" - elif type.nullable() or self.jsObjectsArePtr: + if isMember: declType = "JSObject*" + elif optional: + declType = "JS::Rooted" else: - declType = "JSObject&" + declType = "JS::Handle" return declType, False, False if type.isDictionary(): diff --git a/dom/bindings/test/TestBindingHeader.h b/dom/bindings/test/TestBindingHeader.h index fb515f6e5b0..0bc23de0997 100644 --- a/dom/bindings/test/TestBindingHeader.h +++ b/dom/bindings/test/TestBindingHeader.h @@ -137,12 +137,12 @@ public: JSContext*, const DictForConstructor&, JS::Value, - JSObject&, - JSObject*, + JS::Handle, + JS::Handle, const Sequence&, const Optional >&, - const Optional&, - const Optional&, + const Optional >&, + const Optional >&, ErrorResult&); // Integer types @@ -434,23 +434,23 @@ public: JS::Value ReceiveAny(JSContext*); // object types - void PassObject(JSContext*, JSObject&); - void PassNullableObject(JSContext*, JSObject*); - void PassOptionalObject(JSContext*, const Optional&); - void PassOptionalNullableObject(JSContext*, const Optional&); - void PassOptionalNullableObjectWithDefaultValue(JSContext*, JSObject*); + void PassObject(JSContext*, JS::Handle); + void PassNullableObject(JSContext*, JS::Handle); + void PassOptionalObject(JSContext*, const Optional >&); + void PassOptionalNullableObject(JSContext*, const Optional >&); + void PassOptionalNullableObjectWithDefaultValue(JSContext*, JS::Handle); JSObject* ReceiveObject(JSContext*); JSObject* ReceiveNullableObject(JSContext*); // Union types void PassUnion(JSContext*, const ObjectOrLong& arg); - void PassUnionWithNullable(JSContext*, const ObjectOrNullOrLong& arg) + void PassUnionWithNullable(JSContext* cx, const ObjectOrNullOrLong& arg) { ObjectOrLong returnValue; if (arg.IsNull()) { } else if (arg.IsObject()) { - JSObject& obj = (JSObject&)arg.GetAsObject(); - JS_GetClass(&obj); + JS::Rooted obj(cx, arg.GetAsObject()); + JS_GetClass(obj); //returnValue.SetAsObject(&obj); } else { int32_t i = arg.GetAsLong(); @@ -698,8 +698,8 @@ private: void PassOptionalArrayBuffer(Optional&) MOZ_DELETE; void PassOptionalNullableArrayBuffer(Optional&) MOZ_DELETE; void PassOptionalEnum(Optional&) MOZ_DELETE; - void PassOptionalCallback(JSContext*, Optional&) MOZ_DELETE; - void PassOptionalNullableCallback(JSContext*, Optional&) MOZ_DELETE; + void PassOptionalCallback(JSContext*, Optional >&) MOZ_DELETE; + void PassOptionalNullableCallback(JSContext*, Optional >&) MOZ_DELETE; void PassOptionalAny(Optional >&) MOZ_DELETE; // And test that string stuff is always const diff --git a/dom/bindings/test/TestJSImplGen.webidl b/dom/bindings/test/TestJSImplGen.webidl index 44ad854d298..51927b263e1 100644 --- a/dom/bindings/test/TestJSImplGen.webidl +++ b/dom/bindings/test/TestJSImplGen.webidl @@ -22,9 +22,9 @@ enum MyTestEnum { [Constructor(DOMString str, unsigned long num, boolean? boolArg, TestInterface? iface, long arg1, DictForConstructor dict, any any1, - /* (BUG 856911) object obj1,*/ + object obj1, object? obj2, sequence seq, optional any any2, - /* (BUG 856911) optional object obj3, */ + optional object obj3, optional object? obj4), JSImplementation="@mozilla.org/test-js-impl-interface;1"] interface TestJSImplInterface { @@ -322,12 +322,9 @@ interface TestJSImplInterface { void passAnyDefaultNull(optional any arg = null); any receiveAny(); - // object types. Unfortunately, non-nullable object is inconsistently - // represented as either JSObject* (for callbacks) or JSObject& (for - // non-callbacks), so we can't handle those yet. See bug 856911. - //(BUG 856911) void passObject(object arg); + void passObject(object arg); void passNullableObject(object? arg); - //(BUG 856911) void passOptionalObject(optional object arg); + void passOptionalObject(optional object arg); void passOptionalNullableObject(optional object? arg); void passOptionalNullableObjectWithDefaultValue(optional object? arg = null); object receiveObject(); diff --git a/dom/workers/EventTarget.h b/dom/workers/EventTarget.h index 077cb94e521..7ce2ff5778e 100644 --- a/dom/workers/EventTarget.h +++ b/dom/workers/EventTarget.h @@ -46,9 +46,9 @@ public: bool aCapture, ErrorResult& aRv); bool - DispatchEvent(JSObject& aEvent, ErrorResult& aRv) const + DispatchEvent(JS::Handle aEvent, ErrorResult& aRv) const { - return mListenerManager.DispatchEvent(GetJSContext(), *this, &aEvent, aRv); + return mListenerManager.DispatchEvent(GetJSContext(), *this, aEvent, aRv); } JSObject* diff --git a/dom/workers/FileReaderSync.cpp b/dom/workers/FileReaderSync.cpp index 606d7e67062..2de28de4179 100644 --- a/dom/workers/FileReaderSync.cpp +++ b/dom/workers/FileReaderSync.cpp @@ -71,10 +71,10 @@ FileReaderSync::Constructor(const WorkerGlobalObject& aGlobal, ErrorResult& aRv) } JSObject* -FileReaderSync::ReadAsArrayBuffer(JSContext* aCx, JSObject& aBlob, +FileReaderSync::ReadAsArrayBuffer(JSContext* aCx, JS::Handle aBlob, ErrorResult& aRv) { - nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(&aBlob); + nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(aBlob); if (!blob) { aRv.Throw(NS_ERROR_INVALID_ARG); return nullptr; @@ -117,10 +117,11 @@ FileReaderSync::ReadAsArrayBuffer(JSContext* aCx, JSObject& aBlob, } void -FileReaderSync::ReadAsBinaryString(JSObject& aBlob, nsAString& aResult, +FileReaderSync::ReadAsBinaryString(JS::Handle aBlob, + nsAString& aResult, ErrorResult& aRv) { - nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(&aBlob); + nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(aBlob); if (!blob) { aRv.Throw(NS_ERROR_INVALID_ARG); return; @@ -152,12 +153,12 @@ FileReaderSync::ReadAsBinaryString(JSObject& aBlob, nsAString& aResult, } void -FileReaderSync::ReadAsText(JSObject& aBlob, +FileReaderSync::ReadAsText(JS::Handle aBlob, const Optional& aEncoding, nsAString& aResult, ErrorResult& aRv) { - nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(&aBlob); + nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(aBlob); if (!blob) { aRv.Throw(NS_ERROR_INVALID_ARG); return; @@ -208,10 +209,10 @@ FileReaderSync::ReadAsText(JSObject& aBlob, } void -FileReaderSync::ReadAsDataURL(JSObject& aBlob, nsAString& aResult, +FileReaderSync::ReadAsDataURL(JS::Handle aBlob, nsAString& aResult, ErrorResult& aRv) { - nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(&aBlob); + nsIDOMBlob* blob = file::GetDOMBlobFromJSObject(aBlob); if (!blob) { aRv.Throw(NS_ERROR_INVALID_ARG); return; diff --git a/dom/workers/FileReaderSync.h b/dom/workers/FileReaderSync.h index d5263cf35f8..a07e0b2fc60 100644 --- a/dom/workers/FileReaderSync.h +++ b/dom/workers/FileReaderSync.h @@ -42,13 +42,15 @@ public: FileReaderSync(JSContext* aCx); - JSObject* ReadAsArrayBuffer(JSContext* aCx, JSObject& aBlob, + JSObject* ReadAsArrayBuffer(JSContext* aCx, JS::Handle aBlob, ErrorResult& aRv); - void ReadAsBinaryString(JSObject& aBlob, nsAString& aResult, + void ReadAsBinaryString(JS::Handle aBlob, nsAString& aResult, ErrorResult& aRv); - void ReadAsText(JSObject& aBlob, const Optional& aEncoding, + void ReadAsText(JS::Handle aBlob, + const Optional& aEncoding, nsAString& aResult, ErrorResult& aRv); - void ReadAsDataURL(JSObject& aBlob, nsAString& aResult, ErrorResult& aRv); + void ReadAsDataURL(JS::Handle aBlob, nsAString& aResult, + ErrorResult& aRv); // From nsICharsetDetectionObserver NS_IMETHOD Notify(const char *aCharset, nsDetectionConfident aConf); diff --git a/dom/workers/XMLHttpRequest.h b/dom/workers/XMLHttpRequest.h index a3a1b16f13c..6fdc3dd3421 100644 --- a/dom/workers/XMLHttpRequest.h +++ b/dom/workers/XMLHttpRequest.h @@ -241,7 +241,7 @@ public: } JS::Value - GetInterface(JSContext* cx, JSObject& aIID, ErrorResult& aRv) + GetInterface(JSContext* cx, JS::Handle aIID, ErrorResult& aRv) { aRv.Throw(NS_ERROR_FAILURE); return JSVAL_NULL;