Replaced kernel_oops with error(), and added an enum to clarify the cases where invoke_selector should stop
svn-id: r41095
This commit is contained in:
parent
76bd1b7c0e
commit
c730e0290d
7 changed files with 23 additions and 33 deletions
|
@ -471,12 +471,6 @@ SciKernelFunction kfunct_mappers[] = {
|
||||||
|
|
||||||
static const char *argtype_description[] = { "Undetermined (WTF?)", "List", "Node", "Object", "Reference", "Arithmetic" };
|
static const char *argtype_description[] = { "Undetermined (WTF?)", "List", "Node", "Object", "Reference", "Arithmetic" };
|
||||||
|
|
||||||
int kernel_oops(EngineState *s, const char *file, int line, const char *reason) {
|
|
||||||
sciprintf("Kernel Oops in file %s, line %d: %s\n", file, line, reason);
|
|
||||||
error("Kernel Oops in file %s, line %d: %s", file, line, reason);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allocates a set amount of memory for a specified use and returns a handle to it.
|
// Allocates a set amount of memory for a specified use and returns a handle to it.
|
||||||
reg_t kalloc(EngineState *s, const char *type, int space) {
|
reg_t kalloc(EngineState *s, const char *type, int space) {
|
||||||
reg_t reg;
|
reg_t reg;
|
||||||
|
|
|
@ -49,6 +49,11 @@ extern int _debug_step_running;
|
||||||
|
|
||||||
/******************** Selector functionality ********************/
|
/******************** Selector functionality ********************/
|
||||||
|
|
||||||
|
enum SelectorInvocation {
|
||||||
|
kStopOnInvalidSelector = 0,
|
||||||
|
kContinueOnInvalidSelector = 1
|
||||||
|
};
|
||||||
|
|
||||||
#define GET_SEL32(_o_, _slc_) read_selector(s, _o_, s->_vocabulary->_selectorMap._slc_, __FILE__, __LINE__)
|
#define GET_SEL32(_o_, _slc_) read_selector(s, _o_, s->_vocabulary->_selectorMap._slc_, __FILE__, __LINE__)
|
||||||
#define GET_SEL32V(_o_, _slc_) (GET_SEL32(_o_, _slc_).offset)
|
#define GET_SEL32V(_o_, _slc_) (GET_SEL32(_o_, _slc_).offset)
|
||||||
#define GET_SEL32SV(_o_, _slc_) ((int16)(GET_SEL32(_o_, _slc_).offset))
|
#define GET_SEL32SV(_o_, _slc_) ((int16)(GET_SEL32(_o_, _slc_).offset))
|
||||||
|
@ -81,7 +86,7 @@ extern int _debug_step_running;
|
||||||
|
|
||||||
reg_t read_selector(EngineState *s, reg_t object, Selector selector_id, const char *fname, int line);
|
reg_t read_selector(EngineState *s, reg_t object, Selector selector_id, const char *fname, int line);
|
||||||
void write_selector(EngineState *s, reg_t object, Selector selector_id, reg_t value, const char *fname, int line);
|
void write_selector(EngineState *s, reg_t object, Selector selector_id, reg_t value, const char *fname, int line);
|
||||||
int invoke_selector(EngineState *s, reg_t object, int selector_id, int noinvalid, int kfunct,
|
int invoke_selector(EngineState *s, reg_t object, int selector_id, SelectorInvocation noinvalid, int kfunct,
|
||||||
StackPtr k_argp, int k_argc, const char *fname, int line, int argc, ...);
|
StackPtr k_argp, int k_argc, const char *fname, int line, int argc, ...);
|
||||||
|
|
||||||
|
|
||||||
|
@ -100,7 +105,6 @@ char *kernel_lookup_text(EngineState *s, reg_t address, int index);
|
||||||
|
|
||||||
|
|
||||||
/******************** Debug functionality ********************/
|
/******************** Debug functionality ********************/
|
||||||
#define KERNEL_OOPS(reason) kernel_oops(s, __FILE__, __LINE__, reason)
|
|
||||||
|
|
||||||
bool is_object(EngineState *s, reg_t obj);
|
bool is_object(EngineState *s, reg_t obj);
|
||||||
/* Checks whether a heap address contains an object
|
/* Checks whether a heap address contains an object
|
||||||
|
@ -138,14 +142,6 @@ byte *kernel_dereference_bulk_pointer(EngineState *s, reg_t pointer, int entries
|
||||||
** reg_t dereferenciation also assures alignedness of data.
|
** reg_t dereferenciation also assures alignedness of data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int kernel_oops(EngineState *s, const char *file, int line, const char *reason);
|
|
||||||
/* Halts script execution and informs the user about an internal kernel error or failed assertion
|
|
||||||
** Parameters: (EngineState *) s: The state to use
|
|
||||||
** (const char *) file: The file the oops occured in
|
|
||||||
** (int) line: The line the oops occured in
|
|
||||||
** (const char *) reason: Reason for the kernel oops
|
|
||||||
*/
|
|
||||||
|
|
||||||
/******************** Priority macros/functions ********************/
|
/******************** Priority macros/functions ********************/
|
||||||
|
|
||||||
int _find_priority_band(EngineState *s, int band);
|
int _find_priority_band(EngineState *s, int band);
|
||||||
|
|
|
@ -1818,7 +1818,7 @@ int _k_view_list_dispose_loop(EngineState *s, List *list, GfxDynView *widget, in
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_object(s, obj)) {
|
if (is_object(s, obj)) {
|
||||||
if (invoke_selector(INV_SEL(obj, delete_, 1), 0))
|
if (invoke_selector(INV_SEL(obj, delete_, kContinueOnInvalidSelector), 0))
|
||||||
warning("Object at %04x:%04x requested deletion, but does not have a delete funcselector", PRINT_REG(obj));
|
warning("Object at %04x:%04x requested deletion, but does not have a delete funcselector", PRINT_REG(obj));
|
||||||
if (_k_animate_ran) {
|
if (_k_animate_ran) {
|
||||||
warning("Object at %04x:%04x invoked kAnimate() during deletion", PRINT_REG(obj));
|
warning("Object at %04x:%04x invoked kAnimate() during deletion", PRINT_REG(obj));
|
||||||
|
@ -1979,7 +1979,7 @@ static void _k_make_view_list(EngineState *s, GfxList **widget_list, List *list,
|
||||||
if (!(signal & _K_VIEW_SIG_FLAG_FROZEN)) {
|
if (!(signal & _K_VIEW_SIG_FLAG_FROZEN)) {
|
||||||
|
|
||||||
debugC(2, kDebugLevelGraphics, " invoking %04x:%04x::doit()\n", PRINT_REG(obj));
|
debugC(2, kDebugLevelGraphics, " invoking %04x:%04x::doit()\n", PRINT_REG(obj));
|
||||||
invoke_selector(INV_SEL(obj, doit, 1), 0); // Call obj::doit() if neccessary
|
invoke_selector(INV_SEL(obj, doit, kContinueOnInvalidSelector), 0); // Call obj::doit() if neccessary
|
||||||
|
|
||||||
|
|
||||||
// Lookup node again, since the NodeTable it was in may
|
// Lookup node again, since the NodeTable it was in may
|
||||||
|
|
|
@ -175,7 +175,7 @@ reg_t _k_new_node(EngineState *s, reg_t value, reg_t key) {
|
||||||
Node *n = s->seg_manager->alloc_Node(&nodebase);
|
Node *n = s->seg_manager->alloc_Node(&nodebase);
|
||||||
|
|
||||||
if (!n) {
|
if (!n) {
|
||||||
KERNEL_OOPS("Out of memory while creating a node");
|
error("[Kernel] Out of memory while creating a node");
|
||||||
return NULL_REG;
|
return NULL_REG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,7 +458,7 @@ reg_t kSort(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (node) {
|
while (node) {
|
||||||
invoke_selector(INV_SEL(order_func, doit, 0), 1, node->value);
|
invoke_selector(INV_SEL(order_func, doit, kStopOnInvalidSelector), 1, node->value);
|
||||||
temp_array[i].key = node->key;
|
temp_array[i].key = node->key;
|
||||||
temp_array[i].value = node->value;
|
temp_array[i].value = node->value;
|
||||||
temp_array[i].order = s->r_acc;
|
temp_array[i].order = s->r_acc;
|
||||||
|
|
|
@ -558,9 +558,9 @@ reg_t kDoBresen(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
debugC(2, kDebugLevelBresen, "New data: (x,y)=(%d,%d), di=%d\n", x, y, bdi);
|
debugC(2, kDebugLevelBresen, "New data: (x,y)=(%d,%d), di=%d\n", x, y, bdi);
|
||||||
|
|
||||||
if (s->_vocabulary->_selectorMap.cantBeHere != -1)
|
if (s->_vocabulary->_selectorMap.cantBeHere != -1)
|
||||||
invoke_selector(INV_SEL(client, cantBeHere, 0), 0);
|
invoke_selector(INV_SEL(client, cantBeHere, kStopOnInvalidSelector), 0);
|
||||||
else
|
else
|
||||||
invoke_selector(INV_SEL(client, canBeHere, 0), 0);
|
invoke_selector(INV_SEL(client, canBeHere, kStopOnInvalidSelector), 0);
|
||||||
|
|
||||||
s->r_acc = not_register(s, s->r_acc);
|
s->r_acc = not_register(s, s->r_acc);
|
||||||
|
|
||||||
|
@ -577,7 +577,7 @@ reg_t kDoBresen(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
|
|
||||||
if (s->version > SCI_VERSION_0)
|
if (s->version > SCI_VERSION_0)
|
||||||
if (completed)
|
if (completed)
|
||||||
invoke_selector(INV_SEL(mover, moveDone, 0), 0);
|
invoke_selector(INV_SEL(mover, moveDone, kStopOnInvalidSelector), 0);
|
||||||
|
|
||||||
return make_reg(0, completed);
|
return make_reg(0, completed);
|
||||||
}
|
}
|
||||||
|
@ -622,7 +622,7 @@ reg_t kDoAvoider(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
|
|
||||||
debugC(2, kDebugLevelBresen, "Doing avoider %04x:%04x (dest=%d,%d)\n", PRINT_REG(avoider), destx, desty);
|
debugC(2, kDebugLevelBresen, "Doing avoider %04x:%04x (dest=%d,%d)\n", PRINT_REG(avoider), destx, desty);
|
||||||
|
|
||||||
if (invoke_selector(INV_SEL(mover, doit, 1) , 0)) {
|
if (invoke_selector(INV_SEL(mover, doit, kContinueOnInvalidSelector) , 0)) {
|
||||||
error("Mover %04x:%04x of avoider %04x:%04x doesn't have a doit() funcselector", PRINT_REG(mover), PRINT_REG(avoider));
|
error("Mover %04x:%04x of avoider %04x:%04x doesn't have a doit() funcselector", PRINT_REG(mover), PRINT_REG(avoider));
|
||||||
return NULL_REG;
|
return NULL_REG;
|
||||||
}
|
}
|
||||||
|
@ -631,7 +631,7 @@ reg_t kDoAvoider(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
if (!mover.segment) // Mover has been disposed?
|
if (!mover.segment) // Mover has been disposed?
|
||||||
return s->r_acc; // Return gracefully.
|
return s->r_acc; // Return gracefully.
|
||||||
|
|
||||||
if (invoke_selector(INV_SEL(client, isBlocked, 1) , 0)) {
|
if (invoke_selector(INV_SEL(client, isBlocked, kContinueOnInvalidSelector) , 0)) {
|
||||||
error("Client %04x:%04x of avoider %04x:%04x doesn't"
|
error("Client %04x:%04x of avoider %04x:%04x doesn't"
|
||||||
" have an isBlocked() funcselector", PRINT_REG(client), PRINT_REG(avoider));
|
" have an isBlocked() funcselector", PRINT_REG(client), PRINT_REG(avoider));
|
||||||
return NULL_REG;
|
return NULL_REG;
|
||||||
|
@ -662,7 +662,7 @@ reg_t kDoAvoider(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
|
|
||||||
debugC(2, kDebugLevelBresen, "Pos (%d,%d): Trying angle %d; delta=(%d,%d)\n", oldx, oldy, angle, move_x, move_y);
|
debugC(2, kDebugLevelBresen, "Pos (%d,%d): Trying angle %d; delta=(%d,%d)\n", oldx, oldy, angle, move_x, move_y);
|
||||||
|
|
||||||
if (invoke_selector(INV_SEL(client, canBeHere, 1) , 0)) {
|
if (invoke_selector(INV_SEL(client, canBeHere, kContinueOnInvalidSelector) , 0)) {
|
||||||
error("Client %04x:%04x of avoider %04x:%04x doesn't"
|
error("Client %04x:%04x of avoider %04x:%04x doesn't"
|
||||||
" have a canBeHere() funcselector", PRINT_REG(client), PRINT_REG(avoider));
|
" have a canBeHere() funcselector", PRINT_REG(client), PRINT_REG(avoider));
|
||||||
return NULL_REG;
|
return NULL_REG;
|
||||||
|
@ -696,7 +696,7 @@ reg_t kDoAvoider(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
s->r_acc = make_reg(0, angle);
|
s->r_acc = make_reg(0, angle);
|
||||||
|
|
||||||
if (looper.segment) {
|
if (looper.segment) {
|
||||||
if (invoke_selector(INV_SEL(looper, doit, 1), 2, angle, client)) {
|
if (invoke_selector(INV_SEL(looper, doit, kContinueOnInvalidSelector), 2, angle, client)) {
|
||||||
error("Looper %04x:%04x of avoider %04x:%04x doesn't"
|
error("Looper %04x:%04x of avoider %04x:%04x doesn't"
|
||||||
" have a doit() funcselector", PRINT_REG(looper), PRINT_REG(avoider));
|
" have a doit() funcselector", PRINT_REG(looper), PRINT_REG(avoider));
|
||||||
} else
|
} else
|
||||||
|
|
|
@ -56,7 +56,7 @@ void write_selector(EngineState *s, reg_t object, Selector selector_id, reg_t va
|
||||||
*address = value;
|
*address = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
int invoke_selector(EngineState *s, reg_t object, int selector_id, int noinvalid, int kfunct,
|
int invoke_selector(EngineState *s, reg_t object, int selector_id, SelectorInvocation noinvalid, int kfunct,
|
||||||
StackPtr k_argp, int k_argc, const char *fname, int line, int argc, ...) {
|
StackPtr k_argp, int k_argc, const char *fname, int line, int argc, ...) {
|
||||||
va_list argp;
|
va_list argp;
|
||||||
int i;
|
int i;
|
||||||
|
@ -71,10 +71,10 @@ int invoke_selector(EngineState *s, reg_t object, int selector_id, int noinvalid
|
||||||
slc_type = lookup_selector(s, object, selector_id, NULL, &address);
|
slc_type = lookup_selector(s, object, selector_id, NULL, &address);
|
||||||
|
|
||||||
if (slc_type == kSelectorNone) {
|
if (slc_type == kSelectorNone) {
|
||||||
error("Selector '%s' of object at %04x:%04x could not be invoked (%s L%d)",
|
warning("Selector '%s' of object at %04x:%04x could not be invoked (%s L%d)",
|
||||||
s->_vocabulary->getSelectorName(selector_id).c_str(), PRINT_REG(object), fname, line);
|
s->_vocabulary->getSelectorName(selector_id).c_str(), PRINT_REG(object), fname, line);
|
||||||
if (noinvalid == 0)
|
if (noinvalid == kStopOnInvalidSelector)
|
||||||
KERNEL_OOPS("Not recoverable: VM was halted\n");
|
error("[Kernel] Not recoverable: VM was halted\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (slc_type == kSelectorVariable) // Swallow silently
|
if (slc_type == kSelectorVariable) // Swallow silently
|
||||||
|
|
|
@ -229,7 +229,7 @@ reg_t kParse(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
s->r_acc = make_reg(0, 1);
|
s->r_acc = make_reg(0, 1);
|
||||||
PUT_SEL32V(event, claimed, 1);
|
PUT_SEL32V(event, claimed, 1);
|
||||||
|
|
||||||
invoke_selector(INV_SEL(s->game_obj, syntaxFail, 0), 2, s->parser_base, stringpos);
|
invoke_selector(INV_SEL(s->game_obj, syntaxFail, kStopOnInvalidSelector), 2, s->parser_base, stringpos);
|
||||||
/* Issue warning */
|
/* Issue warning */
|
||||||
|
|
||||||
debugC(2, kDebugLevelParser, "Tree building failed\n");
|
debugC(2, kDebugLevelParser, "Tree building failed\n");
|
||||||
|
@ -253,7 +253,7 @@ reg_t kParse(EngineState *s, int funct_nr, int argc, reg_t *argv) {
|
||||||
debugC(2, kDebugLevelParser, "Word unknown: %s\n", error);
|
debugC(2, kDebugLevelParser, "Word unknown: %s\n", error);
|
||||||
/* Issue warning: */
|
/* Issue warning: */
|
||||||
|
|
||||||
invoke_selector(INV_SEL(s->game_obj, wordFail, 0), 2, s->parser_base, stringpos);
|
invoke_selector(INV_SEL(s->game_obj, wordFail, kStopOnInvalidSelector), 2, s->parser_base, stringpos);
|
||||||
free(error);
|
free(error);
|
||||||
return make_reg(0, 1); /* Tell them that it dind't work */
|
return make_reg(0, 1); /* Tell them that it dind't work */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue