| Index: src/messages.js
|
| diff --git a/src/messages.js b/src/messages.js
|
| index 79b58e49f08ee5aee270be7a66d849e88b5156c5..e0baf6c34058329be879ddd63673554660501cd9 100644
|
| --- a/src/messages.js
|
| +++ b/src/messages.js
|
| @@ -734,29 +734,6 @@ function GetStackTraceLine(recv, fun, pos, isGlobal) {
|
| // ----------------------------------------------------------------------------
|
| // Error implementation
|
|
|
| -// Defines accessors for a property that is calculated the first time
|
| -// the property is read.
|
| -function DefineOneShotAccessor(obj, name, fun) {
|
| - // Note that the accessors consistently operate on 'obj', not 'this'.
|
| - // Since the object may occur in someone else's prototype chain we
|
| - // can't rely on 'this' being the same as 'obj'.
|
| - var value;
|
| - var value_factory = fun;
|
| - var getter = function() {
|
| - if (value_factory == null) {
|
| - return value;
|
| - }
|
| - value = value_factory(obj);
|
| - value_factory = null;
|
| - return value;
|
| - };
|
| - var setter = function(v) {
|
| - value_factory = null;
|
| - value = v;
|
| - };
|
| - %DefineOrRedefineAccessorProperty(obj, name, getter, setter, DONT_ENUM);
|
| -}
|
| -
|
| function CallSite(receiver, fun, pos) {
|
| this.receiver = receiver;
|
| this.fun = fun;
|
| @@ -1091,9 +1068,21 @@ function captureStackTrace(obj, cons_opt) {
|
| var raw_stack = %CollectStackTrace(obj,
|
| cons_opt ? cons_opt : captureStackTrace,
|
| stackTraceLimit);
|
| - DefineOneShotAccessor(obj, 'stack', function (obj) {
|
| - return FormatRawStackTrace(obj, raw_stack);
|
| - });
|
| + // 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.
|
| + var getter = function() {
|
| + var value = FormatRawStackTrace(obj, raw_stack);
|
| + %DefineOrRedefineDataProperty(obj, 'stack', value, NONE);
|
| + return value;
|
| + };
|
| + // 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) {
|
| + %DefineOrRedefineDataProperty(this, 'stack', v, NONE);
|
| + };
|
| +
|
| + %DefineOrRedefineAccessorProperty(obj, 'stack', getter, setter, DONT_ENUM);
|
| }
|
|
|
|
|
| @@ -1228,4 +1217,37 @@ InstallFunctions($Error.prototype, DONT_ENUM, ['toString', ErrorToString]);
|
|
|
| // Boilerplate for exceptions for stack overflows. Used from
|
| // Isolate::StackOverflow().
|
| -var kStackOverflowBoilerplate = MakeRangeError('stack_overflow', []);
|
| +function SetUpStackOverflowBoilerplate() {
|
| + var boilerplate = MakeRangeError('stack_overflow', []);
|
| +
|
| + // The raw stack trace is stored as hidden property of the copy of this
|
| + // boilerplate error object. Note that the receiver 'this' may not be that
|
| + // 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.
|
| + function getter() {
|
| + var holder = this;
|
| + while (!IS_ERROR(holder)) {
|
| + holder = %GetPrototype(holder);
|
| + if (holder == null) return MakeSyntaxError('illegal_access', []);
|
| + }
|
| + var raw_stack = %GetOverflowedRawStackTrace(holder);
|
| + var result = IS_ARRAY(raw_stack) ? FormatRawStackTrace(holder, raw_stack)
|
| + : void 0;
|
| + %DefineOrRedefineDataProperty(holder, 'stack', result, NONE);
|
| + return result;
|
| + }
|
| +
|
| + // 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);
|
| + }
|
| +
|
| + %DefineOrRedefineAccessorProperty(
|
| + boilerplate, 'stack', getter, setter, DONT_ENUM);
|
| +
|
| + return boilerplate;
|
| +}
|
| +
|
| +var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate();
|
|
|