changeset 5:1f38f4f61768

added global lastException and lastExceptionTraceback properties to the TCB global, which are similar to python's exc_info().
author Atul Varma <varmaa@toolness.com>
date Fri, 19 Jun 2009 03:49:44 -0700
parents 71de19be1054
children 500e267ed094
files spidermonkey-playground.cpp tcb.js
diffstat 2 files changed, 55 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/spidermonkey-playground.cpp	Fri Jun 19 02:58:49 2009 -0700
+++ b/spidermonkey-playground.cpp	Fri Jun 19 03:49:44 2009 -0700
@@ -64,6 +64,10 @@
   JSObject *firstFrameInfo = NULL;
   bool skippedMyFrame = false;
 
+  if (obj == NULL)
+    // We're being called from native code, don't skip the topmost frame.
+    skippedMyFrame = true;
+
   while ((frame = JS_FrameIterator(cx, &iterator)) != NULL) {
     if (!skippedMyFrame) {
       skippedMyFrame = true;
@@ -119,6 +123,34 @@
   return JS_TRUE;
 }
 
+static JSTrapStatus throwHook(JSContext *cx, JSScript *script, jsbytecode *pc,
+                              jsval *rval, void *closure)
+{
+  JSObject *tcb_global = (JSObject *) closure;
+  jsval lastExceptionTraceback;
+  jsval lastException;
+
+  if (!JS_GetProperty(cx, tcb_global, "lastException", &lastException))
+    printf("Unable to retrieve last exception.");
+
+  if (lastException == *rval)
+    // The same exception is just propagating through the stack; keep
+    // our existing last-exception info.
+    return JSTRAP_CONTINUE;
+
+  if (!stack(cx, NULL, 0, NULL, &lastExceptionTraceback)) {
+    printf("Generation of exception info failed.");
+    lastExceptionTraceback = JSVAL_NULL;
+  }
+
+  if (!JS_SetProperty(cx, tcb_global, "lastExceptionTraceback",
+                      &lastExceptionTraceback) ||
+      !JS_SetProperty(cx, tcb_global, "lastException", rval))
+    printf("Setting of exception info failed.");
+
+  return JSTRAP_CONTINUE;
+}
+
 static JSFunctionSpec tcb_global_functions[] = {
   JS_FS("print",   print,   1, 0, 0),
   JS_FS("wrap",    wrap,    2, 0, 0),
@@ -159,6 +191,12 @@
   if (!JS_DefineFunctions(tcb_cx, tcb_global, tcb_global_functions))
     return 1;
 
+  JS_SetThrowHook(rt, throwHook, tcb_global);
+  JS_DefineProperty(tcb_cx, tcb_global, "lastExceptionTraceback", JSVAL_NULL,
+                    NULL, NULL, 0);
+  JS_DefineProperty(tcb_cx, tcb_global, "lastException", JSVAL_NULL,
+                    NULL, NULL, 0);
+
   /* Your application code here. This may include JSAPI calls
      to create your own custom JS objects and run scripts. */
   FILE *f = fopen(TCB_FILENAME, "r");
--- a/tcb.js	Fri Jun 19 02:58:49 2009 -0700
+++ b/tcb.js	Fri Jun 19 03:49:44 2009 -0700
@@ -1,6 +1,7 @@
-function printTraceback() {
+function printTraceback(frame) {
   print("Traceback (most recent call last):");
-  var frame = stack();
+  if (frame === undefined)
+    frame = stack();
   var lines = [];
   while (frame) {
     var line = ('  File "' + frame.filename + '", line ' +
@@ -15,7 +16,20 @@
   print("Hello World.");
 }
 
+function throwError() {
+  function innerThrowError() {
+    throw new Error("hi");
+  }
+  innerThrowError();
+}
+
 showInfo();
-printTraceback();
+try {
+  print("about to throw.");
+  throwError();
+} catch (e) {
+  printTraceback(lastExceptionTraceback);
+  print(e);
+}
 
 var wrapped = wrap({}, {});