qse/ase/stx/bytecode.c

194 lines
5.4 KiB
C
Raw Normal View History

2005-07-07 07:45:05 +00:00
/*
2007-03-22 11:19:28 +00:00
* $Id: bytecode.c,v 1.17 2007-03-22 11:19:28 bacon Exp $
2005-07-07 07:45:05 +00:00
*/
2007-03-22 11:19:28 +00:00
#include <ase/stx/bytecode.h>
#include <ase/stx/class.h>
#include <ase/stx/method.h>
#include <ase/stx/dict.h>
2005-07-07 07:45:05 +00:00
2007-03-22 11:19:28 +00:00
static void __decode1 (ase_stx_t* stx, ase_word_t idx, void* data);
static int __decode2 (ase_stx_t* stx,
ase_stx_class_t* class_obj, ase_stx_method_t* method_obj);
2005-07-07 07:45:05 +00:00
2007-03-22 11:19:28 +00:00
int ase_stx_decode (ase_stx_t* stx, ase_word_t class)
2005-07-07 07:45:05 +00:00
{
2007-03-22 11:19:28 +00:00
ase_stx_class_t* class_obj;
2005-07-07 07:45:05 +00:00
2007-03-22 11:19:28 +00:00
class_obj = (ase_stx_class_t*)ASE_STX_OBJECT(stx, class);
2005-07-07 07:45:05 +00:00
if (class_obj->methods == stx->nil) return 0;
/* TODO */
2007-03-22 11:19:28 +00:00
ase_stx_dict_traverse (stx, class_obj->methods, __decode1, class_obj);
2005-07-07 07:45:05 +00:00
return 0;
}
2007-03-22 11:19:28 +00:00
#include <ase/bas/stdio.h>
static void __dump_object (ase_stx_t* stx, ase_word_t obj)
2005-07-11 13:41:59 +00:00
{
2007-03-22 11:19:28 +00:00
if (ASE_STX_IS_SMALLINT(obj)) {
ase_printf (ASE_T("%d"), ASE_STX_FROM_SMALLINT(obj));
2005-07-11 13:41:59 +00:00
}
2007-03-22 11:19:28 +00:00
else if (ASE_STX_CLASS(stx,obj) == stx->class_character) {
ase_printf (ASE_T("$%c"), ASE_STX_WORD_AT(stx,obj,0));
2005-07-11 13:41:59 +00:00
}
2007-03-22 11:19:28 +00:00
else if (ASE_STX_CLASS(stx,obj) == stx->class_string) {
ase_printf (ASE_T("'%s'"), ASE_STX_DATA(stx,obj));
2005-07-11 13:41:59 +00:00
}
2007-03-22 11:19:28 +00:00
else if (ASE_STX_CLASS(stx,obj) == stx->class_symbol) {
ase_printf (ASE_T("#%s"), ASE_STX_DATA(stx,obj));
2005-07-11 13:41:59 +00:00
}
2007-03-22 11:19:28 +00:00
else if (ASE_STX_IS_CHAR_OBJECT(stx, obj)) {
ase_printf (ASE_T("unknow char object [%s]"), ASE_STX_DATA(stx,obj));
2005-07-11 13:41:59 +00:00
}
2007-03-22 11:19:28 +00:00
else if (ASE_STX_IS_BYTE_OBJECT(stx, obj)) {
ase_printf (ASE_T("unknown byte object"), ASE_STX_DATA(stx,obj));
2005-07-11 13:41:59 +00:00
}
2007-03-22 11:19:28 +00:00
else if (ASE_STX_IS_WORD_OBJECT(stx, obj)) {
ase_printf (ASE_T("unknown word object"), ASE_STX_DATA(stx,obj));
2005-07-11 13:41:59 +00:00
}
else {
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("invalid object type"));
2005-07-11 13:41:59 +00:00
}
}
2007-03-22 11:19:28 +00:00
static void __decode1 (ase_stx_t* stx, ase_word_t idx, void* data)
2005-07-07 07:45:05 +00:00
{
2007-03-22 11:19:28 +00:00
ase_stx_method_t* method_obj;
ase_stx_class_t* class_obj;
ase_word_t key = ASE_STX_WORD_AT(stx,idx,ASE_STX_ASSOCIATION_KEY);
ase_word_t value = ASE_STX_WORD_AT(stx,idx,ASE_STX_ASSOCIATION_VALUE);
ase_word_t* literals;
ase_word_t literal_count, i;
2005-07-11 13:41:59 +00:00
2007-03-22 11:19:28 +00:00
ase_word_t method_class;
ase_stx_class_t* method_class_obj;
2005-09-11 15:15:35 +00:00
2007-03-22 11:19:28 +00:00
class_obj = (ase_stx_class_t*)data;
2005-07-07 07:45:05 +00:00
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("* Method: %s\n"), ASE_STX_DATA(stx, key));
method_obj = (ase_stx_method_t*)ASE_STX_OBJECT(stx, value);
2005-07-11 13:41:59 +00:00
literals = method_obj->literals;
2005-09-11 15:15:35 +00:00
/*
2007-03-22 11:19:28 +00:00
literal_count = ASE_STX_SIZE(stx, value) -
(ASE_STX_FROM_SMALLINT(class_obj->spec) >> ASE_STX_SPEC_INDEXABLE_BITS);
2005-09-11 15:15:35 +00:00
*/
2007-03-22 11:19:28 +00:00
method_class = ASE_STX_CLASS(stx,value);
method_class_obj = ASE_STX_OBJECT(stx, method_class);
literal_count = ASE_STX_SIZE(stx,value) -
(ASE_STX_FROM_SMALLINT(method_class_obj->spec) >> ASE_STX_SPEC_INDEXABLE_BITS);
2005-07-11 13:41:59 +00:00
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("* Literal Count: %d, Temporary Count: %d, Argument Count: %d\n"),
2005-09-13 11:15:41 +00:00
literal_count,
2007-03-22 11:19:28 +00:00
ASE_STX_FROM_SMALLINT(method_obj->tmpcount),
ASE_STX_FROM_SMALLINT(method_obj->argcount));
2005-07-11 13:41:59 +00:00
for (i = 0; i < literal_count; i++) {
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("%d. ["), i);
2005-07-11 13:41:59 +00:00
__dump_object (stx, literals[i]);
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("]\n"));
2005-07-11 13:41:59 +00:00
}
2005-07-07 07:45:05 +00:00
__decode2 (stx, data, method_obj);
}
2007-03-22 11:19:28 +00:00
static int __decode2 (ase_stx_t* stx,
ase_stx_class_t* class_obj, ase_stx_method_t* method_obj)
2005-07-07 07:45:05 +00:00
{
2007-03-22 11:19:28 +00:00
ase_stx_byte_object_t* bytecodes;
ase_word_t bytecode_size, pc = 0;
2005-07-10 16:50:50 +00:00
int code, next, next2;
2005-07-10 09:21:46 +00:00
2007-03-22 11:19:28 +00:00
static const ase_char_t* stack_opcode_names[] =
2005-08-11 16:16:04 +00:00
{
2007-03-22 11:19:28 +00:00
ASE_T("push_receiver_variable"),
ASE_T("push_temporary_location"),
ASE_T("push_literal_constant"),
ASE_T("push_literal_variable"),
ASE_T("store_receiver_variable"),
ASE_T("store_temporary_location")
2005-07-10 09:21:46 +00:00
};
2005-07-07 07:45:05 +00:00
2007-03-22 11:19:28 +00:00
static const ase_char_t* send_opcode_names[] =
2005-08-11 16:16:04 +00:00
{
2007-03-22 11:19:28 +00:00
ASE_T("send_to_self"),
ASE_T("send_to_super")
2005-07-10 16:50:50 +00:00
};
2007-03-22 11:19:28 +00:00
static const ase_char_t* stack_special_opcode_names[] =
2005-08-11 16:16:04 +00:00
{
2007-03-22 11:19:28 +00:00
ASE_T("pop_stack_top"),
ASE_T("duplicate_pop_stack_top"),
ASE_T("push_active_context"),
ASE_T("push_nil"),
ASE_T("push_true"),
ASE_T("push_false"),
ASE_T("push_receiver")
2005-08-11 16:16:04 +00:00
};
2007-03-22 11:19:28 +00:00
static const ase_char_t* return_opcode_names[] =
2005-08-11 16:16:04 +00:00
{
2007-03-22 11:19:28 +00:00
ASE_T("return_receiver"),
ASE_T("return_true"),
ASE_T("return_false"),
ASE_T("return_nil"),
ASE_T("return_from_message"),
ASE_T("return_from_block")
2005-08-11 16:16:04 +00:00
};
2005-07-11 13:41:59 +00:00
2007-03-22 11:19:28 +00:00
bytecodes = ASE_STX_BYTE_OBJECT(stx, method_obj->bytecodes);
bytecode_size = ASE_STX_SIZE(stx, method_obj->bytecodes);
2005-07-07 07:45:05 +00:00
while (pc < bytecode_size) {
code = bytecodes->data[pc++];
2005-07-10 09:21:46 +00:00
if (code >= 0x00 && code <= 0x5F) {
/* stack */
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("%s %d\n"),
2005-07-10 09:21:46 +00:00
stack_opcode_names[code >> 4], code & 0x0F);
}
else if (code >= 0x60 && code <= 0x65) {
/* stack extended */
next = bytecodes->data[pc++];
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("%s %d\n"),
2005-07-10 09:21:46 +00:00
stack_opcode_names[code & 0x0F], next);
}
2005-09-30 12:19:00 +00:00
else if (code >= 0x67 && code <= 0x6D) {
2005-08-11 16:16:04 +00:00
/* stack special */
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("%s\n"),
2005-08-11 16:16:04 +00:00
stack_special_opcode_names[code - 0x67]);
}
2005-07-10 16:50:50 +00:00
else if (code >= 0x70 && code <= 0x71 ) {
2005-10-02 10:44:49 +00:00
/* send message */
2005-07-10 16:50:50 +00:00
next = bytecodes->data[pc++];
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("%s nargs(%d) selector(%d)\n"),
2005-09-11 17:01:56 +00:00
send_opcode_names[code - 0x70], next >> 5, next & 0x1F);
2005-07-10 16:50:50 +00:00
}
else if (code >= 0x72 && code <= 0x73 ) {
2005-10-02 10:44:49 +00:00
/* send message extended */
2005-07-10 16:50:50 +00:00
next = bytecodes->data[pc++];
next2 = bytecodes->data[pc++];
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("%s %d %d\n"),
2005-07-10 16:50:50 +00:00
send_opcode_names[code - 0x72], next, next2);
2005-07-10 09:21:46 +00:00
}
else if (code >= 0x78 && code <= 0x7D) {
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("%s\n"),
2005-08-11 16:16:04 +00:00
return_opcode_names[code - 0x78]);
2005-07-10 09:21:46 +00:00
}
else if (code >= 0x80 && code <= 0x8F) {
// jump
}
else if (code >= 0xF0 && code <= 0xFF) {
// primitive
next = bytecodes->data[pc++];
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("do_primitive %d\n"), ((code & 0x0F) << 8) | next);
2005-07-10 09:21:46 +00:00
}
else {
2007-03-22 11:19:28 +00:00
ase_printf (ASE_T("unknown byte code 0x%x\n"), code);
2005-07-07 07:45:05 +00:00
}
}
return 0;
}