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

Unified Diff: src/messages.js

Issue 11377158: Fire 'stack' getter of error objects after GC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: use hidden properties to mark oneshot getter Created 8 years 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
« no previous file with comments | « src/mark-compact.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 0a50ae7861e5e6f1032c4673dfb4aed904db2611..d1518dcbb43226c3600ccc8a3258edba7cf43775 100644
--- a/src/messages.js
+++ b/src/messages.js
@@ -1016,22 +1016,39 @@ function FormatEvalOrigin(script) {
return eval_origin;
}
-function FormatStackTrace(error, frames) {
- var lines = [];
+
+function FormatErrorString(error) {
try {
- lines.push(error.toString());
+ return %_CallFunction(error, ErrorToString);
} catch (e) {
try {
- lines.push("<error: " + e + ">");
+ return "<error: " + e + ">";
} catch (ee) {
- lines.push("<error>");
+ return "<error>";
}
}
+}
+
Vyacheslav Egorov (Google) 2012/12/10 14:46:45 one more empty line
+function GetStackFrames(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);
+ %_CallFunction(frames, new CallSite(recv, fun, pos), ArrayPush)
Vyacheslav Egorov (Google) 2012/12/10 14:46:45 This code can still be broken (formatting detected
+ }
+ return frames;
+}
+
Vyacheslav Egorov (Google) 2012/12/10 14:46:45 ditto
+function FormatStackTrace(error_string, frames) {
+ var lines = [error_string];
for (var i = 0; i < frames.length; i++) {
var frame = frames[i];
var line;
try {
- line = frame.toString();
+ line = %_CallFunction(frame, CallSiteToString);
} catch (e) {
try {
line = "<error: " + e + ">";
@@ -1040,26 +1057,9 @@ function FormatStackTrace(error, frames) {
line = "<error>";
}
}
- lines.push(" at " + line);
- }
- 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);
+ %_CallFunction(lines, " at " + line, ArrayPush);
}
+ return %_CallFunction(lines, "\n", ArrayJoin);
}
function GetTypeName(obj, requireConstructor) {
Vyacheslav Egorov (Google) 2012/12/10 14:46:45 ditto
@@ -1085,14 +1085,24 @@ function captureStackTrace(obj, cons_opt) {
var raw_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)) {
+ obj.stack = $Error.prepareStackTrace(obj, GetStackFrames(raw_stack));
Vyacheslav Egorov (Google) 2012/12/10 14:46:45 should we maybe catch an error if it flies from pr
+ return;
+ }
+
+ var error_string = FormatErrorString(obj);
// 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);
+ var value = FormatStackTrace(error_string, GetStackFrames(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) {
@@ -1239,6 +1249,8 @@ 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;
+
function getter() {
var holder = this;
while (!IS_ERROR(holder)) {
@@ -1246,11 +1258,13 @@ function SetUpStackOverflowBoilerplate() {
if (holder == null) return MakeSyntaxError('illegal_access', []);
}
var raw_stack = %GetOverflowedRawStackTrace(holder);
- var result = IS_ARRAY(raw_stack) ? FormatRawStackTrace(holder, raw_stack)
- : void 0;
+ var result = IS_ARRAY(raw_stack)
+ ? FormatStackTrace(error_string, GetStackFrames(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.
« no previous file with comments | « src/mark-compact.cc ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698