Mercurial > pymonkey
diff object.c @ 70:b0360c0ed546
Factored the JS FunctionHolder class into the JS PymonkeyObject class, so that any PymonkeyObject can contain a private Python object if it needs to.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Mon, 27 Jul 2009 04:47:33 -0700 |
parents | f3ecf06a2851 |
children | 755af0a94c94 |
line wrap: on
line diff
--- a/object.c Sun Jul 26 16:44:12 2009 -0700 +++ b/object.c Mon Jul 27 04:47:33 2009 -0700 @@ -39,10 +39,72 @@ #include "runtime.h" #include "utils.h" +JSObject * +PYM_JS_newObject(JSContext *cx, PyObject *pyObject) +{ + JSObject *obj = JS_NewObject(cx, &PYM_JS_ObjectClass, NULL, NULL); + if (obj) { + if (!JS_SetReservedSlot(cx, obj, 0, PRIVATE_TO_JSVAL(pyObject))) + return NULL; + Py_XINCREF(pyObject); + } + return obj; +} + +JSBool +PYM_JS_setPrivatePyObject(JSContext *cx, JSObject *obj, PyObject *pyObject) +{ + JSClass *klass = JS_GET_CLASS(cx, obj); + if (klass != &PYM_JS_ObjectClass) { + JS_ReportError(cx, "Object is not an instance of PymonkeyObject"); + return JS_FALSE; + } + + PyObject *old; + if (!PYM_JS_getPrivatePyObject(cx, obj, &old)) + return JS_FALSE; + if (!JS_SetReservedSlot(cx, obj, 0, PRIVATE_TO_JSVAL(pyObject))) + return JS_FALSE; + Py_INCREF(pyObject); + Py_XDECREF(old); + return JS_TRUE; +} + +JSBool +PYM_JS_getPrivatePyObject(JSContext *cx, JSObject *obj, PyObject **pyObject) +{ + JSClass *klass = JS_GET_CLASS(cx, obj); + if (klass != &PYM_JS_ObjectClass) { + JS_ReportError(cx, "Object is not an instance of PymonkeyObject"); + return JS_FALSE; + } + + jsval val; + if (!JS_GetReservedSlot(cx, obj, 0, &val)) + return JS_FALSE; + *pyObject = (PyObject *) JSVAL_TO_PRIVATE(val); + return JS_TRUE; +} + +static void +PYM_JS_finalizeObject(JSContext *cx, JSObject *obj) +{ + PYM_PyAutoEnsureGIL gil; + PyObject *pyObject; + // TODO: What if this fails? + if (PYM_JS_getPrivatePyObject(cx, obj, &pyObject)) + Py_XDECREF(pyObject); +} + +// This one-size-fits-all JSClass is used for any JS objects created +// in Python. It can hold a reference to a Python object for as long as +// its parent JS object is accessible from JS-land. As soon as it's +// garbage collected by the JS interpreter, it releases its reference on +// the Python object. JSClass PYM_JS_ObjectClass = { - "PymonkeyObject", JSCLASS_GLOBAL_FLAGS, + "PymonkeyObject", JSCLASS_GLOBAL_FLAGS | JSCLASS_HAS_RESERVED_SLOTS(1), JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, - JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, + JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, PYM_JS_finalizeObject, JSCLASS_NO_OPTIONAL_MEMBERS };