gjs r135 - in trunk: . gi modules test/js



Author: johan
Date: Tue Dec 16 16:35:14 2008
New Revision: 135
URL: http://svn.gnome.org/viewvc/gjs?rev=135&view=rev

Log:
Bug 564664 â Expose JS_SetDebugErrorHook


Added:
   trunk/modules/debugger.c
   trunk/modules/debugger.h
   trunk/test/js/testDebugger.js
Modified:
   trunk/Makefile-modules.am
   trunk/configure.ac
   trunk/gi/closure.c
   trunk/gi/closure.h

Modified: trunk/Makefile-modules.am
==============================================================================
--- trunk/Makefile-modules.am	(original)
+++ trunk/Makefile-modules.am	Tue Dec 16 16:35:14 2008
@@ -6,7 +6,7 @@
 dist_gjsjs_DATA += modules/lang.js	\
                    modules/signals.js
 
-gjsnative_LTLIBRARIES += console.la gi.la mainloop.la
+gjsnative_LTLIBRARIES += console.la debugger.la gi.la mainloop.la
 
 JS_NATIVE_MODULE_CFLAGS =	\
         $(AM_CFLAGS)		\
@@ -53,3 +53,15 @@
 console_la_SOURCES =		\
 	modules/console.h	\
 	modules/console.c
