deps: update v8 to 4.3.61.21
[platform/upstream/nodejs.git] / deps / v8 / src / messages.js
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
3 // found in the LICENSE file.
4
5 // -------------------------------------------------------------------
6
7 var kMessages = {
8   // Error
9   cyclic_proto:                  ["Cyclic __proto__ value"],
10   code_gen_from_strings:         ["%0"],
11   constructor_is_generator:      ["Class constructor may not be a generator"],
12   constructor_is_accessor:       ["Class constructor may not be an accessor"],
13   // TypeError
14   generator_running:             ["Generator is already running"],
15   unexpected_token:              ["Unexpected token ", "%0"],
16   unexpected_token_number:       ["Unexpected number"],
17   unexpected_token_string:       ["Unexpected string"],
18   unexpected_token_identifier:   ["Unexpected identifier"],
19   unexpected_reserved:           ["Unexpected reserved word"],
20   unexpected_strict_reserved:    ["Unexpected strict mode reserved word"],
21   unexpected_eos:                ["Unexpected end of input"],
22   unexpected_template_string:    ["Unexpected template string"],
23   malformed_regexp:              ["Invalid regular expression: /", "%0", "/: ", "%1"],
24   malformed_regexp_flags:        ["Invalid regular expression flags"],
25   unterminated_regexp:           ["Invalid regular expression: missing /"],
26   unterminated_template:         ["Unterminated template literal"],
27   unterminated_template_expr:    ["Missing } in template expression"],
28   unterminated_arg_list:         ["missing ) after argument list"],
29   regexp_flags:                  ["Cannot supply flags when constructing one RegExp from another"],
30   incompatible_method_receiver:  ["Method ", "%0", " called on incompatible receiver ", "%1"],
31   multiple_defaults_in_switch:   ["More than one default clause in switch statement"],
32   newline_after_throw:           ["Illegal newline after throw"],
33   label_redeclaration:           ["Label '", "%0", "' has already been declared"],
34   var_redeclaration:             ["Identifier '", "%0", "' has already been declared"],
35   duplicate_template_property:   ["Object template has duplicate property '", "%0", "'"],
36   no_catch_or_finally:           ["Missing catch or finally after try"],
37   unknown_label:                 ["Undefined label '", "%0", "'"],
38   uncaught_exception:            ["Uncaught ", "%0"],
39   stack_trace:                   ["Stack Trace:\n", "%0"],
40   called_non_callable:           ["%0", " is not a function"],
41   undefined_method:              ["Object ", "%1", " has no method '", "%0", "'"],
42   property_not_function:         ["Property '", "%0", "' of object ", "%1", " is not a function"],
43   cannot_convert_to_primitive:   ["Cannot convert object to primitive value"],
44   not_constructor:               ["%0", " is not a constructor"],
45   not_defined:                   ["%0", " is not defined"],
46   non_method:                    ["'super' is referenced from non-method"],
47   unsupported_super:             ["Unsupported reference to 'super'"],
48   non_object_property_load:      ["Cannot read property '", "%0", "' of ", "%1"],
49   non_object_property_store:     ["Cannot set property '", "%0", "' of ", "%1"],
50   with_expression:               ["%0", " has no properties"],
51   illegal_invocation:            ["Illegal invocation"],
52   no_setter_in_callback:         ["Cannot set property ", "%0", " of ", "%1", " which has only a getter"],
53   apply_non_function:            ["Function.prototype.apply was called on ", "%0", ", which is a ", "%1", " and not a function"],
54   apply_wrong_args:              ["Function.prototype.apply: Arguments list has wrong type"],
55   reflect_apply_wrong_args:      ["Reflect.apply: Arguments list has wrong type"],
56   reflect_construct_wrong_args:  ["Reflect.construct: Arguments list has wrong type"],
57   flags_getter_non_object:       ["RegExp.prototype.flags getter called on non-object ", "%0"],
58   invalid_in_operator_use:       ["Cannot use 'in' operator to search for '", "%0", "' in ", "%1"],
59   instanceof_function_expected:  ["Expecting a function in instanceof check, but got ", "%0"],
60   instanceof_nonobject_proto:    ["Function has non-object prototype '", "%0", "' in instanceof check"],
61   undefined_or_null_to_object:   ["Cannot convert undefined or null to object"],
62   reduce_no_initial:             ["Reduce of empty array with no initial value"],
63   getter_must_be_callable:       ["Getter must be a function: ", "%0"],
64   setter_must_be_callable:       ["Setter must be a function: ", "%0"],
65   value_and_accessor:            ["Invalid property.  A property cannot both have accessors and be writable or have a value, ", "%0"],
66   proto_object_or_null:          ["Object prototype may only be an Object or null: ", "%0"],
67   property_desc_object:          ["Property description must be an object: ", "%0"],
68   redefine_disallowed:           ["Cannot redefine property: ", "%0"],
69   define_disallowed:             ["Cannot define property:", "%0", ", object is not extensible."],
70   non_extensible_proto:          ["%0", " is not extensible"],
71   handler_non_object:            ["Proxy.", "%0", " called with non-object as handler"],
72   proto_non_object:              ["Proxy.", "%0", " called with non-object as prototype"],
73   trap_function_expected:        ["Proxy.", "%0", " called with non-function for '", "%1", "' trap"],
74   handler_trap_missing:          ["Proxy handler ", "%0", " has no '", "%1", "' trap"],
75   handler_trap_must_be_callable: ["Proxy handler ", "%0", " has non-callable '", "%1", "' trap"],
76   handler_returned_false:        ["Proxy handler ", "%0", " returned false from '", "%1", "' trap"],
77   handler_returned_undefined:    ["Proxy handler ", "%0", " returned undefined from '", "%1", "' trap"],
78   proxy_prop_not_configurable:   ["Proxy handler ", "%0", " returned non-configurable descriptor for property '", "%2", "' from '", "%1", "' trap"],
79   proxy_non_object_prop_names:   ["Trap '", "%1", "' returned non-object ", "%0"],
80   proxy_repeated_prop_name:      ["Trap '", "%1", "' returned repeated property name '", "%2", "'"],
81   invalid_weakmap_key:           ["Invalid value used as weak map key"],
82   invalid_weakset_value:         ["Invalid value used in weak set"],
83   not_date_object:               ["this is not a Date object."],
84   observe_non_object:            ["Object.", "%0", " cannot ", "%0", " non-object"],
85   observe_non_function:          ["Object.", "%0", " cannot deliver to non-function"],
86   observe_callback_frozen:       ["Object.observe cannot deliver to a frozen function object"],
87   observe_invalid_accept:        ["Third argument to Object.observe must be an array of strings."],
88   observe_type_non_string:       ["Invalid changeRecord with non-string 'type' property"],
89   observe_perform_non_string:    ["Invalid non-string changeType"],
90   observe_perform_non_function:  ["Cannot perform non-function"],
91   observe_notify_non_notifier:   ["notify called on non-notifier object"],
92   observe_global_proxy:          ["%0", " cannot be called on the global proxy object"],
93   not_typed_array:               ["this is not a typed array."],
94   invalid_argument:              ["invalid_argument"],
95   data_view_not_array_buffer:    ["First argument to DataView constructor must be an ArrayBuffer"],
96   constructor_not_function:      ["Constructor ", "%0", " requires 'new'"],
97   not_a_symbol:                  ["%0", " is not a symbol"],
98   not_a_promise:                 ["%0", " is not a promise"],
99   resolver_not_a_function:       ["Promise resolver ", "%0", " is not a function"],
100   promise_cyclic:                ["Chaining cycle detected for promise ", "%0"],
101   array_functions_on_frozen:     ["Cannot modify frozen array elements"],
102   array_functions_change_sealed: ["Cannot add/remove sealed array elements"],
103   first_argument_not_regexp:     ["First argument to ", "%0", " must not be a regular expression"],
104   not_iterable:                  ["%0", " is not iterable"],
105   not_an_iterator:               ["%0", " is not an iterator"],
106   iterator_result_not_an_object: ["Iterator result ", "%0", " is not an object"],
107   iterator_value_not_an_object:  ["Iterator value ", "%0", " is not an entry object"],
108   // RangeError
109   invalid_array_length:          ["Invalid array length"],
110   invalid_array_buffer_length:   ["Invalid array buffer length"],
111   invalid_string_length:         ["Invalid string length"],
112   invalid_typed_array_offset:    ["Start offset is too large:"],
113   invalid_typed_array_length:    ["Invalid typed array length"],
114   invalid_typed_array_alignment: ["%0", " of ", "%1", " should be a multiple of ", "%2"],
115   typed_array_set_source_too_large:
116                                  ["Source is too large"],
117   typed_array_set_negative_offset:
118                                  ["Start offset is negative"],
119   invalid_data_view_offset:      ["Start offset is outside the bounds of the buffer"],
120   invalid_data_view_length:      ["Invalid data view length"],
121   invalid_data_view_accessor_offset:
122                                  ["Offset is outside the bounds of the DataView"],
123
124   stack_overflow:                ["Maximum call stack size exceeded"],
125   invalid_time_value:            ["Invalid time value"],
126   invalid_count_value:           ["Invalid count value"],
127   invalid_code_point:            ["Invalid code point ", "%0"],
128   // ReferenceError
129   invalid_lhs_in_assignment:     ["Invalid left-hand side in assignment"],
130   invalid_lhs_in_for:            ["Invalid left-hand side in for-loop"],
131   invalid_lhs_in_postfix_op:     ["Invalid left-hand side expression in postfix operation"],
132   invalid_lhs_in_prefix_op:      ["Invalid left-hand side expression in prefix operation"],
133   // SyntaxError
134   paren_in_arg_string:           ["Function arg string contains parenthesis"],
135   not_isvar:                     ["builtin %IS_VAR: not a variable"],
136   single_function_literal:       ["Single function literal required"],
137   invalid_regexp_flags:          ["Invalid flags supplied to RegExp constructor '", "%0", "'"],
138   invalid_regexp:                ["Invalid RegExp pattern /", "%0", "/"],
139   illegal_break:                 ["Illegal break statement"],
140   illegal_continue:              ["Illegal continue statement"],
141   illegal_return:                ["Illegal return statement"],
142   error_loading_debugger:        ["Error loading debugger"],
143   no_input_to_regexp:            ["No input to ", "%0"],
144   invalid_json:                  ["String '", "%0", "' is not valid JSON"],
145   circular_structure:            ["Converting circular structure to JSON"],
146   called_on_non_object:          ["%0", " called on non-object"],
147   called_on_null_or_undefined:   ["%0", " called on null or undefined"],
148   array_indexof_not_defined:     ["Array.getIndexOf: Argument undefined"],
149   object_not_extensible:         ["Can't add property ", "%0", ", object is not extensible"],
150   illegal_access:                ["Illegal access"],
151   static_prototype:              ["Classes may not have static property named prototype"],
152   strict_mode_with:              ["Strict mode code may not include a with statement"],
153   strict_eval_arguments:         ["Unexpected eval or arguments in strict mode"],
154   too_many_arguments:            ["Too many arguments in function call (only 65535 allowed)"],
155   too_many_parameters:           ["Too many parameters in function definition (only 65535 allowed)"],
156   too_many_variables:            ["Too many variables declared (only 4194303 allowed)"],
157   strict_param_dupe:             ["Strict mode function may not have duplicate parameter names"],
158   strict_octal_literal:          ["Octal literals are not allowed in strict mode."],
159   template_octal_literal:        ["Octal literals are not allowed in template strings."],
160   strict_delete:                 ["Delete of an unqualified identifier in strict mode."],
161   strict_delete_property:        ["Cannot delete property '", "%0", "' of ", "%1"],
162   strict_function:               ["In strict mode code, functions can only be declared at top level or immediately within another function." ],
163   strict_read_only_property:     ["Cannot assign to read only property '", "%0", "' of ", "%1"],
164   strict_cannot_assign:          ["Cannot assign to read only '", "%0", "' in strict mode"],
165   strict_poison_pill:            ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"],
166   strict_caller:                 ["Illegal access to a strict mode caller function."],
167   strong_ellision:               ["In strong mode, arrays with holes are deprecated, use maps instead"],
168   strong_arguments:              ["In strong mode, 'arguments' is deprecated, use '...args' instead"],
169   strong_equal:                  ["In strong mode, '==' and '!=' are deprecated, use '===' and '!==' instead"],
170   strong_delete:                 ["In strong mode, 'delete' is deprecated, use maps or sets instead"],
171   strong_var:                    ["In strong mode, 'var' is deprecated, use 'let' or 'const' instead"],
172   strong_for_in:                 ["In strong mode, 'for'-'in' loops are deprecated, use 'for'-'of' instead"],
173   strong_empty:                  ["In strong mode, empty sub-statements are deprecated, make them explicit with '{}' instead"],
174   strong_use_before_declaration: ["In strong mode, declaring variable '", "%0", "' before its use is required"],
175   strong_unbound_global:         ["In strong mode, using an undeclared global variable '", "%0", "' is not allowed"],
176   strong_super_call_missing:     ["In strong mode, invoking the super constructor in a subclass is required"],
177   strong_super_call_duplicate:   ["In strong mode, invoking the super constructor multiple times is deprecated"],
178   strong_super_call_nested:      ["In strong mode, invoking the super constructor nested inside another statement or expression is deprecated"],
179   strong_constructor_return_value: ["In strong mode, returning a value from a constructor is deprecated"],
180   strong_constructor_return_misplaced: ["In strong mode, returning from a constructor before its super constructor invocation is deprecated"],
181   sloppy_lexical:                ["Block-scoped declarations (let, const, function, class) not yet supported outside strict mode"],
182   malformed_arrow_function_parameter_list: ["Malformed arrow function parameter list"],
183   generator_poison_pill:         ["'caller' and 'arguments' properties may not be accessed on generator functions."],
184   cant_prevent_ext_external_array_elements: ["Cannot prevent extension of an object with external array elements"],
185   redef_external_array_element:  ["Cannot redefine a property of an object with external array elements"],
186   const_assign:                  ["Assignment to constant variable."],
187   symbol_to_string:              ["Cannot convert a Symbol value to a string"],
188   symbol_to_primitive:           ["Cannot convert a Symbol wrapper object to a primitive value"],
189   symbol_to_number:              ["Cannot convert a Symbol value to a number"],
190   module_export_undefined:       ["Export '", "%0", "' is not defined in module"],
191   duplicate_export:              ["Duplicate export of '", "%0", "'"],
192   unexpected_super:              ["'super' keyword unexpected here"],
193   extends_value_not_a_function:  ["Class extends value ", "%0", " is not a function or null"],
194   prototype_parent_not_an_object: ["Class extends value does not have valid prototype property ", "%0"],
195   duplicate_constructor:         ["A class may only have one constructor"],
196   super_constructor_call:        ["A 'super' constructor call may only appear as the first statement of a function, and its arguments may not access 'this'. Other forms are not yet supported."],
197   duplicate_proto:               ["Duplicate __proto__ fields are not allowed in object literals"],
198   param_after_rest:              ["Rest parameter must be last formal parameter"],
199   constructor_noncallable:       ["Class constructors cannot be invoked without 'new'"],
200   array_not_subclassable:        ["Subclassing Arrays is not currently supported."]
201 };
202
203
204 function FormatString(format, args) {
205   var result = "";
206   var arg_num = 0;
207   for (var i = 0; i < format.length; i++) {
208     var str = format[i];
209     if (str.length == 2 && %_StringCharCodeAt(str, 0) == 0x25) {
210       // Two-char string starts with "%".
211       var arg_num = (%_StringCharCodeAt(str, 1) - 0x30) >>> 0;
212       if (arg_num < 4) {
213         // str is one of %0, %1, %2 or %3.
214         try {
215           str = NoSideEffectToString(args[arg_num]);
216         } catch (e) {
217           if (%IsJSModule(args[arg_num]))
218             str = "module";
219           else if (IS_SPEC_OBJECT(args[arg_num]))
220             str = "object";
221           else
222             str = "#<error>";
223         }
224       }
225     }
226     result += str;
227   }
228   return result;
229 }
230
231
232 function NoSideEffectToString(obj) {
233   if (IS_STRING(obj)) return obj;
234   if (IS_NUMBER(obj)) return %_NumberToString(obj);
235   if (IS_BOOLEAN(obj)) return obj ? 'true' : 'false';
236   if (IS_UNDEFINED(obj)) return 'undefined';
237   if (IS_NULL(obj)) return 'null';
238   if (IS_FUNCTION(obj)) {
239     var str = %_CallFunction(obj, FunctionToString);
240     if (str.length > 128) {
241       str = %_SubString(str, 0, 111) + "...<omitted>..." +
242             %_SubString(str, str.length - 2, str.length);
243     }
244     return str;
245   }
246   if (IS_SYMBOL(obj)) return %_CallFunction(obj, $symbolToString);
247   if (IS_OBJECT(obj)
248       && %GetDataProperty(obj, "toString") === DefaultObjectToString) {
249     var constructor = %GetDataProperty(obj, "constructor");
250     if (typeof constructor == "function") {
251       var constructorName = constructor.name;
252       if (IS_STRING(constructorName) && constructorName !== "") {
253         return "#<" + constructorName + ">";
254       }
255     }
256   }
257   if (CanBeSafelyTreatedAsAnErrorObject(obj)) {
258     return %_CallFunction(obj, ErrorToString);
259   }
260
261   return %_CallFunction(obj, NoSideEffectsObjectToString);
262 }
263
264 // To determine whether we can safely stringify an object using ErrorToString
265 // without the risk of side-effects, we need to check whether the object is
266 // either an instance of a native error type (via '%_ClassOf'), or has $Error
267 // in its prototype chain and hasn't overwritten 'toString' with something
268 // strange and unusual.
269 function CanBeSafelyTreatedAsAnErrorObject(obj) {
270   switch (%_ClassOf(obj)) {
271     case 'Error':
272     case 'EvalError':
273     case 'RangeError':
274     case 'ReferenceError':
275     case 'SyntaxError':
276     case 'TypeError':
277     case 'URIError':
278       return true;
279   }
280
281   var objToString = %GetDataProperty(obj, "toString");
282   return obj instanceof $Error && objToString === ErrorToString;
283 }
284
285
286 // When formatting internally created error messages, do not
287 // invoke overwritten error toString methods but explicitly use
288 // the error to string method. This is to avoid leaking error
289 // objects between script tags in a browser setting.
290 function ToStringCheckErrorObject(obj) {
291   if (CanBeSafelyTreatedAsAnErrorObject(obj)) {
292     return %_CallFunction(obj, ErrorToString);
293   } else {
294     return ToString(obj);
295   }
296 }
297
298
299 function ToDetailString(obj) {
300   if (obj != null && IS_OBJECT(obj) && obj.toString === DefaultObjectToString) {
301     var constructor = obj.constructor;
302     if (typeof constructor == "function") {
303       var constructorName = constructor.name;
304       if (IS_STRING(constructorName) && constructorName !== "") {
305         return "#<" + constructorName + ">";
306       }
307     }
308   }
309   return ToStringCheckErrorObject(obj);
310 }
311
312
313 function MakeGenericError(constructor, type, args) {
314   if (IS_UNDEFINED(args)) args = [];
315   return new constructor(FormatMessage(type, args));
316 }
317
318
319 /**
320  * Set up the Script function and constructor.
321  */
322 %FunctionSetInstanceClassName(Script, 'Script');
323 %AddNamedProperty(Script.prototype, 'constructor', Script,
324                   DONT_ENUM | DONT_DELETE | READ_ONLY);
325 %SetCode(Script, function(x) {
326   // Script objects can only be created by the VM.
327   throw new $Error("Not supported");
328 });
329
330
331 // Helper functions; called from the runtime system.
332 function FormatMessage(type, args) {
333   var format = kMessages[type];
334   if (!format) return "<unknown message " + type + ">";
335   return FormatString(format, args);
336 }
337
338
339 function GetLineNumber(message) {
340   var start_position = %MessageGetStartPosition(message);
341   if (start_position == -1) return kNoLineNumberInfo;
342   var script = %MessageGetScript(message);
343   var location = script.locationFromPosition(start_position, true);
344   if (location == null) return kNoLineNumberInfo;
345   return location.line + 1;
346 }
347
348
349 // Returns the source code line containing the given source
350 // position, or the empty string if the position is invalid.
351 function GetSourceLine(message) {
352   var script = %MessageGetScript(message);
353   var start_position = %MessageGetStartPosition(message);
354   var location = script.locationFromPosition(start_position, true);
355   if (location == null) return "";
356   return location.sourceText();
357 }
358
359
360 function MakeTypeError(type, args) {
361   return MakeGenericError($TypeError, type, args);
362 }
363
364
365 function MakeRangeError(type, args) {
366   return MakeGenericError($RangeError, type, args);
367 }
368
369
370 function MakeSyntaxError(type, args) {
371   return MakeGenericError($SyntaxError, type, args);
372 }
373
374
375 function MakeReferenceError(type, args) {
376   return MakeGenericError($ReferenceError, type, args);
377 }
378
379
380 function MakeEvalError(type, args) {
381   return MakeGenericError($EvalError, type, args);
382 }
383
384
385 function MakeError(type, args) {
386   return MakeGenericError($Error, type, args);
387 }
388
389
390 // The embedded versions are called from unoptimized code, with embedded
391 // arguments. Those arguments cannot be arrays, which are context-dependent.
392 function MakeTypeErrorEmbedded(type, arg) {
393   return MakeGenericError($TypeError, type, [arg]);
394 }
395
396
397 function MakeSyntaxErrorEmbedded(type, arg) {
398   return MakeGenericError($SyntaxError, type, [arg]);
399 }
400
401
402 function MakeReferenceErrorEmbedded(type, arg) {
403   return MakeGenericError($ReferenceError, type, [arg]);
404 }
405
406 /**
407  * Find a line number given a specific source position.
408  * @param {number} position The source position.
409  * @return {number} 0 if input too small, -1 if input too large,
410        else the line number.
411  */
412 function ScriptLineFromPosition(position) {
413   var line_ends = this.line_ends;
414   var upper = line_ends.length - 1;
415   if (upper < 0) return -1;
416
417   // We'll never find invalid positions so bail right away.
418   if (position > line_ends[upper]) return -1;
419   if (position <= line_ends[0]) return 0;
420
421   var lower = 1;
422   // Binary search.
423   while (true) {
424     var mid = (upper + lower) >> 1;
425     if (position <= line_ends[mid - 1]) {
426       upper = mid - 1;
427     } else if (position > line_ends[mid]){
428       lower = mid + 1;
429     } else {
430       return mid;
431     }
432   }
433 }
434
435 /**
436  * Get information on a specific source position.
437  * @param {number} position The source position
438  * @param {boolean} include_resource_offset Set to true to have the resource
439  *     offset added to the location
440  * @return {SourceLocation}
441  *     If line is negative or not in the source null is returned.
442  */
443 function ScriptLocationFromPosition(position,
444                                     include_resource_offset) {
445   var line = this.lineFromPosition(position);
446   if (line == -1) return null;
447
448   // Determine start, end and column.
449   var line_ends = this.line_ends;
450   var start = line == 0 ? 0 : line_ends[line - 1] + 1;
451   var end = line_ends[line];
452   if (end > 0 && %_CallFunction(this.source, end - 1, $stringCharAt) == '\r') {
453     end--;
454   }
455   var column = position - start;
456
457   // Adjust according to the offset within the resource.
458   if (include_resource_offset) {
459     line += this.line_offset;
460     if (line == this.line_offset) {
461       column += this.column_offset;
462     }
463   }
464
465   return new SourceLocation(this, position, line, column, start, end);
466 }
467
468
469 /**
470  * Get information on a specific source line and column possibly offset by a
471  * fixed source position. This function is used to find a source position from
472  * a line and column position. The fixed source position offset is typically
473  * used to find a source position in a function based on a line and column in
474  * the source for the function alone. The offset passed will then be the
475  * start position of the source for the function within the full script source.
476  * @param {number} opt_line The line within the source. Default value is 0
477  * @param {number} opt_column The column in within the line. Default value is 0
478  * @param {number} opt_offset_position The offset from the begining of the
479  *     source from where the line and column calculation starts.
480  *     Default value is 0
481  * @return {SourceLocation}
482  *     If line is negative or not in the source null is returned.
483  */
484 function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) {
485   // Default is the first line in the script. Lines in the script is relative
486   // to the offset within the resource.
487   var line = 0;
488   if (!IS_UNDEFINED(opt_line)) {
489     line = opt_line - this.line_offset;
490   }
491
492   // Default is first column. If on the first line add the offset within the
493   // resource.
494   var column = opt_column || 0;
495   if (line == 0) {
496     column -= this.column_offset;
497   }
498
499   var offset_position = opt_offset_position || 0;
500   if (line < 0 || column < 0 || offset_position < 0) return null;
501   if (line == 0) {
502     return this.locationFromPosition(offset_position + column, false);
503   } else {
504     // Find the line where the offset position is located.
505     var offset_line = this.lineFromPosition(offset_position);
506
507     if (offset_line == -1 || offset_line + line >= this.lineCount()) {
508       return null;
509     }
510
511     return this.locationFromPosition(
512         this.line_ends[offset_line + line - 1] + 1 + column);  // line > 0 here.
513   }
514 }
515
516
517 /**
518  * Get a slice of source code from the script. The boundaries for the slice is
519  * specified in lines.
520  * @param {number} opt_from_line The first line (zero bound) in the slice.
521  *     Default is 0
522  * @param {number} opt_to_column The last line (zero bound) in the slice (non
523  *     inclusive). Default is the number of lines in the script
524  * @return {SourceSlice} The source slice or null of the parameters where
525  *     invalid
526  */
527 function ScriptSourceSlice(opt_from_line, opt_to_line) {
528   var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset
529                                               : opt_from_line;
530   var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
531                                           : opt_to_line;
532
533   // Adjust according to the offset within the resource.
534   from_line -= this.line_offset;
535   to_line -= this.line_offset;
536   if (from_line < 0) from_line = 0;
537   if (to_line > this.lineCount()) to_line = this.lineCount();
538
539   // Check parameters.
540   if (from_line >= this.lineCount() ||
541       to_line < 0 ||
542       from_line > to_line) {
543     return null;
544   }
545
546   var line_ends = this.line_ends;
547   var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1;
548   var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1;
549
550   // Return a source slice with line numbers re-adjusted to the resource.
551   return new SourceSlice(this,
552                          from_line + this.line_offset,
553                          to_line + this.line_offset,
554                           from_position, to_position);
555 }
556
557
558 function ScriptSourceLine(opt_line) {
559   // Default is the first line in the script. Lines in the script are relative
560   // to the offset within the resource.
561   var line = 0;
562   if (!IS_UNDEFINED(opt_line)) {
563     line = opt_line - this.line_offset;
564   }
565
566   // Check parameter.
567   if (line < 0 || this.lineCount() <= line) {
568     return null;
569   }
570
571   // Return the source line.
572   var line_ends = this.line_ends;
573   var start = line == 0 ? 0 : line_ends[line - 1] + 1;
574   var end = line_ends[line];
575   return %_CallFunction(this.source, start, end, $stringSubstring);
576 }
577
578
579 /**
580  * Returns the number of source lines.
581  * @return {number}
582  *     Number of source lines.
583  */
584 function ScriptLineCount() {
585   // Return number of source lines.
586   return this.line_ends.length;
587 }
588
589
590 /**
591  * If sourceURL comment is available and script starts at zero returns sourceURL
592  * comment contents. Otherwise, script name is returned. See
593  * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
594  * and Source Map Revision 3 proposal for details on using //# sourceURL and
595  * deprecated //@ sourceURL comment to identify scripts that don't have name.
596  *
597  * @return {?string} script name if present, value for //# sourceURL or
598  * deprecated //@ sourceURL comment otherwise.
599  */
600 function ScriptNameOrSourceURL() {
601   if (this.line_offset > 0 || this.column_offset > 0) {
602     return this.name;
603   }
604   if (this.source_url) {
605     return this.source_url;
606   }
607   return this.name;
608 }
609
610
611 SetUpLockedPrototype(Script,
612   $Array("source", "name", "source_url", "source_mapping_url", "line_ends",
613          "line_offset", "column_offset"),
614   $Array(
615     "lineFromPosition", ScriptLineFromPosition,
616     "locationFromPosition", ScriptLocationFromPosition,
617     "locationFromLine", ScriptLocationFromLine,
618     "sourceSlice", ScriptSourceSlice,
619     "sourceLine", ScriptSourceLine,
620     "lineCount", ScriptLineCount,
621     "nameOrSourceURL", ScriptNameOrSourceURL
622   )
623 );
624
625
626 /**
627  * Class for source location. A source location is a position within some
628  * source with the following properties:
629  *   script   : script object for the source
630  *   line     : source line number
631  *   column   : source column within the line
632  *   position : position within the source
633  *   start    : position of start of source context (inclusive)
634  *   end      : position of end of source context (not inclusive)
635  * Source text for the source context is the character interval
636  * [start, end[. In most cases end will point to a newline character.
637  * It might point just past the final position of the source if the last
638  * source line does not end with a newline character.
639  * @param {Script} script The Script object for which this is a location
640  * @param {number} position Source position for the location
641  * @param {number} line The line number for the location
642  * @param {number} column The column within the line for the location
643  * @param {number} start Source position for start of source context
644  * @param {number} end Source position for end of source context
645  * @constructor
646  */
647 function SourceLocation(script, position, line, column, start, end) {
648   this.script = script;
649   this.position = position;
650   this.line = line;
651   this.column = column;
652   this.start = start;
653   this.end = end;
654 }
655
656
657 /**
658  * Get the source text for a SourceLocation
659  * @return {String}
660  *     Source text for this location.
661  */
662 function SourceLocationSourceText() {
663   return %_CallFunction(this.script.source,
664                         this.start,
665                         this.end,
666                         $stringSubstring);
667 }
668
669
670 SetUpLockedPrototype(SourceLocation,
671   $Array("script", "position", "line", "column", "start", "end"),
672   $Array(
673     "sourceText", SourceLocationSourceText
674  )
675 );
676
677
678 /**
679  * Class for a source slice. A source slice is a part of a script source with
680  * the following properties:
681  *   script        : script object for the source
682  *   from_line     : line number for the first line in the slice
683  *   to_line       : source line number for the last line in the slice
684  *   from_position : position of the first character in the slice
685  *   to_position   : position of the last character in the slice
686  * The to_line and to_position are not included in the slice, that is the lines
687  * in the slice are [from_line, to_line[. Likewise the characters in the slice
688  * are [from_position, to_position[.
689  * @param {Script} script The Script object for the source slice
690  * @param {number} from_line
691  * @param {number} to_line
692  * @param {number} from_position
693  * @param {number} to_position
694  * @constructor
695  */
696 function SourceSlice(script, from_line, to_line, from_position, to_position) {
697   this.script = script;
698   this.from_line = from_line;
699   this.to_line = to_line;
700   this.from_position = from_position;
701   this.to_position = to_position;
702 }
703
704 /**
705  * Get the source text for a SourceSlice
706  * @return {String} Source text for this slice. The last line will include
707  *     the line terminating characters (if any)
708  */
709 function SourceSliceSourceText() {
710   return %_CallFunction(this.script.source,
711                         this.from_position,
712                         this.to_position,
713                         $stringSubstring);
714 }
715
716 SetUpLockedPrototype(SourceSlice,
717   $Array("script", "from_line", "to_line", "from_position", "to_position"),
718   $Array("sourceText", SourceSliceSourceText)
719 );
720
721
722 // Returns the offset of the given position within the containing
723 // line.
724 function GetPositionInLine(message) {
725   var script = %MessageGetScript(message);
726   var start_position = %MessageGetStartPosition(message);
727   var location = script.locationFromPosition(start_position, false);
728   if (location == null) return -1;
729   return start_position - location.start;
730 }
731
732
733 function GetStackTraceLine(recv, fun, pos, isGlobal) {
734   return new CallSite(recv, fun, pos, false).toString();
735 }
736
737 // ----------------------------------------------------------------------------
738 // Error implementation
739
740 var CallSiteReceiverKey = NEW_PRIVATE_OWN("CallSite#receiver");
741 var CallSiteFunctionKey = NEW_PRIVATE_OWN("CallSite#function");
742 var CallSitePositionKey = NEW_PRIVATE_OWN("CallSite#position");
743 var CallSiteStrictModeKey = NEW_PRIVATE_OWN("CallSite#strict_mode");
744
745 function CallSite(receiver, fun, pos, strict_mode) {
746   SET_PRIVATE(this, CallSiteReceiverKey, receiver);
747   SET_PRIVATE(this, CallSiteFunctionKey, fun);
748   SET_PRIVATE(this, CallSitePositionKey, pos);
749   SET_PRIVATE(this, CallSiteStrictModeKey, strict_mode);
750 }
751
752 function CallSiteGetThis() {
753   return GET_PRIVATE(this, CallSiteStrictModeKey)
754       ? UNDEFINED : GET_PRIVATE(this, CallSiteReceiverKey);
755 }
756
757 function CallSiteGetTypeName() {
758   return GetTypeName(GET_PRIVATE(this, CallSiteReceiverKey), false);
759 }
760
761 function CallSiteIsToplevel() {
762   if (GET_PRIVATE(this, CallSiteReceiverKey) == null) {
763     return true;
764   }
765   return IS_GLOBAL(GET_PRIVATE(this, CallSiteReceiverKey));
766 }
767
768 function CallSiteIsEval() {
769   var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
770   return script && script.compilation_type == COMPILATION_TYPE_EVAL;
771 }
772
773 function CallSiteGetEvalOrigin() {
774   var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
775   return FormatEvalOrigin(script);
776 }
777
778 function CallSiteGetScriptNameOrSourceURL() {
779   var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
780   return script ? script.nameOrSourceURL() : null;
781 }
782
783 function CallSiteGetFunction() {
784   return GET_PRIVATE(this, CallSiteStrictModeKey)
785       ? UNDEFINED : GET_PRIVATE(this, CallSiteFunctionKey);
786 }
787
788 function CallSiteGetFunctionName() {
789   // See if the function knows its own name
790   var fun = GET_PRIVATE(this, CallSiteFunctionKey);
791   var name = %FunctionGetDebugName(fun);
792   if (name) {
793     return name;
794   }
795   // Maybe this is an evaluation?
796   var script = %FunctionGetScript(fun);
797   if (script && script.compilation_type == COMPILATION_TYPE_EVAL) {
798     return "eval";
799   }
800   return null;
801 }
802
803 function CallSiteGetMethodName() {
804   // See if we can find a unique property on the receiver that holds
805   // this function.
806   var receiver = GET_PRIVATE(this, CallSiteReceiverKey);
807   var fun = GET_PRIVATE(this, CallSiteFunctionKey);
808   var ownName = fun.name;
809   if (ownName && receiver &&
810       (%_CallFunction(receiver, ownName, ObjectLookupGetter) === fun ||
811        %_CallFunction(receiver, ownName, ObjectLookupSetter) === fun ||
812        (IS_OBJECT(receiver) && %GetDataProperty(receiver, ownName) === fun))) {
813     // To handle DontEnum properties we guess that the method has
814     // the same name as the function.
815     return ownName;
816   }
817   var name = null;
818   for (var prop in receiver) {
819     if (%_CallFunction(receiver, prop, ObjectLookupGetter) === fun ||
820         %_CallFunction(receiver, prop, ObjectLookupSetter) === fun ||
821         (IS_OBJECT(receiver) && %GetDataProperty(receiver, prop) === fun)) {
822       // If we find more than one match bail out to avoid confusion.
823       if (name) {
824         return null;
825       }
826       name = prop;
827     }
828   }
829   if (name) {
830     return name;
831   }
832   return null;
833 }
834
835 function CallSiteGetFileName() {
836   var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
837   return script ? script.name : null;
838 }
839
840 function CallSiteGetLineNumber() {
841   if (GET_PRIVATE(this, CallSitePositionKey) == -1) {
842     return null;
843   }
844   var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
845   var location = null;
846   if (script) {
847     location = script.locationFromPosition(
848         GET_PRIVATE(this, CallSitePositionKey), true);
849   }
850   return location ? location.line + 1 : null;
851 }
852
853 function CallSiteGetColumnNumber() {
854   if (GET_PRIVATE(this, CallSitePositionKey) == -1) {
855     return null;
856   }
857   var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
858   var location = null;
859   if (script) {
860     location = script.locationFromPosition(
861       GET_PRIVATE(this, CallSitePositionKey), true);
862   }
863   return location ? location.column + 1: null;
864 }
865
866 function CallSiteIsNative() {
867   var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
868   return script ? (script.type == TYPE_NATIVE) : false;
869 }
870
871 function CallSiteGetPosition() {
872   return GET_PRIVATE(this, CallSitePositionKey);
873 }
874
875 function CallSiteIsConstructor() {
876   var receiver = GET_PRIVATE(this, CallSiteReceiverKey);
877   var constructor = (receiver != null && IS_OBJECT(receiver))
878                         ? %GetDataProperty(receiver, "constructor") : null;
879   if (!constructor) return false;
880   return GET_PRIVATE(this, CallSiteFunctionKey) === constructor;
881 }
882
883 function CallSiteToString() {
884   var fileName;
885   var fileLocation = "";
886   if (this.isNative()) {
887     fileLocation = "native";
888   } else {
889     fileName = this.getScriptNameOrSourceURL();
890     if (!fileName && this.isEval()) {
891       fileLocation = this.getEvalOrigin();
892       fileLocation += ", ";  // Expecting source position to follow.
893     }
894
895     if (fileName) {
896       fileLocation += fileName;
897     } else {
898       // Source code does not originate from a file and is not native, but we
899       // can still get the source position inside the source string, e.g. in
900       // an eval string.
901       fileLocation += "<anonymous>";
902     }
903     var lineNumber = this.getLineNumber();
904     if (lineNumber != null) {
905       fileLocation += ":" + lineNumber;
906       var columnNumber = this.getColumnNumber();
907       if (columnNumber) {
908         fileLocation += ":" + columnNumber;
909       }
910     }
911   }
912
913   var line = "";
914   var functionName = this.getFunctionName();
915   var addSuffix = true;
916   var isConstructor = this.isConstructor();
917   var isMethodCall = !(this.isToplevel() || isConstructor);
918   if (isMethodCall) {
919     var typeName = GetTypeName(GET_PRIVATE(this, CallSiteReceiverKey), true);
920     var methodName = this.getMethodName();
921     if (functionName) {
922       if (typeName &&
923           %_CallFunction(functionName, typeName, $stringIndexOf) != 0) {
924         line += typeName + ".";
925       }
926       line += functionName;
927       if (methodName &&
928           (%_CallFunction(functionName, "." + methodName, $stringIndexOf) !=
929            functionName.length - methodName.length - 1)) {
930         line += " [as " + methodName + "]";
931       }
932     } else {
933       line += typeName + "." + (methodName || "<anonymous>");
934     }
935   } else if (isConstructor) {
936     line += "new " + (functionName || "<anonymous>");
937   } else if (functionName) {
938     line += functionName;
939   } else {
940     line += fileLocation;
941     addSuffix = false;
942   }
943   if (addSuffix) {
944     line += " (" + fileLocation + ")";
945   }
946   return line;
947 }
948
949 SetUpLockedPrototype(CallSite, $Array("receiver", "fun", "pos"), $Array(
950   "getThis", CallSiteGetThis,
951   "getTypeName", CallSiteGetTypeName,
952   "isToplevel", CallSiteIsToplevel,
953   "isEval", CallSiteIsEval,
954   "getEvalOrigin", CallSiteGetEvalOrigin,
955   "getScriptNameOrSourceURL", CallSiteGetScriptNameOrSourceURL,
956   "getFunction", CallSiteGetFunction,
957   "getFunctionName", CallSiteGetFunctionName,
958   "getMethodName", CallSiteGetMethodName,
959   "getFileName", CallSiteGetFileName,
960   "getLineNumber", CallSiteGetLineNumber,
961   "getColumnNumber", CallSiteGetColumnNumber,
962   "isNative", CallSiteIsNative,
963   "getPosition", CallSiteGetPosition,
964   "isConstructor", CallSiteIsConstructor,
965   "toString", CallSiteToString
966 ));
967
968
969 function FormatEvalOrigin(script) {
970   var sourceURL = script.nameOrSourceURL();
971   if (sourceURL) {
972     return sourceURL;
973   }
974
975   var eval_origin = "eval at ";
976   if (script.eval_from_function_name) {
977     eval_origin += script.eval_from_function_name;
978   } else {
979     eval_origin +=  "<anonymous>";
980   }
981
982   var eval_from_script = script.eval_from_script;
983   if (eval_from_script) {
984     if (eval_from_script.compilation_type == COMPILATION_TYPE_EVAL) {
985       // eval script originated from another eval.
986       eval_origin += " (" + FormatEvalOrigin(eval_from_script) + ")";
987     } else {
988       // eval script originated from "real" source.
989       if (eval_from_script.name) {
990         eval_origin += " (" + eval_from_script.name;
991         var location = eval_from_script.locationFromPosition(
992             script.eval_from_script_position, true);
993         if (location) {
994           eval_origin += ":" + (location.line + 1);
995           eval_origin += ":" + (location.column + 1);
996         }
997         eval_origin += ")";
998       } else {
999         eval_origin += " (unknown source)";
1000       }
1001     }
1002   }
1003
1004   return eval_origin;
1005 }
1006
1007
1008 function FormatErrorString(error) {
1009   try {
1010     return %_CallFunction(error, ErrorToString);
1011   } catch (e) {
1012     try {
1013       return "<error: " + e + ">";
1014     } catch (ee) {
1015       return "<error>";
1016     }
1017   }
1018 }
1019
1020
1021 function GetStackFrames(raw_stack) {
1022   var frames = new InternalArray();
1023   var sloppy_frames = raw_stack[0];
1024   for (var i = 1; i < raw_stack.length; i += 4) {
1025     var recv = raw_stack[i];
1026     var fun = raw_stack[i + 1];
1027     var code = raw_stack[i + 2];
1028     var pc = raw_stack[i + 3];
1029     var pos = %FunctionGetPositionForOffset(code, pc);
1030     sloppy_frames--;
1031     frames.push(new CallSite(recv, fun, pos, (sloppy_frames < 0)));
1032   }
1033   return frames;
1034 }
1035
1036
1037 // Flag to prevent recursive call of Error.prepareStackTrace.
1038 var formatting_custom_stack_trace = false;
1039
1040
1041 function FormatStackTrace(obj, raw_stack) {
1042   var frames = GetStackFrames(raw_stack);
1043   if (IS_FUNCTION($Error.prepareStackTrace) && !formatting_custom_stack_trace) {
1044     var array = [];
1045     %MoveArrayContents(frames, array);
1046     formatting_custom_stack_trace = true;
1047     var stack_trace = UNDEFINED;
1048     try {
1049       stack_trace = $Error.prepareStackTrace(obj, array);
1050     } catch (e) {
1051       throw e;  // The custom formatting function threw.  Rethrow.
1052     } finally {
1053       formatting_custom_stack_trace = false;
1054     }
1055     return stack_trace;
1056   }
1057
1058   var lines = new InternalArray();
1059   lines.push(FormatErrorString(obj));
1060   for (var i = 0; i < frames.length; i++) {
1061     var frame = frames[i];
1062     var line;
1063     try {
1064       line = frame.toString();
1065     } catch (e) {
1066       try {
1067         line = "<error: " + e + ">";
1068       } catch (ee) {
1069         // Any code that reaches this point is seriously nasty!
1070         line = "<error>";
1071       }
1072     }
1073     lines.push("    at " + line);
1074   }
1075   return %_CallFunction(lines, "\n", ArrayJoin);
1076 }
1077
1078
1079 function GetTypeName(receiver, requireConstructor) {
1080   var constructor = receiver.constructor;
1081   if (!constructor) {
1082     return requireConstructor ? null :
1083         %_CallFunction(receiver, NoSideEffectsObjectToString);
1084   }
1085   var constructorName = constructor.name;
1086   if (!constructorName) {
1087     return requireConstructor ? null :
1088         %_CallFunction(receiver, NoSideEffectsObjectToString);
1089   }
1090   return constructorName;
1091 }
1092
1093
1094 var stack_trace_symbol;  // Set during bootstrapping.
1095 var formatted_stack_trace_symbol = NEW_PRIVATE_OWN("formatted stack trace");
1096
1097
1098 // Format the stack trace if not yet done, and return it.
1099 // Cache the formatted stack trace on the holder.
1100 var StackTraceGetter = function() {
1101   var formatted_stack_trace = UNDEFINED;
1102   var holder = this;
1103   while (holder) {
1104     var formatted_stack_trace =
1105       GET_PRIVATE(holder, formatted_stack_trace_symbol);
1106     if (IS_UNDEFINED(formatted_stack_trace)) {
1107       // No formatted stack trace available.
1108       var stack_trace = GET_PRIVATE(holder, stack_trace_symbol);
1109       if (IS_UNDEFINED(stack_trace)) {
1110         // Neither formatted nor structured stack trace available.
1111         // Look further up the prototype chain.
1112         holder = %_GetPrototype(holder);
1113         continue;
1114       }
1115       formatted_stack_trace = FormatStackTrace(holder, stack_trace);
1116       SET_PRIVATE(holder, stack_trace_symbol, UNDEFINED);
1117       SET_PRIVATE(holder, formatted_stack_trace_symbol, formatted_stack_trace);
1118     }
1119     return formatted_stack_trace;
1120   }
1121   return UNDEFINED;
1122 };
1123
1124
1125 // If the receiver equals the holder, set the formatted stack trace that the
1126 // getter returns.
1127 var StackTraceSetter = function(v) {
1128   if (HAS_PRIVATE(this, stack_trace_symbol)) {
1129     SET_PRIVATE(this, stack_trace_symbol, UNDEFINED);
1130     SET_PRIVATE(this, formatted_stack_trace_symbol, v);
1131   }
1132 };
1133
1134
1135 // Use a dummy function since we do not actually want to capture a stack trace
1136 // when constructing the initial Error prototytpes.
1137 var captureStackTrace = function captureStackTrace(obj, cons_opt) {
1138   // Define accessors first, as this may fail and throw.
1139   ObjectDefineProperty(obj, 'stack', { get: StackTraceGetter,
1140                                        set: StackTraceSetter,
1141                                        configurable: true });
1142   %CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace);
1143 }
1144
1145
1146 function SetUpError() {
1147   // Define special error type constructors.
1148
1149   var DefineError = function(f) {
1150     // Store the error function in both the global object
1151     // and the runtime object. The function is fetched
1152     // from the runtime object when throwing errors from
1153     // within the runtime system to avoid strange side
1154     // effects when overwriting the error functions from
1155     // user code.
1156     var name = f.name;
1157     %AddNamedProperty(global, name, f, DONT_ENUM);
1158     %AddNamedProperty(builtins, '$' + name, f,
1159                       DONT_ENUM | DONT_DELETE | READ_ONLY);
1160     // Configure the error function.
1161     if (name == 'Error') {
1162       // The prototype of the Error object must itself be an error.
1163       // However, it can't be an instance of the Error object because
1164       // it hasn't been properly configured yet.  Instead we create a
1165       // special not-a-true-error-but-close-enough object.
1166       var ErrorPrototype = function() {};
1167       %FunctionSetPrototype(ErrorPrototype, $Object.prototype);
1168       %FunctionSetInstanceClassName(ErrorPrototype, 'Error');
1169       %FunctionSetPrototype(f, new ErrorPrototype());
1170     } else {
1171       %FunctionSetPrototype(f, new $Error());
1172     }
1173     %FunctionSetInstanceClassName(f, 'Error');
1174     %AddNamedProperty(f.prototype, 'constructor', f, DONT_ENUM);
1175     %AddNamedProperty(f.prototype, "name", name, DONT_ENUM);
1176     %SetCode(f, function(m) {
1177       if (%_IsConstructCall()) {
1178         try { captureStackTrace(this, f); } catch (e) { }
1179         // Define all the expected properties directly on the error
1180         // object. This avoids going through getters and setters defined
1181         // on prototype objects.
1182         if (!IS_UNDEFINED(m)) {
1183           %AddNamedProperty(this, 'message', ToString(m), DONT_ENUM);
1184         }
1185       } else {
1186         return new f(m);
1187       }
1188     });
1189     %SetNativeFlag(f);
1190   };
1191
1192   DefineError(function Error() { });
1193   DefineError(function TypeError() { });
1194   DefineError(function RangeError() { });
1195   DefineError(function SyntaxError() { });
1196   DefineError(function ReferenceError() { });
1197   DefineError(function EvalError() { });
1198   DefineError(function URIError() { });
1199 }
1200
1201 SetUpError();
1202
1203 $Error.captureStackTrace = captureStackTrace;
1204
1205 %AddNamedProperty($Error.prototype, 'message', '', DONT_ENUM);
1206
1207 // Global list of error objects visited during ErrorToString. This is
1208 // used to detect cycles in error toString formatting.
1209 var visited_errors = new InternalArray();
1210 var cyclic_error_marker = new $Object();
1211
1212 function GetPropertyWithoutInvokingMonkeyGetters(error, name) {
1213   var current = error;
1214   // Climb the prototype chain until we find the holder.
1215   while (current && !%HasOwnProperty(current, name)) {
1216     current = %_GetPrototype(current);
1217   }
1218   if (IS_NULL(current)) return UNDEFINED;
1219   if (!IS_OBJECT(current)) return error[name];
1220   // If the property is an accessor on one of the predefined errors that can be
1221   // generated statically by the compiler, don't touch it. This is to address
1222   // http://code.google.com/p/chromium/issues/detail?id=69187
1223   var desc = %GetOwnProperty(current, name);
1224   if (desc && desc[IS_ACCESSOR_INDEX]) {
1225     var isName = name === "name";
1226     if (current === $ReferenceError.prototype)
1227       return isName ? "ReferenceError" : UNDEFINED;
1228     if (current === $SyntaxError.prototype)
1229       return isName ? "SyntaxError" : UNDEFINED;
1230     if (current === $TypeError.prototype)
1231       return isName ? "TypeError" : UNDEFINED;
1232   }
1233   // Otherwise, read normally.
1234   return error[name];
1235 }
1236
1237 function ErrorToStringDetectCycle(error) {
1238   if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker;
1239   try {
1240     var name = GetPropertyWithoutInvokingMonkeyGetters(error, "name");
1241     name = IS_UNDEFINED(name) ? "Error" : TO_STRING_INLINE(name);
1242     var message = GetPropertyWithoutInvokingMonkeyGetters(error, "message");
1243     message = IS_UNDEFINED(message) ? "" : TO_STRING_INLINE(message);
1244     if (name === "") return message;
1245     if (message === "") return name;
1246     return name + ": " + message;
1247   } finally {
1248     visited_errors.length = visited_errors.length - 1;
1249   }
1250 }
1251
1252 function ErrorToString() {
1253   if (!IS_SPEC_OBJECT(this)) {
1254     throw MakeTypeError("called_on_non_object", ["Error.prototype.toString"]);
1255   }
1256
1257   try {
1258     return ErrorToStringDetectCycle(this);
1259   } catch(e) {
1260     // If this error message was encountered already return the empty
1261     // string for it instead of recursively formatting it.
1262     if (e === cyclic_error_marker) {
1263       return '';
1264     }
1265     throw e;
1266   }
1267 }
1268
1269
1270 InstallFunctions($Error.prototype, DONT_ENUM, ['toString', ErrorToString]);
1271
1272 // Boilerplate for exceptions for stack overflows. Used from
1273 // Isolate::StackOverflow().
1274 function SetUpStackOverflowBoilerplate() {
1275   var boilerplate = MakeRangeError('stack_overflow', []);
1276
1277   %DefineAccessorPropertyUnchecked(
1278       boilerplate, 'stack', StackTraceGetter, StackTraceSetter, DONT_ENUM);
1279
1280   return boilerplate;
1281 }
1282
1283 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate();