| Index: test/cctest/test-api.cc
|
| diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
|
| index f47c997f518462433d693c9ec5904ae3e702022d..1e68ead93408bbcf65a9306ed731a26857a9223a 100644
|
| --- a/test/cctest/test-api.cc
|
| +++ b/test/cctest/test-api.cc
|
| @@ -14472,6 +14472,11 @@ void AnalyzeStackInNativeCode(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| const char* origin = "capture-stack-trace-test";
|
| const int kOverviewTest = 1;
|
| const int kDetailedTest = 2;
|
| + const int kFunctionName = 3;
|
| + const int kDisplayName = 4;
|
| + const int kFunctionNameAndDisplayName = 5;
|
| + const int kDisplayNameIsNotString = 6;
|
| + const int kFunctionNameIsNotString = 7;
|
|
|
| DCHECK(args.Length() == 1);
|
|
|
| @@ -14505,6 +14510,35 @@ void AnalyzeStackInNativeCode(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
| checkStackFrame(origin, "", 10, 1, false, false, stackTrace->GetFrame(3));
|
|
|
| CHECK(stackTrace->AsArray()->IsArray());
|
| + } else if (testGroup == kFunctionName) {
|
| + v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
|
| + args.GetIsolate(), 5, v8::StackTrace::kOverview);
|
| + CHECK_EQ(3, stackTrace->GetFrameCount());
|
| + checkStackFrame(origin, "function.name", 2, 24, false, false,
|
| + stackTrace->GetFrame(0));
|
| + } else if (testGroup == kDisplayName) {
|
| + v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
|
| + args.GetIsolate(), 5, v8::StackTrace::kOverview);
|
| + CHECK_EQ(3, stackTrace->GetFrameCount());
|
| + checkStackFrame(origin, "function.displayName", 2, 24, false, false,
|
| + stackTrace->GetFrame(0));
|
| + } else if (testGroup == kFunctionNameAndDisplayName) {
|
| + v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
|
| + args.GetIsolate(), 5, v8::StackTrace::kOverview);
|
| + CHECK_EQ(3, stackTrace->GetFrameCount());
|
| + checkStackFrame(origin, "function.displayName", 2, 24, false, false,
|
| + stackTrace->GetFrame(0));
|
| + } else if (testGroup == kDisplayNameIsNotString) {
|
| + v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
|
| + args.GetIsolate(), 5, v8::StackTrace::kOverview);
|
| + CHECK_EQ(3, stackTrace->GetFrameCount());
|
| + checkStackFrame(origin, "function.name", 2, 24, false, false,
|
| + stackTrace->GetFrame(0));
|
| + } else if (testGroup == kFunctionNameIsNotString) {
|
| + v8::Handle<v8::StackTrace> stackTrace = v8::StackTrace::CurrentStackTrace(
|
| + args.GetIsolate(), 5, v8::StackTrace::kOverview);
|
| + CHECK_EQ(3, stackTrace->GetFrameCount());
|
| + checkStackFrame(origin, "f", 2, 24, false, false, stackTrace->GetFrame(0));
|
| }
|
| }
|
|
|
| @@ -14566,6 +14600,33 @@ TEST(CaptureStackTrace) {
|
| detailed_script->BindToCurrentContext()->Run());
|
| CHECK(!detailed_result.IsEmpty());
|
| CHECK(detailed_result->IsObject());
|
| +
|
| + // Test using function.name and function.displayName in stack trace
|
| + const char* function_name_source =
|
| + "function bar(function_name, display_name, testGroup) {\n"
|
| + " var f = function() { AnalyzeStackInNativeCode(testGroup); };\n"
|
| + " if (function_name) {\n"
|
| + " Object.defineProperty(f, 'name', { value: function_name });\n"
|
| + " }\n"
|
| + " if (display_name) {\n"
|
| + " f.displayName = display_name;"
|
| + " }\n"
|
| + " f()\n"
|
| + "}\n"
|
| + "bar('function.name', undefined, 3);\n"
|
| + "bar(undefined, 'function.displayName', 4);\n"
|
| + "bar('function.name', 'function.displayName', 5);\n"
|
| + "bar('function.name', 239, 6);\n"
|
| + "bar(239, undefined, 7);\n";
|
| + v8::Handle<v8::String> function_name_src =
|
| + v8::String::NewFromUtf8(isolate, function_name_source);
|
| + v8::ScriptCompiler::Source script_source3(function_name_src,
|
| + v8::ScriptOrigin(origin));
|
| + v8::Handle<Value> function_name_result(
|
| + v8::ScriptCompiler::CompileUnbound(isolate, &script_source3)
|
| + ->BindToCurrentContext()
|
| + ->Run());
|
| + CHECK(!function_name_result.IsEmpty());
|
| }
|
|
|
|
|
| @@ -16099,6 +16160,79 @@ THREADED_TEST(FunctionGetInferredName) {
|
| }
|
|
|
|
|
| +THREADED_TEST(FunctionGetDebugName) {
|
| + LocalContext env;
|
| + v8::HandleScope scope(env->GetIsolate());
|
| + const char* code =
|
| + "var error = false;"
|
| + "function a() { this.x = 1; };"
|
| + "a.displayName = 'display_a';"
|
| + "var b = (function() {"
|
| + " var f = function() { this.x = 2; };"
|
| + " f.displayName = 'display_b';"
|
| + " return f;"
|
| + "})();"
|
| + "var c = function() {};"
|
| + "c.__defineGetter__('displayName', function() {"
|
| + " error = true;"
|
| + " throw new Error();"
|
| + "});"
|
| + "function d() {};"
|
| + "d.__defineGetter__('displayName', function() {"
|
| + " error = true;"
|
| + " return 'wrong_display_name';"
|
| + "});"
|
| + "function e() {};"
|
| + "e.displayName = 'wrong_display_name';"
|
| + "e.__defineSetter__('displayName', function() {"
|
| + " error = true;"
|
| + " throw new Error();"
|
| + "});"
|
| + "function f() {};"
|
| + "f.displayName = { 'foo': 6, toString: function() {"
|
| + " error = true;"
|
| + " return 'wrong_display_name';"
|
| + "}};"
|
| + "var g = function() {"
|
| + " arguments.callee.displayName = 'set_in_runtime';"
|
| + "}; g();"
|
| + "var h = function() {};"
|
| + "h.displayName = 'displayName';"
|
| + "Object.defineProperty(h, 'name', { value: 'function.name' });"
|
| + "var i = function() {};"
|
| + "i.displayName = 239;"
|
| + "Object.defineProperty(i, 'name', { value: 'function.name' });"
|
| + "var j = function() {};"
|
| + "Object.defineProperty(j, 'name', { value: 'function.name' });"
|
| + "var foo = { bar : { baz : function() {}}}; var k = foo.bar.baz;";
|
| + v8::ScriptOrigin origin =
|
| + v8::ScriptOrigin(v8::String::NewFromUtf8(env->GetIsolate(), "test"));
|
| + v8::Script::Compile(v8::String::NewFromUtf8(env->GetIsolate(), code), &origin)
|
| + ->Run();
|
| + v8::Local<v8::Value> error =
|
| + env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "error"));
|
| + CHECK_EQ(false, error->BooleanValue());
|
| + const char* functions[] = {"a", "display_a",
|
| + "b", "display_b",
|
| + "c", "c",
|
| + "d", "d",
|
| + "e", "e",
|
| + "f", "f",
|
| + "g", "set_in_runtime",
|
| + "h", "displayName",
|
| + "i", "function.name",
|
| + "j", "function.name",
|
| + "k", "foo.bar.baz"};
|
| + for (size_t i = 0; i < sizeof(functions) / sizeof(functions[0]) / 2; ++i) {
|
| + v8::Local<v8::Function> f =
|
| + v8::Local<v8::Function>::Cast(env->Global()->Get(
|
| + v8::String::NewFromUtf8(env->GetIsolate(), functions[i * 2])));
|
| + CHECK_EQ(0, strcmp(functions[i * 2 + 1],
|
| + *v8::String::Utf8Value(f->GetDebugName())));
|
| + }
|
| +}
|
| +
|
| +
|
| THREADED_TEST(FunctionGetDisplayName) {
|
| LocalContext env;
|
| v8::HandleScope scope(env->GetIsolate());
|
|
|