| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // ------------------------------------------------------------------- | 5 // ------------------------------------------------------------------- |
| 6 | 6 |
| 7 var $errorToString; |
| 8 var $formatMessage; |
| 9 var $getStackTraceLine; |
| 10 var $messageGetPositionInLine; |
| 11 var $messageGetLineNumber; |
| 12 var $messageGetSourceLine; |
| 13 var $stackOverflowBoilerplate; |
| 14 var $stackTraceSymbol; |
| 15 var $toDetailString; |
| 16 var $Error; |
| 17 var $EvalError; |
| 18 var $RangeError; |
| 19 var $ReferenceError; |
| 20 var $SyntaxError; |
| 21 var $TypeError; |
| 22 var $URIError; |
| 23 var MakeError; |
| 24 var MakeEvalError; |
| 25 var MakeRangeError; |
| 26 var MakeReferenceError; |
| 27 var MakeSyntaxError; |
| 28 var MakeTypeError; |
| 29 var MakeURIError; |
| 30 var MakeReferenceErrorEmbedded; |
| 31 var MakeSyntaxErrorEmbedded; |
| 32 var MakeTypeErrorEmbedded; |
| 33 |
| 34 (function() { |
| 35 |
| 36 %CheckIsBootstrapping(); |
| 37 |
| 38 var GlobalObject = global.Object; |
| 39 var GlobalError; |
| 40 var GlobalTypeError; |
| 41 var GlobalRangeError; |
| 42 var GlobalURIError; |
| 43 var GlobalSyntaxError; |
| 44 var GlobalReferenceError; |
| 45 var GlobalEvalError; |
| 46 |
| 47 // ------------------------------------------------------------------- |
| 48 |
| 7 var kMessages = { | 49 var kMessages = { |
| 8 // Error | 50 // Error |
| 9 constructor_is_generator: ["Class constructor may not be a generator"], | 51 constructor_is_generator: ["Class constructor may not be a generator"], |
| 10 constructor_is_accessor: ["Class constructor may not be an accessor"], | 52 constructor_is_accessor: ["Class constructor may not be an accessor"], |
| 11 // TypeError | 53 // TypeError |
| 12 unexpected_token: ["Unexpected token ", "%0"], | 54 unexpected_token: ["Unexpected token ", "%0"], |
| 13 unexpected_token_number: ["Unexpected number"], | 55 unexpected_token_number: ["Unexpected number"], |
| 14 unexpected_token_string: ["Unexpected string"], | 56 unexpected_token_string: ["Unexpected string"], |
| 15 unexpected_token_identifier: ["Unexpected identifier"], | 57 unexpected_token_identifier: ["Unexpected identifier"], |
| 16 unexpected_reserved: ["Unexpected reserved word"], | 58 unexpected_reserved: ["Unexpected reserved word"], |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 227 } | 269 } |
| 228 if (CanBeSafelyTreatedAsAnErrorObject(obj)) { | 270 if (CanBeSafelyTreatedAsAnErrorObject(obj)) { |
| 229 return %_CallFunction(obj, ErrorToString); | 271 return %_CallFunction(obj, ErrorToString); |
| 230 } | 272 } |
| 231 | 273 |
| 232 return %_CallFunction(obj, NoSideEffectsObjectToString); | 274 return %_CallFunction(obj, NoSideEffectsObjectToString); |
| 233 } | 275 } |
| 234 | 276 |
| 235 // To determine whether we can safely stringify an object using ErrorToString | 277 // To determine whether we can safely stringify an object using ErrorToString |
| 236 // without the risk of side-effects, we need to check whether the object is | 278 // without the risk of side-effects, we need to check whether the object is |
| 237 // either an instance of a native error type (via '%_ClassOf'), or has $Error | 279 // either an instance of a native error type (via '%_ClassOf'), or has Error |
| 238 // in its prototype chain and hasn't overwritten 'toString' with something | 280 // in its prototype chain and hasn't overwritten 'toString' with something |
| 239 // strange and unusual. | 281 // strange and unusual. |
| 240 function CanBeSafelyTreatedAsAnErrorObject(obj) { | 282 function CanBeSafelyTreatedAsAnErrorObject(obj) { |
| 241 switch (%_ClassOf(obj)) { | 283 switch (%_ClassOf(obj)) { |
| 242 case 'Error': | 284 case 'Error': |
| 243 case 'EvalError': | 285 case 'EvalError': |
| 244 case 'RangeError': | 286 case 'RangeError': |
| 245 case 'ReferenceError': | 287 case 'ReferenceError': |
| 246 case 'SyntaxError': | 288 case 'SyntaxError': |
| 247 case 'TypeError': | 289 case 'TypeError': |
| 248 case 'URIError': | 290 case 'URIError': |
| 249 return true; | 291 return true; |
| 250 } | 292 } |
| 251 | 293 |
| 252 var objToString = %GetDataProperty(obj, "toString"); | 294 var objToString = %GetDataProperty(obj, "toString"); |
| 253 return obj instanceof $Error && objToString === ErrorToString; | 295 return obj instanceof GlobalError && objToString === ErrorToString; |
| 254 } | 296 } |
| 255 | 297 |
| 256 | 298 |
| 257 // When formatting internally created error messages, do not | 299 // When formatting internally created error messages, do not |
| 258 // invoke overwritten error toString methods but explicitly use | 300 // invoke overwritten error toString methods but explicitly use |
| 259 // the error to string method. This is to avoid leaking error | 301 // the error to string method. This is to avoid leaking error |
| 260 // objects between script tags in a browser setting. | 302 // objects between script tags in a browser setting. |
| 261 function ToStringCheckErrorObject(obj) { | 303 function ToStringCheckErrorObject(obj) { |
| 262 if (CanBeSafelyTreatedAsAnErrorObject(obj)) { | 304 if (CanBeSafelyTreatedAsAnErrorObject(obj)) { |
| 263 return %_CallFunction(obj, ErrorToString); | 305 return %_CallFunction(obj, ErrorToString); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 // Returns the source code line containing the given source | 373 // Returns the source code line containing the given source |
| 332 // position, or the empty string if the position is invalid. | 374 // position, or the empty string if the position is invalid. |
| 333 function GetSourceLine(message) { | 375 function GetSourceLine(message) { |
| 334 var script = %MessageGetScript(message); | 376 var script = %MessageGetScript(message); |
| 335 var start_position = %MessageGetStartPosition(message); | 377 var start_position = %MessageGetStartPosition(message); |
| 336 var location = script.locationFromPosition(start_position, true); | 378 var location = script.locationFromPosition(start_position, true); |
| 337 if (location == null) return ""; | 379 if (location == null) return ""; |
| 338 return location.sourceText(); | 380 return location.sourceText(); |
| 339 } | 381 } |
| 340 | 382 |
| 341 | |
| 342 function MakeError(type, arg0, arg1, arg2) { | |
| 343 return MakeGenericError($Error, type, arg0, arg1, arg2); | |
| 344 } | |
| 345 | |
| 346 | |
| 347 function MakeTypeError(type, arg0, arg1, arg2) { | |
| 348 return MakeGenericError($TypeError, type, arg0, arg1, arg2); | |
| 349 } | |
| 350 | |
| 351 | |
| 352 function MakeRangeError(type, arg0, arg1, arg2) { | |
| 353 return MakeGenericError($RangeError, type, arg0, arg1, arg2); | |
| 354 } | |
| 355 | |
| 356 | |
| 357 function MakeSyntaxError(type, arg0, arg1, arg2) { | |
| 358 return MakeGenericError($SyntaxError, type, arg0, arg1, arg2); | |
| 359 } | |
| 360 | |
| 361 | |
| 362 function MakeReferenceError(type, arg0, arg1, arg2) { | |
| 363 return MakeGenericError($ReferenceError, type, arg0, arg1, arg2); | |
| 364 } | |
| 365 | |
| 366 | |
| 367 function MakeEvalError(type, arg0, arg1, arg2) { | |
| 368 return MakeGenericError($EvalError, type, arg0, arg1, arg2); | |
| 369 } | |
| 370 | |
| 371 | |
| 372 function MakeURIError() { | |
| 373 return MakeGenericError($URIError, kURIMalformed); | |
| 374 } | |
| 375 | |
| 376 // The embedded versions are called from unoptimized code, with embedded | |
| 377 // arguments. Those arguments cannot be arrays, which are context-dependent. | |
| 378 function MakeTypeErrorEmbedded(type, arg) { | |
| 379 return MakeGenericError($TypeError, type, [arg]); | |
| 380 } | |
| 381 | |
| 382 | |
| 383 function MakeSyntaxErrorEmbedded(type, arg) { | |
| 384 return MakeGenericError($SyntaxError, type, [arg]); | |
| 385 } | |
| 386 | |
| 387 | |
| 388 function MakeReferenceErrorEmbedded(type, arg) { | |
| 389 return MakeGenericError($ReferenceError, type, [arg]); | |
| 390 } | |
| 391 | |
| 392 /** | 383 /** |
| 393 * Find a line number given a specific source position. | 384 * Find a line number given a specific source position. |
| 394 * @param {number} position The source position. | 385 * @param {number} position The source position. |
| 395 * @return {number} 0 if input too small, -1 if input too large, | 386 * @return {number} 0 if input too small, -1 if input too large, |
| 396 else the line number. | 387 else the line number. |
| 397 */ | 388 */ |
| 398 function ScriptLineFromPosition(position) { | 389 function ScriptLineFromPosition(position) { |
| 399 var lower = 0; | 390 var lower = 0; |
| 400 var upper = this.lineCount() - 1; | 391 var upper = this.lineCount() - 1; |
| 401 var line_ends = this.line_ends; | 392 var line_ends = this.line_ends; |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1025 return frames; | 1016 return frames; |
| 1026 } | 1017 } |
| 1027 | 1018 |
| 1028 | 1019 |
| 1029 // Flag to prevent recursive call of Error.prepareStackTrace. | 1020 // Flag to prevent recursive call of Error.prepareStackTrace. |
| 1030 var formatting_custom_stack_trace = false; | 1021 var formatting_custom_stack_trace = false; |
| 1031 | 1022 |
| 1032 | 1023 |
| 1033 function FormatStackTrace(obj, raw_stack) { | 1024 function FormatStackTrace(obj, raw_stack) { |
| 1034 var frames = GetStackFrames(raw_stack); | 1025 var frames = GetStackFrames(raw_stack); |
| 1035 if (IS_FUNCTION($Error.prepareStackTrace) && !formatting_custom_stack_trace) { | 1026 if (IS_FUNCTION(GlobalError.prepareStackTrace) && |
| 1027 !formatting_custom_stack_trace) { |
| 1036 var array = []; | 1028 var array = []; |
| 1037 %MoveArrayContents(frames, array); | 1029 %MoveArrayContents(frames, array); |
| 1038 formatting_custom_stack_trace = true; | 1030 formatting_custom_stack_trace = true; |
| 1039 var stack_trace = UNDEFINED; | 1031 var stack_trace = UNDEFINED; |
| 1040 try { | 1032 try { |
| 1041 stack_trace = $Error.prepareStackTrace(obj, array); | 1033 stack_trace = GlobalError.prepareStackTrace(obj, array); |
| 1042 } catch (e) { | 1034 } catch (e) { |
| 1043 throw e; // The custom formatting function threw. Rethrow. | 1035 throw e; // The custom formatting function threw. Rethrow. |
| 1044 } finally { | 1036 } finally { |
| 1045 formatting_custom_stack_trace = false; | 1037 formatting_custom_stack_trace = false; |
| 1046 } | 1038 } |
| 1047 return stack_trace; | 1039 return stack_trace; |
| 1048 } | 1040 } |
| 1049 | 1041 |
| 1050 var lines = new InternalArray(); | 1042 var lines = new InternalArray(); |
| 1051 lines.push(FormatErrorString(obj)); | 1043 lines.push(FormatErrorString(obj)); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1075 %_CallFunction(receiver, NoSideEffectsObjectToString); | 1067 %_CallFunction(receiver, NoSideEffectsObjectToString); |
| 1076 } | 1068 } |
| 1077 var constructorName = constructor.name; | 1069 var constructorName = constructor.name; |
| 1078 if (!constructorName) { | 1070 if (!constructorName) { |
| 1079 return requireConstructor ? null : | 1071 return requireConstructor ? null : |
| 1080 %_CallFunction(receiver, NoSideEffectsObjectToString); | 1072 %_CallFunction(receiver, NoSideEffectsObjectToString); |
| 1081 } | 1073 } |
| 1082 return constructorName; | 1074 return constructorName; |
| 1083 } | 1075 } |
| 1084 | 1076 |
| 1085 | |
| 1086 var stack_trace_symbol; // Set during bootstrapping. | |
| 1087 var formatted_stack_trace_symbol = NEW_PRIVATE_OWN("formatted stack trace"); | 1077 var formatted_stack_trace_symbol = NEW_PRIVATE_OWN("formatted stack trace"); |
| 1088 | 1078 |
| 1089 | 1079 |
| 1090 // Format the stack trace if not yet done, and return it. | 1080 // Format the stack trace if not yet done, and return it. |
| 1091 // Cache the formatted stack trace on the holder. | 1081 // Cache the formatted stack trace on the holder. |
| 1092 var StackTraceGetter = function() { | 1082 var StackTraceGetter = function() { |
| 1093 var formatted_stack_trace = UNDEFINED; | 1083 var formatted_stack_trace = UNDEFINED; |
| 1094 var holder = this; | 1084 var holder = this; |
| 1095 while (holder) { | 1085 while (holder) { |
| 1096 var formatted_stack_trace = | 1086 var formatted_stack_trace = |
| 1097 GET_PRIVATE(holder, formatted_stack_trace_symbol); | 1087 GET_PRIVATE(holder, formatted_stack_trace_symbol); |
| 1098 if (IS_UNDEFINED(formatted_stack_trace)) { | 1088 if (IS_UNDEFINED(formatted_stack_trace)) { |
| 1099 // No formatted stack trace available. | 1089 // No formatted stack trace available. |
| 1100 var stack_trace = GET_PRIVATE(holder, stack_trace_symbol); | 1090 var stack_trace = GET_PRIVATE(holder, $stackTraceSymbol); |
| 1101 if (IS_UNDEFINED(stack_trace)) { | 1091 if (IS_UNDEFINED(stack_trace)) { |
| 1102 // Neither formatted nor structured stack trace available. | 1092 // Neither formatted nor structured stack trace available. |
| 1103 // Look further up the prototype chain. | 1093 // Look further up the prototype chain. |
| 1104 holder = %_GetPrototype(holder); | 1094 holder = %_GetPrototype(holder); |
| 1105 continue; | 1095 continue; |
| 1106 } | 1096 } |
| 1107 formatted_stack_trace = FormatStackTrace(holder, stack_trace); | 1097 formatted_stack_trace = FormatStackTrace(holder, stack_trace); |
| 1108 SET_PRIVATE(holder, stack_trace_symbol, UNDEFINED); | 1098 SET_PRIVATE(holder, $stackTraceSymbol, UNDEFINED); |
| 1109 SET_PRIVATE(holder, formatted_stack_trace_symbol, formatted_stack_trace); | 1099 SET_PRIVATE(holder, formatted_stack_trace_symbol, formatted_stack_trace); |
| 1110 } | 1100 } |
| 1111 return formatted_stack_trace; | 1101 return formatted_stack_trace; |
| 1112 } | 1102 } |
| 1113 return UNDEFINED; | 1103 return UNDEFINED; |
| 1114 }; | 1104 }; |
| 1115 | 1105 |
| 1116 | 1106 |
| 1117 // If the receiver equals the holder, set the formatted stack trace that the | 1107 // If the receiver equals the holder, set the formatted stack trace that the |
| 1118 // getter returns. | 1108 // getter returns. |
| 1119 var StackTraceSetter = function(v) { | 1109 var StackTraceSetter = function(v) { |
| 1120 if (HAS_PRIVATE(this, stack_trace_symbol)) { | 1110 if (HAS_PRIVATE(this, $stackTraceSymbol)) { |
| 1121 SET_PRIVATE(this, stack_trace_symbol, UNDEFINED); | 1111 SET_PRIVATE(this, $stackTraceSymbol, UNDEFINED); |
| 1122 SET_PRIVATE(this, formatted_stack_trace_symbol, v); | 1112 SET_PRIVATE(this, formatted_stack_trace_symbol, v); |
| 1123 } | 1113 } |
| 1124 }; | 1114 }; |
| 1125 | 1115 |
| 1126 | 1116 |
| 1127 // Use a dummy function since we do not actually want to capture a stack trace | 1117 // Use a dummy function since we do not actually want to capture a stack trace |
| 1128 // when constructing the initial Error prototytpes. | 1118 // when constructing the initial Error prototytpes. |
| 1129 var captureStackTrace = function captureStackTrace(obj, cons_opt) { | 1119 var captureStackTrace = function captureStackTrace(obj, cons_opt) { |
| 1130 // Define accessors first, as this may fail and throw. | 1120 // Define accessors first, as this may fail and throw. |
| 1131 ObjectDefineProperty(obj, 'stack', { get: StackTraceGetter, | 1121 ObjectDefineProperty(obj, 'stack', { get: StackTraceGetter, |
| 1132 set: StackTraceSetter, | 1122 set: StackTraceSetter, |
| 1133 configurable: true }); | 1123 configurable: true }); |
| 1134 %CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace); | 1124 %CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace); |
| 1135 } | 1125 } |
| 1136 | 1126 |
| 1137 | 1127 |
| 1138 function SetUpError() { | 1128 // Define special error type constructors. |
| 1139 // Define special error type constructors. | 1129 function DefineError(f) { |
| 1130 // Store the error function in both the global object |
| 1131 // and the runtime object. The function is fetched |
| 1132 // from the runtime object when throwing errors from |
| 1133 // within the runtime system to avoid strange side |
| 1134 // effects when overwriting the error functions from |
| 1135 // user code. |
| 1136 var name = f.name; |
| 1137 %AddNamedProperty(global, name, f, DONT_ENUM); |
| 1138 // Configure the error function. |
| 1139 if (name == 'Error') { |
| 1140 // The prototype of the Error object must itself be an error. |
| 1141 // However, it can't be an instance of the Error object because |
| 1142 // it hasn't been properly configured yet. Instead we create a |
| 1143 // special not-a-true-error-but-close-enough object. |
| 1144 var ErrorPrototype = function() {}; |
| 1145 %FunctionSetPrototype(ErrorPrototype, GlobalObject.prototype); |
| 1146 %FunctionSetInstanceClassName(ErrorPrototype, 'Error'); |
| 1147 %FunctionSetPrototype(f, new ErrorPrototype()); |
| 1148 } else { |
| 1149 %FunctionSetPrototype(f, new GlobalError()); |
| 1150 %InternalSetPrototype(f, GlobalError); |
| 1151 } |
| 1152 %FunctionSetInstanceClassName(f, 'Error'); |
| 1153 %AddNamedProperty(f.prototype, 'constructor', f, DONT_ENUM); |
| 1154 %AddNamedProperty(f.prototype, 'name', name, DONT_ENUM); |
| 1155 %SetCode(f, function(m) { |
| 1156 if (%_IsConstructCall()) { |
| 1157 try { captureStackTrace(this, f); } catch (e) { } |
| 1158 // Define all the expected properties directly on the error |
| 1159 // object. This avoids going through getters and setters defined |
| 1160 // on prototype objects. |
| 1161 if (!IS_UNDEFINED(m)) { |
| 1162 %AddNamedProperty(this, 'message', ToString(m), DONT_ENUM); |
| 1163 } |
| 1164 } else { |
| 1165 return new f(m); |
| 1166 } |
| 1167 }); |
| 1168 %SetNativeFlag(f); |
| 1169 return f; |
| 1170 }; |
| 1140 | 1171 |
| 1141 var DefineError = function(f) { | 1172 GlobalError = DefineError(function Error() { }); |
| 1142 // Store the error function in both the global object | 1173 GlobalEvalError = DefineError(function EvalError() { }); |
| 1143 // and the runtime object. The function is fetched | 1174 GlobalRangeError = DefineError(function RangeError() { }); |
| 1144 // from the runtime object when throwing errors from | 1175 GlobalReferenceError = DefineError(function ReferenceError() { }); |
| 1145 // within the runtime system to avoid strange side | 1176 GlobalSyntaxError = DefineError(function SyntaxError() { }); |
| 1146 // effects when overwriting the error functions from | 1177 GlobalTypeError = DefineError(function TypeError() { }); |
| 1147 // user code. | 1178 GlobalURIError = DefineError(function URIError() { }); |
| 1148 var name = f.name; | |
| 1149 %AddNamedProperty(global, name, f, DONT_ENUM); | |
| 1150 %AddNamedProperty(builtins, '$' + name, f, | |
| 1151 DONT_ENUM | DONT_DELETE | READ_ONLY); | |
| 1152 // Configure the error function. | |
| 1153 if (name == 'Error') { | |
| 1154 // The prototype of the Error object must itself be an error. | |
| 1155 // However, it can't be an instance of the Error object because | |
| 1156 // it hasn't been properly configured yet. Instead we create a | |
| 1157 // special not-a-true-error-but-close-enough object. | |
| 1158 var ErrorPrototype = function() {}; | |
| 1159 %FunctionSetPrototype(ErrorPrototype, $Object.prototype); | |
| 1160 %FunctionSetInstanceClassName(ErrorPrototype, 'Error'); | |
| 1161 %FunctionSetPrototype(f, new ErrorPrototype()); | |
| 1162 } else { | |
| 1163 %FunctionSetPrototype(f, new $Error()); | |
| 1164 %InternalSetPrototype(f, $Error); | |
| 1165 } | |
| 1166 %FunctionSetInstanceClassName(f, 'Error'); | |
| 1167 %AddNamedProperty(f.prototype, 'constructor', f, DONT_ENUM); | |
| 1168 %AddNamedProperty(f.prototype, 'name', name, DONT_ENUM); | |
| 1169 %SetCode(f, function(m) { | |
| 1170 if (%_IsConstructCall()) { | |
| 1171 try { captureStackTrace(this, f); } catch (e) { } | |
| 1172 // Define all the expected properties directly on the error | |
| 1173 // object. This avoids going through getters and setters defined | |
| 1174 // on prototype objects. | |
| 1175 if (!IS_UNDEFINED(m)) { | |
| 1176 %AddNamedProperty(this, 'message', ToString(m), DONT_ENUM); | |
| 1177 } | |
| 1178 } else { | |
| 1179 return new f(m); | |
| 1180 } | |
| 1181 }); | |
| 1182 %SetNativeFlag(f); | |
| 1183 }; | |
| 1184 | 1179 |
| 1185 DefineError(function Error() { }); | |
| 1186 DefineError(function TypeError() { }); | |
| 1187 DefineError(function RangeError() { }); | |
| 1188 DefineError(function SyntaxError() { }); | |
| 1189 DefineError(function ReferenceError() { }); | |
| 1190 DefineError(function EvalError() { }); | |
| 1191 DefineError(function URIError() { }); | |
| 1192 } | |
| 1193 | 1180 |
| 1194 SetUpError(); | 1181 GlobalError.captureStackTrace = captureStackTrace; |
| 1195 | 1182 |
| 1196 $Error.captureStackTrace = captureStackTrace; | 1183 %AddNamedProperty(GlobalError.prototype, 'message', '', DONT_ENUM); |
| 1197 | |
| 1198 %AddNamedProperty($Error.prototype, 'message', '', DONT_ENUM); | |
| 1199 | 1184 |
| 1200 // Global list of error objects visited during ErrorToString. This is | 1185 // Global list of error objects visited during ErrorToString. This is |
| 1201 // used to detect cycles in error toString formatting. | 1186 // used to detect cycles in error toString formatting. |
| 1202 var visited_errors = new InternalArray(); | 1187 var visited_errors = new InternalArray(); |
| 1203 var cyclic_error_marker = new $Object(); | 1188 var cyclic_error_marker = new GlobalObject(); |
| 1204 | 1189 |
| 1205 function GetPropertyWithoutInvokingMonkeyGetters(error, name) { | 1190 function GetPropertyWithoutInvokingMonkeyGetters(error, name) { |
| 1206 var current = error; | 1191 var current = error; |
| 1207 // Climb the prototype chain until we find the holder. | 1192 // Climb the prototype chain until we find the holder. |
| 1208 while (current && !%HasOwnProperty(current, name)) { | 1193 while (current && !%HasOwnProperty(current, name)) { |
| 1209 current = %_GetPrototype(current); | 1194 current = %_GetPrototype(current); |
| 1210 } | 1195 } |
| 1211 if (IS_NULL(current)) return UNDEFINED; | 1196 if (IS_NULL(current)) return UNDEFINED; |
| 1212 if (!IS_OBJECT(current)) return error[name]; | 1197 if (!IS_OBJECT(current)) return error[name]; |
| 1213 // If the property is an accessor on one of the predefined errors that can be | 1198 // If the property is an accessor on one of the predefined errors that can be |
| 1214 // generated statically by the compiler, don't touch it. This is to address | 1199 // generated statically by the compiler, don't touch it. This is to address |
| 1215 // http://code.google.com/p/chromium/issues/detail?id=69187 | 1200 // http://code.google.com/p/chromium/issues/detail?id=69187 |
| 1216 var desc = %GetOwnProperty(current, name); | 1201 var desc = %GetOwnProperty(current, name); |
| 1217 if (desc && desc[IS_ACCESSOR_INDEX]) { | 1202 if (desc && desc[IS_ACCESSOR_INDEX]) { |
| 1218 var isName = name === "name"; | 1203 var isName = name === "name"; |
| 1219 if (current === $ReferenceError.prototype) | 1204 if (current === GlobalReferenceError.prototype) |
| 1220 return isName ? "ReferenceError" : UNDEFINED; | 1205 return isName ? "ReferenceError" : UNDEFINED; |
| 1221 if (current === $SyntaxError.prototype) | 1206 if (current === GlobalSyntaxError.prototype) |
| 1222 return isName ? "SyntaxError" : UNDEFINED; | 1207 return isName ? "SyntaxError" : UNDEFINED; |
| 1223 if (current === $TypeError.prototype) | 1208 if (current === GlobalTypeError.prototype) |
| 1224 return isName ? "TypeError" : UNDEFINED; | 1209 return isName ? "TypeError" : UNDEFINED; |
| 1225 } | 1210 } |
| 1226 // Otherwise, read normally. | 1211 // Otherwise, read normally. |
| 1227 return error[name]; | 1212 return error[name]; |
| 1228 } | 1213 } |
| 1229 | 1214 |
| 1230 function ErrorToStringDetectCycle(error) { | 1215 function ErrorToStringDetectCycle(error) { |
| 1231 if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker; | 1216 if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker; |
| 1232 try { | 1217 try { |
| 1233 var name = GetPropertyWithoutInvokingMonkeyGetters(error, "name"); | 1218 var name = GetPropertyWithoutInvokingMonkeyGetters(error, "name"); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1252 } catch(e) { | 1237 } catch(e) { |
| 1253 // If this error message was encountered already return the empty | 1238 // If this error message was encountered already return the empty |
| 1254 // string for it instead of recursively formatting it. | 1239 // string for it instead of recursively formatting it. |
| 1255 if (e === cyclic_error_marker) { | 1240 if (e === cyclic_error_marker) { |
| 1256 return ''; | 1241 return ''; |
| 1257 } | 1242 } |
| 1258 throw e; | 1243 throw e; |
| 1259 } | 1244 } |
| 1260 } | 1245 } |
| 1261 | 1246 |
| 1247 InstallFunctions(GlobalError.prototype, DONT_ENUM, ['toString', ErrorToString]); |
| 1262 | 1248 |
| 1263 InstallFunctions($Error.prototype, DONT_ENUM, ['toString', ErrorToString]); | 1249 $errorToString = ErrorToString; |
| 1250 $formatMessage = FormatMessage; |
| 1251 $getStackTraceLine = GetStackTraceLine; |
| 1252 $messageGetPositionInLine = GetPositionInLine; |
| 1253 $messageGetLineNumber = GetLineNumber; |
| 1254 $messageGetSourceLine = GetSourceLine; |
| 1255 $toDetailString = ToDetailString; |
| 1264 | 1256 |
| 1265 // Boilerplate for exceptions for stack overflows. Used from | 1257 $Error = GlobalError; |
| 1266 // Isolate::StackOverflow(). | 1258 $EvalError = GlobalEvalError; |
| 1267 function SetUpStackOverflowBoilerplate() { | 1259 $RangeError = GlobalRangeError; |
| 1268 var boilerplate = MakeRangeError(kStackOverflow); | 1260 $ReferenceError = GlobalReferenceError; |
| 1261 $SyntaxError = GlobalSyntaxError; |
| 1262 $TypeError = GlobalTypeError; |
| 1263 $URIError = GlobalURIError; |
| 1269 | 1264 |
| 1270 %DefineAccessorPropertyUnchecked( | 1265 MakeError = function(type, arg0, arg1, arg2) { |
| 1271 boilerplate, 'stack', StackTraceGetter, StackTraceSetter, DONT_ENUM); | 1266 return MakeGenericError(GlobalError, type, arg0, arg1, arg2); |
| 1272 | |
| 1273 return boilerplate; | |
| 1274 } | 1267 } |
| 1275 | 1268 |
| 1276 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); | 1269 MakeEvalError = function(type, arg0, arg1, arg2) { |
| 1270 return MakeGenericError(GlobalEvalError, type, arg0, arg1, arg2); |
| 1271 } |
| 1272 |
| 1273 MakeRangeError = function(type, arg0, arg1, arg2) { |
| 1274 return MakeGenericError(GlobalRangeError, type, arg0, arg1, arg2); |
| 1275 } |
| 1276 |
| 1277 MakeReferenceError = function(type, arg0, arg1, arg2) { |
| 1278 return MakeGenericError(GlobalReferenceError, type, arg0, arg1, arg2); |
| 1279 } |
| 1280 |
| 1281 MakeSyntaxError = function(type, arg0, arg1, arg2) { |
| 1282 return MakeGenericError(GlobalSyntaxError, type, arg0, arg1, arg2); |
| 1283 } |
| 1284 |
| 1285 MakeTypeError = function(type, arg0, arg1, arg2) { |
| 1286 return MakeGenericError(GlobalTypeError, type, arg0, arg1, arg2); |
| 1287 } |
| 1288 |
| 1289 MakeURIError = function() { |
| 1290 return MakeGenericError(GlobalURIError, kURIMalformed); |
| 1291 } |
| 1292 |
| 1293 // The embedded versions are called from unoptimized code, with embedded |
| 1294 // arguments. Those arguments cannot be arrays, which are context-dependent. |
| 1295 MakeSyntaxErrorEmbedded = function(type, arg) { |
| 1296 return MakeGenericError(GlobalSyntaxError, type, [arg]); |
| 1297 } |
| 1298 |
| 1299 MakeReferenceErrorEmbedded = function(type, arg) { |
| 1300 return MakeGenericError(GlobalReferenceError, type, [arg]); |
| 1301 } |
| 1302 |
| 1303 MakeTypeErrorEmbedded = function(type, arg) { |
| 1304 return MakeGenericError(GlobalTypeError, type, [arg]); |
| 1305 } |
| 1306 |
| 1307 //Boilerplate for exceptions for stack overflows. Used from |
| 1308 //Isolate::StackOverflow(). |
| 1309 $stackOverflowBoilerplate = MakeRangeError(kStackOverflow); |
| 1310 %DefineAccessorPropertyUnchecked($stackOverflowBoilerplate, 'stack', |
| 1311 StackTraceGetter, StackTraceSetter, DONT_ENUM); |
| 1312 |
| 1313 })(); |
| OLD | NEW |