factor/native/run.c

153 lines
2.8 KiB
C
Raw Normal View History

2004-07-16 02:26:21 -04:00
#include "factor.h"
2004-08-16 21:05:38 -04:00
void signal_handler(int signal, siginfo_t* siginfo, void* uap)
{
general_error(ERROR_SIGNAL,tag_fixnum(signal));
}
2004-08-23 01:13:09 -04:00
/* Called from a signal handler. XXX - is this safe? */
2004-08-29 03:20:19 -04:00
void call_profiling_step(int signal, siginfo_t* siginfo, void* uap)
2004-08-23 01:13:09 -04:00
{
CELL depth = (cs - cs_bot) / CELLS;
int i;
CELL obj;
for(i = profile_depth; i < depth; i++)
{
obj = get(cs_bot + i * CELLS);
if(TAG(obj) == WORD_TYPE)
untag_word(obj)->call_count++;
}
executing->call_count++;
}
2004-08-16 21:05:38 -04:00
void init_signals(void)
{
struct sigaction custom_sigaction;
2004-08-23 01:13:09 -04:00
struct sigaction profiling_sigaction;
2004-08-23 18:46:46 -04:00
struct sigaction ign_sigaction;
2004-08-16 21:05:38 -04:00
custom_sigaction.sa_sigaction = signal_handler;
custom_sigaction.sa_flags = SA_SIGINFO;
2004-08-29 03:20:19 -04:00
profiling_sigaction.sa_sigaction = call_profiling_step;
2004-08-23 01:13:09 -04:00
profiling_sigaction.sa_flags = SA_SIGINFO;
2004-08-23 18:46:46 -04:00
ign_sigaction.sa_handler = SIG_IGN;
2004-08-16 21:05:38 -04:00
sigaction(SIGABRT,&custom_sigaction,NULL);
sigaction(SIGFPE,&custom_sigaction,NULL);
sigaction(SIGBUS,&custom_sigaction,NULL);
sigaction(SIGSEGV,&custom_sigaction,NULL);
2004-08-23 18:46:46 -04:00
sigaction(SIGPIPE,&ign_sigaction,NULL);
2004-08-23 01:13:09 -04:00
sigaction(SIGPROF,&profiling_sigaction,NULL);
2004-08-16 21:05:38 -04:00
}
2004-07-16 02:26:21 -04:00
void clear_environment(void)
{
int i;
for(i = 0; i < USER_ENV; i++)
2004-08-20 18:48:08 -04:00
userenv[i] = 0;
2004-08-23 18:46:46 -04:00
profile_depth = 0;
2004-07-16 02:26:21 -04:00
}
2004-07-27 23:29:37 -04:00
#define EXECUTE(w) ((XT)(w->xt))()
2004-07-16 02:26:21 -04:00
void run(void)
{
CELL next;
/* Error handling. */
sigsetjmp(toplevel, 1);
2004-07-16 02:26:21 -04:00
for(;;)
{
2004-08-20 18:48:08 -04:00
if(callframe == F)
2004-07-16 02:26:21 -04:00
{
2004-08-20 18:48:08 -04:00
callframe = cpop();
2004-08-23 01:13:09 -04:00
cpop();
2004-07-16 02:26:21 -04:00
continue;
}
2004-08-20 18:48:08 -04:00
callframe = (CELL)untag_cons(callframe);
next = get(callframe);
callframe = get(callframe + CELLS);
2004-07-16 02:26:21 -04:00
if(TAG(next) == WORD_TYPE)
{
2004-08-20 18:48:08 -04:00
executing = (WORD*)UNTAG(next);
EXECUTE(executing);
2004-07-16 02:26:21 -04:00
}
else
dpush(next);
2004-07-16 02:26:21 -04:00
}
}
/* XT of deferred words */
void undefined()
{
2004-08-20 18:48:08 -04:00
general_error(ERROR_UNDEFINED_WORD,tag_word(executing));
2004-07-16 02:26:21 -04:00
}
/* XT of compound definitions */
2004-08-23 01:13:09 -04:00
void docol(void)
2004-07-16 02:26:21 -04:00
{
2004-08-23 01:13:09 -04:00
call(executing->parameter);
2004-07-16 02:26:21 -04:00
}
void primitive_execute(void)
{
2004-08-23 01:13:09 -04:00
executing = untag_word(dpop());
2004-08-20 18:48:08 -04:00
EXECUTE(executing);
2004-07-16 02:26:21 -04:00
}
void primitive_call(void)
{
2004-08-23 01:13:09 -04:00
call(dpop());
2004-07-16 02:26:21 -04:00
}
void primitive_ifte(void)
{
CELL f = dpop();
2004-07-16 02:26:21 -04:00
CELL t = dpop();
CELL cond = dpop();
2004-08-23 01:13:09 -04:00
call(untag_boolean(cond) ? t : f);
2004-07-16 02:26:21 -04:00
}
void primitive_getenv(void)
{
FIXNUM e = to_fixnum(dpeek());
2004-07-16 02:26:21 -04:00
if(e < 0 || e >= USER_ENV)
range_error(F,e,USER_ENV);
2004-08-20 18:48:08 -04:00
drepl(userenv[e]);
2004-07-16 02:26:21 -04:00
}
void primitive_setenv(void)
{
FIXNUM e = to_fixnum(dpop());
2004-07-16 02:26:21 -04:00
CELL value = dpop();
if(e < 0 || e >= USER_ENV)
range_error(F,e,USER_ENV);
2004-08-20 18:48:08 -04:00
userenv[e] = value;
2004-07-16 02:26:21 -04:00
}
2004-08-23 01:13:09 -04:00
2004-08-29 03:20:19 -04:00
void primitive_call_profiling(void)
2004-08-23 01:13:09 -04:00
{
CELL d = dpop();
if(d == F)
{
timerclear(&prof_timer.it_interval);
timerclear(&prof_timer.it_value);
2004-08-23 18:46:46 -04:00
profile_depth = 0;
2004-08-23 01:13:09 -04:00
}
else
{
prof_timer.it_interval.tv_sec = 0;
prof_timer.it_interval.tv_usec = 1000;
prof_timer.it_value.tv_sec = 0;
prof_timer.it_value.tv_usec = 1000;
profile_depth = to_fixnum(d);
}
if(setitimer(ITIMER_PROF,&prof_timer,NULL) < 0)
io_error(__FUNCTION__);
}