2014-09-04 100 views
2

我想在運行js腳本時調用每個函數的日誌。 所以我想爲所有在JavaScript這樣的功能的回調:v8:無法在函數調用中獲取調用函數名稱

global->Set(v8::String::NewFromUtf8(isolate, "print"), v8::FunctionTemplate::New(isolate, LogName)); 
global->Set(v8::String::NewFromUtf8(isolate, "eval"), v8::FunctionTemplate::New(isolate, LogName)); 
global->Set(v8::String::NewFromUtf8(isolate, "unescape"), v8::FunctionTemplate::New(isolate, LogName)); 

我這樣定義我的功能:

void LogName(const v8::FunctionCallbackInfo<v8::Value>& args) { 
    v8::String::Utf8Value str_caller(args.Callee()); 
    printf("%s", str_caller); 
} 

這時候UNESCAPE被稱爲印刷:功能UNESCAPE() {[本地代碼]}

但是,如果這樣做:

object = v8::Handle<v8::Object>::Cast(context->Global()->Get(v8::String::NewFromUtf8(isolate, "String"))); 
object->Set(v8::String::NewFromUtf8(isolate, "fromCharCode"), v8::FunctionTemplate::New(isolate, LogName)->GetFunction()); 

這是對在調用String.fromCharCode時r:function(){[native code]}

爲什麼在第二個示例中,我沒有函數名稱,例如「fromCharCode」?

回答

1

我還是V8的新手,但遇到了同樣的問題。到目前爲止我只找到一個解決方案。我不知道它是否理想,但沒有其他解決方案,所以在這裏...

請注意獲取名稱的作用是將FunctionTemplate值添加到ObjectTemplate的位置(大概是這樣在創建上下文時用作全局模板參數)。另外請注意,在那些不起作用的情況下,您正在嘗試爲該現有上下文的全局對象添加一個函數,這是在獲取被調用者名稱失敗時(返回空字符串)。

到目前爲止,我發現的唯一解決方案是爲您爲全局範圍創建的ObjectTemplate保留一個持久句柄,在註冊新函數時添加FunctionTemplate,然後創建一個新的Context那個修改過的ObjectTemplate。在此之後,調用該函數將根據需要返回被調用者名稱。

要儘量說明這與一些代碼:

Isolate *gIsolate; 
Persistent<ObjectTemplate> gTemplate; 
Persistent<Context> gContext; 

// Adds a new function to the global object template 
void AddFunction(const char *name, FunctionCallback func) 
{ 
    // Get global template 
    Local<ObjectTemplate> global = ObjectTemplate::New(gIsolate, gTemplate); 

    // Add new function to it 
    global->Set(String::NewFromUtf8(gIsolate, name), FunctionTemplate::New(gIsolate, func)); 
} 

void FirstTimeInit() 
{ 
    gIsolate = Isolate::New(); 
    HandleScope handle_scope(gIsolate); 
    Handle<ObjectTemplate> global = ObjectTemplate::New(gIsolate); 

    // Store global template in persistent handle 
    gTemplate.Reset(gIsolate, global); 

    // Register starting functions 
    AddFunction("print", LogName); 
    AddFunction("eval", LogName); 
    AddFunction("unescape", LogName); 

    // Create context 
    Handle<Context> context = Context::New(gIsolate, NULL, global); 

    gContext.Reset(gIsolate, context); 
} 

void AddOtherFunction() 
{ 
    AddFunction("fromCharCode", LogName); 

    Local<ObjectTemplate> global = ObjectTemplate::New(gIsolate, gTemplate); 

    // Create a new context from the modified global template 
    Local<Context> newContext = Context::New(gIsolate, nil, global); 

    // Update persistent context handle to reference the new one 
    gContext.Reset(gIsolate, newContext); 
}