From e8985e6dc5d80e233f546ffd23107cf865fa79ad Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Mon, 21 Nov 2016 13:56:20 +0000 Subject: [PATCH] fixed the method lookup bug in exec.c --- stix/kernel/Apex.st | 1 - stix/kernel/Class.st | 3 +- stix/kernel/Stdio.st | 14 +++++++-- stix/kernel/test-014.st | 5 +++- stix/lib/comp.c | 7 +++-- stix/lib/exec.c | 65 ++++++++++++++++++++--------------------- stix/lib/logfmt.c | 6 ++-- stix/lib/stix-prv.h | 1 - 8 files changed, 57 insertions(+), 45 deletions(-) diff --git a/stix/kernel/Apex.st b/stix/kernel/Apex.st index 2c8f906..5d0aaa3 100644 --- a/stix/kernel/Apex.st +++ b/stix/kernel/Apex.st @@ -304,7 +304,6 @@ { self class cannotInstantiate } - } #class Object(Apex) diff --git a/stix/kernel/Class.st b/stix/kernel/Class.st index a342bef..7cac092 100644 --- a/stix/kernel/Class.st +++ b/stix/kernel/Class.st @@ -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 diff --git a/stix/kernel/Stdio.st b/stix/kernel/Stdio.st index 2d019b7..ed73d4e 100644 --- a/stix/kernel/Stdio.st +++ b/stix/kernel/Stdio.st @@ -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 @@ -35,6 +36,13 @@ } } -#class(#word) Stdio2 (Stdio) +#class(#word) Stdio2(Stdio) { + #method(#class) new + { + ##self prohibited + ##raise exception. prohibited... + ^(super new). + } + } diff --git a/stix/kernel/test-014.st b/stix/kernel/test-014.st index 21f641c..05d6986 100644 --- a/stix/kernel/test-014.st +++ b/stix/kernel/test-014.st @@ -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. ]. } } diff --git a/stix/lib/comp.c b/stix/lib/comp.c index 537be60..fb08cf9 100644 --- a/stix/lib/comp.c +++ b/stix/lib/comp.c @@ -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 */ diff --git a/stix/lib/exec.c b/stix/lib/exec.c index fe499d6..50d606e 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -987,55 +987,53 @@ 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) { - if (super) - { - c = ((stix_oop_class_t)c)->superclass; - if (c == stix->_nil) goto not_found; - } - - 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); - -/*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); + /* + 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 + { + 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: 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; } diff --git a/stix/lib/logfmt.c b/stix/lib/logfmt.c index 8238b8d..e0d10e3 100644 --- a/stix/lib/logfmt.c +++ b/stix/lib/logfmt.c @@ -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)); diff --git a/stix/lib/stix-prv.h b/stix/lib/stix-prv.h index 196a5f6..6020a93 100644 --- a/stix/lib/stix-prv.h +++ b/stix/lib/stix-prv.h @@ -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