Changeset 5

Show
Ignore:
Timestamp:
04/02/06 18:38:36 (3 years ago)
Author:
scottmc
Message:

Sagot segfaults

  • Builds but segfaults, not entirely sure why(!)
  • Add dispatch handlers
  • Added cleanup callback but not used
  • Completed enqueue interface but not tested
Location:
trunk/sagot
Files:
2 added
4 modified

Legend:

Unmodified
Added
Removed
  • trunk/sagot/src/Makefile.am

    r4 r5  
    22sagot_SOURCES = sagot.c sagot_glib_eventcontext.c sagot_glib_eventloop.c 
    33sagot_LDADD = $(DEPS_LIBS) 
    4 AM_CFLAGS = $(DEPS_CFLAGS) 
     4AM_CFLAGS = --std=c99 $(DEPS_CFLAGS) 
  • trunk/sagot/src/sagot.c

    r4 r5  
     1/* ----------------------------------------------------------------------------  
     2 * "THE BEER-WARE LICENSE" (Revision 43) borrowed from FreeBSD's jail.c:  
     3 * <tag@cpan.org> wrote this file.  As long as you retain this notice you  
     4 * can do whatever you want with this stuff. If we meet some day, and you think  
     5 * this stuff is worth it, you can buy me a beer in return.   Scott S. McCoy  
     6 * ----------------------------------------------------------------------------  
     7 */ 
     8 
    19#include <stdio.h> 
    210#include <sys/types.h> 
     
    715#include <jsapi.h> 
    816#include "sagot_glib.h" 
     17 
     18#define PTRDIFF(p1, p2, type)                                 \ 
     19    ((((unsigned long)(p1)) - ((unsigned long)(p2))) / sizeof(type)) 
     20 
     21static void 
     22my_ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) 
     23{ 
     24    int i, j, k, n; 
     25    char *prefix, *tmp; 
     26    const char *ctmp; 
     27 
     28    if (!report) { 
     29        fprintf(stderr, "%s\n", message); 
     30        return; 
     31    } 
     32 
     33    /* Conditionally ignore reported warnings. */ 
     34//  if (JSREPORT_IS_WARNING(report->flags) && !reportWarnings) 
     35//      return; 
     36 
     37    prefix = NULL; 
     38 
     39    if (report->filename) 
     40        prefix = JS_smprintf("%s:", report->filename); 
     41 
     42    if (report->lineno) { 
     43        tmp = prefix; 
     44        prefix = JS_smprintf("%s%u: ", tmp ? tmp : "", report->lineno); 
     45        JS_free(cx, tmp); 
     46    } 
     47    if (JSREPORT_IS_WARNING(report->flags)) { 
     48        tmp = prefix; 
     49        prefix = JS_smprintf("%s%swarning: ", 
     50                tmp ? tmp : "", 
     51                JSREPORT_IS_STRICT(report->flags) ? "strict " : ""); 
     52        JS_free(cx, tmp); 
     53    } 
     54 
     55    /* embedded newlines -- argh! */ 
     56    while ((ctmp = strchr(message, '\n')) != 0) { 
     57        ctmp++; 
     58        if (prefix) 
     59            fputs(prefix, stderr); 
     60        fwrite(message, 1, ctmp - message, stderr); 
     61        message = ctmp; 
     62    } 
     63 
     64    /* If there were no filename or lineno, the prefix might be empty */ 
     65    if (prefix) 
     66        fputs(prefix, stderr); 
     67    fputs(message, stderr); 
     68 
     69    if (!report->linebuf) { 
     70        fputc('\n', stderr); 
     71        goto out; 
     72    } 
     73 
     74    /* report->linebuf usually ends with a newline. */ 
     75    n = strlen(report->linebuf); 
     76    fprintf(stderr, ":\n%s%s%s%s", 
     77            prefix, 
     78            report->linebuf, 
     79            (n > 0 && report->linebuf[n-1] == '\n') ? "" : "\n", 
     80            prefix); 
     81    n = PTRDIFF(report->tokenptr, report->linebuf, char); 
     82    for (i = j = 0; i < n; i++) { 
     83        if (report->linebuf[i] == '\t') { 
     84            for (k = (j + 8) & ~7; j < k; j++) { 
     85                fputc('.', stderr); 
     86            } 
     87            continue; 
     88        } 
     89        fputc('.', stderr); 
     90        j++; 
     91    } 
     92    fputs("^\n", stderr); 
     93out: 
     94//  if (!JSREPORT_IS_WARNING(report->flags)) 
     95//      gExitCode = EXITCODE_RUNTIME_ERROR; 
     96    JS_free(cx, prefix); 
     97} 
     98 
     99static JSBool Print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, 
     100        jsval *rval) { 
     101    uintN i, n; 
     102    JSString *str; 
     103 
     104    for (i = n = 0; i < argc; i++) { 
     105        str = JS_ValueToString(cx, argv[i]); 
     106        if (!str) 
     107            return JS_FALSE; 
     108        fprintf(stdout, "%s%s", i ? " " : "", JS_GetStringBytes(str)); 
     109    } 
     110    n++; 
     111    if (n) 
     112        fputc('\n', stdout); 
     113    return JS_TRUE; 
     114} 
     115 
     116static JSFunctionSpec shell_functions[] = { 
     117    {"print",           Print,          0}, 
     118}; 
    9119 
    10120int main (int argc, char *argv[]) { 
     
    31141    rt = JS_NewRuntime(0x100000); 
    32142    cx = JS_NewContext(rt, 0x1000); 
     143 
     144    JS_SetErrorReporter(cx, my_ErrorReporter); 
     145 
     146     
    33147    global = JS_NewObject(cx, &global_class, NULL, NULL); 
    34148    JS_InitStandardClasses(cx, global); 
     149    JS_DefineFunctions(cx, global, shell_functions); 
    35150 
    36151    sagot_InitEventContextClass(cx, global); 
     
    55170        JS_ExecuteScript(cx, global, bytecode, &rval); 
    56171    } 
     172 
     173    JS_DestroyContext(cx); 
     174    JS_DestroyRuntime(rt); 
     175    JS_ShutDown(); 
    57176} 
    58177 
  • trunk/sagot/src/sagot_glib_eventcontext.c

    r4 r5  
    99#include <glib.h> 
    1010#include <jsapi.h> 
     11#include "sagot_glib_eventcontext.h" 
    1112 
    12 static JSClass eventcontext_class = { 
    13     "MainContext", 
     13JSClass eventcontext_class = { 
     14    "EventContext", 
    1415    JSCLASS_HAS_PRIVATE, 
    1516    JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, 
     
    1920 
    2021static JSFunctionSpec eventcontext_methods[] = { 
    21     {"incrementRefcount",   sagot_main_context_ref, 0,0,0}, 
    22     {"decrementRefcount",   sagot_main_context_unref, 0,0,0}, 
    23     {"iterate", sagot_eventcontext_iterate, 1,0,0}, 
     22    {"incrementRefcount",   sagot_eventcontext_ref,    0,0,0}, 
     23    {"decrementRefcount",   sagot_eventcontext_unref,  0,0,0}, 
     24    {"iterate",             sagot_eventcontext_iterate, 1,0,0}, 
    2425}; 
    2526 
    2627static JSFunctionSpec eventcontext_methods_static[] = { 
    27     {"default",     sagot_main_context_default, 0,0,0}, 
     28    // Not quite sure how this works yet 
     29//  {"default",             sagot_eventcontext_default, 0,0,0}, 
    2830}; 
     31 
     32/* 
     33static JSBool sagot_eventcontext_default (JSContext *cx, JSObject *obj, uintN 
     34        argc, jsval *argv, jsval *rval) { 
     35} 
     36*/ 
     37 
     38 
     39static JSBool sagot_eventcontext_ref (JSContext *cx, JSObject *obj, uintN argc, 
     40        jsval *argv, jsval *rval) { 
     41    GMainContext *context = (GMainContext *) JS_GetPrivate(cx, obj); 
     42 
     43    g_main_context_ref(context); 
     44 
     45    return JSVAL_TRUE; 
     46} 
     47 
     48static JSBool sagot_eventcontext_unref (JSContext *cx, JSObject *obj, uintN 
     49        argc, jsval *argv, jsval *rval) { 
     50    GMainContext *context = (GMainContext *) JS_GetPrivate(cx, obj); 
     51 
     52    g_main_context_unref(context); 
     53 
     54    return JSVAL_TRUE; 
     55} 
     56 
     57static JSBool sagot_eventcontext_iterate (JSContext *cx, JSObject *object, 
     58        uintN argc, jsval *argv, jsval *rval) { 
     59     
     60} 
     61 
     62static JSBool EventContext (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, 
     63        jsval *rval) { 
     64    JS_SetPrivate(cx, obj, g_main_context_new()); 
     65} 
     66 
     67JSObject * sagot_InitEventContextClass (JSContext *cx, JSObject *object) { 
     68    JSObject *proto = JS_InitClass(cx, object, NULL, &eventcontext_class, 
     69            EventContext, 0, NULL, eventcontext_methods, NULL, 
     70            eventcontext_methods_static); 
     71 
     72    return !proto ? NULL : proto; 
     73} 
  • trunk/sagot/src/sagot_glib_eventloop.c

    r4 r5  
    1313#include <jsapi.h> 
    1414#include <stdbool.h> 
     15#include "sagot_glib_eventcontext.h" 
     16#include "sagot_glib_eventloop.h" 
    1517 
    1618static JSClass eventloop_class = { 
     
    2729}; 
    2830 
    29 /* Run the main loop */ 
    30 static JSBool sagot_eventloop_run (JSContext *cx, JSObject *obj, uintN argc, 
    31         jsval *argv, jsval *rval) { 
    32     GMainLoop *eventloop = (GMainLoop *) JS_GetPrivate(cx, obj); 
    33  
    34     g_main_loop_run(); 
    35  
    36     rval = JSVAL_TRUE; 
    37 } 
     31static JSFunctionSpec eventloop_methods_static[] = { 
     32}; 
    3833 
    3934/* Create a new main loop.  If we aren't provided a context, use the default 
     
    4843    GMainContext *glib_context = NULL; 
    4944 
    50     if (argc == 0) glib_context = g_main_context_default(); 
    51     else glib_context = (GMainContext *) JS_GetPrivate( 
    52             JSVAL_TO_OBJECT(argv[0])); 
    53      
     45    if (argc > 0) { 
     46        JSObject *glib_context_obj = JSVAL_TO_OBJECT(argv[0]); 
     47        JSClass *argument_class = JS_GetClass(glib_context_obj); 
     48 
     49        /* We have the right type of thing */ 
     50        if (argument_class == &eventcontext_class) 
     51            glib_context = (GMainContext *) JS_GetPrivate(cx, glib_context_obj); 
     52 
     53        /* else throw an error, but for now just ignore it */ 
     54    } 
     55    else { 
     56        glib_context = g_main_context_default(); 
     57    } 
     58 
    5459    JS_SetPrivate(cx, obj, g_main_loop_new(glib_context, false)); 
    5560} 
    5661 
     62static JSBool sagot_eventloop_run (JSContext *cx, JSObject *obj, uintN argc, 
     63        jsval *argv, jsval *rval) { 
     64    GMainLoop *mainloop = (GMainLoop *) JS_GetPrivate(cx, obj); 
     65    g_main_loop_run(mainloop); 
     66} 
     67 
     68static JSBool sagot_eventloop_quit (JSContext *cx, JSObject *obj, uintN argc, 
     69        jsval *argv, jsval *rval) { 
     70    GMainLoop *mainloop = (GMainLoop *) JS_GetPrivate(cx, obj); 
     71    g_main_loop_quit(mainloop); 
     72} 
     73 
     74struct queue_item { 
     75    jsval *argv; 
     76    uintN argc; 
     77    JSContext *cx; 
     78}; 
     79 
     80gboolean sagot_eventloop_dispatch (void *data) { 
     81    struct queue_item *qitem = (struct queue_item *) data; 
     82    JSContext *cx = qitem->cx; 
     83    jsval *argv = qitem->argv; 
     84 
     85    JSObject *fobj = JSVAL_TO_OBJECT(argv[0]); 
     86    JSObject *parent = JS_GetParent(cx, fobj); 
     87 
     88    JSFunction *function = JS_ValueToFunction(cx, argv[0]); 
     89 
     90    jsval *rval; 
     91    JS_CallFunction(cx, parent, function, qitem->argc, argv, rval);  
     92 
     93    JS_RemoveRoot(cx, rval); 
     94    JS_RemoveRoot(cx, argv); 
     95 
     96    g_free(qitem); 
     97} 
     98 
     99void sagot_eventloop_dispatch_cleanup (void *data) { 
     100    JSObject *object = (JSObject *) data; 
     101} 
     102 
     103static JSBool sagot_eventloop_enqueue (JSContext *cx, JSObject *obj, uintN 
     104        argc, jsval *argv, jsval *rval) { 
     105    GMainLoop *mainloop = (GMainLoop *) JS_GetPrivate(cx, obj); 
     106 
     107    /* glib provides nice malloc/free warnings at runtime */ 
     108    struct queue_item *qitem = g_malloc(sizeof(struct queue_item)); 
     109 
     110    *qitem = (struct queue_item) { 
     111        .argv = argv, 
     112        .argc = argc, 
     113    }; 
     114 
     115    if (argc < 1) { 
     116        JS_ReportError(cx, "EventLoop.enqueue() requires arguments"); 
     117        return JS_FALSE; 
     118    } 
     119 
     120    if (JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(qitem->argv[0]))) { 
     121        qitem->cx = cx; 
     122 
     123        g_idle_add_full(0, sagot_eventloop_dispatch, qitem,  
     124                sagot_eventloop_dispatch_cleanup); 
     125 
     126        JS_AddRoot(cx, argv); 
     127 
     128        return JS_TRUE; 
     129    } 
     130 
     131    JS_ReportError(cx, "argument 1 to enqueue() must be a function"); 
     132 
     133    return JS_FALSE; 
     134} 
     135 
     136 
    57137JSObject * sagot_InitEventLoopClass (JSContext *cx, JSObject *object) { 
    58     JSObject *proto = JS_InitClass(cx, object, NULL, &eventloop_class, EventLoop, 
    59             MAXARGS, NULL, eventloop_methods, NULL, eventloop_methods_static); 
     138    JSObject *proto = JS_InitClass(cx, object, NULL, &eventloop_class, 
     139            EventLoop, 1, NULL, eventloop_methods, NULL, 
     140            eventloop_methods_static); 
    60141 
    61142    return !proto ? NULL : proto;