removed experimental code on error exceptionization.
made the sp method of the Process class a primitive method for accuracy fixed omission of some fields when initializing a nil_process. wrote a macro to inspect a receiver and changed the receiver inspect code to use the macro corrected the order between return value setting and process suspension/temrination/activation in some primitive functions
This commit is contained in:
parent
ce72ffa193
commit
7ee4453bf3
@ -289,15 +289,6 @@ extend Apex
|
||||
self primitiveFailed
|
||||
}
|
||||
|
||||
## -------------------------------------------------------
|
||||
## -------------------------------------------------------
|
||||
|
||||
method exceptionizeError: trueOrFalse
|
||||
{
|
||||
<primitive: #_exceptionize_error>
|
||||
self class cannotExceptionizeError
|
||||
}
|
||||
|
||||
(* ------------------------------------------------------------------
|
||||
* COMMON ERROR/EXCEPTION HANDLERS
|
||||
* ------------------------------------------------------------------ *)
|
||||
|
@ -507,10 +507,4 @@ extend Apex
|
||||
class_name := if (self class == Class) { self name } else { self class name }.
|
||||
ProhibitedMessageException signal: (method_name & ' not allowed for ' & class_name).
|
||||
}
|
||||
|
||||
method(#dual) cannotExceptionizeError
|
||||
{
|
||||
## todo: accept the object
|
||||
ErrorExceptionizationFailureException signal: 'Cannot exceptionize an error'
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,19 @@
|
||||
class(#pointer,#final,#limited) Process(Object)
|
||||
{
|
||||
var(#get) initialContext, currentContext, id, state.
|
||||
var(#get) sp, ps_prev, ps_next, sem_wait_prev, sem_wait_next.
|
||||
var sp.
|
||||
var(#get) ps_prev, ps_next, sem_wait_prev, sem_wait_next.
|
||||
var sem, perr, perrmsg.
|
||||
|
||||
method primError { ^self.perr }
|
||||
method primErrorMessage { ^self.perrmsg }
|
||||
|
||||
method(#primitive) sp.
|
||||
|
||||
method(#primitive) resume.
|
||||
method(#primitive) yield.
|
||||
method(#primitive) suspend.
|
||||
method(#primitive) _terminate.
|
||||
method(#primitive) _suspend.
|
||||
|
||||
method terminate
|
||||
{
|
||||
@ -38,8 +41,8 @@ class(#pointer,#final,#limited) Process(Object)
|
||||
## the process must not be scheduled.
|
||||
## ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
##if (Processor activeProcess ~~ self) { self _suspend }.
|
||||
if (thisProcess ~~ self) { self _suspend }.
|
||||
##if (Processor activeProcess ~~ self) { self suspend }.
|
||||
if (thisProcess ~~ self) { self suspend }.
|
||||
self.currentContext unwindTo: self.initialContext return: nil.
|
||||
^self _terminate
|
||||
}
|
||||
@ -191,6 +194,7 @@ class SemaphoreGroup(Object)
|
||||
size := 0,
|
||||
pos := 0,
|
||||
semarr := nil.
|
||||
var(#get,#set) signaledSemaphore := nil.
|
||||
|
||||
(* TODO: good idea to a shortcut way to prohibit a certain method in the heirarchy chain?
|
||||
|
||||
@ -204,7 +208,7 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
|
||||
|
||||
method(#class,#variadic) with()
|
||||
{
|
||||
| i x arr |
|
||||
| i x arr sem |
|
||||
|
||||
i := 0.
|
||||
x := thisContext vargCount.
|
||||
@ -212,7 +216,13 @@ method(#class,#abstract) xxx. => method(#class) xxx { self subclassResponsibilit
|
||||
arr := Array new: x.
|
||||
while (i < x)
|
||||
{
|
||||
arr at: i put: (thisContext vargAt: i).
|
||||
sem := thisContext vargAt: i.
|
||||
if (sem _group notNil)
|
||||
{
|
||||
System.Exception signal: 'Cannot add a semaphore in a group to another group'
|
||||
}.
|
||||
|
||||
arr at: i put: sem.
|
||||
i := i + 1.
|
||||
}.
|
||||
|
||||
@ -514,7 +524,7 @@ class(#final,#limited) ProcessScheduler(Object)
|
||||
## -----------------------------------------------------
|
||||
| s |
|
||||
s := Semaphore new.
|
||||
self signal: s after: secs and: nanosecs
|
||||
self signal: s after: secs and: nanosecs.
|
||||
s wait.
|
||||
}
|
||||
}
|
||||
|
400
moo/lib/exec.c
400
moo/lib/exec.c
@ -32,6 +32,16 @@
|
||||
#define PROC_STATE_SUSPENDED 0
|
||||
#define PROC_STATE_TERMINATED -1
|
||||
|
||||
|
||||
#define MOO_PF_CHECK_RCV(moo,cond) do { \
|
||||
if (!(cond)) { moo_seterrnum((moo), MOO_EMSGRCV); return MOO_PF_HARD_FAILURE; } \
|
||||
} while(0)
|
||||
|
||||
#define MOO_PF_CHECK_ARGS(moo,nargs,cond) do { \
|
||||
if (!(cond)) { MOO_STACK_SETRETTOERROR ((moo), (nargs), MOO_EINVAL); return MOO_PF_SUCCESS; } \
|
||||
} while(0)
|
||||
|
||||
|
||||
static MOO_INLINE const char* proc_state_to_string (int state)
|
||||
{
|
||||
static const char* str[] =
|
||||
@ -319,6 +329,8 @@ static MOO_INLINE void wake_process (moo_t* moo, moo_oop_process_t proc)
|
||||
proc->state = MOO_SMOOI_TO_OOP(PROC_STATE_RUNNING);
|
||||
moo->processor->active = proc;
|
||||
|
||||
/* load the stack pointer from 'proc'.
|
||||
* moo->processor->active points to 'proc' now. */
|
||||
LOAD_ACTIVE_SP(moo);
|
||||
|
||||
/* activate the suspended context of the new process */
|
||||
@ -354,7 +366,6 @@ static MOO_INLINE void switch_to_process_from_nil (moo_t* moo, moo_oop_process_t
|
||||
static MOO_INLINE moo_oop_process_t find_next_runnable_process (moo_t* moo)
|
||||
{
|
||||
moo_oop_process_t nrp;
|
||||
|
||||
MOO_ASSERT (moo, moo->processor->active->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNING));
|
||||
nrp = moo->processor->active->ps.next;
|
||||
if ((moo_oop_t)nrp == moo->_nil) nrp = moo->processor->runnable.first;
|
||||
@ -364,7 +375,6 @@ static MOO_INLINE moo_oop_process_t find_next_runnable_process (moo_t* moo)
|
||||
static MOO_INLINE void switch_to_next_runnable_process (moo_t* moo)
|
||||
{
|
||||
moo_oop_process_t nrp;
|
||||
|
||||
nrp = find_next_runnable_process (moo);
|
||||
if (nrp != moo->processor->active) switch_to_process (moo, nrp, PROC_STATE_RUNNABLE);
|
||||
}
|
||||
@ -382,9 +392,12 @@ static MOO_INLINE void chain_into_processor (moo_t* moo, moo_oop_process_t proc,
|
||||
MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_SUSPENDED));
|
||||
MOO_ASSERT (moo, new_state == PROC_STATE_RUNNABLE || new_state == PROC_STATE_RUNNING);
|
||||
|
||||
|
||||
#if defined(MOO_DEBUG_VM_PROCESSOR)
|
||||
MOO_LOG3 (moo, MOO_LOG_IC | MOO_LOG_DEBUG, "Processor - process [%zd] %hs->%hs in chain_into_processor\n", MOO_OOP_TO_SMOOI(proc->id), proc_state_to_string(MOO_OOP_TO_SMOOI(proc->state)), proc_state_to_string(MOO_OOP_TO_SMOOI(new_state)));
|
||||
MOO_LOG3 (moo, MOO_LOG_IC | MOO_LOG_DEBUG,
|
||||
"Processor - process [%zd] %hs->%hs in chain_into_processor\n",
|
||||
MOO_OOP_TO_SMOOI(proc->id),
|
||||
proc_state_to_string(MOO_OOP_TO_SMOOI(proc->state)),
|
||||
proc_state_to_string(new_state));
|
||||
#endif
|
||||
|
||||
runnable_count = MOO_OOP_TO_SMOOI(moo->processor->runnable.count);
|
||||
@ -732,15 +745,17 @@ static moo_oop_process_t signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
||||
unchain_from_semaphore (moo, proc);
|
||||
resume_process (moo, proc);
|
||||
|
||||
/* store the last signaled semaphore into the semaphore group */
|
||||
semgrp->sigsem = sem;
|
||||
return proc;
|
||||
}
|
||||
}
|
||||
|
||||
/* if the semaphore belongs to a semaphore group, no process is waiting
|
||||
* on the semaphore group. however, a process may still be waiting on
|
||||
* the semaphore. If a process waits on a semaphore group and another
|
||||
* process wait on a semaphor that belongs to the semaphore group, the
|
||||
* process waiting on the group always wins.
|
||||
/* if the semaphore belongs to a semaphore group and the control reaches
|
||||
* here, no process is waiting on the semaphore group. however, a process
|
||||
* may still be waiting on the semaphore. If a process waits on a semaphore
|
||||
* group and another process wait on a semaphor that belongs to the
|
||||
* semaphore group, the process waiting on the group always wins.
|
||||
*
|
||||
* TODO: implement a fair scheduling policy. or do i simply have to disallow individual wait on a semaphore belonging to a group?
|
||||
*
|
||||
@ -775,7 +790,7 @@ static moo_oop_process_t signal_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
||||
}
|
||||
}
|
||||
|
||||
static int await_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
||||
static MOO_INLINE int await_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
||||
{
|
||||
/* TODO: support timeout */
|
||||
moo_oop_process_t proc;
|
||||
@ -819,7 +834,7 @@ static int await_semaphore (moo_t* moo, moo_oop_semaphore_t sem)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore_group_t semgrp)
|
||||
static MOO_INLINE moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore_group_t semgrp)
|
||||
{
|
||||
/* TODO: support timeout and wait all */
|
||||
/* wait for one of semaphores in the group to be signaled */
|
||||
@ -843,7 +858,8 @@ static moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore_group_t se
|
||||
{
|
||||
count--;
|
||||
sem->count = MOO_SMOOI_TO_OOP(count);
|
||||
semgrp->pos = MOO_SMOOI_TO_OOP(sempos);
|
||||
semgrp->pos = MOO_SMOOI_TO_OOP(sempos); /* position of the last inspected semaphore */
|
||||
semgrp->sigsem = sem; /* remember the last signaled semaphore */
|
||||
return (moo_oop_t)sem;
|
||||
}
|
||||
}
|
||||
@ -855,24 +871,14 @@ static moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore_group_t se
|
||||
/* suspend the active process */
|
||||
suspend_process (moo, proc);
|
||||
|
||||
#if 0
|
||||
/* link the suspended process to the semaphore's process list */
|
||||
for (i = 0; i < numsems; i++)
|
||||
{
|
||||
sem = (moo_oop_semaphore_t)((moo_oop_oop_t)semgrp->semarr)->slot[sempos];
|
||||
sempos = (sempos + 1) % numsems;
|
||||
chain_into_semaphore (moo, proc, sem);
|
||||
MOO_ASSERT (moo, sem->waiting.last == proc);
|
||||
if (MOO_OOP_TO_SMOOI(sem->io_index) >= 0) moo->sem_io_wait_count++;
|
||||
}
|
||||
#else
|
||||
/* link the suspended process to the semaphore group's process list */
|
||||
chain_into_semaphore (moo, proc, (moo_oop_semaphore_t)semgrp);
|
||||
MOO_ASSERT (moo, semgrp->waiting.last == proc);
|
||||
/*if (MOO_OOP_TO_SMOOI(sem->io_index) >= 0) moo->sem_io_wait_count++;*/
|
||||
#endif
|
||||
|
||||
/*if (MOO_OOP_TO_SMOOI(semgrp->io_index) >= 0) moo->semgrp_io_wait_count++;*/
|
||||
|
||||
/* the current process will get suspended after the caller (mostly a
|
||||
* a primitive function handler) is over as it's added to a suspened
|
||||
* process list above */
|
||||
MOO_ASSERT (moo, moo->processor->active != proc);
|
||||
return moo->_nil;
|
||||
}
|
||||
@ -1075,7 +1081,7 @@ static int add_to_sem_io (moo_t* moo, moo_oop_semaphore_t sem)
|
||||
return n;
|
||||
}
|
||||
|
||||
static MOO_INLINE int mod_in_sem_io (moo_t* moo, moo_oop_semaphore_t sem)
|
||||
static MOO_INLINE int modify_in_sem_io (moo_t* moo, moo_oop_semaphore_t sem)
|
||||
{
|
||||
return moo->vmprim.vm_muxmod (moo, sem);
|
||||
}
|
||||
@ -1561,7 +1567,8 @@ static moo_pfrc_t pf_dump (moo_t* moo, moo_ooi_t nargs)
|
||||
|
||||
MOO_ASSERT (moo, nargs >= 0);
|
||||
|
||||
moo_logbfmt (moo, 0, "RECEIVER: %O\n", MOO_STACK_GET(moo, moo->sp - nargs));
|
||||
/*moo_logbfmt (moo, 0, "RECEIVER: %O IN PID %d SP %d XSP %d\n", MOO_STACK_GET(moo, moo->sp - nargs), (int)MOO_OOP_TO_SMOOI(moo->processor->active->id), (int)moo->sp, (int)MOO_OOP_TO_SMOOI(moo->processor->active->sp));*/
|
||||
moo_logbfmt (moo, 0, "RECEIVER: %O IN PID %d\n", MOO_STACK_GET(moo, moo->sp - nargs), (int)MOO_OOP_TO_SMOOI(moo->processor->active->id));
|
||||
for (i = nargs; i > 0; )
|
||||
{
|
||||
--i;
|
||||
@ -2134,28 +2141,6 @@ static moo_pfrc_t pf_perform (moo_t* moo, moo_ooi_t nargs)
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_exceptionize_error (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_POINTER(rcv))
|
||||
{
|
||||
/* the receiver is a special numeric object, not a normal pointer.
|
||||
* excceptionization is not supported for small integers, characters, and errors.
|
||||
* first of all, methods of these classes must not return errors */
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
/* TODO: .......
|
||||
MOO_OBJ_SET_FLAGS_EXTRA (rcv, xxx); */
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_context_goto (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv;
|
||||
@ -2169,13 +2154,7 @@ static moo_pfrc_t pf_context_goto (moo_t* moo, moo_ooi_t nargs)
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (MOO_CLASSOF(moo, rcv) != moo->_method_context)
|
||||
{
|
||||
MOO_LOG2 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR,
|
||||
"Error(%hs) - invalid receiver, not a method context - %O\n", __PRIMITIVE_NAME__, rcv);
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv) == moo->_method_context);
|
||||
|
||||
pc = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
if (!MOO_OOP_IS_SMOOI(pc) || MOO_OOP_TO_SMOOI(pc) < 0)
|
||||
@ -2314,14 +2293,7 @@ static moo_pfrc_t pf_block_value (moo_t* moo, moo_ooi_t nargs)
|
||||
moo_oop_context_t rcv_blkctx, blkctx;
|
||||
|
||||
rcv_blkctx = (moo_oop_context_t)MOO_STACK_GETRCV(moo, nargs);
|
||||
if (MOO_CLASSOF(moo, rcv_blkctx) != moo->_block_context)
|
||||
{
|
||||
/* the receiver must be a block context */
|
||||
MOO_LOG2 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR,
|
||||
"Error(%hs) - invalid receiver, not a block context - %O\n", __PRIMITIVE_NAME__, rcv_blkctx);
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv_blkctx) == moo->_block_context);
|
||||
|
||||
x = __block_value (moo, rcv_blkctx, nargs, 0, &blkctx);
|
||||
if (x <= MOO_PF_FAILURE) return x; /* hard failure and soft failure */
|
||||
@ -2393,20 +2365,32 @@ static moo_pfrc_t pf_block_new_process (moo_t* moo, moo_ooi_t nargs)
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
static moo_pfrc_t pf_process_sp (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv;
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv) == moo->_process);
|
||||
|
||||
/* commit the SP register of the VM to the active process for accuracy */
|
||||
STORE_ACTIVE_SP (moo);
|
||||
MOO_STACK_SETRET (moo, nargs, moo->processor->active->sp);
|
||||
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_process_resume (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv;
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (MOO_CLASSOF(moo,rcv) != moo->_process)
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv) == moo->_process);
|
||||
|
||||
/* set the return value before resume_process() in case it changes
|
||||
* the active process. */
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
resume_process (moo, (moo_oop_process_t)rcv);
|
||||
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2417,15 +2401,13 @@ static moo_pfrc_t pf_process_terminate (moo_t* moo, moo_ooi_t nargs)
|
||||
/* TODO: need to run ensure blocks here..
|
||||
* when it's executed here. it does't have to be in Exception>>handleException when there is no exception handler */
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (MOO_CLASSOF(moo,rcv) != moo->_process)
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv) == moo->_process);
|
||||
|
||||
/* set the return value before terminate_process() in case it changes
|
||||
* the active process. */
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
terminate_process (moo, (moo_oop_process_t)rcv);
|
||||
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2434,15 +2416,13 @@ static moo_pfrc_t pf_process_yield (moo_t* moo, moo_ooi_t nargs)
|
||||
moo_oop_t rcv;
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (MOO_CLASSOF(moo,rcv) != moo->_process)
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv) == moo->_process);
|
||||
|
||||
/* set the return value before yield_process() in case it changes
|
||||
* the active process. */
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
yield_process (moo, (moo_oop_process_t)rcv);
|
||||
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2451,15 +2431,13 @@ static moo_pfrc_t pf_process_suspend (moo_t* moo, moo_ooi_t nargs)
|
||||
moo_oop_t rcv;
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (MOO_CLASSOF(moo,rcv) != moo->_process)
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv) == moo->_process);
|
||||
|
||||
/* set the return value before suspend_process() in case it changes
|
||||
* the active process. */
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
suspend_process (moo, (moo_oop_process_t)rcv);
|
||||
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
@ -2467,102 +2445,92 @@ static moo_pfrc_t pf_process_suspend (moo_t* moo, moo_ooi_t nargs)
|
||||
static moo_pfrc_t pf_semaphore_signal (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv;
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (MOO_CLASSOF(moo,rcv) != moo->_semaphore)
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EMSGRCV);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv) == moo->_semaphore); /* TODO: use moo_iskindof(moo,rcv,moo->_semaphore); */
|
||||
|
||||
/* signal_semaphore() may change the active process though the
|
||||
* implementation as of this writing makes runnable the process waiting
|
||||
* on the signal to be processed. it is safer to set the return value
|
||||
* before calling signal_sempahore() */
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
|
||||
signal_semaphore (moo, (moo_oop_semaphore_t)rcv);
|
||||
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_semaphore_wait (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv;
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (MOO_CLASSOF(moo,rcv) != moo->_semaphore)
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EMSGRCV);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv) == moo->_semaphore);
|
||||
|
||||
/* i must set the return value before calling await_semaphore().
|
||||
* await_semaphore() may switch the active process and the stack
|
||||
* manipulation macros target at the active process. i'm not supposed
|
||||
* to change the return value of a new active process. */
|
||||
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
|
||||
if (await_semaphore (moo, (moo_oop_semaphore_t)rcv) <= -1)
|
||||
{
|
||||
MOO_STACK_SETRETTOERRNUM (moo, nargs);
|
||||
return -1;
|
||||
/* i must switch the top because the return value has been set already */
|
||||
MOO_STACK_SETTOP (moo, MOO_ERROR_TO_OOP(moo->errnum));
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_semaphore_group_wait (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv;
|
||||
moo_oop_t sem;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (MOO_CLASSOF(moo,rcv) != moo->_semaphore_group)
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EMSGRCV);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_CLASSOF(moo,rcv) == moo->_semaphore_group);
|
||||
|
||||
sem = await_semaphore_group (moo, (moo_oop_semaphore_group_t)rcv);
|
||||
/* i must set the return value before calling await_semaphore_group().
|
||||
* MOO_STACK_SETRETTORCV() manipulates the stack of the currently active
|
||||
* process(moo->processor->active). moo->processor->active may become
|
||||
* moo->nil_process if the current active process must get suspended.
|
||||
* it is safer to set the return value of the calling method here.
|
||||
* but the arguments and the receiver information will be lost from
|
||||
* the stack from this moment on. */
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
|
||||
MOO_STACK_SETRET (moo, nargs, sem);
|
||||
await_semaphore_group (moo, (moo_oop_semaphore_group_t)rcv);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_processor_schedule (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, arg;
|
||||
moo_oop_t arg;
|
||||
|
||||
/*MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->processor);*/
|
||||
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
arg = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
MOO_PF_CHECK_ARGS (moo, nargs, MOO_CLASSOF(moo,arg) == moo->_process);
|
||||
|
||||
if (rcv != (moo_oop_t)moo->processor || MOO_CLASSOF(moo,arg) != moo->_process)
|
||||
{
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
/* set the return value before resume_process() in case it changes the active process */
|
||||
MOO_STACK_SETRETTORCV (moo, nargs);
|
||||
|
||||
resume_process (moo, (moo_oop_process_t)arg);
|
||||
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
static moo_pfrc_t pf_processor_add_gcfin_semaphore (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv;
|
||||
moo_oop_semaphore_t sem;
|
||||
|
||||
/*MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->processor);*/
|
||||
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
|
||||
if (rcv != (moo_oop_t)moo->processor)
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EMSGRCV);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
if (MOO_CLASSOF(moo,sem) != moo->_semaphore)
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
MOO_PF_CHECK_ARGS (moo, nargs, MOO_CLASSOF(moo,sem) == moo->_semaphore);
|
||||
|
||||
/* TODO: no overwriting.. */
|
||||
moo->sem_gcfin = sem;
|
||||
@ -2573,27 +2541,31 @@ static moo_pfrc_t pf_processor_add_gcfin_semaphore (moo_t* moo, moo_ooi_t nargs)
|
||||
|
||||
static moo_pfrc_t pf_processor_add_timed_semaphore (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, sec, nsec;
|
||||
moo_oop_t sec, nsec;
|
||||
moo_oop_semaphore_t sem;
|
||||
moo_ntime_t now, ft;
|
||||
|
||||
/*MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->processor);*/
|
||||
|
||||
MOO_ASSERT (moo, nargs >= 2 || nargs <= 3);
|
||||
|
||||
if (nargs == 3)
|
||||
{
|
||||
nsec = MOO_STACK_GETARG (moo, nargs, 2);
|
||||
if (!MOO_OOP_IS_SMOOI(nsec)) return MOO_PF_FAILURE;
|
||||
if (!MOO_OOP_IS_SMOOI(nsec)) goto einval;
|
||||
}
|
||||
else nsec = MOO_SMOOI_TO_OOP(0);
|
||||
|
||||
sec = MOO_STACK_GETARG(moo, nargs, 1);
|
||||
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
|
||||
/* ProcessScheduler>>signal:after: calls this primitive function. */
|
||||
if (rcv != (moo_oop_t)moo->processor ||
|
||||
MOO_CLASSOF(moo,sem) != moo->_semaphore ||
|
||||
!MOO_OOP_IS_SMOOI(sec)) return MOO_PF_FAILURE;
|
||||
if (MOO_CLASSOF(moo,sem) != moo->_semaphore || !MOO_OOP_IS_SMOOI(sec))
|
||||
{
|
||||
einval:
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
if (MOO_OOP_IS_SMOOI(sem->heap_index) &&
|
||||
sem->heap_index != MOO_SMOOI_TO_OOP(-1))
|
||||
@ -2615,11 +2587,12 @@ static moo_pfrc_t pf_processor_add_timed_semaphore (moo_t* moo, moo_ooi_t nargs)
|
||||
MOO_ADDNTIMESNS (&ft, &now, MOO_OOP_TO_SMOOI(sec), MOO_OOP_TO_SMOOI(nsec));
|
||||
if (ft.sec < 0 || ft.sec > MOO_SMOOI_MAX)
|
||||
{
|
||||
/* soft error - cannot represent the expiry time in
|
||||
* a small integer. */
|
||||
/* soft error - cannot represent the expiry time in a small integer. */
|
||||
MOO_LOG3 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR,
|
||||
"Error(%hs) - time (%ld) out of range(0 - %zd) when adding a timed semaphore\n",
|
||||
__PRIMITIVE_NAME__, (unsigned long int)ft.sec, (moo_ooi_t)MOO_SMOOI_MAX);
|
||||
|
||||
moo_seterrnum (moo, MOO_ERANGE);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
@ -2634,20 +2607,15 @@ static moo_pfrc_t pf_processor_add_timed_semaphore (moo_t* moo, moo_ooi_t nargs)
|
||||
|
||||
static moo_pfrc_t __processor_add_io_semaphore (moo_t* moo, moo_ooi_t nargs, moo_ooi_t mask)
|
||||
{
|
||||
moo_oop_t rcv, fd;
|
||||
moo_oop_t fd;
|
||||
moo_oop_semaphore_t sem;
|
||||
|
||||
/*MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->processor);*/
|
||||
|
||||
MOO_ASSERT (moo, nargs == 2);
|
||||
|
||||
fd = MOO_STACK_GETARG(moo, nargs, 1);
|
||||
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
|
||||
if (rcv != (moo_oop_t)moo->processor)
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EMSGRCV);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
if (MOO_CLASSOF(moo,sem) != moo->_semaphore || !MOO_OOP_IS_SMOOI(fd))
|
||||
{
|
||||
@ -2659,11 +2627,13 @@ static moo_pfrc_t __processor_add_io_semaphore (moo_t* moo, moo_ooi_t nargs, moo
|
||||
{
|
||||
moo_ooi_t old_mask;
|
||||
|
||||
/* the semaphore is already linked with the requested IO handle */
|
||||
|
||||
old_mask = MOO_OOP_TO_SMOOI(sem->io_mask);
|
||||
if (old_mask != mask)
|
||||
{
|
||||
sem->io_mask = MOO_SMOOI_TO_OOP(mask);
|
||||
if (mod_in_sem_io (moo, sem) <= -1)
|
||||
if (modify_in_sem_io(moo, sem) <= -1)
|
||||
{
|
||||
sem->io_mask = MOO_SMOOI_TO_OOP(old_mask);
|
||||
MOO_STACK_SETRETTOERRNUM (moo, nargs);
|
||||
@ -2716,23 +2686,17 @@ static moo_pfrc_t pf_processor_remove_semaphore (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
/* remove a semaphore from processor's signal scheduling */
|
||||
|
||||
moo_oop_t rcv;
|
||||
moo_oop_semaphore_t sem;
|
||||
|
||||
/*MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->processor);*/
|
||||
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0);
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
|
||||
/* TODO: remove a semaphore from IO handler if it's registered...
|
||||
* remove a semaphore from elsewhere registered too */
|
||||
|
||||
if (rcv != (moo_oop_t)moo->processor)
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EMSGRCV);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
|
||||
if (MOO_CLASSOF(moo,sem) != moo->_semaphore)
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||
@ -2755,6 +2719,7 @@ static moo_pfrc_t pf_processor_remove_semaphore (moo_t* moo, moo_ooi_t nargs)
|
||||
if (MOO_OOP_IS_SMOOI(sem->io_index) &&
|
||||
sem->io_index != MOO_SMOOI_TO_OOP(-1))
|
||||
{
|
||||
/* the semaphore is associated with IO */
|
||||
if (delete_from_sem_io (moo, MOO_OOP_TO_SMOOI(sem->io_index)) <= -1)
|
||||
{
|
||||
MOO_STACK_SETRETTOERRNUM (moo, nargs);
|
||||
@ -2770,18 +2735,21 @@ static moo_pfrc_t pf_processor_remove_semaphore (moo_t* moo, moo_ooi_t nargs)
|
||||
|
||||
static moo_pfrc_t pf_processor_return_to (moo_t* moo, moo_ooi_t nargs)
|
||||
{
|
||||
moo_oop_t rcv, ret, ctx;
|
||||
moo_oop_t ret, ctx;
|
||||
|
||||
/*MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->processor);*/
|
||||
|
||||
MOO_ASSERT (moo, nargs == 2);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
ret = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
ctx = MOO_STACK_GETARG(moo, nargs, 1);
|
||||
|
||||
if (rcv != (moo_oop_t)moo->processor) return MOO_PF_FAILURE;
|
||||
|
||||
if (MOO_CLASSOF(moo, ctx) != moo->_block_context &&
|
||||
MOO_CLASSOF(moo, ctx) != moo->_method_context) return MOO_PF_FAILURE;
|
||||
MOO_CLASSOF(moo, ctx) != moo->_method_context)
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EINVAL);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
|
||||
MOO_STACK_POPS (moo, nargs + 1); /* pop arguments and receiver */
|
||||
/* TODO: verify if this is correct? does't it correct restore the stack pointer?
|
||||
@ -3153,11 +3121,7 @@ static moo_pfrc_t pf_character_as_smooi (moo_t* moo, moo_ooi_t nargs)
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_CHAR(rcv))
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_CHAR(rcv));
|
||||
|
||||
c = MOO_OOP_TO_CHAR(rcv);
|
||||
MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(c));
|
||||
@ -3172,11 +3136,7 @@ static moo_pfrc_t pf_smooi_as_character (moo_t* moo, moo_ooi_t nargs)
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_SMOOI(rcv))
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_SMOOI(rcv));
|
||||
|
||||
ec = MOO_OOP_TO_SMOOI(rcv);
|
||||
if (ec < 0) ec = 0;
|
||||
@ -3192,11 +3152,7 @@ static moo_pfrc_t pf_smooi_as_error (moo_t* moo, moo_ooi_t nargs)
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_SMOOI(rcv))
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_SMOOI(rcv));
|
||||
|
||||
ec = MOO_OOP_TO_SMOOI(rcv);
|
||||
if (ec < MOO_ERROR_MIN) ec = MOO_ERROR_MIN;
|
||||
@ -3214,11 +3170,7 @@ static moo_pfrc_t pf_error_as_character (moo_t* moo, moo_ooi_t nargs)
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_ERROR(rcv))
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_ERROR(rcv));
|
||||
|
||||
ec = MOO_OOP_TO_ERROR(rcv);
|
||||
MOO_ASSERT (moo, ec >= MOO_CHAR_MIN && ec <= MOO_CHAR_MAX);
|
||||
@ -3234,11 +3186,7 @@ static moo_pfrc_t pf_error_as_integer (moo_t* moo, moo_ooi_t nargs)
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_ERROR(rcv))
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_ERROR(rcv));
|
||||
|
||||
ec = MOO_OOP_TO_ERROR(rcv);
|
||||
MOO_ASSERT (moo, MOO_IN_SMOOI_RANGE(ec));
|
||||
@ -3255,11 +3203,7 @@ static moo_pfrc_t pf_error_as_string (moo_t* moo, moo_ooi_t nargs)
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_ERROR(rcv))
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_ERROR(rcv));
|
||||
|
||||
ec = MOO_OOP_TO_ERROR(rcv);
|
||||
MOO_ASSERT (moo, MOO_IN_SMOOI_RANGE(ec));
|
||||
@ -3284,11 +3228,7 @@ static moo_pfrc_t pf_strlen (moo_t* moo, moo_ooi_t nargs)
|
||||
moo_ooch_t* ptr;
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OBJ_IS_CHAR_POINTER(rcv))
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OBJ_IS_CHAR_POINTER(rcv));
|
||||
|
||||
/* [NOTE] the length check loop is directly implemented
|
||||
* here to be able to handle character objects
|
||||
@ -3454,6 +3394,8 @@ static moo_pfrc_t pf_system_free (moo_t* moo, moo_ooi_t nargs)
|
||||
moo_oop_t tmp;
|
||||
void* rawptr;
|
||||
|
||||
/*MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->_system);*/
|
||||
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
tmp = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
@ -3477,11 +3419,7 @@ static moo_pfrc_t pf_smptr_free (moo_t* moo, moo_ooi_t nargs)
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
tmp = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_SMPTR(tmp))
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_SMPTR(tmp));
|
||||
|
||||
moo_freemem (moo, MOO_OOP_TO_SMPTR(tmp));
|
||||
|
||||
@ -3690,8 +3628,9 @@ static moo_pfrc_t _get_system_int (moo_t* moo, moo_ooi_t nargs, int size)
|
||||
moo_oow_t offset;
|
||||
moo_oop_t tmp;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 2);
|
||||
/* MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->_system); */
|
||||
|
||||
MOO_ASSERT (moo, nargs == 2);
|
||||
tmp = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
if (MOO_OOP_IS_SMPTR(tmp)) rawptr = MOO_OOP_TO_SMPTR(tmp);
|
||||
else if (moo_inttooow (moo, tmp, (moo_oow_t*)&rawptr) <= 0) goto einval;
|
||||
@ -3720,8 +3659,9 @@ static moo_pfrc_t _get_system_uint (moo_t* moo, moo_ooi_t nargs, int size)
|
||||
moo_oow_t offset;
|
||||
moo_oop_t tmp;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 2);
|
||||
/* MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->_system); */
|
||||
|
||||
MOO_ASSERT (moo, nargs == 2);
|
||||
tmp = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
if (MOO_OOP_IS_SMPTR(tmp)) rawptr = MOO_OOP_TO_SMPTR(tmp);
|
||||
else if (moo_inttooow (moo, tmp, (moo_oow_t*)&rawptr) <= 0) goto einval;
|
||||
@ -3790,8 +3730,9 @@ static moo_pfrc_t _put_system_int (moo_t* moo, moo_ooi_t nargs, int size)
|
||||
moo_oow_t offset;
|
||||
moo_oop_t tmp;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 3);
|
||||
/* MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->_system); */
|
||||
|
||||
MOO_ASSERT (moo, nargs == 3);
|
||||
tmp = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
if (MOO_OOP_IS_SMPTR(tmp)) rawptr = MOO_OOP_TO_SMPTR(tmp);
|
||||
else if (moo_inttooow (moo, tmp, (moo_oow_t*)&rawptr) <= 0) goto einval;
|
||||
@ -3818,8 +3759,9 @@ static moo_pfrc_t _put_system_uint (moo_t* moo, moo_ooi_t nargs, int size)
|
||||
moo_oow_t offset;
|
||||
moo_oop_t tmp;
|
||||
|
||||
MOO_ASSERT (moo, nargs == 3);
|
||||
/* MOO_PF_CHECK_RCV (moo, MOO_STACK_GETRCV(moo, nargs) == (moo_oop_t)moo->_system); */
|
||||
|
||||
MOO_ASSERT (moo, nargs == 3);
|
||||
tmp = MOO_STACK_GETARG(moo, nargs, 0);
|
||||
if (MOO_OOP_IS_SMPTR(tmp)) rawptr = MOO_OOP_TO_SMPTR(tmp);
|
||||
else if (moo_inttooow (moo, tmp, (moo_oow_t*)&rawptr) <= 0) goto einval;
|
||||
@ -3891,11 +3833,7 @@ static moo_pfrc_t _get_smptr_int (moo_t* moo, moo_ooi_t nargs, int size)
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_SMPTR(rcv))
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_SMPTR(rcv));
|
||||
|
||||
if (moo_inttooow (moo, MOO_STACK_GETARG(moo, nargs, 0), &offset) <= 0)
|
||||
{
|
||||
@ -3926,11 +3864,7 @@ static moo_pfrc_t _get_smptr_uint (moo_t* moo, moo_ooi_t nargs, int size)
|
||||
MOO_ASSERT (moo, nargs == 1);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_SMPTR(rcv))
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_SMPTR(rcv));
|
||||
|
||||
if (moo_inttooow (moo, MOO_STACK_GETARG(moo, nargs, 0), &offset) <= 0)
|
||||
{
|
||||
@ -4000,11 +3934,7 @@ static moo_pfrc_t _put_smptr_int (moo_t* moo, moo_ooi_t nargs, int size)
|
||||
MOO_ASSERT (moo, nargs == 2);
|
||||
|
||||
tmp = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_SMPTR(tmp))
|
||||
{
|
||||
MOO_STACK_SETRETTOERROR (moo, nargs, MOO_EMSGRCV);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_SMPTR(tmp));
|
||||
|
||||
rawptr = MOO_OOP_TO_SMPTR(tmp);
|
||||
|
||||
@ -4033,11 +3963,7 @@ static moo_pfrc_t _put_smptr_uint (moo_t* moo, moo_ooi_t nargs, int size)
|
||||
MOO_ASSERT (moo, nargs == 2);
|
||||
|
||||
tmp = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_SMPTR(tmp))
|
||||
{
|
||||
MOO_STACK_SETRETTOERRNUM (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_SUCCESS;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_SMPTR(tmp));
|
||||
|
||||
rawptr = MOO_OOP_TO_SMPTR(tmp);
|
||||
|
||||
@ -4136,11 +4062,7 @@ static moo_pfrc_t pf_smptr_as_string (moo_t* moo, moo_ooi_t nargs)
|
||||
MOO_ASSERT (moo, nargs == 0);
|
||||
|
||||
rcv = MOO_STACK_GETRCV(moo, nargs);
|
||||
if (!MOO_OOP_IS_SMPTR(rcv))
|
||||
{
|
||||
moo_seterrnum (moo, MOO_EMSGRCV);
|
||||
return MOO_PF_HARD_FAILURE;
|
||||
}
|
||||
MOO_PF_CHECK_RCV (moo, MOO_OOP_IS_SMPTR(rcv));
|
||||
|
||||
ptr = MOO_OOP_TO_SMPTR(rcv);
|
||||
sprintptr (buf, (moo_oow_t)ptr, &len);
|
||||
@ -4185,7 +4107,6 @@ static pf_t pftab[] =
|
||||
|
||||
{ "_responds_to", { pf_responds_to, 1, 1 } },
|
||||
{ "_perform", { pf_perform, 1, MA } },
|
||||
{ "_exceptionize_error", { pf_exceptionize_error, 1, 1 } },
|
||||
|
||||
{ "_context_goto", { pf_context_goto, 1, 1 } },
|
||||
{ "_block_value", { pf_block_value, 0, MA } },
|
||||
@ -4238,10 +4159,11 @@ static pf_t pftab[] =
|
||||
{ "Error_asInteger", { pf_error_as_integer, 0, 0 } },
|
||||
{ "Error_asString", { pf_error_as_string, 0, 0 } },
|
||||
|
||||
{ "Process__suspend", { pf_process_suspend, 0, 0 } },
|
||||
{ "Process__terminate", { pf_process_terminate, 0, 0 } },
|
||||
{ "Process_resume", { pf_process_resume, 0, 0 } },
|
||||
{ "Process_sp", { pf_process_sp, 0, 0 } },
|
||||
{ "Process_suspend", { pf_process_suspend, 0, 0 } },
|
||||
{ "Process_yield", { pf_process_yield, 0, 0 } },
|
||||
{ "Process__terminate", { pf_process_terminate, 0, 0 } },
|
||||
|
||||
{ "Semaphore_signal", { pf_semaphore_signal, 0, 0 } },
|
||||
{ "Semaphore_wait", { pf_semaphore_wait, 0, 0 } },
|
||||
|
@ -461,6 +461,9 @@ static int ignite_2 (moo_t* moo)
|
||||
if (!tmp) return -1;
|
||||
moo->nil_process = (moo_oop_process_t)tmp;
|
||||
moo->nil_process->sp = MOO_SMOOI_TO_OOP(-1);
|
||||
moo->nil_process->id = MOO_SMOOI_TO_OOP(-1);
|
||||
moo->nil_process->perr = MOO_ERROR_TO_OOP(MOO_ENOERR);
|
||||
moo->nil_process->perrmsg = moo->_nil;
|
||||
|
||||
/* Create a process scheduler */
|
||||
tmp = (moo_oop_t)moo_instantiate (moo, moo->_process_scheduler, MOO_NULL, 0);
|
||||
|
@ -752,7 +752,7 @@ typedef struct moo_process_t* moo_oop_process_t;
|
||||
typedef struct moo_semaphore_t moo_semaphore_t;
|
||||
typedef struct moo_semaphore_t* moo_oop_semaphore_t;
|
||||
|
||||
#define MOO_SEMAPHORE_GROUP_NAMED_INSTVARS 5
|
||||
#define MOO_SEMAPHORE_GROUP_NAMED_INSTVARS 6
|
||||
typedef struct moo_semaphore_group_t moo_semaphore_group_t;
|
||||
typedef struct moo_semaphore_group_t* moo_oop_semaphore_group_t;
|
||||
|
||||
@ -802,6 +802,8 @@ struct moo_semaphore_t
|
||||
moo_oop_process_t first;
|
||||
moo_oop_process_t last;
|
||||
} waiting; /* list of processes waiting on this semaphore */
|
||||
/* [END IMPORTANT] */
|
||||
|
||||
moo_oop_t count; /* SmallInteger */
|
||||
|
||||
moo_oop_t heap_index; /* index to the heap */
|
||||
@ -826,10 +828,12 @@ struct moo_semaphore_group_t
|
||||
moo_oop_process_t first;
|
||||
moo_oop_process_t last; /* list of processes waiting on this semaphore group */
|
||||
} waiting;
|
||||
/* [END IMPORTANT] */
|
||||
|
||||
moo_oop_t size; /* SmallInteger */
|
||||
moo_oop_t pos; /* current processing position */
|
||||
moo_oop_oop_t semarr; /* Array of Semaphores */
|
||||
moo_oop_semaphore_t sigsem; /* Last signaled semaphore */
|
||||
};
|
||||
|
||||
#define MOO_PROCESS_SCHEDULER_NAMED_INSTVARS 9
|
||||
@ -1268,7 +1272,11 @@ struct moo_t
|
||||
} while(0)
|
||||
|
||||
#define MOO_STACK_GET(moo,v_sp) ((moo)->processor->active->slot[v_sp])
|
||||
#define MOO_STACK_SET(moo,v_sp,v_obj) ((moo)->processor->active->slot[v_sp] = v_obj)
|
||||
#define MOO_STACK_SET(moo,v_sp,v_obj) \
|
||||
do { \
|
||||
MOO_ASSERT (moo, (v_sp) < (moo_ooi_t)(MOO_OBJ_GET_SIZE((moo)->processor->active) - MOO_PROCESS_NAMED_INSTVARS)); \
|
||||
(moo)->processor->active->slot[v_sp] = v_obj; \
|
||||
} while(0)
|
||||
|
||||
#define MOO_STACK_GETTOP(moo) MOO_STACK_GET(moo, (moo)->sp)
|
||||
#define MOO_STACK_SETTOP(moo,v_obj) MOO_STACK_SET(moo, (moo)->sp, v_obj)
|
||||
@ -1284,9 +1292,13 @@ struct moo_t
|
||||
/* get the receiver of a message */
|
||||
#define MOO_STACK_GETRCV(moo,nargs) MOO_STACK_GET(moo, (moo)->sp - nargs)
|
||||
|
||||
/* you can't access arguments and receiver after this macro.
|
||||
/* you can't access arguments and receiver after these macros.
|
||||
* also you must not call this macro more than once */
|
||||
#define MOO_STACK_SETRET(moo,nargs,retv) (MOO_STACK_POPS(moo, nargs), MOO_STACK_SETTOP(moo, (retv)))
|
||||
#define MOO_STACK_SETRET(moo,nargs,retv) \
|
||||
do { \
|
||||
MOO_STACK_POPS(moo, nargs); \
|
||||
MOO_STACK_SETTOP(moo, (retv)); \
|
||||
} while(0)
|
||||
#define MOO_STACK_SETRETTORCV(moo,nargs) (MOO_STACK_POPS(moo, nargs))
|
||||
#define MOO_STACK_SETRETTOERRNUM(moo,nargs) MOO_STACK_SETRET(moo, nargs, MOO_ERROR_TO_OOP(moo->errnum))
|
||||
#define MOO_STACK_SETRETTOERROR(moo,nargs,ec) MOO_STACK_SETRET(moo, nargs, MOO_ERROR_TO_OOP(ec))
|
||||
|
Loading…
Reference in New Issue
Block a user