added JUMP2_FORWARD and JUMP2_BACKWARD

This commit is contained in:
hyunghwan.chung 2015-07-01 07:21:54 +00:00
parent 2d2039f4a5
commit d6a9ca91fa
4 changed files with 209 additions and 504 deletions

View File

@ -1499,7 +1499,6 @@ static int emit_single_param_instruction (stix_t* stix, int cmd, stix_oow_t para
case BCODE_JUMP_BACKWARD_0: case BCODE_JUMP_BACKWARD_0:
case BCODE_JUMP_IF_TRUE_0: case BCODE_JUMP_IF_TRUE_0:
case BCODE_JUMP_IF_FALSE_0: case BCODE_JUMP_IF_FALSE_0:
case BCODE_JUMP_BY_OFFSET_0:
if (param_1 < 4) if (param_1 < 4)
{ {
bc = (stix_byte_t)(cmd & 0xFC) | (stix_byte_t)param_1; bc = (stix_byte_t)(cmd & 0xFC) | (stix_byte_t)param_1;
@ -1511,6 +1510,11 @@ static int emit_single_param_instruction (stix_t* stix, int cmd, stix_oow_t para
bc = cmd | 0x80; bc = cmd | 0x80;
goto write_long; goto write_long;
} }
case BCODE_JUMP2_FORWARD:
case BCODE_JUMP2_BACKWARD:
bc = cmd;
goto write_long;
} }
stix->errnum = STIX_EINVAL; stix->errnum = STIX_EINVAL;
@ -2503,21 +2507,35 @@ printf ("\treturn_from_block\n");
} }
block_code_size = stix->c->mth.code.len - jump_inst_pos - (STIX_BCODE_LONG_PARAM_SIZE + 1); block_code_size = stix->c->mth.code.len - jump_inst_pos - (STIX_BCODE_LONG_PARAM_SIZE + 1);
if (block_code_size > MAX_CODE_BLKCODE) if (block_code_size > MAX_CODE_JUMP * 2)
{ {
/* TOOD: increate the max block code size and
* if it exceedes the limit for BCODE_JUMP_FORWARD_X, switch to BECODE_JUMP_BY_OFFSET */
set_syntax_error (stix, STIX_SYNERR_BLKFLOOD, &block_loc, STIX_NULL); set_syntax_error (stix, STIX_SYNERR_BLKFLOOD, &block_loc, STIX_NULL);
return -1; return -1;
} }
else
{
stix_size_t jump_offset;
if (block_code_size > MAX_CODE_JUMP)
{
printf ("\tfixed jump to jump2\n");
stix->c->mth.code.ptr[jump_inst_pos] = BCODE_JUMP2_FORWARD;
jump_offset = block_code_size - MAX_CODE_JUMP;
}
else
{
jump_offset = block_code_size;
}
printf ("\tfixed jump offset to %u\n", (unsigned int)jump_offset);
/* note that the jump offset is a signed number */
#if (STIX_BCODE_LONG_PARAM_SIZE == 2) #if (STIX_BCODE_LONG_PARAM_SIZE == 2)
stix->c->mth.code.ptr[jump_inst_pos + 1] = block_code_size >> 8; stix->c->mth.code.ptr[jump_inst_pos + 1] = jump_offset >> 8;
stix->c->mth.code.ptr[jump_inst_pos + 2] = ((stix_int16_t)block_code_size & 0xFF); stix->c->mth.code.ptr[jump_inst_pos + 2] = jump_offset & 0xFF;
#else #else
stix->c->mth.code.ptr[jump_inst_pos + 1] = block_code_size ; stix->c->mth.code.ptr[jump_inst_pos + 1] = jump_offset;
#endif #endif
}
/* restore the temporary count */ /* restore the temporary count */
stix->c->mth.tmprs.len = saved_tmprs_len; stix->c->mth.tmprs.len = saved_tmprs_len;

View File

