// 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.


// -------------------------------------------------------------------
//
// Matches Script::Type from objects.h
var TYPE_NATIVE = 0;
var TYPE_EXTENSION = 1;
var TYPE_NORMAL = 2;

// Matches Script::CompilationType from objects.h
var COMPILATION_TYPE_HOST = 0;
var COMPILATION_TYPE_EVAL = 1;
var COMPILATION_TYPE_JSON = 2;

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

// 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 = { };


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",
      getter_must_be_callable:      "Getter must be a function: %0",
      setter_must_be_callable:      "Setter must be a function: %0",
      value_and_accessor:           "Invalid property.  A property cannot both have accessors and be writable or have a value: %0",
      proto_object_or_null:         "Object prototype may only be an Object or null",
      property_desc_object:         "Property description must be an object: %0",
      redefine_disallowed:          "Cannot redefine property: %0",
      define_disallowed:            "Cannot define property, object is not extensible: %0",
      // 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",
      obj_ctor_property_non_object: "Object.%0 called on non-object",
      array_indexof_not_defined:    "Array.getIndexOf: Argument undefined"
    };
  }
  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;
  var line_ends = this.line_ends;

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

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

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

    if (position > line_ends[i]) {
      lower = i + 1;
    } else if (position <= 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 line_ends = this.line_ends;
  var start = line == 0 ? 0 : line_ends[line - 1] + 1;
  var end = 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 line_ends = this.line_ends;
  var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1;
  var to_position = to_line == 0 ? 0 : 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 line_ends = this.line_ends;
  var start = line == 0 ? 0 : line_ends[line - 1] + 1;
  var end = 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

// 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 == COMPILATION_TYPE_EVAL;
};

CallSite.prototype.getEvalOrigin = function () {
  var script = %FunctionGetScript(this.fun);
  return FormatEvalOrigin(script);
};

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 == COMPILATION_TYPE_EVAL)
    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 + 1: null;
};

CallSite.prototype.isNative = function () {
  var script = %FunctionGetScript(this.fun);
  return script ? (script.type == TYPE_NATIVE) : 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 FormatEvalOrigin(script) {
  var eval_origin = "";
  if (script.eval_from_function_name) {
    eval_origin += script.eval_from_function_name;
  } else {
    eval_origin +=  "<anonymous>";
  }
  
  var eval_from_script = script.eval_from_script;
  if (eval_from_script) {
    if (eval_from_script.compilation_type == COMPILATION_TYPE_EVAL) {
      // eval script originated from another eval.
      eval_origin += " (eval at " + FormatEvalOrigin(eval_from_script) + ")";
    } else {
      // eval script originated from "real" scource.
      if (eval_from_script.name) {
        eval_origin += " (" + eval_from_script.name;
        var location = eval_from_script.locationFromPosition(script.eval_from_script_position, true);
        if (location) {
          eval_origin += ":" + (location.line + 1);
          eval_origin += ":" + (location.column + 1);
        }
        eval_origin += ")"
      } else {
        eval_origin += " (unknown source)";
      }
    }
  }
  
  return eval_origin;
};

function FormatSourcePosition(frame) {
  var fileLocation = "";
  if (frame.isNative()) {
    fileLocation = "native";
  } else if (frame.isEval()) {
    fileLocation = "eval at " + 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];
    var line;
    try {
      line = FormatSourcePosition(frame);
    } catch (e) {
      try {
        line = "<error: " + e + ">";
      } catch (ee) {
        // Any code that reaches this point is seriously nasty!
        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', []);
