// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


// -------------------------------------------------------------------

// Lazily initialized.
var kVowelSounds = 0;
var kCapitalVowelSounds = 0;


function GetInstanceName(cons) {
  if (cons.length == 0) {
    return "";
  }
  var first = %StringToLowerCase(StringCharAt.call(cons, 0));
  if (kVowelSounds === 0) {
    kVowelSounds = {a: true, e: true, i: true, o: true, u: true, y: true};
    kCapitalVowelSounds = {a: true, e: true, i: true, o: true, u: true, h: true,
        f: true, l: true, m: true, n: true, r: true, s: true, x: true, y: true};
  }
  var vowel_mapping = kVowelSounds;
  if (cons.length > 1 && (StringCharAt.call(cons, 0) != first)) {
    // First char is upper case
    var second = %StringToLowerCase(StringCharAt.call(cons, 1));
    // Second char is upper case
    if (StringCharAt.call(cons, 1) != second) {
      vowel_mapping = kCapitalVowelSounds;
    }
  }
  var s = vowel_mapping[first] ? "an " : "a ";
  return s + cons;
}


var kMessages = 0;


function FormatString(format, args) {
  var result = format;
  for (var i = 0; i < args.length; i++) {
    var str;
    try { str = ToDetailString(args[i]); }
    catch (e) { str = "#<error>"; }
    result = ArrayJoin.call(StringSplit.call(result, "%" + i), str);
  }
  return result;
}


function ToDetailString(obj) {
  if (obj != null && IS_OBJECT(obj) && obj.toString === $Object.prototype.toString) {
    var constructor = obj.constructor;
    if (!constructor) return ToString(obj);
    var constructorName = constructor.name;
    if (!constructorName) return ToString(obj);
    return "#<" + GetInstanceName(constructorName) + ">";
  } else {
    return ToString(obj);
  }
}


function MakeGenericError(constructor, type, args) {
  if (IS_UNDEFINED(args)) {
    args = [];
  }
  var e = new constructor(kAddMessageAccessorsMarker);
  e.type = type;
  e.arguments = args;
  return e;
}


/**
 * Setup the Script function and constructor.
 */
%FunctionSetInstanceClassName(Script, 'Script');
%SetProperty(Script.prototype, 'constructor', Script, DONT_ENUM);
%SetCode(Script, function(x) {
  // Script objects can only be created by the VM.
  throw new $Error("Not supported");
});


// Helper functions; called from the runtime system.
function FormatMessage(message) {
  if (kMessages === 0) {
    kMessages = {
      // Error
      cyclic_proto:                 "Cyclic __proto__ value",
      // TypeError
      unexpected_token:             "Unexpected token %0",
      unexpected_token_number:      "Unexpected number",
      unexpected_token_string:      "Unexpected string",
      unexpected_token_identifier:  "Unexpected identifier",
      unexpected_eos:               "Unexpected end of input",
      malformed_regexp:             "Invalid regular expression: /%0/: %1",
      unterminated_regexp:          "Invalid regular expression: missing /",
      regexp_flags:                 "Cannot supply flags when constructing one RegExp from another",
      invalid_lhs_in_assignment:    "Invalid left-hand side in assignment",
      invalid_lhs_in_for_in:        "Invalid left-hand side in for-in",
      invalid_lhs_in_postfix_op:    "Invalid left-hand side expression in postfix operation",
      invalid_lhs_in_prefix_op:     "Invalid left-hand side expression in prefix operation",
      multiple_defaults_in_switch:  "More than one default clause in switch statement",
      newline_after_throw:          "Illegal newline after throw",
      redeclaration:                "%0 '%1' has already been declared",
      no_catch_or_finally:          "Missing catch or finally after try",
      unknown_label:                "Undefined label '%0'",
      uncaught_exception:           "Uncaught %0",
      stack_trace:                  "Stack Trace:\n%0",
      called_non_callable:          "%0 is not a function",
      undefined_method:             "Object %1 has no method '%0'",
      property_not_function:        "Property '%0' of object %1 is not a function",
      cannot_convert_to_primitive:  "Cannot convert object to primitive value",
      not_constructor:              "%0 is not a constructor",
      not_defined:                  "%0 is not defined",
      non_object_property_load:     "Cannot read property '%0' of %1",
      non_object_property_store:    "Cannot set property '%0' of %1",
      non_object_property_call:     "Cannot call method '%0' of %1",
      with_expression:              "%0 has no properties",
      illegal_invocation:           "Illegal invocation",
      no_setter_in_callback:        "Cannot set property %0 of %1 which has only a getter",
      apply_non_function:           "Function.prototype.apply was called on %0, which is a %1 and not a function",
      apply_wrong_args:             "Function.prototype.apply: Arguments list has wrong type",
      invalid_in_operator_use:      "Cannot use 'in' operator to search for '%0' in %1",
      instanceof_function_expected: "Expecting a function in instanceof check, but got %0",
      instanceof_nonobject_proto:   "Function has non-object prototype '%0' in instanceof check",
      null_to_object:               "Cannot convert null to object",
      reduce_no_initial:            "Reduce of empty array with no initial value",
      // RangeError
      invalid_array_length:         "Invalid array length",
      stack_overflow:               "Maximum call stack size exceeded",
      apply_overflow:               "Function.prototype.apply cannot support %0 arguments",
      // SyntaxError
      unable_to_parse:              "Parse error",
      duplicate_regexp_flag:        "Duplicate RegExp flag %0",
      invalid_regexp:               "Invalid RegExp pattern /%0/",
      illegal_break:                "Illegal break statement",
      illegal_continue:             "Illegal continue statement",
      illegal_return:               "Illegal return statement",
      error_loading_debugger:       "Error loading debugger",
      no_input_to_regexp:           "No input to %0",
      result_not_primitive:         "Result of %0 must be a primitive, was %1",
      invalid_json:                 "String '%0' is not valid JSON",
      circular_structure:           "Converting circular structure to JSON"
    };
  }
  var format = kMessages[message.type];
  if (!format) return "<unknown message " + message.type + ">";
  return FormatString(format, message.args);
}


