Function::Call only allows you to set the receiver, not rebind the function to a different context.
You should be able to access number1 using this.number1. You could pass the script in as a string and compile it for the target context for example. On Thu, Jul 21, 2016 at 11:58 PM Bryan Grim <[email protected]> wrote: > I have a need to execute functions in completely isolated contexts. I'm > not having much luck, though. My context's global object does not seem > accessible to a call to my javascript function. > > Using the shell.cc example, I added these callbacks: > > void SetupContext(const v8::FunctionCallbackInfo<v8::Value>& args); > void CallInContext(const v8::FunctionCallbackInfo<v8::Value>& args); > void PrintGlobalContext(const v8::FunctionCallbackInfo<v8::Value>& args); > > > Implemented like so: > > void SetupContext(const v8::FunctionCallbackInfo<v8::Value>& args) > { > //Get the default isolate > v8::Isolate* pIsolate = args.GetIsolate(); > //create a stack allocated handle scope > v8::HandleScope handle_scope(pIsolate); > //Create the global template > > if (args.Length() < 2) > { > args.GetIsolate()->ThrowException( > v8::String::NewFromUtf8(args.GetIsolate(), "Not enough > parameters for call. Correct format: ([ontext name], [script to run])", > v8::NewStringType::kNormal).ToLocalChecked()); > return; > } > v8::String::Utf8Value argContextName(args[0]); > v8::String::Utf8Value argContextGlobals(args[1]); > std::string strScriptName = ToCString(argContextName); > if (!sContextMap[strScriptName].IsEmpty()) > { > // assume it's not an error for, as we should be able to continue > on no problem. > return; > } > > v8::Local<v8::ObjectTemplate> global_template = v8::ObjectTemplate:: > New(); > //Create the context > v8::Local<v8::Context> context = v8::Context::New(pIsolate, NULL, > global_template); > v8::Context::Scope context_scope(context); > > v8::Local<v8::String> scriptName = v8::String::NewFromUtf8(pIsolate, * > argContextName, v8::NewStringType::kNormal).ToLocalChecked(); > v8::Local<v8::String> source = v8::String::NewFromUtf8(pIsolate, * > argContextGlobals, v8::NewStringType::kNormal).ToLocalChecked(); > > bool success = ExecuteString(pIsolate, source, scriptName, false, true > ); > > if (success) > { > if (sContextMap[strScriptName].IsEmpty()) > { > v8::Local<v8::Value> security = v8::String::NewFromUtf8( > pIsolate, "Security!", v8::NewStringType::kNormal).ToLocalChecked(); > context->SetSecurityToken(security); > sContextMap[strScriptName].Reset(pIsolate, context); > } > args.GetReturnValue().Set( > v8::String::NewFromUtf8(args.GetIsolate(), "Awesome!!" > , > v8::NewStringType::kNormal).ToLocalChecked()); > } > else > { > args.GetReturnValue().Set( > v8::String::NewFromUtf8(args.GetIsolate(), "Totally Not > Awesome...", > v8::NewStringType::kNormal).ToLocalChecked()); > > } > } > > As you can see, I keep the newly created contexts in a map: static > std::map<std::string, v8::Persistent<v8::Context>> sContextMap; They are > created when this script runs: > setupContext("one","var number1 = 4;"); > > I want to be able to call a function within this new context, by running > this: > var num3 = 0; > var num4 = 0; > callInContext("one", function (outerNum1, outerNum2) { var num2 = 3; > outerNum1 = number1; outerNum2 = outerNum1 + num2; }, num3, num4); > > The CallinContext function looks like this: > > void CallInContext(const v8::FunctionCallbackInfo<v8::Value>& args) > { > //Get the default isolate > v8::Isolate* pIsolate = args.GetIsolate(); > //create a stack allocated handle scope > v8::HandleScope handle_scope(pIsolate); > > if (args.Length() < 4) > { > args.GetIsolate()->ThrowException( > v8::String::NewFromUtf8(args.GetIsolate(), "Not enough > parameters for call.", > v8::NewStringType::kNormal).ToLocalChecked()); > return; > } > > int argIndex = 0; > std::string ruleContext = ToCString(v8::String::Utf8Value(args[ > argIndex])); > v8::String::Utf8Value argContext(args[argIndex]); > auto context = sContextMap[ruleContext].Get(pIsolate); > > if (!context.IsEmpty()) > { > v8::Context::Scope cs(context); > > auto scriptFun = v8::Local<v8::Function>::Cast(args[1]); > const int argc = 2; > v8::Local<v8::Value> argv[argc]; > argv[0] = args[2]; > argv[1] = args[3]; > > auto result = scriptFun->Call(context->Global(), argc, argv); > > > } > } > > When I run it all, though, I get a complaint that "number1 is not defined." > > If I run this script, though > printGlobalContext("one"); > > and trigger this function: > void PrintGlobalContext(const v8::FunctionCallbackInfo<v8::Value>& args) { > bool first = true; > for (int i = 0; i < args.Length(); i++) > { > v8::HandleScope handle_scope(args.GetIsolate()); > if (first) { > first = false; > } > else { > printf(" "); > } > v8::String::Utf8Value str(args[i]); > const char* cstr = ToCString(str); > > auto context = sContextMap[cstr].Get(args.GetIsolate()); > if (!context.IsEmpty()) > { > v8::Context::Scope cs(context); > auto global = context->Global(); > v8::Local<v8::Array> keys = global->GetOwnPropertyNames(); > uint32_t length = keys->Length(); > for (uint32_t i = 0; i < length; ++i) { > v8::Local<v8::Value> key = keys->Get(i); > v8::Local<v8::String> key_str(key->ToString()); > v8::String::Utf8Value tag(key_str); > v8::String::Utf8Value val(global->Get(key_str)); > > printf("%s: %s\n", ToCString(tag), ToCString(val)); > } > } > } > printf("\n"); > fflush(stdout); > } > > It prints: > number1: 4 > > -- > -- > v8-users mailing list > [email protected] > http://groups.google.com/group/v8-users > --- > You received this message because you are subscribed to the Google Groups > "v8-users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- -- v8-users mailing list [email protected] http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
