fixed the method lookup bug in exec.c
This commit is contained in:
		| @ -304,7 +304,6 @@ | |||||||
| 	{ | 	{ | ||||||
| 		self class cannotInstantiate | 		self class cannotInstantiate | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #class Object(Apex) | #class Object(Apex) | ||||||
|  | |||||||
| @ -19,7 +19,8 @@ | |||||||
|  |  | ||||||
|  |  | ||||||
| 	## ######################################################################## | 	## ######################################################################## | ||||||
| 	## most of the following methods can actuall become class methods of Apex. | 	## most of the following methods can actually become class methods of Apex. | ||||||
|  | 	## if the instance varibles can be made accessible from the Apex class. | ||||||
| 	## ######################################################################## | 	## ######################################################################## | ||||||
|  |  | ||||||
| 	#method name | 	#method name | ||||||
|  | |||||||
| @ -1,17 +1,18 @@ | |||||||
| #class(#word) Stdio(Object) | #class(#word) Stdio(Object) | ||||||
| { | { | ||||||
|  |  | ||||||
| 	#method(#class) new: size | 	#method(#class) new: size | ||||||
| 	{ | 	{ | ||||||
| 		##self prohibited | 		##self prohibited | ||||||
| 		##raise exception. prohibited... | 		##raise exception. prohibited... | ||||||
| 		^nil. | 		^(super new: 1) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	#method(#class) new | 	#method(#class) new | ||||||
| 	{ | 	{ | ||||||
| 		##self prohibited | 		##self prohibited | ||||||
| 		##raise exception. prohibited... | 		##raise exception. prohibited... | ||||||
| 		^nil. | 		^(super new: 1) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	#method(#class) open: name for: mode | 	#method(#class) open: name for: mode | ||||||
| @ -35,6 +36,13 @@ | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| #class(#word) Stdio2 (Stdio) | #class(#word) Stdio2(Stdio) | ||||||
| { | { | ||||||
|  | 	#method(#class) new | ||||||
|  | 	{ | ||||||
|  | 		##self prohibited | ||||||
|  | 		##raise exception. prohibited... | ||||||
|  | 		^(super new). | ||||||
|  | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -124,9 +124,12 @@ | |||||||
| 		System logNl: S'\0\0\0END OF MAIN\0AB\0\0\0C\0\0\0'. | 		System logNl: S'\0\0\0END OF MAIN\0AB\0\0\0C\0\0\0'. | ||||||
|  |  | ||||||
|  |  | ||||||
| 		v1 := Stdio open: '/tmp/1.txt' for: 'w+'. | 		##v1 := Stdio2 open: '/tmp/1.txt' for: 'w+'. | ||||||
|  | 		v1 := Stdio2 new open: '/tmp/1.txt' for: 'w+'. | ||||||
| 		v1 xxx. | 		v1 xxx. | ||||||
| 		v1 close. | 		v1 close. | ||||||
|  | 		nil isNil ifTrue: [ 'NIL NIL NIL' dump. ]. | ||||||
|  | 		(Apex new) notNil ifTrue: [ 'APEX NIL NIL NIL' dump. ]. | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -2478,19 +2478,20 @@ static int compile_class_level_variables (stix_t* stix) | |||||||
| 				var_info_t var; | 				var_info_t var; | ||||||
|  |  | ||||||
| /* | /* | ||||||
| TODO: check variability conflict. | TODO: more check on variability conflict. | ||||||
| if it's a indexed class, check if the superclass is fixed or index. | if it's a indexed class, check if the superclass is fixed or index. | ||||||
| if super is fixed and self is fixed or variable-pointer, no restriction. | if super is fixed and self is fixed or variable-pointer, no restriction. | ||||||
| if super is fixed and self is variable-nonpointer, no instance varaible in the super side and in the self side. | if super is fixed and self is variable-nonpointer, no instance varaible in the super side and in the self side. | ||||||
| if super is variable-pointer, self must be a variable-pointer. can't be fixed either | if super is variable-pointer, self must be a variable-pointer. can't be fixed either | ||||||
| if super is variable-nonpointer, self must be a variable-nonpointer of the same type. can't be fixed either | if super is variable-nonpointer, self must be a variable-nonpointer of the same type. can't be fixed either | ||||||
| if super is variable-nonpointer, no instance variable is allowed. | if super is variable-nonpointer, no instance variable is allowed. | ||||||
| 				if (stix->c->cls.flags & CLASS_INDEXED) | */ | ||||||
|  | 				if (dcl_type == VAR_INSTANCE && (stix->c->cls.flags & CLASS_INDEXED) && (stix->c->cls.indexed_type != STIX_OBJ_TYPE_OOP)) | ||||||
| 				{ | 				{ | ||||||
| 					set_syntax_error (stix, STIX_SYNERR_VARNAMEDUP, TOKEN_LOC(stix), TOKEN_NAME(stix)); | 					set_syntax_error (stix, STIX_SYNERR_VARNAMEDUP, TOKEN_LOC(stix), TOKEN_NAME(stix)); | ||||||
| 					return -1; | 					return -1; | ||||||
| 				} | 				} | ||||||
| */ |  | ||||||
| 				if (find_class_level_variable(stix, STIX_NULL, TOKEN_NAME(stix), &var) >= 0 || | 				if (find_class_level_variable(stix, STIX_NULL, TOKEN_NAME(stix), &var) >= 0 || | ||||||
| 				    stix_lookupdic (stix, stix->sysdic, TOKEN_NAME(stix)) ||  /* conflicts with a top global name */ | 				    stix_lookupdic (stix, stix->sysdic, TOKEN_NAME(stix)) ||  /* conflicts with a top global name */ | ||||||
| 				    stix_lookupdic (stix, stix->c->cls.ns_oop, TOKEN_NAME(stix))) /* conflicts with a global name in the class'es name space */ | 				    stix_lookupdic (stix, stix->c->cls.ns_oop, TOKEN_NAME(stix))) /* conflicts with a global name in the class'es name space */ | ||||||
|  | |||||||
| @ -987,55 +987,53 @@ static stix_oop_method_t find_method (stix_t* stix, stix_oop_t receiver, const s | |||||||
| 	int dic_no; | 	int dic_no; | ||||||
| /* TODO: implement method lookup cache */ | /* TODO: implement method lookup cache */ | ||||||
|  |  | ||||||
| #if defined(STIX_DEBUG_VM_METHOD_LOOKUP) |  | ||||||
| 	STIX_LOG3 (stix, STIX_LOG_IC | STIX_LOG_DEBUG, "Method lookup - Finding method %.*S for %O in ", message->len, message->ptr, receiver); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| 	cls = (stix_oop_class_t)STIX_CLASSOF(stix, receiver); | 	cls = (stix_oop_class_t)STIX_CLASSOF(stix, receiver); | ||||||
| 	if ((stix_oop_t)cls == stix->_class) | 	if ((stix_oop_t)cls == stix->_class) | ||||||
| 	{ | 	{ | ||||||
| 		/* receiver is a class object (an instance of Class) */ | 		/* receiver is a class object (an instance of Class) */ | ||||||
| 		c = receiver;  | 		c = receiver;  | ||||||
| 		dic_no = STIX_CLASS_MTHDIC_CLASS; | 		dic_no = STIX_CLASS_MTHDIC_CLASS; | ||||||
| #if defined(STIX_DEBUG_VM_METHOD_LOOKUP) |  | ||||||
| 	STIX_LOG1 (stix, STIX_LOG_IC | STIX_LOG_DEBUG, "Method lookup - class method dictionary of %O\n", c); |  | ||||||
| #endif |  | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
|  | 		/* receiver is not a class object. so take its class */ | ||||||
| 		c = (stix_oop_t)cls; | 		c = (stix_oop_t)cls; | ||||||
| 		dic_no = STIX_CLASS_MTHDIC_INSTANCE; | 		dic_no = STIX_CLASS_MTHDIC_INSTANCE; | ||||||
| #if defined(STIX_DEBUG_VM_METHOD_LOOKUP) |  | ||||||
| 	STIX_LOG1 (stix, STIX_LOG_IC | STIX_LOG_DEBUG, "Method lookup - instance method dictionary of %O\n", c); |  | ||||||
| #endif |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	if (c != stix->_nil) | 	STIX_ASSERT (c != stix->_nil); | ||||||
|  |  | ||||||
|  | 	if (super)  | ||||||
| 	{ | 	{ | ||||||
| 		if (super)  | 		/* | ||||||
| 		{ | 		stix_oop_method_t m; | ||||||
| 			c = ((stix_oop_class_t)c)->superclass; | 		STIX_ASSERT (STIX_CLASSOF(stix, stix->active_context->origin) == stix->_method_context); | ||||||
| 			if (c == stix->_nil) goto not_found; | 		m = (stix_oop_method_t)stix->active_context->origin->method_or_nargs; | ||||||
| 		} | 		c = ((stix_oop_class_t)m->owner)->superclass; | ||||||
|  | 		*/ | ||||||
| 		do | 		STIX_ASSERT (stix->active_method); | ||||||
| 		{ | 		STIX_ASSERT (stix->active_method->owner); | ||||||
| 			mthdic = ((stix_oop_class_t)c)->mthdic[dic_no]; | 		c = ((stix_oop_class_t)stix->active_method->owner)->superclass; | ||||||
| 			STIX_ASSERT ((stix_oop_t)mthdic != stix->_nil); | 		if (c == stix->_nil) goto not_found; /* reached the top of the hierarchy */ | ||||||
| 			STIX_ASSERT (STIX_CLASSOF(stix, mthdic) == stix->_method_dictionary); |  | ||||||
|  |  | ||||||
| /*stix_dumpdic (stix, mthdic, "Method dictionary");*/ |  | ||||||
| 			ass = (stix_oop_association_t)stix_lookupdic (stix, mthdic, message); |  | ||||||
| 			if (ass)  |  | ||||||
| 			{ |  | ||||||
| 				STIX_ASSERT (STIX_CLASSOF(stix, ass->value) == stix->_method); |  | ||||||
| 				return (stix_oop_method_t)ass->value; |  | ||||||
| 			} |  | ||||||
| 			c = ((stix_oop_class_t)c)->superclass; |  | ||||||
| 		} |  | ||||||
| 		while (c != stix->_nil); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	do | ||||||
|  | 	{ | ||||||
|  | 		mthdic = ((stix_oop_class_t)c)->mthdic[dic_no]; | ||||||
|  | 		STIX_ASSERT ((stix_oop_t)mthdic != stix->_nil); | ||||||
|  | 		STIX_ASSERT (STIX_CLASSOF(stix, mthdic) == stix->_method_dictionary); | ||||||
|  |  | ||||||
|  | 		ass = (stix_oop_association_t)stix_lookupdic (stix, mthdic, message); | ||||||
|  | 		if (ass)  | ||||||
|  | 		{ | ||||||
|  | 			/* found the method */ | ||||||
|  | 			STIX_ASSERT (STIX_CLASSOF(stix, ass->value) == stix->_method); | ||||||
|  | 			return (stix_oop_method_t)ass->value; | ||||||
|  | 		} | ||||||
|  | 		c = ((stix_oop_class_t)c)->superclass; | ||||||
|  | 	} | ||||||
|  | 	while (c != stix->_nil); | ||||||
|  |  | ||||||
| not_found: | not_found: | ||||||
| 	if ((stix_oop_t)cls == stix->_class) | 	if ((stix_oop_t)cls == stix->_class) | ||||||
| 	{ | 	{ | ||||||
| @ -1053,6 +1051,7 @@ not_found: | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	STIX_DEBUG3 (stix, "Method [%.*S] not found for %O\n", message->len, message->ptr, receiver); | ||||||
| 	stix->errnum = STIX_ENOENT; | 	stix->errnum = STIX_ENOENT; | ||||||
| 	return STIX_NULL; | 	return STIX_NULL; | ||||||
| } | } | ||||||
|  | |||||||
| @ -235,6 +235,7 @@ redo: | |||||||
| 		stix->log.capa = newcapa;  | 		stix->log.capa = newcapa;  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	while (len > 0) | 	while (len > 0) | ||||||
| 	{ | 	{ | ||||||
| 		stix->log.ptr[stix->log.len++] = ch; | 		stix->log.ptr[stix->log.len++] = ch; | ||||||
| @ -276,11 +277,12 @@ static int put_oocs (stix_t* stix, stix_oow_t mask, const stix_ooch_t* ptr, stix | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		newcapa = STIX_ALIGN(stix->log.len + len, 512); /* TODO: adjust this capacity */ | 		newcapa = STIX_ALIGN(stix->log.len + len, 512); /* TODO: adjust this capacity */ | ||||||
| 		tmp = stix_reallocmem (stix, stix->log.ptr, newcapa * STIX_SIZEOF(*tmp)); | 		/* +1 to handle line ending injection more easily */ | ||||||
|  | 		tmp = stix_reallocmem (stix, stix->log.ptr, (newcapa + 1) * STIX_SIZEOF(*tmp)); | ||||||
| 		if (!tmp) return -1; | 		if (!tmp) return -1; | ||||||
|  |  | ||||||
| 		stix->log.ptr = tmp; | 		stix->log.ptr = tmp; | ||||||
| 		stix->log.capa = newcapa - 1; /* -1 to handle line ending injection more easily */ | 		stix->log.capa = newcapa; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	STIX_MEMCPY (&stix->log.ptr[stix->log.len], ptr, len * STIX_SIZEOF(*ptr)); | 	STIX_MEMCPY (&stix->log.ptr[stix->log.len], ptr, len * STIX_SIZEOF(*ptr)); | ||||||
|  | |||||||
| @ -49,7 +49,6 @@ | |||||||
| #define STIX_DEBUG_COMPILER | #define STIX_DEBUG_COMPILER | ||||||
| /*#define STIX_DEBUG_VM_PROCESSOR*/ | /*#define STIX_DEBUG_VM_PROCESSOR*/ | ||||||
| /*#define STIX_DEBUG_VM_EXEC*/ | /*#define STIX_DEBUG_VM_EXEC*/ | ||||||
| /*#define STIX_DEBUG_VM_METHOD_LOOKUP*/ |  | ||||||
| #define STIX_DEBUG_BIGINT | #define STIX_DEBUG_BIGINT | ||||||
| #define STIX_PROFILE_VM | #define STIX_PROFILE_VM | ||||||
|  |  | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user