| Index: src/messages.js | 
| diff --git a/src/messages.js b/src/messages.js | 
| index 4a8143e611162a447436ecb64aefb670e10c14fb..5d065d098434f39743d7d35a20524e22d973f22a 100644 | 
| --- a/src/messages.js | 
| +++ b/src/messages.js | 
| @@ -820,7 +820,7 @@ function CallSiteGetMethodName() { | 
| %_CallFunction(this.receiver, | 
| ownName, | 
| ObjectLookupSetter) === this.fun || | 
| -       %GetDataProperty(this.receiver, ownName) === this.fun)) { | 
| +       this.receiver[ownName] === this.fun)) { | 
| // To handle DontEnum properties we guess that the method has | 
| // the same name as the function. | 
| return ownName; | 
| @@ -829,7 +829,8 @@ function CallSiteGetMethodName() { | 
| for (var prop in this.receiver) { | 
| if (%_CallFunction(this.receiver, prop, ObjectLookupGetter) === this.fun || | 
| %_CallFunction(this.receiver, prop, ObjectLookupSetter) === this.fun || | 
| -        %GetDataProperty(this.receiver, prop) === this.fun) { | 
| +        (!%_CallFunction(this.receiver, prop, ObjectLookupGetter) && | 
| +         this.receiver[prop] === this.fun)) { | 
| // If we find more than one match bail out to avoid confusion. | 
| if (name) { | 
| return null; | 
| @@ -882,8 +883,7 @@ function CallSiteGetPosition() { | 
| } | 
|  | 
| function CallSiteIsConstructor() { | 
| -  var receiver = this.receiver; | 
| -  var constructor = receiver ? %GetDataProperty(receiver, "constructor") : null; | 
| +  var constructor = this.receiver ? this.receiver.constructor : null; | 
| if (!constructor) { | 
| return false; | 
| } | 
| @@ -933,14 +933,12 @@ function CallSiteToString() { | 
| var typeName = GetTypeName(this, true); | 
| var methodName = this.getMethodName(); | 
| if (functionName) { | 
| -      if (typeName && | 
| -          %_CallFunction(functionName, typeName, StringIndexOf) != 0) { | 
| +      if (typeName && functionName.indexOf(typeName) != 0) { | 
| line += typeName + "."; | 
| } | 
| line += functionName; | 
| -      if (methodName && | 
| -          (%_CallFunction(functionName, "." + methodName, StringIndexOf) != | 
| -           functionName.length - methodName.length - 1)) { | 
| +      if (methodName && functionName.lastIndexOf("." + methodName) != | 
| +          functionName.length - methodName.length - 1) { | 
| line += " [as " + methodName + "]"; | 
| } | 
| } else { | 
| @@ -1018,37 +1016,17 @@ function FormatEvalOrigin(script) { | 
| return eval_origin; | 
| } | 
|  | 
| - | 
| -function FormatErrorString(error) { | 
| +function FormatStackTrace(error, frames) { | 
| +  var lines = []; | 
| try { | 
| -    return %_CallFunction(error, ErrorToString); | 
| +    lines.push(error.toString()); | 
| } catch (e) { | 
| try { | 
| -      return "<error: " + e + ">"; | 
| +      lines.push("<error: " + e + ">"); | 
| } catch (ee) { | 
| -      return "<error>"; | 
| +      lines.push("<error>"); | 
| } | 
| } | 
| -} | 
| - | 
| - | 
| -function GetStackFrames(raw_stack) { | 
| -  var frames = new InternalArray(); | 
| -  for (var i = 0; i < raw_stack.length; i += 4) { | 
| -    var recv = raw_stack[i]; | 
| -    var fun = raw_stack[i + 1]; | 
| -    var code = raw_stack[i + 2]; | 
| -    var pc = raw_stack[i + 3]; | 
| -    var pos = %FunctionGetPositionForOffset(code, pc); | 
| -    frames.push(new CallSite(recv, fun, pos)); | 
| -  } | 
| -  return frames; | 
| -} | 
| - | 
| - | 
| -function FormatStackTrace(error_string, frames) { | 
| -  var lines = new InternalArray(); | 
| -  lines.push(error_string); | 
| for (var i = 0; i < frames.length; i++) { | 
| var frame = frames[i]; | 
| var line; | 
| @@ -1064,9 +1042,25 @@ function FormatStackTrace(error_string, frames) { | 
| } | 
| lines.push("    at " + line); | 
| } | 
| -  return %_CallFunction(lines, "\n", ArrayJoin); | 
| +  return lines.join("\n"); | 
| } | 
|  | 
| +function FormatRawStackTrace(error, raw_stack) { | 
| +  var frames = [ ]; | 
| +  for (var i = 0; i < raw_stack.length; i += 4) { | 
| +    var recv = raw_stack[i]; | 
| +    var fun = raw_stack[i + 1]; | 
| +    var code = raw_stack[i + 2]; | 
| +    var pc = raw_stack[i + 3]; | 
| +    var pos = %FunctionGetPositionForOffset(code, pc); | 
| +    frames.push(new CallSite(recv, fun, pos)); | 
| +  } | 
| +  if (IS_FUNCTION($Error.prepareStackTrace)) { | 
| +    return $Error.prepareStackTrace(error, frames); | 
| +  } else { | 
| +    return FormatStackTrace(error, frames); | 
| +  } | 
| +} | 
|  | 
| function GetTypeName(obj, requireConstructor) { | 
| var constructor = obj.receiver.constructor; | 
| @@ -1082,51 +1076,23 @@ function GetTypeName(obj, requireConstructor) { | 
| return constructorName; | 
| } | 
|  | 
| - | 
| -// Flag to prevent recursive call of Error.prepareStackTrace. | 
| -var formatting_custom_stack_trace = false; | 
| - | 
| - | 
| function captureStackTrace(obj, cons_opt) { | 
| var stackTraceLimit = $Error.stackTraceLimit; | 
| if (!stackTraceLimit || !IS_NUMBER(stackTraceLimit)) return; | 
| if (stackTraceLimit < 0 || stackTraceLimit > 10000) { | 
| stackTraceLimit = 10000; | 
| } | 
| -  var stack = %CollectStackTrace(obj, | 
| -                                 cons_opt ? cons_opt : captureStackTrace, | 
| -                                 stackTraceLimit); | 
| - | 
| -  // Don't be lazy if the error stack formatting is custom (observable). | 
| -  if (IS_FUNCTION($Error.prepareStackTrace) && !formatting_custom_stack_trace) { | 
| -    var array = []; | 
| -    %MoveArrayContents(GetStackFrames(stack), array); | 
| -    formatting_custom_stack_trace = true; | 
| -    try { | 
| -      obj.stack = $Error.prepareStackTrace(obj, array); | 
| -    } catch (e) { | 
| -      throw e;  // The custom formatting function threw.  Rethrow. | 
| -    } finally { | 
| -      formatting_custom_stack_trace = false; | 
| -    } | 
| -    return; | 
| -  } | 
| - | 
| -  var error_string = FormatErrorString(obj); | 
| +  var raw_stack = %CollectStackTrace(obj, | 
| +                                     cons_opt ? cons_opt : captureStackTrace, | 
| +                                     stackTraceLimit); | 
| // Note that 'obj' and 'this' maybe different when called on objects that | 
| // have the error object on its prototype chain.  The getter replaces itself | 
| // with a data property as soon as the stack trace has been formatted. | 
| -  // The getter must not change the object layout as it may be called after GC. | 
| var getter = function() { | 
| -    if (IS_STRING(stack)) return stack; | 
| -    // Stack is still a raw array awaiting to be formatted. | 
| -    stack = FormatStackTrace(error_string, GetStackFrames(stack)); | 
| -    // Release context value. | 
| -    error_string = void 0; | 
| -    return stack; | 
| +    var value = FormatRawStackTrace(obj, raw_stack); | 
| +    %DefineOrRedefineDataProperty(obj, 'stack', value, NONE); | 
| +    return value; | 
| }; | 
| -  %MarkOneShotGetter(getter); | 
| - | 
| // The 'stack' property of the receiver is set as data property.  If | 
| // the receiver is the same as holder, this accessor pair is replaced. | 
| var setter = function(v) { | 
| @@ -1273,32 +1239,23 @@ function SetUpStackOverflowBoilerplate() { | 
| // error object copy, but can be found on the prototype chain of 'this'. | 
| // When the stack trace is formatted, this accessor property is replaced by | 
| // a data property. | 
| -  var error_string = boilerplate.name + ": " + boilerplate.message; | 
| - | 
| -  // The getter must not change the object layout as it may be called after GC. | 
| function getter() { | 
| var holder = this; | 
| while (!IS_ERROR(holder)) { | 
| holder = %GetPrototype(holder); | 
| if (holder == null) return MakeSyntaxError('illegal_access', []); | 
| } | 
| -    var stack = %GetOverflowedStackTrace(holder); | 
| -    if (IS_STRING(stack)) return stack; | 
| -    if (IS_ARRAY(stack)) { | 
| -      var result = FormatStackTrace(error_string, GetStackFrames(stack)); | 
| -      %SetOverflowedStackTrace(holder, result); | 
| -      return result; | 
| -    } | 
| -    return void 0; | 
| +    var raw_stack = %GetOverflowedRawStackTrace(holder); | 
| +    var result = IS_ARRAY(raw_stack) ? FormatRawStackTrace(holder, raw_stack) | 
| +                                     : void 0; | 
| +    %DefineOrRedefineDataProperty(holder, 'stack', result, NONE); | 
| +    return result; | 
| } | 
| -  %MarkOneShotGetter(getter); | 
|  | 
| // The 'stack' property of the receiver is set as data property.  If | 
| // the receiver is the same as holder, this accessor pair is replaced. | 
| function setter(v) { | 
| %DefineOrRedefineDataProperty(this, 'stack', v, NONE); | 
| -    // Release the stack trace that is stored as hidden property, if exists. | 
| -    %SetOverflowedStackTrace(this, void 0); | 
| } | 
|  | 
| %DefineOrRedefineAccessorProperty( | 
|  |