changeset 62:2b5696b91b01

Fixed a bug whereby some objects wouldn't be finalized when a runtime was destroyed.
author Atul Varma <varmaa@toolness.com>
date Sat, 25 Jul 2009 22:51:20 -0700
parents 1506350991d4
children f3ecf06a2851
files runtime.c runtime.h test_pymonkey.py
diffstat 3 files changed, 33 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/runtime.c	Sat Jul 25 16:14:03 2009 -0700
+++ b/runtime.c	Sat Jul 25 22:51:20 2009 -0700
@@ -47,6 +47,7 @@
   self = (PYM_JSRuntimeObject *) type->tp_alloc(type, 0);
   if (self != NULL) {
     self->rt = NULL;
+    self->cx = NULL;
     self->objects.ops = NULL;
 
     if (!JS_DHashTableInit(&self->objects,
@@ -65,6 +66,13 @@
         PyErr_SetString(PYM_error, "JS_NewRuntime() failed");
         type->tp_dealloc((PyObject *) self);
         self = NULL;
+      } else {
+        self->cx = JS_NewContext(self->rt, 8192);
+        if (!self->cx) {
+          PyErr_SetString(PYM_error, "JS_NewContext() failed");
+          type->tp_dealloc((PyObject *) self);
+          self = NULL;
+        }
       }
     }
   }
@@ -80,6 +88,13 @@
     self->objects.ops = NULL;
   }
 
+  if (self->cx) {
+    // Note that this will also force GC of any remaining objects
+    // in the runtime.
+    JS_DestroyContext(self->cx);
+    self->cx = NULL;
+  }
+
   if (self->rt) {
     JS_DestroyRuntime(self->rt);
     self->rt = NULL;
--- a/runtime.h	Sat Jul 25 16:14:03 2009 -0700
+++ b/runtime.h	Sat Jul 25 22:51:20 2009 -0700
@@ -44,6 +44,7 @@
 typedef struct {
   PyObject_HEAD
   JSRuntime *rt;
+  JSContext *cx;
   JSDHashTable objects;
 } PYM_JSRuntimeObject;
 
--- a/test_pymonkey.py	Sat Jul 25 16:14:03 2009 -0700
+++ b/test_pymonkey.py	Sat Jul 25 22:51:20 2009 -0700
@@ -56,6 +56,23 @@
         cx.gc()
         self.assertEqual(ref(), None)
 
+    def testJsWrappedPythonFuncIsGCdAtRuntimeDestruction(self):
+        def define(cx, obj):
+            def func(cx, this, args):
+                return u'func was called'
+            jsfunc = cx.new_function(func, func.__name__)
+            cx.define_property(obj, func.__name__, jsfunc)
+            return weakref.ref(func)
+        rt = pymonkey.Runtime()
+        cx = rt.new_context()
+        obj = cx.new_object()
+        cx.init_standard_classes(obj)
+        ref = define(cx, obj)
+        del rt
+        del cx
+        del obj
+        self.assertEqual(ref(), None)
+
     def testJsWrappedPythonFuncPassesContext(self):
         contexts = []