| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 // Matches Script::Type from objects.h | 31 // Matches Script::Type from objects.h |
| 32 var TYPE_NATIVE = 0; | 32 var TYPE_NATIVE = 0; |
| 33 var TYPE_EXTENSION = 1; | 33 var TYPE_EXTENSION = 1; |
| 34 var TYPE_NORMAL = 2; | 34 var TYPE_NORMAL = 2; |
| 35 | 35 |
| 36 // Matches Script::CompilationType from objects.h | 36 // Matches Script::CompilationType from objects.h |
| 37 var COMPILATION_TYPE_HOST = 0; | 37 var COMPILATION_TYPE_HOST = 0; |
| 38 var COMPILATION_TYPE_EVAL = 1; | 38 var COMPILATION_TYPE_EVAL = 1; |
| 39 var COMPILATION_TYPE_JSON = 2; | 39 var COMPILATION_TYPE_JSON = 2; |
| 40 | 40 |
| 41 // Lazily initialized. | |
| 42 var kVowelSounds = 0; | |
| 43 var kCapitalVowelSounds = 0; | |
| 44 | |
| 45 // Matches Messages::kNoLineNumberInfo from v8.h | 41 // Matches Messages::kNoLineNumberInfo from v8.h |
| 46 var kNoLineNumberInfo = 0; | 42 var kNoLineNumberInfo = 0; |
| 47 | 43 |
| 48 // If this object gets passed to an error constructor the error will | 44 // If this object gets passed to an error constructor the error will |
| 49 // get an accessor for .message that constructs a descriptive error | 45 // get an accessor for .message that constructs a descriptive error |
| 50 // message on access. | 46 // message on access. |
| 51 var kAddMessageAccessorsMarker = { }; | 47 var kAddMessageAccessorsMarker = { }; |
| 52 | 48 |
| 49 var kMessages = 0; |
| 53 | 50 |
| 54 function GetInstanceName(cons) { | 51 var kReplacementMarkers = [ "%0", "%1", "%2", "%3" ]; |
| 55 if (cons.length == 0) { | 52 |
| 56 return ""; | 53 function FormatString(format, message) { |
| 54 var args = %MessageGetArguments(message); |
| 55 var result = ""; |
| 56 var arg_num = 0; |
| 57 for (var i = 0; i < format.length; i++) { |
| 58 var str = format[i]; |
| 59 for (arg_num = 0; arg_num < kReplacementMarkers.length; arg_num++) { |
| 60 if (format[i] !== kReplacementMarkers[arg_num]) continue; |
| 61 try { |
| 62 str = ToDetailString(args[arg_num]); |
| 63 } catch (e) { |
| 64 str = "#<error>"; |
| 65 } |
| 66 } |
| 67 result += str; |
| 57 } | 68 } |
| 58 var first = %StringToLowerCase(StringCharAt.call(cons, 0)); | 69 return result; |
| 59 if (kVowelSounds === 0) { | |
| 60 kVowelSounds = {a: true, e: true, i: true, o: true, u: true, y: true}; | |
| 61 kCapitalVowelSounds = {a: true, e: true, i: true, o: true, u: true, h: true, | |
| 62 f: true, l: true, m: true, n: true, r: true, s: true, x: true, y: true}; | |
| 63 } | |
| 64 var vowel_mapping = kVowelSounds; | |
| 65 if (cons.length > 1 && (StringCharAt.call(cons, 0) != first)) { | |
| 66 // First char is upper case | |
| 67 var second = %StringToLowerCase(StringCharAt.call(cons, 1)); | |
| 68 // Second char is upper case | |
| 69 if (StringCharAt.call(cons, 1) != second) { | |
| 70 vowel_mapping = kCapitalVowelSounds; | |
| 71 } | |
| 72 } | |
| 73 var s = vowel_mapping[first] ? "an " : "a "; | |
| 74 return s + cons; | |
| 75 } | 70 } |
| 76 | 71 |
| 77 | 72 |
| 78 var kMessages = 0; | 73 // To check if something is a native error we need to check the |
| 74 // concrete native error types. It is not enough to check "obj |
| 75 // instanceof $Error" because user code can replace |
| 76 // NativeError.prototype.__proto__. User code cannot replace |
| 77 // NativeError.prototype though and therefore this is a safe test. |
| 78 function IsNativeErrorObject(obj) { |
| 79 return (obj instanceof $Error) || |
| 80 (obj instanceof $EvalError) || |
| 81 (obj instanceof $RangeError) || |
| 82 (obj instanceof $ReferenceError) || |
| 83 (obj instanceof $SyntaxError) || |
| 84 (obj instanceof $TypeError) || |
| 85 (obj instanceof $URIError); |
| 86 } |
| 79 | 87 |
| 80 | 88 |
| 81 function FormatString(format, args) { | 89 // When formatting internally created error messages, do not |
| 82 var result = format; | 90 // invoke overwritten error toString methods but explicitly use |
| 83 for (var i = 0; i < args.length; i++) { | 91 // the error to string method. This is to avoid leaking error |
| 84 var str; | 92 // objects between script tags in a browser setting. |
| 85 try { str = ToDetailString(args[i]); } | 93 function ToStringCheckErrorObject(obj) { |
| 86 catch (e) { str = "#<error>"; } | 94 if (IsNativeErrorObject(obj)) { |
| 87 result = ArrayJoin.call(StringSplit.call(result, "%" + i), str); | 95 return %_CallFunction(obj, errorToString); |
| 96 } else { |
| 97 return ToString(obj); |
| 88 } | 98 } |
| 89 return result; | |
| 90 } | 99 } |
| 91 | 100 |
| 92 | 101 |
| 93 function ToDetailString(obj) { | 102 function ToDetailString(obj) { |
| 94 if (obj != null && IS_OBJECT(obj) && obj.toString === $Object.prototype.toStri
ng) { | 103 if (obj != null && IS_OBJECT(obj) && obj.toString === $Object.prototype.toStri
ng) { |
| 95 var constructor = obj.constructor; | 104 var constructor = obj.constructor; |
| 96 if (!constructor) return ToString(obj); | 105 if (!constructor) return ToStringCheckErrorObject(obj); |
| 97 var constructorName = constructor.name; | 106 var constructorName = constructor.name; |
| 98 if (!constructorName) return ToString(obj); | 107 if (!constructorName || !IS_STRING(constructorName)) { |
| 99 return "#<" + GetInstanceName(constructorName) + ">"; | 108 return ToStringCheckErrorObject(obj); |
| 109 } |
| 110 return "#<" + constructorName + ">"; |
| 100 } else { | 111 } else { |
| 101 return ToString(obj); | 112 return ToStringCheckErrorObject(obj); |
| 102 } | 113 } |
| 103 } | 114 } |
| 104 | 115 |
| 105 | 116 |
| 106 function MakeGenericError(constructor, type, args) { | 117 function MakeGenericError(constructor, type, args) { |
| 107 if (IS_UNDEFINED(args)) { | 118 if (IS_UNDEFINED(args)) { |
| 108 args = []; | 119 args = []; |
| 109 } | 120 } |
| 110 var e = new constructor(kAddMessageAccessorsMarker); | 121 var e = new constructor(kAddMessageAccessorsMarker); |
| 111 e.type = type; | 122 e.type = type; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 123 // Script objects can only be created by the VM. | 134 // Script objects can only be created by the VM. |
| 124 throw new $Error("Not supported"); | 135 throw new $Error("Not supported"); |
| 125 }); | 136 }); |
| 126 | 137 |
| 127 | 138 |
| 128 // Helper functions; called from the runtime system. | 139 // Helper functions; called from the runtime system. |
| 129 function FormatMessage(message) { | 140 function FormatMessage(message) { |
| 130 if (kMessages === 0) { | 141 if (kMessages === 0) { |
| 131 kMessages = { | 142 kMessages = { |
| 132 // Error | 143 // Error |
| 133 cyclic_proto: "Cyclic __proto__ value", | 144 cyclic_proto: ["Cyclic __proto__ value"], |
| 134 // TypeError | 145 // TypeError |
| 135 unexpected_token: "Unexpected token %0", | 146 unexpected_token: ["Unexpected token ", "%0"], |
| 136 unexpected_token_number: "Unexpected number", | 147 unexpected_token_number: ["Unexpected number"], |
| 137 unexpected_token_string: "Unexpected string", | 148 unexpected_token_string: ["Unexpected string"], |
| 138 unexpected_token_identifier: "Unexpected identifier", | 149 unexpected_token_identifier: ["Unexpected identifier"], |
| 139 unexpected_eos: "Unexpected end of input", | 150 unexpected_strict_reserved: ["Unexpected strict mode reserved word"], |
| 140 malformed_regexp: "Invalid regular expression: /%0/: %1", | 151 unexpected_eos: ["Unexpected end of input"], |
| 141 unterminated_regexp: "Invalid regular expression: missing /", | 152 malformed_regexp: ["Invalid regular expression: /", "%0", "/:
", "%1"], |
| 142 regexp_flags: "Cannot supply flags when constructing one R
egExp from another", | 153 unterminated_regexp: ["Invalid regular expression: missing /"], |
| 143 incompatible_method_receiver: "Method %0 called on incompatible receiver %
1", | 154 regexp_flags: ["Cannot supply flags when constructing one
RegExp from another"], |
| 144 invalid_lhs_in_assignment: "Invalid left-hand side in assignment", | 155 incompatible_method_receiver: ["Method ", "%0", " called on incompatible r
eceiver ", "%1"], |
| 145 invalid_lhs_in_for_in: "Invalid left-hand side in for-in", | 156 invalid_lhs_in_assignment: ["Invalid left-hand side in assignment"], |
| 146 invalid_lhs_in_postfix_op: "Invalid left-hand side expression in postfi
x operation", | 157 invalid_lhs_in_for_in: ["Invalid left-hand side in for-in"], |
| 147 invalid_lhs_in_prefix_op: "Invalid left-hand side expression in prefix
operation", | 158 invalid_lhs_in_postfix_op: ["Invalid left-hand side expression in postf
ix operation"], |
| 148 multiple_defaults_in_switch: "More than one default clause in switch stat
ement", | 159 invalid_lhs_in_prefix_op: ["Invalid left-hand side expression in prefi
x operation"], |
| 149 newline_after_throw: "Illegal newline after throw", | 160 multiple_defaults_in_switch: ["More than one default clause in switch sta
tement"], |
| 150 redeclaration: "%0 '%1' has already been declared", | 161 newline_after_throw: ["Illegal newline after throw"], |
| 151 no_catch_or_finally: "Missing catch or finally after try", | 162 redeclaration: ["%0", " '", "%1", "' has already been decla
red"], |
| 152 unknown_label: "Undefined label '%0'", | 163 no_catch_or_finally: ["Missing catch or finally after try"], |
| 153 uncaught_exception: "Uncaught %0", | 164 unknown_label: ["Undefined label '", "%0", "'"], |
| 154 stack_trace: "Stack Trace:\n%0", | 165 uncaught_exception: ["Uncaught ", "%0"], |
| 155 called_non_callable: "%0 is not a function", | 166 stack_trace: ["Stack Trace:\n", "%0"], |
| 156 undefined_method: "Object %1 has no method '%0'", | 167 called_non_callable: ["%0", " is not a function"], |
| 157 property_not_function: "Property '%0' of object %1 is not a functio
n", | 168 undefined_method: ["Object ", "%1", " has no method '", "%0",
"'"], |
| 158 cannot_convert_to_primitive: "Cannot convert object to primitive value", | 169 property_not_function: ["Property '", "%0", "' of object ", "%1", "
is not a function"], |
| 159 not_constructor: "%0 is not a constructor", | 170 cannot_convert_to_primitive: ["Cannot convert object to primitive value"]
, |
| 160 not_defined: "%0 is not defined", | 171 not_constructor: ["%0", " is not a constructor"], |
| 161 non_object_property_load: "Cannot read property '%0' of %1", | 172 not_defined: ["%0", " is not defined"], |
| 162 non_object_property_store: "Cannot set property '%0' of %1", | 173 non_object_property_load: ["Cannot read property '", "%0", "' of ", "%
1"], |
| 163 non_object_property_call: "Cannot call method '%0' of %1", | 174 non_object_property_store: ["Cannot set property '", "%0", "' of ", "%1
"], |
| 164 with_expression: "%0 has no properties", | 175 non_object_property_call: ["Cannot call method '", "%0", "' of ", "%1"
], |
| 165 illegal_invocation: "Illegal invocation", | 176 with_expression: ["%0", " has no properties"], |
| 166 no_setter_in_callback: "Cannot set property %0 of %1 which has only
a getter", | 177 illegal_invocation: ["Illegal invocation"], |
| 167 apply_non_function: "Function.prototype.apply was called on %0,
which is a %1 and not a function", | 178 no_setter_in_callback: ["Cannot set property ", "%0", " of ", "%1",
" which has only a getter"], |
| 168 apply_wrong_args: "Function.prototype.apply: Arguments list ha
s wrong type", | 179 apply_non_function: ["Function.prototype.apply was called on ",
"%0", ", which is a ", "%1", " and not a function"], |
| 169 invalid_in_operator_use: "Cannot use 'in' operator to search for '%0'
in %1", | 180 apply_wrong_args: ["Function.prototype.apply: Arguments list h
as wrong type"], |
| 170 instanceof_function_expected: "Expecting a function in instanceof check, b
ut got %0", | 181 invalid_in_operator_use: ["Cannot use 'in' operator to search for '",
"%0", "' in ", "%1"], |
| 171 instanceof_nonobject_proto: "Function has non-object prototype '%0' in i
nstanceof check", | 182 instanceof_function_expected: ["Expecting a function in instanceof check,
but got ", "%0"], |
| 172 null_to_object: "Cannot convert null to object", | 183 instanceof_nonobject_proto: ["Function has non-object prototype '", "%0"
, "' in instanceof check"], |
| 173 reduce_no_initial: "Reduce of empty array with no initial value
", | 184 null_to_object: ["Cannot convert null to object"], |
| 174 getter_must_be_callable: "Getter must be a function: %0", | 185 reduce_no_initial: ["Reduce of empty array with no initial valu
e"], |
| 175 setter_must_be_callable: "Setter must be a function: %0", | 186 getter_must_be_callable: ["Getter must be a function: ", "%0"], |
| 176 value_and_accessor: "Invalid property. A property cannot both h
ave accessors and be writable or have a value: %0", | 187 setter_must_be_callable: ["Setter must be a function: ", "%0"], |
| 177 proto_object_or_null: "Object prototype may only be an Object or n
ull", | 188 value_and_accessor: ["Invalid property. A property cannot both
have accessors and be writable or have a value: ", "%0"], |
| 178 property_desc_object: "Property description must be an object: %0"
, | 189 proto_object_or_null: ["Object prototype may only be an Object or
null"], |
| 179 redefine_disallowed: "Cannot redefine property: %0", | 190 property_desc_object: ["Property description must be an object: ",
"%0"], |
| 180 define_disallowed: "Cannot define property, object is not exten
sible: %0", | 191 redefine_disallowed: ["Cannot redefine property: ", "%0"], |
| 192 define_disallowed: ["Cannot define property, object is not exte
nsible: ", "%0"], |
| 181 // RangeError | 193 // RangeError |
| 182 invalid_array_length: "Invalid array length", | 194 invalid_array_length: ["Invalid array length"], |
| 183 stack_overflow: "Maximum call stack size exceeded", | 195 stack_overflow: ["Maximum call stack size exceeded"], |
| 184 // SyntaxError | 196 // SyntaxError |
| 185 unable_to_parse: "Parse error", | 197 unable_to_parse: ["Parse error"], |
| 186 duplicate_regexp_flag: "Duplicate RegExp flag %0", | 198 duplicate_regexp_flag: ["Duplicate RegExp flag ", "%0"], |
| 187 invalid_regexp: "Invalid RegExp pattern /%0/", | 199 invalid_regexp: ["Invalid RegExp pattern /", "%0", "/"], |
| 188 illegal_break: "Illegal break statement", | 200 illegal_break: ["Illegal break statement"], |
| 189 illegal_continue: "Illegal continue statement", | 201 illegal_continue: ["Illegal continue statement"], |
| 190 illegal_return: "Illegal return statement", | 202 illegal_return: ["Illegal return statement"], |
| 191 error_loading_debugger: "Error loading debugger", | 203 error_loading_debugger: ["Error loading debugger"], |
| 192 no_input_to_regexp: "No input to %0", | 204 no_input_to_regexp: ["No input to ", "%0"], |
| 193 invalid_json: "String '%0' is not valid JSON", | 205 invalid_json: ["String '", "%0", "' is not valid JSON"], |
| 194 circular_structure: "Converting circular structure to JSON", | 206 circular_structure: ["Converting circular structure to JSON"], |
| 195 obj_ctor_property_non_object: "Object.%0 called on non-object", | 207 obj_ctor_property_non_object: ["Object.", "%0", " called on non-object"], |
| 196 array_indexof_not_defined: "Array.getIndexOf: Argument undefined", | 208 array_indexof_not_defined: ["Array.getIndexOf: Argument undefined"], |
| 197 object_not_extensible: "Can't add property %0, object is not extens
ible", | 209 object_not_extensible: ["Can't add property ", "%0", ", object is n
ot extensible"], |
| 198 illegal_access: "Illegal access", | 210 illegal_access: ["Illegal access"], |
| 199 invalid_preparser_data: "Invalid preparser data for function %0" | 211 invalid_preparser_data: ["Invalid preparser data for function ", "%0
"], |
| 212 strict_mode_with: ["Strict mode code may not include a with st
atement"], |
| 213 strict_catch_variable: ["Catch variable may not be eval or argument
s in strict mode"], |
| 214 too_many_parameters: ["Too many parameters in function definition
"], |
| 215 strict_param_name: ["Parameter name eval or arguments is not al
lowed in strict mode"], |
| 216 strict_param_dupe: ["Strict mode function may not have duplicat
e parameter names"], |
| 217 strict_var_name: ["Variable name may not be eval or arguments
in strict mode"], |
| 218 strict_function_name: ["Function name may not be eval or arguments
in strict mode"], |
| 219 strict_octal_literal: ["Octal literals are not allowed in strict m
ode."], |
| 220 strict_duplicate_property: ["Duplicate data property in object literal
not allowed in strict mode"], |
| 221 accessor_data_property: ["Object literal may not have data and acces
sor property with the same name"], |
| 222 accessor_get_set: ["Object literal may not have multiple get/s
et accessors with the same name"], |
| 223 strict_lhs_assignment: ["Assignment to eval or arguments is not all
owed in strict mode"], |
| 224 strict_lhs_postfix: ["Postfix increment/decrement may not have e
val or arguments operand in strict mode"], |
| 225 strict_lhs_prefix: ["Prefix increment/decrement may not have ev
al or arguments operand in strict mode"], |
| 226 strict_reserved_word: ["Use of future reserved word in strict mode
"], |
| 227 strict_delete: ["Delete of an unqualified identifier in str
ict mode."], |
| 228 strict_delete_property: ["Cannot delete property '", "%0", "' of ",
"%1"], |
| 200 }; | 229 }; |
| 201 } | 230 } |
| 202 var format = kMessages[message.type]; | 231 var message_type = %MessageGetType(message); |
| 203 if (!format) return "<unknown message " + message.type + ">"; | 232 var format = kMessages[message_type]; |
| 204 return FormatString(format, message.args); | 233 if (!format) return "<unknown message " + message_type + ">"; |
| 234 return FormatString(format, message); |
| 205 } | 235 } |
| 206 | 236 |
| 207 | 237 |
| 208 function GetLineNumber(message) { | 238 function GetLineNumber(message) { |
| 209 if (message.startPos == -1) return kNoLineNumberInfo; | 239 var start_position = %MessageGetStartPosition(message); |
| 210 var location = message.script.locationFromPosition(message.startPos, true); | 240 if (start_position == -1) return kNoLineNumberInfo; |
| 241 var script = %MessageGetScript(message); |
| 242 var location = script.locationFromPosition(start_position, true); |
| 211 if (location == null) return kNoLineNumberInfo; | 243 if (location == null) return kNoLineNumberInfo; |
| 212 return location.line + 1; | 244 return location.line + 1; |
| 213 } | 245 } |
| 214 | 246 |
| 215 | 247 |
| 216 // Returns the source code line containing the given source | 248 // Returns the source code line containing the given source |
| 217 // position, or the empty string if the position is invalid. | 249 // position, or the empty string if the position is invalid. |
| 218 function GetSourceLine(message) { | 250 function GetSourceLine(message) { |
| 219 var location = message.script.locationFromPosition(message.startPos, true); | 251 var script = %MessageGetScript(message); |
| 252 var start_position = %MessageGetStartPosition(message); |
| 253 var location = script.locationFromPosition(start_position, true); |
| 220 if (location == null) return ""; | 254 if (location == null) return ""; |
| 221 location.restrict(); | 255 location.restrict(); |
| 222 return location.sourceText(); | 256 return location.sourceText(); |
| 223 } | 257 } |
| 224 | 258 |
| 225 | 259 |
| 226 function MakeTypeError(type, args) { | 260 function MakeTypeError(type, args) { |
| 227 return MakeGenericError($TypeError, type, args); | 261 return MakeGenericError($TypeError, type, args); |
| 228 } | 262 } |
| 229 | 263 |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 var i = (lower + upper) >> 1; | 312 var i = (lower + upper) >> 1; |
| 279 | 313 |
| 280 if (position > line_ends[i]) { | 314 if (position > line_ends[i]) { |
| 281 lower = i + 1; | 315 lower = i + 1; |
| 282 } else if (position <= line_ends[i - 1]) { | 316 } else if (position <= line_ends[i - 1]) { |
| 283 upper = i - 1; | 317 upper = i - 1; |
| 284 } else { | 318 } else { |
| 285 return i; | 319 return i; |
| 286 } | 320 } |
| 287 } | 321 } |
| 322 |
| 288 return -1; | 323 return -1; |
| 289 } | 324 } |
| 290 | 325 |
| 291 /** | 326 /** |
| 292 * Get information on a specific source position. | 327 * Get information on a specific source position. |
| 293 * @param {number} position The source position | 328 * @param {number} position The source position |
| 294 * @param {boolean} include_resource_offset Set to true to have the resource | 329 * @param {boolean} include_resource_offset Set to true to have the resource |
| 295 * offset added to the location | 330 * offset added to the location |
| 296 * @return {SourceLocation} | 331 * @return {SourceLocation} |
| 297 * If line is negative or not in the source null is returned. | 332 * If line is negative or not in the source null is returned. |
| 298 */ | 333 */ |
| 299 Script.prototype.locationFromPosition = function (position, | 334 Script.prototype.locationFromPosition = function (position, |
| 300 include_resource_offset) { | 335 include_resource_offset) { |
| 301 var line = this.lineFromPosition(position); | 336 var line = this.lineFromPosition(position); |
| 302 if (line == -1) return null; | 337 if (line == -1) return null; |
| 303 | 338 |
| 304 // Determine start, end and column. | 339 // Determine start, end and column. |
| 305 var line_ends = this.line_ends; | 340 var line_ends = this.line_ends; |
| 306 var start = line == 0 ? 0 : line_ends[line - 1] + 1; | 341 var start = line == 0 ? 0 : line_ends[line - 1] + 1; |
| 307 var end = line_ends[line]; | 342 var end = line_ends[line]; |
| 308 if (end > 0 && StringCharAt.call(this.source, end - 1) == '\r') end--; | 343 if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') end
--; |
| 309 var column = position - start; | 344 var column = position - start; |
| 310 | 345 |
| 311 // Adjust according to the offset within the resource. | 346 // Adjust according to the offset within the resource. |
| 312 if (include_resource_offset) { | 347 if (include_resource_offset) { |
| 313 line += this.line_offset; | 348 line += this.line_offset; |
| 314 if (line == this.line_offset) { | 349 if (line == this.line_offset) { |
| 315 column += this.column_offset; | 350 column += this.column_offset; |
| 316 } | 351 } |
| 317 } | 352 } |
| 318 | 353 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 | 448 |
| 414 // Check parameter. | 449 // Check parameter. |
| 415 if (line < 0 || this.lineCount() <= line) { | 450 if (line < 0 || this.lineCount() <= line) { |
| 416 return null; | 451 return null; |
| 417 } | 452 } |
| 418 | 453 |
| 419 // Return the source line. | 454 // Return the source line. |
| 420 var line_ends = this.line_ends; | 455 var line_ends = this.line_ends; |
| 421 var start = line == 0 ? 0 : line_ends[line - 1] + 1; | 456 var start = line == 0 ? 0 : line_ends[line - 1] + 1; |
| 422 var end = line_ends[line]; | 457 var end = line_ends[line]; |
| 423 return StringSubstring.call(this.source, start, end); | 458 return %_CallFunction(this.source, start, end, StringSubstring); |
| 424 } | 459 } |
| 425 | 460 |
| 426 | 461 |
| 427 /** | 462 /** |
| 428 * Returns the number of source lines. | 463 * Returns the number of source lines. |
| 429 * @return {number} | 464 * @return {number} |
| 430 * Number of source lines. | 465 * Number of source lines. |
| 431 */ | 466 */ |
| 432 Script.prototype.lineCount = function() { | 467 Script.prototype.lineCount = function() { |
| 433 // Return number of source lines. | 468 // Return number of source lines. |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 } | 576 } |
| 542 }; | 577 }; |
| 543 | 578 |
| 544 | 579 |
| 545 /** | 580 /** |
| 546 * Get the source text for a SourceLocation | 581 * Get the source text for a SourceLocation |
| 547 * @return {String} | 582 * @return {String} |
| 548 * Source text for this location. | 583 * Source text for this location. |
| 549 */ | 584 */ |
| 550 SourceLocation.prototype.sourceText = function () { | 585 SourceLocation.prototype.sourceText = function () { |
| 551 return StringSubstring.call(this.script.source, this.start, this.end); | 586 return %_CallFunction(this.script.source, this.start, this.end, StringSubstrin
g); |
| 552 }; | 587 }; |
| 553 | 588 |
| 554 | 589 |
| 555 /** | 590 /** |
| 556 * Class for a source slice. A source slice is a part of a script source with | 591 * Class for a source slice. A source slice is a part of a script source with |
| 557 * the following properties: | 592 * the following properties: |
| 558 * script : script object for the source | 593 * script : script object for the source |
| 559 * from_line : line number for the first line in the slice | 594 * from_line : line number for the first line in the slice |
| 560 * to_line : source line number for the last line in the slice | 595 * to_line : source line number for the last line in the slice |
| 561 * from_position : position of the first character in the slice | 596 * from_position : position of the first character in the slice |
| (...skipping 16 matching lines...) Expand all Loading... |
| 578 this.to_position = to_position; | 613 this.to_position = to_position; |
| 579 } | 614 } |
| 580 | 615 |
| 581 | 616 |
| 582 /** | 617 /** |
| 583 * Get the source text for a SourceSlice | 618 * Get the source text for a SourceSlice |
| 584 * @return {String} Source text for this slice. The last line will include | 619 * @return {String} Source text for this slice. The last line will include |
| 585 * the line terminating characters (if any) | 620 * the line terminating characters (if any) |
| 586 */ | 621 */ |
| 587 SourceSlice.prototype.sourceText = function () { | 622 SourceSlice.prototype.sourceText = function () { |
| 588 return StringSubstring.call(this.script.source, this.from_position, this.to_po
sition); | 623 return %_CallFunction(this.script.source, |
| 624 this.from_position, |
| 625 this.to_position, |
| 626 StringSubstring); |
| 589 }; | 627 }; |
| 590 | 628 |
| 591 | 629 |
| 592 // Returns the offset of the given position within the containing | 630 // Returns the offset of the given position within the containing |
| 593 // line. | 631 // line. |
| 594 function GetPositionInLine(message) { | 632 function GetPositionInLine(message) { |
| 595 var location = message.script.locationFromPosition(message.startPos, false); | 633 var script = %MessageGetScript(message); |
| 634 var start_position = %MessageGetStartPosition(message); |
| 635 var location = script.locationFromPosition(start_position, false); |
| 596 if (location == null) return -1; | 636 if (location == null) return -1; |
| 597 location.restrict(); | 637 location.restrict(); |
| 598 return message.startPos - location.start; | 638 return start_position - location.start; |
| 599 } | |
| 600 | |
| 601 | |
| 602 function ErrorMessage(type, args, startPos, endPos, script, stackTrace, | |
| 603 stackFrames) { | |
| 604 this.startPos = startPos; | |
| 605 this.endPos = endPos; | |
| 606 this.type = type; | |
| 607 this.args = args; | |
| 608 this.script = script; | |
| 609 this.stackTrace = stackTrace; | |
| 610 this.stackFrames = stackFrames; | |
| 611 } | |
| 612 | |
| 613 | |
| 614 function MakeMessage(type, args, startPos, endPos, script, stackTrace, | |
| 615 stackFrames) { | |
| 616 return new ErrorMessage(type, args, startPos, endPos, script, stackTrace, | |
| 617 stackFrames); | |
| 618 } | 639 } |
| 619 | 640 |
| 620 | 641 |
| 621 function GetStackTraceLine(recv, fun, pos, isGlobal) { | 642 function GetStackTraceLine(recv, fun, pos, isGlobal) { |
| 622 return FormatSourcePosition(new CallSite(recv, fun, pos)); | 643 return FormatSourcePosition(new CallSite(recv, fun, pos)); |
| 623 } | 644 } |
| 624 | 645 |
| 625 // ---------------------------------------------------------------------------- | 646 // ---------------------------------------------------------------------------- |
| 626 // Error implementation | 647 // Error implementation |
| 627 | 648 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 653 this.pos = pos; | 674 this.pos = pos; |
| 654 } | 675 } |
| 655 | 676 |
| 656 CallSite.prototype.getThis = function () { | 677 CallSite.prototype.getThis = function () { |
| 657 return this.receiver; | 678 return this.receiver; |
| 658 }; | 679 }; |
| 659 | 680 |
| 660 CallSite.prototype.getTypeName = function () { | 681 CallSite.prototype.getTypeName = function () { |
| 661 var constructor = this.receiver.constructor; | 682 var constructor = this.receiver.constructor; |
| 662 if (!constructor) | 683 if (!constructor) |
| 663 return $Object.prototype.toString.call(this.receiver); | 684 return %_CallFunction(this.receiver, ObjectToString); |
| 664 var constructorName = constructor.name; | 685 var constructorName = constructor.name; |
| 665 if (!constructorName) | 686 if (!constructorName) |
| 666 return $Object.prototype.toString.call(this.receiver); | 687 return %_CallFunction(this.receiver, ObjectToString); |
| 667 return constructorName; | 688 return constructorName; |
| 668 }; | 689 }; |
| 669 | 690 |
| 670 CallSite.prototype.isToplevel = function () { | 691 CallSite.prototype.isToplevel = function () { |
| 671 if (this.receiver == null) | 692 if (this.receiver == null) |
| 672 return true; | 693 return true; |
| 673 return IS_GLOBAL(this.receiver); | 694 return IS_GLOBAL(this.receiver); |
| 674 }; | 695 }; |
| 675 | 696 |
| 676 CallSite.prototype.isEval = function () { | 697 CallSite.prototype.isEval = function () { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 705 if (script && script.compilation_type == COMPILATION_TYPE_EVAL) | 726 if (script && script.compilation_type == COMPILATION_TYPE_EVAL) |
| 706 return "eval"; | 727 return "eval"; |
| 707 return null; | 728 return null; |
| 708 }; | 729 }; |
| 709 | 730 |
| 710 CallSite.prototype.getMethodName = function () { | 731 CallSite.prototype.getMethodName = function () { |
| 711 // See if we can find a unique property on the receiver that holds | 732 // See if we can find a unique property on the receiver that holds |
| 712 // this function. | 733 // this function. |
| 713 var ownName = this.fun.name; | 734 var ownName = this.fun.name; |
| 714 if (ownName && this.receiver && | 735 if (ownName && this.receiver && |
| 715 (ObjectLookupGetter.call(this.receiver, ownName) === this.fun || | 736 (%_CallFunction(this.receiver, ownName, ObjectLookupGetter) === this.fun |
| |
| 716 ObjectLookupSetter.call(this.receiver, ownName) === this.fun || | 737 %_CallFunction(this.receiver, ownName, ObjectLookupSetter) === this.fun |
| |
| 717 this.receiver[ownName] === this.fun)) { | 738 this.receiver[ownName] === this.fun)) { |
| 718 // To handle DontEnum properties we guess that the method has | 739 // To handle DontEnum properties we guess that the method has |
| 719 // the same name as the function. | 740 // the same name as the function. |
| 720 return ownName; | 741 return ownName; |
| 721 } | 742 } |
| 722 var name = null; | 743 var name = null; |
| 723 for (var prop in this.receiver) { | 744 for (var prop in this.receiver) { |
| 724 if (this.receiver.__lookupGetter__(prop) === this.fun || | 745 if (this.receiver.__lookupGetter__(prop) === this.fun || |
| 725 this.receiver.__lookupSetter__(prop) === this.fun || | 746 this.receiver.__lookupSetter__(prop) === this.fun || |
| 726 (!this.receiver.__lookupGetter__(prop) && this.receiver[prop] === this.f
un)) { | 747 (!this.receiver.__lookupGetter__(prop) && this.receiver[prop] === this.f
un)) { |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 936 // special not-a-true-error-but-close-enough object. | 957 // special not-a-true-error-but-close-enough object. |
| 937 function ErrorPrototype() {} | 958 function ErrorPrototype() {} |
| 938 %FunctionSetPrototype(ErrorPrototype, $Object.prototype); | 959 %FunctionSetPrototype(ErrorPrototype, $Object.prototype); |
| 939 %FunctionSetInstanceClassName(ErrorPrototype, 'Error'); | 960 %FunctionSetInstanceClassName(ErrorPrototype, 'Error'); |
| 940 %FunctionSetPrototype(f, new ErrorPrototype()); | 961 %FunctionSetPrototype(f, new ErrorPrototype()); |
| 941 } else { | 962 } else { |
| 942 %FunctionSetPrototype(f, new $Error()); | 963 %FunctionSetPrototype(f, new $Error()); |
| 943 } | 964 } |
| 944 %FunctionSetInstanceClassName(f, 'Error'); | 965 %FunctionSetInstanceClassName(f, 'Error'); |
| 945 %SetProperty(f.prototype, 'constructor', f, DONT_ENUM); | 966 %SetProperty(f.prototype, 'constructor', f, DONT_ENUM); |
| 946 f.prototype.name = name; | 967 // The name property on the prototype of error objects is not |
| 968 // specified as being read-one and dont-delete. However, allowing |
| 969 // overwriting allows leaks of error objects between script blocks |
| 970 // in the same context in a browser setting. Therefore we fix the |
| 971 // name. |
| 972 %SetProperty(f.prototype, "name", name, READ_ONLY | DONT_DELETE); |
| 947 %SetCode(f, function(m) { | 973 %SetCode(f, function(m) { |
| 948 if (%_IsConstructCall()) { | 974 if (%_IsConstructCall()) { |
| 975 // Define all the expected properties directly on the error |
| 976 // object. This avoids going through getters and setters defined |
| 977 // on prototype objects. |
| 978 %IgnoreAttributesAndSetProperty(this, 'stack', void 0); |
| 979 %IgnoreAttributesAndSetProperty(this, 'arguments', void 0); |
| 980 %IgnoreAttributesAndSetProperty(this, 'type', void 0); |
| 949 if (m === kAddMessageAccessorsMarker) { | 981 if (m === kAddMessageAccessorsMarker) { |
| 982 // DefineOneShotAccessor always inserts a message property and |
| 983 // ignores setters. |
| 950 DefineOneShotAccessor(this, 'message', function (obj) { | 984 DefineOneShotAccessor(this, 'message', function (obj) { |
| 951 return FormatMessage({type: obj.type, args: obj.arguments}); | 985 return FormatMessage(%NewMessageObject(obj.type, obj.arguments)); |
| 952 }); | 986 }); |
| 953 } else if (!IS_UNDEFINED(m)) { | 987 } else if (!IS_UNDEFINED(m)) { |
| 954 this.message = ToString(m); | 988 %IgnoreAttributesAndSetProperty(this, 'message', ToString(m)); |
| 955 } | 989 } |
| 956 captureStackTrace(this, f); | 990 captureStackTrace(this, f); |
| 957 } else { | 991 } else { |
| 958 return new f(m); | 992 return new f(m); |
| 959 } | 993 } |
| 960 }); | 994 }); |
| 961 } | 995 } |
| 962 | 996 |
| 963 function captureStackTrace(obj, cons_opt) { | 997 function captureStackTrace(obj, cons_opt) { |
| 964 var stackTraceLimit = $Error.stackTraceLimit; | 998 var stackTraceLimit = $Error.stackTraceLimit; |
| 965 if (!stackTraceLimit) return; | 999 if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return; |
| 966 if (stackTraceLimit < 0 || stackTraceLimit > 10000) | 1000 if (stackTraceLimit < 0 || stackTraceLimit > 10000) |
| 967 stackTraceLimit = 10000; | 1001 stackTraceLimit = 10000; |
| 968 var raw_stack = %CollectStackTrace(cons_opt ? cons_opt : captureStackTrace, | 1002 var raw_stack = %CollectStackTrace(cons_opt |
| 969 stackTraceLimit); | 1003 ? cons_opt |
| 1004 : captureStackTrace, stackTraceLimit); |
| 970 DefineOneShotAccessor(obj, 'stack', function (obj) { | 1005 DefineOneShotAccessor(obj, 'stack', function (obj) { |
| 971 return FormatRawStackTrace(obj, raw_stack); | 1006 return FormatRawStackTrace(obj, raw_stack); |
| 972 }); | 1007 }); |
| 973 }; | 1008 }; |
| 974 | 1009 |
| 975 $Math.__proto__ = global.Object.prototype; | 1010 $Math.__proto__ = global.Object.prototype; |
| 976 | 1011 |
| 977 DefineError(function Error() { }); | 1012 DefineError(function Error() { }); |
| 978 DefineError(function TypeError() { }); | 1013 DefineError(function TypeError() { }); |
| 979 DefineError(function RangeError() { }); | 1014 DefineError(function RangeError() { }); |
| 980 DefineError(function SyntaxError() { }); | 1015 DefineError(function SyntaxError() { }); |
| 981 DefineError(function ReferenceError() { }); | 1016 DefineError(function ReferenceError() { }); |
| 982 DefineError(function EvalError() { }); | 1017 DefineError(function EvalError() { }); |
| 983 DefineError(function URIError() { }); | 1018 DefineError(function URIError() { }); |
| 984 | 1019 |
| 985 $Error.captureStackTrace = captureStackTrace; | 1020 $Error.captureStackTrace = captureStackTrace; |
| 986 | 1021 |
| 987 // Setup extra properties of the Error.prototype object. | 1022 // Setup extra properties of the Error.prototype object. |
| 988 $Error.prototype.message = ''; | 1023 $Error.prototype.message = ''; |
| 989 | 1024 |
| 990 %SetProperty($Error.prototype, 'toString', function toString() { | 1025 // Global list of error objects visited during errorToString. This is |
| 991 var type = this.type; | 1026 // used to detect cycles in error toString formatting. |
| 992 if (type && !this.hasOwnProperty("message")) { | 1027 var visited_errors = new $Array(); |
| 993 return this.name + ": " + FormatMessage({ type: type, args: this.arguments }
); | 1028 var cyclic_error_marker = new $Object(); |
| 1029 |
| 1030 function errorToStringDetectCycle() { |
| 1031 if (!%PushIfAbsent(visited_errors, this)) throw cyclic_error_marker; |
| 1032 try { |
| 1033 var type = this.type; |
| 1034 if (type && !%_CallFunction(this, "message", ObjectHasOwnProperty)) { |
| 1035 var formatted = FormatMessage(%NewMessageObject(type, this.arguments)); |
| 1036 return this.name + ": " + formatted; |
| 1037 } |
| 1038 var message = %_CallFunction(this, "message", ObjectHasOwnProperty) |
| 1039 ? (": " + this.message) |
| 1040 : ""; |
| 1041 return this.name + message; |
| 1042 } finally { |
| 1043 visited_errors.length = visited_errors.length - 1; |
| 994 } | 1044 } |
| 995 var message = this.message; | 1045 } |
| 996 return this.name + (message ? (": " + message) : ""); | |
| 997 }, DONT_ENUM); | |
| 998 | 1046 |
| 1047 function errorToString() { |
| 1048 // This helper function is needed because access to properties on |
| 1049 // the builtins object do not work inside of a catch clause. |
| 1050 function isCyclicErrorMarker(o) { return o === cyclic_error_marker; } |
| 1051 |
| 1052 try { |
| 1053 return %_CallFunction(this, errorToStringDetectCycle); |
| 1054 } catch(e) { |
| 1055 // If this error message was encountered already return the empty |
| 1056 // string for it instead of recursively formatting it. |
| 1057 if (isCyclicErrorMarker(e)) return ''; |
| 1058 else throw e; |
| 1059 } |
| 1060 } |
| 1061 |
| 1062 %FunctionSetName(errorToString, 'toString'); |
| 1063 %SetProperty($Error.prototype, 'toString', errorToString, DONT_ENUM); |
| 999 | 1064 |
| 1000 // Boilerplate for exceptions for stack overflows. Used from | 1065 // Boilerplate for exceptions for stack overflows. Used from |
| 1001 // Top::StackOverflow(). | 1066 // Top::StackOverflow(). |
| 1002 const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); | 1067 const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); |
| OLD | NEW |