Index: src/messages.js |
diff --git a/src/messages.js b/src/messages.js |
index 7d0c6bda42f1931e01c787959395caf64cae3b50..ef239fa7655ca714681c0fdc4a54bde19b30c0fe 100644 |
--- a/src/messages.js |
+++ b/src/messages.js |
@@ -1271,4 +1271,46 @@ 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', []); |
+ |
+ // 'this' may not be the holder of the accessor. However, all Error objects |
+ // have a 'stack' property. By searching the prototype chain for an Error |
+ // object, we can find the holder of this accessor. |
+ function GetHolder(receiver) { |
+ var holder = receiver; |
+ while (!IS_ERROR(holder)) { |
+ holder = %GetPrototype(holder); |
+ if (holder == null) return MakeSyntaxError('illegal_access', []); |
+ } |
+ return holder; |
+ } |
+ |
+ // We cannot use a context allocated value to hold the value after the |
+ // stack trace string has been formatted or the setter has been called, |
+ // because that value would be shared between all copies of the boilerplate. |
+ // We also cannot replace the accessors with a normal property because |
+ // accessors behave differently than normal properties wrt prototype chain. |
+ // Instead, we replace the getter with a new getter. |
+ function Getter() { |
+ var holder = GetHolder(this); |
+ var raw_stack = %GetOverflowedRawStackTrace(holder) |
+ var result = FormatRawStackTrace(holder, raw_stack); |
+ %DefineOrRedefineAccessorProperty( |
+ holder, 'stack', function() { return result; }, null, DONT_ENUM); |
+ return result; |
+ } |
+ |
+ function Setter(v) { |
+ var holder = GetHolder(this); |
+ %DefineOrRedefineAccessorProperty( |
+ holder, 'stack', function() { return v; }, null, DONT_ENUM); |
+ } |
+ |
+ %DefineOrRedefineAccessorProperty( |
+ boilerplate, 'stack', Getter, Setter, DONT_ENUM); |
+ |
+ return boilerplate; |
+} |
+ |
+var kStackOverflowBoilerplate = SetUpStackOverflowBoilerplate(); |