Mercurial > pymonkey
comparison function.c @ 37:d4efcbb06964
Added a new PYM_JSFunction type, PYM_JSContext.define_property(), and PYM_JSContext.new_function(). Also fixed a memory leak.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Thu, 02 Jul 2009 22:42:31 -0700 |
parents | |
children | 9103afca7386 |
comparison
equal
deleted
inserted
replaced
36:04a6e9a67ae5 | 37:d4efcbb06964 |
---|---|
1 #include "function.h" | |
2 #include "utils.h" | |
3 | |
4 static void | |
5 PYM_JSFunctionDealloc(PYM_JSFunction *self) | |
6 { | |
7 // TODO: What if there's still a reference to the callable in | |
8 // JS-land? | |
9 if (self->callable) { | |
10 Py_DECREF(self->callable); | |
11 self->callable = NULL; | |
12 } | |
13 PYM_JSObjectType.tp_dealloc((PyObject *) self); | |
14 } | |
15 | |
16 static JSBool | |
17 dispatchJSFunctionToPython(JSContext *cx, | |
18 JSObject *obj, | |
19 uintN argc, | |
20 jsval *argv, | |
21 jsval *rval) | |
22 { | |
23 jsval callee = JS_ARGV_CALLEE(argv); | |
24 jsval jsCallable; | |
25 if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(callee), 0, &jsCallable)) { | |
26 JS_ReportError(cx, "JS_GetReservedSlot() failed."); | |
27 return JS_FALSE; | |
28 } | |
29 PyObject *callable = (PyObject *) JSVAL_TO_PRIVATE(jsCallable); | |
30 | |
31 // TODO: Convert args and 'this' parameter. | |
32 PyObject *args = PyTuple_New(0); | |
33 if (args == NULL) { | |
34 JS_ReportOutOfMemory(cx); | |
35 return JS_FALSE; | |
36 } | |
37 | |
38 PyObject *result = PyObject_Call(callable, args, NULL); | |
39 if (result == NULL) { | |
40 // TODO: Get the actual exception. | |
41 JS_ReportError(cx, "Python function failed."); | |
42 return JS_FALSE; | |
43 } | |
44 | |
45 int error = PYM_pyObjectToJsval(cx, result, rval); | |
46 Py_DECREF(result); | |
47 | |
48 if (error) { | |
49 // TODO: Get the actual exception. | |
50 JS_ReportError(cx, "Python function failed."); | |
51 return JS_FALSE; | |
52 } | |
53 return JS_TRUE; | |
54 } | |
55 | |
56 PYM_JSFunction * | |
57 PYM_newJSFunction(PYM_JSContextObject *context, | |
58 PyObject *callable, | |
59 const char *name) | |
60 { | |
61 if (!PyCallable_Check(callable)) { | |
62 PyErr_SetString(PyExc_TypeError, "Callable must be callable"); | |
63 return NULL; | |
64 } | |
65 | |
66 JSFunction *func = JS_NewFunction(context->cx, | |
67 dispatchJSFunctionToPython, 0, | |
68 0, NULL, name); | |
69 | |
70 if (func == NULL) { | |
71 PyErr_SetString(PYM_error, "JS_DefineFunction() failed"); | |
72 return NULL; | |
73 } | |
74 | |
75 JSObject *funcObj = JS_GetFunctionObject(func); | |
76 | |
77 if (funcObj == NULL) { | |
78 PyErr_SetString(PYM_error, "JS_GetFunctionObject() failed"); | |
79 return NULL; | |
80 } | |
81 | |
82 if (!JS_SetReservedSlot(context->cx, funcObj, 0, | |
83 PRIVATE_TO_JSVAL(callable))) { | |
84 PyErr_SetString(PYM_error, "JS_SetReservedSlot() failed"); | |
85 return NULL; | |
86 } | |
87 | |
88 PYM_JSFunction *object = PyObject_New(PYM_JSFunction, | |
89 &PYM_JSFunctionType); | |
90 if (object == NULL) | |
91 return NULL; | |
92 | |
93 object->callable = NULL; | |
94 if (PYM_newJSObject(context, funcObj, | |
95 (PYM_JSObject *) object) == NULL) | |
96 // Note that our object's reference count will have already | |
97 // been decremented by PYM_newJSObject(). | |
98 return NULL; | |
99 | |
100 object->callable = callable; | |
101 Py_INCREF(callable); | |
102 | |
103 return object; | |
104 } | |
105 | |
106 PyTypeObject PYM_JSFunctionType = { | |
107 PyObject_HEAD_INIT(NULL) | |
108 0, /*ob_size*/ | |
109 "pymonkey.Function", /*tp_name*/ | |
110 sizeof(PYM_JSFunction), /*tp_basicsize*/ | |
111 0, /*tp_itemsize*/ | |
112 /*tp_dealloc*/ | |
113 (destructor) PYM_JSFunctionDealloc, | |
114 0, /*tp_print*/ | |
115 0, /*tp_getattr*/ | |
116 0, /*tp_setattr*/ | |
117 0, /*tp_compare*/ | |
118 0, /*tp_repr*/ | |
119 0, /*tp_as_number*/ | |
120 0, /*tp_as_sequence*/ | |
121 0, /*tp_as_mapping*/ | |
122 0, /*tp_hash */ | |
123 0, /*tp_call*/ | |
124 0, /*tp_str*/ | |
125 0, /*tp_getattro*/ | |
126 0, /*tp_setattro*/ | |
127 0, /*tp_as_buffer*/ | |
128 /*tp_flags*/ | |
129 Py_TPFLAGS_DEFAULT, | |
130 /* tp_doc */ | |
131 "JavaScript Function.", | |
132 0, /* tp_traverse */ | |
133 0, /* tp_clear */ | |
134 0, /* tp_richcompare */ | |
135 0, /* tp_weaklistoffset */ | |
136 0, /* tp_iter */ | |
137 0, /* tp_iternext */ | |
138 0, /* tp_methods */ | |
139 0, /* tp_members */ | |
140 0, /* tp_getset */ | |
141 0, /* tp_base */ | |
142 0, /* tp_dict */ | |
143 0, /* tp_descr_get */ | |
144 0, /* tp_descr_set */ | |
145 0, /* tp_dictoffset */ | |
146 0, /* tp_init */ | |
147 0, /* tp_alloc */ | |
148 0, /* tp_new */ | |
149 }; |