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.

Reply via email to