@ -728,6 +728,58 @@ static int primitive_integer_sub (stix_t* stix, stix_ooi_t nargs)
return 0; return 0;
} }
static int primitive_integer_mul (stix_t* stix, stix_ooi_t nargs)
{
stix_ooi_t tmp;
stix_oop_t rcv, arg;
STIX_ASSERT (nargs == 1);
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
arg = ACTIVE_STACK_GET(stix, stix->sp);
if (STIX_OOP_IS_SMINT(rcv) && STIX_OOP_IS_SMINT(arg))
{
tmp = STIX_OOP_TO_SMINT(rcv) * STIX_OOP_TO_SMINT(arg);
/* TODO: check overflow. if so convert it to LargeInteger */
ACTIVE_STACK_POP (stix);
ACTIVE_STACK_SETTOP (stix, STIX_OOP_FROM_SMINT(tmp));
return 1;
}
/* TODO: handle LargeInteger */
return 0;
}
static int primitive_integer_eq (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t rcv, arg;
STIX_ASSERT (nargs == 1);
rcv = ACTIVE_STACK_GET(stix, stix->sp - 1);
arg = ACTIVE_STACK_GET(stix, stix->sp);
if (STIX_OOP_IS_SMINT(rcv) && STIX_OOP_IS_SMINT(arg))
{
ACTIVE_STACK_POP (stix);
if (STIX_OOP_TO_SMINT(rcv) < STIX_OOP_TO_SMINT(arg))
{
ACTIVE_STACK_SETTOP (stix, stix->_true);
}
else
{
ACTIVE_STACK_SETTOP (stix, stix->_false);
}
return 1;
}
/* TODO: handle LargeInteger */
return 0;
}
static int primitive_integer_lt (stix_t* stix, stix_ooi_t nargs) static int primitive_integer_lt (stix_t* stix, stix_ooi_t nargs)
{ {
stix_oop_t rcv, arg; stix_oop_t rcv, arg;
@ -796,17 +848,19 @@ typedef struct primitive_t primitive_t;
static primitive_t primitives[] = static primitive_t primitives[] =
{ {
{ -1, primitive_dump }, { -1, primitive_dump }, /* 0 */
{ 0, primitive_new }, { 0, primitive_new }, /* 1 */
{ 1, primitive_new_with_size }, { 1, primitive_new_with_size }, /* 2 */
{ 0, primitive_basic_size }, { 0, primitive_basic_size }, /* 3 */
{ 1, primitive_basic_at }, { 1, primitive_basic_at }, /* 4 */
{ 2, primitive_basic_at_put }, { 2, primitive_basic_at_put }, /* 5 */
{ -1, primitive_block_context_value }, { -1, primitive_block_context_value }, /* 6 */
{ 1, primitive_integer_add }, { 1, primitive_integer_add }, /* 7 */
{ 1, primitive_integer_sub }, { 1, primitive_integer_sub }, /* 8 */
{ 1, primitive_integer_lt }, { 1, primitive_integer_mul }, /* 9 */
{ 1, primitive_integer_gt } { 1, primitive_integer_eq }, /* 10 */
{ 1, primitive_integer_lt }, /* 11 */
{ 1, primitive_integer_gt } /* 12 */
}; };
@ -1127,7 +1181,6 @@ printf ("JUMP_BACKWARD %d\n", (int)(bcode & 0x3));
case BCODE_JUMP_IF_TRUE_X: case BCODE_JUMP_IF_TRUE_X:
case BCODE_JUMP_IF_FALSE_X: case BCODE_JUMP_IF_FALSE_X:
case BCODE_JUMP_BY_OFFSET_X:
case BCODE_JUMP_IF_TRUE_0: case BCODE_JUMP_IF_TRUE_0:
case BCODE_JUMP_IF_TRUE_1: case BCODE_JUMP_IF_TRUE_1:
case BCODE_JUMP_IF_TRUE_2: case BCODE_JUMP_IF_TRUE_2:
@ -1136,13 +1189,21 @@ printf ("JUMP_BACKWARD %d\n", (int)(bcode & 0x3));
case BCODE_JUMP_IF_FALSE_1: case BCODE_JUMP_IF_FALSE_1:
case BCODE_JUMP_IF_FALSE_2: case BCODE_JUMP_IF_FALSE_2:
case BCODE_JUMP_IF_FALSE_3: case BCODE_JUMP_IF_FALSE_3:
case BCODE_JUMP_BY_OFFSET_0:
case BCODE_JUMP_BY_OFFSET_1:
case BCODE_JUMP_BY_OFFSET_2:
case BCODE_JUMP_BY_OFFSET_3:
printf ("<<<<<<<<<<<<<< JUMP NOT IMPLEMENTED YET >>>>>>>>>>>> \n"); printf ("<<<<<<<<<<<<<< JUMP NOT IMPLEMENTED YET >>>>>>>>>>>> \n");
stix->errnum = STIX_ENOIMPL; stix->errnum = STIX_ENOIMPL;
return -1; return -1;
case BCODE_JUMP2_FORWARD:
FETCH_PARAM_CODE_TO (stix, b1);
printf ("JUMP2_FORWARD %d\n", (int)b1);
stix->ip += MAX_CODE_JUMP + b1;
break;
break;
case BCODE_JUMP2_BACKWARD:
FETCH_PARAM_CODE_TO (stix, b1);
printf ("JUMP2_BACKWARD %d\n", (int)b1);
stix->ip -= MAX_CODE_JUMP + b1;
break; break;
/* -------------------------------------------------------- */ /* -------------------------------------------------------- */

View File

@ -43,7 +43,6 @@
#define STIX_DEBUG_GC_001 #define STIX_DEBUG_GC_001
#include <stdio.h> /* TODO: delete these header inclusion lines */ #include <stdio.h> /* TODO: delete these header inclusion lines */
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
@ -477,7 +476,7 @@ struct stix_compiler_t
# define MAX_CODE_NBLKARGS (0xFFu) # define MAX_CODE_NBLKARGS (0xFFu)
# define MAX_CODE_NBLKTMPRS (0xFFu) # define MAX_CODE_NBLKTMPRS (0xFFu)
# define MAX_CODE_PRIMNO (0xFFFFu) # define MAX_CODE_PRIMNO (0xFFFFu)
# define MAX_CODE_JUMP (0xFF) # define MAX_CODE_JUMP (0xFFu)
#elif defined(STIX_BCODE_LONG_PARAM_SIZE) && (STIX_BCODE_LONG_PARAM_SIZE == 2) #elif defined(STIX_BCODE_LONG_PARAM_SIZE) && (STIX_BCODE_LONG_PARAM_SIZE == 2)
# define MAX_CODE_INDEX (0xFFFFu) # define MAX_CODE_INDEX (0xFFFFu)
# define MAX_CODE_NTMPRS (0xFFFFu) # define MAX_CODE_NTMPRS (0xFFFFu)
@ -485,14 +484,11 @@ struct stix_compiler_t
# define MAX_CODE_NBLKARGS (0xFFFFu) # define MAX_CODE_NBLKARGS (0xFFFFu)
# define MAX_CODE_NBLKTMPRS (0xFFFFu) # define MAX_CODE_NBLKTMPRS (0xFFFFu)
# define MAX_CODE_PRIMNO (0xFFFFu) # define MAX_CODE_PRIMNO (0xFFFFu)
# define MAX_CODE_JUMP (0xFFFF) # define MAX_CODE_JUMP (0xFFFFu)
#else #else
# error Unsupported STIX_BCODE_LONG_PARAM_SIZE # error Unsupported STIX_BCODE_LONG_PARAM_SIZE
#endif #endif
#define MAX_CODE_BLKCODE MAX_CODE_JUMP
/* /*
---------------------------------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------
@ -527,8 +523,8 @@ SHORT INSTRUCTION CODE LONG INSTRUCTION C
72-75 0100 10XX JUMP_BACKWARD 200 1100 1000 XXXXXXXX JUMP_BACKWARD_X 72-75 0100 10XX JUMP_BACKWARD 200 1100 1000 XXXXXXXX JUMP_BACKWARD_X
76-79 0100 11XX JUMP_IF_TRUE 204 1100 1100 XXXXXXXX JUMP_IF_TRUE_X 76-79 0100 11XX JUMP_IF_TRUE 204 1100 1100 XXXXXXXX JUMP_IF_TRUE_X
80-83 0101 00XX JUMP_IF_FALSE 208 1101 0000 XXXXXXXX JUMP_IF_FALSE_X 80-83 0101 00XX JUMP_IF_FALSE 208 1101 0000 XXXXXXXX JUMP_IF_FALSE_X
84-87 0101 01XX JUMP_BY_OFFSET 212 1101 0100 XXXXXXXX JUMP_BY_OFFSET_X
# for JUMP_BY_OFFSET, XX is an index to literal frame pointing to a small integer. 84-87 0101 01XX UNUSED
vv vv
88-91 0101 10XX YYYYYYYY STORE_INTO_CTXTEMPVAR 216 1101 1000 XXXXXXXX YYYYYYYY STORE_INTO_CTXTEMPVAR_X (bit 3 on, bit 2 off) 88-91 0101 10XX YYYYYYYY STORE_INTO_CTXTEMPVAR 216 1101 1000 XXXXXXXX YYYYYYYY STORE_INTO_CTXTEMPVAR_X (bit 3 on, bit 2 off)
@ -659,15 +655,12 @@ enum stix_bcode_t
BCODE_JUMP_IF_TRUE_2 = 0x4E, BCODE_JUMP_IF_TRUE_2 = 0x4E,
BCODE_JUMP_IF_TRUE_3 = 0x4F, BCODE_JUMP_IF_TRUE_3 = 0x4F,
BCODE_JUMP_IF_FALSE_0 = 0x50, BCODE_JUMP_IF_FALSE_0 = 0x50, /* 80 */
BCODE_JUMP_IF_FALSE_1 = 0x51, BCODE_JUMP_IF_FALSE_1 = 0x51, /* 81 */
BCODE_JUMP_IF_FALSE_2 = 0x52, BCODE_JUMP_IF_FALSE_2 = 0x52, /* 82 */
BCODE_JUMP_IF_FALSE_3 = 0x53, BCODE_JUMP_IF_FALSE_3 = 0x53, /* 83 */
BCODE_JUMP_BY_OFFSET_0 = 0x54,
BCODE_JUMP_BY_OFFSET_1 = 0x55,
BCODE_JUMP_BY_OFFSET_2 = 0x56,
BCODE_JUMP_BY_OFFSET_3 = 0x57,
BCODE_STORE_INTO_CTXTEMPVAR_0 = 0x58, /* 88 */ BCODE_STORE_INTO_CTXTEMPVAR_0 = 0x58, /* 88 */
BCODE_STORE_INTO_CTXTEMPVAR_1 = 0x59, /* 89 */ BCODE_STORE_INTO_CTXTEMPVAR_1 = 0x59, /* 89 */
@ -729,7 +722,7 @@ enum stix_bcode_t
BCODE_JUMP_BACKWARD_X = 0xC8, /* 200 */ BCODE_JUMP_BACKWARD_X = 0xC8, /* 200 */
BCODE_JUMP_IF_TRUE_X = 0xCC, /* 204 */ BCODE_JUMP_IF_TRUE_X = 0xCC, /* 204 */
BCODE_JUMP_IF_FALSE_X = 0xD0, /* 208 */ BCODE_JUMP_IF_FALSE_X = 0xD0, /* 208 */
BCODE_JUMP_BY_OFFSET_X = 0xD4, /* 212 */
BCODE_STORE_INTO_CTXTEMPVAR_X = 0xD8, /* 216 */ BCODE_STORE_INTO_CTXTEMPVAR_X = 0xD8, /* 216 */
BCODE_POP_INTO_CTXTEMPVAR_X = 0xDC, /* 220 */ BCODE_POP_INTO_CTXTEMPVAR_X = 0xDC, /* 220 */
@ -743,15 +736,18 @@ enum stix_bcode_t
BCODE_SEND_MESSAGE_TO_SUPER_X = 0xF4, /* 244 */ BCODE_SEND_MESSAGE_TO_SUPER_X = 0xF4, /* 244 */
BCODE_PUSH_RECEIVER = 0x81, BCODE_JUMP2_FORWARD = 0xC5, /* 197 */
BCODE_PUSH_NIL = 0x82, BCODE_JUMP2_BACKWARD = 0xC9, /* 201 */
BCODE_PUSH_TRUE = 0x83,
BCODE_PUSH_FALSE = 0x84, BCODE_PUSH_RECEIVER = 0x81, /* 129 */
BCODE_PUSH_CONTEXT = 0x85, BCODE_PUSH_NIL = 0x82, /* 130 */
BCODE_PUSH_NEGONE = 0x86, BCODE_PUSH_TRUE = 0x83, /* 131 */
BCODE_PUSH_ZERO = 0x87, BCODE_PUSH_FALSE = 0x84, /* 132 */
BCODE_PUSH_ONE = 0x89, BCODE_PUSH_CONTEXT = 0x85, /* 133 */
BCODE_PUSH_TWO = 0x91, BCODE_PUSH_NEGONE = 0x86, /* 134 */
BCODE_PUSH_ZERO = 0x87, /* 135 */
BCODE_PUSH_ONE = 0x89, /* 137 */
BCODE_PUSH_TWO = 0x8A, /* 138 */
/* UNUSED 0xE8 - 0xF8 */ /* UNUSED 0xE8 - 0xF8 */

View File

@ -1,375 +1,5 @@
#class Stix(nil)
{
#dcl(#class) sysdic.
#method(#class) yourself #include 'Stix.st'
{
^self.
}
#method yourself
{
^self.
}
#method(#class) dump
{
<primitive: 0>
}
#method dump
{
<primitive: 0>
}
#method(#class) new
{
<primitive: 1>
}
#method(#class) new: anInteger
{
<primitive: 2>
}
#method basicSize
{
<primitive: 3>
^0
}
#method basicAt: anInteger
{
<primitive: 4>
## self error: 'out of range'.
}
#method basicAt: anInteger put: anObject
{
<primitive: 5>
## self error: 'out of range'.
}
#method badReturnError
{
## TODO: implement this
}
#method mustBeBoolean
{
## TODO: implement this
}
#method doesNotUnderstand: aMessageSymbol
{
## TODO: implement this
}
#method error: anErrorString
{
anErrorString dump.
}
}
#class Object(Stix)
{
}
#class NilObject(Stix)
{
}
#class(#pointer) Class(Stix)
{
#dcl spec selfspec superclass subclasses name instvars classvars classinstvars instmthdic classmthdic.
}
#class Magnitude(Object)
{
}
#class Association(Magnitude)
{
#dcl key value.
}
#class Character(Magnitude)
{
}
#class Number(Magnitude)
{
#method add: aNumber
{
<primitive: 7>
}
#method + aNumber
{
<primitive: 7>
}
#method - aNumber
{
<primitive: 8>
}
#method < aNumber
{
<primitive: 9>
}
}
#class SmallInteger(Number)
{
}
#class Boolean(Object)
{
}
#class True(Boolean)
{
#method ifTrue: trueBlock ifFalse: falseBlock
{
^trueBlock value.
}
#method ifTrue: trueBlock
{
^trueBlock value.
}
#method ifFalse: falseBlock
{
^nil.
}
}
#class False(Boolean)
{
#method ifTrue: trueBlock ifFalse: falseBlock
{
^falseBlock value.
}
#method ifTrue: trueBlock
{
^nil.
}
#method ifFalse: falseBlock
{
^falseBlock value.
}
}
#class Collection(Object)
{
}
#class(#byte) ByteArray(Collection)
{
#method at: anInteger
{
^self basicAt: anInteger.
}
#method at: anInteger put: aValue
{
^self basicAt: anInteger put: aValue.
}
}
#class(#pointer) Array(Collection)
{
#method at: anInteger
{
^self basicAt: anInteger.
}
#method at: anInteger put: aValue
{
^self basicAt: anInteger put: aValue.
}
}
#class(#character) String(Array)
{
}
#class(#character) Symbol(Array)
{
}
#class Set(Collection)
{
#dcl tally bucket.
}
#class SymbolSet(Set)
{
}
#class Dictionary(Set)
{
}
#class SystemDictionary(Dictionary)
{
}
#class MethodDictionary(Dictionary)
{
}
#class(#pointer) Context(Stix)
{
}
#class(#pointer) MethodContext(Context)
{
#dcl sender ip sp ntmprs method receiver home origin.
#method pc
{
^ip
}
#method pc: anInteger
{
ip := anInteger.
"sp := sp - 1." "whould this always work??? "
}
#method sp
{
^sp.
}
#method sp: anInteger
{
sp := anInteger.
}
#method pc: aPC sp: aSP
{
ip := aPC.
sp := aSP.
##sp := sp - 1.
}
}
#class(#pointer) BlockContext(Context)
{
#dcl caller ip sp ntmprs nargs source home origin.
#method value
{
<primitive: 6>
}
#method value: a
{
<primitive: 6>
}
#method value: a value: b
{
<primitive: 6>
}
#method value: a value: b value: c
{
<primitive: 6>
}
#method whileTrue: aBlock
{
## http://stackoverflow.com/questions/2500483/is-there-a-way-in-a-message-only-language-to-define-a-whiletrue-message-without
## ----------------------------------------------------------------------------
## ^(self value) ifTrue: [aBlock value. self whileTrue: aBlock].
## ----------------------------------------------------------------------------
## less block context before whileTrue: is recursively sent.
## whileTrue: is sent in a method context.
## (self value) ifFalse: [^nil].
## aBlock value.
## self whileTrue: aBlock.
## ----------------------------------------------------------------------------
## ----------------------------------------------------------------------------
| pc sp xsp |
sp := thisContext sp.
sp := sp - 1. "decrement sp by 1 becuase thisContext pushed above affects the sp method"
pc := thisContext pc.
self value ifFalse: [ ^nil "^self" ].
aBlock value.
##thisContext pc: pc - 3 sp: sp.
##thisContext pc: pc + 2 sp: sp.
thisContext pc: pc + 1 sp: sp.
## this +2 or - 3 above is dependent on the byte code instruction size used for 'store'
## +2 to skip STORE_INTO_TEMP(pc) and POP_STACKTOP.
## TODO: make it independent of the byte code size
## ----------------------------------------------------------------------------
## #<label>:
## thisContext pc: #<label> sp: sp.
##
## | pc |
## pc := thisContext pc.
## ^self value ifTrue: [aBlock value. thisContext pc: pc]
## ----------------------------------------------------------------------------
## self value ifTrue: [ aBlock value. thisContext restart. ].
}
#method pc
{
^ip
}
#method pc: anInteger
{
ip := anInteger.
}
#method sp
{
^sp
}
#method sp: anInteger
{
sp := anInteger.
}
#method restart
{
ip := source pc.
}
}
#class(#pointer) CompiledMethod(Object)
{
#dcl owner preamble ntmprs nargs code source.
}
################################################################# #################################################################
## MAIN ## MAIN