added moo_process_t.perr and Processor>>primError to capture the last error set by a primitive function
This commit is contained in:
		| @ -1,4 +1,38 @@ | |||||||
| class Apex(nil) | 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 | 	method basicAt: index | ||||||
| 	{ | 	{ | ||||||
|  | 		| perr | | ||||||
|  | 		 | ||||||
| 		<primitive: #_basic_at> | 		<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 | 	method basicAt: index put: anObject | ||||||
| 	{ | 	{ | ||||||
|  | 		| perr | | ||||||
|  | 		 | ||||||
| 		<primitive: #_basic_at_put> | 		<primitive: #_basic_at_put> | ||||||
| ## TODO: proper error handling |  | ||||||
| (* | 		perr := thisProcess primError. | ||||||
| 		if (primitiveError == error(generic)) | 		if (perr == Error.Code.ERANGE) { self index: index outOfRange: (self basicSize) } | ||||||
| 		{ | 		elsif (perr == Error.Code.EPERM) { self messageProhibited: #basicAt:put: } | ||||||
| 		} | 		else { self primitiveFailed } | ||||||
| 		else |  | ||||||
| 		{ |  | ||||||
| 			self index: index outOfRange: (self basicSize). |  | ||||||
| 		}*) |  | ||||||
| 		self index: index outOfRange: (self basicSize). |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	method(#class) basicAt: index | 	method(#class) basicAt: index | ||||||
| 	{ | 	{ | ||||||
|  | 		| perr | | ||||||
| 		<primitive: #_basic_at> | 		<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 | 	method(#class) basicAt: index put: anObject | ||||||
| 	{ | 	{ | ||||||
|  | 		| perr | | ||||||
| 		<primitive: #_basic_at_put> | 		<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 | extend Error | ||||||
| { | { | ||||||
|  | |||||||
| @ -1,33 +1,21 @@ | |||||||
|  |  | ||||||
| class(#pointer) Process(Object) | 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 | 	method new | ||||||
| 	{ | 	{ | ||||||
| 		"instantiation is not allowed" | 		"instantiation is not allowed" | ||||||
| 		^nil. "TODO: raise an exception" | 		^nil. "TODO: raise an exception or return an error" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	method prev | 	method prev { ^self.prev } | ||||||
| 	{ | 	method next { ^self.next } | ||||||
| 		^self.prev. |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	method next | 	method next: process { self.next := process } | ||||||
| 	{ | 	method prev: process { self.prev := process } | ||||||
| 		^self.next. |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	method next: process | 	method primError { ^self.perr } | ||||||
| 	{ |  | ||||||
| 		self.next := process. |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	method prev: process |  | ||||||
| 	{ |  | ||||||
| 		self.prev := process. |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	method resume | 	method resume | ||||||
| 	{ | 	{ | ||||||
|  | |||||||
| @ -3214,8 +3214,13 @@ if super is variable-nonpointer, no instance variable is allowed. | |||||||
|  |  | ||||||
| 				GET_TOKEN (moo); | 				GET_TOKEN (moo); | ||||||
|  |  | ||||||
| 				/* [NOTE] default value assignment. only a literal is allowed */ | 				/* [NOTE] default value assignment. only a literal is allowed  | ||||||
| 				lit = token_to_literal (moo, 1); | 				 *    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; | 				if (!lit) return -1; | ||||||
|  |  | ||||||
| 				/* set the initial value for the variable added above */ | 				/* 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 (__read_byte_array_literal (moo, &lit) <= -1) return -1; | ||||||
| 				if (rdonly) | 				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); | 					MOO_OBJ_SET_FLAGS_RDONLY (lit, 1); | ||||||
| 				} | 				} | ||||||
| 				break; | 				break; | ||||||
| @ -7071,7 +7076,9 @@ static MOO_INLINE moo_oop_t token_to_literal (moo_t* moo, int rdonly) | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| #if 0 | #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: | ||||||
| 		case MOO_IOTOK_IDENT_DOTTED: | 		case MOO_IOTOK_IDENT_DOTTED: | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -160,6 +160,7 @@ static moo_oop_process_t make_process (moo_t* moo, moo_oop_context_t c) | |||||||
| 	proc->initial_context = c; | 	proc->initial_context = c; | ||||||
| 	proc->current_context = c; | 	proc->current_context = c; | ||||||
| 	proc->sp = MOO_SMOOI_TO_OOP(-1); | 	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); | 	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 | 			else | ||||||
| 			{ | 			{ | ||||||
|  | 				moo->errnum = MOO_EINVAL; | ||||||
| 				MOO_DEBUG1 (moo, "Cannot call primitive numbered %zd - invalid number\n", pfnum); | 				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; | 			goto activate_primitive_method_body; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | |||||||
| @ -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_process_t; | ||||||
| typedef struct moo_process_t* moo_oop_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 | struct moo_process_t | ||||||
| { | { | ||||||
| 	MOO_OBJ_HEADER; | 	MOO_OBJ_HEADER; | ||||||
| 	moo_oop_context_t initial_context; | 	moo_oop_context_t   initial_context; | ||||||
| 	moo_oop_context_t current_context; | 	moo_oop_context_t   current_context; | ||||||
|  |  | ||||||
| 	moo_oop_t         state; /* SmallInteger */ | 	moo_oop_t           state; /* SmallInteger */ | ||||||
| 	moo_oop_t         sp;    /* stack pointer. SmallInteger */ | 	moo_oop_t           sp;    /* stack pointer. SmallInteger */ | ||||||
|  |  | ||||||
| 	moo_oop_process_t prev; | 	moo_oop_process_t   prev; | ||||||
| 	moo_oop_process_t next; | 	moo_oop_process_t   next; | ||||||
|  |  | ||||||
| 	moo_oop_semaphore_t sem; | 	moo_oop_semaphore_t sem; | ||||||
|  | 	moo_oop_t           perr; /* last error set by a primitive function */ | ||||||
|  |  | ||||||
| 	/* == variable indexed part == */ | 	/* == variable indexed part == */ | ||||||
| 	moo_oop_t slot[1]; /* process stack */ | 	moo_oop_t slot[1]; /* process stack */ | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user