added moo_process_t.perr and Processor>>primError to capture the last error set by a primitive function

This commit is contained in:
hyunghwan.chung 2017-04-25 15:20:58 +00:00
parent d3c9a33c30
commit 8298bad3e0
5 changed files with 90 additions and 69 deletions

View File

@ -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 |
<primitive: #_basic_at>
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 |
<primitive: #_basic_at_put>
## 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 |
<primitive: #_basic_at>
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 |
<primitive: #_basic_at_put>
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
{

View File

@ -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
{

View File

@ -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

View File

@ -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;
}

View File

@ -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 */