function GetLineNumber(message) {
  if (message.startPos == -1) return -1;
  var location = message.script.locationFromPosition(message.startPos, true);
  if (location == null) return -1;
  return location.line + 1;
}


// Returns the source code line containing the given source
// position, or the empty string if the position is invalid.
function GetSourceLine(message) {
  var location = message.script.locationFromPosition(message.startPos, true);
  if (location == null) return "";
  location.restrict();
  return location.sourceText();
}


function MakeTypeError(type, args) {
  return MakeGenericError($TypeError, type, args);
}


function MakeRangeError(type, args) {
  return MakeGenericError($RangeError, type, args);
}


function MakeSyntaxError(type, args) {
  return MakeGenericError($SyntaxError, type, args);
}


function MakeReferenceError(type, args) {
  return MakeGenericError($ReferenceError, type, args);
}


function MakeEvalError(type, args) {
  return MakeGenericError($EvalError, type, args);
}


function MakeError(type, args) {
  return MakeGenericError($Error, type, args);
}

/**
 * Find a line number given a specific source position.
 * @param {number} position The source position.
 * @return {number} 0 if input too small, -1 if input too large,
       else the line number.
 */
Script.prototype.lineFromPosition = function(position) {
  var lower = 0;
  var upper = this.lineCount() - 1;

  // We'll never find invalid positions so bail right away.
  if (position > this.line_ends[upper]) {
    return -1;
  }

  // This means we don't have to safe-guard indexing line_ends[i - 1].
  if (position <= this.line_ends[0]) {
    return 0;
  }

  // Binary search to find line # from position range.
  while (upper >= 1) {
    var i = (lower + upper) >> 1;

    if (position > this.line_ends[i]) {
      lower = i + 1;
    } else if (position <= this.line_ends[i - 1]) {
      upper = i - 1;
    } else {
      return i;
    }
  }
  return -1;
}

/**
 * Get information on a specific source position.
 * @param {number} position The source position
 * @param {boolean} include_resource_offset Set to true to have the resource
 *     offset added to the location
 * @return {SourceLocation}
 *     If line is negative or not in the source null is returned.
 */
Script.prototype.locationFromPosition = function (position,
                                                  include_resource_offset) {
  var line = this.lineFromPosition(position);
  if (line == -1) return null;

  // Determine start, end and column.
  var start = line == 0 ? 0 : this.line_ends[line - 1] + 1;
  var end = this.line_ends[line];
  if (end > 0 && StringCharAt.call(this.source, end - 1) == '\r') end--;
  var column = position - start;

  // Adjust according to the offset within the resource.
  if (include_resource_offset) {
    line += this.line_offset;
    if (line == this.line_offset) {
      column += this.column_offset;
    }
  }

  return new SourceLocation(this, position, line, column, start, end);
};


