Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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 this issue May 31, 2015 · 1 comment

Comments

@GoogleCodeExporter
Copy link

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:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant