diff --git a/README.SRC.txt b/README.SRC.txt index 50e0f76a38..86d9232abc 100644 --- a/README.SRC.txt +++ b/README.SRC.txt @@ -31,8 +31,10 @@ Makefile - Makefile for building C interpreter. native/ - source code for Factor interpreter written in C. library/platform/native - C interpreter-specific code f - compiled C interpreter - needs image to run -boot.image.le - image for x86 -boot.image.be - image for 32-bit SPARC and 32-bit PowerPC +boot.image.le32 - image for x86 +boot.image.le64 - image for AMD64 +boot.image.be32 - image for 32-bit SPARC and 32-bit PowerPC +boot.image.be64 - iamge for 64-bit SPARC and 64-bit PowerPC Notes on the C interpreter -------------------------- @@ -40,20 +42,3 @@ Notes on the C interpreter When you run the interpreter with a boot image, it loads a bunch of files and saves a 'factor.image'. Run the interpreter again with this image. - -At the moment it assumes a 32-bit architecture. Your C -compiler's types must be as follows: - -short - signed 16 bits -long - signed 32 bits -long long - signed 64 bits -double -IEEE double precision 64-bit float - -Moving to 64-bits would require a few changes in the image -cross-compiler, namely in the way it packs strings. - -Not everything has been implemented yet. However, a lot -already works. Compare the output of this in the C and -Java interpreters to see how they differ: - -"vocabularies" get describe diff --git a/examples/factoroids.factor b/examples/factoroids.factor index 335917fd9b..d5f8870586 100644 --- a/examples/factoroids.factor +++ b/examples/factoroids.factor @@ -1,5 +1,12 @@ -! Currently the plugin doesn't handle GENERIC: and M:, so we -! disable the parser. too many errors :sidekick.parser=none: +! A simple space shooter. +! +! To play the game: +! +! ./f factor.image -libraries:sdl=libSDL.so -libraries:sdl-gfx=libSDL_gfx.so +! +! "examples/oop.factor" run-file +! "examples/factoroids.factor" run-file + IN: factoroids USE: combinators @@ -267,3 +274,6 @@ SYMBOL: event ] with-screen ; factoroids + +! Currently the plugin doesn't handle GENERIC: and M:, so we +! disable the parser. too many errors :sidekick.parser=none: diff --git a/library/platform/native/debugger.factor b/library/platform/native/debugger.factor index 4812bf14ca..96b8178b7b 100644 --- a/library/platform/native/debugger.factor +++ b/library/platform/native/debugger.factor @@ -94,18 +94,6 @@ USE: words : ffi-error ( obj -- ) "FFI: " write print ; -: datastack-underflow-error ( obj -- ) - drop "Datastack underflow" print ; - -: datastack-overflow-error ( obj -- ) - drop "Datastack overflow" print ; - -: callstack-underflow-error ( obj -- ) - drop "Callstack underflow" print ; - -: callstack-overflow-error ( obj -- ) - drop "Callstack overflow" print ; - : port-closed-error ( obj -- ) "Port closed: " write . ; @@ -126,10 +114,6 @@ USE: words c-string-error ffi-disabled-error ffi-error - datastack-underflow-error - datastack-overflow-error - callstack-underflow-error - callstack-overflow-error port-closed-error } vector-nth execute ; diff --git a/native/error.c b/native/error.c index 131fc59fe6..d10168a95e 100644 --- a/native/error.c +++ b/native/error.c @@ -18,9 +18,12 @@ void critical_error(char* msg, CELL tagged) exit(1); } -void throw_error(CELL error) +void throw_error(CELL error, bool keep_stacks) { thrown_error = error; + thrown_keep_stacks = keep_stacks; + thrown_ds = ds; + thrown_cs = cs; /* Return to run() method */ siglongjmp(toplevel,1); @@ -28,30 +31,32 @@ void throw_error(CELL error) void primitive_throw(void) { - throw_error(dpop()); + throw_error(dpop(),true); +} + +void early_error(CELL error) +{ + if(userenv[BREAK_ENV] == F) + { + /* Crash at startup */ + fprintf(stderr,"Error %ld thrown before BREAK_ENV set\n",to_fixnum(error)); + fflush(stderr); + exit(1); + } } void general_error(CELL error, CELL tagged) { - CELL c = cons(error,cons(tagged,F)); - if(userenv[BREAK_ENV] == F) - { - /* Crash at startup */ - fprintf(stderr,"Error thrown before BREAK_ENV set\n"); - fprintf(stderr,"Error #%ld\n",to_fixnum(error)); - if(error == ERROR_TYPE) - { - CELL obj = untag_cons(untag_cons(tagged)->cdr)->car; + early_error(error); + throw_error(cons(error,cons(tagged,F)),true); +} - fprintf(stderr,"Type #%ld\n",to_fixnum( - untag_cons(tagged)->car)); - fprintf(stderr,"Object %ld\n",obj); - fprintf(stderr,"Got type #%ld\n",type_of(obj)); - } - fflush(stderr); - exit(1); - } - throw_error(c); +/* It is not safe to access 'ds' from a signal handler, so we just not +touch it */ +void signal_error(int signal) +{ + early_error(ERROR_SIGNAL); + throw_error(cons(ERROR_SIGNAL,cons(tag_fixnum(signal),F)),false); } void type_error(CELL type, CELL tagged) diff --git a/native/error.h b/native/error.h index 47d1a98170..89d83cd464 100644 --- a/native/error.h +++ b/native/error.h @@ -13,21 +13,22 @@ #define ERROR_C_STRING (12<<3) #define ERROR_FFI_DISABLED (13<<3) #define ERROR_FFI (14<<3) -#define ERROR_DATASTACK_UNDERFLOW (15<<3) -#define ERROR_DATASTACK_OVERFLOW (16<<3) -#define ERROR_CALLSTACK_UNDERFLOW (17<<3) -#define ERROR_CALLSTACK_OVERFLOW (18<<3) -#define ERROR_CLOSED (19<<3) +#define ERROR_CLOSED (15<<3) /* When throw_error throws an error, it sets this global and longjmps back to the top-level. */ CELL thrown_error; +CELL thrown_keep_stacks; +CELL thrown_ds; +CELL thrown_cs; void init_errors(void); void fatal_error(char* msg, CELL tagged); void critical_error(char* msg, CELL tagged); -void throw_error(CELL object); +void throw_error(CELL error, bool keep_stacks); +void early_error(CELL error); void general_error(CELL error, CELL tagged); +void signal_error(int signal); void type_error(CELL type, CELL tagged); void primitive_throw(void); void range_error(CELL tagged, FIXNUM index, CELL max); diff --git a/native/run.c b/native/run.c index 1d7469acc4..c2d94cd70f 100644 --- a/native/run.c +++ b/native/run.c @@ -18,7 +18,14 @@ void run(void) sigsetjmp(toplevel, 1); if(thrown_error != F) { - fix_stacks(); + if(thrown_keep_stacks) + { + ds = thrown_ds; + cs = thrown_cs; + } + else + fix_stacks(); + dpush(thrown_error); /* Notify any 'catch' blocks */ call(userenv[BREAK_ENV]); diff --git a/native/signal.c b/native/signal.c index 402b2d5364..37db15c3c8 100644 --- a/native/signal.c +++ b/native/signal.c @@ -2,12 +2,6 @@ void signal_handler(int signal, siginfo_t* siginfo, void* uap) { - general_error(ERROR_SIGNAL,tag_fixnum(signal)); -} - -void memory_signal_handler(int signal, siginfo_t* siginfo, void* uap) -{ - fprintf(stderr,"memory signal\n"); if(active.here > active.limit) { fprintf(stderr,"Out of memory\n"); @@ -18,7 +12,7 @@ void memory_signal_handler(int signal, siginfo_t* siginfo, void* uap) exit(1); } else - general_error(ERROR_SIGNAL,tag_fixnum(signal)); + signal_error(signal); } /* Called from a signal handler. XXX - is this safe? */ @@ -41,19 +35,16 @@ void init_signals(void) { struct sigaction custom_sigaction; struct sigaction profiling_sigaction; - struct sigaction memory_sigaction; struct sigaction ign_sigaction; custom_sigaction.sa_sigaction = signal_handler; custom_sigaction.sa_flags = SA_SIGINFO; profiling_sigaction.sa_sigaction = call_profiling_step; profiling_sigaction.sa_flags = SA_SIGINFO; - memory_sigaction.sa_sigaction = memory_signal_handler; - memory_sigaction.sa_flags = SA_SIGINFO; ign_sigaction.sa_handler = SIG_IGN; sigaction(SIGABRT,&custom_sigaction,NULL); sigaction(SIGFPE,&custom_sigaction,NULL); - sigaction(SIGBUS,&memory_sigaction,NULL); - sigaction(SIGSEGV,&memory_sigaction,NULL); + sigaction(SIGBUS,&custom_sigaction,NULL); + sigaction(SIGSEGV,&custom_sigaction,NULL); sigaction(SIGPIPE,&ign_sigaction,NULL); sigaction(SIGPROF,&profiling_sigaction,NULL); }