Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(485)

Unified Diff: src/messages.js

Issue 11275186: Collect stack trace on stack overflow. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: . Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« src/isolate.cc ('K') | « src/isolate.cc ('k') | src/runtime.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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();
« src/isolate.cc ('K') | « src/isolate.cc ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698