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.

Reply via email to