/**
 * Get information on a specific source line and column possibly offset by a
 * fixed source position. This function is used to find a source position from
 * a line and column position. The fixed source position offset is typically
 * used to find a source position in a function based on a line and column in
 * the source for the function alone. The offset passed will then be the
 * start position of the source for the function within the full script source.
 * @param {number} opt_line The line within the source. Default value is 0
 * @param {number} opt_column The column in within the line. Default value is 0
 * @param {number} opt_offset_position The offset from the begining of the
 *     source from where the line and column calculation starts. Default value is 0
 * @return {SourceLocation}
 *     If line is negative or not in the source null is returned.
 */
Script.prototype.locationFromLine = function (opt_line, opt_column, opt_offset_position) {
  // Default is the first line in the script. Lines in the script is relative
  // to the offset within the resource.
  var line = 0;
  if (!IS_UNDEFINED(opt_line)) {
    line = opt_line - this.line_offset;
  }

  // Default is first column. If on the first line add the offset within the
  // resource.
  var column = opt_column || 0;
  if (line == 0) {
    column -= this.column_offset
  }

  var offset_position = opt_offset_position || 0;
  if (line < 0 || column < 0 || offset_position < 0) return null;
  if (line == 0) {
    return this.locationFromPosition(offset_position + column, false);
  } else {
    // Find the line where the offset position is located.
    var offset_line = this.lineFromPosition(offset_position);

    if (offset_line == -1 || offset_line + line >= this.lineCount()) {
      return null;
    }

    return this.locationFromPosition(this.line_ends[offset_line + line - 1] + 1 + column);  // line > 0 here.
  }
}


/**
 * Get a slice of source code from the script. The boundaries for the slice is
 * specified in lines.
 * @param {number} opt_from_line The first line (zero bound) in the slice.
 *     Default is 0
 * @param {number} opt_to_column The last line (zero bound) in the slice (non
 *     inclusive). Default is the number of lines in the script
 * @return {SourceSlice} The source slice or null of the parameters where
 *     invalid
 */
Script.prototype.sourceSlice = function (opt_from_line, opt_to_line) {
  var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset : opt_from_line;
  var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount() : opt_to_line

  // Adjust according to the offset within the resource.
  from_line -= this.line_offset;
  to_line -= this.line_offset;
  if (from_line < 0) from_line = 0;
  if (to_line > this.lineCount()) to_line = this.lineCount();

  // Check parameters.
  if (from_line >= this.lineCount() ||
      to_line < 0 ||
      from_line > to_line) {
    return null;
  }

  var from_position = from_line == 0 ? 0 : this.line_ends[from_line - 1] + 1;
  var to_position = to_line == 0 ? 0 : this.line_ends[to_line - 1] + 1;

  // Return a source slice with line numbers re-adjusted to the resource.
  return new SourceSlice(this, from_line + this.line_offset, to_line + this.line_offset,
                         from_position, to_position);
}


Script.prototype.sourceLine = function (opt_line) {
  // Default is the first line in the script. Lines in the script are relative
  // to the offset within the resource.
  var line = 0;
  if (!IS_UNDEFINED(opt_line)) {
    line = opt_line - this.line_offset;
  }

  // Check parameter.
  if (line < 0 || this.lineCount() <= line) {
    return null;
  }

  // Return the source line.
  var start = line == 0 ? 0 : this.line_ends[line - 1] + 1;
  var end = this.line_ends[line];
  return StringSubstring.call(this.source, start, end);
}


/**
 * Returns the number of source lines.
 * @return {number}
 *     Number of source lines.
 */
Script.prototype.lineCount = function() {
  // Return number of source lines.
  return this.line_ends.length;
};


/**
 * Class for source location. A source location is a position within some
 * source with the following properties:
 *   script   : script object for the source
 *   line     : source line number
 *   column   : source column within the line
 *   position : position within the source
 *   start    : position of start of source context (inclusive)
 *   end      : position of end of source context (not inclusive)
 * Source text for the source context is the character interval [start, end[. In
 * most cases end will point to a newline character. It might point just past
 * the final position of the source if the last source line does not end with a
 * newline character.
 * @param {Script} script The Script object for which this is a location
 * @param {number} position Source position for the location
 * @param {number} line The line number for the location
 * @param {number} column The column within the line for the location
 * @param {number} start Source position for start of source context
 * @param {number} end Source position for end of source context
 * @constructor
 */
function SourceLocation(script, position, line, column, start, end) {
  this.script = script;
  this.position = position;
  this.line = line;
  this.column = column;
  this.start = start;
  this.end = end;
}


