diff --git a/dom/bindings/BindingUtils.cpp b/dom/bindings/BindingUtils.cpp index d2b16cf403e6..d6e5db56676d 100644 --- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -60,47 +60,26 @@ ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...) } bool -ThrowInvalidMethodThis(JSContext* aCx, const JS::CallArgs& aArgs, - const char* aInterfaceName) +ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs, + const ErrNum aErrorNumber, + const char* aInterfaceName) { NS_ConvertASCIItoUTF16 ifaceName(aInterfaceName); - // This should only be called for DOM methods, which are JSNative-backed - // functions, so we can assume that JS_ValueToFunction and - // JS_GetFunctionDisplayId will both return non-null and that - // JS_GetStringCharsZ returns non-null. + // This should only be called for DOM methods/getters/setters, which + // are JSNative-backed functions, so we can assume that + // JS_ValueToFunction and JS_GetFunctionDisplayId will both return + // non-null and that JS_GetStringCharsZ returns non-null. JS::Rooted func(aCx, JS_ValueToFunction(aCx, aArgs.calleev())); MOZ_ASSERT(func); JS::Rooted funcName(aCx, JS_GetFunctionDisplayId(func)); MOZ_ASSERT(funcName); JS_ReportErrorNumberUC(aCx, GetErrorMessage, nullptr, - static_cast(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE), + static_cast(aErrorNumber), JS_GetStringCharsZ(aCx, funcName), ifaceName.get()); return false; } -bool -ThrowInvalidGetterThis(JSContext* aCx, const char* aInterfaceName) -{ - // Sadly for getters we have no way to get the name of the property. - NS_ConvertASCIItoUTF16 ifaceName(aInterfaceName); - JS_ReportErrorNumberUC(aCx, GetErrorMessage, nullptr, - static_cast(MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE), - ifaceName.get()); - return false; -} - -bool -ThrowInvalidSetterThis(JSContext* aCx, const char* aInterfaceName) -{ - // Sadly for setters we have no way to get the name of the property. - NS_ConvertASCIItoUTF16 ifaceName(aInterfaceName); - JS_ReportErrorNumberUC(aCx, GetErrorMessage, nullptr, - static_cast(MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE), - ifaceName.get()); - return false; -} - } // namespace dom struct ErrorResult::Message { @@ -850,8 +829,8 @@ XrayResolveAttribute(JSContext* cx, JS::Handle wrapper, // They all have getters, so we can just make it. JS::Rooted global(cx, JS_GetGlobalForObject(cx, wrapper)); JS::Rooted fun(cx, - JS_NewFunction(cx, (JSNative)attrSpec.getter.op, - 0, 0, global, nullptr)); + JS_NewFunctionById(cx, (JSNative)attrSpec.getter.op, + 0, 0, global, id)); if (!fun) return false; SET_JITINFO(fun, attrSpec.getter.info); @@ -860,8 +839,8 @@ XrayResolveAttribute(JSContext* cx, JS::Handle wrapper, desc->attrs |= JSPROP_GETTER; if (attrSpec.setter.op) { // We have a setter! Make it. - fun = JS_NewFunction(cx, (JSNative)attrSpec.setter.op, 1, 0, - global, nullptr); + fun = JS_NewFunctionById(cx, (JSNative)attrSpec.setter.op, 1, 0, + global, id); if (!fun) return false; SET_JITINFO(fun, attrSpec.setter.info); diff --git a/dom/bindings/BindingUtils.h b/dom/bindings/BindingUtils.h index 0042c1e97c7d..558fd89421a6 100644 --- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -60,12 +60,9 @@ UnwrapArg(JSContext* cx, jsval v, Interface** ppArg, bool ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...); bool -ThrowInvalidMethodThis(JSContext* aCx, const JS::CallArgs& aArgs, - const char* aInterfaceName); -bool -ThrowInvalidGetterThis(JSContext* aCx, const char* aInterfaceName); -bool -ThrowInvalidSetterThis(JSContext* aCx, const char* aInterfaceName); +ThrowInvalidThis(JSContext* aCx, const JS::CallArgs& aArgs, + const ErrNum aErrorNumber, + const char* aInterfaceName); template inline bool diff --git a/dom/bindings/Codegen.py b/dom/bindings/Codegen.py index c144b0bf6852..f0e25fd11346 100644 --- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -5185,7 +5185,7 @@ class CGGenericMethod(CGAbstractBindingMethod): args = [Argument('JSContext*', 'cx'), Argument('unsigned', 'argc'), Argument('JS::Value*', 'vp')] unwrapFailureCode = ( - 'return ThrowInvalidMethodThis(cx, args, \"%s\");' % + 'return ThrowInvalidThis(cx, args, MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, \"%s\");' % descriptor.interface.identifier.name) CGAbstractBindingMethod.__init__(self, descriptor, 'genericMethod', args, @@ -5322,7 +5322,7 @@ class CGGenericGetter(CGAbstractBindingMethod): else: name = "genericGetter" unwrapFailureCode = ( - 'return ThrowInvalidGetterThis(cx, "%s");' % + 'return ThrowInvalidThis(cx, args, MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "%s");' % descriptor.interface.identifier.name) CGAbstractBindingMethod.__init__(self, descriptor, name, args, unwrapFailureCode) @@ -5402,7 +5402,7 @@ class CGGenericSetter(CGAbstractBindingMethod): else: name = "genericSetter" unwrapFailureCode = ( - 'return ThrowInvalidSetterThis(cx, "%s");' % + 'return ThrowInvalidThis(cx, args, MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, "%s");' % descriptor.interface.identifier.name) CGAbstractBindingMethod.__init__(self, descriptor, name, args, diff --git a/dom/bindings/Errors.msg b/dom/bindings/Errors.msg index a705918f4f7e..68fb8762d767 100644 --- a/dom/bindings/Errors.msg +++ b/dom/bindings/Errors.msg @@ -24,9 +24,9 @@ MSG_DEF(MSG_MISSING_ARGUMENTS, 1, "Not enough arguments to {0}.") MSG_DEF(MSG_NOT_OBJECT, 1, "{0} is not an object.") MSG_DEF(MSG_NOT_CALLABLE, 1, "{0} is not callable.") MSG_DEF(MSG_DOES_NOT_IMPLEMENT_INTERFACE, 2, "{0} does not implement interface {1}.") -MSG_DEF(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "{0} called on an object that does not implement interface {1}.") -MSG_DEF(MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, "getter called on an object that does not implement interface {0}.") -MSG_DEF(MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, "setter called on an object that does not implement interface {0}.") +MSG_DEF(MSG_METHOD_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' called on an object that does not implement interface {1}.") +MSG_DEF(MSG_GETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' getter called on an object that does not implement interface {1}.") +MSG_DEF(MSG_SETTER_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 2, "'{0}' setter called on an object that does not implement interface {1}.") MSG_DEF(MSG_THIS_DOES_NOT_IMPLEMENT_INTERFACE, 1, "\"this\" object does not implement interface {0}.") MSG_DEF(MSG_NOT_IN_UNION, 2, "{0} could not be converted to any of: {1}.") MSG_DEF(MSG_ILLEGAL_CONSTRUCTOR, 0, "Illegal constructor.") diff --git a/dom/bindings/test/Makefile.in b/dom/bindings/test/Makefile.in index d28a87683401..2aacb59de809 100644 --- a/dom/bindings/test/Makefile.in +++ b/dom/bindings/test/Makefile.in @@ -75,6 +75,7 @@ MOCHITEST_FILES := \ test_bug560072.html \ test_lenientThis.html \ test_ByteString.html \ + test_exception_messages.html \ $(NULL) MOCHITEST_CHROME_FILES = \ diff --git a/dom/bindings/test/test_exception_messages.html b/dom/bindings/test/test_exception_messages.html new file mode 100644 index 000000000000..356cff93f631 --- /dev/null +++ b/dom/bindings/test/test_exception_messages.html @@ -0,0 +1,82 @@ + + + + + + Test for Bug 882653 + + + + + +Mozilla Bug 882653 +

+ +
+
+ +