13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Redistribution and use in source and binary forms, with or without
3a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// modification, are permitted provided that the following conditions are
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// met:
5a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
6a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions of source code must retain the above copyright
7a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       notice, this list of conditions and the following disclaimer.
8a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Redistributions in binary form must reproduce the above
9a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       copyright notice, this list of conditions and the following
10a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       disclaimer in the documentation and/or other materials provided
11a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       with the distribution.
12a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//     * Neither the name of Google Inc. nor the names of its
13a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       contributors may be used to endorse or promote products derived
14a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//       from this software without specific prior written permission.
15a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block//
16a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// -------------------------------------------------------------------
293100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu//
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If this object gets passed to an error constructor the error will
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// get an accessor for .message that constructs a descriptive error
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// message on access.
333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar kAddMessageAccessorsMarker = { };
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// This will be lazily initialized when first needed (and forcibly
36589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch// overwritten even though it's const).
373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar kMessages = 0;
381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockfunction FormatString(format, message) {
401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var args = %MessageGetArguments(message);
411e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var result = "";
421e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var arg_num = 0;
431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  for (var i = 0; i < format.length; i++) {
441e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    var str = format[i];
45589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (str.length == 2 && %_StringCharCodeAt(str, 0) == 0x25) {
46589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // Two-char string starts with "%".
47589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      var arg_num = (%_StringCharCodeAt(str, 1) - 0x30) >>> 0;
48589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (arg_num < 4) {
49589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // str is one of %0, %1, %2 or %3.
50257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        try {
51257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          str = ToDetailString(args[arg_num]);
52257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        } catch (e) {
53257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch          str = "#<error>";
54257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch        }
551e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      }
56a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
571e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    result += str;
58a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
591e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return result;
60a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
61a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
62a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
631e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// To check if something is a native error we need to check the
641e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// concrete native error types. It is not enough to check "obj
651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// instanceof $Error" because user code can replace
661e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// NativeError.prototype.__proto__. User code cannot replace
671e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// NativeError.prototype though and therefore this is a safe test.
681e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockfunction IsNativeErrorObject(obj) {
691e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return (obj instanceof $Error) ||
701e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      (obj instanceof $EvalError) ||
711e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      (obj instanceof $RangeError) ||
721e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      (obj instanceof $ReferenceError) ||
731e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      (obj instanceof $SyntaxError) ||
741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      (obj instanceof $TypeError) ||
751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block      (obj instanceof $URIError);
761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
77a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
78a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// When formatting internally created error messages, do not
801e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// invoke overwritten error toString methods but explicitly use
811e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// the error to string method. This is to avoid leaking error
821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// objects between script tags in a browser setting.
831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Blockfunction ToStringCheckErrorObject(obj) {
841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (IsNativeErrorObject(obj)) {
853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return %_CallFunction(obj, ErrorToString);
861e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } else {
871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return ToString(obj);
88a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
89a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
90a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
91a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
92a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction ToDetailString(obj) {
93589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (obj != null && IS_OBJECT(obj) && obj.toString === ObjectToString) {
94a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var constructor = obj.constructor;
95589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (typeof constructor == "function") {
96589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      var constructorName = constructor.name;
97589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (IS_STRING(constructorName) && constructorName !== "") {
98589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        return "#<" + constructorName + ">";
99589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
1001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
101a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
102589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  return ToStringCheckErrorObject(obj);
103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
104a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
105a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
106a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction MakeGenericError(constructor, type, args) {
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_UNDEFINED(args)) {
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    args = [];
109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var e = new constructor(kAddMessageAccessorsMarker);
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  e.type = type;
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  e.arguments = args;
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return e;
114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
118589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch * Set up the Script function and constructor.
119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
120a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%FunctionSetInstanceClassName(Script, 'Script');
121589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch%SetProperty(Script.prototype, 'constructor', Script,
122589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch             DONT_ENUM | DONT_DELETE | READ_ONLY);
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block%SetCode(Script, function(x) {
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Script objects can only be created by the VM.
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  throw new $Error("Not supported");
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block});
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
129a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Helper functions; called from the runtime system.
130a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction FormatMessage(message) {
131a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (kMessages === 0) {
132589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    var messagesDictionary = [
133a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // Error
134589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "cyclic_proto",                 ["Cyclic __proto__ value"],
135589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "code_gen_from_strings",        ["Code generation from strings disallowed for this context"],
136a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // TypeError
137589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "unexpected_token",             ["Unexpected token ", "%0"],
138589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "unexpected_token_number",      ["Unexpected number"],
139589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "unexpected_token_string",      ["Unexpected string"],
140589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "unexpected_token_identifier",  ["Unexpected identifier"],
141589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "unexpected_reserved",          ["Unexpected reserved word"],
142589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "unexpected_strict_reserved",   ["Unexpected strict mode reserved word"],
143589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "unexpected_eos",               ["Unexpected end of input"],
144589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "malformed_regexp",             ["Invalid regular expression: /", "%0", "/: ", "%1"],
145589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "unterminated_regexp",          ["Invalid regular expression: missing /"],
146589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "regexp_flags",                 ["Cannot supply flags when constructing one RegExp from another"],
147589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "incompatible_method_receiver", ["Method ", "%0", " called on incompatible receiver ", "%1"],
148589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "invalid_lhs_in_assignment",    ["Invalid left-hand side in assignment"],
149589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "invalid_lhs_in_for_in",        ["Invalid left-hand side in for-in"],
150589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "invalid_lhs_in_postfix_op",    ["Invalid left-hand side expression in postfix operation"],
151589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "invalid_lhs_in_prefix_op",     ["Invalid left-hand side expression in prefix operation"],
152589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "multiple_defaults_in_switch",  ["More than one default clause in switch statement"],
153589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "newline_after_throw",          ["Illegal newline after throw"],
154589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "redeclaration",                ["%0", " '", "%1", "' has already been declared"],
155589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "no_catch_or_finally",          ["Missing catch or finally after try"],
156589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "unknown_label",                ["Undefined label '", "%0", "'"],
157589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "uncaught_exception",           ["Uncaught ", "%0"],
158589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "stack_trace",                  ["Stack Trace:\n", "%0"],
159589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "called_non_callable",          ["%0", " is not a function"],
160589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "undefined_method",             ["Object ", "%1", " has no method '", "%0", "'"],
161589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "property_not_function",        ["Property '", "%0", "' of object ", "%1", " is not a function"],
162589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "cannot_convert_to_primitive",  ["Cannot convert object to primitive value"],
163589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "not_constructor",              ["%0", " is not a constructor"],
164589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "not_defined",                  ["%0", " is not defined"],
165589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "non_object_property_load",     ["Cannot read property '", "%0", "' of ", "%1"],
166589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "non_object_property_store",    ["Cannot set property '", "%0", "' of ", "%1"],
167589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "non_object_property_call",     ["Cannot call method '", "%0", "' of ", "%1"],
168589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "with_expression",              ["%0", " has no properties"],
169589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "illegal_invocation",           ["Illegal invocation"],
170589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "no_setter_in_callback",        ["Cannot set property ", "%0", " of ", "%1", " which has only a getter"],
171589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "apply_non_function",           ["Function.prototype.apply was called on ", "%0", ", which is a ", "%1", " and not a function"],
172589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "apply_wrong_args",             ["Function.prototype.apply: Arguments list has wrong type"],
173589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "invalid_in_operator_use",      ["Cannot use 'in' operator to search for '", "%0", "' in ", "%1"],
174589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "instanceof_function_expected", ["Expecting a function in instanceof check, but got ", "%0"],
175589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "instanceof_nonobject_proto",   ["Function has non-object prototype '", "%0", "' in instanceof check"],
176589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "null_to_object",               ["Cannot convert null to object"],
177589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "reduce_no_initial",            ["Reduce of empty array with no initial value"],
178589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "getter_must_be_callable",      ["Getter must be a function: ", "%0"],
179589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "setter_must_be_callable",      ["Setter must be a function: ", "%0"],
180589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "value_and_accessor",           ["Invalid property.  A property cannot both have accessors and be writable or have a value, ", "%0"],
181589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "proto_object_or_null",         ["Object prototype may only be an Object or null"],
182589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "property_desc_object",         ["Property description must be an object: ", "%0"],
183589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "redefine_disallowed",          ["Cannot redefine property: ", "%0"],
184589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "define_disallowed",            ["Cannot define property:", "%0", ", object is not extensible."],
185589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "non_extensible_proto",         ["%0", " is not extensible"],
186589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "handler_non_object",           ["Proxy.", "%0", " called with non-object as handler"],
1873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "proto_non_object",             ["Proxy.", "%0", " called with non-object as prototype"],
1883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "trap_function_expected",       ["Proxy.", "%0", " called with non-function for '", "%1", "' trap"],
189589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "handler_trap_missing",         ["Proxy handler ", "%0", " has no '", "%1", "' trap"],
190589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "handler_trap_must_be_callable", ["Proxy handler ", "%0", " has non-callable '", "%1", "' trap"],
1913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "handler_returned_false",       ["Proxy handler ", "%0", " returned false from '", "%1", "' trap"],
1923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "handler_returned_undefined",   ["Proxy handler ", "%0", " returned undefined from '", "%1", "' trap"],
1933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "proxy_prop_not_configurable",  ["Proxy handler ", "%0", " returned non-configurable descriptor for property '", "%2", "' from '", "%1", "' trap"],
1943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "proxy_non_object_prop_names",  ["Trap '", "%1", "' returned non-object ", "%0"],
1953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "proxy_repeated_prop_name",     ["Trap '", "%1", "' returned repeated property name '", "%2", "'"],
196589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "invalid_weakmap_key",          ["Invalid value used as weak map key"],
197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // RangeError
198589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "invalid_array_length",         ["Invalid array length"],
199589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "stack_overflow",               ["Maximum call stack size exceeded"],
2003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "invalid_time_value",           ["Invalid time value"],
201a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      // SyntaxError
202589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "unable_to_parse",              ["Parse error"],
203589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "invalid_regexp_flags",         ["Invalid flags supplied to RegExp constructor '", "%0", "'"],
204589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "invalid_regexp",               ["Invalid RegExp pattern /", "%0", "/"],
205589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "illegal_break",                ["Illegal break statement"],
206589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "illegal_continue",             ["Illegal continue statement"],
207589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "illegal_return",               ["Illegal return statement"],
2083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "illegal_let",                  ["Illegal let declaration outside extended mode"],
209589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "error_loading_debugger",       ["Error loading debugger"],
210589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "no_input_to_regexp",           ["No input to ", "%0"],
211589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "invalid_json",                 ["String '", "%0", "' is not valid JSON"],
212589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "circular_structure",           ["Converting circular structure to JSON"],
2133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "called_on_non_object",         ["%0", " called on non-object"],
214589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "called_on_null_or_undefined",  ["%0", " called on null or undefined"],
215589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "array_indexof_not_defined",    ["Array.getIndexOf: Argument undefined"],
216589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "object_not_extensible",        ["Can't add property ", "%0", ", object is not extensible"],
217589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "illegal_access",               ["Illegal access"],
218589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "invalid_preparser_data",       ["Invalid preparser data for function ", "%0"],
219589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_mode_with",             ["Strict mode code may not include a with statement"],
220589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_catch_variable",        ["Catch variable may not be eval or arguments in strict mode"],
221589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "too_many_arguments",           ["Too many arguments in function call (only 32766 allowed)"],
222589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "too_many_parameters",          ["Too many parameters in function definition (only 32766 allowed)"],
223589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "too_many_variables",           ["Too many variables declared (only 32767 allowed)"],
224589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_param_name",            ["Parameter name eval or arguments is not allowed in strict mode"],
225589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_param_dupe",            ["Strict mode function may not have duplicate parameter names"],
226589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_var_name",              ["Variable name may not be eval or arguments in strict mode"],
227589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_function_name",         ["Function name may not be eval or arguments in strict mode"],
228589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_octal_literal",         ["Octal literals are not allowed in strict mode."],
229589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_duplicate_property",    ["Duplicate data property in object literal not allowed in strict mode"],
230589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "accessor_data_property",       ["Object literal may not have data and accessor property with the same name"],
231589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "accessor_get_set",             ["Object literal may not have multiple get/set accessors with the same name"],
232589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_lhs_assignment",        ["Assignment to eval or arguments is not allowed in strict mode"],
233589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_lhs_postfix",           ["Postfix increment/decrement may not have eval or arguments operand in strict mode"],
234589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_lhs_prefix",            ["Prefix increment/decrement may not have eval or arguments operand in strict mode"],
235589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_reserved_word",         ["Use of future reserved word in strict mode"],
236589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_delete",                ["Delete of an unqualified identifier in strict mode."],
237589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_delete_property",       ["Cannot delete property '", "%0", "' of ", "%1"],
238589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_const",                 ["Use of const in strict mode."],
239589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_function",              ["In strict mode code, functions can only be declared at top level or immediately within another function." ],
240589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_read_only_property",    ["Cannot assign to read only property '", "%0", "' of ", "%1"],
241589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_cannot_assign",         ["Cannot assign to read only '", "%0", "' in strict mode"],
242589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_poison_pill",           ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"],
243589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "strict_caller",                ["Illegal access to a strict mode caller function."],
244589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "unprotected_let",              ["Illegal let declaration in unprotected statement context."],
2453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "unprotected_const",            ["Illegal const declaration in unprotected statement context."],
246589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "cant_prevent_ext_external_array_elements", ["Cannot prevent extension of an object with external array elements"],
247589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      "redef_external_array_element", ["Cannot redefine a property of an object with external array elements"],
2483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "harmony_const_assign",         ["Assignment to constant variable."],
2493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "invalid_module_path",          ["Module does not export '", "%0", "', or export is not itself a module"],
2503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      "module_type_error",            ["Module '", "%0", "' used improperly"],
251589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    ];
252589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    var messages = { __proto__ : null };
253589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    for (var i = 0; i < messagesDictionary.length; i += 2) {
254589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      var key = messagesDictionary[i];
255589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      var format = messagesDictionary[i + 1];
2563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      for (var j = 0; j < format.length; j++) {
2583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        %IgnoreAttributesAndSetProperty(format, %_NumberToString(j), format[j],
2593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        DONT_DELETE | READ_ONLY | DONT_ENUM);
2603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      }
2613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      %IgnoreAttributesAndSetProperty(format, 'length', format.length,
2623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      DONT_DELETE | READ_ONLY | DONT_ENUM);
2633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      %PreventExtensions(format);
2643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      %IgnoreAttributesAndSetProperty(messages,
2653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      key,
2663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      format,
2673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      DONT_DELETE | DONT_ENUM | READ_ONLY);
268589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
269589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %PreventExtensions(messages);
270589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %IgnoreAttributesAndSetProperty(builtins, "kMessages",
271589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                    messages,
272589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                    DONT_DELETE | DONT_ENUM | READ_ONLY);
273a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2741e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var message_type = %MessageGetType(message);
2751e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var format = kMessages[message_type];
2761e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (!format) return "<unknown message " + message_type + ">";
2771e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return FormatString(format, message);
278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
279a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
280a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction GetLineNumber(message) {
2821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var start_position = %MessageGetStartPosition(message);
2831e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (start_position == -1) return kNoLineNumberInfo;
2841e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var script = %MessageGetScript(message);
2851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var location = script.locationFromPosition(start_position, true);
28625f6136652d8341ed047e7fc1a450af5bd218ea9Kristian Monsen  if (location == null) return kNoLineNumberInfo;
287a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return location.line + 1;
288a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
289a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
290a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
291a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns the source code line containing the given source
292a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// position, or the empty string if the position is invalid.
293a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction GetSourceLine(message) {
2941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var script = %MessageGetScript(message);
2951e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var start_position = %MessageGetStartPosition(message);
2961e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var location = script.locationFromPosition(start_position, true);
297a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (location == null) return "";
298a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  location.restrict();
299a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return location.sourceText();
300a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
301a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
302a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction MakeTypeError(type, args) {
304a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return MakeGenericError($TypeError, type, args);
305a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
306a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction MakeRangeError(type, args) {
309a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return MakeGenericError($RangeError, type, args);
310a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
311a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
312a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
313a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction MakeSyntaxError(type, args) {
314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return MakeGenericError($SyntaxError, type, args);
315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
316a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
317a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
318a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction MakeReferenceError(type, args) {
319a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return MakeGenericError($ReferenceError, type, args);
320a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
321a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
322a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
323a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction MakeEvalError(type, args) {
324a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return MakeGenericError($EvalError, type, args);
325a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
326a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
327a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
328a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction MakeError(type, args) {
329a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return MakeGenericError($Error, type, args);
330a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
332a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Find a line number given a specific source position.
334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} position The source position.
335a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @return {number} 0 if input too small, -1 if input too large,
336a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block       else the line number.
337a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
338589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction ScriptLineFromPosition(position) {
339a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var lower = 0;
340a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var upper = this.lineCount() - 1;
341d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  var line_ends = this.line_ends;
342a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
343a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // We'll never find invalid positions so bail right away.
344d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (position > line_ends[upper]) {
345a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return -1;
346a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
347a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
348a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // This means we don't have to safe-guard indexing line_ends[i - 1].
349d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (position <= line_ends[0]) {
350a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return 0;
351a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
352a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
353a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Binary search to find line # from position range.
354a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  while (upper >= 1) {
355a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var i = (lower + upper) >> 1;
356a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
357d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    if (position > line_ends[i]) {
358a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      lower = i + 1;
359d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    } else if (position <= line_ends[i - 1]) {
360a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      upper = i - 1;
361a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
362a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return i;
363a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
364a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
3651e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return -1;
367a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
368a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
369a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
370a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Get information on a specific source position.
371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} position The source position
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {boolean} include_resource_offset Set to true to have the resource
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *     offset added to the location
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @return {SourceLocation}
375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *     If line is negative or not in the source null is returned.
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
377589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction ScriptLocationFromPosition(position,
378589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                    include_resource_offset) {
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var line = this.lineFromPosition(position);
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (line == -1) return null;
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Determine start, end and column.
383d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  var line_ends = this.line_ends;
384d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  var start = line == 0 ? 0 : line_ends[line - 1] + 1;
385d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  var end = line_ends[line];
386589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (end > 0 && %_CallFunction(this.source, end - 1, StringCharAt) == '\r') {
387589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    end--;
388589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var column = position - start;
390a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Adjust according to the offset within the resource.
392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (include_resource_offset) {
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    line += this.line_offset;
394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (line == this.line_offset) {
395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      column += this.column_offset;
396a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
397a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
398a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
399a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return new SourceLocation(this, position, line, column, start, end);
4003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
401a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
402a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
403a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Get information on a specific source line and column possibly offset by a
405a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * fixed source position. This function is used to find a source position from
406a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * a line and column position. The fixed source position offset is typically
407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * used to find a source position in a function based on a line and column in
408a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * the source for the function alone. The offset passed will then be the
409a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * start position of the source for the function within the full script source.
410a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} opt_line The line within the source. Default value is 0
411a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} opt_column The column in within the line. Default value is 0
412a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} opt_offset_position The offset from the begining of the
413589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch *     source from where the line and column calculation starts.
414589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch *     Default value is 0
415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @return {SourceLocation}
416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *     If line is negative or not in the source null is returned.
417a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
418589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction ScriptLocationFromLine(opt_line, opt_column, opt_offset_position) {
419a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Default is the first line in the script. Lines in the script is relative
420a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to the offset within the resource.
421a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var line = 0;
422a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_UNDEFINED(opt_line)) {
423a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    line = opt_line - this.line_offset;
424a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
425a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
426a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Default is first column. If on the first line add the offset within the
427a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // resource.
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var column = opt_column || 0;
429a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (line == 0) {
4303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    column -= this.column_offset;
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
433a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var offset_position = opt_offset_position || 0;
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (line < 0 || column < 0 || offset_position < 0) return null;
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (line == 0) {
436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return this.locationFromPosition(offset_position + column, false);
437a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
438a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // Find the line where the offset position is located.
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var offset_line = this.lineFromPosition(offset_position);
440a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
441a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (offset_line == -1 || offset_line + line >= this.lineCount()) {
442a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return null;
443a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
444a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
4453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return this.locationFromPosition(
4463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        this.line_ends[offset_line + line - 1] + 1 + column);  // line > 0 here.
447a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
448a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
449a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
450a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
451a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
452a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Get a slice of source code from the script. The boundaries for the slice is
453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * specified in lines.
454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} opt_from_line The first line (zero bound) in the slice.
455a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *     Default is 0
456a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} opt_to_column The last line (zero bound) in the slice (non
457a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *     inclusive). Default is the number of lines in the script
458a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @return {SourceSlice} The source slice or null of the parameters where
459a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *     invalid
460a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
461589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction ScriptSourceSlice(opt_from_line, opt_to_line) {
4623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var from_line = IS_UNDEFINED(opt_from_line) ? this.line_offset
4633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              : opt_from_line;
4643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var to_line = IS_UNDEFINED(opt_to_line) ? this.line_offset + this.lineCount()
4653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          : opt_to_line;
466a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
467a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Adjust according to the offset within the resource.
468a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  from_line -= this.line_offset;
469a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  to_line -= this.line_offset;
470a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (from_line < 0) from_line = 0;
471a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (to_line > this.lineCount()) to_line = this.lineCount();
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check parameters.
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (from_line >= this.lineCount() ||
475a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      to_line < 0 ||
476a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      from_line > to_line) {
477a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return null;
478a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
479a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
480d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  var line_ends = this.line_ends;
481d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  var from_position = from_line == 0 ? 0 : line_ends[from_line - 1] + 1;
482d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  var to_position = to_line == 0 ? 0 : line_ends[to_line - 1] + 1;
483a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
484a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return a source slice with line numbers re-adjusted to the resource.
4853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return new SourceSlice(this,
4863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         from_line + this.line_offset,
4873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                         to_line + this.line_offset,
4883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                          from_position, to_position);
489a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
490a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
491a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
492589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction ScriptSourceLine(opt_line) {
493a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Default is the first line in the script. Lines in the script are relative
494a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // to the offset within the resource.
495a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var line = 0;
496a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_UNDEFINED(opt_line)) {
497a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    line = opt_line - this.line_offset;
498a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
499a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
500a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Check parameter.
501a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (line < 0 || this.lineCount() <= line) {
502a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return null;
503a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return the source line.
506d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  var line_ends = this.line_ends;
507d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  var start = line == 0 ? 0 : line_ends[line - 1] + 1;
508d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  var end = line_ends[line];
5091e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return %_CallFunction(this.source, start, end, StringSubstring);
510a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
512a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
513a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
514a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Returns the number of source lines.
515a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @return {number}
516a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *     Number of source lines.
517a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
518589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction ScriptLineCount() {
519a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Return number of source lines.
520a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return this.line_ends.length;
5213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
522a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
523a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
524a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
5256ded16be15dd865a9b21ea304d5273c8be299c87Steve Block * Returns the name of script if available, contents of sourceURL comment
526f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch * otherwise. See
5276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block * http://fbug.googlecode.com/svn/branches/firebug1.1/docs/ReleaseNotes_1.1.txt
5286ded16be15dd865a9b21ea304d5273c8be299c87Steve Block * for details on using //@ sourceURL comment to identify scritps that don't
5296ded16be15dd865a9b21ea304d5273c8be299c87Steve Block * have name.
530f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch *
5316ded16be15dd865a9b21ea304d5273c8be299c87Steve Block * @return {?string} script name if present, value for //@ sourceURL comment
5326ded16be15dd865a9b21ea304d5273c8be299c87Steve Block * otherwise.
5336ded16be15dd865a9b21ea304d5273c8be299c87Steve Block */
534589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction ScriptNameOrSourceURL() {
535589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (this.name) {
5366ded16be15dd865a9b21ea304d5273c8be299c87Steve Block    return this.name;
537589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  }
5383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // The result is cached as on long scripts it takes noticable time to search
5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // for the sourceURL.
5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (this.hasCachedNameOrSourceURL)
5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      return this.cachedNameOrSourceURL;
5433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.hasCachedNameOrSourceURL = true;
5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
545f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  // TODO(608): the spaces in a regexp below had to be escaped as \040
5466ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // because this file is being processed by js2c whose handling of spaces
5476ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // in regexps is broken. Also, ['"] are excluded from allowed URLs to
5486ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  // avoid matches against sources that invoke evals with sourceURL.
54944f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // A better solution would be to detect these special comments in
55044f0eee88ff00398ff7f715fab053374d808c90dSteve Block  // the scanner/parser.
55144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  var source = ToString(this.source);
55244f0eee88ff00398ff7f715fab053374d808c90dSteve Block  var sourceUrlPos = %StringIndexOf(source, "sourceURL=", 0);
5533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  this.cachedNameOrSourceURL = this.name;
55444f0eee88ff00398ff7f715fab053374d808c90dSteve Block  if (sourceUrlPos > 4) {
55544f0eee88ff00398ff7f715fab053374d808c90dSteve Block    var sourceUrlPattern =
55644f0eee88ff00398ff7f715fab053374d808c90dSteve Block        /\/\/@[\040\t]sourceURL=[\040\t]*([^\s\'\"]*)[\040\t]*$/gm;
55744f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // Don't reuse lastMatchInfo here, so we create a new array with room
55844f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // for four captures (array with length one longer than the index
55944f0eee88ff00398ff7f715fab053374d808c90dSteve Block    // of the fourth capture, where the numbering is zero-based).
56044f0eee88ff00398ff7f715fab053374d808c90dSteve Block    var matchInfo = new InternalArray(CAPTURE(3) + 1);
56144f0eee88ff00398ff7f715fab053374d808c90dSteve Block    var match =
56244f0eee88ff00398ff7f715fab053374d808c90dSteve Block        %_RegExpExec(sourceUrlPattern, source, sourceUrlPos - 4, matchInfo);
56344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    if (match) {
5643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      this.cachedNameOrSourceURL =
5653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch          SubString(source, matchInfo[CAPTURE(2)], matchInfo[CAPTURE(3)]);
56644f0eee88ff00398ff7f715fab053374d808c90dSteve Block    }
56744f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
5683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return this.cachedNameOrSourceURL;
5696ded16be15dd865a9b21ea304d5273c8be299c87Steve Block}
5706ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
5716ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
572589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpLockedPrototype(Script,
5733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  $Array("source", "name", "line_ends", "line_offset", "column_offset",
5743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         "cachedNameOrSourceURL", "hasCachedNameOrSourceURL" ),
575589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  $Array(
576589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "lineFromPosition", ScriptLineFromPosition,
577589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "locationFromPosition", ScriptLocationFromPosition,
578589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "locationFromLine", ScriptLocationFromLine,
579589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "sourceSlice", ScriptSourceSlice,
580589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "sourceLine", ScriptSourceLine,
581589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "lineCount", ScriptLineCount,
582589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "nameOrSourceURL", ScriptNameOrSourceURL
583589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  )
584589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch);
585589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
586589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
5876ded16be15dd865a9b21ea304d5273c8be299c87Steve Block/**
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Class for source location. A source location is a position within some
589a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * source with the following properties:
590a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *   script   : script object for the source
591a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *   line     : source line number
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *   column   : source column within the line
593a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *   position : position within the source
594a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *   start    : position of start of source context (inclusive)
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *   end      : position of end of source context (not inclusive)
5963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch * Source text for the source context is the character interval
5973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch * [start, end[. In most cases end will point to a newline character.
5983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch * It might point just past the final position of the source if the last
5993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch * source line does not end with a newline character.
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {Script} script The Script object for which this is a location
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} position Source position for the location
602a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} line The line number for the location
603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} column The column within the line for the location
604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} start Source position for start of source context
605a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} end Source position for end of source context
606a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @constructor
607a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
608a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SourceLocation(script, position, line, column, start, end) {
609a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.script = script;
610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.position = position;
611a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.line = line;
612a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.column = column;
613a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.start = start;
614a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.end = end;
615a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
616a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar kLineLengthLimit = 78;
618a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
619a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
620a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Restrict source location start and end positions to make the source slice
621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * no more that a certain number of characters wide.
622a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} opt_limit The with limit of the source text with a default
623a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *     of 78
624a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} opt_before The number of characters to prefer before the
625a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *     position with a default value of 10 less that the limit
626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
627589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction SourceLocationRestrict(opt_limit, opt_before) {
628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Find the actual limit to use.
629a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var limit;
630a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var before;
631a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_UNDEFINED(opt_limit)) {
632a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    limit = opt_limit;
633a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
634a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    limit = kLineLengthLimit;
635a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
636a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!IS_UNDEFINED(opt_before)) {
637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    before = opt_before;
638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // If no before is specified center for small limits and perfer more source
640a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // before the the position that after for longer limits.
641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (limit <= 20) {
642a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      before = $floor(limit / 2);
643a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
644a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      before = limit - 10;
645a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
646a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
647a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (before >= limit) {
648a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    before = limit - 1;
649a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
650a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
651a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // If the [start, end[ interval is too big we restrict
652a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // it in one or both ends. We make sure to always produce
653a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // restricted intervals of maximum allowed size.
654a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (this.end - this.start > limit) {
655a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var start_limit = this.position - before;
656a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var end_limit = this.position + limit - before;
657a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (this.start < start_limit && end_limit < this.end) {
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      this.start = start_limit;
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      this.end = end_limit;
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else if (this.start < start_limit) {
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      this.start = this.end - limit;
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      this.end = this.start + limit;
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
6663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
668a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
669a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
670a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Get the source text for a SourceLocation
671a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @return {String}
672a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *     Source text for this location.
673a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
674589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction SourceLocationSourceText() {
6753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  return %_CallFunction(this.script.source,
6763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        this.start,
6773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        this.end,
6783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                        StringSubstring);
6793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
680a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
681a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
682589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpLockedPrototype(SourceLocation,
683589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  $Array("script", "position", "line", "column", "start", "end"),
684589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  $Array(
685589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "restrict", SourceLocationRestrict,
686589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    "sourceText", SourceLocationSourceText
6873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch )
688589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch);
689589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
690589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
691a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Class for a source slice. A source slice is a part of a script source with
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * the following properties:
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *   script        : script object for the source
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *   from_line     : line number for the first line in the slice
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *   to_line       : source line number for the last line in the slice
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *   from_position : position of the first character in the slice
698a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *   to_position   : position of the last character in the slice
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * The to_line and to_position are not included in the slice, that is the lines
700a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * in the slice are [from_line, to_line[. Likewise the characters in the slice
701a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * are [from_position, to_position[.
702a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {Script} script The Script object for the source slice
703a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} from_line
704a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} to_line
705a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} from_position
706a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @param {number} to_position
707a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @constructor
708a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
709a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction SourceSlice(script, from_line, to_line, from_position, to_position) {
710a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.script = script;
711a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.from_line = from_line;
712a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.to_line = to_line;
713a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.from_position = from_position;
714a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.to_position = to_position;
715a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
716a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
717a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block/**
718a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * Get the source text for a SourceSlice
719a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block * @return {String} Source text for this slice. The last line will include
720a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block *     the line terminating characters (if any)
721a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block */
722589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction SourceSliceSourceText() {
7231e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return %_CallFunction(this.script.source,
7241e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                        this.from_position,
7251e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                        this.to_position,
7261e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block                        StringSubstring);
7273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
728a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
729589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpLockedPrototype(SourceSlice,
730589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  $Array("script", "from_line", "to_line", "from_position", "to_position"),
731589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  $Array("sourceText", SourceSliceSourceText)
732589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch);
733589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
734a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
735a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Returns the offset of the given position within the containing
736a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// line.
737a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction GetPositionInLine(message) {
7381e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var script = %MessageGetScript(message);
7391e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var start_position = %MessageGetStartPosition(message);
7401e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  var location = script.locationFromPosition(start_position, false);
741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (location == null) return -1;
742a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  location.restrict();
7431e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  return start_position - location.start;
744a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction GetStackTraceLine(recv, fun, pos, isGlobal) {
748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return FormatSourcePosition(new CallSite(recv, fun, pos));
749a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
750a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
751a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
752a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Error implementation
753a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
754a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Defines accessors for a property that is calculated the first time
755a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the property is read.
756a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction DefineOneShotAccessor(obj, name, fun) {
757a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Note that the accessors consistently operate on 'obj', not 'this'.
758a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Since the object may occur in someone else's prototype chain we
759a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // can't rely on 'this' being the same as 'obj'.
760a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var hasBeenSet = false;
761a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var value;
7623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var getter = function() {
763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (hasBeenSet) {
764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      return value;
765a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
766a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    hasBeenSet = true;
767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    value = fun(obj);
768a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return value;
7693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
7703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var setter = function(v) {
771a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    hasBeenSet = true;
772a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    value = v;
7733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
7743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  %DefineOrRedefineAccessorProperty(obj, name, getter, setter, DONT_ENUM);
775a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
776a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction CallSite(receiver, fun, pos) {
778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.receiver = receiver;
779a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.fun = fun;
780a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  this.pos = pos;
781a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
782a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
783589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteGetThis() {
784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return this.receiver;
7853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
787589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteGetTypeName() {
788a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var constructor = this.receiver.constructor;
789257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!constructor) {
7901e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return %_CallFunction(this.receiver, ObjectToString);
791257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
792a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var constructorName = constructor.name;
793257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!constructorName) {
7941e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    return %_CallFunction(this.receiver, ObjectToString);
795257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
796a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return constructorName;
7973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
799589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteIsToplevel() {
800257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (this.receiver == null) {
801a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return true;
802257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
803a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return IS_GLOBAL(this.receiver);
8043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
805a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
806589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteIsEval() {
807a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var script = %FunctionGetScript(this.fun);
8083100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return script && script.compilation_type == COMPILATION_TYPE_EVAL;
8093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
810a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
811589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteGetEvalOrigin() {
812a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var script = %FunctionGetScript(this.fun);
813d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return FormatEvalOrigin(script);
8143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
815a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
816589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteGetScriptNameOrSourceURL() {
8170d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  var script = %FunctionGetScript(this.fun);
8180d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  return script ? script.nameOrSourceURL() : null;
8193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
8200d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
821589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteGetFunction() {
822a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return this.fun;
8233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
824a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
825589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteGetFunctionName() {
826a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // See if the function knows its own name
827a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var name = this.fun.name;
828a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (name) {
829a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return name;
830a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
831a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return %FunctionGetInferredName(this.fun);
832a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Maybe this is an evaluation?
834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var script = %FunctionGetScript(this.fun);
835257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (script && script.compilation_type == COMPILATION_TYPE_EVAL) {
836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return "eval";
837257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return null;
8393ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
841589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteGetMethodName() {
842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // See if we can find a unique property on the receiver that holds
843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // this function.
844a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var ownName = this.fun.name;
845756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  if (ownName && this.receiver &&
8463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      (%_CallFunction(this.receiver,
8473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      ownName,
8483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      ObjectLookupGetter) === this.fun ||
8493ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch       %_CallFunction(this.receiver,
8503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      ownName,
8513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      ObjectLookupSetter) === this.fun ||
852756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick       this.receiver[ownName] === this.fun)) {
853a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // To handle DontEnum properties we guess that the method has
854a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    // the same name as the function.
855a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return ownName;
856756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick  }
857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var name = null;
858a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var prop in this.receiver) {
859756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick    if (this.receiver.__lookupGetter__(prop) === this.fun ||
860756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick        this.receiver.__lookupSetter__(prop) === this.fun ||
8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        (!this.receiver.__lookupGetter__(prop) &&
8623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch         this.receiver[prop] === this.fun)) {
863756813857a4c2a4d8ad2e805969d5768d3cf43a0Iain Merrick      // If we find more than one match bail out to avoid confusion.
864257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      if (name) {
865a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        return null;
866257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      }
867a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      name = prop;
868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
870257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (name) {
871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return name;
872257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
873a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return null;
8743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
876589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteGetFileName() {
877a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var script = %FunctionGetScript(this.fun);
878a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return script ? script.name : null;
8793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
880a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
881589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteGetLineNumber() {
882257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (this.pos == -1) {
883a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return null;
884257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var script = %FunctionGetScript(this.fun);
886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var location = null;
887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (script) {
888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    location = script.locationFromPosition(this.pos, true);
889a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
890a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return location ? location.line + 1 : null;
8913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
893589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteGetColumnNumber() {
894257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (this.pos == -1) {
895a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return null;
896257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
897a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var script = %FunctionGetScript(this.fun);
898a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var location = null;
899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (script) {
900a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    location = script.locationFromPosition(this.pos, true);
901a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
902d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return location ? location.column + 1: null;
9033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
904a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
905589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteIsNative() {
906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var script = %FunctionGetScript(this.fun);
9073100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu  return script ? (script.type == TYPE_NATIVE) : false;
9083ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
909a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
910589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteGetPosition() {
911a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return this.pos;
9123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
913a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
914589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction CallSiteIsConstructor() {
915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var constructor = this.receiver ? this.receiver.constructor : null;
916257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (!constructor) {
917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return false;
918257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return this.fun === constructor;
9203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
922589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpLockedPrototype(CallSite, $Array("receiver", "fun", "pos"), $Array(
923589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "getThis", CallSiteGetThis,
924589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "getTypeName", CallSiteGetTypeName,
925589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "isToplevel", CallSiteIsToplevel,
926589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "isEval", CallSiteIsEval,
927589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "getEvalOrigin", CallSiteGetEvalOrigin,
928589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "getScriptNameOrSourceURL", CallSiteGetScriptNameOrSourceURL,
929589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "getFunction", CallSiteGetFunction,
930589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "getFunctionName", CallSiteGetFunctionName,
931589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "getMethodName", CallSiteGetMethodName,
932589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "getFileName", CallSiteGetFileName,
933589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "getLineNumber", CallSiteGetLineNumber,
934589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "getColumnNumber", CallSiteGetColumnNumber,
935589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "isNative", CallSiteIsNative,
936589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "getPosition", CallSiteGetPosition,
937589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  "isConstructor", CallSiteIsConstructor
938589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch));
939589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
940589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
941d0582a6c46733687d045e4188a1bcd0123c758a1Steve Blockfunction FormatEvalOrigin(script) {
9420d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  var sourceURL = script.nameOrSourceURL();
943257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (sourceURL) {
9440d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    return sourceURL;
945257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
9460d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
9470d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  var eval_origin = "eval at ";
948d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (script.eval_from_function_name) {
949d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    eval_origin += script.eval_from_function_name;
950d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  } else {
951d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    eval_origin +=  "<anonymous>";
952d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
9536ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
954d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  var eval_from_script = script.eval_from_script;
955d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  if (eval_from_script) {
9563100271588b61cbc1dc472a3f2f105d2eed8497fAndrei Popescu    if (eval_from_script.compilation_type == COMPILATION_TYPE_EVAL) {
957d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      // eval script originated from another eval.
9580d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      eval_origin += " (" + FormatEvalOrigin(eval_from_script) + ")";
959d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    } else {
9600d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      // eval script originated from "real" source.
961d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      if (eval_from_script.name) {
962d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        eval_origin += " (" + eval_from_script.name;
9633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        var location = eval_from_script.locationFromPosition(
9643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch            script.eval_from_script_position, true);
965d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        if (location) {
966d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block          eval_origin += ":" + (location.line + 1);
967d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block          eval_origin += ":" + (location.column + 1);
968d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        }
9693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        eval_origin += ")";
970d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      } else {
971d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block        eval_origin += " (unknown source)";
972d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block      }
973d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block    }
974d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  }
9756ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
976d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block  return eval_origin;
9773ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
978d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
979a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction FormatSourcePosition(frame) {
9800d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  var fileName;
981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var fileLocation = "";
982a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (frame.isNative()) {
983a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    fileLocation = "native";
984a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (frame.isEval()) {
9850d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    fileName = frame.getScriptNameOrSourceURL();
9863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (!fileName) {
9870d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      fileLocation = frame.getEvalOrigin();
9883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    }
989a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
9900d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    fileName = frame.getFileName();
9910d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  }
9920d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
9930d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  if (fileName) {
9940d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    fileLocation += fileName;
9950d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    var lineNumber = frame.getLineNumber();
9960d5e116f6aee03185f237311a943491bb079a768Kristian Monsen    if (lineNumber != null) {
9970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      fileLocation += ":" + lineNumber;
9980d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      var columnNumber = frame.getColumnNumber();
9990d5e116f6aee03185f237311a943491bb079a768Kristian Monsen      if (columnNumber) {
10000d5e116f6aee03185f237311a943491bb079a768Kristian Monsen        fileLocation += ":" + columnNumber;
1001a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1002a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
10040d5e116f6aee03185f237311a943491bb079a768Kristian Monsen
1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (!fileLocation) {
1006a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    fileLocation = "unknown source";
1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var line = "";
1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var functionName = frame.getFunction().name;
1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var addPrefix = true;
1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var isConstructor = frame.isConstructor();
1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var isMethodCall = !(frame.isToplevel() || isConstructor);
1013a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (isMethodCall) {
10149ac36c9faca11611ada13b4054edbaa0738661d0Iain Merrick    var methodName = frame.getMethodName();
1015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    line += frame.getTypeName() + ".";
1016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    if (functionName) {
1017a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      line += functionName;
1018a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      if (methodName && (methodName != functionName)) {
1019a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        line += " [as " + methodName + "]";
1020a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1021a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } else {
1022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      line += methodName || "<anonymous>";
1023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (isConstructor) {
1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    line += "new " + (functionName || "<anonymous>");
1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else if (functionName) {
1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    line += functionName;
1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    line += fileLocation;
1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    addPrefix = false;
1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (addPrefix) {
1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    line += " (" + fileLocation + ")";
1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return line;
1036a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1038a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction FormatStackTrace(error, frames) {
1039a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var lines = [];
1040a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  try {
1041a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    lines.push(error.toString());
1042a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } catch (e) {
1043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    try {
1044a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      lines.push("<error: " + e + ">");
1045a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } catch (ee) {
1046a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      lines.push("<error>");
1047a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1048a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1049a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  for (var i = 0; i < frames.length; i++) {
1050a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var frame = frames[i];
1051a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var line;
1052a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    try {
1053a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      line = FormatSourcePosition(frame);
1054a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    } catch (e) {
1055a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      try {
1056a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        line = "<error: " + e + ">";
1057a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      } catch (ee) {
1058a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        // Any code that reaches this point is seriously nasty!
1059a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        line = "<error>";
1060a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block      }
1061a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    }
1062a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    lines.push("    at " + line);
1063a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1064a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  return lines.join("\n");
1065a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1066a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1067a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction FormatRawStackTrace(error, raw_stack) {
1068a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var frames = [ ];
1069b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  for (var i = 0; i < raw_stack.length; i += 4) {
1070a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    var recv = raw_stack[i];
1071b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    var fun = raw_stack[i + 1];
1072b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    var code = raw_stack[i + 2];
1073b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    var pc = raw_stack[i + 3];
1074b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    var pos = %FunctionGetPositionForOffset(code, pc);
1075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    frames.push(new CallSite(recv, fun, pos));
1076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1077a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  if (IS_FUNCTION($Error.prepareStackTrace)) {
1078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return $Error.prepareStackTrace(error, frames);
1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  } else {
1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return FormatStackTrace(error, frames);
1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block}
1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1085a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockfunction captureStackTrace(obj, cons_opt) {
1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  var stackTraceLimit = $Error.stackTraceLimit;
10871e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return;
1088257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  if (stackTraceLimit < 0 || stackTraceLimit > 10000) {
1089a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    stackTraceLimit = 10000;
1090257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
10913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var raw_stack = %CollectStackTrace(obj,
10923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     cons_opt ? cons_opt : captureStackTrace,
10933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                     stackTraceLimit);
1094a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  DefineOneShotAccessor(obj, 'stack', function (obj) {
1095a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return FormatRawStackTrace(obj, raw_stack);
1096a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  });
10973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch}
1098a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1099a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1100589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdochfunction SetUpError() {
1101589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  // Define special error type constructors.
1102589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch
11033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  var DefineError = function(f) {
1104589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Store the error function in both the global object
1105589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // and the runtime object. The function is fetched
1106589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // from the runtime object when throwing errors from
1107589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // within the runtime system to avoid strange side
1108589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // effects when overwriting the error functions from
1109589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // user code.
1110589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    var name = f.name;
1111589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %SetProperty(global, name, f, DONT_ENUM);
1112589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %SetProperty(builtins, '$' + name, f, DONT_ENUM | DONT_DELETE | READ_ONLY);
1113589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // Configure the error function.
1114589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (name == 'Error') {
1115589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // The prototype of the Error object must itself be an error.
1116589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // However, it can't be an instance of the Error object because
1117589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // it hasn't been properly configured yet.  Instead we create a
1118589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      // special not-a-true-error-but-close-enough object.
11193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      var ErrorPrototype = function() {};
1120589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      %FunctionSetPrototype(ErrorPrototype, $Object.prototype);
1121589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      %FunctionSetInstanceClassName(ErrorPrototype, 'Error');
1122589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      %FunctionSetPrototype(f, new ErrorPrototype());
1123589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    } else {
1124589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      %FunctionSetPrototype(f, new $Error());
1125589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    }
1126589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %FunctionSetInstanceClassName(f, 'Error');
1127589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %SetProperty(f.prototype, 'constructor', f, DONT_ENUM);
1128589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // The name property on the prototype of error objects is not
1129589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // specified as being read-one and dont-delete. However, allowing
1130589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // overwriting allows leaks of error objects between script blocks
1131589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // in the same context in a browser setting. Therefore we fix the
1132589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    // name.
1133589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %SetProperty(f.prototype, "name", name,
1134589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                 DONT_ENUM | DONT_DELETE | READ_ONLY)  ;
1135589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    %SetCode(f, function(m) {
1136589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      if (%_IsConstructCall()) {
1137589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // Define all the expected properties directly on the error
1138589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // object. This avoids going through getters and setters defined
1139589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        // on prototype objects.
1140589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        %IgnoreAttributesAndSetProperty(this, 'stack', void 0, DONT_ENUM);
1141589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        %IgnoreAttributesAndSetProperty(this, 'arguments', void 0, DONT_ENUM);
1142589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        %IgnoreAttributesAndSetProperty(this, 'type', void 0, DONT_ENUM);
1143589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        if (m === kAddMessageAccessorsMarker) {
1144589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          // DefineOneShotAccessor always inserts a message property and
1145589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          // ignores setters.
1146589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          DefineOneShotAccessor(this, 'message', function (obj) {
1147589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch              return FormatMessage(%NewMessageObject(obj.type, obj.arguments));
1148589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          });
1149589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        } else if (!IS_UNDEFINED(m)) {
1150589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch          %IgnoreAttributesAndSetProperty(this,
1151589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                          'message',
1152589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                          ToString(m),
1153589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch                                          DONT_ENUM);
1154589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        }
1155589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        captureStackTrace(this, f);
1156589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      } else {
1157589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch        return new f(m);
1158589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch      }
1159589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    });
11603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    %SetNativeFlag(f);
11613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1163589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  DefineError(function Error() { });
1164589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  DefineError(function TypeError() { });
1165589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  DefineError(function RangeError() { });
1166589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  DefineError(function SyntaxError() { });
1167589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  DefineError(function ReferenceError() { });
1168589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  DefineError(function EvalError() { });
1169589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  DefineError(function URIError() { });
1170589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch}
1171a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1172589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben MurdochSetUpError();
11733fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1174589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch$Error.captureStackTrace = captureStackTrace;
11753fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch
1176589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch%SetProperty($Error.prototype, 'message', '', DONT_ENUM);
1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Global list of error objects visited during ErrorToString. This is
11791e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block// used to detect cycles in error toString formatting.
11803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar visited_errors = new InternalArray();
11813ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar cyclic_error_marker = new $Object();
11821e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
11833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction ErrorToStringDetectCycle(error) {
1184589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch  if (!%PushIfAbsent(visited_errors, error)) throw cyclic_error_marker;
11851e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  try {
1186589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    var type = error.type;
11873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var name = error.name;
11883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    name = IS_UNDEFINED(name) ? "Error" : TO_STRING_INLINE(name);
11893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    var message = error.message;
1190589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    var hasMessage = %_CallFunction(error, "message", ObjectHasOwnProperty);
1191589d6979ff2ef66fca2d8fa51404c369ca5e9250Ben Murdoch    if (type && !hasMessage) {
11923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      message = FormatMessage(%NewMessageObject(type, error.arguments));
11931e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    }
11943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    message = IS_UNDEFINED(message) ? "" : TO_STRING_INLINE(message);
11953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (name === "") return message;
11963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (message === "") return name;
11973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return name + ": " + message;
11981e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } finally {
11991e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    visited_errors.length = visited_errors.length - 1;
12001e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  }
12011e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block}
12021e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
12033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochfunction ErrorToString() {
12043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  if (!IS_SPEC_OBJECT(this)) {
12053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    throw MakeTypeError("called_on_non_object", ["Error.prototype.toString"]);
1206257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch  }
12071e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block
12081e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  try {
12093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    return ErrorToStringDetectCycle(this);
12101e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block  } catch(e) {
12111e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // If this error message was encountered already return the empty
12121e0659c275bb392c045087af4f6b0d7565cb3d77Steve Block    // string for it instead of recursively formatting it.
12133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    if (e === cyclic_error_marker) {
1214257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch      return '';
1215257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    }
1216257744e915dfc84d6d07a6b2accf8402d9ffc708Ben Murdoch    throw e;
1217a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1218b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch}
1219b8e0da25ee8efac3bb05cd6b2730aafbd96119f4Ben Murdoch
1220e0cee9b3ed82e2391fd85d118aeaa4ea361c687dBen Murdoch
12213ef787dbeca8a5fb1086949cda830dccee07bfbdBen MurdochInstallFunctions($Error.prototype, DONT_ENUM, ['toString', ErrorToString]);
1222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Boilerplate for exceptions for stack overflows. Used from
122444f0eee88ff00398ff7f715fab053374d808c90dSteve Block// Isolate::StackOverflow().
12253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochvar kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []);
1226