зеркало из https://github.com/mozilla/gecko-dev.git
Bug 801487 - Implement ErrorResult::ThrowTypeError. r=bz
This commit is contained in:
Родитель
0549bbbbdf
Коммит
5e13172aad
|
@ -4,6 +4,7 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include <algorithm>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "BindingUtils.h"
|
||||
|
@ -44,6 +45,58 @@ ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...)
|
|||
return false;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
|
||||
struct ErrorResult::Message {
|
||||
nsTArray<nsString> mArgs;
|
||||
dom::ErrNum mErrorNumber;
|
||||
};
|
||||
|
||||
void
|
||||
ErrorResult::ThrowTypeError(const dom::ErrNum errorNumber, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, errorNumber);
|
||||
if (IsTypeError()) {
|
||||
delete mMessage;
|
||||
}
|
||||
mResult = NS_ERROR_TYPE_ERR;
|
||||
Message* message = new Message();
|
||||
message->mErrorNumber = errorNumber;
|
||||
uint16_t argCount =
|
||||
dom::GetErrorMessage(nullptr, nullptr, errorNumber)->argCount;
|
||||
MOZ_ASSERT(argCount <= 10);
|
||||
argCount = std::min<uint16_t>(argCount, 10);
|
||||
while (argCount--) {
|
||||
message->mArgs.AppendElement(*va_arg(ap, nsString*));
|
||||
}
|
||||
mMessage = message;
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void
|
||||
ErrorResult::ReportTypeError(JSContext* aCx)
|
||||
{
|
||||
MOZ_ASSERT(mMessage, "ReportTypeError() can be called only once");
|
||||
|
||||
Message* message = mMessage;
|
||||
const uint32_t argCount = message->mArgs.Length();
|
||||
const jschar* args[11];
|
||||
for (uint32_t i = 0; i < argCount; ++i) {
|
||||
args[i] = message->mArgs.ElementAt(i).get();
|
||||
}
|
||||
args[argCount] = nullptr;
|
||||
|
||||
JS_ReportErrorNumberUCArray(aCx, dom::GetErrorMessage, nullptr,
|
||||
static_cast<const unsigned>(message->mErrorNumber),
|
||||
argCount > 0 ? args : nullptr);
|
||||
|
||||
delete message;
|
||||
mMessage = nullptr;
|
||||
}
|
||||
|
||||
namespace dom {
|
||||
|
||||
bool
|
||||
DefineConstants(JSContext* cx, JSObject* obj, ConstantSpec* cs)
|
||||
{
|
||||
|
|
|
@ -31,14 +31,6 @@ class nsGlobalWindow;
|
|||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
enum ErrNum {
|
||||
#define MSG_DEF(_name, _argc, _str) \
|
||||
_name,
|
||||
#include "mozilla/dom/Errors.msg"
|
||||
#undef MSG_DEF
|
||||
Err_Limit
|
||||
};
|
||||
|
||||
bool
|
||||
ThrowErrorMessage(JSContext* aCx, const ErrNum aErrorNumber, ...);
|
||||
|
||||
|
@ -61,10 +53,14 @@ Throw(JSContext* cx, nsresult rv)
|
|||
|
||||
template<bool mainThread>
|
||||
inline bool
|
||||
ThrowMethodFailedWithDetails(JSContext* cx, const ErrorResult& rv,
|
||||
ThrowMethodFailedWithDetails(JSContext* cx, ErrorResult& rv,
|
||||
const char* /* ifaceName */,
|
||||
const char* /* memberName */)
|
||||
{
|
||||
if (rv.IsTypeError()) {
|
||||
rv.ReportTypeError(cx);
|
||||
return false;
|
||||
}
|
||||
return Throw<mainThread>(cx, rv.ErrorCode());
|
||||
}
|
||||
|
||||
|
|
|
@ -353,14 +353,9 @@ DOMInterfaces = {
|
|||
},
|
||||
|
||||
'TextEncoder': {
|
||||
'headerFile': 'mozilla/dom/TextEncoder.h',
|
||||
'implicitJSContext': [ 'encode' ],
|
||||
},
|
||||
|
||||
'TextDecoder': {
|
||||
'headerFile': 'mozilla/dom/TextDecoder.h',
|
||||
},
|
||||
|
||||
'WebGLActiveInfo': {
|
||||
'nativeType': 'mozilla::WebGLActiveInfo',
|
||||
'headerFile': 'WebGLContext.h',
|
||||
|
|
|
@ -11,22 +11,48 @@
|
|||
#ifndef mozilla_ErrorResult_h
|
||||
#define mozilla_ErrorResult_h
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "nscore.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
namespace dom {
|
||||
|
||||
enum ErrNum {
|
||||
#define MSG_DEF(_name, _argc, _str) \
|
||||
_name,
|
||||
#include "mozilla/dom/Errors.msg"
|
||||
#undef MSG_DEF
|
||||
Err_Limit
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
||||
class ErrorResult {
|
||||
public:
|
||||
ErrorResult() {
|
||||
mResult = NS_OK;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
~ErrorResult() {
|
||||
MOZ_ASSERT_IF(IsTypeError(), !mMessage);
|
||||
}
|
||||
#endif
|
||||
|
||||
void Throw(nsresult rv) {
|
||||
MOZ_ASSERT(NS_FAILED(rv), "Please don't try throwing success");
|
||||
MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()");
|
||||
MOZ_ASSERT(!IsTypeError(), "Don't overwite TypeError");
|
||||
mResult = rv;
|
||||
}
|
||||
|
||||
void ThrowTypeError(const dom::ErrNum errorNumber, ...);
|
||||
void ReportTypeError(JSContext* cx);
|
||||
bool IsTypeError() const { return ErrorCode() == NS_ERROR_TYPE_ERR; }
|
||||
|
||||
// In the future, we can add overloads of Throw that take more
|
||||
// interesting things, like strings or DOM exception types or
|
||||
// something if desired.
|
||||
|
@ -35,6 +61,8 @@ public:
|
|||
// Throw() here because people can easily pass success codes to
|
||||
// this.
|
||||
void operator=(nsresult rv) {
|
||||
MOZ_ASSERT(rv != NS_ERROR_TYPE_ERR, "Use ThrowTypeError()");
|
||||
MOZ_ASSERT(!IsTypeError(), "Don't overwite TypeError");
|
||||
mResult = rv;
|
||||
}
|
||||
|
||||
|
@ -48,6 +76,9 @@ public:
|
|||
|
||||
private:
|
||||
nsresult mResult;
|
||||
struct Message;
|
||||
// Do not use nsAutoPtr to avoid extra initalizatoin and check.
|
||||
Message* mMessage;
|
||||
|
||||
// Not to be implemented, to make sure people always pass this by
|
||||
// reference, not by value.
|
||||
|
|
|
@ -32,3 +32,5 @@ MSG_DEF(MSG_ENFORCE_RANGE_OUT_OF_RANGE, 1, "Value is out of range for {0}.")
|
|||
MSG_DEF(MSG_NOT_SEQUENCE, 0, "object can not be converted to a sequence")
|
||||
MSG_DEF(MSG_INVALID_ARG, 2, "argument {0} is not valid for any of the {1}-argument overloads")
|
||||
MSG_DEF(MSG_GLOBAL_NOT_NATIVE, 0, "global is not a native object")
|
||||
MSG_DEF(MSG_ENCODING_NOT_SUPPORTED, 1, "The given encoding '{0}' is not supported.")
|
||||
MSG_DEF(MSG_DOM_ENCODING_NOT_UTF, 0, "The encoding must be utf-8, utf-16, or utf-16be.")
|
||||
|
|
Загрузка…
Ссылка в новой задаче