From dc5e7e397d2cb69348f0fe9cd403daa63e553c28 Mon Sep 17 00:00:00 2001 From: Alex Shinn Date: Sun, 22 Feb 2015 16:10:30 +0900 Subject: [PATCH] Emscripten support by default. Patch from Marc Nieper-Wi?kirchen. --- .hgignore | 1 + Makefile | 2 +- lib/chibi/stty.stub | 11 ++++++---- lib/chibi/system.stub | 47 +++++++++++++++++++++++++------------------ lib/chibi/time.sld | 6 +++++- lib/chibi/time.stub | 7 +++++-- main.c | 34 +++++++++++++++++++++++++++++-- 7 files changed, 78 insertions(+), 30 deletions(-) diff --git a/.hgignore b/.hgignore index cd3c0af6..dc5726b4 100644 --- a/.hgignore +++ b/.hgignore @@ -37,6 +37,7 @@ lib/chibi/process.c lib/chibi/system.c lib/chibi/time.c lib/chibi/stty.c +lib/chibi/emscripten.c doc/*.html doc/lib/chibi/*.html misc/* diff --git a/Makefile b/Makefile index ed56bcaf..8f94b879 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ CHIBI_DEPENDENCIES = ./chibi-scheme$(EXE) CHIBI_COMPILED_LIBS = lib/chibi/filesystem$(SO) lib/chibi/process$(SO) \ lib/chibi/time$(SO) lib/chibi/system$(SO) lib/chibi/stty$(SO) \ lib/chibi/weak$(SO) lib/chibi/heap-stats$(SO) lib/chibi/disasm$(SO) \ - lib/chibi/net$(SO) lib/chibi/ast$(SO) + lib/chibi/net$(SO) lib/chibi/ast$(SO) lib/chibi/emscripten$(SO) CHIBI_IO_COMPILED_LIBS = lib/chibi/io/io$(SO) CHIBI_OPT_COMPILED_LIBS = lib/chibi/optimize/rest$(SO) \ lib/chibi/optimize/profile$(SO) diff --git a/lib/chibi/stty.stub b/lib/chibi/stty.stub index 1e66f787..421328ba 100644 --- a/lib/chibi/stty.stub +++ b/lib/chibi/stty.stub @@ -14,10 +14,13 @@ ;;(unsigned-long c_ospeed term-attrs-ospeed term-attrs-ospeed-set!) ) -(define-c unsigned-long (term-attrs-ispeed cfgetispeed) (termios)) -(define-c unsigned-long (term-attrs-ospeed cfgetospeed) (termios)) -(define-c errno (term-attrs-ispeed-set! cfsetispeed) (termios unsigned-long)) -(define-c errno (term-attrs-ospeed-set! cfsetospeed) (termios unsigned-long)) +(cond-expand + (emscripten) + (else + (define-c unsigned-long (term-attrs-ispeed cfgetispeed) (termios)) + (define-c unsigned-long (term-attrs-ospeed cfgetospeed) (termios)) + (define-c errno (term-attrs-ispeed-set! cfsetispeed) (termios unsigned-long)) + (define-c errno (term-attrs-ospeed-set! cfsetospeed) (termios unsigned-long)))) (define-c-struct winsize predicate: winsize? diff --git a/lib/chibi/system.stub b/lib/chibi/system.stub index 23da1d33..1a99755b 100644 --- a/lib/chibi/system.stub +++ b/lib/chibi/system.stub @@ -57,17 +57,20 @@ (define-c errno (set-root-directory! "chroot") (string)) -(define-c errno getpwuid_r - (uid_t (result passwd) - (link string) - (value (string-size arg2) int) - (result pointer passwd))) +(cond-expand + (emscripten) + (else + (define-c errno getpwuid_r + (uid_t (result passwd) + (link string) + (value (string-size arg2) int) + (result pointer passwd))) -(define-c errno getpwnam_r - (string (result passwd) - (link string) - (value (string-size arg2) int) - (result pointer passwd))) + (define-c errno getpwnam_r + (string (result passwd) + (link string) + (value (string-size arg2) int) + (result pointer passwd))))) (define-c-struct group predicate: group? @@ -77,14 +80,18 @@ ;;((array string) gr_mem group-members) ) -(define-c errno getgrgid_r - (gid_t (result group) - (link string) - (value (string-size arg2) int) - (result pointer group))) +(cond-expand + (emscripten) + (else + (define-c errno getgrgid_r + (gid_t (result group) + (link string) + (value (string-size arg2) int) + (result pointer group))) -(define-c errno getgrnam_r - (string (result group) - (link string) - (value (string-size arg2) int) - (result pointer group))) + (define-c errno getgrnam_r + (string (result group) + (link string) + (value (string-size arg2) int) + (result pointer group))))) + diff --git a/lib/chibi/time.sld b/lib/chibi/time.sld index df1e0a3e..20ff0707 100644 --- a/lib/chibi/time.sld +++ b/lib/chibi/time.sld @@ -1,6 +1,6 @@ (define-library (chibi time) - (export current-seconds get-time-of-day set-time-of-day! + (export current-seconds get-time-of-day seconds->time seconds->string time->seconds time->string make-timeval make-tm timeval-seconds timeval-microseconds timezone-offset timezone-dst-time @@ -8,6 +8,10 @@ time-day-of-week time-day-of-year time-dst? time-timezone-name time-offset tm? timeval? timezone?) + (cond-expand + (emscripten) + (else + (export set-time-of-day!))) (cond-expand ((or bsd linux) (export rusage? resource-usage-time resource-usage-system-time diff --git a/lib/chibi/time.stub b/lib/chibi/time.stub index abba475d..cf2a6d1c 100644 --- a/lib/chibi/time.stub +++ b/lib/chibi/time.stub @@ -55,8 +55,11 @@ ;;> Set the current time from a timeval struct and ;;> and optional timezone. -(define-c errno (set-time-of-day! "settimeofday") - (timeval (maybe-null default NULL timezone))) +(cond-expand + (emscripten) + (else + (define-c errno (set-time-of-day! "settimeofday") + (timeval (maybe-null default NULL timezone))))) ;;> Convert an integer number of epoch seconds to a broken-down tm struct. diff --git a/main.c b/main.c index dcfa4764..33cd86cc 100644 --- a/main.c +++ b/main.c @@ -2,6 +2,10 @@ /* Copyright (c) 2009-2013 Alex Shinn. All rights reserved. */ /* BSD-style license: http://synthcode.com/license.txt */ +#ifdef EMSCRIPTEN +#include +#endif + #include "chibi/eval.h" #define sexp_argv_symbol "command-line" @@ -383,6 +387,12 @@ static void do_init_context (sexp* ctx, sexp* env, sexp_uint_t heap_size, check_exception(ctx, env=sexp_load_standard_repl_env(ctx, env, SEXP_SEVEN, bootp)); \ } while (0) +/* static globals for the sake of resuming from within emscripten */ +#ifdef EMSCRIPTEN +static sexp sexp_resume_ctx = SEXP_FALSE; +static sexp sexp_resume_proc = SEXP_FALSE; +#endif + void run_main (int argc, char **argv) { #if SEXP_USE_MODULES char *impmod; @@ -635,12 +645,20 @@ void run_main (int argc, char **argv) { if (sexp_procedurep(tmp)) { sym = sexp_c_string(ctx, argv[i], -1); sym = sexp_list2(ctx, sym, env); - check_exception(ctx, sexp_apply(ctx, tmp, sym)); + tmp = check_exception(ctx, sexp_apply(ctx, tmp, sym)); } else #endif - check_exception(ctx, sexp_load(ctx, sym=sexp_c_string(ctx, argv[i], -1), env)); + tmp = check_exception(ctx, sexp_load(ctx, sym=sexp_c_string(ctx, argv[i], -1), env)); #if SEXP_USE_WARN_UNDEFS sexp_warn_undefs(ctx, env, tmp, SEXP_VOID); +#endif +#ifdef EMSCRIPTEN + if (sexp_applicablep(tmp)) { + sexp_resume_ctx = ctx; + sexp_resume_proc = tmp; + sexp_preserve_object(ctx, sexp_resume_proc); + emscripten_exit_with_live_runtime(); + } #endif } /* SRFI-22: run main if specified */ @@ -661,6 +679,18 @@ void run_main (int argc, char **argv) { sexp_destroy_context(ctx); } +#ifdef EMSCRIPTEN +void sexp_resume() { + sexp_gc_var1(tmp); + sexp_gc_preserve(sexp_resume_ctx, tmp); + tmp = sexp_list1(sexp_resume_ctx, SEXP_VOID); + if (sexp_applicablep(sexp_resume_proc)) { + sexp_resume_proc = check_exception(sexp_resume_ctx, sexp_apply(sexp_resume_ctx, sexp_resume_proc, tmp)); + } + sexp_gc_release1(sexp_resume_ctx); +} +#endif + int main (int argc, char **argv) { #if SEXP_USE_PRINT_BACKTRACE_ON_SEGFAULT signal(SIGSEGV, sexp_segfault_handler);