From 8298bad3e09ec194ebe2bfbaaf20f94aae04c4c3 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Tue, 25 Apr 2017 15:20:58 +0000 Subject: [PATCH] added moo_process_t.perr and Processor>>primError to capture the last error set by a primitive function --- moo/kernel/Apex.moo | 100 +++++++++++++++++++++++++---------------- moo/kernel/Process.moo | 26 +++-------- moo/lib/comp.c | 15 +++++-- moo/lib/exec.c | 3 ++ moo/lib/moo.h | 15 ++++--- 5 files changed, 90 insertions(+), 69 deletions(-) diff --git a/moo/kernel/Apex.moo b/moo/kernel/Apex.moo index 0864934..035cfe7 100644 --- a/moo/kernel/Apex.moo +++ b/moo/kernel/Apex.moo @@ -1,4 +1,38 @@ class Apex(nil) +{ +} + +class Error(Apex) +{ +} + +pooldic Error.Code +{ + ENOERR := error(0). + EGENERIC := error(1). + ENOIMPL := error(2). + ESYSERR := error(3). + EINTERN := error(4). + ESYSMEM := error(5). + EOOMEM := error(6). + EINVAL := error(7). + ENOENT := error(8). + EPERM := error(12). + ERANGE := error(20). +(* add more items... *) +} + +(*pooldic Error.Code2 +{ + >> CAN I SUPPORT this kind of redefnition? as of now, it's not accepted because + >> Error.Code2.EGENERIC is not a literal. Should i treate pooldic members as a constant + >> and treat it as if it's a literal like? then even if the defined value changes, + >> the definition here won't see the change... what is the best way to tackle this issue? + + EGENERIC := Error.Code2.EGENERIC. +}*) + +extend Apex { ## ------------------------------------------------------- ## ------------------------------------------------------- @@ -126,35 +160,49 @@ class Apex(nil) method basicAt: index { + | perr | + - self index: index outOfRange: (self basicSize). + +## TODO: create a common method that translate a primitive error to some standard exceptions of primitive failure. + perr := thisProcess primError. + if (perr == Error.Code.ERANGE) { self index: index outOfRange: (self basicSize) } + elsif (perr == Error.Code.EPERM) { self messageProhibited: #basicAt } + else { self primitiveFailed } } method basicAt: index put: anObject { + | perr | + -## TODO: proper error handling -(* - if (primitiveError == error(generic)) - { - } - else - { - self index: index outOfRange: (self basicSize). - }*) - self index: index outOfRange: (self basicSize). + + perr := thisProcess primError. + if (perr == Error.Code.ERANGE) { self index: index outOfRange: (self basicSize) } + elsif (perr == Error.Code.EPERM) { self messageProhibited: #basicAt:put: } + else { self primitiveFailed } } method(#class) basicAt: index { + | perr | - self index: index outOfRange: (self basicSize). + + perr := thisProcess primError. + if (perr == Error.Code.ERANGE) { self index: index outOfRange: (self basicSize) } + elsif (perr == Error.Code.EPERM) { self messageProhibited: #basicAt:put: } + else { self primitiveFailed } } method(#class) basicAt: index put: anObject { + | perr | - self index: index outOfRange: (self basicSize). + + perr := thisProcess primError. + if (perr == Error.Code.ERANGE) { self index: index outOfRange: (self basicSize) } + elsif (perr == Error.Code.EPERM) { self messageProhibited: #basicAt:put: } + else { self primitiveFailed } } (* ------------------------------------------------------------------ @@ -489,32 +537,6 @@ class UndefinedObject(Apex) } -class Error(Apex) -{ -} - -pooldic Error.Code -{ - EGENERIC := error(1). - ENOIMPL := error(2). - ESYSERR := error(3). - EINTERN := error(4). - ESYSMEM := error(5). - EOOMEM := error(6). - EINVAL := error(7). - ENOENT := error(8). -(* add more items... *) -} - -(*pooldic Error.Code2 -{ - >> CAN I SUPPORT this kind of redefnition? as of now, it's not accepted because - >> Error.Code2.EGENERIC is not a literal. Should i treate pooldic members as a constant - >> and treat it as if it's a literal like? then even if the defined value changes, - >> the definition here won't see the change... what is the best way to tackle this issue? - - EGENERIC := Error.Code2.EGENERIC. -}*) extend Error { diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index 359b2d3..c6a841a 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -1,33 +1,21 @@ class(#pointer) Process(Object) { - var initial_context, current_context, state, sp, prev, next, sem. + var initial_context, current_context, state, sp, prev, next, sem, perr. method new { "instantiation is not allowed" - ^nil. "TODO: raise an exception" + ^nil. "TODO: raise an exception or return an error" } - method prev - { - ^self.prev. - } + method prev { ^self.prev } + method next { ^self.next } - method next - { - ^self.next. - } + method next: process { self.next := process } + method prev: process { self.prev := process } - method next: process - { - self.next := process. - } - - method prev: process - { - self.prev := process. - } + method primError { ^self.perr } method resume { diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 8850d35..52264bb 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -3214,8 +3214,13 @@ if super is variable-nonpointer, no instance variable is allowed. GET_TOKEN (moo); - /* [NOTE] default value assignment. only a literal is allowed */ - lit = token_to_literal (moo, 1); + /* [NOTE] default value assignment. only a literal is allowed + * the initial values for instance variables and + * class instance variables are set to read-only. + * this is likely to change if the actual initial + * value assignment upon instantiation employes + * deep-copying in moo_instantiate() and in the compiler. */ + lit = token_to_literal (moo, dcl_type != VAR_CLASS); if (!lit) return -1; /* set the initial value for the variable added above */ @@ -4310,7 +4315,7 @@ static int __read_array_literal (moo_t* moo, int rdonly, moo_oop_t* xlit) if (__read_byte_array_literal (moo, &lit) <= -1) return -1; if (rdonly) { - MOO_ASSERT (moo, MOO_OOP_IS_POINTER(lit)); + MOO_ASSERT (moo, lit && MOO_OOP_IS_POINTER(lit)); MOO_OBJ_SET_FLAGS_RDONLY (lit, 1); } break; @@ -7071,7 +7076,9 @@ static MOO_INLINE moo_oop_t token_to_literal (moo_t* moo, int rdonly) } #if 0 -/* TODO: if a constant name is specified (constant defined in a class) */ +/* TODO: if a constant name is specified (constant defined in a class) or + * another variable with the default initialization value + * class { var x := 20, y := x. } */ case MOO_IOTOK_IDENT: case MOO_IOTOK_IDENT_DOTTED: #endif diff --git a/moo/lib/exec.c b/moo/lib/exec.c index c615c1d..f7ab795 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -160,6 +160,7 @@ static moo_oop_process_t make_process (moo_t* moo, moo_oop_context_t c) proc->initial_context = c; proc->current_context = c; proc->sp = MOO_SMOOI_TO_OOP(-1); + proc->perr = MOO_ERROR_TO_OOP(MOO_ENOERR); MOO_ASSERT (moo, (moo_oop_t)c->sender == moo->_nil); @@ -3821,9 +3822,11 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs) } else { + moo->errnum = MOO_EINVAL; MOO_DEBUG1 (moo, "Cannot call primitive numbered %zd - invalid number\n", pfnum); } + moo->processor->active->perr = MOO_ERROR_TO_OOP(moo->errnum); goto activate_primitive_method_body; } diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 59f9d7f..9f7364f 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -704,7 +704,7 @@ struct moo_context_t }; -#define MOO_PROCESS_NAMED_INSTVARS 7 +#define MOO_PROCESS_NAMED_INSTVARS 8 typedef struct moo_process_t moo_process_t; typedef struct moo_process_t* moo_oop_process_t; @@ -715,16 +715,17 @@ typedef struct moo_semaphore_t* moo_oop_semaphore_t; struct moo_process_t { MOO_OBJ_HEADER; - moo_oop_context_t initial_context; - moo_oop_context_t current_context; + moo_oop_context_t initial_context; + moo_oop_context_t current_context; - moo_oop_t state; /* SmallInteger */ - moo_oop_t sp; /* stack pointer. SmallInteger */ + moo_oop_t state; /* SmallInteger */ + moo_oop_t sp; /* stack pointer. SmallInteger */ - moo_oop_process_t prev; - moo_oop_process_t next; + moo_oop_process_t prev; + moo_oop_process_t next; moo_oop_semaphore_t sem; + moo_oop_t perr; /* last error set by a primitive function */ /* == variable indexed part == */ moo_oop_t slot[1]; /* process stack */