How to specify script execution scope?

156 views
Skip to first unread message

Andrey Semashev

unread,
Jan 22, 2010, 3:15:54 AM1/22/10
to v8-users
Hi,

I'm trying to port my application (a VoiceXML interpreter) from
Mozilla SpiderMonkey to v8. For ones not familiar with VoiceXML, the
application allows to run JS scripts in one of the several nested
scopes, which are represented as objects. The scopes are session,
application, document and dialog, in order from outer to inner scopes.
Now, if a script is run in document scope, it can access variables and
functions from outer scopes unqualified, and all variables and
functions it defines are created as subobjects of the document scope.
When the scope is left, all its subobjects are deleted.

In SpiderMonkey, I can specify parent objects on their creation, so I
can create scope objects hierarchy with the API calls. Also, I can
specify an object, on which to execute the script, which allows to
execute it in the given scope. How can I achieve similar functionality
in v8?

A few words on what I have tried so far. I managed to construct the
scopes hierarchy by creating properties in the Object interface.
However, I could not figure out the way to specify these objects for
Script to execute on. I tried to wrap scripts in a "with" construct,
but although it solves the scopes visibility problem, it doesn't allow
to create variables in the current scope. For example, if I run this
script:

var a = new Object();
function foo() { return "hello"; }

in the document scope, I want document.a and document.foo objects to
be created. Wrapping it in a "with (document)" block doesn't give
that.

I'm sorry if I'm missing something obvious, I'm relatively new to v8
and JavaScript in general. Any suggestions would be welcome.

Flier Lu

unread,
Jan 22, 2010, 8:24:15 AM1/22/10
to v8-users
v8 provide the global object with Context::Global method, you should
wrap the document object first, and add it to the global object in the
entered context.

to wrap the document object, you must implement the named, indexed
property and call as function handler, and create the object with
ObjectTemplate

v8::HandleScope handle_scope;

v8::Handle<v8::ObjectTemplate> clazz = v8::ObjectTemplate::New();

clazz->SetNamedPropertyHandler(NamedGetter, NamedSetter, NamedQuery,
NamedDeleter, NamedEnumerator);
clazz->SetIndexedPropertyHandler(IndexedGetter, IndexedSetter,
IndexedQuery, IndexedDeleter, IndexedEnumerator);
clazz->SetCallAsFunctionHandler(Caller);

return v8::Persistent<v8::ObjectTemplate>::New(clazz);

if you could use python, it will like following code in pyv8 <http://
code.google.com/p/pyv8/>

from PyV8 import *

class Document(JSClass):
name = "flier"

def hello(self, s):
print "hello " + s

class Global(JSClass):
document = Document()

with JSContext(Global()) as ctxt:
ctxt.eval("document.hello(document.name)")

Andrey Semashev

unread,
Jan 22, 2010, 8:56:55 AM1/22/10
to v8-users
> v8 provide the global object with Context::Global method, you should
> wrap the document object first, and add it to the global object in the
> entered context.

That's right. I added the root scope in my hierarchy (which is
session) to this object. So I have this:

[global object] =
{
session :
{
application :
{
document :
{
dialog : {}
}
}
}
};

The problem is, I can't find any methods in the context to make
another object global (such as document in my example).

> to wrap the document object, you must implement the named, indexed
> property and call as function handler, and create the object with
> ObjectTemplate
>
>   v8::HandleScope handle_scope;
>
>   v8::Handle<v8::ObjectTemplate> clazz = v8::ObjectTemplate::New();
>
>   clazz->SetNamedPropertyHandler(NamedGetter, NamedSetter, NamedQuery,
> NamedDeleter, NamedEnumerator);
>   clazz->SetIndexedPropertyHandler(IndexedGetter, IndexedSetter,
> IndexedQuery, IndexedDeleter, IndexedEnumerator);
>   clazz->SetCallAsFunctionHandler(Caller);
>
>   return v8::Persistent<v8::ObjectTemplate>::New(clazz);

I don't understand. All scope objects are pure JS objects, they are
not native. Why do I need an ObjectTemplate? Or do you mean that I
have to create an artifical native object that would reroute all its
property access calls to the appropriate scope object of my hierarchy?

Flier Lu

unread,
Jan 22, 2010, 9:08:30 AM1/22/10
to v8-users
As I know, v8 doesn't provide any public API to change the global
object of context, but we could do it with javascript way, just set
the __proto__ property of global object to our global object.

http://code.google.com/p/pyv8/source/browse/trunk/src/Context.cpp#79

m_context->Global()->Set(v8::String::NewSymbol("__proto__"),
CPythonObject::Wrap(global));

you could check __proto__ for more detail <https://
developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/
Object/Proto>

Flier Lu

unread,
Jan 22, 2010, 9:11:00 AM1/22/10
to v8-users
Sorry, I'm misunderstand your requirement, if you could do it from
javascript side, you doesn't need any C code for global object, just
use 'this' keyword will be enough.

The ObjectTemplate and other things are all for the C or python
side :)

