fixed the method lookup bug in exec.c
This commit is contained in:
		| @ -304,7 +304,6 @@ | ||||
| 	{ | ||||
| 		self class cannotInstantiate | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| #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 | ||||
|  | ||||
| @ -1,17 +1,18 @@ | ||||
| #class(#word) Stdio(Object) | ||||
| { | ||||
|  | ||||
| 	#method(#class) new: size | ||||
| 	{ | ||||
| 		##self prohibited | ||||
| 		##raise exception. prohibited... | ||||
| 		^nil. | ||||
| 		^(super new: 1) | ||||
| 	} | ||||
|  | ||||
| 	#method(#class) new | ||||
| 	{ | ||||
| 		##self prohibited | ||||
| 		##raise exception. prohibited... | ||||
| 		^nil. | ||||
| 		^(super new: 1) | ||||
| 	} | ||||
|  | ||||
| 	#method(#class) open: name for: mode | ||||
| @ -37,4 +38,11 @@ | ||||
|  | ||||
| #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'. | ||||
|  | ||||
|  | ||||
| 		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 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; | ||||
|  | ||||
| /* | ||||
| 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 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 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, 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)); | ||||
| 					return -1; | ||||
| 				} | ||||
| */ | ||||
|  | ||||
| 				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->c->cls.ns_oop, TOKEN_NAME(stix))) /* conflicts with a global name in the class'es name space */ | ||||
|  | ||||
| @ -987,35 +987,34 @@ static stix_oop_method_t find_method (stix_t* stix, stix_oop_t receiver, const s | ||||
| 	int dic_no; | ||||
| /* 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); | ||||
| 	if ((stix_oop_t)cls == stix->_class) | ||||
| 	{ | ||||
| 		/* receiver is a class object (an instance of Class) */ | ||||
| 		c = receiver;  | ||||
| 		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 | ||||
| 	{ | ||||
| 		/* receiver is not a class object. so take its class */ | ||||
| 		c = (stix_oop_t)cls; | ||||
| 		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)  | ||||
| 	{ | ||||
| 			c = ((stix_oop_class_t)c)->superclass; | ||||
| 			if (c == stix->_nil) goto not_found; | ||||
| 		/* | ||||
| 		stix_oop_method_t m; | ||||
| 		STIX_ASSERT (STIX_CLASSOF(stix, stix->active_context->origin) == stix->_method_context); | ||||
| 		m = (stix_oop_method_t)stix->active_context->origin->method_or_nargs; | ||||
| 		c = ((stix_oop_class_t)m->owner)->superclass; | ||||
| 		*/ | ||||
| 		STIX_ASSERT (stix->active_method); | ||||
| 		STIX_ASSERT (stix->active_method->owner); | ||||
| 		c = ((stix_oop_class_t)stix->active_method->owner)->superclass; | ||||
| 		if (c == stix->_nil) goto not_found; /* reached the top of the hierarchy */ | ||||
| 	} | ||||
|  | ||||
| 	do | ||||
| @ -1024,17 +1023,16 @@ static stix_oop_method_t find_method (stix_t* stix, stix_oop_t receiver, const s | ||||
| 		STIX_ASSERT ((stix_oop_t)mthdic != stix->_nil); | ||||
| 		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)  | ||||
| 		{ | ||||
| 			/* 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: | ||||
| 	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; | ||||
| 	return STIX_NULL; | ||||
| } | ||||
|  | ||||
| @ -235,6 +235,7 @@ redo: | ||||
| 		stix->log.capa = newcapa;  | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	while (len > 0) | ||||
| 	{ | ||||
| 		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 */ | ||||
| 		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; | ||||
|  | ||||
| 		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)); | ||||
|  | ||||
| @ -49,7 +49,6 @@ | ||||
| #define STIX_DEBUG_COMPILER | ||||
| /*#define STIX_DEBUG_VM_PROCESSOR*/ | ||||
| /*#define STIX_DEBUG_VM_EXEC*/ | ||||
| /*#define STIX_DEBUG_VM_METHOD_LOOKUP*/ | ||||
| #define STIX_DEBUG_BIGINT | ||||
| #define STIX_PROFILE_VM | ||||
|  | ||||
|  | ||||
		Reference in New Issue
	
	Block a user