diff options
Diffstat (limited to 'src/messages.js')
-rw-r--r-- | src/messages.js | 228 |
1 files changed, 98 insertions, 130 deletions
diff --git a/src/messages.js b/src/messages.js index a3adcf86..a9993af2 100644 --- a/src/messages.js +++ b/src/messages.js @@ -1,4 +1,4 @@ -// Copyright 2012 the V8 project authors. All rights reserved. +// Copyright 2011 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -25,16 +25,17 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + // ------------------------------------------------------------------- // // If this object gets passed to an error constructor the error will // get an accessor for .message that constructs a descriptive error // message on access. -var kAddMessageAccessorsMarker = { }; +const kAddMessageAccessorsMarker = { }; // This will be lazily initialized when first needed (and forcibly // overwritten even though it's const). -var kMessages = 0; +const kMessages = 0; function FormatString(format, message) { var args = %MessageGetArguments(message); @@ -82,7 +83,7 @@ function IsNativeErrorObject(obj) { // objects between script tags in a browser setting. function ToStringCheckErrorObject(obj) { if (IsNativeErrorObject(obj)) { - return %_CallFunction(obj, ErrorToString); + return %_CallFunction(obj, errorToString); } else { return ToString(obj); } @@ -184,20 +185,18 @@ function FormatMessage(message) { "define_disallowed", ["Cannot define property:", "%0", ", object is not extensible."], "non_extensible_proto", ["%0", " is not extensible"], "handler_non_object", ["Proxy.", "%0", " called with non-object as handler"], - "proto_non_object", ["Proxy.", "%0", " called with non-object as prototype"], - "trap_function_expected", ["Proxy.", "%0", " called with non-function for '", "%1", "' trap"], + "trap_function_expected", ["Proxy.", "%0", " called with non-function for ", "%1", " trap"], "handler_trap_missing", ["Proxy handler ", "%0", " has no '", "%1", "' trap"], "handler_trap_must_be_callable", ["Proxy handler ", "%0", " has non-callable '", "%1", "' trap"], - "handler_returned_false", ["Proxy handler ", "%0", " returned false from '", "%1", "' trap"], - "handler_returned_undefined", ["Proxy handler ", "%0", " returned undefined from '", "%1", "' trap"], - "proxy_prop_not_configurable", ["Proxy handler ", "%0", " returned non-configurable descriptor for property '", "%2", "' from '", "%1", "' trap"], - "proxy_non_object_prop_names", ["Trap '", "%1", "' returned non-object ", "%0"], - "proxy_repeated_prop_name", ["Trap '", "%1", "' returned repeated property name '", "%2", "'"], + "handler_returned_false", ["Proxy handler ", "%0", " returned false for '", "%1", "' trap"], + "handler_returned_undefined", ["Proxy handler ", "%0", " returned undefined for '", "%1", "' trap"], + "proxy_prop_not_configurable", ["Trap ", "%1", " of proxy handler ", "%0", " returned non-configurable descriptor for property ", "%2"], + "proxy_non_object_prop_names", ["Trap ", "%1", " returned non-object ", "%0"], + "proxy_repeated_prop_name", ["Trap ", "%1", " returned repeated property name ", "%2"], "invalid_weakmap_key", ["Invalid value used as weak map key"], // RangeError "invalid_array_length", ["Invalid array length"], "stack_overflow", ["Maximum call stack size exceeded"], - "invalid_time_value", ["Invalid time value"], // SyntaxError "unable_to_parse", ["Parse error"], "invalid_regexp_flags", ["Invalid flags supplied to RegExp constructor '", "%0", "'"], @@ -205,12 +204,11 @@ function FormatMessage(message) { "illegal_break", ["Illegal break statement"], "illegal_continue", ["Illegal continue statement"], "illegal_return", ["Illegal return statement"], - "illegal_let", ["Illegal let declaration outside extended mode"], "error_loading_debugger", ["Error loading debugger"], "no_input_to_regexp", ["No input to ", "%0"], "invalid_json", ["String '", "%0", "' is not valid JSON"], "circular_structure", ["Converting circular structure to JSON"], - "called_on_non_object", ["%0", " called on non-object"], + "obj_ctor_property_non_object", ["Object.", "%0", " called on non-object"], "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"], @@ -242,29 +240,20 @@ function FormatMessage(message) { "strict_poison_pill", ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"], "strict_caller", ["Illegal access to a strict mode caller function."], "unprotected_let", ["Illegal let declaration in unprotected statement context."], - "unprotected_const", ["Illegal const declaration in unprotected statement context."], "cant_prevent_ext_external_array_elements", ["Cannot prevent extension of an object with external array elements"], "redef_external_array_element", ["Cannot redefine a property of an object with external array elements"], - "harmony_const_assign", ["Assignment to constant variable."], - "invalid_module_path", ["Module does not export '", "%0", "', or export is not itself a module"], - "module_type_error", ["Module '", "%0", "' used improperly"], ]; var messages = { __proto__ : null }; + var desc = new PropertyDescriptor(); + desc.setConfigurable(false); + desc.setEnumerable(false); + desc.setWritable(false); for (var i = 0; i < messagesDictionary.length; i += 2) { var key = messagesDictionary[i]; var format = messagesDictionary[i + 1]; - - for (var j = 0; j < format.length; j++) { - %IgnoreAttributesAndSetProperty(format, %_NumberToString(j), format[j], - DONT_DELETE | READ_ONLY | DONT_ENUM); - } - %IgnoreAttributesAndSetProperty(format, 'length', format.length, - DONT_DELETE | READ_ONLY | DONT_ENUM); - %PreventExtensions(format); - %IgnoreAttributesAndSetProperty(messages, - key, - format, - DONT_DELETE | DONT_ENUM | READ_ONLY); + ObjectFreeze(format); + desc.setValue(format); + DefineOwnProperty(messages, key, desc); } %PreventExtensions(messages); %IgnoreAttributesAndSetProperty(builtins, "kMessages", @@ -397,7 +386,7 @@ function ScriptLocationFromPosition(position, } return new SourceLocation(this, position, line, column, start, end); -} +}; /** @@ -427,7 +416,7 @@ function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) { // resource. var column = opt_column || 0; if (line == 0) { - column -= this.column_offset; + column -= this.column_offset } var offset_position = opt_offset_position || 0; @@ -442,8 +431,7 @@ function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) { return null; } - return this.locationFromPosition( - this.line_ends[offset_line + line - 1] + 1 + column); // line > 0 here. + return this.locationFromPosition(this.line_ends[offset_line + line - 1] + 1 + column); // line > 0 here. } } @@ -459,10 +447,8 @@ function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) { * invalid */ function ScriptSourceSlice(opt_from_line, opt_to_line) { - var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset - : opt_from_line; - var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount() - : opt_to_line; + var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset : opt_from_line; + var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount() : opt_to_line // Adjust according to the offset within the resource. from_line -= this.line_offset; @@ -482,10 +468,8 @@ function ScriptSourceSlice(opt_from_line, opt_to_line) { var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1; // Return a source slice with line numbers re-adjusted to the resource. - return new SourceSlice(this, - from_line + this.line_offset, - to_line + this.line_offset, - from_position, to_position); + return new SourceSlice(this, from_line + this.line_offset, to_line + this.line_offset, + from_position, to_position); } @@ -518,7 +502,7 @@ function ScriptSourceLine(opt_line) { function ScriptLineCount() { // Return number of source lines. return this.line_ends.length; -} +}; /** @@ -535,13 +519,6 @@ function ScriptNameOrSourceURL() { if (this.name) { return this.name; } - - // The result is cached as on long scripts it takes noticable time to search - // for the sourceURL. - if (this.hasCachedNameOrSourceURL) - return this.cachedNameOrSourceURL; - this.hasCachedNameOrSourceURL = true; - // TODO(608): the spaces in a regexp below had to be escaped as \040 // because this file is being processed by js2c whose handling of spaces // in regexps is broken. Also, ['"] are excluded from allowed URLs to @@ -550,7 +527,6 @@ function ScriptNameOrSourceURL() { // the scanner/parser. var source = ToString(this.source); var sourceUrlPos = %StringIndexOf(source, "sourceURL=", 0); - this.cachedNameOrSourceURL = this.name; if (sourceUrlPos > 4) { var sourceUrlPattern = /\/\/@[\040\t]sourceURL=[\040\t]*([^\s\'\"]*)[\040\t]*$/gm; @@ -561,17 +537,15 @@ function ScriptNameOrSourceURL() { var match = %_RegExpExec(sourceUrlPattern, source, sourceUrlPos - 4, matchInfo); if (match) { - this.cachedNameOrSourceURL = - SubString(source, matchInfo[CAPTURE(2)], matchInfo[CAPTURE(3)]); + return SubString(source, matchInfo[CAPTURE(2)], matchInfo[CAPTURE(3)]); } } - return this.cachedNameOrSourceURL; + return this.name; } SetUpLockedPrototype(Script, - $Array("source", "name", "line_ends", "line_offset", "column_offset", - "cachedNameOrSourceURL", "hasCachedNameOrSourceURL" ), + $Array("source", "name", "line_ends", "line_offset", "column_offset"), $Array( "lineFromPosition", ScriptLineFromPosition, "locationFromPosition", ScriptLocationFromPosition, @@ -593,10 +567,10 @@ SetUpLockedPrototype(Script, * position : position within the source * start : position of start of source context (inclusive) * end : position of end of source context (not inclusive) - * Source text for the source context is the character interval - * [start, end[. In most cases end will point to a newline character. - * It might point just past the final position of the source if the last - * source line does not end with a newline character. + * Source text for the source context is the character interval [start, end[. In + * most cases end will point to a newline character. It might point just past + * the final position of the source if the last source line does not end with a + * newline character. * @param {Script} script The Script object for which this is a location * @param {number} position Source position for the location * @param {number} line The line number for the location @@ -614,7 +588,7 @@ function SourceLocation(script, position, line, column, start, end) { this.end = end; } -var kLineLengthLimit = 78; +const kLineLengthLimit = 78; /** * Restrict source location start and end positions to make the source slice @@ -663,7 +637,7 @@ function SourceLocationRestrict(opt_limit, opt_before) { this.end = this.start + limit; } } -} +}; /** @@ -672,11 +646,8 @@ function SourceLocationRestrict(opt_limit, opt_before) { * Source text for this location. */ function SourceLocationSourceText() { - return %_CallFunction(this.script.source, - this.start, - this.end, - StringSubstring); -} + return %_CallFunction(this.script.source, this.start, this.end, StringSubstring); +}; SetUpLockedPrototype(SourceLocation, @@ -684,7 +655,7 @@ SetUpLockedPrototype(SourceLocation, $Array( "restrict", SourceLocationRestrict, "sourceText", SourceLocationSourceText - ) + ) ); @@ -724,7 +695,7 @@ function SourceSliceSourceText() { this.from_position, this.to_position, StringSubstring); -} +}; SetUpLockedPrototype(SourceSlice, $Array("script", "from_line", "to_line", "from_position", "to_position"), @@ -759,19 +730,24 @@ function DefineOneShotAccessor(obj, name, fun) { // can't rely on 'this' being the same as 'obj'. var hasBeenSet = false; var value; - var getter = function() { + function getter() { if (hasBeenSet) { return value; } hasBeenSet = true; value = fun(obj); return value; - }; - var setter = function(v) { + } + function setter(v) { hasBeenSet = true; value = v; - }; - %DefineOrRedefineAccessorProperty(obj, name, getter, setter, DONT_ENUM); + } + var desc = { get: getter, + set: setter, + enumerable: false, + configurable: true }; + desc = ToPropertyDescriptor(desc); + DefineOwnProperty(obj, name, desc, true); } function CallSite(receiver, fun, pos) { @@ -782,7 +758,7 @@ function CallSite(receiver, fun, pos) { function CallSiteGetThis() { return this.receiver; -} +}; function CallSiteGetTypeName() { var constructor = this.receiver.constructor; @@ -794,33 +770,33 @@ function CallSiteGetTypeName() { return %_CallFunction(this.receiver, ObjectToString); } return constructorName; -} +}; function CallSiteIsToplevel() { if (this.receiver == null) { return true; } return IS_GLOBAL(this.receiver); -} +}; function CallSiteIsEval() { var script = %FunctionGetScript(this.fun); return script && script.compilation_type == COMPILATION_TYPE_EVAL; -} +}; function CallSiteGetEvalOrigin() { var script = %FunctionGetScript(this.fun); return FormatEvalOrigin(script); -} +}; function CallSiteGetScriptNameOrSourceURL() { var script = %FunctionGetScript(this.fun); return script ? script.nameOrSourceURL() : null; -} +}; function CallSiteGetFunction() { return this.fun; -} +}; function CallSiteGetFunctionName() { // See if the function knows its own name @@ -836,19 +812,15 @@ function CallSiteGetFunctionName() { return "eval"; } return null; -} +}; function CallSiteGetMethodName() { // See if we can find a unique property on the receiver that holds // this function. var ownName = this.fun.name; if (ownName && this.receiver && - (%_CallFunction(this.receiver, - ownName, - ObjectLookupGetter) === this.fun || - %_CallFunction(this.receiver, - ownName, - ObjectLookupSetter) === this.fun || + (%_CallFunction(this.receiver, ownName, ObjectLookupGetter) === this.fun || + %_CallFunction(this.receiver, ownName, ObjectLookupSetter) === this.fun || this.receiver[ownName] === this.fun)) { // To handle DontEnum properties we guess that the method has // the same name as the function. @@ -858,8 +830,7 @@ function CallSiteGetMethodName() { for (var prop in this.receiver) { if (this.receiver.__lookupGetter__(prop) === this.fun || this.receiver.__lookupSetter__(prop) === this.fun || - (!this.receiver.__lookupGetter__(prop) && - this.receiver[prop] === this.fun)) { + (!this.receiver.__lookupGetter__(prop) && this.receiver[prop] === this.fun)) { // If we find more than one match bail out to avoid confusion. if (name) { return null; @@ -871,12 +842,12 @@ function CallSiteGetMethodName() { return name; } return null; -} +}; function CallSiteGetFileName() { var script = %FunctionGetScript(this.fun); return script ? script.name : null; -} +}; function CallSiteGetLineNumber() { if (this.pos == -1) { @@ -888,7 +859,7 @@ function CallSiteGetLineNumber() { location = script.locationFromPosition(this.pos, true); } return location ? location.line + 1 : null; -} +}; function CallSiteGetColumnNumber() { if (this.pos == -1) { @@ -900,16 +871,16 @@ function CallSiteGetColumnNumber() { location = script.locationFromPosition(this.pos, true); } return location ? location.column + 1: null; -} +}; function CallSiteIsNative() { var script = %FunctionGetScript(this.fun); return script ? (script.type == TYPE_NATIVE) : false; -} +}; function CallSiteGetPosition() { return this.pos; -} +}; function CallSiteIsConstructor() { var constructor = this.receiver ? this.receiver.constructor : null; @@ -917,7 +888,7 @@ function CallSiteIsConstructor() { return false; } return this.fun === constructor; -} +}; SetUpLockedPrototype(CallSite, $Array("receiver", "fun", "pos"), $Array( "getThis", CallSiteGetThis, @@ -960,13 +931,12 @@ function FormatEvalOrigin(script) { // eval script originated from "real" source. if (eval_from_script.name) { eval_origin += " (" + eval_from_script.name; - var location = eval_from_script.locationFromPosition( - script.eval_from_script_position, true); + var location = eval_from_script.locationFromPosition(script.eval_from_script_position, true); if (location) { eval_origin += ":" + (location.line + 1); eval_origin += ":" + (location.column + 1); } - eval_origin += ")"; + eval_origin += ")" } else { eval_origin += " (unknown source)"; } @@ -974,7 +944,7 @@ function FormatEvalOrigin(script) { } return eval_origin; -} +}; function FormatSourcePosition(frame) { var fileName; @@ -983,9 +953,8 @@ function FormatSourcePosition(frame) { fileLocation = "native"; } else if (frame.isEval()) { fileName = frame.getScriptNameOrSourceURL(); - if (!fileName) { + if (!fileName) fileLocation = frame.getEvalOrigin(); - } } else { fileName = frame.getFileName(); } @@ -1088,19 +1057,19 @@ function captureStackTrace(obj, cons_opt) { if (stackTraceLimit < 0 || stackTraceLimit > 10000) { stackTraceLimit = 10000; } - var raw_stack = %CollectStackTrace(obj, - cons_opt ? cons_opt : captureStackTrace, - stackTraceLimit); + var raw_stack = %CollectStackTrace(cons_opt + ? cons_opt + : captureStackTrace, stackTraceLimit); DefineOneShotAccessor(obj, 'stack', function (obj) { return FormatRawStackTrace(obj, raw_stack); }); -} +}; function SetUpError() { // Define special error type constructors. - var DefineError = function(f) { + function DefineError(f) { // Store the error function in both the global object // and the runtime object. The function is fetched // from the runtime object when throwing errors from @@ -1116,7 +1085,7 @@ function SetUpError() { // However, it can't be an instance of the Error object because // it hasn't been properly configured yet. Instead we create a // special not-a-true-error-but-close-enough object. - var ErrorPrototype = function() {}; + function ErrorPrototype() {} %FunctionSetPrototype(ErrorPrototype, $Object.prototype); %FunctionSetInstanceClassName(ErrorPrototype, 'Error'); %FunctionSetPrototype(f, new ErrorPrototype()); @@ -1157,8 +1126,7 @@ function SetUpError() { return new f(m); } }); - %SetNativeFlag(f); - }; + } DefineError(function Error() { }); DefineError(function TypeError() { }); @@ -1175,42 +1143,42 @@ $Error.captureStackTrace = captureStackTrace; %SetProperty($Error.prototype, 'message', '', DONT_ENUM); -// Global list of error objects visited during ErrorToString. This is +// Global list of error objects visited during errorToString. This is // used to detect cycles in error toString formatting. -var visited_errors = new InternalArray(); -var cyclic_error_marker = new $Object(); +const visited_errors = new InternalArray(); +const cyclic_error_marker = new $Object(); -function ErrorToStringDetectCycle(error) { +function errorToStringDetectCycle(error) { if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker; try { var type = error.type; - var name = error.name; - name = IS_UNDEFINED(name) ? "Error" : TO_STRING_INLINE(name); - var message = error.message; var hasMessage = %_CallFunction(error, "message", ObjectHasOwnProperty); if (type && !hasMessage) { - message = FormatMessage(%NewMessageObject(type, error.arguments)); + var formatted = FormatMessage(%NewMessageObject(type, error.arguments)); + return error.name + ": " + formatted; } - message = IS_UNDEFINED(message) ? "" : TO_STRING_INLINE(message); - if (name === "") return message; - if (message === "") return name; - return name + ": " + message; + var message = hasMessage ? (": " + error.message) : ""; + return error.name + message; } finally { visited_errors.length = visited_errors.length - 1; } } -function ErrorToString() { - if (!IS_SPEC_OBJECT(this)) { - throw MakeTypeError("called_on_non_object", ["Error.prototype.toString"]); +function errorToString() { + if (IS_NULL_OR_UNDEFINED(this) && !IS_UNDETECTABLE(this)) { + throw MakeTypeError("called_on_null_or_undefined", + ["Error.prototype.toString"]); } + // This helper function is needed because access to properties on + // the builtins object do not work inside of a catch clause. + function isCyclicErrorMarker(o) { return o === cyclic_error_marker; } try { - return ErrorToStringDetectCycle(this); + return errorToStringDetectCycle(this); } catch(e) { // If this error message was encountered already return the empty // string for it instead of recursively formatting it. - if (e === cyclic_error_marker) { + if (isCyclicErrorMarker(e)) { return ''; } throw e; @@ -1218,8 +1186,8 @@ function ErrorToString() { } -InstallFunctions($Error.prototype, DONT_ENUM, ['toString', ErrorToString]); +InstallFunctions($Error.prototype, DONT_ENUM, ['toString', errorToString]); // Boilerplate for exceptions for stack overflows. Used from // Isolate::StackOverflow(). -var kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); +const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); |