Mercurial > pymonkey
diff context.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 | 3f8a2db496f5 |
children | 6cd870a2b81e |
line wrap: on
line diff
--- a/context.c Thu Jul 02 15:29:07 2009 -0700 +++ b/context.c Thu Jul 02 22:42:31 2009 -0700 @@ -1,5 +1,6 @@ #include "context.h" #include "object.h" +#include "function.h" #include "utils.h" static void @@ -34,7 +35,7 @@ // If this fails, we don't need to worry about cleaning up // obj because it'll get cleaned up at the next GC. - return (PyObject *) PYM_newJSObject(self, obj); + return (PyObject *) PYM_newJSObject(self, obj, NULL); } static PyObject * @@ -121,87 +122,44 @@ return pyRval; } -static JSBool dispatchJSFunctionToPython(JSContext *cx, - JSObject *obj, - uintN argc, - jsval *argv, - jsval *rval) +static PyObject * +PYM_defineProperty(PYM_JSContextObject *self, PyObject *args) { - jsval callee = JS_ARGV_CALLEE(argv); - jsval jsCallable; - if (!JS_GetReservedSlot(cx, JSVAL_TO_OBJECT(callee), 0, &jsCallable)) { - JS_ReportError(cx, "JS_GetReservedSlot() failed."); - return JS_FALSE; - } - PyObject *callable = (PyObject *) JSVAL_TO_PRIVATE(jsCallable); + PYM_JSObject *object; + PyObject *value; + const char *name; + + if (!PyArg_ParseTuple(args, "O!sO", &PYM_JSObjectType, &object, + &name, &value)) + return NULL; + + jsval jsValue; - // TODO: Convert args and 'this' parameter. - PyObject *args = PyTuple_New(0); - if (args == NULL) { - JS_ReportOutOfMemory(cx); - return JS_FALSE; + if (PYM_pyObjectToJsval(self->cx, value, &jsValue) == -1) + return NULL; + + // TODO: Support unicode naming. + if (!JS_DefineProperty(self->cx, object->obj, name, jsValue, + NULL, NULL, JSPROP_ENUMERATE)) { + // TODO: There's probably an exception pending on self->cx, + // what should we do about it? + PyErr_SetString(PYM_error, "JS_DefineProperty() failed"); + return NULL; } - PyObject *result = PyObject_Call(callable, args, NULL); - if (result == NULL) { - // TODO: Get the actual exception. - JS_ReportError(cx, "Python function failed."); - return JS_FALSE; - } - - int error = PYM_pyObjectToJsval(cx, result, rval); - Py_DECREF(result); - - if (error) { - // TODO: Get the actual exception. - JS_ReportError(cx, "Python function failed."); - return JS_FALSE; - } - return JS_TRUE; + Py_RETURN_NONE; } static PyObject * -PYM_defineFunction(PYM_JSContextObject *self, PyObject *args) +PYM_newFunction(PYM_JSContextObject *self, PyObject *args) { - PYM_JSObject *object; PyObject *callable; const char *name; - if (!PyArg_ParseTuple(args, "O!Os", &PYM_JSObjectType, &object, - &callable, &name)) + if (!PyArg_ParseTuple(args, "Os", &callable, &name)) return NULL; - if (!PyCallable_Check(callable)) { - PyErr_SetString(PyExc_TypeError, "Callable must be callable"); - return NULL; - } - - // TODO: Support unicode naming. - JSFunction *func = JS_DefineFunction(self->cx, object->obj, name, - dispatchJSFunctionToPython, - 0, JSPROP_ENUMERATE); - if (func == NULL) { - PyErr_SetString(PYM_error, "JS_DefineFunction() failed"); - return NULL; - } - - JSObject *funcObj = JS_GetFunctionObject(func); - - if (funcObj == NULL) { - PyErr_SetString(PYM_error, "JS_GetFunctionObject() failed"); - return NULL; - } - - if (!JS_SetReservedSlot(self->cx, funcObj, 0, - PRIVATE_TO_JSVAL(callable))) { - PyErr_SetString(PYM_error, "JS_SetReservedSlot() failed"); - return NULL; - } - - // TODO: When to decref? - Py_INCREF(callable); - - Py_RETURN_NONE; + return (PyObject *) PYM_newJSFunction(self, callable, name); } static PyMethodDef PYM_JSContextMethods[] = { @@ -217,9 +175,12 @@ "Evaluate the given JavaScript code in the context of the given " "global object, using the given filename" "and line number information."}, - {"define_function", - (PyCFunction) PYM_defineFunction, METH_VARARGS, - "Defines a function callable from JS."}, + {"new_function", + (PyCFunction) PYM_newFunction, METH_VARARGS, + "Creates a new function callable from JS."}, + {"define_property", + (PyCFunction) PYM_defineProperty, METH_VARARGS, + "Defines a property on an object."}, {"get_property", (PyCFunction) PYM_getProperty, METH_VARARGS, "Gets the given property for the given JavaScript object."}, {NULL, NULL, 0, NULL}