const kLineLengthLimit = 78;

/**
 * Restrict source location start and end positions to make the source slice
 * no more that a certain number of characters wide.
 * @param {number} opt_limit The with limit of the source text with a default
 *     of 78
 * @param {number} opt_before The number of characters to prefer before the
 *     position with a default value of 10 less that the limit
 */
SourceLocation.prototype.restrict = function (opt_limit, opt_before) {
  // Find the actual limit to use.
  var limit;
  var before;
  if (!IS_UNDEFINED(opt_limit)) {
    limit = opt_limit;
  } else {
    limit = kLineLengthLimit;
  }
  if (!IS_UNDEFINED(opt_before)) {
    before = opt_before;
  } else {
    // If no before is specified center for small limits and perfer more source
    // before the the position that after for longer limits.
    if (limit <= 20) {
      before = $floor(limit / 2);
    } else {
      before = limit - 10;
    }
  }
  if (before >= limit) {
    before = limit - 1;
  }

  // If the [start, end[ interval is too big we restrict
  // it in one or both ends. We make sure to always produce
  // restricted intervals of maximum allowed size.
  if (this.end - this.start > limit) {
    var start_limit = this.position - before;
    var end_limit = this.position + limit - before;
    if (this.start < start_limit && end_limit < this.end) {
      this.start = start_limit;
      this.end = end_limit;
    } else if (this.start < start_limit) {
      this.start = this.end - limit;
    } else {
      this.end = this.start + limit;
    }
  }
};


/**
 * Get the source text for a SourceLocation
 * @return {String}
 *     Source text for this location.
 */
SourceLocation.prototype.sourceText = function () {
  return StringSubstring.call(this.script.source, this.start, this.end);
};


/**
 * Class for a source slice. A source slice is a part of a script source with
 * the following properties:
 *   script        : script object for the source
 *   from_line     : line number for the first line in the slice
 *   to_line       : source line number for the last line in the slice
 *   from_position : position of the first character in the slice
 *   to_position   : position of the last character in the slice
 * The to_line and to_position are not included in the slice, that is the lines
 * in the slice are [from_line, to_line[. Likewise the characters in the slice
 * are [from_position, to_position[.
 * @param {Script} script The Script object for the source slice
 * @param {number} from_line
 * @param {number} to_line
 * @param {number} from_position
 * @param {number} to_position
 * @constructor
 */
function SourceSlice(script, from_line, to_line, from_position, to_position) {
  this.script = script;
  this.from_line = from_line;
  this.to_line = to_line;
  this.from_position = from_position;
  this.to_position = to_position;
}


/**
 * Get the source text for a SourceSlice
 * @return {String} Source text for this slice. The last line will include
 *     the line terminating characters (if any)
 */
SourceSlice.prototype.sourceText = function () {
  return StringSubstring.call(this.script.source, this.from_position, this.to_position);
};


// Returns the offset of the given position within the containing
// line.
function GetPositionInLine(message) {
  var location = message.script.locationFromPosition(message.startPos, false);
  if (location == null) return -1;
  location.restrict();
  return message.startPos - location.start;
}


function ErrorMessage(type, args, startPos, endPos, script, stackTrace) {
  this.startPos = startPos;
  this.endPos = endPos;
  this.type = type;
  this.args = args;
  this.script = script;
  this.stackTrace = stackTrace;
}


function MakeMessage(type, args, startPos, endPos, script, stackTrace) {
  return new ErrorMessage(type, args, startPos, endPos, script, stackTrace);
}


function GetStackTraceLine(recv, fun, pos, isGlobal) {
  return FormatSourcePosition(new CallSite(recv, fun, pos));
}

// ----------------------------------------------------------------------------
// Error implementation

// If this object gets passed to an error constructor the error will
// get an accessor for .message that constructs a descriptive error
// message on access.
var kAddMessageAccessorsMarker = { };

// Defines accessors for a property that is calculated the first time
// the property is read.
function DefineOneShotAccessor(obj, name, fun) {
  // Note that the accessors consistently operate on 'obj', not 'this'.
  // Since the object may occur in someone else's prototype chain we
  // can't rely on 'this' being the same as 'obj'.
  var hasBeenSet = false;
  var value;
  obj.__defineGetter__(name, function () {
    if (hasBeenSet) {
      return value;
    }
    hasBeenSet = true;
    value = fun(obj);
    return value;
  });
  obj.__defineSetter__(name, function (v) {
    hasBeenSet = true;
    value = v;
  });
}