+
+debugger_la_CFLAGS = 				\
+	$(JS_NATIVE_MODULE_CFLAGS)
+debugger_la_LIBADD = \
+	libgjs-gi.la				\
+	$(JS_NATIVE_MODULE_LIBADD)
+debugger_la_LDFLAGS = 				\
+	$(JS_NATIVE_MODULE_LDFLAGS)
+
+debugger_la_SOURCES =		\
+	modules/debugger.h	\
+	modules/debugger.c

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Tue Dec 16 16:35:14 2008
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.61)
-AC_INIT([gjs], [0.3], [http://bugzilla.gnome.org/enter_bug.cgi?product=gjs])
+AC_INIT([gjs], [0.3],[http://bugzilla.gnome.org/enter_bug.cgi?product=gjs])
 AM_INIT_AUTOMAKE
 AC_CONFIG_SRCDIR([gjs/console.c])
 AC_CONFIG_HEADER([config.h])

Modified: trunk/gi/closure.c
==============================================================================
--- trunk/gi/closure.c	(original)
+++ trunk/gi/closure.c	Tue Dec 16 16:35:14 2008
@@ -23,6 +23,7 @@
 
 #include <config.h>
 
+#include <string.h>
 #include <limits.h>
 #include <util/log.h>
 
@@ -224,6 +225,41 @@
     }
 }
 
+gboolean
+gjs_closure_invoke_simple(JSContext   *context,
+                          GClosure    *closure,
+                          jsval       *retval,
+                          const gchar *format,
+                          ...)
+{
+    va_list ap;
+    int argc;
+    void *stack_space;
+    jsval *argv;
+    int i;
+
+    va_start(ap, format);
+    argv = JS_PushArgumentsVA(context, &stack_space, format, ap);
+    va_end(ap);
+    if (!argv)
+        return FALSE;
+
+    argc = (int)strlen(format);
+    for (i = 0; i < argc; i++)
+        JS_AddRoot(context, &argv[i]);
+    JS_AddRoot(context, retval);
+
+    gjs_closure_invoke(closure, argc, argv, retval);
+
+    for (i = 0; i < argc; i++)
+        JS_RemoveRoot(context, &argv[i]);
+    JS_RemoveRoot(context, retval);
+
+    JS_PopArguments(context, stack_space);
+
+    return TRUE;
+}
+
 JSContext*
 gjs_closure_get_context(GClosure *closure)
 {

Modified: trunk/gi/closure.h
==============================================================================
--- trunk/gi/closure.h	(original)
+++ trunk/gi/closure.h	Tue Dec 16 16:35:14 2008
@@ -37,6 +37,11 @@
                                       int           argc,
                                       jsval        *argv,
                                       jsval        *retval);
+gboolean   gjs_closure_invoke_simple (JSContext    *context,
+                                      GClosure     *closure,
+                                      jsval        *retval,
+                                      const gchar  *format,
+                                      ...);
 JSContext* gjs_closure_get_context   (GClosure     *closure);
 JSObject*  gjs_closure_get_callable  (GClosure     *closure);
 

Added: trunk/modules/debugger.c
==============================================================================
--- (empty file)
+++ trunk/modules/debugger.c	Tue Dec 16 16:35:14 2008
@@ -0,0 +1,138 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (c) 2008  litl, LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <string.h>
+
+#include <jsapi.h>
+#include <jsdbgapi.h>
+
+#include <glib.h>
+#include <gjs/gjs.h>
+#include <gi/closure.h>
+
+#include "debugger.h"
+
+static void
+closure_invalidated(gpointer  data,
+                    GClosure *closure)
+{
+    g_closure_remove_invalidate_notifier(closure, closure,
+                                         closure_invalidated);
+    g_closure_unref(closure);
+}
+
+static JSBool
+gjs_debugger_debug_error_hook(JSContext     *context,
+                              const char    *message,
+                              JSErrorReport *report,
+                              void          *user_data)
+{
+    const char *filename = NULL;
+    static gboolean running = FALSE;
+    guint line = 0, pos = 0, flags = 0, errnum = 0;
+    jsval retval = JSVAL_NULL, exc;
+    GClosure *closure = (GClosure*)user_data;
+
+    if (running)
+        return JS_FALSE;
+
+    running = TRUE;
+    if (report) {
+        filename = report->filename;
+        line = report->lineno;
+        pos = report->tokenptr - report->linebuf;
+        flags = report->flags;
+        errnum = report->errorNumber;
+    }
+
+    if (JS_IsExceptionPending(context)) {
+        JS_GetPendingException(context, &exc);
+    } else {
+        exc = JSVAL_NULL;
+    }
+
+    if (!gjs_closure_invoke_simple(context, closure, &retval, "ssiiiiv",
+                                   message, filename, line, pos,
+                                   flags, errnum, exc))
+        return JS_FALSE;
+
+    running = FALSE;
+    return JS_TRUE;
+}
+
+static JSBool
+gjs_debugger_set_debug_error_hook(JSContext *context,
+                                  JSObject  *obj,
+                                  uintN      argc,
+                                  jsval     *argv,
+                                  jsval     *retval)
+{
+    static GClosure *closure = NULL;
+    JSRuntime *runtime;
+
+    if (!(argc == 1) ||
+        !JSVAL_IS_OBJECT(argv[0])) {
+        gjs_throw(context, "setDebugErrorHook takes 1 argument, "
+                  " the callback");
+        return JS_FALSE;
+    }
+
+    if (closure != NULL) {
+        *retval = OBJECT_TO_JSVAL(gjs_closure_get_callable(closure));
+        g_closure_invalidate(closure);
+        closure = NULL;
+    }
+
+    runtime = JS_GetRuntime(context);
+
+    if (argv[0] == JSVAL_NULL) {
+        JS_SetDebugErrorHook(runtime, NULL, NULL);
+    } else {
+        closure = gjs_closure_new(context,
+                                  JSVAL_TO_OBJECT(argv[0]),
+                                  "debugger DebugErrorHook");
+        g_closure_ref(closure);
+        g_closure_sink(closure);
+        g_closure_add_invalidate_notifier(closure, closure,
+                                          closure_invalidated);
+
+        JS_SetDebugErrorHook(runtime, gjs_debugger_debug_error_hook, closure);
+    }
+
+  return JS_TRUE;
+}
+
+JSBool
+gjs_define_debugger_stuff(JSContext *context,
+                          JSObject  *module_obj)
+{
+    if (!JS_DefineFunction(context, module_obj,
+                           "setDebugErrorHook",
+                           gjs_debugger_set_debug_error_hook,
+                           1, GJS_MODULE_PROP_FLAGS))
+        return JS_FALSE;
+
+    return JS_TRUE;
+}
+
+GJS_REGISTER_NATIVE_MODULE("debugger", gjs_define_debugger_stuff);

Added: trunk/modules/debugger.h
==============================================================================
--- (empty file)
+++ trunk/modules/debugger.h	Tue Dec 16 16:35:14 2008
@@ -0,0 +1,39 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (c) 2008  litl, LLC
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __GJS_DEBUGGER_H__
+#define __GJS_DEBUGGER_H__
+
+#include <config.h>
+#include <glib.h>
+
+#include <jsapi.h>
+
+G_BEGIN_DECLS
+
+JSBool        gjs_define_debugger_stuff    (JSContext      *context,
+                                            JSObject       *in_object);
+
+G_END_DECLS
+
+#endif  /* __GJS_DEBUGGER_H__ */

Added: trunk/test/js/testDebugger.js
==============================================================================
--- (empty file)
+++ trunk/test/js/testDebugger.js	Tue Dec 16 16:35:14 2008
@@ -0,0 +1,43 @@
+// tests for imports.debugger module
+
+const Debugger = imports.debugger;
+
+function testSetDebugErrorHook() {
+    let args;
+
+    let errorHook = function(message, filename, line, pos, flags, errnum, exc) {
+        args = { message: message,
+                 filename: filename,
+                 line: line,
+                 pos: pos,
+                 flags: flags,
+                 errnum: errnum,
+                 exc: exc };
+    };
+
+    let faulty = function() {
+        /* This is a non-obvious way to get an exception raised,
+         * just to workaround the error detection in js2-mode.
+         * */
+        let x = faulty['undefinedProperty'];
+    };
+
+    let old = Debugger.setDebugErrorHook(errorHook);
+    assertUndefined(old);
+    faulty();
+    old = Debugger.setDebugErrorHook(null);
+    assertEquals(old, errorHook);
+
+    assertNotUndefined(args);
+    assertEquals("reference to undefined property faulty.undefinedProperty", args.message);
+    assertEquals("args.line", 22, args.line);
+    assertEquals("args.pos", 0, args.pos);
+    assertEquals("args.flags", 5, args.flags);
+    assertEquals("args.errnum", 162, args.errnum);
+    assertNotUndefined("args.exc", args.exc);
+
+    assertRaises(function() { Debugger.setDebugErrorHook(); });
+
+}
+
+gjstestRun();



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]