Mercurial > pymonkey
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; |