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