This adds functionality for getting original functions from bound functions.

It's of much use when information about function calls is shown on the Events timeline in DevTools: instead of referencing to v8natives.js where bound functions are created, we'll be able to show real function data (name, resource, script line and column numbers) retrieved from original functions.

BUG=None
LOG=Y
R=yangguo@chromium.org, yurys@chromium.org

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

Patch from Alexandra Mikhaylova <amikhaylova@google.com>.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@18401 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
yurys@chromium.org 2013-12-23 08:04:54 +00:00
parent 4692a3a7d5
commit 61c1692c9b
3 changed files with 47 additions and 0 deletions

View File

@ -2539,6 +2539,12 @@ class V8_EXPORT Function : public Object {
*/
int ScriptId() const;
/**
* Returns the original function if this function is bound, else returns
* v8::Undefined.
*/
Local<Value> GetBoundFunction() const;
ScriptOrigin GetScriptOrigin() const;
V8_INLINE static Function* Cast(Value* obj);
static const int kLineOffsetNotFound;

View File

@ -4163,6 +4163,20 @@ int Function::ScriptId() const {
}
Local<v8::Value> Function::GetBoundFunction() const {
i::Handle<i::JSFunction> func = Utils::OpenHandle(this);
if (!func->shared()->bound()) {
return v8::Undefined(reinterpret_cast<v8::Isolate*>(func->GetIsolate()));
}
i::Handle<i::FixedArray> bound_args = i::Handle<i::FixedArray>(
i::FixedArray::cast(func->function_bindings()));
i::Handle<i::Object> original(
bound_args->get(i::JSFunction::kBoundFunctionIndex),
func->GetIsolate());
return Utils::ToLocal(i::Handle<i::JSFunction>::cast(original));
}
int String::Length() const {
i::Handle<i::String> str = Utils::OpenHandle(this);
return str->length();

View File

@ -17955,6 +17955,33 @@ THREADED_TEST(FunctionGetScriptId) {
}
THREADED_TEST(FunctionGetBoundFunction) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
v8::ScriptOrigin origin = v8::ScriptOrigin(v8::String::NewFromUtf8(
env->GetIsolate(), "test"));
v8::Handle<v8::String> script = v8::String::NewFromUtf8(
env->GetIsolate(),
"var a = new Object();\n"
"a.x = 1;\n"
"function f () { return this.x };\n"
"var g = f.bind(a);\n"
"var b = g();");
v8::Script::Compile(script, &origin)->Run();
v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "f")));
v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
env->Global()->Get(v8::String::NewFromUtf8(env->GetIsolate(), "g")));
CHECK(g->GetBoundFunction()->IsFunction());
Local<v8::Function> original_function = Local<v8::Function>::Cast(
g->GetBoundFunction());
CHECK_EQ(f->GetName(), original_function->GetName());
CHECK_EQ(f->GetScriptLineNumber(), original_function->GetScriptLineNumber());
CHECK_EQ(f->GetScriptColumnNumber(),
original_function->GetScriptColumnNumber());
}
static void GetterWhichReturns42(
Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {