# HG changeset patch # User Atul Varma # Date 1251669970 25200 # Node ID a31ff2de6017d15c1aa304a148c98865bbbdc7bc # Parent 7daa74f861c4ba0847c4fa6f8a8b2f43b7a7ca38 Added 'function' key to stack frame dicts; lineno and pc information is now provided even if script is not. diff -r 7daa74f861c4 -r a31ff2de6017 src/context.cpp --- a/src/context.cpp Sun Aug 30 11:53:56 2009 -0700 +++ b/src/context.cpp Sun Aug 30 15:06:10 2009 -0700 @@ -144,6 +144,7 @@ unsigned int pc = 0; unsigned int lineno = 0; PyObject *pyScript = NULL; + PyObject *pyFunc = NULL; // TODO: Ideally, we'd always convert the script to an object and // set it as an attribute of the function, but this can result in @@ -151,15 +152,18 @@ // scripts on finalization while creating an object from a script // makes it subject to GC. So to be safe, we'll only provide the // script object if one already exists. - if (script && JS_GetScriptObject(script)) { - pyScript = (PyObject *) PYM_newJSScript(self, script); - if (pyScript == NULL) { - // TODO: We should clean up here. - return NULL; - } + if (script) { jsbytecode *pcByte = JS_GetFramePC(self->cx, frame); pc = pcByte - script->code; lineno = JS_PCToLineNumber(self->cx, script, pcByte); + + if (JS_GetScriptObject(script)) { + pyScript = (PyObject *) PYM_newJSScript(self, script); + if (pyScript == NULL) { + // TODO: We should clean up here. + return NULL; + } + } } if (pyScript == NULL) { @@ -167,15 +171,29 @@ Py_INCREF(pyScript); } + JSObject *funObj = JS_GetFrameFunctionObject(self->cx, frame); + if (funObj) { + pyFunc = (PyObject *) PYM_newJSObject(self, funObj, NULL); + if (pyFunc == NULL) { + // TODO: We should clean up here. + return NULL; + } + } else { + pyFunc = Py_None; + Py_INCREF(pyFunc); + } + PyObject *frameDict = Py_BuildValue( - "{sOsIsIsO}", + "{sOsIsIsOsO}", "script", pyScript, "pc", pc, "lineno", lineno, - "caller", Py_None + "caller", Py_None, + "function", pyFunc ); Py_DECREF(pyScript); + Py_DECREF(pyFunc); if (frameDict) { if (last) { diff -r 7daa74f861c4 -r a31ff2de6017 tests/test_pymonkey.py --- a/tests/test_pymonkey.py Sun Aug 30 11:53:56 2009 -0700 +++ b/tests/test_pymonkey.py Sun Aug 30 15:06:10 2009 -0700 @@ -81,13 +81,20 @@ jsfunc = cx.new_function(func, func.__name__) self._clearOnTeardown(jsfunc) cx.define_property(obj, func.__name__, jsfunc) - cx.evaluate_script(obj, '(function() { func() })()', '', 1) - script = stack_holder[0]['caller']['caller']['script'] - pc = stack_holder[0]['caller']['caller']['pc'] + cx.evaluate_script(obj, '(function closure() { \nfunc() })()', + '', 1) + stack = stack_holder[0] + script = stack['caller']['caller']['script'] + pc = stack['caller']['caller']['pc'] + closure = stack['caller']['function'] + self.assertEqual(closure.name, 'closure') + self.assertEqual(closure.filename, '') + self.assertEqual(stack['caller']['script'], None) + self.assertEqual(stack['caller']['lineno'], 2) self.assertEqual(script.filename, '') - self.assertEqual(stack_holder[0]['caller']['caller']['lineno'], 1) + self.assertEqual(stack['caller']['caller']['lineno'], 1) self.assertTrue(pc >= 0 and pc < len(buffer(script))) - self.assertEqual(stack_holder[0]['caller']['caller']['caller'], None) + self.assertEqual(stack['caller']['caller']['caller'], None) def testScriptHasFilenameMember(self): cx = pymonkey.Runtime().new_context()