Mercurial > pymonkey
diff object.c @ 22:988a8998c75f
JS objects reflected into Python are now identity-preserving, though the implementation for this is pretty bad right now.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Sun, 28 Jun 2009 21:49:07 -0700 |
parents | fc04e5f1c675 |
children | 951ad1b15587 |
line wrap: on
line diff
--- a/object.c Sun Jun 28 20:40:18 2009 -0700 +++ b/object.c Sun Jun 28 21:49:07 2009 -0700 @@ -1,5 +1,6 @@ #include "object.h" #include "runtime.h" +#include "utils.h" JSClass PYM_JS_ObjectClass = { "PymonkeyObject", JSCLASS_GLOBAL_FLAGS, @@ -11,16 +12,26 @@ static void PYM_JSObjectDealloc(PYM_JSObject *self) { - // JS_RemoveRoot() always returns JS_TRUE, so don't - // bother checking its return value. + if (self->weakrefList) + PyObject_ClearWeakRefs((PyObject *) self); if (self->obj) { + if (PyDict_DelItem(self->runtime->objects, + self->uniqueId) == -1) + PySys_WriteStderr("WARNING: PyDict_DelItem() failed.\n"); + Py_DECREF(self->uniqueId); + self->uniqueId = NULL; + + // JS_RemoveRoot() always returns JS_TRUE, so don't + // bother checking its return value. JS_RemoveRootRT(self->runtime->rt, &self->obj); self->obj = NULL; } - Py_DECREF(self->runtime); - self->runtime = NULL; + if (self->runtime) { + Py_DECREF(self->runtime); + self->runtime = NULL; + } } PyTypeObject PYM_JSObjectType = { @@ -51,7 +62,8 @@ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ + /* tp_weaklistoffset */ + offsetof(PYM_JSObject, weakrefList), 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ @@ -69,15 +81,56 @@ PYM_JSObject *PYM_newJSObject(PYM_JSContextObject *context, JSObject *obj) { + jsid uniqueId; + if (!JS_GetObjectId(context->cx, obj, &uniqueId)) { + PyErr_SetString(PYM_error, "JS_GetObjectId() failed"); + return NULL; + } + PyObject *pyUniqueId = PyLong_FromLong(uniqueId); + if (pyUniqueId == NULL) + return NULL; + + PYM_JSRuntimeObject *runtime = context->runtime; + PyObject *cachedObject = PyDict_GetItem(runtime->objects, + pyUniqueId); + if (cachedObject) { + cachedObject = PyWeakref_GetObject(cachedObject); + Py_INCREF(cachedObject); + Py_DECREF(pyUniqueId); + return (PYM_JSObject *) cachedObject; + } + PYM_JSObject *object = PyObject_New(PYM_JSObject, &PYM_JSObjectType); - if (object == NULL) + if (object == NULL) { + Py_DECREF(pyUniqueId); return NULL; + } + + object->runtime = NULL; + object->obj = NULL; + object->uniqueId = NULL; + object->weakrefList = NULL; + + PyObject *weakref = PyWeakref_NewRef((PyObject *) object, NULL); + if (weakref == NULL) { + Py_DECREF(object); + Py_DECREF(pyUniqueId); + return NULL; + } + + if (PyDict_SetItem(runtime->objects, pyUniqueId, weakref) == -1) { + Py_DECREF(weakref); + Py_DECREF(object); + Py_DECREF(pyUniqueId); + return NULL; + } object->runtime = context->runtime; Py_INCREF(object->runtime); object->obj = obj; + object->uniqueId = pyUniqueId; JS_AddNamedRootRT(object->runtime->rt, &object->obj, "Pymonkey-Generated Object");