| Index: src/messages.js
|
| diff --git a/src/messages.js b/src/messages.js
|
| index 24cd66d1c66ce0ebd4a6866d545209622630a1db..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;
|
| @@ -932,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 {
|
| @@ -1017,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;
|
| @@ -1063,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;
|
| @@ -1081,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) {
|
| @@ -1272,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(
|
|
|