refreshed whileTrue: and whileFalse:
This commit is contained in:
parent
197ceb3a76
commit
36a54fd29f
@ -22,6 +22,11 @@
|
||||
^self.ip
|
||||
}
|
||||
|
||||
#method pcplus1
|
||||
{
|
||||
^self.ip + 1
|
||||
}
|
||||
|
||||
#method pc: anInteger
|
||||
{
|
||||
self.ip := anInteger.
|
||||
@ -107,24 +112,31 @@
|
||||
<primitive: #_block_value>
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
#method value: a
|
||||
{
|
||||
<primitive: #_block_value>
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
#method value: a value: b
|
||||
{
|
||||
<primitive: #_block_value>
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
#method value: a value: b value: c
|
||||
{
|
||||
<primitive: #_block_value>
|
||||
self primitiveFailed.
|
||||
}
|
||||
#method value: a value: b value: c value: d
|
||||
{
|
||||
<primitive: #_block_value>
|
||||
self primitiveFailed.
|
||||
}
|
||||
#method value: a value: b value: c value: d value: e
|
||||
{
|
||||
<primitive: #_block_value>
|
||||
self primitiveFailed.
|
||||
}
|
||||
|
||||
#method ifTrue: aBlock
|
||||
{
|
||||
@ -143,88 +155,128 @@
|
||||
|
||||
#method whileTrue: aBlock
|
||||
{
|
||||
## http://stackoverflow.com/questions/2500483/is-there-a-way-in-a-message-only-language-to-define-a-whiletrue-message-without
|
||||
## --------------------------------------------------
|
||||
## Naive implementation
|
||||
## --------------------------------------------------
|
||||
## (self value) ifFalse: [^nil].
|
||||
## aBlock value.
|
||||
## self whileTrue: aBlock.
|
||||
## --------------------------------------------------
|
||||
|
||||
## ----------------------------------------------------------------------------
|
||||
## --------------------------------------------------
|
||||
## If VM is built without STIX_USE_PROCSTK
|
||||
## --------------------------------------------------
|
||||
## | pc sp |
|
||||
## sp := thisContext sp.
|
||||
## pc := thisContext pcplus1.
|
||||
## self value ifFalse: [ ^nil "^self" ].
|
||||
## aBlock value.
|
||||
## thisContext pc: pc sp: sp.
|
||||
## --------------------------------------------------
|
||||
|
||||
## ^(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].
|
||||
## --------------------------------------------------
|
||||
## If VM is built with STIX_USE_PROCSTK
|
||||
## --------------------------------------------------
|
||||
| pc |
|
||||
pc := thisContext pcplus1.
|
||||
(self value) ifFalse: [ ^nil "^self" ].
|
||||
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. ].
|
||||
thisContext pc: pc.
|
||||
## --------------------------------------------------
|
||||
}
|
||||
|
||||
#method whileTrue
|
||||
{
|
||||
(self value) ifFalse: [^nil].
|
||||
self whileTrue.
|
||||
## (self value) ifFalse: [^nil].
|
||||
## self whileTrue.
|
||||
|
||||
## --------------------------------------------------
|
||||
## If VM is built with STIX_USE_PROCSTK
|
||||
## --------------------------------------------------
|
||||
| pc |
|
||||
pc := thisContext pcplus1.
|
||||
(self value) ifFalse: [ ^nil "^self" ].
|
||||
thisContext pc: pc.
|
||||
## --------------------------------------------------
|
||||
}
|
||||
|
||||
#method whileFalse: aBlock
|
||||
{
|
||||
(self value) ifTrue: [^nil].
|
||||
## --------------------------------------------------
|
||||
## Naive implementation
|
||||
## --------------------------------------------------
|
||||
## (self value) ifTrue: [^nil].
|
||||
## aBlock value.
|
||||
## self whileFalse: aBlock.
|
||||
## --------------------------------------------------
|
||||
|
||||
## --------------------------------------------------
|
||||
## If VM is built without STIX_USE_PROCSTK
|
||||
## --------------------------------------------------
|
||||
## | pc sp |
|
||||
## sp := thisContext sp.
|
||||
## pc := thisContext pcplus1.
|
||||
## self value ifTrue: [ ^nil "^self" ].
|
||||
## aBlock value.
|
||||
## thisContext pc: pc sp: sp.
|
||||
## --------------------------------------------------
|
||||
|
||||
## --------------------------------------------------
|
||||
## If VM is built with STIX_USE_PROCSTK
|
||||
## --------------------------------------------------
|
||||
## The assignment to 'pc' uses the POP_INTO_TEMPVAR_1.
|
||||
## It pops a value off the stack top, stores it to the second
|
||||
## temporary variable(aBlock is the first temporary variable).
|
||||
## It is a single byte instruction. 'pc' returned by
|
||||
## 'thisContext pcplus1'' should point to the instruction after
|
||||
## the POP_INTO_TEMPVAR_0 instruction.
|
||||
##
|
||||
## It would need the increment of 2 if the pair of
|
||||
## STORE_INTO_TEMPVAR_1 and POP_STACKTOP were used.
|
||||
## This implementation is subject to the instructions chosen
|
||||
## by the compiler.
|
||||
##
|
||||
| pc |
|
||||
pc := thisContext pcplus1.
|
||||
(self value) ifTrue: [ ^nil "^self" ].
|
||||
aBlock value.
|
||||
self whileFalse: aBlock.
|
||||
thisContext pc: pc.
|
||||
## --------------------------------------------------
|
||||
}
|
||||
|
||||
#method whileFalse
|
||||
{
|
||||
(self value) ifTrue: [^nil].
|
||||
self whileFalse.
|
||||
## (self value) ifTrue: [^nil].
|
||||
## self whileFalse.
|
||||
|
||||
## --------------------------------------------------
|
||||
## If VM is built with STIX_USE_PROCSTK
|
||||
## --------------------------------------------------
|
||||
| pc |
|
||||
pc := thisContext pcplus1.
|
||||
(self value) ifTrue: [ ^nil "^self" ].
|
||||
thisContext pc: pc.
|
||||
## --------------------------------------------------
|
||||
}
|
||||
|
||||
#method pc
|
||||
{
|
||||
^ip
|
||||
^self.ip
|
||||
}
|
||||
|
||||
#method pc: anInteger
|
||||
{
|
||||
ip := anInteger.
|
||||
self.ip := anInteger.
|
||||
}
|
||||
|
||||
#method sp
|
||||
{
|
||||
^sp
|
||||
^self.sp
|
||||
}
|
||||
|
||||
#method sp: anInteger
|
||||
{
|
||||
sp := anInteger.
|
||||
self.sp := anInteger.
|
||||
}
|
||||
|
||||
#method restart
|
||||
@ -255,7 +307,6 @@ thisContext isExceptionHandlerContext dump.
|
||||
^self value.
|
||||
}
|
||||
|
||||
|
||||
#method ensure: aBlock
|
||||
{
|
||||
"##
|
||||
|
@ -26,14 +26,13 @@
|
||||
|
||||
#include "stix-prv.h"
|
||||
|
||||
#define TOKEN_NAME_ALIGN 256
|
||||
#define CLASS_BUFFER_ALIGN 8 /* 256 */ /*TODO: change 8 to 256 */
|
||||
#define LITERAL_BUFFER_ALIGN 8 /* 256 */
|
||||
#define CODE_BUFFER_ALIGN 8 /* 256 */
|
||||
#define BALIT_BUFFER_ALIGN 8 /* 256 */
|
||||
#define ARLIT_BUFFER_ALIGN 8 /* 256 */
|
||||
#define BLK_TMPRCNT_BUFFER_ALIGN 8
|
||||
#define POOLDIC_OOP_BUFFER_ALIGN 8
|
||||
#define CLASS_BUFFER_ALIGN 64
|
||||
#define LITERAL_BUFFER_ALIGN 64
|
||||
#define CODE_BUFFER_ALIGN 64
|
||||
#define BALIT_BUFFER_ALIGN 64
|
||||
#define ARLIT_BUFFER_ALIGN 64
|
||||
#define BLK_TMPRCNT_BUFFER_ALIGN 32
|
||||
#define POOLDIC_OOP_BUFFER_ALIGN 32
|
||||
|
||||
/* initial method dictionary size */
|
||||
#define INSTANCE_METHOD_DICTIONARY_SIZE 256 /* TODO: choose the right size */
|
||||
@ -643,7 +642,7 @@ static int get_char (stix_t* stix)
|
||||
{
|
||||
/* if the previous charater was a newline,
|
||||
* increment the line counter and reset column to 1.
|
||||
* incrementing it line number here instead of
|
||||
* incrementing the line number here instead of
|
||||
* updating inp->lxc causes the line number for
|
||||
* TOK_EOF to be the same line as the lxc newline. */
|
||||
stix->c->curinp->line++;
|
||||
|
@ -36,6 +36,10 @@
|
||||
# include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#define PROC_STATE_RUNNING 3
|
||||
#define PROC_STATE_WAITING 2
|
||||
#define PROC_STATE_RUNNABLE 1
|
||||
@ -163,7 +167,27 @@
|
||||
#endif
|
||||
|
||||
|
||||
static STIX_INLINE void vm_gettime (stix_ntime_t* now)
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static void vm_startup (stix_t* stix)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
stix->waitable_timer = CreateWaitableTimer(STIX_NULL, TRUE, STIX_NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void vm_cleanup (stix_t* stix)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
if (stix->waitable_timer)
|
||||
{
|
||||
CloseHandle (stix->waitable_timer);
|
||||
stix->waitable_timer = STIX_NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static STIX_INLINE void vm_gettime (stix_t* stix, stix_ntime_t* now)
|
||||
{
|
||||
#if defined(HAVE_CLOCK_GETTIME)
|
||||
struct timespec ts;
|
||||
@ -180,14 +204,33 @@ static STIX_INLINE void vm_gettime (stix_ntime_t* now)
|
||||
#endif
|
||||
}
|
||||
|
||||
static STIX_INLINE void vm_sleep (const stix_ntime_t* dur)
|
||||
static STIX_INLINE void vm_sleep (stix_t* stix, const stix_ntime_t* dur)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
if (stix->waitable_timer)
|
||||
{
|
||||
LARGE_INTEGER li;
|
||||
li.QuadPart = -STIX_SECNSEC_TO_NSEC(dur->sec, dur->nsec);
|
||||
if(SetWaitableTimer(timer, &li, 0, STIX_NULL, STIX_NULL, FALSE) == FALSE) goto normal_sleep;
|
||||
WaitForSingleObject(timer, INFINITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
normal_sleep:
|
||||
/* fallback to normal Sleep() */
|
||||
Sleep (STIX_SECNSEC_TO_MSEC(dur->sec,dur->nsec));
|
||||
}
|
||||
|
||||
#else
|
||||
struct timespec ts;
|
||||
ts.tv_sec = dur->sec;
|
||||
ts.tv_nsec = dur->nsec;
|
||||
nanosleep (&ts, STIX_NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static stix_oop_process_t make_process (stix_t* stix, stix_oop_context_t c)
|
||||
{
|
||||
stix_oop_process_t proc;
|
||||
@ -1782,7 +1825,7 @@ static int prim_processor_add_timed_semaphore (stix_t* stix, stix_ooi_t nargs)
|
||||
*
|
||||
* this code assumes that the monotonic clock returns a small value
|
||||
* that can fit into a small integer, even after some addtions... */
|
||||
vm_gettime (&now);
|
||||
vm_gettime (stix, &now);
|
||||
STIX_ADDNTIMESNS (&ft, &now, STIX_OOP_TO_SMOOI(sec), STIX_OOP_TO_SMOOI(nsec));
|
||||
if (ft.sec < 0 || ft.sec > STIX_SMOOI_MAX)
|
||||
{
|
||||
@ -2961,6 +3004,7 @@ int stix_execute (stix_t* stix)
|
||||
|
||||
STIX_ASSERT (stix->active_context != STIX_NULL);
|
||||
|
||||
vm_startup (stix);
|
||||
stix->proc_switched = 0;
|
||||
|
||||
while (1)
|
||||
@ -2968,7 +3012,7 @@ int stix_execute (stix_t* stix)
|
||||
if (stix->sem_heap_count > 0)
|
||||
{
|
||||
stix_ntime_t ft, now;
|
||||
vm_gettime (&now);
|
||||
vm_gettime (stix, &now);
|
||||
|
||||
do
|
||||
{
|
||||
@ -3012,8 +3056,8 @@ int stix_execute (stix_t* stix)
|
||||
else if (stix->processor->active == stix->nil_process)
|
||||
{
|
||||
STIX_SUBNTIME (&ft, &ft, (stix_ntime_t*)&now);
|
||||
vm_sleep (&ft); /* TODO: change this to i/o multiplexer??? */
|
||||
vm_gettime (&now);
|
||||
vm_sleep (stix, &ft); /* TODO: change this to i/o multiplexer??? */
|
||||
vm_gettime (stix, &now);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3983,6 +4027,7 @@ printf ("UNKNOWN BYTE CODE ENCOUNTERED %x\n", (int)bcode);
|
||||
|
||||
done:
|
||||
|
||||
vm_cleanup (stix);
|
||||
#if defined(STIX_PROFILE_EXEC)
|
||||
printf ("TOTAL_INST_COUTNER = %lu\n", (unsigned long int)inst_counter);
|
||||
#endif
|
||||
|
@ -258,7 +258,7 @@ static int ignite_3 (stix_t* stix)
|
||||
{ 20, { 'L','a','r','g','e','N','e','g','a','t','i','v','e','I','n','t','e','g','e','r' } }
|
||||
};
|
||||
|
||||
static stix_ooch_t str_stix[] = { 'S','t','i','x' };
|
||||
static stix_ooch_t str_system[] = { 'S','y','s','t','e', 'm' };
|
||||
static stix_ooch_t str_processor[] = { 'P', 'r', 'o', 'c', 'e', 's', 's', 'o', 'r' };
|
||||
|
||||
stix_oow_t i;
|
||||
@ -280,7 +280,7 @@ static int ignite_3 (stix_t* stix)
|
||||
}
|
||||
|
||||
/* Make the system dictionary available as the global name 'Stix' */
|
||||
sym = stix_makesymbol (stix, str_stix, 4);
|
||||
sym = stix_makesymbol (stix, str_system, 6);
|
||||
if (!sym) return -1;
|
||||
if (!stix_putatsysdic(stix, sym, (stix_oop_t)stix->sysdic)) return -1;
|
||||
|
||||
|
@ -370,7 +370,7 @@ static char* syntax_error_msg[] =
|
||||
"literal expected"
|
||||
};
|
||||
|
||||
stix_ooch_t str_stix[] = { 'S', 't', 'i', 'x' };
|
||||
stix_ooch_t str_system[] = { 'S', 'y', 's', 't', 'e', 'm' };
|
||||
stix_ooch_t str_my_object[] = { 'M', 'y', 'O', 'b','j','e','c','t' };
|
||||
stix_ooch_t str_main[] = { 'm', 'a', 'i', 'n' };
|
||||
|
||||
@ -593,8 +593,8 @@ printf ("%p\n", a);
|
||||
}
|
||||
}
|
||||
|
||||
/* objname.ptr = str_stix;
|
||||
objname.len = 4;*/
|
||||
/* objname.ptr = str_system;
|
||||
objname.len = 6;*/
|
||||
objname.ptr = str_my_object;
|
||||
objname.len = 8;
|
||||
mthname.ptr = str_main;
|
||||
|
@ -39,7 +39,6 @@ void* stix_allocbytes (stix_t* stix, stix_oow_t size)
|
||||
{
|
||||
stix_gc (stix);
|
||||
ptr = stix_allocheapmem (stix, stix->curheap, size);
|
||||
|
||||
/* TODO: grow heap if ptr is still null. */
|
||||
}
|
||||
|
||||
|
@ -169,11 +169,6 @@
|
||||
# define STIX_HAVE_INT64_T
|
||||
typedef unsigned __int64_t stix_uint64_t;
|
||||
typedef signed __int64_t stix_int64_t;
|
||||
#elif defined(_WIN64) || defined(_WIN32)
|
||||
# define STIX_HAVE_UINT64_T
|
||||
# define STIX_HAVE_INT64_T
|
||||
typedef unsigned __int64 stix_uint64_t;
|
||||
typedef signed __int64 stix_int64_t;
|
||||
#else
|
||||
/* no 64-bit integer */
|
||||
#endif
|
||||
@ -332,10 +327,13 @@ typedef stix_ucs_t stix_oocs_t;
|
||||
#define STIX_NSECS_PER_SEC (STIX_NSECS_PER_USEC * STIX_USECS_PER_MSEC * STIX_MSECS_PER_SEC)
|
||||
|
||||
#define STIX_SECNSEC_TO_MSEC(sec,nsec) \
|
||||
(((qse_long_t)(sec) * STIX_MSECS_PER_SEC) + ((qse_long_t)(nsec) / STIX_NSECS_PER_MSEC))
|
||||
(((stix_intptr_t)(sec) * STIX_MSECS_PER_SEC) + ((stix_intptr_t)(nsec) / STIX_NSECS_PER_MSEC))
|
||||
|
||||
#define STIX_SECNSEC_TO_USEC(sec,nsec) \
|
||||
(((qse_long_t)(sec) * STIX_USECS_PER_SEC) + ((qse_long_t)(nsec) / STIX_NSECS_PER_USEC))
|
||||
(((stix_intptr_t)(sec) * STIX_USECS_PER_SEC) + ((stix_intptr_t)(nsec) / STIX_NSECS_PER_USEC))
|
||||
|
||||
#define STIX_SECNSEC_TO_NSEC(sec,nsec) \
|
||||
(((stix_intptr_t)(sec) * STIX_NSECS_PER_SEC) + (stix_intptr_t)(nsec))
|
||||
|
||||
#define STIX_SEC_TO_MSEC(sec) ((sec) * STIX_MSECS_PER_SEC)
|
||||
#define STIX_MSEC_TO_SEC(sec) ((sec) / STIX_MSECS_PER_SEC)
|
||||
@ -543,7 +541,11 @@ struct stix_cmgr_t
|
||||
* MACROS THAT CHANGES THE BEHAVIORS OF THE C COMPILER/LINKER
|
||||
* =========================================================================*/
|
||||
|
||||
#if defined(_WIN32) || (defined(__WATCOMC__) && !defined(__WINDOWS_386__))
|
||||
#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
|
||||
# define STIX_IMPORT
|
||||
# define STIX_EXPORT
|
||||
# define STIX_PRIVATE
|
||||
#elif defined(_WIN32) || (defined(__WATCOMC__) && !defined(__WINDOWS_386__))
|
||||
# define STIX_IMPORT __declspec(dllimport)
|
||||
# define STIX_EXPORT __declspec(dllexport)
|
||||
# define STIX_PRIVATE
|
||||
|
Loading…
Reference in New Issue
Block a user