Google V8: access to local variables in C ++

Does anyone know how I can look for local variables in a nested function call from C ++? Consider the following example:

// eg a global variable in the browser var global = "global_value"; function foo(){ var global = "local_value"; myCppFunction("global", global); } foo(); 

Now my question is how, in the implementation of myCppFunction could I access the local variable of the "global" function (value NOT, this will be given by the second parameter) from "foo"?

 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' ? } 
+4
source share
1 answer

I managed to find it on my own. See the example below how to find the value on the stack (and also replace it - here is an example of a string variable).

Two comments in advance:

  • I have not tested this for unwanted behavior, except from my most used cases, when I use it in my master's thesis - there may be dragons.
  • I don’t know exactly why in my tests sfl.FindJavaScriptFrame(0) get the desired stack frame, but since it works regardless of the call depth, I suspect that the stack frame indexed to 0 is always the immediate frame of the caller (in my case, I know that I want just that).

And the code:

 // 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); } } } } 
+3
source

Source: https://habr.com/ru/post/1441232/


All Articles