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.
5 // -------------------------------------------------------------------
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"],
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"],
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"],
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"],
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"],
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."]
204 function FormatString(format, args) {
207 for (var i = 0; i < format.length; 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;
213 // str is one of %0, %1, %2 or %3.
215 str = NoSideEffectToString(args[arg_num]);
217 if (%IsJSModule(args[arg_num]))
219 else if (IS_SPEC_OBJECT(args[arg_num]))
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);
246 if (IS_SYMBOL(obj)) return %_CallFunction(obj, $symbolToString);
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 + ">";
257 if (CanBeSafelyTreatedAsAnErrorObject(obj)) {
258 return %_CallFunction(obj, ErrorToString);
261 return %_CallFunction(obj, NoSideEffectsObjectToString);
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)) {
274 case 'ReferenceError':
281 var objToString = %GetDataProperty(obj, "toString");
282 return obj instanceof $Error && objToString === ErrorToString;
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);
294 return ToString(obj);
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 + ">";
309 return ToStringCheckErrorObject(obj);
313 function MakeGenericError(constructor, type, args) {
314 if (IS_UNDEFINED(args)) args = [];
315 return new constructor(FormatMessage(type, args));
320 * Set up the Script function and constructor.
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");
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);
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;
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();
360 function MakeTypeError(type, args) {
361 return MakeGenericError($TypeError, type, args);
365 function MakeRangeError(type, args) {
366 return MakeGenericError($RangeError, type, args);
370 function MakeSyntaxError(type, args) {
371 return MakeGenericError($SyntaxError, type, args);
375 function MakeReferenceError(type, args) {
376 return MakeGenericError($ReferenceError, type, args);
380 function MakeEvalError(type, args) {
381 return MakeGenericError($EvalError, type, args);
385 function MakeError(type, args) {
386 return MakeGenericError($Error, type, args);
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]);
397 function MakeSyntaxErrorEmbedded(type, arg) {
398 return MakeGenericError($SyntaxError, type, [arg]);
402 function MakeReferenceErrorEmbedded(type, arg) {
403 return MakeGenericError($ReferenceError, type, [arg]);
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.
412 function ScriptLineFromPosition(position) {
413 var line_ends = this.line_ends;
414 var upper = line_ends.length - 1;
415 if (upper < 0) return -1;
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;
424 var mid = (upper + lower) >> 1;
425 if (position <= line_ends[mid - 1]) {
427 } else if (position > line_ends[mid]){
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.
443 function ScriptLocationFromPosition(position,
444 include_resource_offset) {
445 var line = this.lineFromPosition(position);
446 if (line == -1) return null;
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') {
455 var column = position - start;
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;
465 return new SourceLocation(this, position, line, column, start, end);
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.
481 * @return {SourceLocation}
482 * If line is negative or not in the source null is returned.
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.
488 if (!IS_UNDEFINED(opt_line)) {
489 line = opt_line - this.line_offset;
492 // Default is first column. If on the first line add the offset within the
494 var column = opt_column || 0;
496 column -= this.column_offset;
499 var offset_position = opt_offset_position || 0;
500 if (line < 0 || column < 0 || offset_position < 0) return null;
502 return this.locationFromPosition(offset_position + column, false);
504 // Find the line where the offset position is located.
505 var offset_line = this.lineFromPosition(offset_position);
507 if (offset_line == -1 || offset_line + line >= this.lineCount()) {
511 return this.locationFromPosition(
512 this.line_ends[offset_line + line - 1] + 1 + column); // line > 0 here.
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.
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
527 function ScriptSourceSlice(opt_from_line, opt_to_line) {
528 var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset
530 var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
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();
540 if (from_line >= this.lineCount() ||
542 from_line > to_line) {
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;
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);
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.
562 if (!IS_UNDEFINED(opt_line)) {
563 line = opt_line - this.line_offset;
567 if (line < 0 || this.lineCount() <= line) {
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);
580 * Returns the number of source lines.
582 * Number of source lines.
584 function ScriptLineCount() {
585 // Return number of source lines.
586 return this.line_ends.length;
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.
597 * @return {?string} script name if present, value for //# sourceURL or
598 * deprecated //@ sourceURL comment otherwise.
600 function ScriptNameOrSourceURL() {
601 if (this.line_offset > 0 || this.column_offset > 0) {
604 if (this.source_url) {
605 return this.source_url;
611 SetUpLockedPrototype(Script,
612 $Array("source", "name", "source_url", "source_mapping_url", "line_ends",
613 "line_offset", "column_offset"),
615 "lineFromPosition", ScriptLineFromPosition,
616 "locationFromPosition", ScriptLocationFromPosition,
617 "locationFromLine", ScriptLocationFromLine,
618 "sourceSlice", ScriptSourceSlice,
619 "sourceLine", ScriptSourceLine,
620 "lineCount", ScriptLineCount,
621 "nameOrSourceURL", ScriptNameOrSourceURL
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
647 function SourceLocation(script, position, line, column, start, end) {
648 this.script = script;
649 this.position = position;
651 this.column = column;
658 * Get the source text for a SourceLocation
660 * Source text for this location.
662 function SourceLocationSourceText() {
663 return %_CallFunction(this.script.source,
670 SetUpLockedPrototype(SourceLocation,
671 $Array("script", "position", "line", "column", "start", "end"),
673 "sourceText", SourceLocationSourceText
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
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;
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)
709 function SourceSliceSourceText() {
710 return %_CallFunction(this.script.source,
716 SetUpLockedPrototype(SourceSlice,
717 $Array("script", "from_line", "to_line", "from_position", "to_position"),
718 $Array("sourceText", SourceSliceSourceText)
722 // Returns the offset of the given position within the containing
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;
733 function GetStackTraceLine(recv, fun, pos, isGlobal) {
734 return new CallSite(recv, fun, pos, false).toString();
737 // ----------------------------------------------------------------------------
738 // Error implementation
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");
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);
752 function CallSiteGetThis() {
753 return GET_PRIVATE(this, CallSiteStrictModeKey)
754 ? UNDEFINED : GET_PRIVATE(this, CallSiteReceiverKey);
757 function CallSiteGetTypeName() {
758 return GetTypeName(GET_PRIVATE(this, CallSiteReceiverKey), false);
761 function CallSiteIsToplevel() {
762 if (GET_PRIVATE(this, CallSiteReceiverKey) == null) {
765 return IS_GLOBAL(GET_PRIVATE(this, CallSiteReceiverKey));
768 function CallSiteIsEval() {
769 var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
770 return script && script.compilation_type == COMPILATION_TYPE_EVAL;
773 function CallSiteGetEvalOrigin() {
774 var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
775 return FormatEvalOrigin(script);
778 function CallSiteGetScriptNameOrSourceURL() {
779 var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
780 return script ? script.nameOrSourceURL() : null;
783 function CallSiteGetFunction() {
784 return GET_PRIVATE(this, CallSiteStrictModeKey)
785 ? UNDEFINED : GET_PRIVATE(this, CallSiteFunctionKey);
788 function CallSiteGetFunctionName() {
789 // See if the function knows its own name
790 var fun = GET_PRIVATE(this, CallSiteFunctionKey);
791 var name = %FunctionGetDebugName(fun);
795 // Maybe this is an evaluation?
796 var script = %FunctionGetScript(fun);
797 if (script && script.compilation_type == COMPILATION_TYPE_EVAL) {
803 function CallSiteGetMethodName() {
804 // See if we can find a unique property on the receiver that holds
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.
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.
835 function CallSiteGetFileName() {
836 var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
837 return script ? script.name : null;
840 function CallSiteGetLineNumber() {
841 if (GET_PRIVATE(this, CallSitePositionKey) == -1) {
844 var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
847 location = script.locationFromPosition(
848 GET_PRIVATE(this, CallSitePositionKey), true);
850 return location ? location.line + 1 : null;
853 function CallSiteGetColumnNumber() {
854 if (GET_PRIVATE(this, CallSitePositionKey) == -1) {
857 var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
860 location = script.locationFromPosition(
861 GET_PRIVATE(this, CallSitePositionKey), true);
863 return location ? location.column + 1: null;
866 function CallSiteIsNative() {
867 var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
868 return script ? (script.type == TYPE_NATIVE) : false;
871 function CallSiteGetPosition() {
872 return GET_PRIVATE(this, CallSitePositionKey);
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;
883 function CallSiteToString() {
885 var fileLocation = "";
886 if (this.isNative()) {
887 fileLocation = "native";
889 fileName = this.getScriptNameOrSourceURL();
890 if (!fileName && this.isEval()) {
891 fileLocation = this.getEvalOrigin();
892 fileLocation += ", "; // Expecting source position to follow.
896 fileLocation += fileName;
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
901 fileLocation += "<anonymous>";
903 var lineNumber = this.getLineNumber();
904 if (lineNumber != null) {
905 fileLocation += ":" + lineNumber;
906 var columnNumber = this.getColumnNumber();
908 fileLocation += ":" + columnNumber;
914 var functionName = this.getFunctionName();
915 var addSuffix = true;
916 var isConstructor = this.isConstructor();
917 var isMethodCall = !(this.isToplevel() || isConstructor);
919 var typeName = GetTypeName(GET_PRIVATE(this, CallSiteReceiverKey), true);
920 var methodName = this.getMethodName();
923 %_CallFunction(functionName, typeName, $stringIndexOf) != 0) {
924 line += typeName + ".";
926 line += functionName;
928 (%_CallFunction(functionName, "." + methodName, $stringIndexOf) !=
929 functionName.length - methodName.length - 1)) {
930 line += " [as " + methodName + "]";
933 line += typeName + "." + (methodName || "<anonymous>");
935 } else if (isConstructor) {
936 line += "new " + (functionName || "<anonymous>");
937 } else if (functionName) {
938 line += functionName;
940 line += fileLocation;
944 line += " (" + fileLocation + ")";
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
969 function FormatEvalOrigin(script) {
970 var sourceURL = script.nameOrSourceURL();
975 var eval_origin = "eval at ";
976 if (script.eval_from_function_name) {
977 eval_origin += script.eval_from_function_name;
979 eval_origin += "<anonymous>";
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) + ")";
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);
994 eval_origin += ":" + (location.line + 1);
995 eval_origin += ":" + (location.column + 1);
999 eval_origin += " (unknown source)";
1008 function FormatErrorString(error) {
1010 return %_CallFunction(error, ErrorToString);
1013 return "<error: " + e + ">";
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);
1031 frames.push(new CallSite(recv, fun, pos, (sloppy_frames < 0)));
1037 // Flag to prevent recursive call of Error.prepareStackTrace.
1038 var formatting_custom_stack_trace = false;
1041 function FormatStackTrace(obj, raw_stack) {
1042 var frames = GetStackFrames(raw_stack);
1043 if (IS_FUNCTION($Error.prepareStackTrace) && !formatting_custom_stack_trace) {
1045 %MoveArrayContents(frames, array);
1046 formatting_custom_stack_trace = true;
1047 var stack_trace = UNDEFINED;
1049 stack_trace = $Error.prepareStackTrace(obj, array);
1051 throw e; // The custom formatting function threw. Rethrow.
1053 formatting_custom_stack_trace = false;
1058 var lines = new InternalArray();
1059 lines.push(FormatErrorString(obj));
1060 for (var i = 0; i < frames.length; i++) {
1061 var frame = frames[i];
1064 line = frame.toString();
1067 line = "<error: " + e + ">";
1069 // Any code that reaches this point is seriously nasty!
1073 lines.push(" at " + line);
1075 return %_CallFunction(lines, "\n", ArrayJoin);
1079 function GetTypeName(receiver, requireConstructor) {
1080 var constructor = receiver.constructor;
1082 return requireConstructor ? null :
1083 %_CallFunction(receiver, NoSideEffectsObjectToString);
1085 var constructorName = constructor.name;
1086 if (!constructorName) {
1087 return requireConstructor ? null :
1088 %_CallFunction(receiver, NoSideEffectsObjectToString);
1090 return constructorName;
1094 var stack_trace_symbol; // Set during bootstrapping.
1095 var formatted_stack_trace_symbol = NEW_PRIVATE_OWN("formatted stack trace");
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;
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);
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);
1119 return formatted_stack_trace;
1125 // If the receiver equals the holder, set the formatted stack trace that the
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);
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);
1146 function SetUpError() {
1147 // Define special error type constructors.
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
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());
1171 %FunctionSetPrototype(f, new $Error());
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);
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() { });
1203 $Error.captureStackTrace = captureStackTrace;
1205 %AddNamedProperty($Error.prototype, 'message', '', DONT_ENUM);
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();
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);
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;
1233 // Otherwise, read normally.
1237 function ErrorToStringDetectCycle(error) {
1238 if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker;
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;
1248 visited_errors.length = visited_errors.length - 1;
1252 function ErrorToString() {
1253 if (!IS_SPEC_OBJECT(this)) {
1254 throw MakeTypeError("called_on_non_object", ["Error.prototype.toString"]);
1258 return ErrorToStringDetectCycle(this);
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) {
1270 InstallFunctions($Error.prototype, DONT_ENUM, ['toString', ErrorToString]);
1272 // Boilerplate for exceptions for stack overflows. Used from
1273 // Isolate::StackOverflow().
1274 function SetUpStackOverflowBoilerplate() {
1275 var boilerplate = MakeRangeError('stack_overflow', []);
1277 %DefineAccessorPropertyUnchecked(
1278 boilerplate, 'stack', StackTraceGetter, StackTraceSetter, DONT_ENUM);
1283 var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate();