| 
									
										
										
										
											2005-05-13 16:45:55 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2005-10-02 15:45:09 +00:00
										 |  |  |  * $Id: interp.c,v 1.19 2005-10-02 15:45:09 bacon Exp $ | 
					
						
							| 
									
										
										
										
											2005-05-13 16:45:55 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <xp/stx/interp.h>
 | 
					
						
							| 
									
										
										
										
											2005-08-15 16:03:57 +00:00
										 |  |  | #include <xp/stx/method.h>
 | 
					
						
							|  |  |  | #include <xp/stx/object.h>
 | 
					
						
							|  |  |  | #include <xp/stx/array.h>
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | #include <xp/stx/class.h>
 | 
					
						
							| 
									
										
										
										
											2005-08-16 15:49:04 +00:00
										 |  |  | #include <xp/bas/assert.h>
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | #include <xp/bas/memory.h>
 | 
					
						
							| 
									
										
										
										
											2005-05-13 16:45:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | /*
 | 
					
						
							|  |  |  | activation record | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | .... | 
					
						
							|  |  |  | .... | 
					
						
							|  |  |  | .... | 
					
						
							|  |  |  | ------------------- | 
					
						
							|  |  |  | previous stack_base | 
					
						
							|  |  |  | ------------------- | 
					
						
							|  |  |  | method | 
					
						
							|  |  |  | ------------------- | 
					
						
							|  |  |  | pc | 
					
						
							|  |  |  | ------------------- | 
					
						
							|  |  |  | temporaries | 
					
						
							|  |  |  | ------------------- | 
					
						
							|  |  |  | arguments | 
					
						
							|  |  |  | ------------------- | 
					
						
							|  |  |  | receiver | 
					
						
							|  |  |  | -------------------   <----- current stack_base | 
					
						
							|  |  |  | .... | 
					
						
							|  |  |  | .... | 
					
						
							|  |  |  | .... | 
					
						
							| 
									
										
										
										
											2005-05-15 18:37:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2005-05-15 18:37:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | struct process_t | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	xp_word_t* stack; | 
					
						
							|  |  |  | 	xp_word_t  stack_size; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 	xp_word_t  stack_base; | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | 	xp_word_t  stack_top; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-30 12:19:00 +00:00
										 |  |  | 	xp_word_t  receiver; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 	xp_word_t  method; | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | 	xp_word_t  pc; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 	/* cached information about the method above */ | 
					
						
							|  |  |  | 	xp_word_t* literals; | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | 	xp_byte_t* bytecodes; | 
					
						
							|  |  |  | 	xp_word_t  bytecode_size; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 	xp_size_t  argcount; | 
					
						
							|  |  |  | 	xp_size_t  tmpcount; | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | typedef struct process_t process_t; | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | static int __run_process (xp_stx_t* stx, process_t* proc); | 
					
						
							|  |  |  | static int __push_to_stack (xp_stx_t* stx,  | 
					
						
							|  |  |  | 	process_t* proc, xp_word_t what, xp_word_t index); | 
					
						
							|  |  |  | static int __store_from_stack (xp_stx_t* stx,  | 
					
						
							|  |  |  | 	process_t* proc, xp_word_t what, xp_word_t index); | 
					
						
							| 
									
										
										
										
											2005-10-02 10:44:49 +00:00
										 |  |  | static int __send_message (xp_stx_t* stx, process_t* proc,  | 
					
						
							|  |  |  | 	xp_word_t nargs, xp_word_t selector, xp_bool_t to_super); | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | static int __return_from_message (xp_stx_t* stx, process_t* proc); | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | static int __dispatch_primitive (xp_stx_t* stx, process_t* proc, xp_word_t no); | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | int xp_stx_interp (xp_stx_t* stx, xp_word_t receiver, xp_word_t method) | 
					
						
							| 
									
										
										
										
											2005-09-12 15:55:13 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	process_t proc; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 	xp_stx_method_t* mthobj; | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	xp_word_t i; | 
					
						
							|  |  |  | 	int n; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	// TODO: size of process stack.
 | 
					
						
							|  |  |  | 	proc.stack = (xp_word_t*)xp_malloc (10000 * xp_sizeof(xp_word_t)); | 
					
						
							|  |  |  | 	if (proc.stack == XP_NULL) { | 
					
						
							|  |  |  | xp_printf (XP_TEXT("out of memory in xp_stx_interp\n")); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2005-09-12 15:55:13 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	proc.stack_size = 10000; | 
					
						
							|  |  |  | 	proc.stack_base = 0; | 
					
						
							|  |  |  | 	proc.stack_top = 0; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 	mthobj = (xp_stx_method_t*)XP_STX_OBJECT(stx,method); | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	xp_assert (mthobj != XP_NULL); | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	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); | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-30 12:19:00 +00:00
										 |  |  | 	proc.receiver = receiver; | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	proc.method = method; | 
					
						
							|  |  |  | 	proc.pc = 0; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	proc.stack_base = proc.stack_top; | 
					
						
							| 
									
										
										
										
											2005-09-12 15:55:13 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	/* push the receiver */ | 
					
						
							|  |  |  | 	proc.stack[proc.stack_top++] = receiver; | 
					
						
							| 
									
										
										
										
											2005-08-15 16:03:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	/* push arguments */ | 
					
						
							|  |  |  | 	for (i = 0; i < proc.argcount; i++) { | 
					
						
							|  |  |  | 		proc.stack[proc.stack_top++] = stx->nil; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	/* secure space for temporaries */ | 
					
						
							|  |  |  | 	for (i = 0; i < proc.tmpcount; i++)  | 
					
						
							|  |  |  | 		proc.stack[proc.stack_top++] = stx->nil; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	/* 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; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	n = __run_process (stx, &proc); | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	xp_free (proc.stack); | 
					
						
							|  |  |  | 	return n; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2005-08-15 16:03:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | static int __run_process (xp_stx_t* stx, process_t* proc) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	int code, next, next2; | 
					
						
							| 
									
										
										
										
											2005-08-15 16:03:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 	while (proc->pc < proc->bytecode_size) { | 
					
						
							|  |  |  | 		code = proc->bytecodes[proc->pc++]; | 
					
						
							| 
									
										
										
										
											2005-08-15 16:03:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-11 15:43:14 +00:00
										 |  |  | #ifdef DEBUG
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 		xp_printf (XP_TEXT("code = 0x%x\n"), code); | 
					
						
							| 
									
										
										
										
											2005-09-11 15:43:14 +00:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-08-15 16:03:57 +00:00
										 |  |  | 		if (code >= 0x00 && code <= 0x3F) { | 
					
						
							|  |  |  | 			/* stack - push */ | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 			__push_to_stack (stx, proc, code >> 4, code & 0x0F); | 
					
						
							| 
									
										
										
										
											2005-05-13 16:45:55 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-08-15 16:03:57 +00:00
										 |  |  | 		else if (code >= 0x40 && code <= 0x5F) { | 
					
						
							|  |  |  | 			/* stack - store */ | 
					
						
							|  |  |  | 			int what = code >> 4; | 
					
						
							|  |  |  | 			int index = code & 0x0F; | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 			__store_from_stack (stx, proc, code >> 4, code & 0x0F); | 
					
						
							| 
									
										
										
										
											2005-09-30 12:19:00 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* TODO: more here .... */ | 
					
						
							| 
									
										
										
										
											2005-08-15 16:03:57 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-02 15:45:09 +00:00
										 |  |  | 		else if (code == 0x67) { | 
					
						
							|  |  |  | 			/*  pop stack top */ | 
					
						
							|  |  |  | 			proc->stack_top--; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		/* TODO: more here .... */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-30 12:19:00 +00:00
										 |  |  | 		else if (code == 0x6A) { | 
					
						
							|  |  |  | 			proc->stack[proc->stack_top++] =  stx->nil; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		else if (code == 0x6B) { | 
					
						
							| 
									
										
										
										
											2005-10-01 05:33:06 +00:00
										 |  |  | 			proc->stack[proc->stack_top++] = stx->true; | 
					
						
							| 
									
										
										
										
											2005-09-30 12:19:00 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (code == 0x6C) { | 
					
						
							| 
									
										
										
										
											2005-10-01 05:33:06 +00:00
										 |  |  | 			proc->stack[proc->stack_top++] = stx->false; | 
					
						
							| 
									
										
										
										
											2005-09-30 12:19:00 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (code == 0x6D) { | 
					
						
							|  |  |  | 			/* push receiver */ | 
					
						
							| 
									
										
										
										
											2005-10-01 05:33:06 +00:00
										 |  |  | 			proc->stack[proc->stack_top++] = proc->receiver; | 
					
						
							| 
									
										
										
										
											2005-05-13 16:45:55 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-30 12:19:00 +00:00
										 |  |  | 		/* TODO: more here .... */ | 
					
						
							| 
									
										
										
										
											2005-09-11 17:01:56 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		else if (code == 0x70) { | 
					
						
							| 
									
										
										
										
											2005-10-02 10:44:49 +00:00
										 |  |  | 			/* send message to self */ | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 			next = proc->bytecodes[proc->pc++]; | 
					
						
							| 
									
										
										
										
											2005-10-02 10:44:49 +00:00
										 |  |  | 			if (__send_message (stx, proc, next >> 5,  | 
					
						
							|  |  |  | 				proc->literals[next & 0x1F], xp_false) == -1) break; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 		}	 | 
					
						
							| 
									
										
										
										
											2005-09-11 17:01:56 +00:00
										 |  |  | 		else if (code == 0x71) { | 
					
						
							| 
									
										
										
										
											2005-10-02 10:44:49 +00:00
										 |  |  | 			/* send message to super */ | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 			next = proc->bytecodes[proc->pc++]; | 
					
						
							| 
									
										
										
										
											2005-10-02 10:44:49 +00:00
										 |  |  | 			if (__send_message (stx, proc, next >> 5,  | 
					
						
							|  |  |  | 				proc->literals[next & 0x1F], xp_true) == -1) break; | 
					
						
							| 
									
										
										
										
											2005-09-11 17:01:56 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (code == 0x72) { | 
					
						
							| 
									
										
										
										
											2005-10-02 10:44:49 +00:00
										 |  |  | 			/* send message to self extended */ | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 			next = proc->bytecodes[proc->pc++]; | 
					
						
							|  |  |  | 			next2 = proc->bytecodes[proc->pc++]; | 
					
						
							| 
									
										
										
										
											2005-10-02 10:44:49 +00:00
										 |  |  | 			if (__send_message (stx, proc, next >> 5,  | 
					
						
							|  |  |  | 				proc->literals[next2], xp_false) == -1) break; | 
					
						
							| 
									
										
										
										
											2005-09-11 17:01:56 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else if (code == 0x73) { | 
					
						
							| 
									
										
										
										
											2005-10-02 10:44:49 +00:00
										 |  |  | 			/* send message to super extended */ | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 			next = proc->bytecodes[proc->pc++]; | 
					
						
							|  |  |  | 			next2 = proc->bytecodes[proc->pc++]; | 
					
						
							| 
									
										
										
										
											2005-10-02 10:44:49 +00:00
										 |  |  | 			if (__send_message (stx, proc, next >> 5,  | 
					
						
							|  |  |  | 				proc->literals[next2], xp_true) == -1) break; | 
					
						
							| 
									
										
										
										
											2005-09-11 17:01:56 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | 		/* more code .... */ | 
					
						
							| 
									
										
										
										
											2005-10-01 05:33:06 +00:00
										 |  |  | 		else if (code == 0x78) { | 
					
						
							|  |  |  | 			/* return receiver */ | 
					
						
							|  |  |  | 			proc->stack[proc->stack_top++] = proc->receiver; | 
					
						
							|  |  |  | 			if (__return_from_message (stx, proc) == -1) break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 		else if (code == 0x7C) { | 
					
						
							|  |  |  | 			/* return from message */ | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 			if (__return_from_message (stx, proc) == -1) break; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		else if (code >= 0xF0 && code <= 0xFF)  { | 
					
						
							|  |  |  | 			/* primitive */ | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 			next = proc->bytecodes[proc->pc++]; | 
					
						
							|  |  |  | 			__dispatch_primitive (stx, proc, ((code & 0x0F) << 8) | next); | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-10-01 05:33:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | xp_printf (XP_TEXT("INVALID OPCODE...........\n")); | 
					
						
							|  |  |  | break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-08-15 16:03:57 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-05-13 16:45:55 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2005-05-13 16:45:55 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2005-08-16 15:49:04 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | static int __push_to_stack (xp_stx_t* stx,  | 
					
						
							|  |  |  | 	process_t* proc, xp_word_t what, xp_word_t index) | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	switch (what) { | 
					
						
							|  |  |  | 	case 0: /* receiver variable */ | 
					
						
							|  |  |  | 		proc->stack[proc->stack_top++] =  | 
					
						
							|  |  |  | 			XP_STX_WORD_AT(stx, proc->stack[proc->stack_base], index); | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 1: /* temporary variable */ | 
					
						
							|  |  |  | 		proc->stack[proc->stack_top++] =  | 
					
						
							|  |  |  | 			proc->stack[proc->stack_base + 1 + index]; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 2: /* literal constant */ | 
					
						
							|  |  |  | 		proc->stack[proc->stack_top++] = proc->literals[index]; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case 3: /* literal variable */ | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int __store_from_stack (xp_stx_t* stx,  | 
					
						
							|  |  |  | 	process_t* proc, xp_word_t what, xp_word_t index) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	switch (what) { | 
					
						
							|  |  |  | 	case 4: /* receiver variable */ | 
					
						
							|  |  |  | 		XP_STX_WORD_AT(stx,proc->stack[proc->stack_base],index) = proc->stack[--proc->stack_top]; | 
					
						
							|  |  |  | 		break;  | 
					
						
							|  |  |  | 	case 5: /* temporary location */ | 
					
						
							|  |  |  | 		proc->stack[proc->stack_base + 1 + index] = proc->stack[--proc->stack_top]; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-02 10:44:49 +00:00
										 |  |  | static int __send_message (xp_stx_t* stx, process_t* proc,  | 
					
						
							|  |  |  | 	xp_word_t nargs, xp_word_t selector, xp_bool_t to_super) | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	xp_word_t receiver, method;  | 
					
						
							|  |  |  | 	xp_word_t i, tmpcount, argcount; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 	xp_stx_method_t* mthobj; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	xp_assert (XP_STX_CLASS(stx,selector) == stx->class_symbol); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	receiver = proc->stack[proc->stack_top - nargs - 1]; | 
					
						
							| 
									
										
										
										
											2005-10-02 15:45:09 +00:00
										 |  |  | 	method = xp_stx_lookup_method ( | 
					
						
							|  |  |  | 		stx, XP_STX_CLASS(stx,receiver),  | 
					
						
							|  |  |  | 		XP_STX_DATA(stx,selector), to_super); | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	if (method == stx->nil) { | 
					
						
							|  |  |  | xp_printf (XP_TEXT("cannot find the method....\n")); | 
					
						
							|  |  |  | 		return -1;	 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 	mthobj = (xp_stx_method_t*)XP_STX_OBJECT(stx,method); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	argcount = XP_STX_FROM_SMALLINT(mthobj->argcount); | 
					
						
							|  |  |  | 	tmpcount = XP_STX_FROM_SMALLINT(mthobj->tmpcount); | 
					
						
							|  |  |  | 	xp_assert (argcount == nargs); | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	/* secure space for temporaries */ | 
					
						
							|  |  |  | 	for (i = 0; i < tmpcount; i++) { | 
					
						
							|  |  |  | 		proc->stack[proc->stack_top++] = stx->nil; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	/* 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; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	proc->stack_base = proc->stack_top - 3 - tmpcount - argcount - 1; | 
					
						
							|  |  |  | 	xp_assert (proc->stack_base > 0); | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-30 12:19:00 +00:00
										 |  |  | 	proc->receiver = receiver; | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	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) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	xp_word_t method, pc, stack_base; | 
					
						
							|  |  |  | 	xp_stx_method_t* mthobj; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (proc->stack_base == 0) { | 
					
						
							|  |  |  | 		/* return from the startup method */ | 
					
						
							|  |  |  | 		return -1; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	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]; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	mthobj = (xp_stx_method_t*)XP_STX_OBJECT(stx,method); | 
					
						
							|  |  |  | 	xp_assert (mthobj != XP_NULL); | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2005-09-30 12:19:00 +00:00
										 |  |  | 	/* return value is located on top of the previous stack */ | 
					
						
							|  |  |  | 	proc->stack[proc->stack_base - 1] = proc->stack[proc->stack_top - 1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	/* restore the stack pointers */ | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	proc->stack_top = proc->stack_base; | 
					
						
							|  |  |  | 	proc->stack_base = stack_base; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-09-30 12:19:00 +00:00
										 |  |  | 	proc->receiver = proc->stack[stack_base]; | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	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; | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static int __dispatch_primitive (xp_stx_t* stx, process_t* proc, xp_word_t no) | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	switch (no) { | 
					
						
							|  |  |  | 	case 0: | 
					
						
							| 
									
										
										
										
											2005-09-13 11:15:41 +00:00
										 |  |  | 		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])); | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2005-09-13 12:10:23 +00:00
										 |  |  | 	case 3: | 
					
						
							|  |  |  | 		xp_printf (XP_TEXT("<<  HIGH STX SMALLTALK  >> %d, %d\n"),  | 
					
						
							|  |  |  | 			XP_STX_FROM_SMALLINT(proc->stack[proc->stack_base + 1]), | 
					
						
							|  |  |  | 			XP_STX_FROM_SMALLINT(proc->stack[proc->stack_base + 2])); | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2005-10-02 15:45:09 +00:00
										 |  |  | 	case 20: | 
					
						
							|  |  |  | 		xp_printf (XP_TEXT("<< PRIMITIVE 20 >>\n")); | 
					
						
							|  |  |  | 		break; | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2005-09-13 15:56:23 +00:00
										 |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2005-09-11 13:17:35 +00:00
										 |  |  | } |