Changeset 5
- Timestamp:
- 04/02/06 18:38:36 (3 years ago)
- Location:
- trunk/sagot
- Files:
-
- 2 added
- 4 modified
-
src/Makefile.am (modified) (1 diff)
-
src/sagot.c (modified) (4 diffs)
-
src/sagot_glib_eventcontext.c (modified) (2 diffs)
-
src/sagot_glib_eventloop.c (modified) (3 diffs)
-
tests (added)
-
tests/test.js (added)
Legend:
- Unmodified
- Added
- Removed
-
trunk/sagot/src/Makefile.am
r4 r5 2 2 sagot_SOURCES = sagot.c sagot_glib_eventcontext.c sagot_glib_eventloop.c 3 3 sagot_LDADD = $(DEPS_LIBS) 4 AM_CFLAGS = $(DEPS_CFLAGS)4 AM_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 1 9 #include <stdio.h> 2 10 #include <sys/types.h> … … 7 15 #include <jsapi.h> 8 16 #include "sagot_glib.h" 17 18 #define PTRDIFF(p1, p2, type) \ 19 ((((unsigned long)(p1)) - ((unsigned long)(p2))) / sizeof(type)) 20 21 static void 22 my_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); 93 out: 94 // if (!JSREPORT_IS_WARNING(report->flags)) 95 // gExitCode = EXITCODE_RUNTIME_ERROR; 96 JS_free(cx, prefix); 97 } 98 99 static 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 116 static JSFunctionSpec shell_functions[] = { 117 {"print", Print, 0}, 118 }; 9 119 10 120 int main (int argc, char *argv[]) { … … 31 141 rt = JS_NewRuntime(0x100000); 32 142 cx = JS_NewContext(rt, 0x1000); 143 144 JS_SetErrorReporter(cx, my_ErrorReporter); 145 146 33 147 global = JS_NewObject(cx, &global_class, NULL, NULL); 34 148 JS_InitStandardClasses(cx, global); 149 JS_DefineFunctions(cx, global, shell_functions); 35 150 36 151 sagot_InitEventContextClass(cx, global); … … 55 170 JS_ExecuteScript(cx, global, bytecode, &rval); 56 171 } 172 173 JS_DestroyContext(cx); 174 JS_DestroyRuntime(rt); 175 JS_ShutDown(); 57 176 } 58 177 -
trunk/sagot/src/sagot_glib_eventcontext.c
r4 r5 9 9 #include <glib.h> 10 10 #include <jsapi.h> 11 #include "sagot_glib_eventcontext.h" 11 12 12 staticJSClass eventcontext_class = {13 " MainContext",13 JSClass eventcontext_class = { 14 "EventContext", 14 15 JSCLASS_HAS_PRIVATE, 15 16 JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, … … 19 20 20 21 static 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}, 24 25 }; 25 26 26 27 static 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}, 28 30 }; 31 32 /* 33 static JSBool sagot_eventcontext_default (JSContext *cx, JSObject *obj, uintN 34 argc, jsval *argv, jsval *rval) { 35 } 36 */ 37 38 39 static 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 48 static 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 57 static JSBool sagot_eventcontext_iterate (JSContext *cx, JSObject *object, 58 uintN argc, jsval *argv, jsval *rval) { 59 60 } 61 62 static JSBool EventContext (JSContext *cx, JSObject *obj, uintN argc, jsval *argv, 63 jsval *rval) { 64 JS_SetPrivate(cx, obj, g_main_context_new()); 65 } 66 67 JSObject * 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 13 13 #include <jsapi.h> 14 14 #include <stdbool.h> 15 #include "sagot_glib_eventcontext.h" 16 #include "sagot_glib_eventloop.h" 15 17 16 18 static JSClass eventloop_class = { … … 27 29 }; 28 30 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 } 31 static JSFunctionSpec eventloop_methods_static[] = { 32 }; 38 33 39 34 /* Create a new main loop. If we aren't provided a context, use the default … … 48 43 GMainContext *glib_context = NULL; 49 44 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 54 59 JS_SetPrivate(cx, obj, g_main_loop_new(glib_context, false)); 55 60 } 56 61 62 static 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 68 static 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 74 struct queue_item { 75 jsval *argv; 76 uintN argc; 77 JSContext *cx; 78 }; 79 80 gboolean 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 99 void sagot_eventloop_dispatch_cleanup (void *data) { 100 JSObject *object = (JSObject *) data; 101 } 102 103 static 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 57 137 JSObject * 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); 60 141 61 142 return !proto ? NULL : proto;