/*
// Full copyright information is available in the file ../doc/CREDITS
*/
#include "defs.h"
#include "lookup.h"
#include "execute.h"
#include "grammar.h"
#include "opcodes.h"
/* ----------------------------------------------------------------- */
/* cancel a suspended task */
COLDC_FUNC(task_info) {
cList * list;
cData *args;
if (!func_init_1(&args, INTEGER))
return;
list = task_info(INT1);
if (!list)
THROW((type_id, "No task %d.", INT1))
pop(1);
push_list(list);
list_discard(list);
}
/* ----------------------------------------------------------------- */
/* cancel a suspended task */
COLDC_FUNC(cancel) {
cData *args;
if (!func_init_1(&args, INTEGER))
return;
if (!task_lookup(args[0].u.val)) {
cthrow(type_id, "No task %d.", args[0].u.val);
} else {
task_cancel(args[0].u.val);
pop(1);
push_int(1);
}
}
/* ----------------------------------------------------------------- */
/* suspend a task */
void func_suspend(void) {
if (!func_init_0())
return;
if (atomic) {
cthrow(atomic_id, "Attempt to suspend while executing atomically.");
return;
}
task_suspend();
/* we'll let task_resume push something onto the stack for us */
}
/* ----------------------------------------------------------------- */
void func_resume(void) {
cData *args;
Int nargs;
Long tid;
if (!func_init_1_or_2(&args, &nargs, INTEGER, 0))
return;
tid = args[0].u.val;
if (!task_lookup(tid)) {
cthrow(type_id, "No task %d.", args[0].u.val);
} else {
if (nargs == 1)
task_resume(tid, NULL);
else
task_resume(tid, &args[1]);
pop(nargs);
push_int(1);
}
}
/* ----------------------------------------------------------------- */
void func_pause(void) {
if (!func_init_0())
return;
push_int(1);
if (atomic) {
if (cur_frame->ticks <= REFRESH_METHOD_THRESHOLD)
cur_frame->ticks = PAUSED_METHOD_TICKS;
} else {
task_pause();
}
}
/* ----------------------------------------------------------------- */
void func_atomic(void) {
cData * args;
if (!func_init_1(&args, INTEGER))
return;
if (!coldcc)
atomic = (Bool) (args[0].u.val ? YES : NO);
pop(1);
push_int(atomic ? 1 : 0);
}
/* ----------------------------------------------------------------- */
void func_refresh(void) {
if (!func_init_0())
return;
push_int(1);
if (cur_frame->ticks <= REFRESH_METHOD_THRESHOLD) {
if (atomic) {
cur_frame->ticks = PAUSED_METHOD_TICKS;
} else {
task_pause();
}
}
}
/* ----------------------------------------------------------------- */
void func_tasks(void) {
cList * list;
if (!func_init_0())
return;
list = task_list();
push_list(list);
list_discard(list);
}
/* ----------------------------------------------------------------- */
void func_tick(void) {
if (!func_init_0())
return;
push_int(tick);
}
/* ----------------------------------------------------------------- */
void func_stack(void) {
cList * list;
if (!func_init_0())
return;
list = task_stack();
push_list(list);
list_discard(list);
}
void func_method(void) {
if (!func_init_0())
return;
push_symbol(cur_frame->method->name);
}
void func_this(void) {
/* Accept no arguments, and push the objnum of the current object. */
if (!func_init_0())
return;
push_objnum(cur_frame->object->objnum);
}
void func_definer(void) {
/* Accept no arguments, and push the objnum of the method definer. */
if (!func_init_0())
return;
push_objnum(cur_frame->method->object->objnum);
}
void func_sender(void) {
/* Accept no arguments, and push the objnum of the sending object. */
if (!func_init_0())
return;
if (cur_frame->sender == NOT_AN_IDENT)
push_int(0);
else
push_objnum(cur_frame->sender);
}
void func_caller(void) {
/* Accept no arguments, and push the objnum of the calling method's
* definer. */
if (!func_init_0())
return;
if (cur_frame->caller == NOT_AN_IDENT)
push_int(0);
else
push_objnum(cur_frame->caller);
}
void func_task_id(void) {
/* Accept no arguments, and push the task ID. */
if (!func_init_0())
return;
push_int(task_id);
}
void func_ticks_left(void) {
if (!func_init_0())
return;
push_int(cur_frame->ticks);
}
COLDC_FUNC(user) {
if (!func_init_0())
return;
if (cur_frame->user == NOT_AN_IDENT)
push_int(0);
else
push_objnum(cur_frame->user);
}
COLDC_FUNC(set_user) {
if (!func_init_0())
return;
cur_frame->user = cur_frame->object->objnum;
push_objnum(cur_frame->user);
}