From cadf96da9049330f4701147f042ebc7038cd6dbf Mon Sep 17 00:00:00 2001 From: yangguo Date: Fri, 24 Apr 2015 03:22:00 -0700 Subject: [PATCH] Migrate error messages, part 5 (array.js and i18n.js). R=mvstanton@chromium.org Review URL: https://codereview.chromium.org/1096243003 Cr-Commit-Position: refs/heads/master@{#28040} --- src/array.js | 15 +++---- src/date.js | 5 --- src/harmony-array.js | 3 +- src/i18n.js | 104 ++++++++++++++++++++--------------------------- src/macros.py | 4 +- src/messages.h | 36 +++++++++++++++- src/messages.js | 11 ++--- src/string.js | 3 +- src/uri.js | 62 ++++++++++------------------ src/v8natives.js | 4 +- test/mjsunit/messages.js | 55 ++++++++++++++++++++++++- tools/js2c.py | 5 ++- 12 files changed, 174 insertions(+), 133 deletions(-) diff --git a/src/array.js b/src/array.js index e9cd9c0..e0a1fc9 100644 --- a/src/array.js +++ b/src/array.js @@ -620,10 +620,7 @@ function ArrayShift() { return; } - if (ObjectIsSealed(array)) { - throw MakeTypeError("array_functions_change_sealed", - ["Array.prototype.shift"]); - } + if (ObjectIsSealed(array)) throw MakeTypeError(kArrayFunctionsOnSealed); if (%IsObserved(array)) return ObservedArrayShift.call(array, len); @@ -821,11 +818,9 @@ function ArraySplice(start, delete_count) { var num_elements_to_add = num_arguments > 2 ? num_arguments - 2 : 0; if (del_count != num_elements_to_add && ObjectIsSealed(array)) { - throw MakeTypeError("array_functions_change_sealed", - ["Array.prototype.splice"]); + throw MakeTypeError(kArrayFunctionsOnSealed); } else if (del_count > 0 && ObjectIsFrozen(array)) { - throw MakeTypeError("array_functions_on_frozen", - ["Array.prototype.splice"]); + throw MakeTypeError(kArrayFunctionsOnFrozen); } var changed_elements = del_count; @@ -1446,7 +1441,7 @@ function ArrayReduce(callback, current) { break find_initial; } } - throw MakeTypeError('reduce_no_initial', []); + throw MakeTypeError(kReduceNoInitial); } var receiver = %GetDefaultReceiver(callback); @@ -1484,7 +1479,7 @@ function ArrayReduceRight(callback, current) { break find_initial; } } - throw MakeTypeError('reduce_no_initial', []); + throw MakeTypeError(kReduceNoInitial); } var receiver = %GetDefaultReceiver(callback); diff --git a/src/date.js b/src/date.js index 877fc73..11cf4e9 100644 --- a/src/date.js +++ b/src/date.js @@ -20,11 +20,6 @@ var GlobalDate = global.Date; // This file contains date support implemented in JavaScript. -// Helper function to throw error. -function ThrowDateTypeError() { - throw new $TypeError('this is not a Date object.'); -} - var timezone_cache_time = NAN; var timezone_cache_timezone; diff --git a/src/harmony-array.js b/src/harmony-array.js index 934d3b7..b24caff 100644 --- a/src/harmony-array.js +++ b/src/harmony-array.js @@ -174,8 +174,7 @@ function ArrayFill(value /* [, start [, end ] ] */) { // length == 1 } if ((end - i) > 0 && ObjectIsFrozen(array)) { - throw MakeTypeError("array_functions_on_frozen", - ["Array.prototype.fill"]); + throw MakeTypeError(kArrayFunctionsOnFrozen); } for (; i < end; i++) diff --git a/src/i18n.js b/src/i18n.js index e5dc8d2..302a929 100644 --- a/src/i18n.js +++ b/src/i18n.js @@ -219,8 +219,7 @@ var ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR = function addBoundMethod(obj, methodName, implementation, length) { function getter() { if (!%IsInitializedIntlObject(this)) { - throw new $TypeError('Method ' + methodName + ' called on a ' + - 'non-object or on a wrong type of object.'); + throw MakeTypeError(kMethodCalledOnWrongObject, methodName); } var internalName = '__bound' + methodName + '__'; if (this[internalName] === undefined) { @@ -229,21 +228,21 @@ function addBoundMethod(obj, methodName, implementation, length) { if (length === undefined || length === 2) { boundMethod = function(x, y) { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } return implementation(that, x, y); } } else if (length === 1) { boundMethod = function(x) { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } return implementation(that, x); } } else { boundMethod = function() { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } // DateTimeFormat.format needs to be 0 arg method, but can stil // receive optional dateValue param. If one was provided, pass it @@ -281,7 +280,7 @@ function addBoundMethod(obj, methodName, implementation, length) { */ function supportedLocalesOf(service, locales, options) { if (IS_NULL(service.match(GetServiceRE()))) { - throw new $Error('Internal error, wrong service type: ' + service); + throw MakeError(kWrongServiceType, service); } // Provide defaults if matcher was not specified. @@ -295,7 +294,7 @@ function supportedLocalesOf(service, locales, options) { if (matcher !== undefined) { matcher = GlobalString(matcher); if (matcher !== 'lookup' && matcher !== 'best fit') { - throw new $RangeError('Illegal value for localeMatcher:' + matcher); + throw MakeRangeError(kLocaleMatcher, matcher); } } else { matcher = 'best fit'; @@ -366,10 +365,7 @@ function bestFitSupportedLocalesOf(requestedLocales, availableLocales) { * is out of range for that property it throws RangeError. */ function getGetOption(options, caller) { - if (options === undefined) { - throw new $Error('Internal ' + caller + ' error. ' + - 'Default options are missing.'); - } + if (options === undefined) throw MakeError(kDefaultOptionsMissing, caller); var getOption = function getOption(property, type, values, defaultValue) { if (options[property] !== undefined) { @@ -385,11 +381,10 @@ function getGetOption(options, caller) { value = GlobalNumber(value); break; default: - throw new $Error('Internal error. Wrong value type.'); + throw MakeError(kWrongValueType); } if (values !== undefined && values.indexOf(value) === -1) { - throw new $RangeError('Value ' + value + ' out of range for ' + caller + - ' options property ' + property); + throw MakeRangeError(kValueOutOfRange, value, caller, property); } return value; @@ -438,7 +433,7 @@ function resolveLocale(service, requestedLocales, options) { */ function lookupMatcher(service, requestedLocales) { if (IS_NULL(service.match(GetServiceRE()))) { - throw new $Error('Internal error, wrong service type: ' + service); + throw MakeError(kWrongServiceType, service); } // Cache these, they don't ever change per service. @@ -711,13 +706,13 @@ function canonicalizeLanguageTag(localeID) { // null is typeof 'object' so we have to do extra check. if (typeof localeID !== 'string' && typeof localeID !== 'object' || IS_NULL(localeID)) { - throw new $TypeError('Language ID should be string or object.'); + throw MakeTypeError(kLanguageID); } var localeString = GlobalString(localeID); if (isValidLanguageTag(localeString) === false) { - throw new $RangeError('Invalid language tag: ' + localeString); + throw MakeRangeError(kInvalidLanguageTag, localeString); } // This call will strip -kn but not -kn-true extensions. @@ -726,7 +721,7 @@ function canonicalizeLanguageTag(localeID) { // upgrade to ICU 4.9. var tag = %CanonicalizeLanguageTag(localeString); if (tag === 'invalid-tag') { - throw new $RangeError('Invalid language tag: ' + localeString); + throw MakeRangeError(kInvalidLanguageTag, localeString); } return tag; @@ -869,7 +864,7 @@ function BuildLanguageTagREs() { */ function initializeCollator(collator, locales, options) { if (%IsInitializedIntlObject(collator)) { - throw new $TypeError('Trying to re-initialize Collator object.'); + throw MakeTypeError(kReinitializeIntl, "Collator"); } if (options === undefined) { @@ -972,12 +967,11 @@ function initializeCollator(collator, locales, options) { */ %AddNamedProperty(Intl.Collator.prototype, 'resolvedOptions', function() { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } if (!%IsInitializedIntlObjectOfType(this, 'collator')) { - throw new $TypeError('resolvedOptions method called on a non-object ' + - 'or on a object that is not Intl.Collator.'); + throw MakeTypeError(kResolvedOptionsCalledOnNonObject, "Collator"); } var coll = this; @@ -1009,7 +1003,7 @@ function initializeCollator(collator, locales, options) { */ %AddNamedProperty(Intl.Collator, 'supportedLocalesOf', function(locales) { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } return supportedLocalesOf('collator', locales, %_Arguments(1)); @@ -1060,7 +1054,7 @@ function getNumberOption(options, property, min, max, fallback) { if (value !== undefined) { value = GlobalNumber(value); if ($isNaN(value) || value < min || value > max) { - throw new $RangeError(property + ' value is out of range.'); + throw MakeRangeError(kPropertyValueOutOfRange, property); } return $floor(value); } @@ -1075,7 +1069,7 @@ function getNumberOption(options, property, min, max, fallback) { */ function initializeNumberFormat(numberFormat, locales, options) { if (%IsInitializedIntlObject(numberFormat)) { - throw new $TypeError('Trying to re-initialize NumberFormat object.'); + throw MakeTypeError(kReinitializeIntl, "NumberFormat"); } if (options === undefined) { @@ -1092,11 +1086,11 @@ function initializeNumberFormat(numberFormat, locales, options) { var currency = getOption('currency', 'string'); if (currency !== undefined && !isWellFormedCurrencyCode(currency)) { - throw new $RangeError('Invalid currency code: ' + currency); + throw MakeRangeError(kInvalidCurrencyCode, currency); } if (internalOptions.style === 'currency' && currency === undefined) { - throw new $TypeError('Currency code is required with currency style.'); + throw MakeTypeError(kCurrencyCode); } var currencyDisplay = getOption( @@ -1199,12 +1193,11 @@ function initializeNumberFormat(numberFormat, locales, options) { */ %AddNamedProperty(Intl.NumberFormat.prototype, 'resolvedOptions', function() { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } if (!%IsInitializedIntlObjectOfType(this, 'numberformat')) { - throw new $TypeError('resolvedOptions method called on a non-object' + - ' or on a object that is not Intl.NumberFormat.'); + throw MakeTypeError(kResolvedOptionsCalledOnNonObject, "NumberFormat"); } var format = this; @@ -1255,7 +1248,7 @@ function initializeNumberFormat(numberFormat, locales, options) { */ %AddNamedProperty(Intl.NumberFormat, 'supportedLocalesOf', function(locales) { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } return supportedLocalesOf('numberformat', locales, %_Arguments(1)); @@ -1498,7 +1491,7 @@ function toDateTimeOptions(options, required, defaults) { function initializeDateTimeFormat(dateFormat, locales, options) { if (%IsInitializedIntlObject(dateFormat)) { - throw new $TypeError('Trying to re-initialize DateTimeFormat object.'); + throw MakeTypeError(kReinitializeIntl, "DateTimeFormat"); } if (options === undefined) { @@ -1556,7 +1549,7 @@ function initializeDateTimeFormat(dateFormat, locales, options) { requestedLocale, {skeleton: ldmlString, timeZone: tz}, resolved); if (tz !== undefined && tz !== resolved.timeZone) { - throw new $RangeError('Unsupported time zone specified ' + tz); + throw MakeRangeError(kUnsupportedTimeZone, tz); } %MarkAsInitializedIntlObjectOfType(dateFormat, 'dateformat', formatter); @@ -1592,12 +1585,11 @@ function initializeDateTimeFormat(dateFormat, locales, options) { */ %AddNamedProperty(Intl.DateTimeFormat.prototype, 'resolvedOptions', function() { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } if (!%IsInitializedIntlObjectOfType(this, 'dateformat')) { - throw new $TypeError('resolvedOptions method called on a non-object or ' + - 'on a object that is not Intl.DateTimeFormat.'); + throw MakeTypeError(kResolvedOptionsCalledOnNonObject, "DateTimeFormat"); } var format = this; @@ -1648,7 +1640,7 @@ function initializeDateTimeFormat(dateFormat, locales, options) { */ %AddNamedProperty(Intl.DateTimeFormat, 'supportedLocalesOf', function(locales) { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } return supportedLocalesOf('dateformat', locales, %_Arguments(1)); @@ -1673,9 +1665,7 @@ function formatDate(formatter, dateValue) { dateMs = GlobalNumber(dateValue); } - if (!$isFinite(dateMs)) { - throw new $RangeError('Provided date is not in valid range.'); - } + if (!$isFinite(dateMs)) throw MakeRangeError(kDateRange); return %InternalDateFormat(%GetImplFromInitializedIntlObject(formatter), new GlobalDate(dateMs)); @@ -1719,9 +1709,7 @@ function canonicalizeTimeZoneID(tzID) { // We expect only _ and / beside ASCII letters. // All inputs should conform to Area/Location from now on. var match = GetTimezoneNameCheckRE().exec(tzID); - if (IS_NULL(match)) { - throw new $RangeError('Expected Area/Location for time zone, got ' + tzID); - } + if (IS_NULL(match)) throw MakeRangeError(kExpectedLocation, tzID); var result = toTitleCaseWord(match[1]) + '/' + toTitleCaseWord(match[2]); var i = 3; @@ -1739,7 +1727,7 @@ function canonicalizeTimeZoneID(tzID) { */ function initializeBreakIterator(iterator, locales, options) { if (%IsInitializedIntlObject(iterator)) { - throw new $TypeError('Trying to re-initialize v8BreakIterator object.'); + throw MakeTypeError(kReinitializeIntl, "v8BreakIterator"); } if (options === undefined) { @@ -1799,12 +1787,11 @@ function initializeBreakIterator(iterator, locales, options) { %AddNamedProperty(Intl.v8BreakIterator.prototype, 'resolvedOptions', function() { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } if (!%IsInitializedIntlObjectOfType(this, 'breakiterator')) { - throw new $TypeError('resolvedOptions method called on a non-object or ' + - 'on a object that is not Intl.v8BreakIterator.'); + throw MakeTypeError(kResolvedOptionsCalledOnNonObject, "v8BreakIterator"); } var segmenter = this; @@ -1833,7 +1820,7 @@ function initializeBreakIterator(iterator, locales, options) { %AddNamedProperty(Intl.v8BreakIterator, 'supportedLocalesOf', function(locales) { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } return supportedLocalesOf('breakiterator', locales, %_Arguments(1)); @@ -1936,11 +1923,11 @@ function cachedOrNewService(service, locales, options, defaults) { */ OverrideFunction(GlobalString.prototype, 'localeCompare', function(that) { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } if (IS_NULL_OR_UNDEFINED(this)) { - throw new $TypeError('Method invoked on undefined or null value.'); + throw MakeTypeError(kMethodInvokedOnNullOrUndefined); } var locales = %_Arguments(1); @@ -1960,7 +1947,7 @@ OverrideFunction(GlobalString.prototype, 'localeCompare', function(that) { */ OverrideFunction(GlobalString.prototype, 'normalize', function(that) { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } CHECK_OBJECT_COERCIBLE(this, "String.prototype.normalize"); @@ -1969,8 +1956,7 @@ OverrideFunction(GlobalString.prototype, 'normalize', function(that) { var normalizationForm = NORMALIZATION_FORMS.indexOf(form); if (normalizationForm === -1) { - throw new $RangeError('The normalization form should be one of ' - + NORMALIZATION_FORMS.join(', ') + '.'); + throw MakeRangeError(kNormalizationForm, NORMALIZATION_FORMS.join(', ')); } return %StringNormalize(this, normalizationForm); @@ -1984,11 +1970,11 @@ OverrideFunction(GlobalString.prototype, 'normalize', function(that) { */ OverrideFunction(GlobalNumber.prototype, 'toLocaleString', function() { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } if (!(this instanceof GlobalNumber) && typeof(this) !== 'number') { - throw new $TypeError('Method invoked on an object that is not Number.'); + throw MakeTypeError(kMethodInvokedOnWrongType, "Number"); } var locales = %_Arguments(0); @@ -2004,7 +1990,7 @@ OverrideFunction(GlobalNumber.prototype, 'toLocaleString', function() { */ function toLocaleDateTime(date, locales, options, required, defaults, service) { if (!(date instanceof GlobalDate)) { - throw new $TypeError('Method invoked on an object that is not Date.'); + throw MakeTypeError(kMethodInvokedOnWrongType, "Date"); } if ($isNaN(date)) { @@ -2027,7 +2013,7 @@ function toLocaleDateTime(date, locales, options, required, defaults, service) { */ OverrideFunction(GlobalDate.prototype, 'toLocaleString', function() { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } var locales = %_Arguments(0); @@ -2045,7 +2031,7 @@ OverrideFunction(GlobalDate.prototype, 'toLocaleString', function() { */ OverrideFunction(GlobalDate.prototype, 'toLocaleDateString', function() { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } var locales = %_Arguments(0); @@ -2063,7 +2049,7 @@ OverrideFunction(GlobalDate.prototype, 'toLocaleDateString', function() { */ OverrideFunction(GlobalDate.prototype, 'toLocaleTimeString', function() { if (%_IsConstructCall()) { - throw new $TypeError(ORDINARY_FUNCTION_CALLED_AS_CONSTRUCTOR); + throw MakeTypeError(kOrdinaryFunctionCalledAsConstructor); } var locales = %_Arguments(0); diff --git a/src/macros.py b/src/macros.py index 2dab3b2..f00a8b7 100644 --- a/src/macros.py +++ b/src/macros.py @@ -133,7 +133,7 @@ macro IS_SPEC_FUNCTION(arg) = (%_ClassOf(arg) === 'Function'); # Macro for ES6 CheckObjectCoercible # Will throw a TypeError of the form "[functionName] called on null or undefined". -macro CHECK_OBJECT_COERCIBLE(arg, functionName) = if (IS_NULL_OR_UNDEFINED(arg) && !IS_UNDETECTABLE(arg)) throw MakeTypeError('called_on_null_or_undefined', [functionName]); +macro CHECK_OBJECT_COERCIBLE(arg, functionName) = if (IS_NULL_OR_UNDEFINED(arg) && !IS_UNDETECTABLE(arg)) throw MakeTypeError(kCalledOnNullOrUndefined, functionName); # Indices in bound function info retrieved by %BoundFunctionGetBindings(...). const kBoundFunctionIndex = 0; @@ -191,7 +191,7 @@ const MAX_TIME_BEFORE_UTC = 8640002592000000; # Gets the value of a Date object. If arg is not a Date object # a type error is thrown. -macro CHECK_DATE(arg) = if (%_ClassOf(arg) !== 'Date') ThrowDateTypeError(); +macro CHECK_DATE(arg) = if (%_ClassOf(arg) !== 'Date') throw MakeTypeError(kDateType); macro LOCAL_DATE_VALUE(arg) = (%_DateField(arg, 0) + %_DateField(arg, 21)); macro UTC_DATE_VALUE(arg) = (%_DateField(arg, 0)); diff --git a/src/messages.h b/src/messages.h index 132df76..5f7aca3 100644 --- a/src/messages.h +++ b/src/messages.h @@ -91,13 +91,22 @@ class MessageHandler { #define MESSAGE_TEMPLATES(T) \ /* Error */ \ T(CyclicProto, "Cyclic __proto__ value") \ + T(DefaultOptionsMissing, "Internal % error. Default options are missing.") \ + T(Unsupported, "Not supported") \ + T(WrongServiceType, "Internal error, wrong service type: %") \ + T(WrongValueType, "Internal error. Wrong value type.") \ /* TypeError */ \ T(ApplyNonFunction, \ "Function.prototype.apply was called on %, which is a % and not a " \ "function") \ + T(ArrayFunctionsOnFrozen, "Cannot modify frozen array elements") \ + T(ArrayFunctionsOnSealed, "Cannot add/remove sealed array elements") \ T(CalledNonCallable, "% is not a function") \ T(CalledOnNonObject, "% called on non-object") \ + T(CalledOnNullOrUndefined, "% called on null or undefined") \ + T(CurrencyCode, "Currency code is required with currency style.") \ T(CannotConvertToPrimitive, "Cannot convert object to primitive value") \ + T(DateType, "this is not a Date object.") \ T(DefineDisallowed, "Cannot define property:%, object is not extensible.") \ T(GeneratorRunning, "Generator is already running") \ T(FunctionBind, "Bind must be called on a function") \ @@ -107,6 +116,12 @@ class MessageHandler { T(InstanceofNonobjectProto, \ "Function has non-object prototype '%' in instanceof check") \ T(InvalidInOperatorUse, "Cannot use 'in' operator to search for '%' in %") \ + T(LanguageID, "Language ID should be string or object.") \ + T(MethodCalledOnWrongObject, \ + "Method % called on a non-object or on a wrong type of object.") \ + T(MethodInvokedOnNullOrUndefined, \ + "Method invoked on undefined or null value.") \ + T(MethodInvokedOnWrongType, "Method invoked on an object that is not %.") \ T(NotAnIterator, "% is not an iterator") \ T(NotConstructor, "% is not a constructor") \ T(NotGeneric, "% is not generic") \ @@ -117,6 +132,8 @@ class MessageHandler { T(ObjectSetterExpectingFunction, \ "Object.prototype.__defineSetter__: Expecting function") \ T(ObjectSetterCallable, "Setter must be a function: %") \ + T(OrdinaryFunctionCalledAsConstructor, \ + "Function object that's not a constructor was created with new") \ T(PropertyDescObject, "Property description must be an object: %") \ T(PropertyNotFunction, "Property '%' of object % is not a function") \ T(ProtoObjectOrNull, "Object prototype may only be an Object or null: %") \ @@ -130,6 +147,11 @@ class MessageHandler { "Proxy handler % returned non-configurable descriptor for property '%' " \ "from '%' trap") \ T(RedefineDisallowed, "Cannot redefine property: %") \ + T(ReduceNoInitial, "Reduce of empty array with no initial value") \ + T(ReinitializeIntl, "Trying to re-initialize % object.") \ + T(ResolvedOptionsCalledOnNonObject, \ + "resolvedOptions method called on a non-object or on a object that is " \ + "not Intl.%.") \ T(SymbolToPrimitive, \ "Cannot convert a Symbol wrapper object to a primitive value") \ T(SymbolToNumber, "Cannot convert a Symbol value to a number") \ @@ -142,13 +164,25 @@ class MessageHandler { T(WrongArgs, "%: Arguments list has wrong type") \ /* RangeError */ \ T(ArrayLengthOutOfRange, "defineProperty() array length out of range") \ + T(DateRange, "Provided date is not in valid range.") \ + T(ExpectedLocation, "Expected Area/Location for time zone, got %") \ + T(InvalidCurrencyCode, "Invalid currency code: %") \ + T(InvalidLanguageTag, "Invalid language tag: %") \ + T(LocaleMatcher, "Illegal value for localeMatcher:%") \ + T(NormalizationForm, "The normalization form should be one of %.") \ T(NumberFormatRange, "% argument must be between 0 and 20") \ + T(PropertyValueOutOfRange, "% value is out of range.") \ T(StackOverflow, "Maximum call stack size exceeded") \ T(ToPrecisionFormatRange, "toPrecision() argument must be between 1 and 21") \ + T(ToRadixFormatRange, "toString() radix argument must be between 2 and 36") \ + T(UnsupportedTimeZone, "Unsupported time zone specified %") \ + T(ValueOutOfRange, "Value % out of range for % options property %") \ /* SyntaxError */ \ T(ParenthesisInArgString, "Function arg string contains parenthesis") \ /* EvalError */ \ - T(CodeGenFromStrings, "%") + T(CodeGenFromStrings, "%") \ + /* URIError */ \ + T(URIMalformed, "URI malformed") class MessageTemplate { public: diff --git a/src/messages.js b/src/messages.js index 0e48ae6..c42ea2a 100644 --- a/src/messages.js +++ b/src/messages.js @@ -41,7 +41,6 @@ var kMessages = { illegal_invocation: ["Illegal invocation"], no_setter_in_callback: ["Cannot set property ", "%0", " of ", "%1", " which has only a getter"], flags_getter_non_object: ["RegExp.prototype.flags getter called on non-object ", "%0"], - reduce_no_initial: ["Reduce of empty array with no initial value"], value_and_accessor: ["Invalid property. A property cannot both have accessors and be writable or have a value, ", "%0"], proto_object_or_null: ["Object prototype may only be an Object or null: ", "%0"], non_extensible_proto: ["%0", " is not extensible"], @@ -69,8 +68,6 @@ var kMessages = { not_a_promise: ["%0", " is not a promise"], resolver_not_a_function: ["Promise resolver ", "%0", " is not a function"], promise_cyclic: ["Chaining cycle detected for promise ", "%0"], - array_functions_on_frozen: ["Cannot modify frozen array elements"], - array_functions_change_sealed: ["Cannot add/remove sealed array elements"], first_argument_not_regexp: ["First argument to ", "%0", " must not be a regular expression"], iterator_result_not_an_object: ["Iterator result ", "%0", " is not an object"], iterator_value_not_an_object: ["Iterator value ", "%0", " is not an entry object"], @@ -108,7 +105,6 @@ var kMessages = { illegal_return: ["Illegal return statement"], error_loading_debugger: ["Error loading debugger"], circular_structure: ["Converting circular structure to JSON"], - called_on_null_or_undefined: ["%0", " called on null or undefined"], array_indexof_not_defined: ["Array.getIndexOf: Argument undefined"], object_not_extensible: ["Can't add property ", "%0", ", object is not extensible"], illegal_access: ["Illegal access"], @@ -298,7 +294,7 @@ function MakeGenericError(constructor, type, arg0, arg1, arg2) { DONT_ENUM | DONT_DELETE | READ_ONLY); %SetCode(Script, function(x) { // Script objects can only be created by the VM. - throw new $Error("Not supported"); + throw MakeError(kUnsupported); }); @@ -371,6 +367,11 @@ function MakeEvalError(type, arg0, arg1, arg2) { return MakeGenericError($EvalError, type, arg0, arg1, arg2); } + +function MakeURIError() { + return MakeGenericError($URIError, kURIMalformed); +} + // The embedded versions are called from unoptimized code, with embedded // arguments. Those arguments cannot be arrays, which are context-dependent. function MakeTypeErrorEmbedded(type, arg) { diff --git a/src/string.js b/src/string.js index 3da316d..87823d9 100644 --- a/src/string.js +++ b/src/string.js @@ -179,8 +179,7 @@ function StringNormalizeJS(form) { var form = form ? TO_STRING_INLINE(form) : 'NFC'; var normalizationForm = NORMALIZATION_FORMS.indexOf(form); if (normalizationForm === -1) { - throw new $RangeError('The normalization form should be one of ' - + NORMALIZATION_FORMS.join(', ') + '.'); + throw MakeRangeError(kNormalizationForm, NORMALIZATION_FORMS.join(', ')); } return %_ValueOf(this); diff --git a/src/uri.js b/src/uri.js index f693ff2..b7dd050 100644 --- a/src/uri.js +++ b/src/uri.js @@ -97,9 +97,7 @@ function URIEncodePair(cc1 , cc2, result, index) { function URIHexCharsToCharCode(highChar, lowChar) { var highCode = HexValueOf(highChar); var lowCode = HexValueOf(lowChar); - if (highCode == -1 || lowCode == -1) { - throw new $URIError("URI malformed"); - } + if (highCode == -1 || lowCode == -1) throw MakeURIError(); return (highCode << 4) | lowCode; } @@ -111,64 +109,46 @@ function URIDecodeOctets(octets, result, index) { if (o0 < 0x80) { value = o0; } else if (o0 < 0xc2) { - throw new $URIError("URI malformed"); + throw MakeURIError(); } else { var o1 = octets[1]; if (o0 < 0xe0) { var a = o0 & 0x1f; - if ((o1 < 0x80) || (o1 > 0xbf)) { - throw new $URIError("URI malformed"); - } + if ((o1 < 0x80) || (o1 > 0xbf)) throw MakeURIError(); var b = o1 & 0x3f; value = (a << 6) + b; - if (value < 0x80 || value > 0x7ff) { - throw new $URIError("URI malformed"); - } + if (value < 0x80 || value > 0x7ff) throw MakeURIError(); } else { var o2 = octets[2]; if (o0 < 0xf0) { var a = o0 & 0x0f; - if ((o1 < 0x80) || (o1 > 0xbf)) { - throw new $URIError("URI malformed"); - } + if ((o1 < 0x80) || (o1 > 0xbf)) throw MakeURIError(); var b = o1 & 0x3f; - if ((o2 < 0x80) || (o2 > 0xbf)) { - throw new $URIError("URI malformed"); - } + if ((o2 < 0x80) || (o2 > 0xbf)) throw MakeURIError(); var c = o2 & 0x3f; value = (a << 12) + (b << 6) + c; - if ((value < 0x800) || (value > 0xffff)) { - throw new $URIError("URI malformed"); - } + if ((value < 0x800) || (value > 0xffff)) throw MakeURIError(); } else { var o3 = octets[3]; if (o0 < 0xf8) { var a = (o0 & 0x07); - if ((o1 < 0x80) || (o1 > 0xbf)) { - throw new $URIError("URI malformed"); - } + if ((o1 < 0x80) || (o1 > 0xbf)) throw MakeURIError(); var b = (o1 & 0x3f); if ((o2 < 0x80) || (o2 > 0xbf)) { - throw new $URIError("URI malformed"); + throw MakeURIError(); } var c = (o2 & 0x3f); - if ((o3 < 0x80) || (o3 > 0xbf)) { - throw new $URIError("URI malformed"); - } + if ((o3 < 0x80) || (o3 > 0xbf)) throw MakeURIError(); var d = (o3 & 0x3f); value = (a << 18) + (b << 12) + (c << 6) + d; - if ((value < 0x10000) || (value > 0x10ffff)) { - throw new $URIError("URI malformed"); - } + if ((value < 0x10000) || (value > 0x10ffff)) throw MakeURIError(); } else { - throw new $URIError("URI malformed"); + throw MakeURIError(); } } } } - if (0xD800 <= value && value <= 0xDFFF) { - throw new $URIError("URI malformed"); - } + if (0xD800 <= value && value <= 0xDFFF) throw MakeURIError(); if (value < 0x10000) { %_TwoByteSeqStringSetChar(index++, value, result); } else { @@ -188,14 +168,14 @@ function Encode(uri, unescape) { if (unescape(cc1)) { array[index++] = cc1; } else { - if (cc1 >= 0xDC00 && cc1 <= 0xDFFF) throw new $URIError("URI malformed"); + if (cc1 >= 0xDC00 && cc1 <= 0xDFFF) throw MakeURIError(); if (cc1 < 0xD800 || cc1 > 0xDBFF) { index = URIEncodeSingle(cc1, array, index); } else { k++; - if (k == uriLength) throw new $URIError("URI malformed"); + if (k == uriLength) throw MakeURIError(); var cc2 = uri.charCodeAt(k); - if (cc2 < 0xDC00 || cc2 > 0xDFFF) throw new $URIError("URI malformed"); + if (cc2 < 0xDC00 || cc2 > 0xDFFF) throw MakeURIError(); index = URIEncodePair(cc1, cc2, array, index); } } @@ -219,7 +199,7 @@ function Decode(uri, reserved) { for ( ; k < uriLength; k++) { var code = uri.charCodeAt(k); if (code == 37) { // '%' - if (k + 2 >= uriLength) throw new $URIError("URI malformed"); + if (k + 2 >= uriLength) throw MakeURIError(); var cc = URIHexCharsToCharCode(uri.charCodeAt(k+1), uri.charCodeAt(k+2)); if (cc >> 7) break; // Assumption wrong, two-byte string. if (reserved(cc)) { @@ -246,17 +226,17 @@ function Decode(uri, reserved) { for ( ; k < uriLength; k++) { var code = uri.charCodeAt(k); if (code == 37) { // '%' - if (k + 2 >= uriLength) throw new $URIError("URI malformed"); + if (k + 2 >= uriLength) throw MakeURIError(); var cc = URIHexCharsToCharCode(uri.charCodeAt(++k), uri.charCodeAt(++k)); if (cc >> 7) { var n = 0; while (((cc << ++n) & 0x80) != 0) { } - if (n == 1 || n > 4) throw new $URIError("URI malformed"); + if (n == 1 || n > 4) throw MakeURIError(); var octets = new GlobalArray(n); octets[0] = cc; - if (k + 3 * (n - 1) >= uriLength) throw new $URIError("URI malformed"); + if (k + 3 * (n - 1) >= uriLength) throw MakeURIError(); for (var i = 1; i < n; i++) { - if (uri.charAt(++k) != '%') throw new $URIError("URI malformed"); + if (uri.charAt(++k) != '%') throw MakeURIError(); octets[i] = URIHexCharsToCharCode(uri.charCodeAt(++k), uri.charCodeAt(++k)); } diff --git a/src/v8natives.js b/src/v8natives.js index 41453d0..8080e12 100644 --- a/src/v8natives.js +++ b/src/v8natives.js @@ -1538,9 +1538,7 @@ function NumberToStringJS(radix) { // Convert the radix to an integer and check the range. radix = TO_INTEGER(radix); - if (radix < 2 || radix > 36) { - throw new $RangeError('toString() radix argument must be between 2 and 36'); - } + if (radix < 2 || radix > 36) throw MakeRangeError(kToRadixFormatRange); // Convert the number to a string in the given radix. return %NumberToRadixString(number, radix); } diff --git a/test/mjsunit/messages.js b/test/mjsunit/messages.js index 30920a1..4b6915d 100644 --- a/test/mjsunit/messages.js +++ b/test/mjsunit/messages.js @@ -32,16 +32,45 @@ test(function() { }, "Function.prototype.apply was called on 1, which is a number " + "and not a function", TypeError); +// kArrayFunctionsOnFrozen +test(function() { + var a = [1, 2]; + Object.freeze(a); + a.splice(1, 1, [1]); +}, "Cannot modify frozen array elements", TypeError); + +// kArrayFunctionsOnSealed +test(function() { + var a = [1]; + Object.seal(a); + a.shift(); +}, "Cannot add/remove sealed array elements", TypeError); + // kCalledNonCallable test(function() { [].forEach(1); }, "1 is not a function", TypeError); +// kCalledOnNonObject +test(function() { + Object.defineProperty(1, "x", {}); +}, "Object.defineProperty called on non-object", TypeError); + +// kCalledOnNullOrUndefined +test(function() { + Array.prototype.shift.call(null); +}, "Array.prototype.shift called on null or undefined", TypeError); + // kCannotConvertToPrimitive test(function() { [].join(Object(Symbol(1))); }, "Cannot convert object to primitive value", TypeError); +// kDateType +test(function() { + Date.prototype.setYear.call({}, 1); +}, "this is not a Date object.", TypeError); + // kDefineDisallowed test(function() { "use strict"; @@ -121,7 +150,6 @@ test(function() { Function.prototype.toString.call(1); }, "Function.prototype.toString is not generic", TypeError); - // kObjectGetterExpectingFunction test(function() { ({}).__defineGetter__("x", 0); @@ -166,6 +194,11 @@ test(function() { Object.defineProperty(o, "x", { value: 2 }); }, "Cannot redefine property: x", TypeError); +// kReduceNoInitial +test(function() { + [].reduce(function() {}); +}, "Reduce of empty array with no initial value", TypeError); + // kSymbolToPrimitive test(function() { 1 + Object(Symbol()); @@ -226,7 +259,12 @@ test(function() { Object.defineProperty([], "length", { value: 1E100 }); }, "defineProperty() array length out of range", RangeError); -//kNumberFormatRange +// kNormalizationForm +test(function() { + "".normalize("ABC"); +}, "The normalization form should be one of NFC, NFD, NFKC, NFKD.", RangeError); + +// kNumberFormatRange test(function() { Number(1).toFixed(100); }, "toFixed() digits argument must be between 0 and 20", RangeError); @@ -245,3 +283,16 @@ test(function() { test(function() { Number(1).toPrecision(100); }, "toPrecision() argument must be between 1 and 21", RangeError); + +// kToPrecisionFormatRange +test(function() { + Number(1).toString(100); +}, "toString() radix argument must be between 2 and 36", RangeError); + + +// === URIError === + +// kURIMalformed +test(function() { + decodeURI("%%"); +}, "URI malformed", URIError); diff --git a/tools/js2c.py b/tools/js2c.py index d0484b5..e913ca1 100755 --- a/tools/js2c.py +++ b/tools/js2c.py @@ -69,7 +69,8 @@ def ReadFile(filename): EVAL_PATTERN = re.compile(r'\beval\s*\(') WITH_PATTERN = re.compile(r'\bwith\s*\(') -INVALID_ERROR_MESSAGE_PATTERN = re.compile(r'Make\w*Error\((k\w+),') +INVALID_ERROR_MESSAGE_PATTERN = re.compile(r'Make\w*Error\(([kA-Z]\w+)') +NEW_ERROR_PATTERN = re.compile(r'new \$\w*Error\((?!\))'); def Validate(lines): # Because of simplified context setup, eval and with is not @@ -81,6 +82,8 @@ def Validate(lines): invalid_error = INVALID_ERROR_MESSAGE_PATTERN.search(lines) if invalid_error: raise Error("Unknown error message template '%s'" % invalid_error.group(1)) + if NEW_ERROR_PATTERN.search(lines): + raise Error("Error constructed without message template.") # Pass lines through unchanged. return lines -- 2.7.4