108 lines
2.5 KiB
C
108 lines
2.5 KiB
C
/*
|
|
* $Id: interp.c,v 1.3 2005-05-18 04:01:51 bacon Exp $
|
|
*/
|
|
|
|
#include <xp/stx/interp.h>
|
|
|
|
#define XP_STX_PROCESS_SIZE 3
|
|
#define XP_STX_PROCESS_STACK 0
|
|
#define XP_STX_PROCESS_STACK_TOP 1
|
|
#define XP_STX_PROCESS_LINK 2
|
|
|
|
#define XP_STX_CONTEXT_SIZE 6
|
|
#define XP_STX_PROCESS_LINK 0
|
|
#define XP_STX_PROCESS_METHOD 1
|
|
#define XP_STX_PROCESS_ARGUMENTS 2
|
|
#define XP_STX_PROCESS_TEMPORARIES 3
|
|
|
|
typedef int (*byte_code_func_t) (xp_stx_t*
|
|
|
|
static byte_code_func_t byte_code_funcs[] =
|
|
{
|
|
XP_NULL,
|
|
push_instance,
|
|
push_argyment,
|
|
push_temporary,
|
|
push_literal,
|
|
push_constant,
|
|
store_instance,
|
|
store_temporary,
|
|
send_message,
|
|
send_unary,
|
|
send_binary,
|
|
XP_NULL,
|
|
do_primitive,
|
|
XP_NULL,
|
|
do_special
|
|
};
|
|
|
|
xp_stx_word_t xp_stx_new_method (xp_stx_t* stx)
|
|
{
|
|
xp_stx_word_t method;
|
|
method = xp_stx_alloc_object(XP_STX_METHOD_SIZE);
|
|
|
|
return method;
|
|
}
|
|
|
|
xp_stx_word_t xp_stx_new_context (xp_stx_t* stx,
|
|
xp_stx_word_t method, xp_stx_word_t args, xp_stx_word_t temp)
|
|
{
|
|
xp_stx_word_t context;
|
|
|
|
context = xp_stx_alloc_object(XP_STX_CONTEXT_SIZE);
|
|
XP_STX_CLASS(stx,context) = stx->class_context;
|
|
XP_STX_AT(stx,context,XP_STX_CONTEXT_METHOD) = method;
|
|
XP_STX_AT(stx,context,XP_STX_CONTEXT_ARGUMENTS) = args;
|
|
XP_STX_AT(stx,context,XP_STX_CONTEXT_TEMPORARIES) = temp;
|
|
|
|
return context;
|
|
}
|
|
|
|
xp_stx_word_t xp_stx_new_process (xp_stx_t* stx, xp_stx_word_t method)
|
|
{
|
|
xp_stx_word_t process, stx;
|
|
|
|
process = xp_stx_alloc_object(XP_STX_PROCESS_SIZE);
|
|
stack = xp_new_array(stx,50);
|
|
|
|
XP_STX_CLASS(stx,process) = stx->class_process;
|
|
XP_STX_AT(stx,process,XP_STX_PROCESS_STACK) = stack;
|
|
XP_STX_AT(stx,process,XP_STX_PROCESS_STACKTOP) = XP_STX_FROM_SMALLINT(6);
|
|
XP_STX_AT(stx,process,XP_STX_PROCESS_LINK) = XP_STX_FROM_SMALLINT(1);
|
|
|
|
XP_STX_AT(stx,stack,0) = stx->nil; /* argument */
|
|
XP_STX_AT(stx,stack,1) = XP_STX_FROM_SMALLINT(0); /* previous link */
|
|
XP_STX_AT(stx,stack,2) = stx->nil; /* context */
|
|
XP_STX_AT(stx,stack,3) = XP_STX_FROM_SMALLINT(1); /* return point */
|
|
XP_STX_AT(stx,stack,4) = method;
|
|
XP_STX_AT(stx,stack,5) = XP_STX_FROM_SMALLINT(1); /* byte offset */
|
|
|
|
return process;
|
|
}
|
|
|
|
int xp_stx_execute (xp_stx_t* stx, xp_stx_word_t process)
|
|
{
|
|
int low, high;
|
|
byte_code_func_t bcfunc;
|
|
|
|
stack = XP_STX_AT(stx,process,XP_PROCESS_STACK);
|
|
stack_top = XP_STX_AT(stx,process,XP_PROCESS_STACK_TOP);
|
|
link = XP_STX_AT(stx,process,XP_PROCESS_LINK);
|
|
|
|
for (;;) {
|
|
low = (high = nextByte(&es)) & 0x0F;
|
|
high >>= 4;
|
|
if(high == 0) {
|
|
high = low;
|
|
low = nextByte(&es);
|
|
}
|
|
|
|
bcfunc = byte_code_funcs[high];
|
|
if (bcfunc != XP_NULL) {
|
|
bcfunc (stx, low);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|