• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(function(global, utils) {
8
9%CheckIsBootstrapping();
10
11// -------------------------------------------------------------------
12// Imports
13
14var ArrayJoin;
15var Bool16x8ToString;
16var Bool32x4ToString;
17var Bool8x16ToString;
18var callSiteReceiverSymbol =
19    utils.ImportNow("call_site_receiver_symbol");
20var callSiteFunctionSymbol =
21    utils.ImportNow("call_site_function_symbol");
22var callSitePositionSymbol =
23    utils.ImportNow("call_site_position_symbol");
24var callSiteStrictSymbol =
25    utils.ImportNow("call_site_strict_symbol");
26var callSiteWasmObjectSymbol =
27    utils.ImportNow("call_site_wasm_obj_symbol");
28var callSiteWasmFunctionIndexSymbol =
29    utils.ImportNow("call_site_wasm_func_index_symbol");
30var Float32x4ToString;
31var formattedStackTraceSymbol =
32    utils.ImportNow("formatted_stack_trace_symbol");
33var GlobalObject = global.Object;
34var Int16x8ToString;
35var Int32x4ToString;
36var Int8x16ToString;
37var InternalArray = utils.InternalArray;
38var internalErrorSymbol = utils.ImportNow("internal_error_symbol");
39var ObjectHasOwnProperty;
40var ObjectToString = utils.ImportNow("object_to_string");
41var Script = utils.ImportNow("Script");
42var stackTraceSymbol = utils.ImportNow("stack_trace_symbol");
43var StringIndexOf;
44var SymbolToString;
45var toStringTagSymbol = utils.ImportNow("to_string_tag_symbol");
46var Uint16x8ToString;
47var Uint32x4ToString;
48var Uint8x16ToString;
49
50utils.Import(function(from) {
51  ArrayJoin = from.ArrayJoin;
52  Bool16x8ToString = from.Bool16x8ToString;
53  Bool32x4ToString = from.Bool32x4ToString;
54  Bool8x16ToString = from.Bool8x16ToString;
55  Float32x4ToString = from.Float32x4ToString;
56  Int16x8ToString = from.Int16x8ToString;
57  Int32x4ToString = from.Int32x4ToString;
58  Int8x16ToString = from.Int8x16ToString;
59  ObjectHasOwnProperty = from.ObjectHasOwnProperty;
60  StringIndexOf = from.StringIndexOf;
61  SymbolToString = from.SymbolToString;
62  Uint16x8ToString = from.Uint16x8ToString;
63  Uint32x4ToString = from.Uint32x4ToString;
64  Uint8x16ToString = from.Uint8x16ToString;
65});
66
67// -------------------------------------------------------------------
68
69var GlobalError;
70var GlobalTypeError;
71var GlobalRangeError;
72var GlobalURIError;
73var GlobalSyntaxError;
74var GlobalReferenceError;
75var GlobalEvalError;
76
77
78function NoSideEffectsObjectToString() {
79  if (IS_UNDEFINED(this)) return "[object Undefined]";
80  if (IS_NULL(this)) return "[object Null]";
81  var O = TO_OBJECT(this);
82  var builtinTag = %_ClassOf(O);
83  var tag = %GetDataProperty(O, toStringTagSymbol);
84  if (!IS_STRING(tag)) {
85    tag = builtinTag;
86  }
87  return `[object ${tag}]`;
88}
89
90function IsErrorObject(obj) {
91  return HAS_PRIVATE(obj, stackTraceSymbol);
92}
93
94function NoSideEffectsErrorToString() {
95  var name = %GetDataProperty(this, "name");
96  var message = %GetDataProperty(this, "message");
97  name = IS_UNDEFINED(name) ? "Error" : NoSideEffectsToString(name);
98  message = IS_UNDEFINED(message) ? "" : NoSideEffectsToString(message);
99  if (name == "") return message;
100  if (message == "") return name;
101  return `${name}: ${message}`;
102}
103
104function NoSideEffectsToString(obj) {
105  if (IS_STRING(obj)) return obj;
106  if (IS_NUMBER(obj)) return %_NumberToString(obj);
107  if (IS_BOOLEAN(obj)) return obj ? 'true' : 'false';
108  if (IS_UNDEFINED(obj)) return 'undefined';
109  if (IS_NULL(obj)) return 'null';
110  if (IS_FUNCTION(obj)) {
111    var str = %FunctionToString(obj);
112    if (str.length > 128) {
113      str = %_SubString(str, 0, 111) + "...<omitted>..." +
114            %_SubString(str, str.length - 2, str.length);
115    }
116    return str;
117  }
118  if (IS_SYMBOL(obj)) return %_Call(SymbolToString, obj);
119  if (IS_SIMD_VALUE(obj)) {
120    switch (typeof(obj)) {
121      case 'float32x4': return %_Call(Float32x4ToString, obj);
122      case 'int32x4':   return %_Call(Int32x4ToString, obj);
123      case 'int16x8':   return %_Call(Int16x8ToString, obj);
124      case 'int8x16':   return %_Call(Int8x16ToString, obj);
125      case 'uint32x4':   return %_Call(Uint32x4ToString, obj);
126      case 'uint16x8':   return %_Call(Uint16x8ToString, obj);
127      case 'uint8x16':   return %_Call(Uint8x16ToString, obj);
128      case 'bool32x4':  return %_Call(Bool32x4ToString, obj);
129      case 'bool16x8':  return %_Call(Bool16x8ToString, obj);
130      case 'bool8x16':  return %_Call(Bool8x16ToString, obj);
131    }
132  }
133
134  if (IS_RECEIVER(obj)) {
135    // When internally formatting error objects, use a side-effects-free version
136    // of Error.prototype.toString independent of the actually installed
137    // toString method.
138    if (IsErrorObject(obj) ||
139        %GetDataProperty(obj, "toString") === ErrorToString) {
140      return %_Call(NoSideEffectsErrorToString, obj);
141    }
142
143    if (%GetDataProperty(obj, "toString") === ObjectToString) {
144      var constructor = %GetDataProperty(obj, "constructor");
145      if (IS_FUNCTION(constructor)) {
146        var constructor_name = %FunctionGetName(constructor);
147        if (constructor_name != "") return `#<${constructor_name}>`;
148      }
149    }
150  }
151
152  return %_Call(NoSideEffectsObjectToString, obj);
153}
154
155
156function MakeGenericError(constructor, type, arg0, arg1, arg2) {
157  var error = new constructor(FormatMessage(type, arg0, arg1, arg2));
158  error[internalErrorSymbol] = true;
159  return error;
160}
161
162
163/**
164 * Set up the Script function and constructor.
165 */
166%FunctionSetInstanceClassName(Script, 'Script');
167%AddNamedProperty(Script.prototype, 'constructor', Script,
168                  DONT_ENUM | DONT_DELETE | READ_ONLY);
169%SetCode(Script, function(x) {
170  // Script objects can only be created by the VM.
171  throw MakeError(kUnsupported);
172});
173
174
175// Helper functions; called from the runtime system.
176function FormatMessage(type, arg0, arg1, arg2) {
177  var arg0 = NoSideEffectsToString(arg0);
178  var arg1 = NoSideEffectsToString(arg1);
179  var arg2 = NoSideEffectsToString(arg2);
180  try {
181    return %FormatMessageString(type, arg0, arg1, arg2);
182  } catch (e) {
183    return "<error>";
184  }
185}
186
187
188function GetLineNumber(message) {
189  var start_position = %MessageGetStartPosition(message);
190  if (start_position == -1) return kNoLineNumberInfo;
191  var script = %MessageGetScript(message);
192  var location = script.locationFromPosition(start_position, true);
193  if (location == null) return kNoLineNumberInfo;
194  return location.line + 1;
195}
196
197
198//Returns the offset of the given position within the containing line.
199function GetColumnNumber(message) {
200  var script = %MessageGetScript(message);
201  var start_position = %MessageGetStartPosition(message);
202  var location = script.locationFromPosition(start_position, true);
203  if (location == null) return -1;
204  return location.column;
205}
206
207
208// Returns the source code line containing the given source
209// position, or the empty string if the position is invalid.
210function GetSourceLine(message) {
211  var script = %MessageGetScript(message);
212  var start_position = %MessageGetStartPosition(message);
213  var location = script.locationFromPosition(start_position, true);
214  if (location == null) return "";
215  return location.sourceText;
216}
217
218
219/**
220 * Get information on a specific source position.
221 * Returns an object with the following following properties:
222 *   script     : script object for the source
223 *   line       : source line number
224 *   column     : source column within the line
225 *   position   : position within the source
226 *   sourceText : a string containing the current line
227 * @param {number} position The source position
228 * @param {boolean} include_resource_offset Set to true to have the resource
229 *     offset added to the location
230 * @return If line is negative or not in the source null is returned.
231 */
232function ScriptLocationFromPosition(position,
233                                    include_resource_offset) {
234  return %ScriptPositionInfo(this, position, !!include_resource_offset);
235}
236
237
238/**
239 * If sourceURL comment is available returns sourceURL comment contents.
240 * Otherwise, script name is returned. See
241 * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
242 * and Source Map Revision 3 proposal for details on using //# sourceURL and
243 * deprecated //@ sourceURL comment to identify scripts that don't have name.
244 *
245 * @return {?string} script name if present, value for //# sourceURL comment or
246 * deprecated //@ sourceURL comment otherwise.
247 */
248function ScriptNameOrSourceURL() {
249  if (this.source_url) return this.source_url;
250  return this.name;
251}
252
253
254utils.SetUpLockedPrototype(Script, [
255    "source",
256    "name",
257    "source_url",
258    "source_mapping_url",
259    "line_offset",
260    "column_offset"
261  ], [
262    "locationFromPosition", ScriptLocationFromPosition,
263    "nameOrSourceURL", ScriptNameOrSourceURL,
264  ]
265);
266
267
268function GetStackTraceLine(recv, fun, pos, isGlobal) {
269  return new CallSite(recv, fun, pos, false).toString();
270}
271
272// ----------------------------------------------------------------------------
273// Error implementation
274
275function CallSite(receiver, fun, pos, strict_mode) {
276  // For wasm frames, receiver is the wasm object and fun is the function index
277  // instead of an actual function.
278  if (!IS_FUNCTION(fun) && !%IsWasmObject(receiver)) {
279    throw MakeTypeError(kCallSiteExpectsFunction, typeof receiver, typeof fun);
280  }
281
282  if (IS_UNDEFINED(new.target)) {
283    return new CallSite(receiver, fun, pos, strict_mode);
284  }
285
286  if (IS_FUNCTION(fun)) {
287    SET_PRIVATE(this, callSiteReceiverSymbol, receiver);
288    SET_PRIVATE(this, callSiteFunctionSymbol, fun);
289  } else {
290    SET_PRIVATE(this, callSiteWasmObjectSymbol, receiver);
291    SET_PRIVATE(this, callSiteWasmFunctionIndexSymbol, TO_UINT32(fun));
292  }
293  SET_PRIVATE(this, callSitePositionSymbol, TO_INT32(pos));
294  SET_PRIVATE(this, callSiteStrictSymbol, TO_BOOLEAN(strict_mode));
295}
296
297function CheckCallSite(obj, name) {
298  if (!IS_RECEIVER(obj) || !HAS_PRIVATE(obj, callSitePositionSymbol)) {
299    throw MakeTypeError(kCallSiteMethod, name);
300  }
301}
302
303function CallSiteGetThis() {
304  CheckCallSite(this, "getThis");
305  return GET_PRIVATE(this, callSiteStrictSymbol)
306      ? UNDEFINED : GET_PRIVATE(this, callSiteReceiverSymbol);
307}
308
309function CallSiteGetFunction() {
310  CheckCallSite(this, "getFunction");
311  return GET_PRIVATE(this, callSiteStrictSymbol)
312      ? UNDEFINED : GET_PRIVATE(this, callSiteFunctionSymbol);
313}
314
315function CallSiteGetPosition() {
316  CheckCallSite(this, "getPosition");
317  return GET_PRIVATE(this, callSitePositionSymbol);
318}
319
320function CallSiteGetTypeName() {
321  CheckCallSite(this, "getTypeName");
322  return GetTypeName(GET_PRIVATE(this, callSiteReceiverSymbol), false);
323}
324
325function CallSiteIsToplevel() {
326  CheckCallSite(this, "isTopLevel");
327  return %CallSiteIsToplevelRT(this);
328}
329
330function CallSiteIsEval() {
331  CheckCallSite(this, "isEval");
332  return %CallSiteIsEvalRT(this);
333}
334
335function CallSiteGetEvalOrigin() {
336  CheckCallSite(this, "getEvalOrigin");
337  var script = %FunctionGetScript(GET_PRIVATE(this, callSiteFunctionSymbol));
338  return FormatEvalOrigin(script);
339}
340
341function CallSiteGetScriptNameOrSourceURL() {
342  CheckCallSite(this, "getScriptNameOrSourceURL");
343  return %CallSiteGetScriptNameOrSourceUrlRT(this);
344}
345
346function CallSiteGetFunctionName() {
347  // See if the function knows its own name
348  CheckCallSite(this, "getFunctionName");
349  return %CallSiteGetFunctionNameRT(this);
350}
351
352function CallSiteGetMethodName() {
353  // See if we can find a unique property on the receiver that holds
354  // this function.
355  CheckCallSite(this, "getMethodName");
356  return %CallSiteGetMethodNameRT(this);
357}
358
359function CallSiteGetFileName() {
360  CheckCallSite(this, "getFileName");
361  return %CallSiteGetFileNameRT(this);
362}
363
364function CallSiteGetLineNumber() {
365  if (HAS_PRIVATE(this, callSiteWasmObjectSymbol)) {
366    return GET_PRIVATE(this, callSiteWasmFunctionIndexSymbol);
367  }
368  CheckCallSite(this, "getLineNumber");
369  return %CallSiteGetLineNumberRT(this);
370}
371
372function CallSiteGetColumnNumber() {
373  CheckCallSite(this, "getColumnNumber");
374  return %CallSiteGetColumnNumberRT(this);
375}
376
377function CallSiteIsNative() {
378  CheckCallSite(this, "isNative");
379  return %CallSiteIsNativeRT(this);
380}
381
382function CallSiteIsConstructor() {
383  CheckCallSite(this, "isConstructor");
384  return %CallSiteIsConstructorRT(this);
385}
386
387function CallSiteToString() {
388  if (HAS_PRIVATE(this, callSiteWasmObjectSymbol)) {
389    var funName = this.getFunctionName();
390    var funcIndex = GET_PRIVATE(this, callSiteWasmFunctionIndexSymbol);
391    var pos = this.getPosition();
392    if (IS_NULL(funName)) funName = "<WASM UNNAMED>";
393    return funName + " (<WASM>[" + funcIndex + "]+" + pos + ")";
394  }
395
396  var fileName;
397  var fileLocation = "";
398  if (this.isNative()) {
399    fileLocation = "native";
400  } else {
401    fileName = this.getScriptNameOrSourceURL();
402    if (!fileName && this.isEval()) {
403      fileLocation = this.getEvalOrigin();
404      fileLocation += ", ";  // Expecting source position to follow.
405    }
406
407    if (fileName) {
408      fileLocation += fileName;
409    } else {
410      // Source code does not originate from a file and is not native, but we
411      // can still get the source position inside the source string, e.g. in
412      // an eval string.
413      fileLocation += "<anonymous>";
414    }
415    var lineNumber = this.getLineNumber();
416    if (lineNumber != null) {
417      fileLocation += ":" + lineNumber;
418      var columnNumber = this.getColumnNumber();
419      if (columnNumber) {
420        fileLocation += ":" + columnNumber;
421      }
422    }
423  }
424
425  var line = "";
426  var functionName = this.getFunctionName();
427  var addSuffix = true;
428  var isConstructor = this.isConstructor();
429  var isMethodCall = !(this.isToplevel() || isConstructor);
430  if (isMethodCall) {
431    var typeName = GetTypeName(GET_PRIVATE(this, callSiteReceiverSymbol), true);
432    var methodName = this.getMethodName();
433    if (functionName) {
434      if (typeName && %_Call(StringIndexOf, functionName, typeName) != 0) {
435        line += typeName + ".";
436      }
437      line += functionName;
438      if (methodName &&
439          (%_Call(StringIndexOf, functionName, "." + methodName) !=
440           functionName.length - methodName.length - 1)) {
441        line += " [as " + methodName + "]";
442      }
443    } else {
444      line += typeName + "." + (methodName || "<anonymous>");
445    }
446  } else if (isConstructor) {
447    line += "new " + (functionName || "<anonymous>");
448  } else if (functionName) {
449    line += functionName;
450  } else {
451    line += fileLocation;
452    addSuffix = false;
453  }
454  if (addSuffix) {
455    line += " (" + fileLocation + ")";
456  }
457  return line;
458}
459
460utils.SetUpLockedPrototype(CallSite, ["receiver", "fun", "pos"], [
461  "getThis", CallSiteGetThis,
462  "getTypeName", CallSiteGetTypeName,
463  "isToplevel", CallSiteIsToplevel,
464  "isEval", CallSiteIsEval,
465  "getEvalOrigin", CallSiteGetEvalOrigin,
466  "getScriptNameOrSourceURL", CallSiteGetScriptNameOrSourceURL,
467  "getFunction", CallSiteGetFunction,
468  "getFunctionName", CallSiteGetFunctionName,
469  "getMethodName", CallSiteGetMethodName,
470  "getFileName", CallSiteGetFileName,
471  "getLineNumber", CallSiteGetLineNumber,
472  "getColumnNumber", CallSiteGetColumnNumber,
473  "isNative", CallSiteIsNative,
474  "getPosition", CallSiteGetPosition,
475  "isConstructor", CallSiteIsConstructor,
476  "toString", CallSiteToString
477]);
478
479
480function FormatEvalOrigin(script) {
481  var sourceURL = script.nameOrSourceURL();
482  if (sourceURL) {
483    return sourceURL;
484  }
485
486  var eval_origin = "eval at ";
487  if (script.eval_from_function_name) {
488    eval_origin += script.eval_from_function_name;
489  } else {
490    eval_origin +=  "<anonymous>";
491  }
492
493  var eval_from_script = script.eval_from_script;
494  if (eval_from_script) {
495    if (eval_from_script.compilation_type == COMPILATION_TYPE_EVAL) {
496      // eval script originated from another eval.
497      eval_origin += " (" + FormatEvalOrigin(eval_from_script) + ")";
498    } else {
499      // eval script originated from "real" source.
500      if (eval_from_script.name) {
501        eval_origin += " (" + eval_from_script.name;
502        var location = eval_from_script.locationFromPosition(
503            script.eval_from_script_position, true);
504        if (location) {
505          eval_origin += ":" + (location.line + 1);
506          eval_origin += ":" + (location.column + 1);
507        }
508        eval_origin += ")";
509      } else {
510        eval_origin += " (unknown source)";
511      }
512    }
513  }
514
515  return eval_origin;
516}
517
518
519function FormatErrorString(error) {
520  try {
521    return %_Call(ErrorToString, error);
522  } catch (e) {
523    try {
524      return "<error: " + e + ">";
525    } catch (ee) {
526      return "<error>";
527    }
528  }
529}
530
531
532function GetStackFrames(raw_stack) {
533  var internal_raw_stack = new InternalArray();
534  %MoveArrayContents(raw_stack, internal_raw_stack);
535  var frames = new InternalArray();
536  var sloppy_frames = internal_raw_stack[0];
537  for (var i = 1; i < internal_raw_stack.length; i += 4) {
538    var recv = internal_raw_stack[i];
539    var fun = internal_raw_stack[i + 1];
540    var code = internal_raw_stack[i + 2];
541    var pc = internal_raw_stack[i + 3];
542    // For traps in wasm, the bytecode offset is passed as (-1 - offset).
543    // Otherwise, lookup the position from the pc.
544    var pos = IS_NUMBER(fun) && pc < 0 ? (-1 - pc) :
545      %FunctionGetPositionForOffset(code, pc);
546    sloppy_frames--;
547    frames.push(new CallSite(recv, fun, pos, (sloppy_frames < 0)));
548  }
549  return frames;
550}
551
552
553// Flag to prevent recursive call of Error.prepareStackTrace.
554var formatting_custom_stack_trace = false;
555
556
557function FormatStackTrace(obj, raw_stack) {
558  var frames = GetStackFrames(raw_stack);
559  if (IS_FUNCTION(GlobalError.prepareStackTrace) &&
560      !formatting_custom_stack_trace) {
561    var array = [];
562    %MoveArrayContents(frames, array);
563    formatting_custom_stack_trace = true;
564    var stack_trace = UNDEFINED;
565    try {
566      stack_trace = GlobalError.prepareStackTrace(obj, array);
567    } catch (e) {
568      throw e;  // The custom formatting function threw.  Rethrow.
569    } finally {
570      formatting_custom_stack_trace = false;
571    }
572    return stack_trace;
573  }
574
575  var lines = new InternalArray();
576  lines.push(FormatErrorString(obj));
577  for (var i = 0; i < frames.length; i++) {
578    var frame = frames[i];
579    var line;
580    try {
581      line = frame.toString();
582    } catch (e) {
583      try {
584        line = "<error: " + e + ">";
585      } catch (ee) {
586        // Any code that reaches this point is seriously nasty!
587        line = "<error>";
588      }
589    }
590    lines.push("    at " + line);
591  }
592  return %_Call(ArrayJoin, lines, "\n");
593}
594
595
596function GetTypeName(receiver, requireConstructor) {
597  if (IS_NULL_OR_UNDEFINED(receiver)) return null;
598  if (IS_PROXY(receiver)) return "Proxy";
599
600  var constructor = %GetDataProperty(TO_OBJECT(receiver), "constructor");
601  if (!IS_FUNCTION(constructor)) {
602    return requireConstructor ? null : %_Call(NoSideEffectsToString, receiver);
603  }
604  return %FunctionGetName(constructor);
605}
606
607
608// Format the stack trace if not yet done, and return it.
609// Cache the formatted stack trace on the holder.
610var StackTraceGetter = function() {
611  var formatted_stack_trace = UNDEFINED;
612  var holder = this;
613  while (holder) {
614    var formatted_stack_trace =
615      GET_PRIVATE(holder, formattedStackTraceSymbol);
616    if (IS_UNDEFINED(formatted_stack_trace)) {
617      // No formatted stack trace available.
618      var stack_trace = GET_PRIVATE(holder, stackTraceSymbol);
619      if (IS_UNDEFINED(stack_trace)) {
620        // Neither formatted nor structured stack trace available.
621        // Look further up the prototype chain.
622        holder = %object_get_prototype_of(holder);
623        continue;
624      }
625      formatted_stack_trace = FormatStackTrace(holder, stack_trace);
626      SET_PRIVATE(holder, stackTraceSymbol, UNDEFINED);
627      SET_PRIVATE(holder, formattedStackTraceSymbol, formatted_stack_trace);
628    }
629    return formatted_stack_trace;
630  }
631  return UNDEFINED;
632};
633
634
635// If the receiver equals the holder, set the formatted stack trace that the
636// getter returns.
637var StackTraceSetter = function(v) {
638  if (IsErrorObject(this)) {
639    SET_PRIVATE(this, stackTraceSymbol, UNDEFINED);
640    SET_PRIVATE(this, formattedStackTraceSymbol, v);
641  }
642};
643
644
645// Use a dummy function since we do not actually want to capture a stack trace
646// when constructing the initial Error prototytpes.
647var captureStackTrace = function() {};
648
649
650// Set up special error type constructors.
651function SetUpError(error_function) {
652  %FunctionSetInstanceClassName(error_function, 'Error');
653  var name = error_function.name;
654  var prototype = new GlobalObject();
655  if (name !== 'Error') {
656    %InternalSetPrototype(error_function, GlobalError);
657    %InternalSetPrototype(prototype, GlobalError.prototype);
658  }
659  %FunctionSetPrototype(error_function, prototype);
660
661  %AddNamedProperty(error_function.prototype, 'name', name, DONT_ENUM);
662  %AddNamedProperty(error_function.prototype, 'message', '', DONT_ENUM);
663  %AddNamedProperty(
664      error_function.prototype, 'constructor', error_function, DONT_ENUM);
665
666  %SetCode(error_function, function(m) {
667    if (IS_UNDEFINED(new.target)) return new error_function(m);
668
669    try { captureStackTrace(this, error_function); } catch (e) { }
670    // Define all the expected properties directly on the error
671    // object. This avoids going through getters and setters defined
672    // on prototype objects.
673    if (!IS_UNDEFINED(m)) {
674      %AddNamedProperty(this, 'message', TO_STRING(m), DONT_ENUM);
675    }
676  });
677
678  %SetNativeFlag(error_function);
679  return error_function;
680};
681
682GlobalError = SetUpError(global.Error);
683GlobalEvalError = SetUpError(global.EvalError);
684GlobalRangeError = SetUpError(global.RangeError);
685GlobalReferenceError = SetUpError(global.ReferenceError);
686GlobalSyntaxError = SetUpError(global.SyntaxError);
687GlobalTypeError = SetUpError(global.TypeError);
688GlobalURIError = SetUpError(global.URIError);
689
690utils.InstallFunctions(GlobalError.prototype, DONT_ENUM,
691                       ['toString', ErrorToString]);
692
693function ErrorToString() {
694  if (!IS_RECEIVER(this)) {
695    throw MakeTypeError(kCalledOnNonObject, "Error.prototype.toString");
696  }
697
698  var name = this.name;
699  name = IS_UNDEFINED(name) ? "Error" : TO_STRING(name);
700
701  var message = this.message;
702  message = IS_UNDEFINED(message) ? "" : TO_STRING(message);
703
704  if (name == "") return message;
705  if (message == "") return name;
706  return `${name}: ${message}`
707}
708
709function MakeError(type, arg0, arg1, arg2) {
710  return MakeGenericError(GlobalError, type, arg0, arg1, arg2);
711}
712
713function MakeRangeError(type, arg0, arg1, arg2) {
714  return MakeGenericError(GlobalRangeError, type, arg0, arg1, arg2);
715}
716
717function MakeSyntaxError(type, arg0, arg1, arg2) {
718  return MakeGenericError(GlobalSyntaxError, type, arg0, arg1, arg2);
719}
720
721function MakeTypeError(type, arg0, arg1, arg2) {
722  return MakeGenericError(GlobalTypeError, type, arg0, arg1, arg2);
723}
724
725function MakeURIError() {
726  return MakeGenericError(GlobalURIError, kURIMalformed);
727}
728
729// Boilerplate for exceptions for stack overflows. Used from
730// Isolate::StackOverflow().
731var StackOverflowBoilerplate = MakeRangeError(kStackOverflow);
732utils.InstallGetterSetter(StackOverflowBoilerplate, 'stack',
733                          StackTraceGetter, StackTraceSetter)
734
735// Define actual captureStackTrace function after everything has been set up.
736captureStackTrace = function captureStackTrace(obj, cons_opt) {
737  // Define accessors first, as this may fail and throw.
738  %object_define_property(obj, 'stack', { get: StackTraceGetter,
739                                          set: StackTraceSetter,
740                                          configurable: true });
741  %CollectStackTrace(obj, cons_opt ? cons_opt : captureStackTrace);
742};
743
744GlobalError.captureStackTrace = captureStackTrace;
745
746%InstallToContext([
747  "get_stack_trace_line_fun", GetStackTraceLine,
748  "make_error_function", MakeGenericError,
749  "make_range_error", MakeRangeError,
750  "make_type_error", MakeTypeError,
751  "message_get_column_number", GetColumnNumber,
752  "message_get_line_number", GetLineNumber,
753  "message_get_source_line", GetSourceLine,
754  "no_side_effects_to_string_fun", NoSideEffectsToString,
755  "stack_overflow_boilerplate", StackOverflowBoilerplate,
756]);
757
758utils.Export(function(to) {
759  to.ErrorToString = ErrorToString;
760  to.MakeError = MakeError;
761  to.MakeRangeError = MakeRangeError;
762  to.MakeSyntaxError = MakeSyntaxError;
763  to.MakeTypeError = MakeTypeError;
764  to.MakeURIError = MakeURIError;
765});
766
767});
768