Mercurial > pymonkey
changeset 52:427b01954b22
The 'this' argument for a js-wrapped python function, as well as the function's arguments, are now passed to the python function.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Wed, 08 Jul 2009 18:45:38 -0700 |
parents | fabd3f2271fa |
children | 2055d853b995 |
files | function.c test_pymonkey.py utils.c |
diffstat | 3 files changed, 89 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/function.c Wed Jul 08 09:32:31 2009 -0700 +++ b/function.c Wed Jul 08 18:45:38 2009 -0700 @@ -64,19 +64,48 @@ } PyObject *callable = (PyObject *) JSVAL_TO_PRIVATE(jsCallable); - // TODO: Convert args and 'this' parameter. - PyObject *args = PyTuple_New(1); + PYM_JSContextObject *context = (PYM_JSContextObject *) + JS_GetContextPrivate(cx); + + jsval thisArg = OBJECT_TO_JSVAL(obj); + PyObject *pyThisArg = PYM_jsvalToPyObject(context, thisArg); + if (pyThisArg == NULL) { + PYM_pythonExceptionToJs(context); + return JS_FALSE; + } + + PyObject *funcArgs = PyTuple_New(argc); + if (funcArgs == NULL) { + Py_DECREF(pyThisArg); + JS_ReportOutOfMemory(cx); + return JS_FALSE; + } + + for (unsigned int i = 0; i < argc; i++) { + PyObject *arg = PYM_jsvalToPyObject(context, argv[i]); + if (arg == NULL || PyTuple_SetItem(funcArgs, i, arg)) { + if (arg) + Py_DECREF(arg); + Py_DECREF(funcArgs); + Py_DECREF(pyThisArg); + PYM_pythonExceptionToJs(context); + return JS_FALSE; + } + } + + PyObject *args = PyTuple_Pack(3, + (PyObject *) context, + pyThisArg, + funcArgs); + Py_DECREF(pyThisArg); + Py_DECREF(funcArgs); if (args == NULL) { JS_ReportOutOfMemory(cx); return JS_FALSE; } - PYM_JSContextObject *context = (PYM_JSContextObject *) - JS_GetContextPrivate(cx); - Py_INCREF(context); - PyTuple_SET_ITEM(args, 0, (PyObject *) context); - PyObject *result = PyObject_Call(callable, args, NULL); + Py_DECREF(args); if (result == NULL) { PYM_pythonExceptionToJs(context); return JS_FALSE; @@ -89,6 +118,7 @@ PYM_pythonExceptionToJs(context); return JS_FALSE; } + return JS_TRUE; }
--- a/test_pymonkey.py Wed Jul 08 09:32:31 2009 -0700 +++ b/test_pymonkey.py Wed Jul 08 18:45:38 2009 -0700 @@ -31,7 +31,7 @@ def testJsWrappedPythonFuncPassesContext(self): contexts = [] - def func(cx): + def func(cx, this, args): contexts.append(cx) return True @@ -44,14 +44,52 @@ cx.evaluate_script(obj, code, '<string>', 1) self.assertEqual(contexts[0], cx) + def testJsWrappedPythonFuncPassesThisArg(self): + thisObjs = [] + + def func(cx, this, args): + thisObjs.append(this) + return True + + code = "func()" + cx = pymonkey.Runtime().new_context() + obj = cx.new_object() + cx.init_standard_classes(obj) + jsfunc = cx.new_function(func, func.__name__) + cx.define_property(obj, func.__name__, jsfunc) + cx.evaluate_script(obj, code, '<string>', 1) + self.assertEqual(thisObjs[0], obj) + + def testJsWrappedPythonFuncPassesFuncArgs(self): + funcArgs = [] + + def func(cx, this, args): + funcArgs.append(args) + return True + + cx = pymonkey.Runtime().new_context() + obj = cx.new_object() + cx.init_standard_classes(obj) + jsfunc = cx.new_function(func, func.__name__) + cx.define_property(obj, func.__name__, jsfunc) + + cx.evaluate_script(obj, "func()", '<string>', 1) + self.assertEqual(len(funcArgs[0]), 0) + self.assertTrue(isinstance(funcArgs[0], tuple)) + + cx.evaluate_script(obj, "func(1, 'foo')", '<string>', 1) + self.assertEqual(len(funcArgs[1]), 2) + self.assertEqual(funcArgs[1][0], 1) + self.assertEqual(funcArgs[1][1], u'foo') + def testJsWrappedPythonFunctionReturnsUnicode(self): - def hai2u(cx): + def hai2u(cx, this, args): return u"o hai" self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'), u"o hai") def testJsWrappedPythonFunctionThrowsException(self): - def hai2u(cx): + def hai2u(cx, this, args): raise Exception("hello") self.assertRaises(pymonkey.error, self._evalJsWrappedPyFunc, @@ -60,43 +98,43 @@ "hello") def testJsWrappedPythonFunctionReturnsNone(self): - def hai2u(cx): + def hai2u(cx, this, args): pass self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'), None) def testJsWrappedPythonFunctionReturnsTrue(self): - def hai2u(cx): + def hai2u(cx, this, args): return True self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'), True) def testJsWrappedPythonFunctionReturnsFalse(self): - def hai2u(cx): + def hai2u(cx, this, args): return False self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'), False) def testJsWrappedPythonFunctionReturnsSmallInt(self): - def hai2u(cx): + def hai2u(cx, this, args): return 5 self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'), 5) def testJsWrappedPythonFunctionReturnsFloat(self): - def hai2u(cx): + def hai2u(cx, this, args): return 5.1 self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'), 5.1) def testJsWrappedPythonFunctionReturnsNegativeInt(self): - def hai2u(cx): + def hai2u(cx, this, args): return -5 self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'), -5) def testJsWrappedPythonFunctionReturnsBigInt(self): - def hai2u(cx): + def hai2u(cx, this, args): return 2147483647 self.assertEqual(self._evalJsWrappedPyFunc(hai2u, 'hai2u()'), 2147483647)
--- a/utils.c Wed Jul 08 09:32:31 2009 -0700 +++ b/utils.c Wed Jul 08 18:45:38 2009 -0700 @@ -188,11 +188,12 @@ JS_SetPendingException(context->cx, val); } else JS_ReportError(context->cx, "Python exception occurred"); + Py_DECREF(str); } - Py_DECREF(type); - Py_DECREF(value); - Py_DECREF(traceback); + Py_XDECREF(type); + Py_XDECREF(value); + Py_XDECREF(traceback); } void