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 kMessages = { | 7 var kMessages = { |
8 // Error | 8 // Error |
9 cyclic_proto: ["Cyclic __proto__ value"], | 9 cyclic_proto: ["Cyclic __proto__ value"], |
10 code_gen_from_strings: ["%0"], | 10 code_gen_from_strings: ["%0"], |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 function MakeGenericError(constructor, type, args) { | 275 function MakeGenericError(constructor, type, args) { |
276 if (IS_UNDEFINED(args)) args = []; | 276 if (IS_UNDEFINED(args)) args = []; |
277 return new constructor(FormatMessage(type, args)); | 277 return new constructor(FormatMessage(type, args)); |
278 } | 278 } |
279 | 279 |
280 | 280 |
281 /** | 281 /** |
282 * Set up the Script function and constructor. | 282 * Set up the Script function and constructor. |
283 */ | 283 */ |
284 %FunctionSetInstanceClassName(Script, 'Script'); | 284 %FunctionSetInstanceClassName(Script, 'Script'); |
285 %SetProperty(Script.prototype, 'constructor', Script, | 285 %AddProperty(Script.prototype, 'constructor', Script, |
286 DONT_ENUM | DONT_DELETE | READ_ONLY); | 286 DONT_ENUM | DONT_DELETE | READ_ONLY); |
287 %SetCode(Script, function(x) { | 287 %SetCode(Script, function(x) { |
288 // Script objects can only be created by the VM. | 288 // Script objects can only be created by the VM. |
289 throw new $Error("Not supported"); | 289 throw new $Error("Not supported"); |
290 }); | 290 }); |
291 | 291 |
292 | 292 |
293 // Helper functions; called from the runtime system. | 293 // Helper functions; called from the runtime system. |
294 function FormatMessage(type, args) { | 294 function FormatMessage(type, args) { |
295 var format = kMessages[type]; | 295 var format = kMessages[type]; |
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1137 var stack = %CollectStackTrace(obj, | 1137 var stack = %CollectStackTrace(obj, |
1138 cons_opt ? cons_opt : captureStackTrace, | 1138 cons_opt ? cons_opt : captureStackTrace, |
1139 stackTraceLimit); | 1139 stackTraceLimit); |
1140 | 1140 |
1141 var error_string = FormatErrorString(obj); | 1141 var error_string = FormatErrorString(obj); |
1142 | 1142 |
1143 // Set the 'stack' property on the receiver. If the receiver is the same as | 1143 // Set the 'stack' property on the receiver. If the receiver is the same as |
1144 // holder of this setter, the accessor pair is turned into a data property. | 1144 // holder of this setter, the accessor pair is turned into a data property. |
1145 var setter = function(v) { | 1145 var setter = function(v) { |
1146 // Set data property on the receiver (not necessarily holder). | 1146 // Set data property on the receiver (not necessarily holder). |
1147 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); | 1147 %DefineDataPropertyUnchecked(this, 'stack', v, NONE); |
1148 if (this === obj) { | 1148 if (this === obj) { |
1149 // Release context values if holder is the same as the receiver. | 1149 // Release context values if holder is the same as the receiver. |
1150 stack = error_string = UNDEFINED; | 1150 stack = error_string = UNDEFINED; |
1151 } | 1151 } |
1152 }; | 1152 }; |
1153 | 1153 |
1154 // The holder of this getter ('obj') may not be the receiver ('this'). | 1154 // The holder of this getter ('obj') may not be the receiver ('this'). |
1155 // When this getter is called the first time, we use the context values to | 1155 // When this getter is called the first time, we use the context values to |
1156 // format a stack trace string and turn this accessor pair into a data | 1156 // format a stack trace string and turn this accessor pair into a data |
1157 // property (on the holder). | 1157 // property (on the holder). |
1158 var getter = function() { | 1158 var getter = function() { |
1159 // Stack is still a raw array awaiting to be formatted. | 1159 // Stack is still a raw array awaiting to be formatted. |
1160 var result = FormatStackTrace(obj, error_string, GetStackFrames(stack)); | 1160 var result = FormatStackTrace(obj, error_string, GetStackFrames(stack)); |
1161 // Replace this accessor to return result directly. | 1161 // Replace this accessor to return result directly. |
1162 %DefineOrRedefineAccessorProperty( | 1162 %DefineAccessorPropertyUnchecked( |
1163 obj, 'stack', function() { return result }, setter, DONT_ENUM); | 1163 obj, 'stack', function() { return result }, setter, DONT_ENUM); |
1164 // Release context values. | 1164 // Release context values. |
1165 stack = error_string = UNDEFINED; | 1165 stack = error_string = UNDEFINED; |
1166 return result; | 1166 return result; |
1167 }; | 1167 }; |
1168 | 1168 |
1169 %DefineOrRedefineAccessorProperty(obj, 'stack', getter, setter, DONT_ENUM); | 1169 %DefineAccessorPropertyUnchecked(obj, 'stack', getter, setter, DONT_ENUM); |
1170 } | 1170 } |
1171 | 1171 |
1172 | 1172 |
1173 function SetUpError() { | 1173 function SetUpError() { |
1174 // Define special error type constructors. | 1174 // Define special error type constructors. |
1175 | 1175 |
1176 var DefineError = function(f) { | 1176 var DefineError = function(f) { |
1177 // Store the error function in both the global object | 1177 // Store the error function in both the global object |
1178 // and the runtime object. The function is fetched | 1178 // and the runtime object. The function is fetched |
1179 // from the runtime object when throwing errors from | 1179 // from the runtime object when throwing errors from |
1180 // within the runtime system to avoid strange side | 1180 // within the runtime system to avoid strange side |
1181 // effects when overwriting the error functions from | 1181 // effects when overwriting the error functions from |
1182 // user code. | 1182 // user code. |
1183 var name = f.name; | 1183 var name = f.name; |
1184 %SetProperty(global, name, f, DONT_ENUM); | 1184 %AddProperty(global, name, f, DONT_ENUM); |
1185 %SetProperty(builtins, '$' + name, f, DONT_ENUM | DONT_DELETE | READ_ONLY); | 1185 %AddProperty(builtins, '$' + name, f, |
| 1186 DONT_ENUM | DONT_DELETE | READ_ONLY); |
1186 // Configure the error function. | 1187 // Configure the error function. |
1187 if (name == 'Error') { | 1188 if (name == 'Error') { |
1188 // The prototype of the Error object must itself be an error. | 1189 // The prototype of the Error object must itself be an error. |
1189 // However, it can't be an instance of the Error object because | 1190 // However, it can't be an instance of the Error object because |
1190 // it hasn't been properly configured yet. Instead we create a | 1191 // it hasn't been properly configured yet. Instead we create a |
1191 // special not-a-true-error-but-close-enough object. | 1192 // special not-a-true-error-but-close-enough object. |
1192 var ErrorPrototype = function() {}; | 1193 var ErrorPrototype = function() {}; |
1193 %FunctionSetPrototype(ErrorPrototype, $Object.prototype); | 1194 %FunctionSetPrototype(ErrorPrototype, $Object.prototype); |
1194 %FunctionSetInstanceClassName(ErrorPrototype, 'Error'); | 1195 %FunctionSetInstanceClassName(ErrorPrototype, 'Error'); |
1195 %FunctionSetPrototype(f, new ErrorPrototype()); | 1196 %FunctionSetPrototype(f, new ErrorPrototype()); |
1196 } else { | 1197 } else { |
1197 %FunctionSetPrototype(f, new $Error()); | 1198 %FunctionSetPrototype(f, new $Error()); |
1198 } | 1199 } |
1199 %FunctionSetInstanceClassName(f, 'Error'); | 1200 %FunctionSetInstanceClassName(f, 'Error'); |
1200 %SetProperty(f.prototype, 'constructor', f, DONT_ENUM); | 1201 %AddProperty(f.prototype, 'constructor', f, DONT_ENUM); |
1201 %SetProperty(f.prototype, "name", name, DONT_ENUM); | 1202 %AddProperty(f.prototype, "name", name, DONT_ENUM); |
1202 %SetCode(f, function(m) { | 1203 %SetCode(f, function(m) { |
1203 if (%_IsConstructCall()) { | 1204 if (%_IsConstructCall()) { |
1204 // Define all the expected properties directly on the error | 1205 // Define all the expected properties directly on the error |
1205 // object. This avoids going through getters and setters defined | 1206 // object. This avoids going through getters and setters defined |
1206 // on prototype objects. | 1207 // on prototype objects. |
1207 %IgnoreAttributesAndSetProperty(this, 'stack', UNDEFINED, DONT_ENUM); | 1208 %AddProperty(this, 'stack', UNDEFINED, DONT_ENUM); |
1208 if (!IS_UNDEFINED(m)) { | 1209 if (!IS_UNDEFINED(m)) { |
1209 %IgnoreAttributesAndSetProperty( | 1210 %AddProperty(this, 'message', ToString(m), DONT_ENUM); |
1210 this, 'message', ToString(m), DONT_ENUM); | |
1211 } | 1211 } |
1212 captureStackTrace(this, f); | 1212 captureStackTrace(this, f); |
1213 } else { | 1213 } else { |
1214 return new f(m); | 1214 return new f(m); |
1215 } | 1215 } |
1216 }); | 1216 }); |
1217 %SetNativeFlag(f); | 1217 %SetNativeFlag(f); |
1218 }; | 1218 }; |
1219 | 1219 |
1220 DefineError(function Error() { }); | 1220 DefineError(function Error() { }); |
1221 DefineError(function TypeError() { }); | 1221 DefineError(function TypeError() { }); |
1222 DefineError(function RangeError() { }); | 1222 DefineError(function RangeError() { }); |
1223 DefineError(function SyntaxError() { }); | 1223 DefineError(function SyntaxError() { }); |
1224 DefineError(function ReferenceError() { }); | 1224 DefineError(function ReferenceError() { }); |
1225 DefineError(function EvalError() { }); | 1225 DefineError(function EvalError() { }); |
1226 DefineError(function URIError() { }); | 1226 DefineError(function URIError() { }); |
1227 } | 1227 } |
1228 | 1228 |
1229 SetUpError(); | 1229 SetUpError(); |
1230 | 1230 |
1231 $Error.captureStackTrace = captureStackTrace; | 1231 $Error.captureStackTrace = captureStackTrace; |
1232 | 1232 |
1233 %SetProperty($Error.prototype, 'message', '', DONT_ENUM); | 1233 %AddProperty($Error.prototype, 'message', '', DONT_ENUM); |
1234 | 1234 |
1235 // Global list of error objects visited during ErrorToString. This is | 1235 // Global list of error objects visited during ErrorToString. This is |
1236 // used to detect cycles in error toString formatting. | 1236 // used to detect cycles in error toString formatting. |
1237 var visited_errors = new InternalArray(); | 1237 var visited_errors = new InternalArray(); |
1238 var cyclic_error_marker = new $Object(); | 1238 var cyclic_error_marker = new $Object(); |
1239 | 1239 |
1240 function GetPropertyWithoutInvokingMonkeyGetters(error, name) { | 1240 function GetPropertyWithoutInvokingMonkeyGetters(error, name) { |
1241 var current = error; | 1241 var current = error; |
1242 // Climb the prototype chain until we find the holder. | 1242 // Climb the prototype chain until we find the holder. |
1243 while (current && !%HasOwnProperty(current, name)) { | 1243 while (current && !%HasOwnProperty(current, name)) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1300 // Boilerplate for exceptions for stack overflows. Used from | 1300 // Boilerplate for exceptions for stack overflows. Used from |
1301 // Isolate::StackOverflow(). | 1301 // Isolate::StackOverflow(). |
1302 function SetUpStackOverflowBoilerplate() { | 1302 function SetUpStackOverflowBoilerplate() { |
1303 var boilerplate = MakeRangeError('stack_overflow', []); | 1303 var boilerplate = MakeRangeError('stack_overflow', []); |
1304 | 1304 |
1305 var error_string = boilerplate.name + ": " + boilerplate.message; | 1305 var error_string = boilerplate.name + ": " + boilerplate.message; |
1306 | 1306 |
1307 // Set the 'stack' property on the receiver. If the receiver is the same as | 1307 // Set the 'stack' property on the receiver. If the receiver is the same as |
1308 // holder of this setter, the accessor pair is turned into a data property. | 1308 // holder of this setter, the accessor pair is turned into a data property. |
1309 var setter = function(v) { | 1309 var setter = function(v) { |
1310 %DefineOrRedefineDataProperty(this, 'stack', v, NONE); | 1310 %DefineDataPropertyUnchecked(this, 'stack', v, NONE); |
1311 // Tentatively clear the hidden property. If the receiver is the same as | 1311 // Tentatively clear the hidden property. If the receiver is the same as |
1312 // holder, we release the raw stack trace this way. | 1312 // holder, we release the raw stack trace this way. |
1313 %GetAndClearOverflowedStackTrace(this); | 1313 %GetAndClearOverflowedStackTrace(this); |
1314 }; | 1314 }; |
1315 | 1315 |
1316 // The raw stack trace is stored as a hidden property on the holder of this | 1316 // The raw stack trace is stored as a hidden property on the holder of this |
1317 // getter, which may not be the same as the receiver. Find the holder to | 1317 // getter, which may not be the same as the receiver. Find the holder to |
1318 // retrieve the raw stack trace and then turn this accessor pair into a | 1318 // retrieve the raw stack trace and then turn this accessor pair into a |
1319 // data property. | 1319 // data property. |
1320 var getter = function() { | 1320 var getter = function() { |
1321 var holder = this; | 1321 var holder = this; |
1322 while (!IS_ERROR(holder)) { | 1322 while (!IS_ERROR(holder)) { |
1323 holder = %GetPrototype(holder); | 1323 holder = %GetPrototype(holder); |
1324 if (IS_NULL(holder)) return MakeSyntaxError('illegal_access', []); | 1324 if (IS_NULL(holder)) return MakeSyntaxError('illegal_access', []); |
1325 } | 1325 } |
1326 var stack = %GetAndClearOverflowedStackTrace(holder); | 1326 var stack = %GetAndClearOverflowedStackTrace(holder); |
1327 // We may not have captured any stack trace. | 1327 // We may not have captured any stack trace. |
1328 if (IS_UNDEFINED(stack)) return stack; | 1328 if (IS_UNDEFINED(stack)) return stack; |
1329 | 1329 |
1330 var result = FormatStackTrace(holder, error_string, GetStackFrames(stack)); | 1330 var result = FormatStackTrace(holder, error_string, GetStackFrames(stack)); |
1331 // Replace this accessor to return result directly. | 1331 // Replace this accessor to return result directly. |
1332 %DefineOrRedefineAccessorProperty( | 1332 %DefineAccessorPropertyUnchecked( |
1333 holder, 'stack', function() { return result }, setter, DONT_ENUM); | 1333 holder, 'stack', function() { return result }, setter, DONT_ENUM); |
1334 return result; | 1334 return result; |
1335 }; | 1335 }; |
1336 | 1336 |
1337 %DefineOrRedefineAccessorProperty( | 1337 %DefineAccessorPropertyUnchecked( |
1338 boilerplate, 'stack', getter, setter, DONT_ENUM); | 1338 boilerplate, 'stack', getter, setter, DONT_ENUM); |
1339 | 1339 |
1340 return boilerplate; | 1340 return boilerplate; |
1341 } | 1341 } |
1342 | 1342 |
1343 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); | 1343 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); |
OLD | NEW |