Alex,
Thanks for the insight. That's very helpful.
I do have complete control over the code calling evalcx. I also can
assume that I have more-or-less complete control over the code being
evaluated, though that might be used by someone who is not quite as
savvy about the problems with leaking contexts.
Here's the application:
A fastcgi script, written in Javascript, loads the file that was
requested by the user. It interprets that file's syntax, converting
it to "regular" Javascript. Then it evaluates the script server-side,
and outputs the results.
So, I'm actually not too concerned with exposing the global object,
since all the script is in-house, so to speak. However, I'm quite
concerned about accidentally creating a global variable (ie, if I
misplace a "var" somewhere), and having that variable stick around
until the server is restarted (since the script and the fcgi share a
context.)
> var obj = {"foo": this}; //passing the global scope
> evalcx(code, obj); //we just gave the other context our global scope.
That's actually fine, at least for my application. You can enable
another script to use your global context, but you still can't "get
outside the box". I can give you keys to my house, but I can't steal
the keys to your house without you giving them to me. And while you
might do "foo.blah = 1", you'll at least *know* that you're creating a
persistent shared global variable, rather than just doing it by
accident.
> A possibly simpler and more secure alternative might be to pass the
> object back. Your JavaScript code would then look like:
>
> obj = evalcx(code, obj);
That would be interesting. Couldn't your code just do something like
"return this;" to accomplish the same thing? If evalcx worked that
way, then it would not be possible to use it to return a computation
or something. I suppose it could create a new global which would be
accessible via "obj" in this case. Maybe that's not such a big deal,
I don't know. I haven't thought about the ideal return value too
much. Knowing about success or failure would be handy.
> Also, just wondering, why do they need to be global variables?
Because that's what happens when you're writing code late at night
trying out a new idea, and you forget to put "var" in front of
something. ;)
It's not that globals are wonderful, per se, but rather that
supporting globals means that the system will not be able to spring
random leaks and have variables that never get garbage collected.
Some other ideas that I've thrown around:
1. In js-land, create a single read-only object on the global scope
that is shared between scripts. After evaling, delete any new globals
that show up.
2. In c-land, create a new empty Handle<ObjectTemplate> like I'm
doing, and then loop through the properties of the supplied object,
and Set them on the ObjectTemplate as well.
However, it seems like there must be a better way. After all, the
function prototypes are ObjectTemplates (well, PrototypeTemplates,
which are convertible), and they can be set from a js object, right?
--i