On 1月22日, 下午9时56分, Andrey Semashev <andrey.semas...@gmail.com> wrote:

Andrey Semashev

unread,
Jan 22, 2010, 9:21:51 AM1/22/10
to v8-users
BTW, this is how I create the needed scope hierarchy:

var Session = new Function();
var Application = new Function();
var Document = new Function();
var Dialog = new Function();

var session = new Session();
Application.prototype = session;

session.application = new Application();
Document.prototype = session.application;

session.application.document = new Document();
Dialog.prototype = session.application.document;

session.application.document.dialog = new Dialog();

Flier Lu

unread,
Jan 22, 2010, 9:31:47 AM1/22/10
to v8-users

So, what's your expected? As you know, any object you create in global
name space will be accessible as a property of global object.

Andrey Semashev

unread,
Jan 22, 2010, 9:39:06 AM1/22/10
to v8-users
Looks like the __proto__ trick works similarly to wrapping the script
in a "with" block. However, it looks better than wrapping, thanks for
the hint. One thing that bothers me is that it's not standard. Can I
be sure it won't disappear or change behavior in future revisions of
v8?

Andrey Semashev

unread,
Jan 22, 2010, 9:47:27 AM1/22/10
to v8-users
I'll explain more closely to the code. Let's assume my scope hierarchy
is initialized the way I presented in my post. I have this script:

var x = 10;

and I want to execute it in the document scope. So the sequence should
be like this:

[set the current scope to session.application.document]
v8::Script::Run(); // run the script
[restore scope to the root object]

so that then I have "typeof(session.application.document.x) ==
number", and "typeof(x) == undefined".

Flier Lu

unread,
Jan 22, 2010, 10:33:07 AM1/22/10
to v8-users
Ok, I think your problem is that you want to replace the global object
of context, right?

I suggest you could create the context with a customized global_object
that point to a stub object, which will redirect any getter/setter/
call to your document object later. Because any v8 javascript object
must belongs to a context, so, you could create a stub object from C
side, and create document object ASAP after create context, and set
the stub object redirect the remaining call.

class V8EXPORT Context {
/** Creates a new context. */
static Persistent<Context> New(
ExtensionConfiguration* extensions = 0,
Handle<ObjectTemplate> global_template = Handle<ObjectTemplate>
(),
Handle<Value> global_object = Handle<Value>());

The __proto__ doesn't work because for your scene.

vance huang

unread,
Mar 14, 2019, 1:04:22 PM3/14/19
to v8-users
Hi, Andrey:

I am having similar issue as you regarding how to implement the vxml scoping hierarchy using v8 (coming from old spidermonkey). Do you get this issue resolved? Any help/direction will  be really appreciated. Thanks.

Vance

Andrey Semashev

unread,
Mar 14, 2019, 1:16:36 PM3/14/19
to v8-u...@googlegroups.com, vance huang
No, I did not solve this problem. At the time, I was using Mozilla JS
engine and because of this problem stayed on it. I have moved away from
that project quite a few years ago, so I don't know if there were any
developments on this issue.
> --
> --
> v8-users mailing list
> v8-u...@googlegroups.com
> http://groups.google.com/group/v8-users
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "v8-users" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/v8-users/whmYtQafCjs/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> v8-users+u...@googlegroups.com
> <mailto:v8-users+u...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.

vance huang

unread,
Mar 14, 2019, 2:11:18 PM3/14/19
to v8-users
Ok, thanks a lot for your quick response. Appreciate it.

Yang Guo

unread,
Mar 18, 2019, 5:22:04 AM3/18/19
to v8-users
You can use v8::Compiler::CompileFunctionInContext. That way, you can pass in context extension objects.

Yang

muhammad sami

unread,
Mar 26, 2019, 8:43:55 AM3/26/19
to v8-users
Hi vance 

I am having similar issue as you regarding how to implement the vxml scoping hierarchy using v8. Do you get this issue resolved? Any help/direction will  be really appreciated. Thanks

vance huang

unread,
Mar 26, 2019, 11:01:45 AM3/26/19
to v8-users
Hi, Muhammad:

Sorry I haven't been able to get back to this project so there is no progress yet. Have you tried the v8::Compiler::CompileFunctionInContext recommended by Yang? I haven't tried it so not sure if that will help and not sure how to use it. May take awhile for me to get back to this so if you have more question regarding the above function, you may ask Yang and hopefully we will overcome this issue. Good luck!!

Vance

muhammad sami

unread,
Mar 28, 2019, 5:39:56 AM3/28/19
to v8-users
Hi, Vance :
  
Thanks for your appreciated response, I didn't try v8::Compiler::CompileFunctionInContext yet.  I'm trying to achieve scoping now using spidermonkey I  hope it  works out.

muhammad sami

unread,
Mar 31, 2019, 10:44:07 AM3/31/19
to v8-users
Hi 
Andrey How did you achieve scoping in spidermonkey in first place, knowing that I'm using spidermonkey 45.
Reply all
Reply to author
Forward
0 new messages