2014-09-04 2 views
2

Я хочу создать журнал каждой функции, вызываемой при запуске js-скрипта. Так я хочу, чтобы сделать обратный вызов для всех функций JavaScript, как это:v8: не удается получить имя вызывающей функции в functioncallback

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); 
} 

Это выдаваемое когда экранирования в называется: функция экранирования в() {[машинный код]}

Но если сделать:

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()); 

Это р rinted, когда вызывается String.fromCharCode: function() {[собственный код]}

Почему во втором примере у меня нет имени функции, например, например «fromCharCode»?

ответ

1

Я все еще довольно новичок в V8, но столкнулся с этой же проблемой. До сих пор я нашел только одно решение. Я не уверен, что это идеальный вариант, но нет других решений, поэтому здесь нет ...

Обратите внимание, что функции, в которых выполняется работа с именами, это то, где вы добавляете значение FunctionTemplate в ObjectTemplate (это, предположительно, тогда используется в качестве глобального параметра шаблона при создании Контекста). Также обратите внимание на те, которые не работают, вы пытаетесь добавить функцию в глобальный объект для этого существующего Контекста, и это происходит, когда получение имени Callee терпит неудачу (возвращает пустую строку).

Единственное решение, которое я нашел до сих пор, это сохранить постоянный дескриптор ObjectTemplate, который вы создаете для глобальной области, добавить к нему FunctionTemplate, когда вы переходите к регистрации новой функции, а затем создаете новый контекст, который использует который модифицировал ObjectTemplate. После этого вызовы функции возвращают имя Callee по желанию.

Чтобы попытаться проиллюстрировать это с какой-то код:

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); 
} 
Смежные вопросы