[V8] Use Function.name for stack frames in v8::StackTrace

If function.name property has string type then stack frame will contain it otherwise DebugName from shared function info.

BUG=17356
LOG=Y
R=yurys@chromium.org

Review URL: https://codereview.chromium.org/917743002

Cr-Commit-Position: refs/heads/master@{#27025}
This commit is contained in:
kozyatinskiy 2015-03-05 10:31:32 -08:00 committed by Commit bot
parent 4873d8c74e
commit 54196b17c8
2 changed files with 54 additions and 1 deletions

View File

@ -489,6 +489,8 @@ class CaptureStackTraceHelper {
if (options & StackTrace::kFunctionName) {
function_key_ = factory()->InternalizeOneByteString(
STATIC_CHAR_VECTOR("functionName"));
name_key_ =
factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("name"));
}
if (options & StackTrace::kIsEval) {
eval_key_ =
@ -550,7 +552,9 @@ class CaptureStackTraceHelper {
}
if (!function_key_.is_null()) {
Handle<Object> fun_name(fun->shared()->DebugName(), isolate_);
Handle<Object> fun_name = JSObject::GetDataProperty(fun, name_key_);
if (!fun_name->IsString())
fun_name = Handle<Object>(fun->shared()->DebugName(), isolate_);
JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE);
}
@ -581,6 +585,7 @@ class CaptureStackTraceHelper {
Handle<String> function_key_;
Handle<String> eval_key_;
Handle<String> constructor_key_;
Handle<String> name_key_;
};

View File

@ -14909,6 +14909,54 @@ TEST(CaptureStackTraceForUncaughtExceptionAndSetters) {
}
static void StackTraceFunctionNameListener(v8::Handle<v8::Message> message,
v8::Handle<Value>) {
v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace();
CHECK_EQ(5, stack_trace->GetFrameCount());
checkStackFrame("origin", "foo:0", 4, 7, false, false,
stack_trace->GetFrame(0));
checkStackFrame("origin", "foo:1", 5, 27, false, false,
stack_trace->GetFrame(1));
checkStackFrame("origin", "foo", 5, 27, false, false,
stack_trace->GetFrame(2));
checkStackFrame("origin", "foo", 5, 27, false, false,
stack_trace->GetFrame(3));
checkStackFrame("origin", "", 1, 14, false, false, stack_trace->GetFrame(4));
}
TEST(GetStackTraceContainsFunctionsWithFunctionName) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
CompileRunWithOrigin(
"function gen(name, counter) {\n"
" var f = function foo() {\n"
" if (counter === 0)\n"
" throw 1;\n"
" gen(name, counter - 1)();\n"
" };\n"
" if (counter == 3) {\n"
" Object.defineProperty(f, 'name', {get: function(){ throw 239; }});\n"
" } else {\n"
" Object.defineProperty(f, 'name', {writable:true});\n"
" if (counter == 2)\n"
" f.name = 42;\n"
" else\n"
" f.name = name + ':' + counter;\n"
" }\n"
" return f;\n"
"};",
"origin");
v8::V8::AddMessageListener(StackTraceFunctionNameListener);
v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
CompileRunWithOrigin("gen('foo', 3)();", "origin");
v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
v8::V8::RemoveMessageListeners(StackTraceFunctionNameListener);
}
static void RethrowStackTraceHandler(v8::Handle<v8::Message> message,
v8::Handle<v8::Value> data) {
// Use the frame where JavaScript is called from.