tychota / pyv8

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

Python dict holding python object access from JavaScript. #68

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

import PyV8

class NewClass(PyV8.JSClass):

    def __init__(self):
        pass        

class Global(PyV8.JSClass):

    def __init__(self):
        x = NewClass()
        self.python_dict = {"class" : x}

    def write(self, val):
        print val

with PyV8.JSContext(Global()) as ctx:

    ctx.eval(""" x = python_dict """)

    ctx.eval(""" write( x ) """)
    ctx.eval(""" write( x["class"] ) """)
    ctx.eval(""" write( x["class"] == x["class"] ) """)

What is the expected output? What do you see instead?
Expected: 

{'class': <__main__.NewClass object at 0x7f77b6419e90>}
<__main__.NewClass object at 0x7f77b6419e90>
True

Saw:
{'class': <__main__.NewClass object at 0x7f77b6419e90>}
<__main__.NewClass object at 0x7f77b6419e90>
False

What version of the product are you using? On what operating system?

Linux x86 -- PyV8 somewhere around release 315.

Please provide any additional information below.

None

Original issue reported on code.google.com by ATM1...@gmail.com on 12 Jan 2011 at 8:37

GoogleCodeExporter commented 9 years ago
I am actually seeing this as being a larger problem comparing objects not just 
with objects stored in python dictionary.

import PyV8

class NewClass(PyV8.JSClass):

    def __init__(self):
        pass        

class Global(PyV8.JSClass):

    def __init__(self):
        self.x = NewClass()

    def write(self, val):
        print val

# Pure Python
obj = Global().x
print obj == obj

with PyV8.JSContext(Global()) as ctx:

    ctx.eval(""" write( x ) """)
    ctx.eval(""" write( x == x ) """)

Output is:

True
<__main__.NewClass object at 0x7fe058cffcd0>
False

Original comment by ATM1...@gmail.com on 12 Jan 2011 at 8:50

GoogleCodeExporter commented 9 years ago
I agree, it seems pyv8 should trace all the Javascript object base on its 
Python object. 

Original comment by flier...@gmail.com on 13 Jan 2011 at 2:52

GoogleCodeExporter commented 9 years ago
Hi, can you elaborate on what you mean by that.  I'm still having trouble 
figuring out what causes this problem.

Original comment by ATM1...@gmail.com on 13 Jan 2011 at 2:39

GoogleCodeExporter commented 9 years ago
Sorry, the root cause is pyv8 will wrap the Python object as a new Javascript 
object, it means, every time you get the Python attribute from Javascript side, 
a new Javascript object will be created. That's why your compare failed in 
Javascript, because there are two Javascript object mapping to same Python 
object.

So, I think pyv8 should maintain a large weak reference dictionary, which 
mapping the Python object to Javascript object, and return the same Javascript 
object when you get it from Javascript side.

Original comment by flier...@gmail.com on 13 Jan 2011 at 2:45

GoogleCodeExporter commented 9 years ago
Thanks for explaining that... it actually answers a lot of other questions I 
had.  I feel that would be a great improvement, and if I am not 
misunderstanding it should also improve performance (although I don't know the 
performance impact between creating a new js object vs storing and retrieving 
it).    

Original comment by ATM1...@gmail.com on 13 Jan 2011 at 3:24

GoogleCodeExporter commented 9 years ago
I have finished a prototype, which will trace all the Javascript object in the 
context global object, and return the cached Javascript object when Javascript 
code try to access the same Python object. 

Please verify the issue with SVN trunk code after r327. 

Notes: I haven't use any lock to protect the living object map, because one 
context should be used in same thread. This assumption may introduce a new 
crash.

Original comment by flier...@gmail.com on 13 Jan 2011 at 5:03