function CallSite(receiver, fun, pos) {
  this.receiver = receiver;
  this.fun = fun;
  this.pos = pos;
}

CallSite.prototype.getThis = function () {
  return this.receiver;
};

CallSite.prototype.getTypeName = function () {
  var constructor = this.receiver.constructor;
  if (!constructor)
    return $Object.prototype.toString.call(this.receiver);
  var constructorName = constructor.name;
  if (!constructorName)
    return $Object.prototype.toString.call(this.receiver);
  return constructorName;
};

CallSite.prototype.isToplevel = function () {
  if (this.receiver == null)
    return true;
  return IS_GLOBAL(this.receiver);
};

CallSite.prototype.isEval = function () {
  var script = %FunctionGetScript(this.fun);
  return script && script.compilation_type == 1;
};

CallSite.prototype.getEvalOrigin = function () {
  var script = %FunctionGetScript(this.fun);
  if (!script || script.compilation_type != 1)
    return null;
  return new CallSite(null, script.eval_from_function,
      script.eval_from_position);
};

CallSite.prototype.getFunction = function () {
  return this.fun;
};

CallSite.prototype.getFunctionName = function () {
  // See if the function knows its own name
  var name = this.fun.name;
  if (name) {
    return name;
  } else {
    return %FunctionGetInferredName(this.fun);
  }
  // Maybe this is an evaluation?
  var script = %FunctionGetScript(this.fun);
  if (script && script.compilation_type == 1)
    return "eval";
  return null;
};

CallSite.prototype.getMethodName = function () {
  // See if we can find a unique property on the receiver that holds
  // this function.
  var ownName = this.fun.name;
  if (ownName && this.receiver && this.receiver[ownName] === this.fun)
    // To handle DontEnum properties we guess that the method has
    // the same name as the function.
    return ownName;
  var name = null;
  for (var prop in this.receiver) {
    if (this.receiver[prop] === this.fun) {
      // If we find more than one match bail out to avoid confusion
      if (name)
        return null;
      name = prop;
    }
  }
  if (name)
    return name;
  return null;
};

CallSite.prototype.getFileName = function () {
  var script = %FunctionGetScript(this.fun);
  return script ? script.name : null;
};

CallSite.prototype.getLineNumber = function () {
  if (this.pos == -1)
    return null;
  var script = %FunctionGetScript(this.fun);
  var location = null;
  if (script) {
    location = script.locationFromPosition(this.pos, true);
  }
  return location ? location.line + 1 : null;
};

CallSite.prototype.getColumnNumber = function () {
  if (this.pos == -1)
    return null;
  var script = %FunctionGetScript(this.fun);
  var location = null;
  if (script) {
    location = script.locationFromPosition(this.pos, true);
  }
  return location ? location.column : null;
};

CallSite.prototype.isNative = function () {
  var script = %FunctionGetScript(this.fun);
  return script ? (script.type == 0) : false;
};

CallSite.prototype.getPosition = function () {
  return this.pos;
};

CallSite.prototype.isConstructor = function () {
  var constructor = this.receiver ? this.receiver.constructor : null;
  if (!constructor)
    return false;
  return this.fun === constructor;
};

function FormatSourcePosition(frame) {
  var fileLocation = "";
  if (frame.isNative()) {
    fileLocation = "native";
  } else if (frame.isEval()) {
    fileLocation = "eval at " + FormatSourcePosition(frame.getEvalOrigin());
  } else {
    var fileName = frame.getFileName();
    if (fileName) {
      fileLocation += fileName;
      var lineNumber = frame.getLineNumber();
      if (lineNumber != null) {
        fileLocation += ":" + lineNumber;
        var columnNumber = frame.getColumnNumber();
        if (columnNumber) {
          fileLocation += ":" + columnNumber;
        }
      }
    }
  }
  if (!fileLocation) {
    fileLocation = "unknown source";
  }
  var line = "";
  var functionName = frame.getFunction().name;
  var methodName = frame.getMethodName();
  var addPrefix = true;
  var isConstructor = frame.isConstructor();
  var isMethodCall = !(frame.isToplevel() || isConstructor);
  if (isMethodCall) {
    line += frame.getTypeName() + ".";
    if (functionName) {
      line += functionName;
      if (methodName && (methodName != functionName)) {
        line += " [as " + methodName + "]";
      }
    } else {
      line += methodName || "<anonymous>";
    }
  } else if (isConstructor) {
    line += "new " + (functionName || "<anonymous>");
  } else if (functionName) {
    line += functionName;
  } else {
    line += fileLocation;
    addPrefix = false;
  }
  if (addPrefix) {
    line += " (" + fileLocation + ")";
  }
  return line;
}

