OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 apply_non_function: "Function.prototype.apply was called on %0, whic
h is a %1 and not a function", | 95 apply_non_function: "Function.prototype.apply was called on %0, whic
h is a %1 and not a function", |
96 apply_wrong_args: "Function.prototype.apply: Arguments list has wr
ong type", | 96 apply_wrong_args: "Function.prototype.apply: Arguments list has wr
ong type", |
97 invalid_in_operator_use: "Cannot use 'in' operator to search for '%0' in
%1", | 97 invalid_in_operator_use: "Cannot use 'in' operator to search for '%0' in
%1", |
98 instanceof_function_expected: "Expecting a function in instanceof check, but g
ot %0", | 98 instanceof_function_expected: "Expecting a function in instanceof check, but g
ot %0", |
99 instanceof_nonobject_proto: "Function has non-object prototype '%0' in insta
nceof check", | 99 instanceof_nonobject_proto: "Function has non-object prototype '%0' in insta
nceof check", |
100 null_to_object: "Cannot convert null to object", | 100 null_to_object: "Cannot convert null to object", |
101 // RangeError | 101 // RangeError |
102 invalid_array_length: "Invalid array length", | 102 invalid_array_length: "Invalid array length", |
103 invalid_array_apply_length: "Function.prototype.apply supports only up to 10
24 arguments", | 103 invalid_array_apply_length: "Function.prototype.apply supports only up to 10
24 arguments", |
104 stack_overflow: "Maximum call stack size exceeded", | 104 stack_overflow: "Maximum call stack size exceeded", |
105 apply_overflow: "Function.prototype.apply cannot support %0 argu
ments", | 105 apply_overflow: "Function.prototype.apply cannot support %0 argu
ments", |
106 // SyntaxError | 106 // SyntaxError |
107 unable_to_parse: "Parse error", | 107 unable_to_parse: "Parse error", |
108 duplicate_regexp_flag: "Duplicate RegExp flag %0", | 108 duplicate_regexp_flag: "Duplicate RegExp flag %0", |
109 unrecognized_regexp_flag: "Unrecognized RegExp flag %0", | 109 unrecognized_regexp_flag: "Unrecognized RegExp flag %0", |
110 invalid_regexp: "Invalid RegExp pattern /%0/", | 110 invalid_regexp: "Invalid RegExp pattern /%0/", |
111 illegal_break: "Illegal break statement", | 111 illegal_break: "Illegal break statement", |
112 illegal_continue: "Illegal continue statement", | 112 illegal_continue: "Illegal continue statement", |
113 illegal_return: "Illegal return statement", | 113 illegal_return: "Illegal return statement", |
114 error_loading_debugger: "Error loading debugger %0", | 114 error_loading_debugger: "Error loading debugger %0", |
115 no_input_to_regexp: "No input to %0", | 115 no_input_to_regexp: "No input to %0", |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 return MakeGenericError($EvalError, type, args); | 221 return MakeGenericError($EvalError, type, args); |
222 } | 222 } |
223 | 223 |
224 | 224 |
225 function MakeError(type, args) { | 225 function MakeError(type, args) { |
226 return MakeGenericError($Error, type, args); | 226 return MakeGenericError($Error, type, args); |
227 } | 227 } |
228 | 228 |
229 | 229 |
230 /** | 230 /** |
231 * Initialize the cached source information in a script. Currently all line | |
232 * end positions are cached. | |
233 */ | |
234 Script.prototype.initSourceInfo_ = function () { | |
235 // Just return if initialized. | |
236 if (this.lineEnds_) return; | |
237 | |
238 // Collect all line endings. | |
239 this.lineEnds_ = []; | |
240 for (var i = 0; i < this.source.length; i++) { | |
241 var current = this.source.charAt(i); | |
242 if (current == '\n') { | |
243 this.lineEnds_.push(i); | |
244 } | |
245 } | |
246 | |
247 // If the script does not end with a line ending add the final end position | |
248 // as just past the last line ending. | |
249 if (this.lineEnds_[this.lineEnds_.length - 1] != this.source.length - 1) { | |
250 this.lineEnds_.push(this.source.length); | |
251 } | |
252 }; | |
253 | |
254 | |
255 /** | |
256 * Get information on a specific source position. | 231 * Get information on a specific source position. |
257 * @param {number} position The source position | 232 * @param {number} position The source position |
258 * @return {SourceLocation} | 233 * @return {SourceLocation} |
259 * If line is negative or not in the source null is returned. | 234 * If line is negative or not in the source null is returned. |
260 */ | 235 */ |
261 Script.prototype.locationFromPosition = function (position) { | 236 Script.prototype.locationFromPosition = function (position) { |
262 // Make sure source info has been initialized. | |
263 this.initSourceInfo_(); | |
264 | |
265 var lineCount = this.lineCount(); | 237 var lineCount = this.lineCount(); |
266 var line = -1; | 238 var line = -1; |
267 if (position <= this.lineEnds_[0]) { | 239 if (position <= this.line_ends[0]) { |
268 line = 0; | 240 line = 0; |
269 } else { | 241 } else { |
270 for (var i = 1; i < lineCount; i++) { | 242 for (var i = 1; i < lineCount; i++) { |
271 if (this.lineEnds_[i - 1] < position && position <= this.lineEnds_[i]) { | 243 if (this.line_ends[i - 1] < position && position <= this.line_ends[i]) { |
272 line = i; | 244 line = i; |
273 break; | 245 break; |
274 } | 246 } |
275 } | 247 } |
276 } | 248 } |
277 | 249 |
278 if (line == -1) return null; | 250 if (line == -1) return null; |
279 | 251 |
280 // Determine start, end and column. | 252 // Determine start, end and column. |
281 var start = line == 0 ? 0 : this.lineEnds_[line - 1] + 1; | 253 var start = line == 0 ? 0 : this.line_ends[line - 1] + 1; |
282 var end = this.lineEnds_[line]; | 254 var end = this.line_ends[line]; |
283 if (end > 0 && this.source.charAt(end - 1) == '\r') end--; | 255 if (end > 0 && this.source.charAt(end - 1) == '\r') end--; |
284 var column = position - start; | 256 var column = position - start; |
285 | 257 |
286 // Adjust according to the offset within the resource. | 258 // Adjust according to the offset within the resource. |
287 line += this.line_offset; | 259 line += this.line_offset; |
288 if (line == this.line_offset) { | 260 if (line == this.line_offset) { |
289 column += this.column_offset; | 261 column += this.column_offset; |
290 } | 262 } |
291 | 263 |
292 return new SourceLocation(this, position, line, column, start, end); | 264 return new SourceLocation(this, position, line, column, start, end); |
293 }; | 265 }; |
294 | 266 |
295 | 267 |
296 /** | 268 /** |
297 * Get information on a specific source line and column possibly offset by a | 269 * Get information on a specific source line and column possibly offset by a |
298 * fixed source position. This function is used to find a source position from | 270 * fixed source position. This function is used to find a source position from |
299 * a line and column position. The fixed source position offset is typically | 271 * a line and column position. The fixed source position offset is typically |
300 * used to find a source position in a function based on a line and column in | 272 * used to find a source position in a function based on a line and column in |
301 * the source for the function alone. The offset passed will then be the | 273 * the source for the function alone. The offset passed will then be the |
302 * start position of the source for the function within the full script source. | 274 * start position of the source for the function within the full script source. |
303 * @param {number} opt_line The line within the source. Default value is 0 | 275 * @param {number} opt_line The line within the source. Default value is 0 |
304 * @param {number} opt_column The column in within the line. Default value is 0 | 276 * @param {number} opt_column The column in within the line. Default value is 0 |
305 * @param {number} opt_offset_position The offset from the begining of the | 277 * @param {number} opt_offset_position The offset from the begining of the |
306 * source from where the line and column calculation starts. Default value i
s 0 | 278 * source from where the line and column calculation starts. Default value i
s 0 |
307 * @return {SourceLocation} | 279 * @return {SourceLocation} |
308 * If line is negative or not in the source null is returned. | 280 * If line is negative or not in the source null is returned. |
309 */ | 281 */ |
310 Script.prototype.locationFromLine = function (opt_line, opt_column, opt_offset_p
osition) { | 282 Script.prototype.locationFromLine = function (opt_line, opt_column, opt_offset_p
osition) { |
311 // Make soure source info has been initialized. | |
312 this.initSourceInfo_(); | |
313 | |
314 // Default is the first line in the script. Lines in the script is relative | 283 // Default is the first line in the script. Lines in the script is relative |
315 // to the offset within the resource. | 284 // to the offset within the resource. |
316 var line = 0; | 285 var line = 0; |
317 if (!IS_UNDEFINED(opt_line)) { | 286 if (!IS_UNDEFINED(opt_line)) { |
318 line = opt_line - this.line_offset; | 287 line = opt_line - this.line_offset; |
319 } | 288 } |
320 | 289 |
321 // Default is first column. If on the first line add the offset within the | 290 // Default is first column. If on the first line add the offset within the |
322 // resource. | 291 // resource. |
323 var column = opt_column || 0; | 292 var column = opt_column || 0; |
324 if (line == 0) { | 293 if (line == 0) { |
325 column -= this.column_offset | 294 column -= this.column_offset |
326 } | 295 } |
327 | 296 |
328 var offset_position = opt_offset_position || 0; | 297 var offset_position = opt_offset_position || 0; |
329 if (line < 0 || column < 0 || offset_position < 0) return null; | 298 if (line < 0 || column < 0 || offset_position < 0) return null; |
330 if (line == 0) { | 299 if (line == 0) { |
331 return this.locationFromPosition(offset_position + column); | 300 return this.locationFromPosition(offset_position + column); |
332 } else { | 301 } else { |
333 // Find the line where the offset position is located | 302 // Find the line where the offset position is located |
334 var lineCount = this.lineCount(); | 303 var lineCount = this.lineCount(); |
335 var offset_line; | 304 var offset_line; |
336 for (var i = 0; i < lineCount; i++) { | 305 for (var i = 0; i < lineCount; i++) { |
337 if (offset_position <= this.lineEnds_[i]) { | 306 if (offset_position <= this.line_ends[i]) { |
338 offset_line = i; | 307 offset_line = i; |
339 break; | 308 break; |
340 } | 309 } |
341 } | 310 } |
342 if (offset_line + line >= lineCount) return null; | 311 if (offset_line + line >= lineCount) return null; |
343 return this.locationFromPosition(this.lineEnds_[offset_line + line - 1] + 1
+ column); // line > 0 here. | 312 return this.locationFromPosition(this.line_ends[offset_line + line - 1] + 1
+ column); // line > 0 here. |
344 } | 313 } |
345 } | 314 } |
346 | 315 |
347 | 316 |
348 /** | 317 /** |
349 * Get a slice of source code from the script. The boundaries for the slice is | 318 * Get a slice of source code from the script. The boundaries for the slice is |
350 * specified in lines. | 319 * specified in lines. |
351 * @param {number} opt_from_line The first line (zero bound) in the slice. | 320 * @param {number} opt_from_line The first line (zero bound) in the slice. |
352 * Default is 0 | 321 * Default is 0 |
353 * @param {number} opt_to_column The last line (zero bound) in the slice (non | 322 * @param {number} opt_to_column The last line (zero bound) in the slice (non |
354 * inclusive). Default is the number of lines in the script | 323 * inclusive). Default is the number of lines in the script |
355 * @return {SourceSlice} The source slice or null of the parameters where | 324 * @return {SourceSlice} The source slice or null of the parameters where |
356 * invalid | 325 * invalid |
357 */ | 326 */ |
358 Script.prototype.sourceSlice = function (opt_from_line, opt_to_line) { | 327 Script.prototype.sourceSlice = function (opt_from_line, opt_to_line) { |
359 // Make soure source info has been initialized. | |
360 this.initSourceInfo_(); | |
361 | |
362 var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset : opt_from_line
; | 328 var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset : opt_from_line
; |
363 var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
: opt_to_line | 329 var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
: opt_to_line |
364 | 330 |
365 // Adjust according to the offset within the resource. | 331 // Adjust according to the offset within the resource. |
366 from_line -= this.line_offset; | 332 from_line -= this.line_offset; |
367 to_line -= this.line_offset; | 333 to_line -= this.line_offset; |
368 if (from_line < 0) from_line = 0; | 334 if (from_line < 0) from_line = 0; |
369 if (to_line > this.lineCount()) to_line = this.lineCount(); | 335 if (to_line > this.lineCount()) to_line = this.lineCount(); |
370 | 336 |
371 // Check parameters. | 337 // Check parameters. |
372 if (from_line >= this.lineCount() || | 338 if (from_line >= this.lineCount() || |
373 to_line < 0 || | 339 to_line < 0 || |
374 from_line > to_line) { | 340 from_line > to_line) { |
375 return null; | 341 return null; |
376 } | 342 } |
377 | 343 |
378 var from_position = from_line == 0 ? 0 : this.lineEnds_[from_line - 1] + 1; | 344 var from_position = from_line == 0 ? 0 : this.line_ends[from_line - 1] + 1; |
379 var to_position = to_line == 0 ? 0 : this.lineEnds_[to_line - 1] + 1; | 345 var to_position = to_line == 0 ? 0 : this.line_ends[to_line - 1] + 1; |
380 | 346 |
381 // Return a source slice with line numbers re-adjusted to the resource. | 347 // Return a source slice with line numbers re-adjusted to the resource. |
382 return new SourceSlice(this, from_line + this.line_offset, to_line + this.line
_offset, | 348 return new SourceSlice(this, from_line + this.line_offset, to_line + this.line
_offset, |
383 from_position, to_position); | 349 from_position, to_position); |
384 } | 350 } |
385 | 351 |
386 | 352 |
387 Script.prototype.sourceLine = function (opt_line) { | 353 Script.prototype.sourceLine = function (opt_line) { |
388 // Default is the first line in the script. Lines in the script are relative | 354 // Default is the first line in the script. Lines in the script are relative |
389 // to the offset within the resource. | 355 // to the offset within the resource. |
390 var line = 0; | 356 var line = 0; |
391 if (!IS_UNDEFINED(opt_line)) { | 357 if (!IS_UNDEFINED(opt_line)) { |
392 line = opt_line - this.line_offset; | 358 line = opt_line - this.line_offset; |
393 } | 359 } |
394 | 360 |
395 // Check parameter. | 361 // Check parameter. |
396 if (line < 0 || this.lineCount() <= line) { | 362 if (line < 0 || this.lineCount() <= line) { |
397 return null; | 363 return null; |
398 } | 364 } |
399 | 365 |
400 // Return the source line. | 366 // Return the source line. |
401 var start = line == 0 ? 0 : this.lineEnds_[line - 1] + 1; | 367 var start = line == 0 ? 0 : this.line_ends[line - 1] + 1; |
402 var end = this.lineEnds_[line]; | 368 var end = this.line_ends[line]; |
403 return this.source.substring(start, end); | 369 return this.source.substring(start, end); |
404 } | 370 } |
405 | 371 |
406 | 372 |
407 /** | 373 /** |
408 * Returns the number of source lines. | 374 * Returns the number of source lines. |
409 * @return {number} | 375 * @return {number} |
410 * Number of source lines. | 376 * Number of source lines. |
411 */ | 377 */ |
412 Script.prototype.lineCount = function() { | 378 Script.prototype.lineCount = function() { |
413 // Make soure source info has been initialized. | 379 // Return number of source lines. |
414 this.initSourceInfo_(); | 380 return this.line_ends.length; |
415 | |
416 // Return number of source lines. | |
417 return this.lineEnds_.length; | |
418 }; | 381 }; |
419 | 382 |
420 | 383 |
421 /** | 384 /** |
422 * Class for source location. A source location is a position within some | 385 * Class for source location. A source location is a position within some |
423 * source with the following properties: | 386 * source with the following properties: |
424 * script : script object for the source | 387 * script : script object for the source |
425 * line : source line number | 388 * line : source line number |
426 * column : source column within the line | 389 * column : source column within the line |
427 * position : position within the source | 390 * position : position within the source |
428 * start : position of start of source context (inclusive) | 391 * start : position of start of source context (inclusive) |
429 * end : position of end of source context (not inclusive) | 392 * end : position of end of source context (not inclusive) |
430 * Source text for the source context is the character interval [start, end[. In | 393 * Source text for the source context is the character interval [start, end[. In |
431 * most cases end will point to a newline character. It might point just past | 394 * most cases end will point to a newline character. It might point just past |
432 * the final position of the source if the last source line does not end with a | 395 * the final position of the source if the last source line does not end with a |
433 * newline character. | 396 * newline character. |
434 * @param {Script} script The Script object for which this is a location | 397 * @param {Script} script The Script object for which this is a location |
435 * @param {number} position Source position for the location | 398 * @param {number} position Source position for the location |
436 * @param {number} line The line number for the location | 399 * @param {number} line The line number for the location |
437 * @param {number} column The column within the line for the location | 400 * @param {number} column The column within the line for the location |
438 * @param {number} start Source position for start of source context | 401 * @param {number} start Source position for start of source context |
439 * @param {number} end Source position for end of source context | 402 * @param {number} end Source position for end of source context |
440 * @constructor | 403 * @constructor |
441 */ | 404 */ |
442 function SourceLocation(script, position, line, column, start, end) { | 405 function SourceLocation(script, position, line, column, start, end) { |
443 this.script = script; | 406 this.script = script; |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
670 return this.name + ": " + FormatMessage({ type: type, args: this.arguments }
); | 633 return this.name + ": " + FormatMessage({ type: type, args: this.arguments }
); |
671 } | 634 } |
672 var message = this.message; | 635 var message = this.message; |
673 return this.name + (message ? (": " + message) : ""); | 636 return this.name + (message ? (": " + message) : ""); |
674 }, DONT_ENUM); | 637 }, DONT_ENUM); |
675 | 638 |
676 | 639 |
677 // Boilerplate for exceptions for stack overflows. Used from | 640 // Boilerplate for exceptions for stack overflows. Used from |
678 // Top::StackOverflow(). | 641 // Top::StackOverflow(). |
679 const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); | 642 const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []); |
OLD | NEW |