Revision: 2545
Author: [email protected]
Date: Tue Jul 28 01:14:49 2009
Log: Merge r2541 and r2542 to branches/1.2.
Review URL: http://codereview.chromium.org/160263
http://code.google.com/p/v8/source/detail?r=2545
Modified:
/branches/1.2/src/messages.js
/branches/1.2/src/runtime.cc
/branches/1.2/src/version.cc
/branches/1.2/test/mjsunit/stack-traces.js
=======================================
--- /branches/1.2/src/messages.js Wed Jul 8 23:00:35 2009
+++ /branches/1.2/src/messages.js Tue Jul 28 01:14:49 2009
@@ -561,20 +561,24 @@
var kAddMessageAccessorsMarker = { };
// Defines accessors for a property that is calculated the first time
-// the property is read and then replaces the accessor with the value.
-// Also, setting the property causes the accessors to be deleted.
+// 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 hasBeenSet = false;
+ var value;
obj.__defineGetter__(name, function () {
- var value = fun(obj);
- obj[name] = value;
+ if (hasBeenSet) {
+ return value;
+ }
+ hasBeenSet = true;
+ value = fun(obj);
return value;
});
obj.__defineSetter__(name, function (v) {
- delete obj[name];
- obj[name] = v;
+ hasBeenSet = true;
+ value = v;
});
}
@@ -833,22 +837,25 @@
} else if (!IS_UNDEFINED(m)) {
this.message = ToString(m);
}
- var stackTraceLimit = $Error.stackTraceLimit;
- if (stackTraceLimit) {
- // Cap the limit to avoid extremely big traces
- if (stackTraceLimit < 0 || stackTraceLimit > 10000)
- stackTraceLimit = 10000;
- var raw_stack = %CollectStackTrace(f, stackTraceLimit);
- DefineOneShotAccessor(this, 'stack', function (obj) {
- return FormatRawStackTrace(obj, raw_stack);
- });
- }
+ captureStackTrace(this, f);
} else {
return new f(m);
}
});
}
+function captureStackTrace(obj, cons_opt) {
+ var stackTraceLimit = $Error.stackTraceLimit;
+ if (!stackTraceLimit) return;
+ if (stackTraceLimit < 0 || stackTraceLimit > 10000)
+ stackTraceLimit = 10000;
+ var raw_stack = %CollectStackTrace(cons_opt ? cons_opt :
captureStackTrace,
+ stackTraceLimit);
+ DefineOneShotAccessor(obj, 'stack', function (obj) {
+ return FormatRawStackTrace(obj, raw_stack);
+ });
+};
+
$Math.__proto__ = global.Object.prototype;
DefineError(function Error() { });
@@ -859,6 +866,8 @@
DefineError(function EvalError() { });
DefineError(function URIError() { });
+$Error.captureStackTrace = captureStackTrace;
+
// Setup extra properties of the Error.prototype object.
$Error.prototype.message = '';
=======================================
--- /branches/1.2/src/runtime.cc Mon Jul 13 07:04:26 2009
+++ /branches/1.2/src/runtime.cc Tue Jul 28 01:14:49 2009
@@ -7408,14 +7408,15 @@
// Not sure when this can happen but skip it just in case.
if (!raw_fun->IsJSFunction())
return false;
- if ((raw_fun == caller) && !(*seen_caller) && frame->IsConstructor()) {
+ if ((raw_fun == caller) && !(*seen_caller)) {
*seen_caller = true;
return false;
}
- // Skip the most obvious builtin calls. Some builtin calls (such as
- // Number.ADD which is invoked using 'call') are very difficult to
- // recognize so we're leaving them in for now.
- return !frame->receiver()->IsJSBuiltinsObject();
+ // Skip all frames until we've seen the caller. Also, skip the most
+ // obvious builtin calls. Some builtin calls (such as Number.ADD
+ // which is invoked using 'call') are very difficult to recognize
+ // so we're leaving them in for now.
+ return *seen_caller && !frame->receiver()->IsJSBuiltinsObject();
}
@@ -7424,7 +7425,7 @@
// code offset.
static Object* Runtime_CollectStackTrace(Arguments args) {
ASSERT_EQ(args.length(), 2);
- Object* caller = args[0];
+ Handle<Object> caller = args.at<Object>(0);
CONVERT_NUMBER_CHECKED(int32_t, limit, Int32, args[1]);
HandleScope scope;
@@ -7433,12 +7434,14 @@
Handle<JSArray> result = Factory::NewJSArray(initial_size * 3);
StackFrameIterator iter;
- bool seen_caller = false;
+ // If the caller parameter is a function we skip frames until we're
+ // under it before starting to collect.
+ bool seen_caller = !caller->IsJSFunction();
int cursor = 0;
int frames_seen = 0;
while (!iter.done() && frames_seen < limit) {
StackFrame* raw_frame = iter.frame();
- if (ShowFrameInStackTrace(raw_frame, caller, &seen_caller)) {
+ if (ShowFrameInStackTrace(raw_frame, *caller, &seen_caller)) {
frames_seen++;
JavaScriptFrame* frame = JavaScriptFrame::cast(raw_frame);
Object* recv = frame->receiver();
@@ -7453,8 +7456,10 @@
elements->set(cursor++, offset, SKIP_WRITE_BARRIER);
} else {
HandleScope scope;
- SetElement(result, cursor++, Handle<Object>(recv));
- SetElement(result, cursor++, Handle<Object>(fun));
+ Handle<Object> recv_handle(recv);
+ Handle<Object> fun_handle(fun);
+ SetElement(result, cursor++, recv_handle);
+ SetElement(result, cursor++, fun_handle);
SetElement(result, cursor++, Handle<Smi>(offset));
}
}
=======================================
--- /branches/1.2/src/version.cc Thu Jul 23 07:57:42 2009
+++ /branches/1.2/src/version.cc Tue Jul 28 01:14:49 2009
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 1
#define MINOR_VERSION 2
#define BUILD_NUMBER 14
-#define PATCH_LEVEL 6
+#define PATCH_LEVEL 7
#define CANDIDATE_VERSION false
// Define SONAME to have the SCons build the put a specific SONAME into the
=======================================
--- /branches/1.2/test/mjsunit/stack-traces.js Mon Jul 6 01:21:57 2009
+++ /branches/1.2/test/mjsunit/stack-traces.js Tue Jul 28 01:14:49 2009
@@ -83,10 +83,27 @@
function testAnonymousMethod() {
(function () { FAIL }).call([1, 2, 3]);
}
+
+function CustomError(message, stripPoint) {
+ this.message = message;
+ Error.captureStackTrace(this, stripPoint);
+}
+
+CustomError.prototype.toString = function () {
+ return "CustomError: " + this.message;
+};
+
+function testDefaultCustomError() {
+ throw new CustomError("hep-hey", undefined);
+}
+
+function testStrippedCustomError() {
+ throw new CustomError("hep-hey", CustomError);
+}
// Utility function for testing that the expected strings occur
// in the stack trace produced when running the given function.
-function testTrace(fun, expected) {
+function testTrace(fun, expected, unexpected) {
var threw = false;
try {
fun();
@@ -94,6 +111,11 @@
for (var i = 0; i < expected.length; i++) {
assertTrue(e.stack.indexOf(expected[i]) != -1);
}
+ if (unexpected) {
+ for (var i = 0; i < unexpected.length; i++) {
+ assertEquals(e.stack.indexOf(unexpected[i]), -1);
+ }
+ }
threw = true;
}
assertTrue(threw);
@@ -165,6 +187,10 @@
testTrace(testConstructor, ["new Plonk"]);
testTrace(testRenamedMethod, ["Wookie.a$b$c$d [as d]"]);
testTrace(testAnonymousMethod, ["Array.<anonymous>"]);
+testTrace(testDefaultCustomError, ["hep-hey", "new CustomError"],
+ ["collectStackTrace"]);
+testTrace(testStrippedCustomError, ["hep-hey"], ["new CustomError",
+ "collectStackTrace"]);
testCallerCensorship();
testUnintendedCallerCensorship();
--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---