function FormatStackTrace(error, frames) {
  var lines = [];
  try {
    lines.push(error.toString());
  } catch (e) {
    try {
      lines.push("<error: " + e + ">");
    } catch (ee) {
      lines.push("<error>");
    }
  }
  for (var i = 0; i < frames.length; i++) {
    var frame = frames[i];
    try {
      var line = FormatSourcePosition(frame);
    } catch (e) {
      try {
        var line = "<error: " + e + ">";
      } catch (ee) {
        // Any code that reaches this point is seriously nasty!
        var line = "<error>";
      }
    }
    lines.push("    at " + line);
  }
  return lines.join("\n");
}

function FormatRawStackTrace(error, raw_stack) {
  var frames = [ ];
  for (var i = 0; i < raw_stack.length; i += 3) {
    var recv = raw_stack[i];
    var fun = raw_stack[i+1];
    var pc = raw_stack[i+2];
    var pos = %FunctionGetPositionForOffset(fun, pc);
    frames.push(new CallSite(recv, fun, pos));
  }
  if (IS_FUNCTION($Error.prepareStackTrace)) {
    return $Error.prepareStackTrace(error, frames);
  } else {
    return FormatStackTrace(error, frames);
  }
}

function DefineError(f) {
  // Store the error function in both the global object
  // and the runtime object. The function is fetched
  // from the runtime object when throwing errors from
  // within the runtime system to avoid strange side
  // effects when overwriting the error functions from
  // user code.
  var name = f.name;
  %SetProperty(global, name, f, DONT_ENUM);
  this['$' + name] = f;
  // Configure the error function.
  if (name == 'Error') {
    // The prototype of the Error object must itself be an error.
    // However, it can't be an instance of the Error object because
    // it hasn't been properly configured yet.  Instead we create a
    // special not-a-true-error-but-close-enough object.
    function ErrorPrototype() {}
    %FunctionSetPrototype(ErrorPrototype, $Object.prototype);
    %FunctionSetInstanceClassName(ErrorPrototype, 'Error');
    %FunctionSetPrototype(f, new ErrorPrototype());
  } else {
    %FunctionSetPrototype(f, new $Error());
  }
  %FunctionSetInstanceClassName(f, 'Error');
  %SetProperty(f.prototype, 'constructor', f, DONT_ENUM);
  f.prototype.name = name;
  %SetCode(f, function(m) {
    if (%_IsConstructCall()) {
      if (m === kAddMessageAccessorsMarker) {
        DefineOneShotAccessor(this, 'message', function (obj) {
          return FormatMessage({type: obj.type, args: obj.arguments});
        });
      } else if (!IS_UNDEFINED(m)) {
        this.message = ToString(m);
      }
      captureStackTrace(this, f);
    } else {
      return new f(m);
    }
  });
}

function captureStackTrace(obj, cons_opt) {
  var stackTraceLimit = $Error.stackTraceLimit;
  if (!stackTraceLimit) return;
  if (stackTraceLimit < 0 || stackTraceLimit > 10000)
    stackTraceLimit = 10000;
  var raw_stack = %CollectStackTrace(cons_opt ? cons_opt : captureStackTrace,
      stackTraceLimit);
  DefineOneShotAccessor(obj, 'stack', function (obj) {
    return FormatRawStackTrace(obj, raw_stack);
  });
};

$Math.__proto__ = global.Object.prototype;

DefineError(function Error() { });
DefineError(function TypeError() { });
DefineError(function RangeError() { });
DefineError(function SyntaxError() { });
DefineError(function ReferenceError() { });
DefineError(function EvalError() { });
DefineError(function URIError() { });

$Error.captureStackTrace = captureStackTrace;

// Setup extra properties of the Error.prototype object.
$Error.prototype.message = '';

%SetProperty($Error.prototype, 'toString', function toString() {
  var type = this.type;
  if (type && !this.hasOwnProperty("message")) {
    return this.name + ": " + FormatMessage({ type: type, args: this.arguments });
  }
  var message = this.message;
  return this.name + (message ? (": " + message) : "");
}, DONT_ENUM);


// Boilerplate for exceptions for stack overflows. Used from
// Top::StackOverflow().
const kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []);
