Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/messages.js

Issue 1398733002: Move builtin JavaScript sources into own directory. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Also move macros.py file. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/math.js ('k') | src/object-observe.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 // -------------------------------------------------------------------
6
7 var $errorToString;
8 var MakeError;
9 var MakeEvalError;
10 var MakeRangeError;
11 var MakeReferenceError;
12 var MakeSyntaxError;
13 var MakeTypeError;
14 var MakeURIError;
15
16 (function(global, utils) {
17
18 %CheckIsBootstrapping();
19
20 // -------------------------------------------------------------------
21 // Imports
22
23 var ArrayJoin;
24 var Bool16x8ToString;
25 var Bool32x4ToString;
26 var Bool8x16ToString;
27 var callSiteReceiverSymbol =
28 utils.ImportNow("call_site_receiver_symbol");
29 var callSiteFunctionSymbol =
30 utils.ImportNow("call_site_function_symbol");
31 var callSitePositionSymbol =
32 utils.ImportNow("call_site_position_symbol");
33 var callSiteStrictSymbol =
34 utils.ImportNow("call_site_strict_symbol");
35 var Float32x4ToString;
36 var formattedStackTraceSymbol =
37 utils.ImportNow("formatted_stack_trace_symbol");
38 var FunctionSourceString
39 var GlobalObject = global.Object;
40 var Int16x8ToString;
41 var Int32x4ToString;
42 var Int8x16ToString;
43 var InternalArray = utils.InternalArray;
44 var internalErrorSymbol = utils.ImportNow("internal_error_symbol");
45 var ObjectDefineProperty;
46 var ObjectToString;
47 var stackTraceSymbol = utils.ImportNow("stack_trace_symbol");
48 var StringCharAt;
49 var StringIndexOf;
50 var StringSubstring;
51 var SymbolToString;
52 var Uint16x8ToString;
53 var Uint32x4ToString;
54 var Uint8x16ToString;
55
56 utils.Import(function(from) {
57 ArrayJoin = from.ArrayJoin;
58 Bool16x8ToString = from.Bool16x8ToString;
59 Bool32x4ToString = from.Bool32x4ToString;
60 Bool8x16ToString = from.Bool8x16ToString;
61 Float32x4ToString = from.Float32x4ToString;
62 FunctionSourceString = from.FunctionSourceString;
63 Int16x8ToString = from.Int16x8ToString;
64 Int32x4ToString = from.Int32x4ToString;
65 Int8x16ToString = from.Int8x16ToString;
66 ObjectDefineProperty = from.ObjectDefineProperty;
67 ObjectToString = from.ObjectToString;
68 StringCharAt = from.StringCharAt;
69 StringIndexOf = from.StringIndexOf;
70 StringSubstring = from.StringSubstring;
71 SymbolToString = from.SymbolToString;
72 Uint16x8ToString = from.Uint16x8ToString;
73 Uint32x4ToString = from.Uint32x4ToString;
74 Uint8x16ToString = from.Uint8x16ToString;
75 });
76
77 // -------------------------------------------------------------------
78
79 var GlobalError;
80 var GlobalTypeError;
81 var GlobalRangeError;
82 var GlobalURIError;
83 var GlobalSyntaxError;
84 var GlobalReferenceError;
85 var GlobalEvalError;
86
87
88 function NoSideEffectsObjectToString() {
89 if (IS_UNDEFINED(this)) return "[object Undefined]";
90 if (IS_NULL(this)) return "[object Null]";
91 return "[object " + %_ClassOf(TO_OBJECT(this)) + "]";
92 }
93
94
95 function NoSideEffectToString(obj) {
96 if (IS_STRING(obj)) return obj;
97 if (IS_NUMBER(obj)) return %_NumberToString(obj);
98 if (IS_BOOLEAN(obj)) return obj ? 'true' : 'false';
99 if (IS_UNDEFINED(obj)) return 'undefined';
100 if (IS_NULL(obj)) return 'null';
101 if (IS_FUNCTION(obj)) {
102 var str = %_CallFunction(obj, obj, FunctionSourceString);
103 if (str.length > 128) {
104 str = %_SubString(str, 0, 111) + "...<omitted>..." +
105 %_SubString(str, str.length - 2, str.length);
106 }
107 return str;
108 }
109 if (IS_SYMBOL(obj)) return %_CallFunction(obj, SymbolToString);
110 if (IS_SIMD_VALUE(obj)) {
111 switch (typeof(obj)) {
112 case 'float32x4': return %_CallFunction(obj, Float32x4ToString);
113 case 'int32x4': return %_CallFunction(obj, Int32x4ToString);
114 case 'int16x8': return %_CallFunction(obj, Int16x8ToString);
115 case 'int8x16': return %_CallFunction(obj, Int8x16ToString);
116 case 'uint32x4': return %_CallFunction(obj, Uint32x4ToString);
117 case 'uint16x8': return %_CallFunction(obj, Uint16x8ToString);
118 case 'uint8x16': return %_CallFunction(obj, Uint8x16ToString);
119 case 'bool32x4': return %_CallFunction(obj, Bool32x4ToString);
120 case 'bool16x8': return %_CallFunction(obj, Bool16x8ToString);
121 case 'bool8x16': return %_CallFunction(obj, Bool8x16ToString);
122 }
123 }
124 if (IS_OBJECT(obj)
125 && %GetDataProperty(obj, "toString") === ObjectToString) {
126 var constructor = %GetDataProperty(obj, "constructor");
127 if (typeof constructor == "function") {
128 var constructorName = constructor.name;
129 if (IS_STRING(constructorName) && constructorName !== "") {
130 return "#<" + constructorName + ">";
131 }
132 }
133 }
134 if (CanBeSafelyTreatedAsAnErrorObject(obj)) {
135 return %_CallFunction(obj, ErrorToString);
136 }
137
138 return %_CallFunction(obj, NoSideEffectsObjectToString);
139 }
140
141 // To determine whether we can safely stringify an object using ErrorToString
142 // without the risk of side-effects, we need to check whether the object is
143 // either an instance of a native error type (via '%_ClassOf'), or has Error
144 // in its prototype chain and hasn't overwritten 'toString' with something
145 // strange and unusual.
146 function CanBeSafelyTreatedAsAnErrorObject(obj) {
147 switch (%_ClassOf(obj)) {
148 case 'Error':
149 case 'EvalError':
150 case 'RangeError':
151 case 'ReferenceError':
152 case 'SyntaxError':
153 case 'TypeError':
154 case 'URIError':
155 return true;
156 }
157
158 var objToString = %GetDataProperty(obj, "toString");
159 return obj instanceof GlobalError && objToString === ErrorToString;
160 }
161
162
163 // When formatting internally created error messages, do not
164 // invoke overwritten error toString methods but explicitly use
165 // the error to string method. This is to avoid leaking error
166 // objects between script tags in a browser setting.
167 function ToStringCheckErrorObject(obj) {
168 if (CanBeSafelyTreatedAsAnErrorObject(obj)) {
169 return %_CallFunction(obj, ErrorToString);
170 } else {
171 return TO_STRING(obj);
172 }
173 }
174
175
176 function ToDetailString(obj) {
177 if (obj != null && IS_OBJECT(obj) && obj.toString === ObjectToString) {
178 var constructor = obj.constructor;
179 if (typeof constructor == "function") {
180 var constructorName = constructor.name;
181 if (IS_STRING(constructorName) && constructorName !== "") {
182 return "#<" + constructorName + ">";
183 }
184 }
185 }
186 return ToStringCheckErrorObject(obj);
187 }
188
189
190 function MakeGenericError(constructor, type, arg0, arg1, arg2) {
191 var error = new constructor(FormatMessage(type, arg0, arg1, arg2));
192 error[internalErrorSymbol] = true;
193 return error;
194 }
195
196
197 /**
198 * Set up the Script function and constructor.
199 */
200 %FunctionSetInstanceClassName(Script, 'Script');
201 %AddNamedProperty(Script.prototype, 'constructor', Script,
202 DONT_ENUM | DONT_DELETE | READ_ONLY);
203 %SetCode(Script, function(x) {
204 // Script objects can only be created by the VM.
205 throw MakeError(kUnsupported);
206 });
207
208
209 // Helper functions; called from the runtime system.
210 function FormatMessage(type, arg0, arg1, arg2) {
211 var arg0 = NoSideEffectToString(arg0);
212 var arg1 = NoSideEffectToString(arg1);
213 var arg2 = NoSideEffectToString(arg2);
214 try {
215 return %FormatMessageString(type, arg0, arg1, arg2);
216 } catch (e) {
217 return "<error>";
218 }
219 }
220
221
222 function GetLineNumber(message) {
223 var start_position = %MessageGetStartPosition(message);
224 if (start_position == -1) return kNoLineNumberInfo;
225 var script = %MessageGetScript(message);
226 var location = script.locationFromPosition(start_position, true);
227 if (location == null) return kNoLineNumberInfo;
228 return location.line + 1;
229 }
230
231
232 //Returns the offset of the given position within the containing line.
233 function GetColumnNumber(message) {
234 var script = %MessageGetScript(message);
235 var start_position = %MessageGetStartPosition(message);
236 var location = script.locationFromPosition(start_position, true);
237 if (location == null) return -1;
238 return location.column;
239 }
240
241
242 // Returns the source code line containing the given source
243 // position, or the empty string if the position is invalid.
244 function GetSourceLine(message) {
245 var script = %MessageGetScript(message);
246 var start_position = %MessageGetStartPosition(message);
247 var location = script.locationFromPosition(start_position, true);
248 if (location == null) return "";
249 return location.sourceText();
250 }
251
252
253 /**
254 * Find a line number given a specific source position.
255 * @param {number} position The source position.
256 * @return {number} 0 if input too small, -1 if input too large,
257 else the line number.
258 */
259 function ScriptLineFromPosition(position) {
260 var lower = 0;
261 var upper = this.lineCount() - 1;
262 var line_ends = this.line_ends;
263
264 // We'll never find invalid positions so bail right away.
265 if (position > line_ends[upper]) {
266 return -1;
267 }
268
269 // This means we don't have to safe-guard indexing line_ends[i - 1].
270 if (position <= line_ends[0]) {
271 return 0;
272 }
273
274 // Binary search to find line # from position range.
275 while (upper >= 1) {
276 var i = (lower + upper) >> 1;
277
278 if (position > line_ends[i]) {
279 lower = i + 1;
280 } else if (position <= line_ends[i - 1]) {
281 upper = i - 1;
282 } else {
283 return i;
284 }
285 }
286
287 return -1;
288 }
289
290 /**
291 * Get information on a specific source position.
292 * @param {number} position The source position
293 * @param {boolean} include_resource_offset Set to true to have the resource
294 * offset added to the location
295 * @return {SourceLocation}
296 * If line is negative or not in the source null is returned.
297 */
298 function ScriptLocationFromPosition(position,
299 include_resource_offset) {
300 var line = this.lineFromPosition(position);
301 if (line == -1) return null;
302
303 // Determine start, end and column.
304 var line_ends = this.line_ends;
305 var start = line == 0 ? 0 : line_ends[line - 1] + 1;
306 var end = line_ends[line];
307 if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') {
308 end--;
309 }
310 var column = position - start;
311
312 // Adjust according to the offset within the resource.
313 if (include_resource_offset) {
314 line += this.line_offset;
315 if (line == this.line_offset) {
316 column += this.column_offset;
317 }
318 }
319
320 return new SourceLocation(this, position, line, column, start, end);
321 }
322
323
324 /**
325 * Get information on a specific source line and column possibly offset by a
326 * fixed source position. This function is used to find a source position from
327 * a line and column position. The fixed source position offset is typically
328 * used to find a source position in a function based on a line and column in
329 * the source for the function alone. The offset passed will then be the
330 * start position of the source for the function within the full script source.
331 * @param {number} opt_line The line within the source. Default value is 0
332 * @param {number} opt_column The column in within the line. Default value is 0
333 * @param {number} opt_offset_position The offset from the begining of the
334 * source from where the line and column calculation starts.
335 * Default value is 0
336 * @return {SourceLocation}
337 * If line is negative or not in the source null is returned.
338 */
339 function ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) {
340 // Default is the first line in the script. Lines in the script is relative
341 // to the offset within the resource.
342 var line = 0;
343 if (!IS_UNDEFINED(opt_line)) {
344 line = opt_line - this.line_offset;
345 }
346
347 // Default is first column. If on the first line add the offset within the
348 // resource.
349 var column = opt_column || 0;
350 if (line == 0) {
351 column -= this.column_offset;
352 }
353
354 var offset_position = opt_offset_position || 0;
355 if (line < 0 || column < 0 || offset_position < 0) return null;
356 if (line == 0) {
357 return this.locationFromPosition(offset_position + column, false);
358 } else {
359 // Find the line where the offset position is located.
360 var offset_line = this.lineFromPosition(offset_position);
361
362 if (offset_line == -1 || offset_line + line >= this.lineCount()) {
363 return null;
364 }
365
366 return this.locationFromPosition(
367 this.line_ends[offset_line + line - 1] + 1 + column); // line > 0 here.
368 }
369 }
370
371
372 /**
373 * Get a slice of source code from the script. The boundaries for the slice is
374 * specified in lines.
375 * @param {number} opt_from_line The first line (zero bound) in the slice.
376 * Default is 0
377 * @param {number} opt_to_column The last line (zero bound) in the slice (non
378 * inclusive). Default is the number of lines in the script
379 * @return {SourceSlice} The source slice or null of the parameters where
380 * invalid
381 */
382 function ScriptSourceSlice(opt_from_line, opt_to_line) {
383 var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset
384 : opt_from_line;
385 var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
386 : opt_to_line;
387
388 // Adjust according to the offset within the resource.
389 from_line -= this.line_offset;
390 to_line -= this.line_offset;
391 if (from_line < 0) from_line = 0;
392 if (to_line > this.lineCount()) to_line = this.lineCount();
393
394 // Check parameters.
395 if (from_line >= this.lineCount() ||
396 to_line < 0 ||
397 from_line > to_line) {
398 return null;
399 }
400
401 var line_ends = this.line_ends;
402 var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1;
403 var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1;
404
405 // Return a source slice with line numbers re-adjusted to the resource.
406 return new SourceSlice(this,
407 from_line + this.line_offset,
408 to_line + this.line_offset,
409 from_position, to_position);
410 }
411
412
413 function ScriptSourceLine(opt_line) {
414 // Default is the first line in the script. Lines in the script are relative
415 // to the offset within the resource.
416 var line = 0;
417 if (!IS_UNDEFINED(opt_line)) {
418 line = opt_line - this.line_offset;
419 }
420
421 // Check parameter.
422 if (line < 0 || this.lineCount() <= line) {
423 return null;
424 }
425
426 // Return the source line.
427 var line_ends = this.line_ends;
428 var start = line == 0 ? 0 : line_ends[line - 1] + 1;
429 var end = line_ends[line];
430 return %_CallFunction(this.source, start, end, StringSubstring);
431 }
432
433
434 /**
435 * Returns the number of source lines.
436 * @return {number}
437 * Number of source lines.
438 */
439 function ScriptLineCount() {
440 // Return number of source lines.
441 return this.line_ends.length;
442 }
443
444
445 /**
446 * Returns the position of the nth line end.
447 * @return {number}
448 * Zero-based position of the nth line end in the script.
449 */
450 function ScriptLineEnd(n) {
451 return this.line_ends[n];
452 }
453
454
455 /**
456 * If sourceURL comment is available returns sourceURL comment contents.
457 * Otherwise, script name is returned. See
458 * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
459 * and Source Map Revision 3 proposal for details on using //# sourceURL and
460 * deprecated //@ sourceURL comment to identify scripts that don't have name.
461 *
462 * @return {?string} script name if present, value for //# sourceURL or
463 * deprecated //@ sourceURL comment otherwise.
464 */
465 function ScriptNameOrSourceURL() {
466 if (this.source_url) return this.source_url;
467 return this.name;
468 }
469
470
471 utils.SetUpLockedPrototype(Script, [
472 "source",
473 "name",
474 "source_url",
475 "source_mapping_url",
476 "line_ends",
477 "line_offset",
478 "column_offset"
479 ], [
480 "lineFromPosition", ScriptLineFromPosition,
481 "locationFromPosition", ScriptLocationFromPosition,
482 "locationFromLine", ScriptLocationFromLine,
483 "sourceSlice", ScriptSourceSlice,
484 "sourceLine", ScriptSourceLine,
485 "lineCount", ScriptLineCount,
486 "nameOrSourceURL", ScriptNameOrSourceURL,
487 "lineEnd", ScriptLineEnd
488 ]
489 );
490
491
492 /**
493 * Class for source location. A source location is a position within some
494 * source with the following properties:
495 * script : script object for the source
496 * line : source line number
497 * column : source column within the line
498 * position : position within the source
499 * start : position of start of source context (inclusive)
500 * end : position of end of source context (not inclusive)
501 * Source text for the source context is the character interval
502 * [start, end[. In most cases end will point to a newline character.
503 * It might point just past the final position of the source if the last
504 * source line does not end with a newline character.
505 * @param {Script} script The Script object for which this is a location
506 * @param {number} position Source position for the location
507 * @param {number} line The line number for the location
508 * @param {number} column The column within the line for the location
509 * @param {number} start Source position for start of source context
510 * @param {number} end Source position for end of source context
511 * @constructor
512 */
513 function SourceLocation(script, position, line, column, start, end) {
514 this.script = script;
515 this.position = position;
516 this.line = line;
517 this.column = column;
518 this.start = start;
519 this.end = end;
520 }
521
522
523 /**
524 * Get the source text for a SourceLocation
525 * @return {String}
526 * Source text for this location.
527 */
528 function SourceLocationSourceText() {
529 return %_CallFunction(this.script.source,
530 this.start,
531 this.end,
532 StringSubstring);
533 }
534
535
536 utils.SetUpLockedPrototype(SourceLocation,
537 ["script", "position", "line", "column", "start", "end"],
538 ["sourceText", SourceLocationSourceText]
539 );
540
541
542 /**
543 * Class for a source slice. A source slice is a part of a script source with
544 * the following properties:
545 * script : script object for the source
546 * from_line : line number for the first line in the slice
547 * to_line : source line number for the last line in the slice
548 * from_position : position of the first character in the slice
549 * to_position : position of the last character in the slice
550 * The to_line and to_position are not included in the slice, that is the lines
551 * in the slice are [from_line, to_line[. Likewise the characters in the slice
552 * are [from_position, to_position[.
553 * @param {Script} script The Script object for the source slice
554 * @param {number} from_line
555 * @param {number} to_line
556 * @param {number} from_position
557 * @param {number} to_position
558 * @constructor
559 */
560 function SourceSlice(script, from_line, to_line, from_position, to_position) {
561 this.script = script;
562 this.from_line = from_line;
563 this.to_line = to_line;
564 this.from_position = from_position;
565 this.to_position = to_position;
566 }
567
568 /**
569 * Get the source text for a SourceSlice
570 * @return {String} Source text for this slice. The last line will include
571 * the line terminating characters (if any)
572 */
573 function SourceSliceSourceText() {
574 return %_CallFunction(this.script.source,
575 this.from_position,
576 this.to_position,
577 StringSubstring);
578 }
579
580 utils.SetUpLockedPrototype(SourceSlice,
581 ["script", "from_line", "to_line", "from_position", "to_position"],
582 ["sourceText", SourceSliceSourceText]
583 );
584
585
586 function GetStackTraceLine(recv, fun, pos, isGlobal) {
587 return new CallSite(recv, fun, pos, false).toString();
588 }
589
590 // ----------------------------------------------------------------------------
591 // Error implementation
592
593 function CallSite(receiver, fun, pos, strict_mode) {
594 SET_PRIVATE(this, callSiteReceiverSymbol, receiver);
595 SET_PRIVATE(this, callSiteFunctionSymbol, fun);
596 SET_PRIVATE(this, callSitePositionSymbol, pos);
597 SET_PRIVATE(this, callSiteStrictSymbol, strict_mode);
598 }
599
600 function CallSiteGetThis() {
601 return GET_PRIVATE(this, callSiteStrictSymbol)
602 ? UNDEFINED : GET_PRIVATE(this, callSiteReceiverSymbol);
603 }
604
605 function CallSiteGetFunction() {
606 return GET_PRIVATE(this, callSiteStrictSymbol)
607 ? UNDEFINED : GET_PRIVATE(this, callSiteFunctionSymbol);
608 }
609
610 function CallSiteGetPosition() {
611 return GET_PRIVATE(this, callSitePositionSymbol);
612 }
613
614 function CallSiteGetTypeName() {
615 return GetTypeName(GET_PRIVATE(this, callSiteReceiverSymbol), false);
616 }
617
618 function CallSiteIsToplevel() {
619 return %CallSiteIsToplevelRT(this);
620 }
621
622 function CallSiteIsEval() {
623 return %CallSiteIsEvalRT(this);
624 }
625
626 function CallSiteGetEvalOrigin() {
627 var script = %FunctionGetScript(GET_PRIVATE(this, callSiteFunctionSymbol));
628 return FormatEvalOrigin(script);
629 }
630
631 function CallSiteGetScriptNameOrSourceURL() {
632 return %CallSiteGetScriptNameOrSourceUrlRT(this);
633 }
634
635 function CallSiteGetFunctionName() {
636 // See if the function knows its own name
637 return %CallSiteGetFunctionNameRT(this);
638 }
639
640 function CallSiteGetMethodName() {
641 // See if we can find a unique property on the receiver that holds
642 // this function.
643 return %CallSiteGetMethodNameRT(this);
644 }
645
646 function CallSiteGetFileName() {
647 return %CallSiteGetFileNameRT(this);
648 }
649
650 function CallSiteGetLineNumber() {
651 return %CallSiteGetLineNumberRT(this);
652 }
653
654 function CallSiteGetColumnNumber() {
655 return %CallSiteGetColumnNumberRT(this);
656 }
657
658 function CallSiteIsNative() {
659 return %CallSiteIsNativeRT(this);
660 }
661
662 function CallSiteIsConstructor() {
663 return %CallSiteIsConstructorRT(this);
664 }
665
666 function CallSiteToString() {
667 var fileName;
668 var fileLocation = "";
669 if (this.isNative()) {
670 fileLocation = "native";
671 } else {
672 fileName = this.getScriptNameOrSourceURL();
673 if (!fileName && this.isEval()) {
674 fileLocation = this.getEvalOrigin();
675 fileLocation += ", "; // Expecting source position to follow.
676 }
677
678 if (fileName) {
679 fileLocation += fileName;
680 } else {
681 // Source code does not originate from a file and is not native, but we
682 // can still get the source position inside the source string, e.g. in
683 // an eval string.
684 fileLocation += "<anonymous>";
685 }
686 var lineNumber = this.getLineNumber();
687 if (lineNumber != null) {
688 fileLocation += ":" + lineNumber;
689 var columnNumber = this.getColumnNumber();
690 if (columnNumber) {
691 fileLocation += ":" + columnNumber;
692 }
693 }
694 }
695
696 var line = "";
697 var functionName = this.getFunctionName();
698 var addSuffix = true;
699 var isConstructor = this.isConstructor();
700 var isMethodCall = !(this.isToplevel() || isConstructor);
701 if (isMethodCall) {
702 var typeName = GetTypeName(GET_PRIVATE(this, callSiteReceiverSymbol), true);
703 var methodName = this.getMethodName();
704 if (functionName) {
705 if (typeName &&
706 %_CallFunction(functionName, typeName, StringIndexOf) != 0) {
707 line += typeName + ".";
708 }
709 line += functionName;
710 if (methodName &&
711 (%_CallFunction(functionName, "." + methodName, StringIndexOf) !=
712 functionName.length - methodName.length - 1)) {
713 line += " [as " + methodName + "]";
714 }
715 } else {
716 line += typeName + "." + (methodName || "<anonymous>");
717 }
718 } else if (isConstructor) {
719 line += "new " + (functionName || "<anonymous>");
720 } else if (functionName) {
721 line += functionName;
722 } else {
723 line += fileLocation;
724 addSuffix = false;
725 }
726 if (addSuffix) {
727 line += " (" + fileLocation + ")";
728 }
729 return line;
730 }
731
732 utils.SetUpLockedPrototype(CallSite, ["receiver", "fun", "pos"], [
733 "getThis", CallSiteGetThis,
734 "getTypeName", CallSiteGetTypeName,
735 "isToplevel", CallSiteIsToplevel,
736 "isEval", CallSiteIsEval,
737 "getEvalOrigin", CallSiteGetEvalOrigin,
738 "getScriptNameOrSourceURL", CallSiteGetScriptNameOrSourceURL,
739 "getFunction", CallSiteGetFunction,
740 "getFunctionName", CallSiteGetFunctionName,
741 "getMethodName", CallSiteGetMethodName,
742 "getFileName", CallSiteGetFileName,
743 "getLineNumber", CallSiteGetLineNumber,
744 "getColumnNumber", CallSiteGetColumnNumber,
745 "isNative", CallSiteIsNative,
746 "getPosition", CallSiteGetPosition,
747 "isConstructor", CallSiteIsConstructor,
748 "toString", CallSiteToString
749 ]);
750
751
752 function FormatEvalOrigin(script) {
753 var sourceURL = script.nameOrSourceURL();
754 if (sourceURL) {
755 return sourceURL;
756 }
757
758 var eval_origin = "eval at ";
759 if (script.eval_from_function_name) {
760 eval_origin += script.eval_from_function_name;
761 } else {
762 eval_origin += "<anonymous>";
763 }
764
765 var eval_from_script = script.eval_from_script;
766 if (eval_from_script) {
767 if (eval_from_script.compilation_type == COMPILATION_TYPE_EVAL) {
768 // eval script originated from another eval.
769 eval_origin += " (" + FormatEvalOrigin(eval_from_script) + ")";
770 } else {
771 // eval script originated from "real" source.
772 if (eval_from_script.name) {
773 eval_origin += " (" + eval_from_script.name;
774 var location = eval_from_script.locationFromPosition(
775 script.eval_from_script_position, true);
776 if (location) {
777 eval_origin += ":" + (location.line + 1);
778 eval_origin += ":" + (location.column + 1);
779 }
780 eval_origin += ")";
781 } else {
782 eval_origin += " (unknown source)";
783 }
784 }
785 }
786
787 return eval_origin;
788 }
789
790
791 function FormatErrorString(error) {
792 try {
793 return %_CallFunction(error, ErrorToString);
794 } catch (e) {
795 try {
796 return "<error: " + e + ">";
797 } catch (ee) {
798 return "<error>";
799 }
800 }
801 }
802
803
804 function GetStackFrames(raw_stack) {
805 var frames = new InternalArray();
806 var sloppy_frames = raw_stack[0];
807 for (var i = 1; i < raw_stack.length; i += 4) {
808 var recv = raw_stack[i];
809 var fun = raw_stack[i + 1];
810 var code = raw_stack[i + 2];
811 var pc = raw_stack[i + 3];
812 var pos = %_IsSmi(code) ? code : %FunctionGetPositionForOffset(code, pc);
813 sloppy_frames--;
814 frames.push(new CallSite(recv, fun, pos, (sloppy_frames < 0)));
815 }
816 return frames;
817 }
818
819
820 // Flag to prevent recursive call of Error.prepareStackTrace.
821 var formatting_custom_stack_trace = false;
822
823
824 function FormatStackTrace(obj, raw_stack) {
825 var frames = GetStackFrames(raw_stack);
826 if (IS_FUNCTION(GlobalError.prepareStackTrace) &&
827 !formatting_custom_stack_trace) {
828 var array = [];
829 %MoveArrayContents(frames, array);
830 formatting_custom_stack_trace = true;
831 var stack_trace = UNDEFINED;
832 try {
833 stack_trace = GlobalError.prepareStackTrace(obj, array);
834 } catch (e) {
835 throw e; // The custom formatting function threw. Rethrow.
836 } finally {
837 formatting_custom_stack_trace = false;
838 }
839 return stack_trace;
840 }
841
842 var lines = new InternalArray();
843 lines.push(FormatErrorString(obj));
844 for (var i = 0; i < frames.length; i++) {
845 var frame = frames[i];
846 var line;
847 try {
848 line = frame.toString();
849 } catch (e) {
850 try {
851 line = "<error: " + e + ">";
852 } catch (ee) {
853 // Any code that reaches this point is seriously nasty!
854 line = "<error>";
855 }
856 }
857 lines.push(" at " + line);
858 }
859 return %_CallFunction(lines, "\n", ArrayJoin);
860 }
861
862
863 function GetTypeName(receiver, requireConstructor) {
864 if (IS_NULL_OR_UNDEFINED(receiver)) return null;
865 var constructor = receiver.constructor;
866 if (!constructor) {
867 return requireConstructor ? null :
868 %_CallFunction(receiver, NoSideEffectsObjectToString);
869 }
870 var constructorName = constructor.name;
871 if (!constructorName) {
872 return requireConstructor ? null :
873 %_CallFunction(receiver, NoSideEffectsObjectToString);
874 }
875 return constructorName;
876 }
877
878
879 // Format the stack trace if not yet done, and return it.
880 // Cache the formatted stack trace on the holder.
881 var StackTraceGetter = function() {
882 var formatted_stack_trace = UNDEFINED;
883 var holder = this;
884 while (holder) {
885 var formatted_stack_trace =
886 GET_PRIVATE(holder, formattedStackTraceSymbol);
887 if (IS_UNDEFINED(formatted_stack_trace)) {
888 // No formatted stack trace available.
889 var stack_trace = GET_PRIVATE(holder, stackTraceSymbol);
890 if (IS_UNDEFINED(stack_trace)) {
891 // Neither formatted nor structured stack trace available.
892 // Look further up the prototype chain.
893 holder = %_GetPrototype(holder);
894 continue;
895 }
896 formatted_stack_trace = FormatStackTrace(holder, stack_trace);
897 SET_PRIVATE(holder, stackTraceSymbol, UNDEFINED);
898 SET_PRIVATE(holder, formattedStackTraceSymbol, formatted_stack_trace);
899 }
900 return formatted_stack_trace;
901 }
902 return UNDEFINED;
903 };
904
905
906 // If the receiver equals the holder, set the formatted stack trace that the
907 // getter returns.
908 var StackTraceSetter = function(v) {
909 if (HAS_PRIVATE(this, stackTraceSymbol)) {
910 SET_PRIVATE(this, stackTraceSymbol, UNDEFINED);
911 SET_PRIVATE(this, formattedStackTraceSymbol, v);
912 }
913 };
914
915
916 // Use a dummy function since we do not actually want to capture a stack trace
917 // when constructing the initial Error prototytpes.
918 var captureStackTrace = function() {};
919
920
921 // Define special error type constructors.
922 function DefineError(global, f) {
923 // Store the error function in both the global object
924 // and the runtime object. The function is fetched
925 // from the runtime object when throwing errors from
926 // within the runtime system to avoid strange side
927 // effects when overwriting the error functions from
928 // user code.
929 var name = f.name;
930 %AddNamedProperty(global, name, f, DONT_ENUM);
931 // Configure the error function.
932 if (name == 'Error') {
933 // The prototype of the Error object must itself be an error.
934 // However, it can't be an instance of the Error object because
935 // it hasn't been properly configured yet. Instead we create a
936 // special not-a-true-error-but-close-enough object.
937 var ErrorPrototype = function() {};
938 %FunctionSetPrototype(ErrorPrototype, GlobalObject.prototype);
939 %FunctionSetInstanceClassName(ErrorPrototype, 'Error');
940 %FunctionSetPrototype(f, new ErrorPrototype());
941 } else {
942 %FunctionSetPrototype(f, new GlobalError());
943 %InternalSetPrototype(f, GlobalError);
944 }
945 %FunctionSetInstanceClassName(f, 'Error');
946 %AddNamedProperty(f.prototype, 'constructor', f, DONT_ENUM);
947 %AddNamedProperty(f.prototype, 'name', name, DONT_ENUM);
948 %SetCode(f, function(m) {
949 if (%_IsConstructCall()) {
950 try { captureStackTrace(this, f); } catch (e) { }
951 // Define all the expected properties directly on the error
952 // object. This avoids going through getters and setters defined
953 // on prototype objects.
954 if (!IS_UNDEFINED(m)) {
955 %AddNamedProperty(this, 'message', TO_STRING(m), DONT_ENUM);
956 }
957 } else {
958 return new f(m);
959 }
960 });
961 %SetNativeFlag(f);
962 return f;
963 };
964
965 GlobalError = DefineError(global, function Error() { });
966 GlobalEvalError = DefineError(global, function EvalError() { });
967 GlobalRangeError = DefineError(global, function RangeError() { });
968 GlobalReferenceError = DefineError(global, function ReferenceError() { });
969 GlobalSyntaxError = DefineError(global, function SyntaxError() { });
970 GlobalTypeError = DefineError(global, function TypeError() { });
971 GlobalURIError = DefineError(global, function URIError() { });
972
973 %AddNamedProperty(GlobalError.prototype, 'message', '', DONT_ENUM);
974
975 function ErrorToString() {
976 if (!IS_SPEC_OBJECT(this)) {
977 throw MakeTypeError(kCalledOnNonObject, "Error.prototype.toString");
978 }
979
980 return %ErrorToStringRT(this);
981 }
982
983 utils.InstallFunctions(GlobalError.prototype, DONT_ENUM,
984 ['toString', ErrorToString]);
985
986 $errorToString = ErrorToString;
987
988 MakeError = function(type, arg0, arg1, arg2) {
989 return MakeGenericError(GlobalError, type, arg0, arg1, arg2);
990 }
991
992 MakeRangeError = function(type, arg0, arg1, arg2) {
993 return MakeGenericError(GlobalRangeError, type, arg0, arg1, arg2);
994 }
995
996 MakeSyntaxError = function(type, arg0, arg1, arg2) {
997 return MakeGenericError(GlobalSyntaxError, type, arg0, arg1, arg2);
998 }
999
1000 MakeTypeError = function(type, arg0, arg1, arg2) {
1001 return MakeGenericError(GlobalTypeError, type, arg0, arg1, arg2);
1002 }
1003
1004 MakeURIError = function() {
1005 return MakeGenericError(GlobalURIError, kURIMalformed);
1006 }
1007
1008 // Boilerplate for exceptions for stack overflows. Used from
1009 // Isolate::StackOverflow().
1010 var StackOverflowBoilerplate = MakeRangeError(kStackOverflow);
1011 %DefineAccessorPropertyUnchecked(StackOverflowBoilerplate, 'stack',
1012 StackTraceGetter, StackTraceSetter,
1013 DONT_ENUM);
1014
1015 // Define actual captureStackTrace function after everything has been set up.
1016 captureStackTrace = function captureStackTrace(obj, cons_opt) {
1017 // Define accessors first, as this may fail and throw.
1018 ObjectDefineProperty(obj, 'stack', { get: StackTraceGetter,
1019 set: StackTraceSetter,
1020 configurable: true });
1021 %CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace);
1022 };
1023
1024 GlobalError.captureStackTrace = captureStackTrace;
1025
1026 %InstallToContext([
1027 "error_function", GlobalError,
1028 "eval_error_function", GlobalEvalError,
1029 "get_stack_trace_line_fun", GetStackTraceLine,
1030 "make_error_function", MakeGenericError,
1031 "make_range_error", MakeRangeError,
1032 "make_type_error", MakeTypeError,
1033 "message_get_column_number", GetColumnNumber,
1034 "message_get_line_number", GetLineNumber,
1035 "message_get_source_line", GetSourceLine,
1036 "no_side_effect_to_string_fun", NoSideEffectToString,
1037 "range_error_function", GlobalRangeError,
1038 "reference_error_function", GlobalReferenceError,
1039 "stack_overflow_boilerplate", StackOverflowBoilerplate,
1040 "syntax_error_function", GlobalSyntaxError,
1041 "to_detail_string_fun", ToDetailString,
1042 "type_error_function", GlobalTypeError,
1043 "uri_error_function", GlobalURIError,
1044 ]);
1045
1046 });
OLDNEW
« no previous file with comments | « src/math.js ('k') | src/object-observe.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698