comparison 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
comparison
equal deleted inserted replaced
21:fc04e5f1c675 22:988a8998c75f
1 #include "object.h" 1 #include "object.h"
2 #include "runtime.h" 2 #include "runtime.h"
3 #include "utils.h"
3 4
4 JSClass PYM_JS_ObjectClass = { 5 JSClass PYM_JS_ObjectClass = {
5 "PymonkeyObject", JSCLASS_GLOBAL_FLAGS, 6 "PymonkeyObject", JSCLASS_GLOBAL_FLAGS,
6 JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, 7 JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
7 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub, 8 JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
9 }; 10 };
10 11
11 static void 12 static void
12 PYM_JSObjectDealloc(PYM_JSObject *self) 13 PYM_JSObjectDealloc(PYM_JSObject *self)
13 { 14 {
14 // JS_RemoveRoot() always returns JS_TRUE, so don't 15 if (self->weakrefList)
15 // bother checking its return value. 16 PyObject_ClearWeakRefs((PyObject *) self);
16 17
17 if (self->obj) { 18 if (self->obj) {
19 if (PyDict_DelItem(self->runtime->objects,
20 self->uniqueId) == -1)
21 PySys_WriteStderr("WARNING: PyDict_DelItem() failed.\n");
22 Py_DECREF(self->uniqueId);
23 self->uniqueId = NULL;
24
25 // JS_RemoveRoot() always returns JS_TRUE, so don't
26 // bother checking its return value.
18 JS_RemoveRootRT(self->runtime->rt, &self->obj); 27 JS_RemoveRootRT(self->runtime->rt, &self->obj);
19 self->obj = NULL; 28 self->obj = NULL;
20 } 29 }
21 30
22 Py_DECREF(self->runtime); 31 if (self->runtime) {
23 self->runtime = NULL; 32 Py_DECREF(self->runtime);
33 self->runtime = NULL;
34 }
24 } 35 }
25 36
26 PyTypeObject PYM_JSObjectType = { 37 PyTypeObject PYM_JSObjectType = {
27 PyObject_HEAD_INIT(NULL) 38 PyObject_HEAD_INIT(NULL)
28 0, /*ob_size*/ 39 0, /*ob_size*/
49 /* tp_doc */ 60 /* tp_doc */
50 "JavaScript Object.", 61 "JavaScript Object.",
51 0, /* tp_traverse */ 62 0, /* tp_traverse */
52 0, /* tp_clear */ 63 0, /* tp_clear */
53 0, /* tp_richcompare */ 64 0, /* tp_richcompare */
54 0, /* tp_weaklistoffset */ 65 /* tp_weaklistoffset */
66 offsetof(PYM_JSObject, weakrefList),
55 0, /* tp_iter */ 67 0, /* tp_iter */
56 0, /* tp_iternext */ 68 0, /* tp_iternext */
57 0, /* tp_methods */ 69 0, /* tp_methods */
58 0, /* tp_members */ 70 0, /* tp_members */
59 0, /* tp_getset */ 71 0, /* tp_getset */
67 0, /* tp_new */ 79 0, /* tp_new */
68 }; 80 };
69 81
70 PYM_JSObject *PYM_newJSObject(PYM_JSContextObject *context, 82 PYM_JSObject *PYM_newJSObject(PYM_JSContextObject *context,
71 JSObject *obj) { 83 JSObject *obj) {
84 jsid uniqueId;
85 if (!JS_GetObjectId(context->cx, obj, &uniqueId)) {
86 PyErr_SetString(PYM_error, "JS_GetObjectId() failed");
87 return NULL;
88 }
89 PyObject *pyUniqueId = PyLong_FromLong(uniqueId);
90 if (pyUniqueId == NULL)
91 return NULL;
92
93 PYM_JSRuntimeObject *runtime = context->runtime;
94 PyObject *cachedObject = PyDict_GetItem(runtime->objects,
95 pyUniqueId);
96 if (cachedObject) {
97 cachedObject = PyWeakref_GetObject(cachedObject);
98 Py_INCREF(cachedObject);
99 Py_DECREF(pyUniqueId);
100 return (PYM_JSObject *) cachedObject;
101 }
102
72 PYM_JSObject *object = PyObject_New(PYM_JSObject, 103 PYM_JSObject *object = PyObject_New(PYM_JSObject,
73 &PYM_JSObjectType); 104 &PYM_JSObjectType);
74 if (object == NULL) 105 if (object == NULL) {
106 Py_DECREF(pyUniqueId);
75 return NULL; 107 return NULL;
108 }
109
110 object->runtime = NULL;
111 object->obj = NULL;
112 object->uniqueId = NULL;
113 object->weakrefList = NULL;
114
115 PyObject *weakref = PyWeakref_NewRef((PyObject *) object, NULL);
116 if (weakref == NULL) {
117 Py_DECREF(object);
118 Py_DECREF(pyUniqueId);
119 return NULL;
120 }
121
122 if (PyDict_SetItem(runtime->objects, pyUniqueId, weakref) == -1) {
123 Py_DECREF(weakref);
124 Py_DECREF(object);
125 Py_DECREF(pyUniqueId);
126 return NULL;
127 }
76 128
77 object->runtime = context->runtime; 129 object->runtime = context->runtime;
78 Py_INCREF(object->runtime); 130 Py_INCREF(object->runtime);
79 131
80 object->obj = obj; 132 object->obj = obj;
133 object->uniqueId = pyUniqueId;
81 134
82 JS_AddNamedRootRT(object->runtime->rt, &object->obj, 135 JS_AddNamedRootRT(object->runtime->rt, &object->obj,
83 "Pymonkey-Generated Object"); 136 "Pymonkey-Generated Object");
84 137
85 return object; 138 return object;