Changeset 35

Show
Ignore:
Timestamp:
03/28/07 04:38:17 (22 months ago)
Author:
scott
Message:

Miscelaneous Fixes

  • Added extra warnings options to autoconf scripts
  • Fixed a few of the ISO-9899-99 errors
  • Removed all empty arrays, now passing in NULL to JSAPI
  • Fixed tolerance of invalid arguments
    • Turns out that when JS_ValueIsFunction() or similar is called with a jsval value which actually has a value of JSVAL_VOID, it leads to a segfault.
    • sagot_eventloop_dispatch was giving JS_CallFunction a pointer for the return value, this is invalid as it actually uses an integer (internally) to refer to the type. Now passing in a reference to a jsval identifier.
  • Added backtracking/regular debugging
  • Now runs (most) tests
Location:
trunk/sagot
Files:
12 modified

Legend:

Unmodified
Added
Removed
  • trunk/sagot/config.h.in

    r20 r35  
    11/* config.h.in.  Generated from configure.in by autoheader.  */ 
     2 
     3/* backtrace_symbols check */ 
     4#undef HAVE_BACKTRACE 
    25 
    36/* Define to 1 if you have the <inttypes.h> header file. */ 
  • trunk/sagot/configure.in

    r23 r35  
    1515AC_SUBST(DEPS_CFLAGS) 
    1616AC_SUBST(DEPS_LIBS) 
     17AC_CHECK_FUNC(backtrace_symbols, [AC_DEFINE(HAVE_BACKTRACE, 1, [backtrace_symbols check])]) 
    1718 
    1819AC_OUTPUT([ 
  • trunk/sagot/src/Makefile.am

    r23 r35  
    33                sagot_glib_iochannel.c sagot_glib_filechannel.c 
    44sagot_LDADD = $(DEPS_LIBS) 
    5 AM_CFLAGS = --std=c99 $(DEPS_CFLAGS) 
     5AM_CFLAGS = -std=c99 -pedantic -Wall -W -O2 $(DEPS_CFLAGS) 
  • trunk/sagot/src/sagot.c

    r23 r35  
    1414#include <sys/stat.h> 
    1515#include <unistd.h> 
     16#include <errno.h> 
    1617 
     18#include "debug.h" 
    1719#include "sagot_glib.h" 
    1820 
     
    155157    sagot_InitIOChannelClass(cx, global); 
    156158 
     159    char *filename = argv[1]; 
     160 
    157161    struct stat statr; 
    158162 
    159     if (!stat(argv[1], &statr)) { 
    160         FILE *script = fopen(argv[1], "r"); 
    161         /* Go C99! */ 
     163    if (!stat(filename, &statr)) { 
     164        FILE *script = fopen(filename, "r"); 
     165 
    162166        char *code = (char *) malloc(statr.st_size); 
    163         //      char script[statr.st_size]; .. we might as well store it in heap space 
    164         //      rather than stack space... 
    165         read(fileno(script), code, statr.st_size); 
     167 
     168        fread(code, statr.st_size, 1, script); 
     169        fclose(script); 
    166170 
    167171        jsval rval; 
    168172 
    169173        JSScript *bytecode = JS_CompileScript(cx, global, code, statr.st_size, 
    170                 argv[1], 0); 
     174                filename, 0); 
    171175 
    172176        /* precompiling the code should increase the speed a lot */ 
    173177        JS_ExecuteScript(cx, global, bytecode, &rval); 
     178    } 
     179    else { 
     180        printf("Cannot open %s: %s\n", filename, strerror(errno)); 
    174181    } 
    175182 
  • trunk/sagot/src/sagot_glib_eventcontext.c

    r5 r35  
    2525}; 
    2626 
     27/* Not quite sure how this works yet 
    2728static JSFunctionSpec eventcontext_methods_static[] = { 
    28     // Not quite sure how this works yet 
    29 //  {"default",             sagot_eventcontext_default, 0,0,0}, 
     29    {"default",             sagot_eventcontext_default, 0,0,0}, 
    3030}; 
     31*/ 
    3132 
    3233/* 
     
    6869    JSObject *proto = JS_InitClass(cx, object, NULL, &eventcontext_class, 
    6970            EventContext, 0, NULL, eventcontext_methods, NULL, 
    70             eventcontext_methods_static); 
     71            NULL); 
    7172 
    7273    return !proto ? NULL : proto; 
  • trunk/sagot/src/sagot_glib_eventcontext.h

    r17 r35  
    2121JSObject * sagot_InitEventContextClass (JSContext *cx, JSObject *object); 
    2222JSClass eventcontext_class; 
    23 static JSFunctionSpec eventcontext_methods[]; 
    24 static JSFunctionSpec eventcontext_methods_static[]; 
     23static JSFunctionSpec eventcontext_methods[3]; 
     24//static JSFunctionSpec eventcontext_methods_static[0]; 
  • trunk/sagot/src/sagot_glib_eventloop.c

    r16 r35  
    2828    {"quit",        sagot_eventloop_quit,       0,0,0 }, 
    2929    {"yield",       sagot_eventloop_yield,      1,0,0 }, 
     30    {"watch",       sagot_eventloop_watch,      3,0,0 }, 
    3031}; 
    3132 
    32 static JSFunctionSpec eventloop_methods_static[] = { 
    33 }; 
     33//static JSFunctionSpec eventloop_methods_static[0]; 
    3434 
    3535/* Create a new main loop.  If we aren't provided a context, use the default 
     
    112112    JSFunction *function = JS_ValueToFunction(cx, argv[1]); 
    113113 
    114     jsval *rval; 
     114    jsval rval; 
    115115    jsval args[argc]; 
    116116 
     
    119119    } 
    120120 
    121     JS_CallFunction(cx, parent, function, argc, args, rval);  
     121    JS_CallFunction(cx, parent, function, argc, args, &rval);  
    122122 
    123123    return FALSE; 
    124124} 
    125125 
     126/** 
     127 * Cleanup data (post-dispatch) 
     128 */ 
    126129void sagot_eventloop_dispatch_cleanup (void *data) { 
    127130    struct queue_item *qitem = (struct queue_item *) data; 
     
    138141 
    139142    /* glib provides nice malloc/free warnings at runtime */ 
    140     struct queue_item *qitem = g_malloc(sizeof(struct queue_item)); 
     143    struct queue_item *qitem = g_malloc(sizeof *qitem); 
    141144 
    142145    if (argc < 2) { 
     
    146149 
    147150    if (JSVAL_IS_STRING(argv[1])) { 
     151        jsval fun; 
     152         
    148153        JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[0]),  
    149                 JS_GetStringBytes(JS_ValueToString(cx, argv[1])), &argv[1]); 
    150  
    151         if (JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(argv[1]))) { 
     154                JS_GetStringBytes(JS_ValueToString(cx, argv[1])), &fun); 
     155 
     156        if (fun == JSVAL_VOID) { 
     157            JS_ReportError(cx, "EventLoop.yield(): Unable to look up method"); 
     158        } 
     159        else if (JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(fun))) { 
    152160            /* This might be kind of slow, think about creating a source 
    153161             * specifically for these vents, attaching the source to the loop, and 
     
    156164             */ 
    157165 
     166            argv[1] = fun; 
    158167            *qitem = (struct queue_item) { 
    159168                .esid = g_malloc(sizeof(int)), 
     
    174183        } 
    175184    } 
    176  
    177     JS_ReportError(cx, "argument 1 to enqueue() must be a string"); 
    178  
    179     return false; 
     185    else { 
     186        JS_ReportError(cx, "argument 1 to enqueue() must be a string"); 
     187        return false; 
     188    } 
     189} 
     190 
     191static JSBool sagot_eventloop_watch (JSContext *cx, JSObject *obj, uintN argc, 
     192        jsval *argv, jsval *rval) { 
     193    GMainLoop *mainloop = JS_GetPrivate(cx, obj); 
     194     
     195    if (argc < 4) { 
     196        JS_ReportError(cx, "EventLoop.watch() requires 4 arguments"); 
     197        return false; 
     198    } 
     199 
     200    if (!JSVAL_IS_OBJECT(argv[0])) { 
     201        JS_ReportError(cx, "EventLoop.watch() argument 1 must be an iochannel"); 
     202        return false; 
     203    } 
     204 
     205    if (!JSVAL_IS_INT(argv[1])) { 
     206        JS_ReportError(cx, "EventLoop.watch() argument 2 must be a number"); 
     207        return false; 
     208    } 
     209 
     210    jsval fun; 
     211 
     212    if (JSVAL_IS_STRING(argv[3])) { 
     213        JS_GetProperty(cx, JSVAL_TO_OBJECT(argv[2]),  
     214                JS_GetStringBytes(JS_ValueToString(cx, argv[3])), &fun); 
     215    } 
     216    else { 
     217        JS_ReportError(cx, "BUGNUTS!"); 
     218    } 
     219 
     220    if (fun == JSVAL_VOID) { 
     221        JS_ReportError(cx, "EventLoop.watch(): Unable to look up method"); 
     222        return false; 
     223    } 
     224    else if (!JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(fun))) { 
     225        JS_ReportError(cx, "Unable to locate function in supplied object"); 
     226        return false; 
     227    } 
     228 
     229    GIOChannel *channel = JS_GetPrivate(cx, JSVAL_TO_OBJECT(argv[0])); 
     230 
     231    if (channel) { 
     232        /* Create a new event source... TODO we may want to explore only having 
     233         * a few event sources per context, and attaching new descriptors to 
     234         * this source.  Although this will likely be more complicated, it may 
     235         * be faster. 
     236         */ 
     237        GSource *source = g_io_create_watch(channel, JSVAL_TO_INT(argv[1])); 
     238         
     239        /* Create a new execution item... */ 
     240        struct queue_item *qitem = g_malloc(sizeof *qitem); 
     241 
     242        /* Now that we got what we wanted out of the argv...let's re-arrange it 
     243         */ 
     244        argv[1] = fun; 
     245        argv[2] = argv[3]; 
     246        argv[3] = argv[0]; 
     247 
     248        argv++; 
     249        argc--; 
     250 
     251        *qitem = (struct queue_item) { 
     252            .esid = g_malloc(sizeof(int)), 
     253            .args = JS_NewArrayObject(cx, argc, argv), 
     254            .argc = argc, 
     255            .cx   = cx, 
     256        }; 
     257 
     258        /* Move the first two items over, creating an empty spot for the 
     259         * channel as an argument...heh, this is a bunch of work just to reuse 
     260         * that dispatch code. 
     261        qitem->args[0] = qitem->args[1]; 
     262        qitem->args[1] = qitem->args[2]; 
     263        qitem->args[2] = argv[0]; 
     264        */ 
     265         
     266        /* Set the callback for this source, storing session data */ 
     267        g_source_set_callback(source, sagot_eventloop_dispatch, qitem, 
     268                sagot_eventloop_dispatch_cleanup); 
     269 
     270        /* Attach our event source to the context for the loop given to us */ 
     271        g_source_attach( source, g_main_loop_get_context( mainloop )); 
     272 
     273        JS_AddRoot(cx, &qitem->args); 
     274 
     275        return true; 
     276    } 
     277    else { 
     278        JS_ReportError(cx, "EventLoop.watch() argument 1 must be an iochannel"); 
     279        return false; 
     280    } 
    180281} 
    181282 
     
    184285    JSObject *proto = JS_InitClass(cx, object, NULL, &eventloop_class, 
    185286            EventLoop, 1, NULL, eventloop_methods, NULL, 
    186             eventloop_methods_static); 
     287            NULL); 
    187288 
    188289    return !proto ? NULL : proto; 
  • trunk/sagot/src/sagot_glib_eventloop.h

    r17 r35  
    2424static JSBool sagot_eventloop_yield (JSContext *cx, JSObject *obj, uintN 
    2525        argc, jsval *argv, jsval *rval); 
     26static JSBool sagot_eventloop_watch (JSContext *cx, JSObject *obj, uintN 
     27        argc, jsval *argv, jsval *rval); 
    2628JSObject * sagot_InitEventLoopClass (JSContext *cx, JSObject *object); 
  • trunk/sagot/src/sagot_glib_filechannel.c

    r24 r35  
    3131static JSPropertySpec filechannel_properties[] = { 
    3232    {"fd", 1, JSPROP_READONLY, sagot_iochannel_fd_get, NULL }, 
    33 }; 
    34  
    35 static JSFunctionSpec filechannel_methods_static[] = { 
    3633}; 
    3734 
     
    8380    JSObject *proto = JS_InitClass(cx, object, NULL, &filechannel_class, 
    8481            FileChannel, 2, NULL, filechannel_methods, NULL, 
    85             filechannel_methods_static); 
     82            NULL); 
    8683 
    8784    return !proto ? NULL : proto; 
  • trunk/sagot/src/sagot_glib_filechannel.h

    r23 r35  
    1212 
    1313static JSClass filechannel_class; 
    14 static JSFunctionSpec filechannel_methods[]; 
    15 static JSPropertySpec filechannel_properties[]; 
    16 static JSFunctionSpec filechannel_methods_static[]; 
    17 static JSPropertySpec filechannel_properties_static[]; 
     14static JSFunctionSpec filechannel_methods[4];  
     15static JSPropertySpec filechannel_properties[1]; 
     16// static JSFunctionSpec filechannel_methods_static[0]; Currently none 
     17// static JSPropertySpec filechannel_properties_static[0]; Currently none 
    1818JSObject * sagot_InitFileChannelClass (JSContext *cx, JSObject *object); 
  • trunk/sagot/src/sagot_glib_iochannel.c

    r24 r35  
    3535}; 
    3636 
    37 JSFunctionSpec iochannel_methods_static[] = { 
    38 }; 
     37// JSFunctionSpec iochannel_methods_static[0]; /* NONE */ 
    3938 
    4039 
     
    5756 * Create a glib unix channel. 
    5857 */ 
    59 bool IOChannel (JSContext *cx, JSObject *object, uintN argc,  
     58JSBool IOChannel (JSContext *cx, JSObject *object, uintN argc,  
    6059        jsval *argv, jsval *rval) { 
    6160    GIOChannel *channel = NULL; 
     
    9695} 
    9796 
    98 bool sagot_iochannel_fd_get (JSContext *cx, JSObject *object, jsval id, 
     97JSBool sagot_iochannel_fd_get (JSContext *cx, JSObject *object, jsval id, 
    9998        jsval *vp) { 
    10099    /* This could be sped up a bit by storing the fd as a jsval and rooting it, 
     
    107106} 
    108107 
    109 bool sagot_iochannel_gettype (JSContext *cx, JSObject *object, jsval id, 
     108JSBool sagot_iochannel_gettype (JSContext *cx, JSObject *object, jsval id, 
    110109        jsval *vp) { 
    111110    /* This is kind of a hack...but it works... ehh ;-) */ 
     
    114113} 
    115114 
    116 bool sagot_iochannel_read (JSContext *cx, JSObject *object, uintN argc,  
     115JSBool sagot_iochannel_read (JSContext *cx, JSObject *object, uintN argc,  
    117116        jsval *argv, jsval *rval) { 
    118117    GIOChannel *channel = (GIOChannel *) JS_GetPrivate(cx, object); 
     
    145144} 
    146145 
    147 bool sagot_iochannel_readline (JSContext *cx, JSObject *self, uintN argc, 
     146JSBool sagot_iochannel_readline (JSContext *cx, JSObject *self, uintN argc, 
    148147        jsval *argv, jsval *rval) { 
    149148    GIOChannel *channel = JS_GetPrivate(cx, self); 
     
    166165} 
    167166 
    168 bool sagot_iochannel_getc (JSContext *cx, JSObject *self, uintN argc, 
     167JSBool sagot_iochannel_getc (JSContext *cx, JSObject *self, uintN argc, 
    169168        jsval *argv, jsval *rval) { 
    170169    GIOChannel *channel = JS_GetPrivate(cx, self); 
     
    184183} 
    185184 
    186 bool sagot_iochannel_close (JSContext *cx, JSObject *self, uintN argc, 
     185JSBool sagot_iochannel_close (JSContext *cx, JSObject *self, uintN argc, 
    187186        jsval *argv, jsval *rval) { 
    188187    GIOChannel *channel = JS_GetPrivate(cx, self); 
     
    195194} 
    196195 
    197 bool sagot_iochannel_watch (JSContext *cx, JSObject *self, uintN argc, 
     196JSBool sagot_iochannel_watch (JSContext *cx, JSObject *self, uintN argc, 
    198197        jsval *argv, jsval *rval) { 
    199198    GIOChannel *channel = JS_GetPrivate(cx, self); 
     
    209208    JSObject *proto = JS_InitClass(cx, object, NULL, &iochannel_class, 
    210209            IOChannel, 2, iochannel_properties, iochannel_methods, 
    211             iochannel_properties_static, iochannel_methods_static); 
     210            iochannel_properties_static, NULL); 
    212211 
    213212    return !proto ? NULL : proto; 
  • trunk/sagot/src/sagot_glib_iochannel.h

    r24 r35  
    2020 
    2121/* Constructor */ 
    22 extern bool IOChannel (JSContext *cx, JSObject *object, uintN argc, jsval *argv, 
     22extern JSBool IOChannel (JSContext *cx, JSObject *object, uintN argc, jsval *argv, 
    2323        jsval *rval); 
    2424 
    25 extern bool sagot_iochannel_fd_get (JSContext *cx, JSObject *object, jsval id, 
     25extern JSBool sagot_iochannel_fd_get (JSContext *cx, JSObject *object, jsval id, 
    2626        jsval *vp); 
    2727 
    28 extern bool sagot_iochannel_gettype (JSContext *cx, JSObject *object, jsval id, 
     28extern JSBool sagot_iochannel_gettype (JSContext *cx, JSObject *object, jsval id, 
    2929        jsval *vp); 
    3030 
    31 extern bool sagot_iochannel_read (JSContext *cx, JSObject *object, uintN argc,  
     31extern JSBool sagot_iochannel_read (JSContext *cx, JSObject *object, uintN argc,  
    3232        jsval *argv, jsval *rval); 
    3333 
    34 extern bool sagot_iochannel_readline (JSContext *cx, JSObject *self, uintN argc, 
     34extern JSBool sagot_iochannel_readline (JSContext *cx, JSObject *self, uintN argc, 
    3535        jsval *argv, jsval *rval); 
    3636 
    37 extern bool sagot_iochannel_getc (JSContext *cx, JSObject *self, uintN argc, 
     37extern JSBool sagot_iochannel_getc (JSContext *cx, JSObject *self, uintN argc, 
    3838        jsval *argv, jsval *rval); 
    3939 
    40 extern bool sagot_iochannel_close (JSContext *cx, JSObject *self, uintN argc, 
     40extern JSBool sagot_iochannel_close (JSContext *cx, JSObject *self, uintN argc, 
    4141        jsval *argv, jsval *rval); 
    4242 
    43 extern bool sagot_iochannel_watch (JSContext *cx, JSObject *self, uintN argc, 
     43extern JSBool sagot_iochannel_watch (JSContext *cx, JSObject *self, uintN argc, 
    4444        jsval *argv, jsval *rval); 
    4545