fixed the method lookup bug in exec.c

This commit is contained in:
hyunghwan.chung 2016-11-21 13:56:20 +00:00
parent eaa9dbc958
commit e8985e6dc5
8 changed files with 57 additions and 45 deletions

View File

@ -304,7 +304,6 @@
{
self class cannotInstantiate
}
}
#class Object(Apex)

View File

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

View File

@ -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).
}
}

View File

@ -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. ].
}
}

View File

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

View File

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

View File

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

View File

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