Commit ec73e088 authored by kozyatinskiy's avatar kozyatinskiy Committed by Commit bot

[V8] Use Function.name in Error.stack

Error.stack contains function.name if its type is string.
Otherwise if function have inferred name then .stack contains it.
For functions from eval .stack property contains "eval".

LOG=N
BUG=chromium:17356
R=yurys@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#27186}
parent c6752179
...@@ -483,8 +483,6 @@ class CaptureStackTraceHelper { ...@@ -483,8 +483,6 @@ class CaptureStackTraceHelper {
if (options & StackTrace::kFunctionName) { if (options & StackTrace::kFunctionName) {
function_key_ = factory()->InternalizeOneByteString( function_key_ = factory()->InternalizeOneByteString(
STATIC_CHAR_VECTOR("functionName")); STATIC_CHAR_VECTOR("functionName"));
name_key_ =
factory()->InternalizeOneByteString(STATIC_CHAR_VECTOR("name"));
} }
if (options & StackTrace::kIsEval) { if (options & StackTrace::kIsEval) {
eval_key_ = eval_key_ =
...@@ -546,9 +544,7 @@ class CaptureStackTraceHelper { ...@@ -546,9 +544,7 @@ class CaptureStackTraceHelper {
} }
if (!function_key_.is_null()) { if (!function_key_.is_null()) {
Handle<Object> fun_name = JSObject::GetDataProperty(fun, name_key_); Handle<Object> fun_name = JSFunction::GetDebugName(fun);
if (!fun_name->IsString())
fun_name = Handle<Object>(fun->shared()->DebugName(), isolate_);
JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE); JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE);
} }
...@@ -579,7 +575,6 @@ class CaptureStackTraceHelper { ...@@ -579,7 +575,6 @@ class CaptureStackTraceHelper {
Handle<String> function_key_; Handle<String> function_key_;
Handle<String> eval_key_; Handle<String> eval_key_;
Handle<String> constructor_key_; Handle<String> constructor_key_;
Handle<String> name_key_;
}; };
......
...@@ -833,16 +833,13 @@ function CallSiteGetFunction() { ...@@ -833,16 +833,13 @@ function CallSiteGetFunction() {
function CallSiteGetFunctionName() { function CallSiteGetFunctionName() {
// See if the function knows its own name // See if the function knows its own name
var name = GET_PRIVATE(this, CallSiteFunctionKey).name; var fun = GET_PRIVATE(this, CallSiteFunctionKey);
if (name) { var name = %FunctionGetDebugName(fun);
return name;
}
name = %FunctionGetInferredName(GET_PRIVATE(this, CallSiteFunctionKey));
if (name) { if (name) {
return name; return name;
} }
// Maybe this is an evaluation? // Maybe this is an evaluation?
var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey)); var script = %FunctionGetScript(fun);
if (script && script.compilation_type == COMPILATION_TYPE_EVAL) { if (script && script.compilation_type == COMPILATION_TYPE_EVAL) {
return "eval"; return "eval";
} }
......
...@@ -10327,6 +10327,15 @@ bool JSFunction::PassesFilter(const char* raw_filter) { ...@@ -10327,6 +10327,15 @@ bool JSFunction::PassesFilter(const char* raw_filter) {
} }
Handle<String> JSFunction::GetDebugName(Handle<JSFunction> function) {
Isolate* isolate = function->GetIsolate();
Handle<Object> name =
JSObject::GetDataProperty(function, isolate->factory()->name_string());
if (name->IsString()) return Handle<String>::cast(name);
return handle(function->shared()->DebugName(), isolate);
}
void Oddball::Initialize(Isolate* isolate, void Oddball::Initialize(Isolate* isolate,
Handle<Oddball> oddball, Handle<Oddball> oddball,
const char* to_string, const char* to_string,
......
...@@ -7605,6 +7605,10 @@ class JSFunction: public JSObject { ...@@ -7605,6 +7605,10 @@ class JSFunction: public JSObject {
// Used for flags such as --hydrogen-filter. // Used for flags such as --hydrogen-filter.
bool PassesFilter(const char* raw_filter); bool PassesFilter(const char* raw_filter);
// The function's name if it is configured, otherwise shared function info
// debug name.
static Handle<String> GetDebugName(Handle<JSFunction> function);
// Layout descriptors. The last property (from kNonWeakFieldsEndOffset to // Layout descriptors. The last property (from kNonWeakFieldsEndOffset to
// kSize) is weak and has special handling during garbage collection. // kSize) is weak and has special handling during garbage collection.
static const int kCodeEntryOffset = JSObject::kHeaderSize; static const int kCodeEntryOffset = JSObject::kHeaderSize;
......
...@@ -2613,6 +2613,15 @@ RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) { ...@@ -2613,6 +2613,15 @@ RUNTIME_FUNCTION(Runtime_FunctionGetInferredName) {
} }
RUNTIME_FUNCTION(Runtime_FunctionGetDebugName) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, f, 0);
return *JSFunction::GetDebugName(f);
}
// A testing entry. Returns statement position which is the closest to // A testing entry. Returns statement position which is the closest to
// source_position. // source_position.
RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) { RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
......
...@@ -564,6 +564,7 @@ namespace internal { ...@@ -564,6 +564,7 @@ namespace internal {
F(DebugDisassembleFunction, 1, 1) \ F(DebugDisassembleFunction, 1, 1) \
F(DebugDisassembleConstructor, 1, 1) \ F(DebugDisassembleConstructor, 1, 1) \
F(FunctionGetInferredName, 1, 1) \ F(FunctionGetInferredName, 1, 1) \
F(FunctionGetDebugName, 1, 1) \
F(LiveEditFindSharedFunctionInfosForScript, 1, 1) \ F(LiveEditFindSharedFunctionInfosForScript, 1, 1) \
F(LiveEditGatherCompileInfo, 2, 1) \ F(LiveEditGatherCompileInfo, 2, 1) \
F(LiveEditReplaceScript, 3, 1) \ F(LiveEditReplaceScript, 3, 1) \
......
...@@ -94,6 +94,37 @@ function testAnonymousMethod() { ...@@ -94,6 +94,37 @@ function testAnonymousMethod() {
(function () { FAIL }).call([1, 2, 3]); (function () { FAIL }).call([1, 2, 3]);
} }
function testFunctionName() {
function gen(name, counter) {
var f = function foo() {
if (counter === 0) {
FAIL;
}
gen(name, counter - 1)();
}
if (counter === 4) {
Object.defineProperty(f, 'name', {get: function(){ throw 239; }});
} else if (counter == 3) {
Object.defineProperty(f, 'name', {value: 'boo' + '_' + counter});
} else {
Object.defineProperty(f, 'name', {writable: true});
if (counter === 2)
f.name = 42;
else
f.name = name + '_' + counter;
}
return f;
}
gen('foo', 4)();
}
function testFunctionInferredName() {
var f = function() {
FAIL;
}
f();
}
function CustomError(message, stripPoint) { function CustomError(message, stripPoint) {
this.message = message; this.message = message;
Error.captureStackTrace(this, stripPoint); Error.captureStackTrace(this, stripPoint);
...@@ -261,6 +292,9 @@ testTrace("testValue", testValue, ["at Number.causeError"]); ...@@ -261,6 +292,9 @@ testTrace("testValue", testValue, ["at Number.causeError"]);
testTrace("testConstructor", testConstructor, ["new Plonk"]); testTrace("testConstructor", testConstructor, ["new Plonk"]);
testTrace("testRenamedMethod", testRenamedMethod, ["Wookie.a$b$c$d [as d]"]); testTrace("testRenamedMethod", testRenamedMethod, ["Wookie.a$b$c$d [as d]"]);
testTrace("testAnonymousMethod", testAnonymousMethod, ["Array.<anonymous>"]); testTrace("testAnonymousMethod", testAnonymousMethod, ["Array.<anonymous>"]);
testTrace("testFunctionName", testFunctionName,
[" at foo_0 ", " at foo_1", " at foo ", " at boo_3 ", " at foo "]);
testTrace("testFunctionInferredName", testFunctionInferredName, [" at f "]);
testTrace("testDefaultCustomError", testDefaultCustomError, testTrace("testDefaultCustomError", testDefaultCustomError,
["hep-hey", "new CustomError"], ["hep-hey", "new CustomError"],
["collectStackTrace"]); ["collectStackTrace"]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment