My favorites | Sign in
v8
Project Home Downloads Wiki Issues Source Code Search
Checkout   Browse   Changes  
Changes to /trunk/src/messages.js
r12693 vs. r12706 Compare: vs.  Format:
Revision r12706
Go to: 
Project members, sign in to write a code review
/trunk/src/messages.js   r12693 /trunk/src/messages.js   r12706
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
11 // with the distribution. 11 // with the distribution.
12 // * Neither the name of Google Inc. nor the names of its 12 // * Neither the name of Google Inc. nor the names of its
13 // contributors may be used to endorse or promote products derived 13 // contributors may be used to endorse or promote products derived
14 // from this software without specific prior written permission. 14 // from this software without specific prior written permission.
15 // 15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 // ------------------------------------------------------------------- 28 // -------------------------------------------------------------------
29 // 29 //
30 // If this object gets passed to an error constructor the error will 30 // If this object gets passed to an error constructor the error will
31 // get an accessor for .message that constructs a descriptive error 31 // get an accessor for .message that constructs a descriptive error
32 // message on access. 32 // message on access.
33 var kAddMessageAccessorsMarker = { }; 33 var kAddMessageAccessorsMarker = { };
34 34
35 // This will be lazily initialized when first needed (and forcibly 35 // This will be lazily initialized when first needed (and forcibly
36 // overwritten even though it's const). 36 // overwritten even though it's const).
37 var kMessages = 0; 37 var kMessages = 0;
38 38
39 function FormatString(format, message) { 39 function FormatString(format, message) {
40 var args = %MessageGetArguments(message); 40 var args = %MessageGetArguments(message);
41 var result = ""; 41 var result = "";
42 var arg_num = 0; 42 var arg_num = 0;
43 for (var i = 0; i < format.length; i++) { 43 for (var i = 0; i < format.length; i++) {
44 var str = format[i]; 44 var str = format[i];
45 if (str.length == 2 && %_StringCharCodeAt(str, 0) == 0x25) { 45 if (str.length == 2 && %_StringCharCodeAt(str, 0) == 0x25) {
46 // Two-char string starts with "%". 46 // Two-char string starts with "%".
47 var arg_num = (%_StringCharCodeAt(str, 1) - 0x30) >>> 0; 47 var arg_num = (%_StringCharCodeAt(str, 1) - 0x30) >>> 0;
48 if (arg_num < 4) { 48 if (arg_num < 4) {
49 // str is one of %0, %1, %2 or %3. 49 // str is one of %0, %1, %2 or %3.
50 try { 50 try {
51 str = ToDetailString(args[arg_num]); 51 str = ToDetailString(args[arg_num]);
52 } catch (e) { 52 } catch (e) {
53 if (%IsJSModule(args[arg_num])) 53 if (%IsJSModule(args[arg_num]))
54 str = "module"; 54 str = "module";
55 else if (IS_SPEC_OBJECT(args[arg_num])) 55 else if (IS_SPEC_OBJECT(args[arg_num]))
56 str = "object"; 56 str = "object";
57 else 57 else
58 str = "#<error>"; 58 str = "#<error>";
59 } 59 }
60 } 60 }
61 } 61 }
62 result += str; 62 result += str;
63 } 63 }
64 return result; 64 return result;
65 } 65 }
66 66
67 67
68 // To check if something is a native error we need to check the 68 // To check if something is a native error we need to check the
69 // concrete native error types. It is not sufficient to use instanceof 69 // concrete native error types. It is not sufficient to use instanceof
70 // since it possible to create an object that has Error.prototype on 70 // since it possible to create an object that has Error.prototype on
71 // its prototype chain. This is the case for DOMException for example. 71 // its prototype chain. This is the case for DOMException for example.
72 function IsNativeErrorObject(obj) { 72 function IsNativeErrorObject(obj) {
73 switch (%_ClassOf(obj)) { 73 switch (%_ClassOf(obj)) {
74 case 'Error': 74 case 'Error':
75 case 'EvalError': 75 case 'EvalError':
76 case 'RangeError': 76 case 'RangeError':
77 case 'ReferenceError': 77 case 'ReferenceError':
78 case 'SyntaxError': 78 case 'SyntaxError':
79 case 'TypeError': 79 case 'TypeError':
80 case 'URIError': 80 case 'URIError':
81 return true; 81 return true;
82 } 82 }
83 return false; 83 return false;
84 } 84 }
85 85
86 86
87 // When formatting internally created error messages, do not 87 // When formatting internally created error messages, do not
88 // invoke overwritten error toString methods but explicitly use 88 // invoke overwritten error toString methods but explicitly use
89 // the error to string method. This is to avoid leaking error 89 // the error to string method. This is to avoid leaking error
90 // objects between script tags in a browser setting. 90 // objects between script tags in a browser setting.
91 function ToStringCheckErrorObject(obj) { 91 function ToStringCheckErrorObject(obj) {
92 if (IsNativeErrorObject(obj)) { 92 if (IsNativeErrorObject(obj)) {
93 return %_CallFunction(obj, ErrorToString); 93 return %_CallFunction(obj, ErrorToString);
94 } else { 94 } else {
95 return ToString(obj); 95 return ToString(obj);
96 } 96 }
97 } 97 }
98 98
99 99
100 function ToDetailString(obj) { 100 function ToDetailString(obj) {
101 if (obj != null && IS_OBJECT(obj) && obj.toString === ObjectToString) { 101 if (obj != null && IS_OBJECT(obj) && obj.toString === ObjectToString) {
102 var constructor = obj.constructor; 102 var constructor = obj.constructor;
103 if (typeof constructor == "function") { 103 if (typeof constructor == "function") {
104 var constructorName = constructor.name; 104 var constructorName = constructor.name;
105 if (IS_STRING(constructorName) && constructorName !== "") { 105 if (IS_STRING(constructorName) && constructorName !== "") {
106 return "#<" + constructorName + ">"; 106 return "#<" + constructorName + ">";
107 } 107 }
108 } 108 }
109 } 109 }
110 return ToStringCheckErrorObject(obj); 110 return ToStringCheckErrorObject(obj);
111 } 111 }
112 112
113 113
114 function MakeGenericError(constructor, type, args) { 114 function MakeGenericError(constructor, type, args) {
115 if (IS_UNDEFINED(args)) { 115 if (IS_UNDEFINED(args)) {
116 args = []; 116 args = [];
117 } 117 }
118 var e = new constructor(kAddMessageAccessorsMarker); 118 var e = new constructor(kAddMessageAccessorsMarker);
119 e.type = type; 119 e.type = type;
120 e.arguments = args; 120 e.arguments = args;
121 return e; 121 return e;
122 } 122 }
123 123
124 124
125 /** 125 /**
126 * Set up the Script function and constructor. 126 * Set up the Script function and constructor.
127 */ 127 */
128 %FunctionSetInstanceClassName(Script, 'Script'); 128 %FunctionSetInstanceClassName(Script, 'Script');
129 %SetProperty(Script.prototype, 'constructor', Script, 129 %SetProperty(Script.prototype, 'constructor', Script,
130 DONT_ENUM | DONT_DELETE | READ_ONLY); 130 DONT_ENUM | DONT_DELETE | READ_ONLY);
131 %SetCode(Script, function(x) { 131 %SetCode(Script, function(x) {
132 // Script objects can only be created by the VM. 132 // Script objects can only be created by the VM.
133 throw new $Error("Not supported"); 133 throw new $Error("Not supported");
134 }); 134 });
135 135
136 136
137 // Helper functions; called from the runtime system. 137 // Helper functions; called from the runtime system.
138 function FormatMessage(message) { 138 function FormatMessage(message) {
139 if (kMessages === 0) { 139 if (kMessages === 0) {
140 var messagesDictionary = [ 140 var messagesDictionary = [
141 // Error 141 // Error
142 "cyclic_proto", ["Cyclic __proto__ value"], 142 "cyclic_proto", ["Cyclic __proto__ value"],
143 "code_gen_from_strings", ["%0"], 143 "code_gen_from_strings", ["%0"],
144 // TypeError 144 // TypeError
145 "unexpected_token", ["Unexpected token ", "%0"], 145 "unexpected_token", ["Unexpected token ", "%0"],
146 "unexpected_token_number", ["Unexpected number"], 146 "unexpected_token_number", ["Unexpected number"],
147 "unexpected_token_string", ["Unexpected string"], 147 "unexpected_token_string", ["Unexpected string"],
148 "unexpected_token_identifier", ["Unexpected identifier"], 148 "unexpected_token_identifier", ["Unexpected identifier"],
149 "unexpected_reserved", ["Unexpected reserved word"], 149 "unexpected_reserved", ["Unexpected reserved word"],
150 "unexpected_strict_reserved", ["Unexpected strict mode reserved word"], 150 "unexpected_strict_reserved", ["Unexpected strict mode reserved word"],
151 "unexpected_eos", ["Unexpected end of input"], 151 "unexpected_eos", ["Unexpected end of input"],
152 "malformed_regexp", ["Invalid regular expression: /", "%0", "/: ", "%1"], 152 "malformed_regexp", ["Invalid regular expression: /", "%0", "/: ", "%1"],
153 "unterminated_regexp", ["Invalid regular expression: missing /"], 153 "unterminated_regexp", ["Invalid regular expression: missing /"],
154 "regexp_flags", ["Cannot supply flags when constructing one RegExp from another"], 154 "regexp_flags", ["Cannot supply flags when constructing one RegExp from another"],
155 "incompatible_method_receiver", ["Method ", "%0", " called on incompatible receiver ", "%1"], 155 "incompatible_method_receiver", ["Method ", "%0", " called on incompatible receiver ", "%1"],
156 "invalid_lhs_in_assignment", ["Invalid left-hand side in assignment"], 156 "invalid_lhs_in_assignment", ["Invalid left-hand side in assignment"],
157 "invalid_lhs_in_for_in", ["Invalid left-hand side in for-in"], 157 "invalid_lhs_in_for_in", ["Invalid left-hand side in for-in"],
158 "invalid_lhs_in_postfix_op", ["Invalid left-hand side expression in postfix operation"], 158 "invalid_lhs_in_postfix_op", ["Invalid left-hand side expression in postfix operation"],
159 "invalid_lhs_in_prefix_op", ["Invalid left-hand side expression in prefix operation"], 159 "invalid_lhs_in_prefix_op", ["Invalid left-hand side expression in prefix operation"],
160 "multiple_defaults_in_switch", ["More than one default clause in switch statement"], 160 "multiple_defaults_in_switch", ["More than one default clause in switch statement"],
161 "newline_after_throw", ["Illegal newline after throw"], 161 "newline_after_throw", ["Illegal newline after throw"],
162 "redeclaration", ["%0", " '", "%1", "' has already been declared"], 162 "redeclaration", ["%0", " '", "%1", "' has already been declared"],
163 "no_catch_or_finally", ["Missing catch or finally after try"], 163 "no_catch_or_finally", ["Missing catch or finally after try"],
164 "unknown_label", ["Undefined label '", "%0", "'"], 164 "unknown_label", ["Undefined label '", "%0", "'"],
165 "uncaught_exception", ["Uncaught ", "%0"], 165 "uncaught_exception", ["Uncaught ", "%0"],
166 "stack_trace", ["Stack Trace:\n", "%0"], 166 "stack_trace", ["Stack Trace:\n", "%0"],
167 "called_non_callable", ["%0", " is not a function"], 167 "called_non_callable", ["%0", " is not a function"],
168 "undefined_method", ["Object ", "%1", " has no method '", "%0", "'"], 168 "undefined_method", ["Object ", "%1", " has no method '", "%0", "'"],
169 "property_not_function", ["Property '", "%0", "' of object ", "%1", " is not a function"], 169 "property_not_function", ["Property '", "%0", "' of object ", "%1", " is not a function"],
170 "cannot_convert_to_primitive", ["Cannot convert object to primitive value"], 170 "cannot_convert_to_primitive", ["Cannot convert object to primitive value"],
171 "not_constructor", ["%0", " is not a constructor"], 171 "not_constructor", ["%0", " is not a constructor"],
172 "not_defined", ["%0", " is not defined"], 172 "not_defined", ["%0", " is not defined"],
173 "non_object_property_load", ["Cannot read property '", "%0", "' of ", "%1"], 173 "non_object_property_load", ["Cannot read property '", "%0", "' of ", "%1"],
174 "non_object_property_store", ["Cannot set property '", "%0", "' of ", "%1"], 174 "non_object_property_store", ["Cannot set property '", "%0", "' of ", "%1"],
175 "non_object_property_call", ["Cannot call method '", "%0", "' of ", "%1"], 175 "non_object_property_call", ["Cannot call method '", "%0", "' of ", "%1"],
176 "with_expression", ["%0", " has no properties"], 176 "with_expression", ["%0", " has no properties"],
177 "illegal_invocation", ["Illegal invocation"], 177 "illegal_invocation", ["Illegal invocation"],
178 "no_setter_in_callback", ["Cannot set property ", "%0", " of ", "%1", " which has only a getter"], 178 "no_setter_in_callback", ["Cannot set property ", "%0", " of ", "%1", " which has only a getter"],
179 "apply_non_function", ["Function.prototype.apply was called on ", "%0", ", which is a ", "%1", " and not a function"], 179 "apply_non_function", ["Function.prototype.apply was called on ", "%0", ", which is a ", "%1", " and not a function"],
180 "apply_wrong_args", ["Function.prototype.apply: Arguments list has wrong type"], 180 "apply_wrong_args", ["Function.prototype.apply: Arguments list has wrong type"],
181 "invalid_in_operator_use", ["Cannot use 'in' operator to search for '", "%0", "' in ", "%1"], 181 "invalid_in_operator_use", ["Cannot use 'in' operator to search for '", "%0", "' in ", "%1"],
182 "instanceof_function_expected", ["Expecting a function in instanceof check, but got ", "%0"], 182 "instanceof_function_expected", ["Expecting a function in instanceof check, but got ", "%0"],
183 "instanceof_nonobject_proto", ["Function has non-object prototype '", "%0", "' in instanceof check"], 183 "instanceof_nonobject_proto", ["Function has non-object prototype '", "%0", "' in instanceof check"],
184 "null_to_object", ["Cannot convert null to object"], 184 "null_to_object", ["Cannot convert null to object"],
185 "reduce_no_initial", ["Reduce of empty array with no initial value"], 185 "reduce_no_initial", ["Reduce of empty array with no initial value"],
186 "getter_must_be_callable", ["Getter must be a function: ", "%0"], 186 "getter_must_be_callable", ["Getter must be a function: ", "%0"],
187 "setter_must_be_callable", ["Setter must be a function: ", "%0"], 187 "setter_must_be_callable", ["Setter must be a function: ", "%0"],
188 "value_and_accessor", ["Invalid property. A property cannot both have accessors and be writable or have a value, ", "%0"], 188 "value_and_accessor", ["Invalid property. A property cannot both have accessors and be writable or have a value, ", "%0"],
189 "proto_object_or_null", ["Object prototype may only be an Object or null"], 189 "proto_object_or_null", ["Object prototype may only be an Object or null"],
190 "property_desc_object", ["Property description must be an object: ", "%0"], 190 "property_desc_object", ["Property description must be an object: ", "%0"],
191 "redefine_disallowed", ["Cannot redefine property: ", "%0"], 191 "redefine_disallowed", ["Cannot redefine property: ", "%0"],
192 "define_disallowed", ["Cannot define property:", "%0", ", object is not extensible."], 192 "define_disallowed", ["Cannot define property:", "%0", ", object is not extensible."],
193 "non_extensible_proto", ["%0", " is not extensible"], 193 "non_extensible_proto", ["%0", " is not extensible"],
194 "handler_non_object", ["Proxy.", "%0", " called with non-object as handler"], 194 "handler_non_object", ["Proxy.", "%0", " called with non-object as handler"],
195 "proto_non_object", ["Proxy.", "%0", " called with non-object as prototype"], 195 "proto_non_object", ["Proxy.", "%0", " called with non-object as prototype"],
196 "trap_function_expected", ["Proxy.", "%0", " called with non-function for '", "%1", "' trap"], 196 "trap_function_expected", ["Proxy.", "%0", " called with non-function for '", "%1", "' trap"],
197 "handler_trap_missing", ["Proxy handler ", "%0", " has no '", "%1", "' trap"], 197 "handler_trap_missing", ["Proxy handler ", "%0", " has no '", "%1", "' trap"],
198 "handler_trap_must_be_callable", ["Proxy handler ", "%0", " has non-callable '", "%1", "' trap"], 198 "handler_trap_must_be_callable", ["Proxy handler ", "%0", " has non-callable '", "%1", "' trap"],
199 "handler_returned_false", ["Proxy handler ", "%0", " returned false from '", "%1", "' trap"], 199 "handler_returned_false", ["Proxy handler ", "%0", " returned false from '", "%1", "' trap"],
200 "handler_returned_undefined", ["Proxy handler ", "%0", " returned undefined from '", "%1", "' trap"], 200 "handler_returned_undefined", ["Proxy handler ", "%0", " returned undefined from '", "%1", "' trap"],
201 "proxy_prop_not_configurable", ["Proxy handler ", "%0", " returned non-configurable descriptor for property '", "%2", "' from '", "%1", "' trap"], 201 "proxy_prop_not_configurable", ["Proxy handler ", "%0", " returned non-configurable descriptor for property '", "%2", "' from '", "%1", "' trap"],
202 "proxy_non_object_prop_names", ["Trap '", "%1", "' returned non-object ", "%0"], 202 "proxy_non_object_prop_names", ["Trap '", "%1", "' returned non-object ", "%0"],
203 "proxy_repeated_prop_name", ["Trap '", "%1", "' returned repeated property name '", "%2", "'"], 203 "proxy_repeated_prop_name", ["Trap '", "%1", "' returned repeated property name '", "%2", "'"],
204 "invalid_weakmap_key", ["Invalid value used as weak map key"], 204 "invalid_weakmap_key", ["Invalid value used as weak map key"],
205 "not_date_object", ["this is not a Date object."], 205 "not_date_object", ["this is not a Date object."],
206 // RangeError 206 // RangeError
207 "invalid_array_length", ["Invalid array length"], 207 "invalid_array_length", ["Invalid array length"],
208 "stack_overflow", ["Maximum call stack size exceeded"], 208 "stack_overflow", ["Maximum call stack size exceeded"],
209 "invalid_time_value", ["Invalid time value"], 209 "invalid_time_value", ["Invalid time value"],
210 // SyntaxError 210 // SyntaxError
211 "unable_to_parse", ["Parse error"], 211 "unable_to_parse", ["Parse error"],
212 "invalid_regexp_flags", ["Invalid flags supplied to RegExp constructor '", "%0", "'"], 212 "invalid_regexp_flags", ["Invalid flags supplied to RegExp constructor '", "%0", "'"],
213 "invalid_regexp", ["Invalid RegExp pattern /", "%0", "/"], 213 "invalid_regexp", ["Invalid RegExp pattern /", "%0", "/"],
214 "illegal_break", ["Illegal break statement"], 214 "illegal_break", ["Illegal break statement"],
215 "illegal_continue", ["Illegal continue statement"], 215 "illegal_continue", ["Illegal continue statement"],
216 "illegal_return", ["Illegal return statement"], 216 "illegal_return", ["Illegal return statement"],
217 "illegal_let", ["Illegal let declaration outside extended mode"], 217 "illegal_let", ["Illegal let declaration outside extended mode"],
218 "error_loading_debugger", ["Error loading debugger"], 218 "error_loading_debugger", ["Error loading debugger"],
219 "no_input_to_regexp", ["No input to ", "%0"], 219 "no_input_to_regexp", ["No input to ", "%0"],
220 "invalid_json", ["String '", "%0", "' is not valid JSON"], 220 "invalid_json", ["String '", "%0", "' is not valid JSON"],
221 "circular_structure", ["Converting circular structure to JSON"], 221 "circular_structure", ["Converting circular structure to JSON"],
222 "called_on_non_object", ["%0", " called on non-object"], 222 "called_on_non_object", ["%0", " called on non-object"],
223 "called_on_null_or_undefined", ["%0", " called on null or undefined"], 223 "called_on_null_or_undefined", ["%0", " called on null or undefined"],
224 "array_indexof_not_defined", ["Array.getIndexOf: Argument undefined"], 224 "array_indexof_not_defined", ["Array.getIndexOf: Argument undefined"],
225 "object_not_extensible", ["Can't add property ", "%0", ", object is not extensible"], 225 "object_not_extensible", ["Can't add property ", "%0", ", object is not extensible"],
226 "illegal_access", ["Illegal access"], 226 "illegal_access", ["Illegal access"],
227 "invalid_preparser_data", ["Invalid preparser data for function ", "%0"], 227 "invalid_preparser_data", ["Invalid preparser data for function ", "%0"],
228 "strict_mode_with", ["Strict mode code may not include a with statement"], 228 "strict_mode_with", ["Strict mode code may not include a with statement"],
229 "strict_catch_variable", ["Catch variable may not be eval or arguments in strict mode"], 229 "strict_catch_variable", ["Catch variable may not be eval or arguments in strict mode"],
230 "too_many_arguments", ["Too many arguments in function call (only 32766 allowed)"], 230 "too_many_arguments", ["Too many arguments in function call (only 32766 allowed)"],
231 "too_many_parameters", ["Too many parameters in function definition (only 32766 allowed)"], 231 "too_many_parameters", ["Too many parameters in function definition (only 32766 allowed)"],
232 "too_many_variables", ["Too many variables declared (only 65535 allowed)"], 232 "too_many_variables", ["Too many variables declared (only 131071 allowed)"],
233 "strict_param_name", ["Parameter name eval or arguments is not allowed in strict mode"], 233 "strict_param_name", ["Parameter name eval or arguments is not allowed in strict mode"],
234 "strict_param_dupe", ["Strict mode function may not have duplicate parameter names"], 234 "strict_param_dupe", ["Strict mode function may not have duplicate parameter names"],
235 "strict_var_name", ["Variable name may not be eval or arguments in strict mode"], 235 "strict_var_name", ["Variable name may not be eval or arguments in strict mode"],
236 "strict_function_name", ["Function name may not be eval or arguments in strict mode"], 236 "strict_function_name", ["Function name may not be eval or arguments in strict mode"],
237 "strict_octal_literal", ["Octal literals are not allowed in strict mode."], 237 "strict_octal_literal", ["Octal literals are not allowed in strict mode."],
238 "strict_duplicate_property", ["Duplicate data property in object literal not allowed in strict mode"], 238 "strict_duplicate_property", ["Duplicate data property in object literal not allowed in strict mode"],
239 "accessor_data_property", ["Object literal may not have data and accessor property with the same name"], 239 "accessor_data_property", ["Object literal may not have data and accessor property with the same name"],
240 "accessor_get_set", ["Object literal may not have multiple get/set accessors with the same name"], 240 "accessor_get_set", ["Object literal may not have multiple get/set accessors with the same name"],
241 "strict_lhs_assignment", ["Assignment to eval or arguments is not allowed in strict mode"], 241 "strict_lhs_assignment", ["Assignment to eval or arguments is not allowed in strict mode"],
242 "strict_lhs_postfix", ["Postfix increment/decrement may not have eval or arguments operand in strict mode"], 242 "strict_lhs_postfix", ["Postfix increment/decrement may not have eval or arguments operand in strict mode"],
243 "strict_lhs_prefix", ["Prefix increment/decrement may not have eval or arguments operand in strict mode"], 243 "strict_lhs_prefix", ["Prefix increment/decrement may not have eval or arguments operand in strict mode"],
244 "strict_reserved_word", ["Use of future reserved word in strict mode"], 244 "strict_reserved_word", ["Use of future reserved word in strict mode"],
245 "strict_delete", ["Delete of an unqualified identifier in strict mode."], 245 "strict_delete", ["Delete of an unqualified identifier in strict mode."],
246 "strict_delete_property", ["Cannot delete property '", "%0", "' of ", "%1"], 246 "strict_delete_property", ["Cannot delete property '", "%0", "' of ", "%1"],
247 "strict_const", ["Use of const in strict mode."], 247 "strict_const", ["Use of const in strict mode."],
248 "strict_function", ["In strict mode code, functions can only be declared at top level or immediately within another function." ], 248 "strict_function", ["In strict mode code, functions can only be declared at top level or immediately within another function." ],
249 "strict_read_only_property", ["Cannot assign to read only property '", "%0", "' of ", "%1"], 249 "strict_read_only_property", ["Cannot assign to read only property '", "%0", "' of ", "%1"],
250 "strict_cannot_assign", ["Cannot assign to read only '", "%0", "' in strict mode"], 250 "strict_cannot_assign", ["Cannot assign to read only '", "%0", "' in strict mode"],
251 "strict_poison_pill", ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"], 251 "strict_poison_pill", ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"],
252 "strict_caller", ["Illegal access to a strict mode caller function."], 252 "strict_caller", ["Illegal access to a strict mode caller function."],
253 "unprotected_let", ["Illegal let declaration in unprotected statement context."], 253 "unprotected_let", ["Illegal let declaration in unprotected statement context."],
254 "unprotected_const", ["Illegal const declaration in unprotected statement context."], 254 "unprotected_const", ["Illegal const declaration in unprotected statement context."],
255 "cant_prevent_ext_external_array_elements", ["Cannot prevent extension of an object with external array elements"], 255 "cant_prevent_ext_external_array_elements", ["Cannot prevent extension of an object with external array elements"],
256 "redef_external_array_element", ["Cannot redefine a property of an object with external array elements"], 256 "redef_external_array_element", ["Cannot redefine a property of an object with external array elements"],
257 "harmony_const_assign", ["Assignment to constant variable."], 257 "harmony_const_assign", ["Assignment to constant variable."],
258 "invalid_module_path", ["Module does not export '", "%0", "', or export is not itself a module"], 258 "invalid_module_path", ["Module does not export '", "%0", "', or export is not itself a module"],
259 "module_type_error", ["Module '", "%0", "' used improperly"], 259 "module_type_error", ["Module '", "%0", "' used improperly"],
260 "module_export_undefined", ["Export '", "%0", "' is not defined in module"], 260 "module_export_undefined", ["Export '", "%0", "' is not defined in module"],
261 ]; 261 ];
262 var messages = { __proto__ : null }; 262 var messages = { __proto__ : null };
263 for (var i = 0; i < messagesDictionary.length; i += 2) { 263 for (var i = 0; i < messagesDictionary.length; i += 2) {
264 var key = messagesDictionary[i]; 264 var key = messagesDictionary[i];
265 var format = messagesDictionary[i + 1]; 265 var format = messagesDictionary[i + 1];
266 266
267 for (var j = 0; j < format.length; j++) { 267 for (var j = 0; j < format.length; j++) {
268 %IgnoreAttributesAndSetProperty(format, %_NumberToString(j), format[j], 268 %IgnoreAttributesAndSetProperty(format, %_NumberToString(j), format[j],
269 DONT_DELETE | READ_ONLY | DONT_ENUM); 269 DONT_DELETE | READ_ONLY | DONT_ENUM);
270 } 270 }
271 %IgnoreAttributesAndSetProperty(format, 'length', format.length, 271 %IgnoreAttributesAndSetProperty(format, 'length', format.length,
272 DONT_DELETE | READ_ONLY | DONT_ENUM); 272 DONT_DELETE | READ_ONLY | DONT_ENUM);
273 %PreventExtensions(format); 273 %PreventExtensions(format);
274 %IgnoreAttributesAndSetProperty(messages, 274 %IgnoreAttributesAndSetProperty(messages,
275 key, 275 key,
276 format, 276 format,
277 DONT_DELETE | DONT_ENUM | READ_ONLY); 277 DONT_DELETE | DONT_ENUM | READ_ONLY);
278 } 278 }
279 %PreventExtensions(messages); 279 %PreventExtensions(messages);
280 %IgnoreAttributesAndSetProperty(builtins, "kMessages", 280 %IgnoreAttributesAndSetProperty(builtins, "kMessages",
281 messages, 281 messages,
282 DONT_DELETE | DONT_ENUM | READ_ONLY); 282 DONT_DELETE | DONT_ENUM | READ_ONLY);
283 } 283 }
284 var message_type = %MessageGetType(message); 284 var message_type = %MessageGetType(message);
285 var format = kMessages[message_type]; 285 var format = kMessages[message_type];
286 if (!format) return "<unknown message " + message_type + ">"; 286 if (!format) return "<unknown message " + message_type + ">";
287 return FormatString(format, message); 287 return FormatString(format, message);
288 } 288 }
289 289
290 290
291 function GetLineNumber(message) { 291 function GetLineNumber(message) {
292 var start_position = %MessageGetStartPosition(message); 292 var start_position = %MessageGetStartPosition(message);
293 if (start_position == -1) return kNoLineNumberInfo; 293 if (start_position == -1) return kNoLineNumberInfo;
294 var script = %MessageGetScript(message); 294 var script = %MessageGetScript(message);
295 var location = script.locationFromPosition(start_position, true); 295 var location = script.locationFromPosition(start_position, true);
296 if (location == null) return kNoLineNumberInfo; 296 if (location == null) return kNoLineNumberInfo;
297 return location.line + 1; 297 return location.line + 1;
298 } 298 }
299 299
300 300
301 // Returns the source code line containing the given source 301 // Returns the source code line containing the given source
302 // position, or the empty string if the position is invalid. 302 // position, or the empty string if the position is invalid.
303 function GetSourceLine(message) { 303 function GetSourceLine(message) {
304 var script = %MessageGetScript(message); 304 var script = %MessageGetScript(message);
305 var start_position = %MessageGetStartPosition(message); 305 var start_position = %MessageGetStartPosition(message);
306 var location = script.locationFromPosition(start_position, true); 306 var location = script.locationFromPosition(start_position, true);
307 if (location == null) return ""; 307 if (location == null) return "";
308 location.restrict(); 308 location.restrict();
309 return location.sourceText(); 309 return location.sourceText();
310 } 310 }
311 311
312 312
313 function MakeTypeError(type, args) { 313 function MakeTypeError(type, args) {
314 return MakeGenericError($TypeError, type, args); 314 return MakeGenericError($TypeError, type, args);
315 } 315 }
316 316
317 317
318 function MakeRangeError(type, args) { 318 function MakeRangeError(type, args) {
319 return MakeGenericError($RangeError, type, args); 319 return MakeGenericError($RangeError, type, args);
320 } 320 }
321 321
322 322
323 function MakeSyntaxError(type, args) { 323 function MakeSyntaxError(type, args) {
324 return MakeGenericError($SyntaxError, type, args); 324 return MakeGenericError($SyntaxError, type, args);
325 } 325 }
326 326
327 327
328 function MakeReferenceError(type, args) { 328 function MakeReferenceError(type, args) {
329 return MakeGenericError($ReferenceError, type, args); 329 return MakeGenericError($ReferenceError, type, args);
330 } 330 }
331 331
332 332
333 function MakeEvalError(type, args) { 333 function MakeEvalError(type, args) {
334 return MakeGenericError($EvalError, type, args); 334 return MakeGenericError($EvalError, type, args);
335 } 335 }
336 336
337 337
338 function MakeError(type, args) { 338 function MakeError(type, args) {
339 return MakeGenericError($Error, type, args); 339 return MakeGenericError($Error, type, args);
340 } 340 }
341 341
342 /** 342 /**
343 * Find a line number given a specific source position. 343 * Find a line number given a specific source position.
344 * @param {number} position The source position. 344 * @param {number} position The source position.
345 * @return {number} 0 if input too small, -1 if input too large, 345 * @return {number} 0 if input too small, -1 if input too large,
346 else the line number. 346 else the line number.
347 */ 347 */
348 function ScriptLineFromPosition(position) { 348 function ScriptLineFromPosition(position) {
349 var lower = 0; 349 var lower = 0;
350 var upper = this.lineCount() - 1; 350 var upper = this.lineCount() - 1;
351 var line_ends = this.line_ends; 351 var line_ends = this.line_ends;
352 352
353 // We'll never find invalid positions so bail right away. 353 // We'll never find invalid positions so bail right away.
354 if (position > line_ends[upper]) { 354 if (position > line_ends[upper]) {
355 return -1; 355 return -1;
356 } 356 }
357 357
358 // This means we don't have to safe-guard indexing line_ends[i - 1]. 358 // This means we don't have to safe-guard indexing line_ends[i - 1].
359 if (position <= line_ends[0]) { 359 if (position <= line_ends[0]) {
360 return 0; 360 return 0;
361 } 361 }
362 362
363 // Binary search to find line # from position range. 363 // Binary search to find line # from position range.
364 while (upper >= 1) { 364 while (upper >= 1) {
365 var i = (lower + upper) >> 1; 365 var i = (lower + upper) >> 1;
366 366
367 if (position > line_ends[i]) { 367 if (position > line_ends[i]) {
368 lower = i + 1; 368 lower = i + 1;
369 } else if (position <= line_ends[i - 1]) { 369 } else if (position <= line_ends[i - 1]) {
370 upper = i - 1; 370 upper = i - 1;
371 } else { 371 } else {
372 return i; 372 return i;
373 } 373 }
374 } 374 }
375 375
376 return -1; 376 return -1;
377 } 377 }
378 378
379 /** 379 /**
380 * Get information on a specific source position. 380 * Get information on a specific source position.
381 * @param {number} position The source position 381 * @param {number} position The source position
382 * @param {boolean} include_resource_offset Set to true to have the resource 382 * @param {boolean} include_resource_offset Set to true to have the resource
383 * offset added to the location 383 * offset added to the location
384 * @return {SourceLocation} 384 * @return {SourceLocation}
385 * If line is negative or not in the source null is returned. 385 * If line is negative or not in the source null is returned.
386 */ 386 */
387 function ScriptLocationFromPosition(position, 387 function ScriptLocationFromPosition(position,
388 include_resource_offset) { 388 include_resource_offset) {
389 var line = this.lineFromPosition(position); 389 var line = this.lineFromPosition(position);
390 if (line == -1) return null; 390 if (line == -1) return null;
391 391
392 // Determine start, end and column. 392 // Determine start, end and column.
393 var line_ends = this.line_ends; 393 var line_ends = this.line_ends;
394 var start = line == 0 ? 0 : line_ends[line - 1] + 1; 394 var start = line == 0 ? 0 : line_ends[line - 1] + 1;
395 var end = line_ends[line]; 395 var end = line_ends[line];
396 if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') { 396 if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') {
397 end--; 397 end--;
398 } 398 }
399 var column = position - start; 399 var column = position - start;
400 400
401 // Adjust according to the offset within the resource. 401 // Adjust according to the offset within the resource.
402 if (include_resource_offset) { 402 if (include_resource_offset) {
403 line += this.line_offset; 403 line += this.line_offset;
404 if (line == this.line_offset) { 404 if (line == this.line_offset) {
405 column += this.column_offset; 405 column += this.column_offset;
406 } 406 }
407 } 407 }
408 408
409 return new SourceLocation(this, position, line, column, start, end); 409 return new SourceLocation(this, position, line, column, start, end);
410 } 410 }
411 411
412 412
413 /** 413 /**
414 * Get information on a specific source line and column possibly offset by a 414 * Get information on a specific source line and column possibly offset by a
415 * fixed source position. This function is used to find a source position from 415 * fixed source position. This function is used to find a source position from
416 * a line and column position. The fixed source position offset is typically 416 * a line and column position. The fixed source position offset is typically
417 * used to find a source position in a function based on a line and column in 417 * used to find a source position in a function based on a line and column in
418 * the source for the function alone. The offset passed will then be the 418 * the source for the function alone. The offset passed will then be the
419 * start position of the source for the function within the full script source. 419 * start position of the source for the function within the full script source.
420 * @param {number} opt_line The line within the source. Default value is 0 420 * @param {number} opt_line The line within the source. Default value is 0
421 * @param {number} opt_column The column in within the line. Default value is 0 421 * @param {number} opt_column The column in within the line. Default value is 0
422 * @param {number} opt_offset_position The offset from the begining of the 422 * @param {number} opt_offset_position The offset from the begining of the
423 * source from where the line and column calculation starts. 423 * source from where the line and column calculation starts.
424 * Default value is 0 424 * Default value is 0
425 * @return {SourceLocation} 425 * @return {SourceLocation}
426 * If line is negative or not in the source null is returned. 426 * If line is negative or not in the source null is returned.
427 */ 427 */
428 function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) { 428 function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) {
429 // Default is the first line in the script. Lines in the script is relative 429 // Default is the first line in the script. Lines in the script is relative
430 // to the offset within the resource. 430 // to the offset within the resource.
431 var line = 0; 431 var line = 0;
432 if (!IS_UNDEFINED(opt_line)) { 432 if (!IS_UNDEFINED(opt_line)) {
433 line = opt_line - this.line_offset; 433 line = opt_line - this.line_offset;
434 } 434 }
435 435
436 // Default is first column. If on the first line add the offset within the 436 // Default is first column. If on the first line add the offset within the
437 // resource. 437 // resource.
438 var column = opt_column || 0; 438 var column = opt_column || 0;
439 if (line == 0) { 439 if (line == 0) {
440 column -= this.column_offset; 440 column -= this.column_offset;
441 } 441 }
442 442
443 var offset_position = opt_offset_position || 0; 443 var offset_position = opt_offset_position || 0;
444 if (line < 0 || column < 0 || offset_position < 0) return null; 444 if (line < 0 || column < 0 || offset_position < 0) return null;
445 if (line == 0) { 445 if (line == 0) {
446 return this.locationFromPosition(offset_position + column, false); 446 return this.locationFromPosition(offset_position + column, false);
447 } else { 447 } else {
448 // Find the line where the offset position is located. 448 // Find the line where the offset position is located.
449 var offset_line = this.lineFromPosition(offset_position); 449 var offset_line = this.lineFromPosition(offset_position);
450 450
451 if (offset_line == -1 || offset_line + line >= this.lineCount()) { 451 if (offset_line == -1 || offset_line + line >= this.lineCount()) {
452 return null; 452 return null;
453 } 453 }
454 454
455 return this.locationFromPosition( 455 return this.locationFromPosition(
456 this.line_ends[offset_line + line - 1] + 1 + column); // line > 0 here. 456 this.line_ends[offset_line + line - 1] + 1 + column); // line > 0 here.
457 } 457 }
458 } 458 }
459 459
460 460
461 /** 461 /**
462 * Get a slice of source code from the script. The boundaries for the slice is 462 * Get a slice of source code from the script. The boundaries for the slice is
463 * specified in lines. 463 * specified in lines.
464 * @param {number} opt_from_line The first line (zero bound) in the slice. 464 * @param {number} opt_from_line The first line (zero bound) in the slice.
465 * Default is 0 465 * Default is 0
466 * @param {number} opt_to_column The last line (zero bound) in the slice (non 466 * @param {number} opt_to_column The last line (zero bound) in the slice (non
467 * inclusive). Default is the number of lines in the script 467 * inclusive). Default is the number of lines in the script
468 * @return {SourceSlice} The source slice or null of the parameters where 468 * @return {SourceSlice} The source slice or null of the parameters where
469 * invalid 469 * invalid
470 */ 470 */
471 function ScriptSourceSlice(opt_from_line, opt_to_line) { 471 function ScriptSourceSlice(opt_from_line, opt_to_line) {
472 var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset 472 var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset
473 : opt_from_line; 473 : opt_from_line;
474 var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount() 474 var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
475 : opt_to_line; 475 : opt_to_line;
476 476
477 // Adjust according to the offset within the resource. 477 // Adjust according to the offset within the resource.
478 from_line -= this.line_offset; 478 from_line -= this.line_offset;
479 to_line -= this.line_offset; 479 to_line -= this.line_offset;
480 if (from_line < 0) from_line = 0; 480 if (from_line < 0) from_line = 0;
481 if (to_line > this.lineCount()) to_line = this.lineCount(); 481 if (to_line > this.lineCount()) to_line = this.lineCount();
482 482
483 // Check parameters. 483 // Check parameters.
484 if (from_line >= this.lineCount() || 484 if (from_line >= this.lineCount() ||
485 to_line < 0 || 485 to_line < 0 ||
486 from_line > to_line) { 486 from_line > to_line) {
487 return null; 487 return null;
488 } 488 }
489 489
490 var line_ends = this.line_ends; 490 var line_ends = this.line_ends;
491 var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1; 491 var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1;
492 var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1; 492 var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1;
493 493
494 // Return a source slice with line numbers re-adjusted to the resource. 494 // Return a source slice with line numbers re-adjusted to the resource.
495 return new SourceSlice(this, 495 return new SourceSlice(this,
496 from_line + this.line_offset, 496 from_line + this.line_offset,
497 to_line + this.line_offset, 497 to_line + this.line_offset,
498 from_position, to_position); 498 from_position, to_position);
499 } 499 }
500 500
501 501
502 function ScriptSourceLine(opt_line) { 502 function ScriptSourceLine(opt_line) {
503 // Default is the first line in the script. Lines in the script are relative 503 // Default is the first line in the script. Lines in the script are relative
504 // to the offset within the resource. 504 // to the offset within the resource.
505 var line = 0; 505 var line = 0;
506 if (!IS_UNDEFINED(opt_line)) { 506 if (!IS_UNDEFINED(opt_line)) {
507 line = opt_line - this.line_offset; 507 line = opt_line - this.line_offset;
508 } 508 }
509 509
510 // Check parameter. 510 // Check parameter.
511 if (line < 0 || this.lineCount() <= line) { 511 if (line < 0 || this.lineCount() <= line) {
512 return null; 512 return null;
513 } 513 }
514 514
515 // Return the source line. 515 // Return the source line.
516 var line_ends = this.line_ends; 516 var line_ends = this.line_ends;
517 var start = line == 0 ? 0 : line_ends[line - 1] + 1; 517 var start = line == 0 ? 0 : line_ends[line - 1] + 1;
518 var end = line_ends[line]; 518 var end = line_ends[line];
519 return %_CallFunction(this.source, start, end, StringSubstring); 519 return %_CallFunction(this.source, start, end, StringSubstring);
520 } 520 }
521 521
522 522
523 /** 523 /**
524 * Returns the number of source lines. 524 * Returns the number of source lines.
525 * @return {number} 525 * @return {number}
526 * Number of source lines. 526 * Number of source lines.
527 */ 527 */
528 function ScriptLineCount() { 528 function ScriptLineCount() {
529 // Return number of source lines. 529 // Return number of source lines.
530 return this.line_ends.length; 530 return this.line_ends.length;
531 } 531 }
532 532
533 533
534 /** 534 /**
535 * If sourceURL comment is available and script starts at zero returns sourceURL 535 * If sourceURL comment is available and script starts at zero returns sourceURL
536 * comment contents. Otherwise, script name is returned. See 536 * comment contents. Otherwise, script name is returned. See
537 * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt 537 * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
538 * for details on using //@ sourceURL comment to identify scritps that don't 538 * for details on using //@ sourceURL comment to identify scritps that don't
539 * have name. 539 * have name.
540 * 540 *
541 * @return {?string} script name if present, value for //@ sourceURL comment 541 * @return {?string} script name if present, value for //@ sourceURL comment
542 * otherwise. 542 * otherwise.
543 */ 543 */
544 function ScriptNameOrSourceURL() { 544 function ScriptNameOrSourceURL() {
545 if (this.line_offset > 0 || this.column_offset > 0) { 545 if (this.line_offset > 0 || this.column_offset > 0) {
546 return this.name; 546 return this.name;
547 } 547 }
548 548
549 // The result is cached as on long scripts it takes noticable time to search 549 // The result is cached as on long scripts it takes noticable time to search
550 // for the sourceURL. 550 // for the sourceURL.
551 if (this.hasCachedNameOrSourceURL) { 551 if (this.hasCachedNameOrSourceURL) {
552 return this.cachedNameOrSourceURL; 552 return this.cachedNameOrSourceURL;
553 } 553 }
554 this.hasCachedNameOrSourceURL = true; 554 this.hasCachedNameOrSourceURL = true;
555 555
556 // TODO(608): the spaces in a regexp below had to be escaped as \040 556 // TODO(608): the spaces in a regexp below had to be escaped as \040
557 // because this file is being processed by js2c whose handling of spaces 557 // because this file is being processed by js2c whose handling of spaces
558 // in regexps is broken. Also, ['"] are excluded from allowed URLs to 558 // in regexps is broken. Also, ['"] are excluded from allowed URLs to
559 // avoid matches against sources that invoke evals with sourceURL. 559 // avoid matches against sources that invoke evals with sourceURL.
560 // A better solution would be to detect these special comments in 560 // A better solution would be to detect these special comments in
561 // the scanner/parser. 561 // the scanner/parser.
562 var source = ToString(this.source); 562 var source = ToString(this.source);
563 var sourceUrlPos = %StringIndexOf(source, "sourceURL=", 0); 563 var sourceUrlPos = %StringIndexOf(source, "sourceURL=", 0);
564 this.cachedNameOrSourceURL = this.name; 564 this.cachedNameOrSourceURL = this.name;
565 if (sourceUrlPos > 4) { 565 if (sourceUrlPos > 4) {
566 var sourceUrlPattern = 566 var sourceUrlPattern =
567 /\/\/@[\040\t]sourceURL=[\040\t]*([^\s\'\"]*)[\040\t]*$/gm; 567 /\/\/@[\040\t]sourceURL=[\040\t]*([^\s\'\"]*)[\040\t]*$/gm;
568 // Don't reuse lastMatchInfo here, so we create a new array with room 568 // Don't reuse lastMatchInfo here, so we create a new array with room
569 // for four captures (array with length one longer than the index 569 // for four captures (array with length one longer than the index
570 // of the fourth capture, where the numbering is zero-based). 570 // of the fourth capture, where the numbering is zero-based).
571 var matchInfo = new InternalArray(CAPTURE(3) + 1); 571 var matchInfo = new InternalArray(CAPTURE(3) + 1);
572 var match = 572 var match =
573 %_RegExpExec(sourceUrlPattern, source, sourceUrlPos - 4, matchInfo); 573 %_RegExpExec(sourceUrlPattern, source, sourceUrlPos - 4, matchInfo);
574 if (match) { 574 if (match) {
575 this.cachedNameOrSourceURL = 575 this.cachedNameOrSourceURL =
576 SubString(source, matchInfo[CAPTURE(2)], matchInfo[CAPTURE(3)]); 576 SubString(source, matchInfo[CAPTURE(2)], matchInfo[CAPTURE(3)]);
577 } 577 }
578 } 578 }
579 return this.cachedNameOrSourceURL; 579 return this.cachedNameOrSourceURL;
580 } 580 }
581 581
582 582
583 SetUpLockedPrototype(Script, 583 SetUpLockedPrototype(Script,
584 $Array("source", "name", "line_ends", "line_offset", "column_offset", 584 $Array("source", "name", "line_ends", "line_offset", "column_offset",
585 "cachedNameOrSourceURL", "hasCachedNameOrSourceURL" ), 585 "cachedNameOrSourceURL", "hasCachedNameOrSourceURL" ),
586 $Array( 586 $Array(
587 "lineFromPosition", ScriptLineFromPosition, 587 "lineFromPosition", ScriptLineFromPosition,
588 "locationFromPosition", ScriptLocationFromPosition, 588 "locationFromPosition", ScriptLocationFromPosition,
589 "locationFromLine", ScriptLocationFromLine, 589 "locationFromLine", ScriptLocationFromLine,
590 "sourceSlice", ScriptSourceSlice, 590 "sourceSlice", ScriptSourceSlice,
591 "sourceLine", ScriptSourceLine, 591 "sourceLine", ScriptSourceLine,
592 "lineCount", ScriptLineCount, 592 "lineCount", ScriptLineCount,
593 "nameOrSourceURL", ScriptNameOrSourceURL 593 "nameOrSourceURL", ScriptNameOrSourceURL
594 ) 594 )
595 ); 595 );
596 596
597 597
598 /** 598 /**
599 * Class for source location. A source location is a position within some 599 * Class for source location. A source location is a position within some
600 * source with the following properties: 600 * source with the following properties:
601 * script : script object for the source 601 * script : script object for the source
602 * line : source line number 602 * line : source line number
603 * column : source column within the line 603 * column : source column within the line
604 * position : position within the source 604 * position : position within the source
605 * start : position of start of source context (inclusive) 605 * start : position of start of source context (inclusive)
606 * end : position of end of source context (not inclusive) 606 * end : position of end of source context (not inclusive)
607 * Source text for the source context is the character interval 607 * Source text for the source context is the character interval
608 * [start, end[. In most cases end will point to a newline character. 608 * [start, end[. In most cases end will point to a newline character.
609 * It might point just past the final position of the source if the last 609 * It might point just past the final position of the source if the last
610 * source line does not end with a newline character. 610 * source line does not end with a newline character.
611 * @param {Script} script The Script object for which this is a location 611 * @param {Script} script The Script object for which this is a location
612 * @param {number} position Source position for the location 612 * @param {number} position Source position for the location
613 * @param {number} line The line number for the location 613 * @param {number} line The line number for the location
614 * @param {number} column The column within the line for the location 614 * @param {number} column The column within the line for the location
615 * @param {number} start Source position for start of source context 615 * @param {number} start Source position for start of source context
616 * @param {number} end Source position for end of source context 616 * @param {number} end Source position for end of source context
617 * @constructor 617 * @constructor
618 */ 618 */
619 function SourceLocation(script, position, line, column, start, end) { 619 function SourceLocation(script, position, line, column, start, end) {
620 this.script = script; 620 this.script = script;
621 this.position = position; 621 this.position = position;
622 this.line = line; 622 this.line = line;
623 this.column = column; 623 this.column = column;
624 this.start = start; 624 this.start = start;
625 this.end = end; 625 this.end = end;
626 } 626 }
627 627
628 var kLineLengthLimit = 78; 628 var kLineLengthLimit = 78;
629 629
630 /** 630 /**
631 * Restrict source location start and end positions to make the source slice 631 * Restrict source location start and end positions to make the source slice
632 * no more that a certain number of characters wide. 632 * no more that a certain number of characters wide.
633 * @param {number} opt_limit The with limit of the source text with a default 633 * @param {number} opt_limit The with limit of the source text with a default
634 * of 78 634 * of 78
635 * @param {number} opt_before The number of characters to prefer before the 635 * @param {number} opt_before The number of characters to prefer before the
636 * position with a default value of 10 less that the limit 636 * position with a default value of 10 less that the limit
637 */ 637 */
638 function SourceLocationRestrict(opt_limit, opt_before) { 638 function SourceLocationRestrict(opt_limit, opt_before) {
639 // Find the actual limit to use. 639 // Find the actual limit to use.
640 var limit; 640 var limit;
641 var before; 641 var before;
642 if (!IS_UNDEFINED(opt_limit)) { 642 if (!IS_UNDEFINED(opt_limit)) {
643 limit = opt_limit; 643 limit = opt_limit;
644 } else { 644 } else {
645 limit = kLineLengthLimit; 645 limit = kLineLengthLimit;
646 } 646 }
647 if (!IS_UNDEFINED(opt_before)) { 647 if (!IS_UNDEFINED(opt_before)) {
648 before = opt_before; 648 before = opt_before;
649 } else { 649 } else {
650 // If no before is specified center for small limits and perfer more source 650 // If no before is specified center for small limits and perfer more source
651 // before the the position that after for longer limits. 651 // before the the position that after for longer limits.
652 if (limit <= 20) { 652 if (limit <= 20) {
653 before = $floor(limit / 2); 653 before = $floor(limit / 2);
654 } else { 654 } else {
655 before = limit - 10; 655 before = limit - 10;
656 } 656 }
657 } 657 }
658 if (before >= limit) { 658 if (before >= limit) {
659 before = limit - 1; 659 before = limit - 1;
660 } 660 }
661 661
662 // If the [start, end[ interval is too big we restrict 662 // If the [start, end[ interval is too big we restrict
663 // it in one or both ends. We make sure to always produce 663 // it in one or both ends. We make sure to always produce
664 // restricted intervals of maximum allowed size. 664 // restricted intervals of maximum allowed size.
665 if (this.end - this.start > limit) { 665 if (this.end - this.start > limit) {
666 var start_limit = this.position - before; 666 var start_limit = this.position - before;
667 var end_limit = this.position + limit - before; 667 var end_limit = this.position + limit - before;
668 if (this.start < start_limit && end_limit < this.end) { 668 if (this.start < start_limit && end_limit < this.end) {
669 this.start = start_limit; 669 this.start = start_limit;
670 this.end = end_limit; 670 this.end = end_limit;
671 } else if (this.start < start_limit) { 671 } else if (this.start < start_limit) {
672 this.start = this.end - limit; 672 this.start = this.end - limit;
673 } else { 673 } else {
674 this.end = this.start + limit; 674 this.end = this.start + limit;
675 } 675 }
676 } 676 }
677 } 677 }
678 678
679 679
680 /** 680 /**
681 * Get the source text for a SourceLocation 681 * Get the source text for a SourceLocation
682 * @return {String} 682 * @return {String}
683 * Source text for this location. 683 * Source text for this location.
684 */ 684 */
685 function SourceLocationSourceText() { 685 function SourceLocationSourceText() {
686 return %_CallFunction(this.script.source, 686 return %_CallFunction(this.script.source,
687 this.start, 687 this.start,
688 this.end, 688 this.end,
689 StringSubstring); 689 StringSubstring);
690 } 690 }
691 691
692 692
693 SetUpLockedPrototype(SourceLocation, 693 SetUpLockedPrototype(SourceLocation,
694 $Array("script", "position", "line", "column", "start", "end"), 694 $Array("script", "position", "line", "column", "start", "end"),
695 $Array( 695 $Array(
696 "restrict", SourceLocationRestrict, 696 "restrict", SourceLocationRestrict,
697 "sourceText", SourceLocationSourceText 697 "sourceText", SourceLocationSourceText
698 ) 698 )
699 ); 699 );
700 700
701 701
702 /** 702 /**
703 * Class for a source slice. A source slice is a part of a script source with 703 * Class for a source slice. A source slice is a part of a script source with
704 * the following properties: 704 * the following properties:
705 * script : script object for the source 705 * script : script object for the source
706 * from_line : line number for the first line in the slice 706 * from_line : line number for the first line in the slice
707 * to_line : source line number for the last line in the slice 707 * to_line : source line number for the last line in the slice
708 * from_position : position of the first character in the slice 708 * from_position : position of the first character in the slice
709 * to_position : position of the last character in the slice 709 * to_position : position of the last character in the slice
710 * The to_line and to_position are not included in the slice, that is the lines 710 * The to_line and to_position are not included in the slice, that is the lines
711 * in the slice are [from_line, to_line[. Likewise the characters in the slice 711 * in the slice are [from_line, to_line[. Likewise the characters in the slice
712 * are [from_position, to_position[. 712 * are [from_position, to_position[.
713 * @param {Script} script The Script object for the source slice 713 * @param {Script} script The Script object for the source slice
714 * @param {number} from_line 714 * @param {number} from_line
715 * @param {number} to_line 715 * @param {number} to_line
716 * @param {number} from_position 716 * @param {number} from_position
717 * @param {number} to_position 717 * @param {number} to_position
718 * @constructor 718 * @constructor
719 */ 719 */
720 function SourceSlice(script, from_line, to_line, from_position, to_position) { 720 function SourceSlice(script, from_line, to_line, from_position, to_position) {
721 this.script = script; 721 this.script = script;
722 this.from_line = from_line; 722 this.from_line = from_line;
723 this.to_line = to_line; 723 this.to_line = to_line;
724 this.from_position = from_position; 724 this.from_position = from_position;
725 this.to_position = to_position; 725 this.to_position = to_position;
726 } 726 }
727 727
728 /** 728 /**
729 * Get the source text for a SourceSlice 729 * Get the source text for a SourceSlice
730 * @return {String} Source text for this slice. The last line will include 730 * @return {String} Source text for this slice. The last line will include
731 * the line terminating characters (if any) 731 * the line terminating characters (if any)
732 */ 732 */
733 function SourceSliceSourceText() { 733 function SourceSliceSourceText() {
734 return %_CallFunction(this.script.source, 734 return %_CallFunction(this.script.source,
735 this.from_position, 735 this.from_position,
736 this.to_position, 736 this.to_position,
737 StringSubstring); 737 StringSubstring);
738 } 738 }
739 739
740 SetUpLockedPrototype(SourceSlice, 740 SetUpLockedPrototype(SourceSlice,
741 $Array("script", "from_line", "to_line", "from_position", "to_position"), 741 $Array("script", "from_line", "to_line", "from_position", "to_position"),
742 $Array("sourceText", SourceSliceSourceText) 742 $Array("sourceText", SourceSliceSourceText)
743 ); 743 );
744 744
745 745
746 // Returns the offset of the given position within the containing 746 // Returns the offset of the given position within the containing
747 // line. 747 // line.
748 function GetPositionInLine(message) { 748 function GetPositionInLine(message) {
749 var script = %MessageGetScript(message); 749 var script = %MessageGetScript(message);
750 var start_position = %MessageGetStartPosition(message); 750 var start_position = %MessageGetStartPosition(message);
751 var location = script.locationFromPosition(start_position, false); 751 var location = script.locationFromPosition(start_position, false);
752 if (location == null) return -1; 752 if (location == null) return -1;
753 location.restrict(); 753 location.restrict();
754 return start_position - location.start; 754 return start_position - location.start;
755 } 755 }
756 756
757 757
758 function GetStackTraceLine(recv, fun, pos, isGlobal) { 758 function GetStackTraceLine(recv, fun, pos, isGlobal) {
759 return new CallSite(recv, fun, pos).toString(); 759 return new CallSite(recv, fun, pos).toString();
760 } 760 }
761 761
762 // ---------------------------------------------------------------------------- 762 // ----------------------------------------------------------------------------
763 // Error implementation 763 // Error implementation
764 764
765 // Defines accessors for a property that is calculated the first time 765 // Defines accessors for a property that is calculated the first time
766 // the property is read. 766 // the property is read.
767 function DefineOneShotAccessor(obj, name, fun) { 767 function DefineOneShotAccessor(obj, name, fun) {
768 // Note that the accessors consistently operate on 'obj', not 'this'. 768 // Note that the accessors consistently operate on 'obj', not 'this'.
769 // Since the object may occur in someone else's prototype chain we 769 // Since the object may occur in someone else's prototype chain we
770 // can't rely on 'this' being the same as 'obj'. 770 // can't rely on 'this' being the same as 'obj'.
771 var value; 771 var value;
772 var value_factory = fun; 772 var value_factory = fun;
773 var getter = function() { 773 var getter = function() {
774 if (value_factory == null) { 774 if (value_factory == null) {
775 return value; 775 return value;
776 } 776 }
777 value = value_factory(obj); 777 value = value_factory(obj);
778 value_factory = null; 778 value_factory = null;
779 return value; 779 return value;
780 }; 780 };
781 var setter = function(v) { 781 var setter = function(v) {
782 value_factory = null; 782 value_factory = null;
783 value = v; 783 value = v;
784 }; 784 };
785 %DefineOrRedefineAccessorProperty(obj, name, getter, setter, DONT_ENUM); 785 %DefineOrRedefineAccessorProperty(obj, name, getter, setter, DONT_ENUM);
786 } 786 }
787 787
788 function CallSite(receiver, fun, pos) { 788 function CallSite(receiver, fun, pos) {
789 this.receiver = receiver; 789 this.receiver = receiver;
790 this.fun = fun; 790 this.fun = fun;
791 this.pos = pos; 791 this.pos = pos;
792 } 792 }
793 793
794 function CallSiteGetThis() { 794 function CallSiteGetThis() {
795 return this.receiver; 795 return this.receiver;
796 } 796 }
797 797
798 function CallSiteGetTypeName() { 798 function CallSiteGetTypeName() {
799 return GetTypeName(this, false); 799 return GetTypeName(this, false);
800 } 800 }
801 801
802 function CallSiteIsToplevel() { 802 function CallSiteIsToplevel() {
803 if (this.receiver == null) { 803 if (this.receiver == null) {
804 return true; 804 return true;
805 } 805 }
806 return IS_GLOBAL(this.receiver); 806 return IS_GLOBAL(this.receiver);
807 } 807 }
808 808
809 function CallSiteIsEval() { 809 function CallSiteIsEval() {
810 var script = %FunctionGetScript(this.fun); 810 var script = %FunctionGetScript(this.fun);
811 return script && script.compilation_type == COMPILATION_TYPE_EVAL; 811 return script && script.compilation_type == COMPILATION_TYPE_EVAL;
812 } 812 }
813 813
814 function CallSiteGetEvalOrigin() { 814 function CallSiteGetEvalOrigin() {
815 var script = %FunctionGetScript(this.fun); 815 var script = %FunctionGetScript(this.fun);
816 return FormatEvalOrigin(script); 816 return FormatEvalOrigin(script);
817 } 817 }
818 818
819 function CallSiteGetScriptNameOrSourceURL() { 819 function CallSiteGetScriptNameOrSourceURL() {
820 var script = %FunctionGetScript(this.fun); 820 var script = %FunctionGetScript(this.fun);
821 return script ? script.nameOrSourceURL() : null; 821 return script ? script.nameOrSourceURL() : null;
822 } 822 }
823 823
824 function CallSiteGetFunction() { 824 function CallSiteGetFunction() {
825 return this.fun; 825 return this.fun;
826 } 826 }
827 827
828 function CallSiteGetFunctionName() { 828 function CallSiteGetFunctionName() {
829 // See if the function knows its own name 829 // See if the function knows its own name
830 var name = this.fun.name; 830 var name = this.fun.name;
831 if (name) { 831 if (name) {
832 return name; 832 return name;
833 } 833 }
834 name = %FunctionGetInferredName(this.fun); 834 name = %FunctionGetInferredName(this.fun);
835 if (name) { 835 if (name) {
836 return name; 836 return name;
837 } 837 }
838 // Maybe this is an evaluation? 838 // Maybe this is an evaluation?
839 var script = %FunctionGetScript(this.fun); 839 var script = %FunctionGetScript(this.fun);
840 if (script && script.compilation_type == COMPILATION_TYPE_EVAL) { 840 if (script && script.compilation_type == COMPILATION_TYPE_EVAL) {
841 return "eval"; 841 return "eval";
842 } 842 }
843 return null; 843 return null;
844 } 844 }
845 845
846 function CallSiteGetMethodName() { 846 function CallSiteGetMethodName() {
847 // See if we can find a unique property on the receiver that holds 847 // See if we can find a unique property on the receiver that holds
848 // this function. 848 // this function.
849 var ownName = this.fun.name; 849 var ownName = this.fun.name;
850 if (ownName && this.receiver && 850 if (ownName && this.receiver &&
851 (%_CallFunction(this.receiver, 851 (%_CallFunction(this.receiver,
852 ownName, 852 ownName,
853 ObjectLookupGetter) === this.fun || 853 ObjectLookupGetter) === this.fun ||
854 %_CallFunction(this.receiver, 854 %_CallFunction(this.receiver,
855 ownName, 855 ownName,
856 ObjectLookupSetter) === this.fun || 856 ObjectLookupSetter) === this.fun ||
857 this.receiver[ownName] === this.fun)) { 857 this.receiver[ownName] === this.fun)) {
858 // To handle DontEnum properties we guess that the method has 858 // To handle DontEnum properties we guess that the method has
859 // the same name as the function. 859 // the same name as the function.
860 return ownName; 860 return ownName;
861 } 861 }
862 var name = null; 862 var name = null;
863 for (var prop in this.receiver) { 863 for (var prop in this.receiver) {
864 if (%_CallFunction(this.receiver, prop, ObjectLookupGetter) === this.fun || 864 if (%_CallFunction(this.receiver, prop, ObjectLookupGetter) === this.fun ||
865 %_CallFunction(this.receiver, prop, ObjectLookupSetter) === this.fun || 865 %_CallFunction(this.receiver, prop, ObjectLookupSetter) === this.fun ||
866 (!%_CallFunction(this.receiver, prop, ObjectLookupGetter) && 866 (!%_CallFunction(this.receiver, prop, ObjectLookupGetter) &&
867 this.receiver[prop] === this.fun)) { 867 this.receiver[prop] === this.fun)) {
868 // If we find more than one match bail out to avoid confusion. 868 // If we find more than one match bail out to avoid confusion.
869 if (name) { 869 if (name) {
870 return null; 870 return null;
871 } 871 }
872 name = prop; 872 name = prop;
873 } 873 }
874 } 874 }
875 if (name) { 875 if (name) {
876 return name; 876 return name;
877 } 877 }
878 return null; 878 return null;
879 } 879 }
880 880
881 function CallSiteGetFileName() { 881 function CallSiteGetFileName() {
882 var script = %FunctionGetScript(this.fun); 882 var script = %FunctionGetScript(this.fun);
883 return script ? script.name : null; 883 return script ? script.name : null;
884 } 884 }
885 885
886 function CallSiteGetLineNumber() { 886 function CallSiteGetLineNumber() {
887 if (this.pos == -1) { 887 if (this.pos == -1) {
888 return null; 888 return null;
889 } 889 }
890 var script = %FunctionGetScript(this.fun); 890 var script = %FunctionGetScript(this.fun);
891 var location = null; 891 var location = null;
892 if (script) { 892 if (script) {
893 location = script.locationFromPosition(this.pos, true); 893 location = script.locationFromPosition(this.pos, true);
894 } 894 }
895 return location ? location.line + 1 : null; 895 return location ? location.line + 1 : null;
896 } 896 }
897 897
898 function CallSiteGetColumnNumber() { 898 function CallSiteGetColumnNumber() {
899 if (this.pos == -1) { 899 if (this.pos == -1) {
900 return null; 900 return null;
901 } 901 }
902 var script = %FunctionGetScript(this.fun); 902 var script = %FunctionGetScript(this.fun);
903 var location = null; 903 var location = null;
904 if (script) { 904 if (script) {
905 location = script.locationFromPosition(this.pos, true); 905 location = script.locationFromPosition(this.pos, true);
906 } 906 }
907 return location ? location.column + 1: null; 907 return location ? location.column + 1: null;
908 } 908 }
909 909
910 function CallSiteIsNative() { 910 function CallSiteIsNative() {
911 var script = %FunctionGetScript(this.fun); 911 var script = %FunctionGetScript(this.fun);
912 return script ? (script.type == TYPE_NATIVE) : false; 912 return script ? (script.type == TYPE_NATIVE) : false;
913 } 913 }
914 914
915 function CallSiteGetPosition() { 915 function CallSiteGetPosition() {
916 return this.pos; 916 return this.pos;
917 } 917 }
918 918
919 function CallSiteIsConstructor() { 919 function CallSiteIsConstructor() {
920 var constructor = this.receiver ? this.receiver.constructor : null; 920 var constructor = this.receiver ? this.receiver.constructor : null;
921 if (!constructor) { 921 if (!constructor) {
922 return false; 922 return false;
923 } 923 }
924 return this.fun === constructor; 924 return this.fun === constructor;
925 } 925 }
926 926
927 function CallSiteToString() { 927 function CallSiteToString() {
928 var fileName; 928 var fileName;
929 var fileLocation = ""; 929 var fileLocation = "";
930 if (this.isNative()) { 930 if (this.isNative()) {
931 fileLocation = "native"; 931 fileLocation = "native";
932 } else { 932 } else {
933 if (this.isEval()) { 933 if (this.isEval()) {
934 fileName = this.getScriptNameOrSourceURL(); 934 fileName = this.getScriptNameOrSourceURL();
935 if (!fileName) { 935 if (!fileName) {
936 fileLocation = this.getEvalOrigin(); 936 fileLocation = this.getEvalOrigin();
937 fileLocation += ", "; // Expecting source position to follow. 937 fileLocation += ", "; // Expecting source position to follow.
938 } 938 }
939 } else { 939 } else {
940 fileName = this.getFileName(); 940 fileName = this.getFileName();
941 } 941 }
942 942
943 if (fileName) { 943 if (fileName) {
944 fileLocation += fileName; 944 fileLocation += fileName;
945 } else { 945 } else {
946 // Source code does not originate from a file and is not native, but we 946 // Source code does not originate from a file and is not native, but we
947 // can still get the source position inside the source string, e.g. in 947 // can still get the source position inside the source string, e.g. in
948 // an eval string. 948 // an eval string.
949 fileLocation += "<anonymous>"; 949 fileLocation += "<anonymous>";
950 } 950 }
951 var lineNumber = this.getLineNumber(); 951 var lineNumber = this.getLineNumber();
952 if (lineNumber != null) { 952 if (lineNumber != null) {
953 fileLocation += ":" + lineNumber; 953 fileLocation += ":" + lineNumber;
954 var columnNumber = this.getColumnNumber(); 954 var columnNumber = this.getColumnNumber();
955 if (columnNumber) { 955 if (columnNumber) {
956 fileLocation += ":" + columnNumber; 956 fileLocation += ":" + columnNumber;
957 } 957 }
958 } 958 }
959 } 959 }
960 960
961 var line = ""; 961 var line = "";
962 var functionName = this.getFunctionName(); 962 var functionName = this.getFunctionName();
963 var addSuffix = true; 963 var addSuffix = true;
964 var isConstructor = this.isConstructor(); 964 var isConstructor = this.isConstructor();
965 var isMethodCall = !(this.isToplevel() || isConstructor); 965 var isMethodCall = !(this.isToplevel() || isConstructor);
966 if (isMethodCall) { 966 if (isMethodCall) {
967 var typeName = GetTypeName(this, true); 967 var typeName = GetTypeName(this, true);
968 var methodName = this.getMethodName(); 968 var methodName = this.getMethodName();
969 if (functionName) { 969 if (functionName) {
970 if (typeName && functionName.indexOf(typeName) != 0) { 970 if (typeName && functionName.indexOf(typeName) != 0) {
971 line += typeName + "."; 971 line += typeName + ".";
972 } 972 }
973 line += functionName; 973 line += functionName;
974 if (methodName && functionName.lastIndexOf("." + methodName) != 974 if (methodName && functionName.lastIndexOf("." + methodName) !=
975 functionName.length - methodName.length - 1) { 975 functionName.length - methodName.length - 1) {
976 line += " [as " + methodName + "]"; 976 line += " [as " + methodName + "]";
977 } 977 }
978 } else { 978 } else {
979 line += typeName + "." + (methodName || "<anonymous>"); 979 line += typeName + "." + (methodName || "<anonymous>");
980 } 980 }
981 } else if (isConstructor) { 981 } else if (isConstructor) {
982 line += "new " + (functionName || "<anonymous>"); 982 line += "new " + (functionName || "<anonymous>");
983 } else if (functionName) { 983 } else if (functionName) {
984 line += functionName; 984 line += functionName;
985 } else { 985 } else {
986 line += fileLocation; 986 line += fileLocation;
987 addSuffix = false; 987 addSuffix = false;
988 } 988 }
989 if (addSuffix) { 989 if (addSuffix) {
990 line += " (" + fileLocation + ")"; 990 line += " (" + fileLocation + ")";
991 } 991 }
992 return line; 992 return line;
993 } 993 }
994 994
995 SetUpLockedPrototype(CallSite, $Array("receiver", "fun", "pos"), $Array( 995 SetUpLockedPrototype(CallSite, $Array("receiver", "fun", "pos"), $Array(
996 "getThis", CallSiteGetThis, 996 "getThis", CallSiteGetThis,
997 "getTypeName", CallSiteGetTypeName, 997 "getTypeName", CallSiteGetTypeName,
998 "isToplevel", CallSiteIsToplevel, 998 "isToplevel", CallSiteIsToplevel,
999 "isEval", CallSiteIsEval, 999 "isEval", CallSiteIsEval,
1000 "getEvalOrigin", CallSiteGetEvalOrigin, 1000 "getEvalOrigin", CallSiteGetEvalOrigin,
1001 "getScriptNameOrSourceURL", CallSiteGetScriptNameOrSourceURL, 1001 "getScriptNameOrSourceURL", CallSiteGetScriptNameOrSourceURL,
1002 "getFunction", CallSiteGetFunction, 1002 "getFunction", CallSiteGetFunction,
1003 "getFunctionName", CallSiteGetFunctionName, 1003 "getFunctionName", CallSiteGetFunctionName,
1004 "getMethodName", CallSiteGetMethodName, 1004 "getMethodName", CallSiteGetMethodName,
1005 "getFileName", CallSiteGetFileName, 1005 "getFileName", CallSiteGetFileName,
1006 "getLineNumber", CallSiteGetLineNumber, 1006 "getLineNumber", CallSiteGetLineNumber,
1007 "getColumnNumber", CallSiteGetColumnNumber, 1007 "getColumnNumber", CallSiteGetColumnNumber,
1008 "isNative", CallSiteIsNative, 1008 "isNative", CallSiteIsNative,
1009 "getPosition", CallSiteGetPosition, 1009 "getPosition", CallSiteGetPosition,
1010 "isConstructor", CallSiteIsConstructor, 1010 "isConstructor", CallSiteIsConstructor,
1011 "toString", CallSiteToString 1011 "toString", CallSiteToString
1012 )); 1012 ));
1013 1013
1014 1014
1015 function FormatEvalOrigin(script) { 1015 function FormatEvalOrigin(script) {
1016 var sourceURL = script.nameOrSourceURL(); 1016 var sourceURL = script.nameOrSourceURL();
1017 if (sourceURL) { 1017 if (sourceURL) {
1018 return sourceURL; 1018 return sourceURL;
1019 } 1019 }
1020 1020
1021 var eval_origin = "eval at "; 1021 var eval_origin = "eval at ";
1022 if (script.eval_from_function_name) { 1022 if (script.eval_from_function_name) {
1023 eval_origin += script.eval_from_function_name; 1023 eval_origin += script.eval_from_function_name;
1024 } else { 1024 } else {
1025 eval_origin += "<anonymous>"; 1025 eval_origin += "<anonymous>";
1026 } 1026 }
1027 1027
1028 var eval_from_script = script.eval_from_script; 1028 var eval_from_script = script.eval_from_script;
1029 if (eval_from_script) { 1029 if (eval_from_script) {
1030 if (eval_from_script.compilation_type == COMPILATION_TYPE_EVAL) { 1030 if (eval_from_script.compilation_type == COMPILATION_TYPE_EVAL) {
1031 // eval script originated from another eval. 1031 // eval script originated from another eval.
1032 eval_origin += " (" + FormatEvalOrigin(eval_from_script) + ")"; 1032 eval_origin += " (" + FormatEvalOrigin(eval_from_script) + ")";
1033 } else { 1033 } else {
1034 // eval script originated from "real" source. 1034 // eval script originated from "real" source.
1035 if (eval_from_script.name) { 1035 if (eval_from_script.name) {
1036 eval_origin += " (" + eval_from_script.name; 1036 eval_origin += " (" + eval_from_script.name;
1037 var location = eval_from_script.locationFromPosition( 1037 var location = eval_from_script.locationFromPosition(
1038 script.eval_from_script_position, true); 1038 script.eval_from_script_position, true);
1039 if (location) { 1039 if (location) {
1040 eval_origin += ":" + (location.line + 1); 1040 eval_origin += ":" + (location.line + 1);
1041 eval_origin += ":" + (location.column + 1); 1041 eval_origin += ":" + (location.column + 1);
1042 } 1042 }
1043 eval_origin += ")"; 1043 eval_origin += ")";
1044 } else { 1044 } else {
1045 eval_origin += " (unknown source)"; 1045 eval_origin += " (unknown source)";
1046 } 1046 }
1047 } 1047 }
1048 } 1048 }
1049 1049
1050 return eval_origin; 1050 return eval_origin;
1051 } 1051 }
1052 1052
1053 function FormatStackTrace(error, frames) { 1053 function FormatStackTrace(error, frames) {
1054 var lines = []; 1054 var lines = [];
1055 try { 1055 try {
1056 lines.push(error.toString()); 1056 lines.push(error.toString());
1057 } catch (e) { 1057 } catch (e) {
1058 try { 1058 try {
1059 lines.push("<error: " + e + ">"); 1059 lines.push("<error: " + e + ">");
1060 } catch (ee) { 1060 } catch (ee) {
1061 lines.push("<error>"); 1061 lines.push("<error>");
1062 } 1062 }
1063 } 1063 }
1064 for (var i = 0; i < frames.length; i++) { 1064 for (var i = 0; i < frames.length; i++) {
1065 var frame = frames[i]; 1065 var frame = frames[i];
1066 var line; 1066 var line;
1067 try { 1067 try {
1068 line = frame.toString(); 1068 line = frame.toString();
1069 } catch (e) { 1069 } catch (e) {
1070 try { 1070 try {
1071 line = "<error: " + e + ">"; 1071 line = "<error: " + e + ">";
1072 } catch (ee) { 1072 } catch (ee) {
1073 // Any code that reaches this point is seriously nasty! 1073 // Any code that reaches this point is seriously nasty!
1074 line = "<error>"; 1074 line = "<error>";
1075 } 1075 }
1076 } 1076 }
1077 lines.push(" at " + line); 1077 lines.push(" at " + line);
1078 } 1078 }
1079 return lines.join("\n"); 1079 return lines.join("\n");
1080 } 1080 }
1081 1081
1082 function FormatRawStackTrace(error, raw_stack) { 1082 function FormatRawStackTrace(error, raw_stack) {
1083 var frames = [ ]; 1083 var frames = [ ];
1084 for (var i = 0; i < raw_stack.length; i += 4) { 1084 for (var i = 0; i < raw_stack.length; i += 4) {
1085 var recv = raw_stack[i]; 1085 var recv = raw_stack[i];
1086 var fun = raw_stack[i + 1]; 1086 var fun = raw_stack[i + 1];
1087 var code = raw_stack[i + 2]; 1087 var code = raw_stack[i + 2];
1088 var pc = raw_stack[i + 3]; 1088 var pc = raw_stack[i + 3];
1089 var pos = %FunctionGetPositionForOffset(code, pc); 1089 var pos = %FunctionGetPositionForOffset(code, pc);
1090 frames.push(new CallSite(recv, fun, pos)); 1090 frames.push(new CallSite(recv, fun, pos));
1091 } 1091 }
1092 if (IS_FUNCTION($Error.prepareStackTrace)) { 1092 if (IS_FUNCTION($Error.prepareStackTrace)) {
1093 return $Error.prepareStackTrace(error, frames); 1093 return $Error.prepareStackTrace(error, frames);
1094 } else { 1094 } else {
1095 return FormatStackTrace(error, frames); 1095 return FormatStackTrace(error, frames);
1096 } 1096 }
1097 } 1097 }
1098 1098
1099 function GetTypeName(obj, requireConstructor) { 1099 function GetTypeName(obj, requireConstructor) {
1100 var constructor = obj.receiver.constructor; 1100 var constructor = obj.receiver.constructor;
1101 if (!constructor) { 1101 if (!constructor) {
1102 return requireConstructor ? null : 1102 return requireConstructor ? null :
1103 %_CallFunction(obj.receiver, ObjectToString); 1103 %_CallFunction(obj.receiver, ObjectToString);
1104 } 1104 }
1105 var constructorName = constructor.name; 1105 var constructorName = constructor.name;
1106 if (!constructorName) { 1106 if (!constructorName) {
1107 return requireConstructor ? null : 1107 return requireConstructor ? null :
1108 %_CallFunction(obj.receiver, ObjectToString); 1108 %_CallFunction(obj.receiver, ObjectToString);
1109 } 1109 }
1110 return constructorName; 1110 return constructorName;
1111 } 1111 }
1112 1112
1113 function captureStackTrace(obj, cons_opt) { 1113 function captureStackTrace(obj, cons_opt) {
1114 var stackTraceLimit = $Error.stackTraceLimit; 1114 var stackTraceLimit = $Error.stackTraceLimit;
1115 if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return; 1115 if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return;
1116 if (stackTraceLimit < 0 || stackTraceLimit > 10000) { 1116 if (stackTraceLimit < 0 || stackTraceLimit > 10000) {
1117 stackTraceLimit = 10000; 1117 stackTraceLimit = 10000;
1118 } 1118 }
1119 var raw_stack = %CollectStackTrace(obj, 1119 var raw_stack = %CollectStackTrace(obj,
1120 cons_opt ? cons_opt : captureStackTrace, 1120 cons_opt ? cons_opt : captureStackTrace,
1121 stackTraceLimit); 1121 stackTraceLimit);
1122 DefineOneShotAccessor(obj, 'stack', function (obj) { 1122 DefineOneShotAccessor(obj, 'stack', function (obj) {
1123 return FormatRawStackTrace(obj, raw_stack); 1123 return FormatRawStackTrace(obj, raw_stack);
1124 }); 1124 });
1125 } 1125 }
1126 1126
1127 1127
1128 function SetUpError() { 1128 function SetUpError() {
1129 // Define special error type constructors. 1129 // Define special error type constructors.
1130 1130
1131 var DefineError = function(f) { 1131 var DefineError = function(f) {
1132 // Store the error function in both the global object 1132 // Store the error function in both the global object
1133 // and the runtime object. The function is fetched 1133 // and the runtime object. The function is fetched
1134 // from the runtime object when throwing errors from 1134 // from the runtime object when throwing errors from
1135 // within the runtime system to avoid strange side 1135 // within the runtime system to avoid strange side
1136 // effects when overwriting the error functions from 1136 // effects when overwriting the error functions from
1137 // user code. 1137 // user code.
1138 var name = f.name; 1138 var name = f.name;
1139 %SetProperty(global, name, f, DONT_ENUM); 1139 %SetProperty(global, name, f, DONT_ENUM);
1140 %SetProperty(builtins, '$' + name, f, DONT_ENUM | DONT_DELETE | READ_ONLY); 1140 %SetProperty(builtins, '$' + name, f, DONT_ENUM | DONT_DELETE | READ_ONLY);
1141 // Configure the error function. 1141 // Configure the error function.
1142 if (name == 'Error') { 1142 if (name == 'Error') {
1143 // The prototype of the Error object must itself be an error. 1143 // The prototype of the Error object must itself be an error.
1144 // However, it can't be an instance of the Error object because 1144 // However, it can't be an instance of the Error object because
1145 // it hasn't been properly configured yet. Instead we create a 1145 // it hasn't been properly configured yet. Instead we create a
1146 // special not-a-true-error-but-close-enough object. 1146 // special not-a-true-error-but-close-enough object.
1147 var ErrorPrototype = function() {}; 1147 var ErrorPrototype = function() {};
1148 %FunctionSetPrototype(ErrorPrototype, $Object.prototype); 1148 %FunctionSetPrototype(ErrorPrototype, $Object.prototype);
1149 %FunctionSetInstanceClassName(ErrorPrototype, 'Error'); 1149 %FunctionSetInstanceClassName(ErrorPrototype, 'Error');
1150 %FunctionSetPrototype(f, new ErrorPrototype()); 1150 %FunctionSetPrototype(f, new ErrorPrototype());
1151 } else { 1151 } else {
1152 %FunctionSetPrototype(f, new $Error()); 1152 %FunctionSetPrototype(f, new $Error());
1153 } 1153 }
1154 %FunctionSetInstanceClassName(f, 'Error'); 1154 %FunctionSetInstanceClassName(f, 'Error');
1155 %SetProperty(f.prototype, 'constructor', f, DONT_ENUM); 1155 %SetProperty(f.prototype, 'constructor', f, DONT_ENUM);
1156 %SetProperty(f.prototype, "name", name, DONT_ENUM); 1156 %SetProperty(f.prototype, "name", name, DONT_ENUM);
1157 %SetCode(f, function(m) { 1157 %SetCode(f, function(m) {
1158 if (%_IsConstructCall()) { 1158 if (%_IsConstructCall()) {
1159 // Define all the expected properties directly on the error 1159 // Define all the expected properties directly on the error
1160 // object. This avoids going through getters and setters defined 1160 // object. This avoids going through getters and setters defined
1161 // on prototype objects. 1161 // on prototype objects.
1162 %IgnoreAttributesAndSetProperty(this, 'stack', void 0, DONT_ENUM); 1162 %IgnoreAttributesAndSetProperty(this, 'stack', void 0, DONT_ENUM);
1163 %IgnoreAttributesAndSetProperty(this, 'arguments', void 0, DONT_ENUM); 1163 %IgnoreAttributesAndSetProperty(this, 'arguments', void 0, DONT_ENUM);
1164 %IgnoreAttributesAndSetProperty(this, 'type', void 0, DONT_ENUM); 1164 %IgnoreAttributesAndSetProperty(this, 'type', void 0, DONT_ENUM);
1165 if (m === kAddMessageAccessorsMarker) { 1165 if (m === kAddMessageAccessorsMarker) {
1166 // DefineOneShotAccessor always inserts a message property and 1166 // DefineOneShotAccessor always inserts a message property and
1167 // ignores setters. 1167 // ignores setters.
1168 DefineOneShotAccessor(this, 'message', function (obj) { 1168 DefineOneShotAccessor(this, 'message', function (obj) {
1169 return FormatMessage(%NewMessageObject(obj.type, obj.arguments)); 1169 return FormatMessage(%NewMessageObject(obj.type, obj.arguments));
1170 }); 1170 });
1171 } else if (!IS_UNDEFINED(m)) { 1171 } else if (!IS_UNDEFINED(m)) {
1172 %IgnoreAttributesAndSetProperty( 1172 %IgnoreAttributesAndSetProperty(
1173 this, 'message', ToString(m), DONT_ENUM); 1173 this, 'message', ToString(m), DONT_ENUM);
1174 } 1174 }
1175 captureStackTrace(this, f); 1175 captureStackTrace(this, f);
1176 } else { 1176 } else {
1177 return new f(m); 1177 return new f(m);
1178 } 1178 }
1179 }); 1179 });
1180 %SetNativeFlag(f); 1180 %SetNativeFlag(f);
1181 }; 1181 };
1182 1182
1183 DefineError(function Error() { }); 1183 DefineError(function Error() { });
1184 DefineError(function TypeError() { }); 1184 DefineError(function TypeError() { });
1185 DefineError(function RangeError() { }); 1185 DefineError(function RangeError() { });
1186 DefineError(function SyntaxError() { }); 1186 DefineError(function SyntaxError() { });
1187 DefineError(function ReferenceError() { }); 1187 DefineError(function ReferenceError() { });
1188 DefineError(function EvalError() { }); 1188 DefineError(function EvalError() { });
1189 DefineError(function URIError() { }); 1189 DefineError(function URIError() { });
1190 } 1190 }
1191 1191
1192 SetUpError(); 1192 SetUpError();
1193 1193
1194 $Error.captureStackTrace = captureStackTrace; 1194 $Error.captureStackTrace = captureStackTrace;
1195 1195
1196 %SetProperty($Error.prototype, 'message', '', DONT_ENUM); 1196 %SetProperty($Error.prototype, 'message', '', DONT_ENUM);
1197 1197
1198 // Global list of error objects visited during ErrorToString. This is 1198 // Global list of error objects visited during ErrorToString. This is
1199 // used to detect cycles in error toString formatting. 1199 // used to detect cycles in error toString formatting.
1200 var visited_errors = new InternalArray(); 1200 var visited_errors = new InternalArray();
1201 var cyclic_error_marker = new $Object(); 1201 var cyclic_error_marker = new $Object();
1202 1202
1203 function GetPropertyWithoutInvokingMonkeyGetters(error, name) { 1203 function GetPropertyWithoutInvokingMonkeyGetters(error, name) {
1204 // Climb the prototype chain until we find the holder. 1204 // Climb the prototype chain until we find the holder.
1205 while (error && !%HasLocalProperty(error, name)) { 1205 while (error && !%HasLocalProperty(error, name)) {
1206 error = error.__proto__; 1206 error = error.__proto__;
1207 } 1207 }
1208 if (error === null) return void 0; 1208 if (error === null) return void 0;
1209 if (!IS_OBJECT(error)) return error[name]; 1209 if (!IS_OBJECT(error)) return error[name];
1210 // If the property is an accessor on one of the predefined errors that can be 1210 // If the property is an accessor on one of the predefined errors that can be
1211 // generated statically by the compiler, don't touch it. This is to address 1211 // generated statically by the compiler, don't touch it. This is to address
1212 // http://code.google.com/p/chromium/issues/detail?id=69187 1212 // http://code.google.com/p/chromium/issues/detail?id=69187
1213 var desc = %GetOwnProperty(error, name); 1213 var desc = %GetOwnProperty(error, name);
1214 if (desc && desc[IS_ACCESSOR_INDEX]) { 1214 if (desc && desc[IS_ACCESSOR_INDEX]) {
1215 var isName = name === "name"; 1215 var isName = name === "name";
1216 if (error === $ReferenceError.prototype) 1216 if (error === $ReferenceError.prototype)
1217 return isName ? "ReferenceError" : void 0; 1217 return isName ? "ReferenceError" : void 0;
1218 if (error === $SyntaxError.prototype) 1218 if (error === $SyntaxError.prototype)
1219 return isName ? "SyntaxError" : void 0; 1219 return isName ? "SyntaxError" : void 0;
1220 if (error === $TypeError.prototype) 1220 if (error === $TypeError.prototype)
1221 return isName ? "TypeError" : void 0; 1221 return isName ? "TypeError" : void 0;
1222 } 1222 }
1223 // Otherwise, read normally. 1223 // Otherwise, read normally.
1224 return error[name]; 1224 return error[name];
1225 } 1225 }
1226 1226
1227 function ErrorToStringDetectCycle(error) { 1227 function ErrorToStringDetectCycle(error) {
1228 if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker; 1228 if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker;
1229 try { 1229 try {
1230 var type = GetPropertyWithoutInvokingMonkeyGetters(error, "type"); 1230 var type = GetPropertyWithoutInvokingMonkeyGetters(error, "type");
1231 var name = GetPropertyWithoutInvokingMonkeyGetters(error, "name"); 1231 var name = GetPropertyWithoutInvokingMonkeyGetters(error, "name");
1232 name = IS_UNDEFINED(name) ? "Error" : TO_STRING_INLINE(name); 1232 name = IS_UNDEFINED(name) ? "Error" : TO_STRING_INLINE(name);
1233 var message = GetPropertyWithoutInvokingMonkeyGetters(error, "message"); 1233 var message = GetPropertyWithoutInvokingMonkeyGetters(error, "message");
1234 var hasMessage = %_CallFunction(error, "message", ObjectHasOwnProperty); 1234 var hasMessage = %_CallFunction(error, "message", ObjectHasOwnProperty);
1235 if (type && !hasMessage) { 1235 if (type && !hasMessage) {
1236 var args = GetPropertyWithoutInvokingMonkeyGetters(error, "arguments"); 1236 var args = GetPropertyWithoutInvokingMonkeyGetters(error, "arguments");
1237 message = FormatMessage(%NewMessageObject(type, args)); 1237 message = FormatMessage(%NewMessageObject(type, args));
1238 } 1238 }
1239 message = IS_UNDEFINED(message) ? "" : TO_STRING_INLINE(message); 1239 message = IS_UNDEFINED(message) ? "" : TO_STRING_INLINE(message);
1240 if (name === "") return message; 1240 if (name === "") return message;
1241 if (message === "") return name; 1241 if (message === "") return name;
1242 return name + ": " + message; 1242 return name + ": " + message;
1243 } finally { 1243 } finally {
1244 visited_errors.length = visited_errors.length - 1; 1244 visited_errors.length = visited_errors.length - 1;
1245 } 1245 }
1246 } 1246 }
1247 1247
1248 function ErrorToString() { 1248 function ErrorToString() {
1249 if (!IS_SPEC_OBJECT(this)) { 1249 if (!IS_SPEC_OBJECT(this)) {
1250 throw MakeTypeError("called_on_non_object", ["Error.prototype.toString"]); 1250 throw MakeTypeError("called_on_non_object", ["Error.prototype.toString"]);
1251 } 1251 }
1252 1252
1253 try { 1253 try {
1254 return ErrorToStringDetectCycle(this); 1254 return ErrorToStringDetectCycle(this);
1255 } catch(e) { 1255 } catch(e) {
1256 // If this error message was encountered already return the empty 1256 // If this error message was encountered already return the empty
1257 // string for it instead of recursively formatting it. 1257 // string for it instead of recursively formatting it.
1258 if (e === cyclic_error_marker) { 1258 if (e === cyclic_error_marker) {
1259 return ''; 1259 return '';
1260 } 1260 }
1261 throw e; 1261 throw e;
1262 } 1262 }
1263 } 1263 }
1264 1264
1265 1265
1266 InstallFunctions($Error.prototype, DONT_ENUM, ['toString', ErrorToString]); 1266 InstallFunctions($Error.prototype, DONT_ENUM, ['toString', ErrorToString]);
1267 1267
1268 // Boilerplate for exceptions for stack overflows. Used from 1268 // Boilerplate for exceptions for stack overflows. Used from
1269 // Isolate::StackOverflow(). 1269 // Isolate::StackOverflow().
1270 var kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); 1270 var kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []);
Powered by Google Project Hosting