diggershort / pyv8

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

calling a javascript function from python, with a javascript argument that contains a python object, leads to that python object not being freed #193

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
Run the following code:

import weakref
import gc

import PyV8

tracks = {} #map weakref id to (weakref, description)
def tracked_deleted(r):
    _, descr = tracks[id(r)]
    print ("Tracked object '%s' just deleted." % (descr,))
    del tracks[id(r)]
def track(o, descr=""):
    r = weakref.ref(o, tracked_deleted)
    tracks[id(r)] = (r, "%s:%s" % (o.__class__.__name__, descr))
    return o

class PyObj(object):
    def __init__(self, name):
        track(self, name)

class Global(object):
    def Obj(self, name):
        return PyObj(name)

    def callWith(self, blah, f):        
        f(blah)

def run_case(name, js, cleanup):
    print "\nCase %s:" % (name,)
    ctxt = PyV8.JSContext(Global())

    with ctxt:
        ctxt.eval(js)

        print "  V8 cleanup"
        ctxt.eval(cleanup)
        print "  V8 gc"
        PyV8.JSEngine.collect()
        print "  Py gc"
        gc.collect()
        print "  V8 gc"
        PyV8.JSEngine.collect()
        print "  Py gc"
        gc.collect()
        print "  Py gc.garbage:", gc.garbage

#------------------

run_case("call_with_py_ok", """
    callWith(Obj('one'), function () {});
""", """
""")

run_case("call_with_py_in_js_from_js_ok", """
    function jsCallWith(obj, f) {
        f(obj);
    }
    jsCallWith({x: Obj('one')}, function () {});
""", """
""")

run_case("call_with_py_in_js_from_py_fail", """
    callWith({x: Obj('one')}, function () {});
""", """
""")

run_case("failed_workaround", """
    var durf = {x: Obj('one')};
    callWith(durf, function () {});
""", """
durf = null;
""")

run_case("successful_workaround", """
    var durf = {x: Obj('one')};
    callWith(durf, function () {});
""", """
durf.x = null;
durf = null;
""")

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

I expect all 5 cases to have the tracked object deleted. However, the 
"call_with_py_in_js_from_py" and "failed_workaround" cases don't free the 
tracked object, even though it's no longer reachable.

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

PyV8 r443 , Python 2.6.6, Windows 7

Please provide any additional information below.

Original issue reported on code.google.com by csaft...@gmail.com on 21 Jul 2013 at 9:34

Attachments:

GoogleCodeExporter commented 8 years ago

Original comment by flier...@gmail.com on 14 Aug 2013 at 6:54