*** empty log message ***

This commit is contained in:
hyung-hwan 2005-09-13 11:15:41 +00:00
parent ea7ea39fa7
commit ae4249e3b9
8 changed files with 258 additions and 126 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: bootstrp.c,v 1.32 2005-09-11 15:15:35 bacon Exp $ * $Id: bootstrp.c,v 1.33 2005-09-13 11:15:41 bacon Exp $
*/ */
#include <xp/stx/bootstrp.h> #include <xp/stx/bootstrp.h>
@ -122,7 +122,7 @@ static class_info_t class_info[] =
{ {
XP_TEXT("Method"), XP_TEXT("Method"),
XP_TEXT("Object"), XP_TEXT("Object"),
XP_TEXT("text selector bytecodes tmpcount"), XP_TEXT("text selector bytecodes tmpCount argCount"),
XP_NULL, XP_NULL,
XP_NULL, XP_NULL,
XP_STX_SPEC_WORD_INDEXABLE XP_STX_SPEC_WORD_INDEXABLE

View File

@ -1,5 +1,5 @@
/* /*
* $Id: bytecode.c,v 1.12 2005-09-11 17:01:56 bacon Exp $ * $Id: bytecode.c,v 1.13 2005-09-13 11:15:41 bacon Exp $
*/ */
#include <xp/stx/bytecode.h> #include <xp/stx/bytecode.h>
#include <xp/stx/class.h> #include <xp/stx/class.h>
@ -79,8 +79,10 @@ static void __decode1 (xp_stx_t* stx, xp_word_t idx, void* data)
literal_count = XP_STX_SIZE(stx,value) - literal_count = XP_STX_SIZE(stx,value) -
(XP_STX_FROM_SMALLINT(method_class_obj->spec) >> XP_STX_SPEC_INDEXABLE_BITS); (XP_STX_FROM_SMALLINT(method_class_obj->spec) >> XP_STX_SPEC_INDEXABLE_BITS);
xp_printf (XP_TEXT("* Literal Count: %d, Temporary Count: %d\n"), xp_printf (XP_TEXT("* Literal Count: %d, Temporary Count: %d, Argument Count: %d\n"),
literal_count, XP_STX_FROM_SMALLINT(method_obj->tmpcount)); literal_count,
XP_STX_FROM_SMALLINT(method_obj->tmpcount),
XP_STX_FROM_SMALLINT(method_obj->argcount));
for (i = 0; i < literal_count; i++) { for (i = 0; i < literal_count; i++) {
xp_printf (XP_TEXT("%d. ["), i); xp_printf (XP_TEXT("%d. ["), i);
__dump_object (stx, literals[i]); __dump_object (stx, literals[i]);

View File

@ -1,113 +1,173 @@
/* /*
* $Id: interp.c,v 1.12 2005-09-12 15:55:13 bacon Exp $ * $Id: interp.c,v 1.13 2005-09-13 11:15:41 bacon Exp $
*/ */
#include <xp/stx/interp.h> #include <xp/stx/interp.h>
#include <xp/stx/method.h> #include <xp/stx/method.h>
#include <xp/stx/object.h> #include <xp/stx/object.h>
#include <xp/stx/array.h> #include <xp/stx/array.h>
#include <xp/stx/class.h>
#include <xp/bas/assert.h> #include <xp/bas/assert.h>
#include <xp/bas/memory.h>
#define XP_STX_CONTEXT_SIZE 5 /*
#define XP_STX_CONTEXT_STACK 0 activation record
#define XP_STX_CONTEXT_STACK_TOP 1
#define XP_STX_CONTEXT_RECEIVER 2
#define XP_STX_CONTEXT_PC 3
#define XP_STX_CONTEXT_METHOD 4
struct xp_stx_context_t ....
{ ....
xp_stx_objhdr_t header; ....
xp_word_t stack; -------------------
xp_word_t stack_top; previous stack_base
xp_word_t receiver; -------------------
xp_word_t pc; method
xp_word_t method; -------------------
}; pc
-------------------
temporaries
-------------------
arguments
-------------------
receiver
------------------- <----- current stack_base
....
....
....
typedef struct xp_stx_context_t xp_stx_context_t;
/* data structure for internal vm operation */
struct vmcontext_t
{
/* from context */
xp_word_t* stack;
xp_word_t stack_size;
xp_word_t stack_top;
xp_word_t receiver;
xp_word_t pc;
/* from method */
xp_byte_t* bytecodes;
xp_word_t bytecode_size;
xp_word_t* literals;
};
typedef struct vmcontext_t vmcontext_t;
static int __dispatch_primitive (xp_stx_t* stx, int no, vmcontext_t* vmc);
xp_word_t xp_stx_new_context (xp_stx_t* stx, xp_word_t receiver, xp_word_t method)
{
xp_word_t context;
xp_stx_context_t* ctxobj;
context = xp_stx_alloc_word_object(
stx, XP_NULL, XP_STX_CONTEXT_SIZE, XP_NULL, 0);
XP_STX_CLASS(stx,context) = stx->class_context;
ctxobj = (xp_stx_context_t*)XP_STX_OBJECT(stx,context);
ctxobj->stack = xp_stx_new_array (stx, 512); /* TODO: initial stack size */
ctxobj->stack_top = XP_STX_TO_SMALLINT(0);
ctxobj->receiver = receiver;
ctxobj->pc = XP_STX_TO_SMALLINT(0);
ctxobj->method = method;
return context;
}
static int __activate_method (
xp_stx_t* stx, vmcontext_t* vmc, xp_word_t argcount)
{
/* TODO check stack overflow...
if (vmc->stack_top >= vmc->stack_size) PANIC
*/ */
//tmpcount = ... struct process_t
vmc->stack_top += argcount; {
while (tmpcount-- > 0) { xp_word_t* stack;
vmc->stack[vmc->stack_top++] = stx->nil; xp_word_t stack_size;
} xp_word_t stack_base;
xp_word_t stack_top;
xp_word_t method;
xp_word_t pc;
/* cached information about the method above */
xp_word_t* literals;
xp_byte_t* bytecodes;
xp_word_t bytecode_size;
xp_size_t argcount;
xp_size_t tmpcount;
};
typedef struct process_t process_t;
static int __dispatch_primitive (xp_stx_t* stx, process_t* proc, xp_word_t no);
static int __init_process (process_t* proc, xp_word_t stack_size)
{
/* don't use the object model for process */
proc->stack = (xp_word_t*)xp_malloc (stack_size * xp_sizeof(xp_word_t));
if (proc->stack == XP_NULL) return -1;
proc->stack_size = stack_size;
proc->stack_base = 0;
proc->stack_top = 0;
return 0;
} }
int xp_stx_interp (xp_stx_t* stx, xp_word_t context) static void __deinit_process (process_t* proc)
{ {
xp_stx_context_t* ctxobj; /* TODO: */
}
static int __send_to_self (xp_stx_t* stx,
process_t* proc, xp_word_t nargs, xp_word_t selector)
{
xp_word_t receiver, method;
xp_word_t i, tmpcount, argcount;
xp_stx_method_t* mthobj; xp_stx_method_t* mthobj;
vmcontext_t vmc;
xp_assert (XP_STX_CLASS(stx,selector) == stx->class_symbol);
receiver = proc->stack[proc->stack_top - nargs - 1];
method = xp_stx_lookup_method (stx,
XP_STX_CLASS(stx,receiver), XP_STX_DATA(stx,selector));
if (method == stx->nil) {
xp_printf (XP_TEXT("cannot find the method....\n"));
return -1;
}
mthobj = (xp_stx_method_t*)XP_STX_OBJECT(stx,method);
argcount = XP_STX_FROM_SMALLINT(mthobj->argcount);
tmpcount = XP_STX_FROM_SMALLINT(mthobj->tmpcount);
xp_assert (argcount == nargs);
/* secure space for temporaries */
for (i = 0; i < tmpcount; i++) {
proc->stack[proc->stack_top++] = stx->nil;
}
/* push pc */
proc->stack[proc->stack_top++] = proc->pc;
/* push method */
proc->stack[proc->stack_top++] = proc->method;
/* push previous stack base */
proc->stack[proc->stack_top++] = proc->stack_base;
proc->stack_base = proc->stack_top - 3 - tmpcount - argcount - 1;
xp_assert (proc->stack_base > 0);
proc->method = method;
proc->pc = 0;
proc->literals = mthobj->literals;
proc->bytecodes = XP_STX_DATA(stx, mthobj->bytecodes);
proc->bytecode_size = XP_STX_SIZE(stx, mthobj->bytecodes);
proc->argcount = argcount;
proc->tmpcount = tmpcount;
return 0;
}
static int __return_from_message (xp_stx_t* stx, process_t* proc, int code)
{
xp_word_t method, pc, stack_base;
xp_stx_method_t* mthobj;
if (proc->stack_base == 0) {
/* return from the startup method */
return -1;
}
stack_base = proc->stack[proc->stack_base + 1 + proc->tmpcount + proc->argcount + 2];
method = proc->stack[proc->stack_base + 1 + proc->tmpcount + proc->argcount + 1];
pc = proc->stack[proc->stack_base + 1 + proc->tmpcount + proc->argcount];
mthobj = (xp_stx_method_t*)XP_STX_OBJECT(stx,method);
xp_assert (mthobj != XP_NULL);
proc->stack_top = proc->stack_base;
proc->stack_base = stack_base;
proc->method = method;
proc->pc = pc;
proc->literals = mthobj->literals;
proc->bytecodes = XP_STX_DATA(stx, mthobj->bytecodes);
proc->bytecode_size = XP_STX_SIZE(stx, mthobj->bytecodes);
proc->argcount = XP_STX_FROM_SMALLINT(mthobj->argcount);
proc->tmpcount = XP_STX_FROM_SMALLINT(mthobj->tmpcount);
return 0;
}
static int __run_process (xp_stx_t* stx, process_t* proc)
{
int code, next, next2; int code, next, next2;
ctxobj = (xp_stx_context_t*)XP_STX_OBJECT(stx,context); while (proc->pc < proc->bytecode_size) {
mthobj = (xp_stx_method_t*)XP_STX_OBJECT(stx,ctxobj->method); code = proc->bytecodes[proc->pc++];
vmc.stack = XP_STX_DATA(stx,ctxobj->stack);
vmc.stack_size = XP_STX_SIZE(stx,ctxobj->stack);
/* the beginning of the stack is reserved for temporaries */
vmc.stack_top =
XP_STX_FROM_SMALLINT(ctxobj->stack_top) +
XP_STX_FROM_SMALLINT(mthobj->tmpcount);
vmc.receiver = ctxobj->receiver;
vmc.pc = XP_STX_FROM_SMALLINT(ctxobj->pc);
vmc.literals = mthobj->literals;
vmc.bytecodes = XP_STX_DATA(stx, mthobj->bytecodes);
vmc.bytecode_size = XP_STX_SIZE(stx, mthobj->bytecodes);
while (vmc.pc < vmc.bytecode_size) {
code = vmc.bytecodes[vmc.pc++];
#ifdef DEBUG #ifdef DEBUG
xp_printf (XP_TEXT("code = 0x%x, %x\n"), code); xp_printf (XP_TEXT("code = 0x%x\n"), code);
#endif #endif
if (code >= 0x00 && code <= 0x3F) { if (code >= 0x00 && code <= 0x3F) {
@ -116,14 +176,16 @@ int xp_stx_interp (xp_stx_t* stx, xp_word_t context)
int index = code & 0x0F; int index = code & 0x0F;
switch (what) { switch (what) {
#if 0
case 0: /* receiver variable */ case 0: /* receiver variable */
vmc.stack[vmc.stack_top++] = XP_STX_WORD_AT(stx, vmc.receiver, index); proc->stack[proc->stack_top++] = XP_STX_WORD_AT(stx, proc->receiver, index);
break; break;
case 1: /* temporary variable */ case 1: /* temporary variable */
vmc.stack[vmc.stack_top++] = vmc.stack[index]; proc->stack[proc->stack_top++] = proc->stack[index];
break; break;
#endif
case 2: /* literal constant */ case 2: /* literal constant */
vmc.stack[vmc.stack_top++] = vmc.literals[index]; proc->stack[proc->stack_top++] = proc->literals[index];
break; break;
case 3: /* literal variable */ case 3: /* literal variable */
break; break;
@ -134,69 +196,123 @@ int xp_stx_interp (xp_stx_t* stx, xp_word_t context)
int what = code >> 4; int what = code >> 4;
int index = code & 0x0F; int index = code & 0x0F;
#if 0
switch (what) { switch (what) {
case 4: /* receiver variable */ case 4: /* receiver variable */
XP_STX_WORD_AT(stx,vmc.receiver,index) = vmc.stack[--vmc.stack_top]; XP_STX_WORD_AT(stx,proc->receiver,index) = proc->stack[--proc->stack_top];
break; break;
case 5: /* temporary location */ case 5: /* temporary location */
vmc.stack[index] = vmc.stack[--vmc.stack_top]; proc->stack[index] = proc->stack[--proc->stack_top];
break; break;
} }
#endif
} }
/* more here .... */ /* more here .... */
else if (code == 0x70) { else if (code == 0x70) {
/* send to self */ next = proc->bytecodes[proc->pc++];
int nargs, selector; //xp_printf (XP_TEXT("%d, %d\n"), next >> 5, next & 0x1F);
next = vmc.bytecodes[vmc.pc++]; __send_to_self (stx,
proc, next >> 5, proc->literals[next & 0x1F]);
nargs = next >> 5; //xp_printf (XP_TEXT("done %d, %d\n"), next >> 5, next & 0x1F);
/*
selector = vmc.literals[next & 0x1F];
receiver = vmc.stack[--vmc.stack_top];
xp_stx_lookup_method (stx, class of receiver, );
*/
} }
else if (code == 0x71) { else if (code == 0x71) {
/* send to super */ /* send to super */
int nargs, selector; next = proc->bytecodes[proc->pc++];
next = vmc.bytecodes[vmc.pc++]; //__send_to_super (stx,
// proc, next >> 5, proc->literals[next & 0x1F]);
nargs = next >> 5;
selector = next & 0x1F;
} }
else if (code == 0x72) { else if (code == 0x72) {
/* send to self extended */ /* send to self extended */
next = vmc.bytecodes[vmc.pc++]; next = proc->bytecodes[proc->pc++];
next2 = vmc.bytecodes[vmc.pc++]; next2 = proc->bytecodes[proc->pc++];
__send_to_self (stx,
proc, next >> 5, proc->literals[next2]);
} }
else if (code == 0x73) { else if (code == 0x73) {
/* send to super extended */ /* send to super extended */
next = vmc.bytecodes[vmc.pc++]; next = proc->bytecodes[proc->pc++];
next2 = vmc.bytecodes[vmc.pc++]; next2 = proc->bytecodes[proc->pc++];
//__send_to_super (stx,
// proc, next >> 5, proc->literals[next2]);
} }
/* more code .... */ /* more code .... */
else if (code == 0x7C) {
/* return from message */
if (__return_from_message (stx, proc, code) == -1) break;
}
else if (code >= 0xF0 && code <= 0xFF) { else if (code >= 0xF0 && code <= 0xFF) {
/* primitive */ /* primitive */
next = vmc.bytecodes[vmc.pc++]; next = proc->bytecodes[proc->pc++];
__dispatch_primitive (stx, ((code & 0x0F) << 8) | next, &vmc); __dispatch_primitive (stx, proc, ((code & 0x0F) << 8) | next);
} }
} }
return 0; return 0;
} }
static int __dispatch_primitive (xp_stx_t* stx, int no, vmcontext_t* vmc) int xp_stx_interp (xp_stx_t* stx, xp_word_t receiver, xp_word_t method)
{
process_t proc;
xp_stx_method_t* mthobj;
xp_word_t i;
// TODO: size of process stack.
if (__init_process(&proc, 10000) == -1) return -1;
mthobj = (xp_stx_method_t*)XP_STX_OBJECT(stx,method);
xp_assert (mthobj != XP_NULL);
proc.literals = mthobj->literals;
proc.bytecodes = XP_STX_DATA(stx, mthobj->bytecodes);
proc.bytecode_size = XP_STX_SIZE(stx, mthobj->bytecodes);
/* TODO: disable the method with arguments for start-up */
proc.argcount = XP_STX_FROM_SMALLINT(mthobj->argcount);
proc.tmpcount = XP_STX_FROM_SMALLINT(mthobj->tmpcount);
proc.method = method;
proc.pc = 0;
proc.stack_base = proc.stack_top;
/* push the receiver */
proc.stack[proc.stack_top++] = receiver;
/* push arguments */
for (i = 0; i < proc.argcount; i++) {
proc.stack[proc.stack_top++] = stx->nil;
}
/* secure space for temporaries */
for (i = 0; i < proc.tmpcount; i++)
proc.stack[proc.stack_top++] = stx->nil;
/* push dummy pc */
proc.stack[proc.stack_top++] = 0;
/* push dummy method */
proc.stack[proc.stack_top++] = stx->nil;
/* push dummy previous stack base */
proc.stack[proc.stack_top++] = 0;
return __run_process (stx, &proc);
}
static int __dispatch_primitive (xp_stx_t* stx, process_t* proc, xp_word_t no)
{ {
switch (no) { switch (no) {
case 0: case 0:
xp_printf (XP_TEXT("Hello, STX Smalltalk\n")); xp_printf (XP_TEXT("[[ hello stx smalltalk ]]\n"));
break;
case 1:
xp_printf (XP_TEXT("<< AMAZING STX SMALLTALK WORLD >>\n"));
break;
case 2:
xp_printf (XP_TEXT("<< FUNKY STX SMALLTALK >> %d\n"),
XP_STX_FROM_SMALLINT(proc->stack[proc->stack_base + 1]));
break; break;
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: interp.h,v 1.5 2005-09-11 15:15:35 bacon Exp $ * $Id: interp.h,v 1.6 2005-09-13 11:15:41 bacon Exp $
*/ */
#ifndef _XP_STX_INTERP_H_ #ifndef _XP_STX_INTERP_H_
@ -11,8 +11,7 @@
extern "C" { extern "C" {
#endif #endif
xp_word_t xp_stx_new_context (xp_stx_t* stx, xp_word_t receiver, xp_word_t method); int xp_stx_interp (xp_stx_t* stx, xp_word_t receiver, xp_word_t method);
int xp_stx_interp (xp_stx_t* stx, xp_word_t context);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -1,5 +1,5 @@
/* /*
* $Id: method.h,v 1.7 2005-09-11 15:15:35 bacon Exp $ * $Id: method.h,v 1.8 2005-09-13 11:15:41 bacon Exp $
*/ */
#ifndef _XP_STX_METHOD_H_ #ifndef _XP_STX_METHOD_H_
@ -7,11 +7,12 @@
#include <xp/stx/stx.h> #include <xp/stx/stx.h>
#define XP_STX_METHOD_SIZE 4 #define XP_STX_METHOD_SIZE 5
#define XP_STX_METHOD_TEXT 0 #define XP_STX_METHOD_TEXT 0
#define XP_STX_METHOD_SELECTOR 1 #define XP_STX_METHOD_SELECTOR 1
#define XP_STX_METHOD_BYTECODES 2 #define XP_STX_METHOD_BYTECODES 2
#define XP_STX_METHOD_TMPCOUNT 3 #define XP_STX_METHOD_TMPCOUNT 3
#define XP_STX_METHOD_ARGCOUNT 4
/* dolphin smalltalk's flags representation /* dolphin smalltalk's flags representation
@ -32,6 +33,7 @@ struct xp_stx_method_t
xp_word_t selector; /* is this necessary? */ xp_word_t selector; /* is this necessary? */
xp_word_t bytecodes; xp_word_t bytecodes;
xp_word_t tmpcount; xp_word_t tmpcount;
xp_word_t argcount;
xp_word_t literals[1]; xp_word_t literals[1];
}; };

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parser.c,v 1.71 2005-09-13 07:07:24 bacon Exp $ * $Id: parser.c,v 1.72 2005-09-13 11:15:41 bacon Exp $
*/ */
#include <xp/stx/parser.h> #include <xp/stx/parser.h>
@ -534,7 +534,8 @@ static int __finish_method (xp_stx_parser_t* parser)
/* TODO: better way to store argument count & temporary count */ /* TODO: better way to store argument count & temporary count */
method_obj->tmpcount = method_obj->tmpcount =
XP_STX_TO_SMALLINT(parser->temporary_count); XP_STX_TO_SMALLINT(parser->temporary_count - parser->argument_count);
method_obj->argcount = XP_STX_TO_SMALLINT(parser->argument_count);
xp_stx_dict_put (stx, class_obj->methods, selector, method); xp_stx_dict_put (stx, class_obj->methods, selector, method);
return 0; return 0;
@ -1166,8 +1167,8 @@ static int __parse_keyword_message (xp_stx_parser_t* parser)
xp_stx_name_close (&name); xp_stx_name_close (&name);
return -1; return -1;
} }
/*EMIT_SEND_TO_SELF (parser, 0, pos);*/ /*EMIT_SEND_TO_SELF (parser, nargs, pos);*/
if (__emit_send_to_self(parser,0,pos) == -1) { if (__emit_send_to_self(parser,nargs,pos) == -1) {
xp_stx_name_close (&name); xp_stx_name_close (&name);
return -1; return -1;
} }

View File

@ -159,6 +159,18 @@ int xp_main (int argc, xp_char_t* argv[])
xp_stx_parser_error_string (&parser)); xp_stx_parser_error_string (&parser));
} }
if (xp_stx_parser_parse_method (&parser, stx.class_symbol,
(void*)XP_TEXT("test2.st")) == -1) {
xp_printf (XP_TEXT("parser error <%s>\n"),
xp_stx_parser_error_string (&parser));
}
if (xp_stx_parser_parse_method (&parser, stx.class_symbol,
(void*)XP_TEXT("test3.st")) == -1) {
xp_printf (XP_TEXT("parser error <%s>\n"),
xp_stx_parser_error_string (&parser));
}
xp_printf (XP_TEXT("== Decoded Methods ==\n")); xp_printf (XP_TEXT("== Decoded Methods ==\n"));
if (xp_stx_decode(&stx, n) == -1) { if (xp_stx_decode(&stx, n) == -1) {
xp_printf (XP_TEXT("parser error <%s>\n"), xp_printf (XP_TEXT("parser error <%s>\n"),
@ -171,7 +183,7 @@ int xp_main (int argc, xp_char_t* argv[])
xp_printf (XP_TEXT("cannot lookup method main\n")); xp_printf (XP_TEXT("cannot lookup method main\n"));
} }
else { else {
xp_stx_interp (&stx, xp_stx_new_context (&stx, n, m)); xp_stx_interp (&stx, n, m);
} }
} }

View File

@ -2,7 +2,7 @@ main
| a b | | a b |
<primitive: 0> <primitive: 0>
a := 10. #abc prim1.
#abc xxx. #def prim1.
b := 3. #def prim2: 4512.
^nil ^nil