marylinh / pyv8

Automatically exported from code.google.com/p/pyv8
0 stars 0 forks source link

Fatal: Refering to custom global object using 'this' keyword #1

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
This code fails on Linux:

class Global(object):pass
engine = PyV8.JSEngine(Global())
engine.eval("this")

Producing:
terminate called after throwing an instance of
'boost::python::error_already_set'
Aborted

If I don't use the custom global object, it succeeds.

Original issue reported on code.google.com by joshua.k...@gmail.com on 17 Feb 2009 at 11:19

GoogleCodeExporter commented 9 years ago
This actually is the case when referencing any python object directly, without 
either
calling a function or accessing a basic type.  I'm guessing that the javascript
interpreter doesn't know how to deal with a python object as a value by 
default, but
can safely scan properties on it.

Original comment by joshua.k...@gmail.com on 18 Feb 2009 at 12:09

GoogleCodeExporter commented 9 years ago
sure, v8 use javascript way to handle the 'this' keyword which refer to an 
implicit 
object, but the PyV8's python wrapper only support the python way :)

For example, javascript think every object have some instance methods, such as 
toString, valueOf etc. So, we need provide similar support for compatibility.

function SetupObject() {
  // Setup non-enumerable functions on the Object.prototype object.
  InstallFunctions($Object.prototype, DONT_ENUM, $Array(
    "toString", ObjectToString,
    "toLocaleString", ObjectToLocaleString,
    "valueOf", ObjectValueOf,
    "hasOwnProperty", ObjectHasOwnProperty,
    "isPrototypeOf", ObjectIsPrototypeOf,
    "propertyIsEnumerable", ObjectPropertyIsEnumerable,
    "__defineGetter__", ObjectDefineGetter,
    "__lookupGetter__", ObjectLookupGetter,
    "__defineSetter__", ObjectDefineSetter,
    "__lookupSetter__", ObjectLookupSetter
  ));
}

Original comment by flier...@gmail.com on 18 Feb 2009 at 3:36

GoogleCodeExporter commented 9 years ago
just give a fast workaround, return the object itself from JSEngine.eval. So, 
we 
don't need use javascript's toString() or valueOf() method to convert it as 
string.

    def testThis(self):
        class GlobalNamespace(object): 
            version = 1.0

        engine = JSEngine(GlobalNamespace())

        self.assertEquals("[object global]", str(engine.eval("this")))

        self.assertEquals(1.0, float(engine.eval("this.version")))  

Please check and verify it at SVN build, thanks

Original comment by flier...@gmail.com on 18 Feb 2009 at 4:59

GoogleCodeExporter commented 9 years ago
Now, it support a more friendly style base on a python concrete class, please 
check PyV8.py for more detail

class JSClass(object):    
    def toString(self):
        "Returns a string representation of an object."
        return "[object %s]" % self.__class__.__name__

class TestEngine(unittest.TestCase):
    def testObjectBuildInMethods(self):
        class Global(JSClass):
            version = 1.0

        engine = JSEngine(Global())

        try:
            self.assertEquals("[object Global]", str(engine.eval("this.toString()")))

Original comment by flier...@gmail.com on 18 Feb 2009 at 11:15

GoogleCodeExporter commented 9 years ago
Looking good!  Onward and upward.

Original comment by joshua.k...@gmail.com on 18 Feb 2009 at 7:44