fixed signal handling, factoroids
parent
9f938842e3
commit
a3bb6acf52
|
@ -31,8 +31,10 @@ Makefile - Makefile for building C interpreter.
|
||||||
native/ - source code for Factor interpreter written in C.
|
native/ - source code for Factor interpreter written in C.
|
||||||
library/platform/native - C interpreter-specific code
|
library/platform/native - C interpreter-specific code
|
||||||
f - compiled C interpreter - needs image to run
|
f - compiled C interpreter - needs image to run
|
||||||
boot.image.le - image for x86
|
boot.image.le32 - image for x86
|
||||||
boot.image.be - image for 32-bit SPARC and 32-bit PowerPC
|
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
|
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
|
When you run the interpreter with a boot image, it loads a
|
||||||
bunch of files and saves a 'factor.image'. Run the
|
bunch of files and saves a 'factor.image'. Run the
|
||||||
interpreter again with this image.
|
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
|
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
! Currently the plugin doesn't handle GENERIC: and M:, so we
|
! A simple space shooter.
|
||||||
! disable the parser. too many errors :sidekick.parser=none:
|
!
|
||||||
|
! 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
|
IN: factoroids
|
||||||
|
|
||||||
USE: combinators
|
USE: combinators
|
||||||
|
@ -267,3 +274,6 @@ SYMBOL: event
|
||||||
] with-screen ;
|
] with-screen ;
|
||||||
|
|
||||||
factoroids
|
factoroids
|
||||||
|
|
||||||
|
! Currently the plugin doesn't handle GENERIC: and M:, so we
|
||||||
|
! disable the parser. too many errors :sidekick.parser=none:
|
||||||
|
|
|
@ -94,18 +94,6 @@ USE: words
|
||||||
: ffi-error ( obj -- )
|
: ffi-error ( obj -- )
|
||||||
"FFI: " write print ;
|
"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-error ( obj -- )
|
||||||
"Port closed: " write . ;
|
"Port closed: " write . ;
|
||||||
|
|
||||||
|
@ -126,10 +114,6 @@ USE: words
|
||||||
c-string-error
|
c-string-error
|
||||||
ffi-disabled-error
|
ffi-disabled-error
|
||||||
ffi-error
|
ffi-error
|
||||||
datastack-underflow-error
|
|
||||||
datastack-overflow-error
|
|
||||||
callstack-underflow-error
|
|
||||||
callstack-overflow-error
|
|
||||||
port-closed-error
|
port-closed-error
|
||||||
} vector-nth execute ;
|
} vector-nth execute ;
|
||||||
|
|
||||||
|
|
|
@ -18,9 +18,12 @@ void critical_error(char* msg, CELL tagged)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void throw_error(CELL error)
|
void throw_error(CELL error, bool keep_stacks)
|
||||||
{
|
{
|
||||||
thrown_error = error;
|
thrown_error = error;
|
||||||
|
thrown_keep_stacks = keep_stacks;
|
||||||
|
thrown_ds = ds;
|
||||||
|
thrown_cs = cs;
|
||||||
|
|
||||||
/* Return to run() method */
|
/* Return to run() method */
|
||||||
siglongjmp(toplevel,1);
|
siglongjmp(toplevel,1);
|
||||||
|
@ -28,30 +31,32 @@ void throw_error(CELL error)
|
||||||
|
|
||||||
void primitive_throw(void)
|
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)
|
void general_error(CELL error, CELL tagged)
|
||||||
{
|
{
|
||||||
CELL c = cons(error,cons(tagged,F));
|
early_error(error);
|
||||||
if(userenv[BREAK_ENV] == F)
|
throw_error(cons(error,cons(tagged,F)),true);
|
||||||
{
|
}
|
||||||
/* 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;
|
|
||||||
|
|
||||||
fprintf(stderr,"Type #%ld\n",to_fixnum(
|
/* It is not safe to access 'ds' from a signal handler, so we just not
|
||||||
untag_cons(tagged)->car));
|
touch it */
|
||||||
fprintf(stderr,"Object %ld\n",obj);
|
void signal_error(int signal)
|
||||||
fprintf(stderr,"Got type #%ld\n",type_of(obj));
|
{
|
||||||
}
|
early_error(ERROR_SIGNAL);
|
||||||
fflush(stderr);
|
throw_error(cons(ERROR_SIGNAL,cons(tag_fixnum(signal),F)),false);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
throw_error(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void type_error(CELL type, CELL tagged)
|
void type_error(CELL type, CELL tagged)
|
||||||
|
|
|
@ -13,21 +13,22 @@
|
||||||
#define ERROR_C_STRING (12<<3)
|
#define ERROR_C_STRING (12<<3)
|
||||||
#define ERROR_FFI_DISABLED (13<<3)
|
#define ERROR_FFI_DISABLED (13<<3)
|
||||||
#define ERROR_FFI (14<<3)
|
#define ERROR_FFI (14<<3)
|
||||||
#define ERROR_DATASTACK_UNDERFLOW (15<<3)
|
#define ERROR_CLOSED (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)
|
|
||||||
|
|
||||||
/* When throw_error throws an error, it sets this global and
|
/* When throw_error throws an error, it sets this global and
|
||||||
longjmps back to the top-level. */
|
longjmps back to the top-level. */
|
||||||
CELL thrown_error;
|
CELL thrown_error;
|
||||||
|
CELL thrown_keep_stacks;
|
||||||
|
CELL thrown_ds;
|
||||||
|
CELL thrown_cs;
|
||||||
|
|
||||||
void init_errors(void);
|
void init_errors(void);
|
||||||
void fatal_error(char* msg, CELL tagged);
|
void fatal_error(char* msg, CELL tagged);
|
||||||
void critical_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 general_error(CELL error, CELL tagged);
|
||||||
|
void signal_error(int signal);
|
||||||
void type_error(CELL type, CELL tagged);
|
void type_error(CELL type, CELL tagged);
|
||||||
void primitive_throw(void);
|
void primitive_throw(void);
|
||||||
void range_error(CELL tagged, FIXNUM index, CELL max);
|
void range_error(CELL tagged, FIXNUM index, CELL max);
|
||||||
|
|
|
@ -18,7 +18,14 @@ void run(void)
|
||||||
sigsetjmp(toplevel, 1);
|
sigsetjmp(toplevel, 1);
|
||||||
if(thrown_error != F)
|
if(thrown_error != F)
|
||||||
{
|
{
|
||||||
|
if(thrown_keep_stacks)
|
||||||
|
{
|
||||||
|
ds = thrown_ds;
|
||||||
|
cs = thrown_cs;
|
||||||
|
}
|
||||||
|
else
|
||||||
fix_stacks();
|
fix_stacks();
|
||||||
|
|
||||||
dpush(thrown_error);
|
dpush(thrown_error);
|
||||||
/* Notify any 'catch' blocks */
|
/* Notify any 'catch' blocks */
|
||||||
call(userenv[BREAK_ENV]);
|
call(userenv[BREAK_ENV]);
|
||||||
|
|
|
@ -2,12 +2,6 @@
|
||||||
|
|
||||||
void signal_handler(int signal, siginfo_t* siginfo, void* uap)
|
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)
|
if(active.here > active.limit)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Out of memory\n");
|
fprintf(stderr,"Out of memory\n");
|
||||||
|
@ -18,7 +12,7 @@ void memory_signal_handler(int signal, siginfo_t* siginfo, void* uap)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
general_error(ERROR_SIGNAL,tag_fixnum(signal));
|
signal_error(signal);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from a signal handler. XXX - is this safe? */
|
/* Called from a signal handler. XXX - is this safe? */
|
||||||
|
@ -41,19 +35,16 @@ void init_signals(void)
|
||||||
{
|
{
|
||||||
struct sigaction custom_sigaction;
|
struct sigaction custom_sigaction;
|
||||||
struct sigaction profiling_sigaction;
|
struct sigaction profiling_sigaction;
|
||||||
struct sigaction memory_sigaction;
|
|
||||||
struct sigaction ign_sigaction;
|
struct sigaction ign_sigaction;
|
||||||
custom_sigaction.sa_sigaction = signal_handler;
|
custom_sigaction.sa_sigaction = signal_handler;
|
||||||
custom_sigaction.sa_flags = SA_SIGINFO;
|
custom_sigaction.sa_flags = SA_SIGINFO;
|
||||||
profiling_sigaction.sa_sigaction = call_profiling_step;
|
profiling_sigaction.sa_sigaction = call_profiling_step;
|
||||||
profiling_sigaction.sa_flags = SA_SIGINFO;
|
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;
|
ign_sigaction.sa_handler = SIG_IGN;
|
||||||
sigaction(SIGABRT,&custom_sigaction,NULL);
|
sigaction(SIGABRT,&custom_sigaction,NULL);
|
||||||
sigaction(SIGFPE,&custom_sigaction,NULL);
|
sigaction(SIGFPE,&custom_sigaction,NULL);
|
||||||
sigaction(SIGBUS,&memory_sigaction,NULL);
|
sigaction(SIGBUS,&custom_sigaction,NULL);
|
||||||
sigaction(SIGSEGV,&memory_sigaction,NULL);
|
sigaction(SIGSEGV,&custom_sigaction,NULL);
|
||||||
sigaction(SIGPIPE,&ign_sigaction,NULL);
|
sigaction(SIGPIPE,&ign_sigaction,NULL);
|
||||||
sigaction(SIGPROF,&profiling_sigaction,NULL);
|
sigaction(SIGPROF,&profiling_sigaction,NULL);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue