[v8-users] Re: Is there any way to create a Handle from a Handle?

Mon, 02 Mar 2009 13:11:00 -0800


On Mar 2, 9:18 am, Alex Iskander <[email protected]> wrote:
> You may be able to use this to call Context::New(0, GlobalTemplate,  
> GlobalObject);
>
> Where GlobalObject is the object passed to evalcx.

Thanks, Alex.

That seems to do two things:
1. the code executes in a new context with no globals.
2. the object passed to evalcx is set to null. (!?)

Here's my code:

// the c++ function
static v8::Handle<v8::Value> EvalCX (const v8::Arguments& args)
{
        v8::HandleScope handlescope;
        v8::String::Utf8Value code(args[0]);
        v8::Local<v8::Object> sandbox = args[1]->ToObject();
        v8::Handle<v8::String> source = v8::String::New(*code);

        // Create a new execution environment for sandbox
        // problem here.
        v8::Handle<v8::Context> context = v8::Context::New(NULL,
Handle<ObjectTemplate>(), sandbox);

        // Enter the newly created execution environment.
        v8::Context::Scope context_scope(context);

        v8::Handle<v8::Script> script = v8::Script::Compile(source,
v8::String::New("evalcx"));
        if (script.IsEmpty()) return v8::ThrowException(v8::String::New
("Error parsing script"));

        // destroys the sandbox object!?
        v8::Handle<v8::Value> result = script->Run();
        if (result.IsEmpty()) return v8::ThrowException(v8::String::New
("Error running script"));

        return result;
}

// the binding to global in main()
global->Set(v8::String::New("evalcx"), v8::FunctionTemplate::New
(EvalCX)->GetFunction());

// the js
code = "foo = 1; bar = 2;";
foo = 2;
o = { foo : 0 };
evalcx(code, obj);
print( o.foo ); // expected: 1. actual: error, o is null
print( o.bar ); // expected: 2. actual: error, o is null
print( foo ); // expected: 2. actual: 2
print( bar ); // expected: undefined. actual: undefined

So, it looks like it's taking the code out of the caller's global
context, and putting it into a new context.  That's great. However,
it's also destroying the object that gets passed in, rather than
modifying it.



>
> However, it may not work; I'm not certain what would happen if you  
> pass an object belonging to another context as a global object of a  
> new context.
>
> So, plan B might be to manually copy the items from your global object  
> passed to evalcx to the global object for your new context.
>
> I hope that helps,
>
> Alex
>
> On Mar 2, 2009, at 11:05 AM, Isaac Z. Schlueter wrote:
>
>
>
>
>
> > Thanks, Stephan.
>
> > It looks like what you're doing will execute the code and set "this"
> > to the object in question.
>
> > However, what I'd really like to do is execute code and set a given
> > object as the global scope.  Here's an example with some code:
>
> > var code = "var foo = 'bar';";
> > var obj = { foo : "baz" };
> > evalcx( code, obj ); // execute code using "obj" as the global object
> > print( obj.foo ); // prints "bar"
>
> > Unless I'm misreading your example, what you're describing will work
> > in this case:
>
> > var code = "this.foo = 'bar';";
> > var obj = { foo : "baz" };
>
> > But, I can already do that from JS like so:
>
> > (new Function(code)).call(obj);
>
> > If I could eval code in an arbitrary global scope within Javascript,
> > which did not have any access to the global scope, then it would be
> > possible to implement a capability-based security model.
>
> > Also, it would make it possible to load and execute many different
> > scripts in a row without having to "clean up" the globals that each
> > one might create.  After being evaluated, the temporary global scope
> > could be discarded, and would be garbage collected normally.
>
> > For example, let's say you have a fastcgi handler written in
> > Javascript, which reads and evals the SCRIPT_FILENAME file.  The
> > problem is that, since the evaled code shares a global scope with the
> > fcgi handler, it also shares a global scope with *every other script
> > loaded by that handler.*  That means that every global variable is
> > persistent in memory, and only gets garbage collected when you restart
> > the server.  Not ideal! :)
>
> > --
> > Isaac Z. Schlueter
>
> > On Mar 1, 5:06 pm, Stephan Beal <[email protected]> wrote:
> >> On Mar 2, 1:34 am, "Isaac Z. Schlueter" <[email protected]> wrote:
>
> >>> I'm trying to write a function that will execute a bit of Javascript
> >>> within an arbitrary global scope.  Something like the "evalcx"
> >>> function in the Spidermonkey shell.
>
> >>> I've got a function defined and exposed to the Javascript that takes
> >>> an object as an argument, and stores it as a Handle<Object>.  
> >>> However,
> >>> in order to create a new execution context, I need a
> >>> Handle<ObjectTemplate>.
>
> >> Do you need a new Context, or just an object to eval the code in? If
> >> you just need an Object to execute the code in...
>
> >> They way i ended up doing this was getting the 'eval' function from  
> >> my
> >> local object, then using Call() on that Function object:
>
> >>         TryCatch tryer;
> >>         Local<Value> rv;
> >>         Local<Function> eval = Function::Cast( *(db->jsobj-
> >> >Get(String::New
> >> ("eval"))) );
> >> // ^^^^^ db->jsobj is my context object
> >>         for( int i = 0; i < argc; ++i )
> >>         {
> >>             char const * cp = reinterpret_cast<char const *>
> >> ( sqlite3_value_text( argv[i] ) );
> >>             if( ! cp || !*cp ) continue;
> >>             Local<Value> arg = String::New( cp,  
> >> sqlite3_value_bytes( argv
> >> [i] ) );
> >>             rv = eval->Call( db->jsobj, 1, &arg );
> >> // ^^^^ that will, in theory, eval the code in the context of db-
> >> >jsobj
>
> >>             if( rv.IsEmpty() )
> >>             {
> >>                 std::string  
> >> err( CastFromJS<std::string>( tryer.Exception() ) );
> >>                 sqlite3_result_text( context, err.c_str(),  
> >> static_cast<int>(err.size
> >> ()), SQLITE_TRANSIENT );
> >>                 return;
> >>             }
> >>         }
>
> Alex Iskander
> Web and Marketing
> TPSi
--~--~---------~--~----~------------~-------~--~----~
v8-users mailing list
[email protected]
http://groups.google.com/group/v8-users
-~----------~----~----~----~------~----~------~--~---

Reply via email to