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 {
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_ =
......@@ -546,9 +544,7 @@ class CaptureStackTraceHelper {
}
if (!function_key_.is_null()) {
Handle<Object> fun_name = JSObject::GetDataProperty(fun, name_key_);
if (!fun_name->IsString())
fun_name = Handle<Object>(fun->shared()->DebugName(), isolate_);
Handle<Object> fun_name = JSFunction::GetDebugName(fun);
JSObject::AddProperty(stack_frame, function_key_, fun_name, NONE);
}
......@@ -579,7 +575,6 @@ class CaptureStackTraceHelper {
Handle<String> function_key_;
Handle<String> eval_key_;
Handle<String> constructor_key_;
Handle<String> name_key_;
};
......
......@@ -833,16 +833,13 @@ function CallSiteGetFunction() {
function CallSiteGetFunctionName() {
// See if the function knows its own name
var name = GET_PRIVATE(this, CallSiteFunctionKey).name;
if (name) {
return name;
}
name = %FunctionGetInferredName(GET_PRIVATE(this, CallSiteFunctionKey));
var fun = GET_PRIVATE(this, CallSiteFunctionKey);
var name = %FunctionGetDebugName(fun);
if (name) {
return name;
}
// Maybe this is an evaluation?
var script = %FunctionGetScript(GET_PRIVATE(this, CallSiteFunctionKey));
var script = %FunctionGetScript(fun);
if (script && script.compilation_type == COMPILATION_TYPE_EVAL) {
return "eval";
}
......
......@@ -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,
Handle<Oddball> oddball,
const char* to_string,
......
......@@ -7605,6 +7605,10 @@ class JSFunction: public JSObject {
// Used for flags such as --hydrogen-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
// kSize) is weak and has special handling during garbage collection.
static const int kCodeEntryOffset = JSObject::kHeaderSize;
......
......@@ -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
// source_position.
RUNTIME_FUNCTION(Runtime_GetFunctionCodePositionFromSource) {
......
......@@ -564,6 +564,7 @@ namespace internal {
F(DebugDisassembleFunction, 1, 1) \
F(DebugDisassembleConstructor, 1, 1) \
F(FunctionGetInferredName, 1, 1) \
F(FunctionGetDebugName, 1, 1) \
F(LiveEditFindSharedFunctionInfosForScript, 1, 1) \
F(LiveEditGatherCompileInfo, 2, 1) \
F(LiveEditReplaceScript, 3, 1) \
......
......@@ -94,6 +94,37 @@ function testAnonymousMethod() {
(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) {
this.message = message;
Error.captureStackTrace(this, stripPoint);
......@@ -261,6 +292,9 @@ testTrace("testValue", testValue, ["at Number.causeError"]);
testTrace("testConstructor", testConstructor, ["new Plonk"]);
testTrace("testRenamedMethod", testRenamedMethod, ["Wookie.a$b$c$d [as d]"]);
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,
["hep-hey", "new CustomError"],
["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