changeset 157:a31ff2de6017

Added 'function' key to stack frame dicts; lineno and pc information is now provided even if script is not.
author Atul Varma <varmaa@toolness.com>
date Sun, 30 Aug 2009 15:06:10 -0700
parents 7daa74f861c4
children 22d46b688ace
files src/context.cpp tests/test_pymonkey.py
diffstat 2 files changed, 38 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- 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) {
--- 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() })()', '<string>', 1)
-        script = stack_holder[0]['caller']['caller']['script']
-        pc = stack_holder[0]['caller']['caller']['pc']
+        cx.evaluate_script(obj, '(function closure() { \nfunc() })()',
+                           '<string>', 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, '<string>')
+        self.assertEqual(stack['caller']['script'], None)
+        self.assertEqual(stack['caller']['lineno'], 2)
         self.assertEqual(script.filename, '<string>')
-        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()