c++ - 谷歌 V8 : access local variables in C++

标签 c++ v8

有人知道如何在 C++ 的嵌套函数调用中查找局部变量吗? 考虑以下示例:

// e.g. a global variable in the browser
var global = "global_value";

function foo(){
    var global = "local_value";
    myCppFunction("global", global);
}

foo();

我现在的问题是,在 myCppFunction 的实现中,我如何从“foo”访问函数局部变量“global”(不是值,这将由第二个参数给出)?

Handle<Value> MyCppFunction(const Arguments& args){
    Local<String> varName = args[0]->ToString();
    Local<String> varValue = args[1]->ToString(); // this holds "local_value"
    // how to access the variable "global" in the scope of 'foo' ?
}

最佳答案

我设法自己找到了它。请参阅下面的示例,了解如何在堆栈上查找值(并替换它 - 此处以字符串变量为例)。

预先说明两点:

  • 除了我在我的硕士论文中使用它的用例之外,我没有测试过它的不良行为 - 那里(可能)有龙。
  • 我不知道为什么在我的测试中 sfl.FindJavaScriptFrame(0) 会产生所需的堆栈帧 - 但是,由于它独立于调用深度工作,我怀疑堆栈帧由0 始终是直接调用者的框架(在我的情况下,我知道我想要的正是那个)。

还有代码:

// Prepare identification of the variable,assuming varName as in the question
// More convenient conversions would be appreciated, at least by me
Local<String> varName = args[0]->ToString();        
std::string varStr = *String::AsciiValue(varName);
// I'm using 'namespace i = internal;' (within v8-namespace)
i::Vector<const char> tmpVar(varStr.data(), varStr.length());
i::Handle<i::String> varIStr = i::Isolate::Current()->factory()->NewStringFromAscii(tmpVar, i::TENURED);

// Now hunt down the stack frame of interest, be sure to consider my remarks above
i::StackFrameLocator sfl;
// Comment from the code: The caller must guarantee that such a frame exists.
i::JavaScriptFrame* jsf = sfl.FindJavaScriptFrame(0);
// create some replacement
i::Vector<const char> tmp("there you go", 12);
i::Handle<i::String> insert = i::Isolate::Current()->factory()->NewStringFromAscii(tmp, i::TENURED);
i::Object* insertObj = insert->ToObjectChecked();

// by the help of JavaScriptFrame::Print I came up with this:
i::Object* fun = jsf->function();
if (fun->IsJSFunction()){
    i::Handle<i::ScopeInfo> scope_info(i::ScopeInfo::Empty());
    i::Handle<i::SharedFunctionInfo> shared((i::JSFunction::cast(fun))->shared());
    scope_info = i::Handle<i::ScopeInfo>(shared->scope_info());
    i::Object* script_obj = shared->script();
    if (script_obj->IsScript()) {
        int stack_locals_count = scope_info->StackLocalCount();
        for (int i = 0; i < stack_locals_count; i++) {
            if (scope_info->StackLocalName(i)->Equals(*varIStr)){
                // replace the value on the stack
                jsf->SetExpression(i,insertObj);
            }
        }
    }
}

关于c++ - 谷歌 V8 : access local variables in C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13007838/

相关文章:

C++:像 PHP 一样将大量数字存储在 float 中?

c++ - 如果我删除了 const,为什么这个使用 boost::shared_ptr 的调用不能在 C++ 中编译?

javascript - 为什么 JavaScript 循环不会溢出堆栈?

c++ - v8 WeakCallback 永远不会被调用

c++ - 使用 avr-gcc : uint8_t vs. uint16_t 隐式转换为 float

c++ - 极大整数的变量类型是什么?

c++ - 提高通过 ctypes 将数据从 Python 传递到 C(++) 的速度

javascript - Linux 下 node.js C++ 插件中的 undefined symbol ,为什么?

c++ - v8、libuv、nodejs、win32 api - 如何调用 EnumWindows 并回调调用 javascript 函数?

c++ - 在 node.js 绑定(bind)中实现继承