qse/ase/stx/bytecode.c

90 lines
2.2 KiB
C

/*
* $Id: bytecode.c,v 1.3 2005-07-07 16:52:48 bacon Exp $
*/
#include <xp/stx/bytecode.h>
#include <xp/stx/class.h>
#include <xp/stx/method.h>
#include <xp/stx/hash.h>
static void __decode1 (xp_stx_t* stx, xp_word_t idx, void* data);
static int __decode2 (xp_stx_t* stx,
xp_stx_class_t* class_obj, xp_stx_method_t* method_obj);
int xp_stx_decode (xp_stx_t* stx, xp_word_t class)
{
xp_stx_class_t* class_obj;
class_obj = (xp_stx_class_t*)XP_STX_OBJECT(stx, class);
if (class_obj->methods == stx->nil) return 0;
/* TODO */
xp_stx_hash_traverse (stx, class_obj->methods, __decode1, class_obj);
return 0;
}
static void __decode1 (xp_stx_t* stx, xp_word_t idx, void* data)
{
xp_stx_method_t* method_obj;
xp_word_t key = XP_STX_WORDAT(stx,idx,XP_STX_PAIRLINK_KEY);
xp_word_t value = XP_STX_WORDAT(stx,idx,XP_STX_PAIRLINK_VALUE);
xp_printf (XP_TEXT("Method: %s\n"), XP_STX_DATA(stx, key));
method_obj = (xp_stx_method_t*)XP_STX_OBJECT(stx, value);
__decode2 (stx, data, method_obj);
}
static const xp_char_t* opcode_names[] =
{
XP_TEXT("PUSH_VARIABLE"),
XP_TEXT("PUSH_TEMPORARY"),
XP_TEXT("PUSH_LITERAL_CONSTANT"),
XP_TEXT("PUSH_LITERAL_VARIABLE"),
XP_TEXT("STORE_VARIABLE"),
XP_TEXT("STORE_TEMPORARY"),
XP_TEXT("DO_SPECIAL"),
XP_TEXT("DO_PRIMITIVE"),
XP_TEXT("UNKNOWN"),
XP_TEXT("UNKNOWN"),
XP_TEXT("PUSH_VARIABLE_EXTENDED"),
XP_TEXT("PUSH_TEMPORARY_EXTENDED"),
XP_TEXT("STORE_TEMPORARY_EXTENDED"),
XP_TEXT("UNKNOWN"),
XP_TEXT("UNKNOWN"),
XP_TEXT("DO_PRIMITIVE_EXTENDED")
};
static int __decode2 (xp_stx_t* stx,
xp_stx_class_t* class_obj, xp_stx_method_t* method_obj)
{
xp_stx_byte_object_t* bytecodes;
xp_word_t bytecode_size, pc = 0;
xp_byte_t code;
int opcode, operand;
bytecodes = XP_STX_BYTE_OBJECT(stx, method_obj->bytecodes);
bytecode_size = XP_STX_SIZE(stx, method_obj->bytecodes);
while (pc < bytecode_size) {
code = bytecodes->data[pc++];
opcode = (code & 0xF0) >> 4;
operand = code & 0x0F;
if (opcode > 0x9) {
if (pc >= bytecode_size) {
/* TODO: */
xp_printf (XP_TEXT("error in bytecodes\n"));
return -1;
}
code = bytecodes->data[pc++];
operand |= (code << 4);
}
xp_printf (XP_TEXT("%s(0x%x), operand = %d\n"),
opcode_names[opcode], opcode, operand);
}
return 0;
}