diff --git a/moo/kernel/Collect.moo b/moo/kernel/Collect.moo index d431440..e16be02 100644 --- a/moo/kernel/Collect.moo +++ b/moo/kernel/Collect.moo @@ -105,11 +105,18 @@ class(#character) String(Array) { ^self } + + (* TODO: Symbol is a #final class. Symbol new is not allowed. To create a symbol programatically, you should + * build a string and send asSymbol to the string............ + method asSymbol + { + } + *) } ## ------------------------------------------------------------------------------- -class(#character) Symbol(String) +class(#character,#final,#limited) Symbol(String) { method asString { diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index 835e59d..35d5f73 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -1,5 +1,5 @@ -class(#pointer,#limited) Process(Object) +class(#pointer,#final,#limited) Process(Object) { var initial_context, current_context, state, sp, prev, next, sem, perr. @@ -345,7 +345,7 @@ class SemaphoreHeap(Object) } } -class(#limited) ProcessScheduler(Object) +class(#final,#limited) ProcessScheduler(Object) { var tally, active, runnable_head, runnable_tail, sem_heap. diff --git a/moo/kernel/generr.moo b/moo/kernel/generr.moo index ebdf192..32e59cc 100644 --- a/moo/kernel/generr.moo +++ b/moo/kernel/generr.moo @@ -74,7 +74,8 @@ class MyObject(Object) 'duplicate class' 'contradictory class definition' 'wrong class name' - 'non-pointer class inheriting superclass with trailer size set' + 'non-pointer class not allowed to inherit a superclass with trailer size set' + 'not allowed to inherit a #final class' 'variable declaration not allowed' 'modifier expected' 'wrong modifier' diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 6678d51..d379980 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -50,9 +50,9 @@ enum class_mod_t { - CLASS_INDEXED = (1 << 0), + CLASS_FINAL = (1 << 0), CLASS_LIMITED = (1 << 1), - CLASS_FINAL = (1 << 2) + CLASS_INDEXED = (1 << 2) }; enum var_type_t @@ -2739,12 +2739,12 @@ done: * local variable string can be adjusted by adding the * number in the superclass */ spec = MOO_OOP_TO_SMOOI(((moo_oop_class_t)super)->spec); - pos += MOO_CLASS_SPEC_NAMED_INSTVAR(spec); + pos += MOO_CLASS_SPEC_NAMED_INSTVARS(spec); break; case VAR_CLASSINST: spec = MOO_OOP_TO_SMOOI(((moo_oop_class_t)super)->selfspec); - pos += MOO_CLASS_SELFSPEC_CLASSINSTVAR(spec); + pos += MOO_CLASS_SELFSPEC_CLASSINSTVARS(spec); break; case VAR_CLASS: @@ -3902,7 +3902,7 @@ static int get_variable_info (moo_t* moo, const moo_oocs_t* name, const moo_iolo /* increment the position by the number of class instance variables * as the class variables are placed after the class instance variables */ var->pos += MOO_CLASS_NAMED_INSTVARS + - MOO_CLASS_SELFSPEC_CLASSINSTVAR(MOO_OOP_TO_SMOOI(var->cls->selfspec)); + MOO_CLASS_SELFSPEC_CLASSINSTVARS(MOO_OOP_TO_SMOOI(var->cls->selfspec)); break; default: @@ -6405,14 +6405,17 @@ static int make_defined_class (moo_t* moo) moo_oop_t tmp; moo_oow_t spec, self_spec; - int just_made = 0; + int just_made = 0, flags; spec = MOO_CLASS_SPEC_MAKE (moo->c->cls.var[VAR_INSTANCE].total_count, ((moo->c->cls.flags & CLASS_INDEXED)? 1: 0), moo->c->cls.indexed_type); + flags = 0; + if (moo->c->cls.flags & CLASS_FINAL) flags |= MOO_CLASS_SELFSPEC_FLAG_FINAL; + if (moo->c->cls.flags & CLASS_LIMITED) flags |= MOO_CLASS_SELFSPEC_FLAG_LIMITED; self_spec = MOO_CLASS_SELFSPEC_MAKE (moo->c->cls.var[VAR_CLASS].total_count, - moo->c->cls.var[VAR_CLASSINST].total_count); + moo->c->cls.var[VAR_CLASSINST].total_count, flags); if (moo->c->cls.self_oop) { @@ -6672,51 +6675,6 @@ static int __compile_class_definition (moo_t* moo, int extend) while (1); } -#if 0 - if (is_token_symbol(moo, VOCA_BYTE_S)) - { - /* class(#byte) */ - moo->c->cls.flags |= CLASS_INDEXED; - moo->c->cls.indexed_type = MOO_OBJ_TYPE_BYTE; - GET_TOKEN (moo); - } - else if (is_token_symbol(moo, VOCA_CHARACTER_S)) - { - /* class(#character) */ - moo->c->cls.flags |= CLASS_INDEXED; - moo->c->cls.indexed_type = MOO_OBJ_TYPE_CHAR; - GET_TOKEN (moo); - } - else if (is_token_symbol(moo, VOCA_HALFWORD_S)) - { - /* class(#halfword) */ - moo->c->cls.flags |= CLASS_INDEXED; - moo->c->cls.indexed_type = MOO_OBJ_TYPE_HALFWORD; - GET_TOKEN (moo); - } - else if (is_token_symbol(moo, VOCA_WORD_S)) - { - /* class(#word) */ - moo->c->cls.flags |= CLASS_INDEXED; - moo->c->cls.indexed_type = MOO_OBJ_TYPE_WORD; - GET_TOKEN (moo); - } - else if (is_token_symbol(moo, VOCA_POINTER_S)) - { - /* class(#pointer) */ - moo->c->cls.flags |= CLASS_INDEXED; - moo->c->cls.indexed_type = MOO_OBJ_TYPE_OOP; - GET_TOKEN (moo); - } - else if (is_token_symbol(moo, VOCA_LIWORD_S)) - { - /* class(#liword) */ - moo->c->cls.flags |= CLASS_INDEXED; - moo->c->cls.indexed_type = MOO_OBJ_TYPE_LIWORD; - GET_TOKEN (moo); - } -#endif - if (TOKEN_TYPE(moo) != MOO_IOTOK_RPAREN) { set_syntax_error (moo, MOO_SYNERR_RPAREN, TOKEN_LOC(moo), TOKEN_NAME(moo)); @@ -6801,8 +6759,7 @@ static int __compile_class_definition (moo_t* moo, int extend) } /* superclass is specified. new class defintion. - * for example, #class Class(Stix) - */ + * for example, #class Class(Stix) */ GET_TOKEN (moo); /* read superclass name */ /* TODO: multiple inheritance */ @@ -6895,6 +6852,13 @@ static int __compile_class_definition (moo_t* moo, int extend) set_syntax_error (moo, MOO_SYNERR_CLASSTRSIZE, &moo->c->cls.fqn_loc, &moo->c->cls.fqn); return -1; } + + if (MOO_CLASS_SELFSPEC_FLAGS(MOO_OOP_TO_SMOOI(((moo_oop_class_t)moo->c->cls.super_oop)->selfspec)) & MOO_CLASS_SELFSPEC_FLAG_FINAL) + { + /* cannot inherit a #final class */ + set_syntax_error (moo, MOO_SYNERR_CLASSFINAL, &moo->c->cls.fqn_loc, &moo->c->cls.fqn); + return -1; + } } else { @@ -6957,8 +6921,8 @@ static int __compile_class_definition (moo_t* moo, int extend) /* [NOTE] class variables are not inherited. * so no data about them are not transferred over */ - moo->c->cls.var[VAR_INSTANCE].total_count = MOO_CLASS_SPEC_NAMED_INSTVAR(spec); - moo->c->cls.var[VAR_CLASSINST].total_count = MOO_CLASS_SELFSPEC_CLASSINSTVAR(self_spec); + moo->c->cls.var[VAR_INSTANCE].total_count = MOO_CLASS_SPEC_NAMED_INSTVARS(spec); + moo->c->cls.var[VAR_CLASSINST].total_count = MOO_CLASS_SELFSPEC_CLASSINSTVARS(self_spec); } GET_TOKEN (moo); diff --git a/moo/lib/err.c b/moo/lib/err.c index e364f72..1fb92f9 100644 --- a/moo/lib/err.c +++ b/moo/lib/err.c @@ -100,43 +100,44 @@ static moo_ooch_t synerrstr_27[] = {'u','n','d','e','f','i','n','e','d',' ','c', static moo_ooch_t synerrstr_28[] = {'d','u','p','l','i','c','a','t','e',' ','c','l','a','s','s','\0'}; static moo_ooch_t synerrstr_29[] = {'c','o','n','t','r','a','d','i','c','t','o','r','y',' ','c','l','a','s','s',' ','d','e','f','i','n','i','t','i','o','n','\0'}; static moo_ooch_t synerrstr_30[] = {'w','r','o','n','g',' ','c','l','a','s','s',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_31[] = {'n','o','n','-','p','o','i','n','t','e','r',' ','c','l','a','s','s',' ','i','n','h','e','r','i','t','i','n','g',' ','s','u','p','e','r','c','l','a','s','s',' ','w','i','t','h',' ','t','r','a','i','l','e','r',' ','s','i','z','e',' ','s','e','t','\0'}; -static moo_ooch_t synerrstr_32[] = {'v','a','r','i','a','b','l','e',' ','d','e','c','l','a','r','a','t','i','o','n',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'}; -static moo_ooch_t synerrstr_33[] = {'m','o','d','i','f','i','e','r',' ','e','x','p','e','c','t','e','d','\0'}; -static moo_ooch_t synerrstr_34[] = {'w','r','o','n','g',' ','m','o','d','i','f','i','e','r','\0'}; -static moo_ooch_t synerrstr_35[] = {'d','i','s','a','l','l','o','w','e','d',' ','m','o','d','i','f','i','e','r','\0'}; -static moo_ooch_t synerrstr_36[] = {'d','u','p','l','i','c','a','t','e',' ','m','o','d','i','f','i','e','r','\0'}; -static moo_ooch_t synerrstr_37[] = {'m','e','t','h','o','d',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'}; -static moo_ooch_t synerrstr_38[] = {'d','u','p','l','i','c','a','t','e',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_39[] = {'i','n','v','a','l','i','d',' ','v','a','r','i','a','d','i','c',' ','m','e','t','h','o','d',' ','d','e','f','i','n','i','t','i','o','n','\0'}; -static moo_ooch_t synerrstr_40[] = {'v','a','r','i','a','b','l','e',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'}; -static moo_ooch_t synerrstr_41[] = {'d','u','p','l','i','c','a','t','e',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_42[] = {'d','u','p','l','i','c','a','t','e',' ','t','e','m','p','o','r','a','r','y',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_43[] = {'d','u','p','l','i','c','a','t','e',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_44[] = {'d','u','p','l','i','c','a','t','e',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_45[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'}; -static moo_ooch_t synerrstr_46[] = {'u','n','u','s','a','b','l','e',' ','v','a','r','i','a','b','l','e',' ','i','n',' ','c','o','m','p','i','l','e','d',' ','c','o','d','e','\0'}; -static moo_ooch_t synerrstr_47[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','v','a','r','i','a','b','l','e','\0'}; -static moo_ooch_t synerrstr_48[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'}; -static moo_ooch_t synerrstr_49[] = {'w','r','o','n','g',' ','e','x','p','r','e','s','s','i','o','n',' ','p','r','i','m','a','r','y','\0'}; -static moo_ooch_t synerrstr_50[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; -static moo_ooch_t synerrstr_51[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'}; -static moo_ooch_t synerrstr_52[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; -static moo_ooch_t synerrstr_53[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'}; -static moo_ooch_t synerrstr_54[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'}; -static moo_ooch_t synerrstr_55[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'}; -static moo_ooch_t synerrstr_56[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'}; -static moo_ooch_t synerrstr_57[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'}; -static moo_ooch_t synerrstr_58[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','a','r','g','u','m','e','n','t',' ','d','e','f','i','n','i','t','i','o','n','\0'}; -static moo_ooch_t synerrstr_59[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_60[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'}; -static moo_ooch_t synerrstr_61[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_62[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_63[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_64[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'}; -static moo_ooch_t synerrstr_65[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'}; -static moo_ooch_t synerrstr_66[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'}; -static moo_ooch_t synerrstr_67[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_31[] = {'n','o','n','-','p','o','i','n','t','e','r',' ','c','l','a','s','s',' ','n','o','t',' ','a','l','l','o','w','e','d',' ','t','o',' ','i','n','h','e','r','i','t',' ','a',' ','s','u','p','e','r','c','l','a','s','s',' ','w','i','t','h',' ','t','r','a','i','l','e','r',' ','s','i','z','e',' ','s','e','t','\0'}; +static moo_ooch_t synerrstr_32[] = {'n','o','t',' ','a','l','l','o','w','e','d',' ','t','o',' ','i','n','h','e','r','i','t',' ','a',' ','#','f','i','n','a','l',' ','c','l','a','s','s','\0'}; +static moo_ooch_t synerrstr_33[] = {'v','a','r','i','a','b','l','e',' ','d','e','c','l','a','r','a','t','i','o','n',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'}; +static moo_ooch_t synerrstr_34[] = {'m','o','d','i','f','i','e','r',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_35[] = {'w','r','o','n','g',' ','m','o','d','i','f','i','e','r','\0'}; +static moo_ooch_t synerrstr_36[] = {'d','i','s','a','l','l','o','w','e','d',' ','m','o','d','i','f','i','e','r','\0'}; +static moo_ooch_t synerrstr_37[] = {'d','u','p','l','i','c','a','t','e',' ','m','o','d','i','f','i','e','r','\0'}; +static moo_ooch_t synerrstr_38[] = {'m','e','t','h','o','d',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_39[] = {'d','u','p','l','i','c','a','t','e',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_40[] = {'i','n','v','a','l','i','d',' ','v','a','r','i','a','d','i','c',' ','m','e','t','h','o','d',' ','d','e','f','i','n','i','t','i','o','n','\0'}; +static moo_ooch_t synerrstr_41[] = {'v','a','r','i','a','b','l','e',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_42[] = {'d','u','p','l','i','c','a','t','e',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_43[] = {'d','u','p','l','i','c','a','t','e',' ','t','e','m','p','o','r','a','r','y',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_44[] = {'d','u','p','l','i','c','a','t','e',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_45[] = {'d','u','p','l','i','c','a','t','e',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_46[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'}; +static moo_ooch_t synerrstr_47[] = {'u','n','u','s','a','b','l','e',' ','v','a','r','i','a','b','l','e',' ','i','n',' ','c','o','m','p','i','l','e','d',' ','c','o','d','e','\0'}; +static moo_ooch_t synerrstr_48[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','v','a','r','i','a','b','l','e','\0'}; +static moo_ooch_t synerrstr_49[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'}; +static moo_ooch_t synerrstr_50[] = {'w','r','o','n','g',' ','e','x','p','r','e','s','s','i','o','n',' ','p','r','i','m','a','r','y','\0'}; +static moo_ooch_t synerrstr_51[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; +static moo_ooch_t synerrstr_52[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'}; +static moo_ooch_t synerrstr_53[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; +static moo_ooch_t synerrstr_54[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'}; +static moo_ooch_t synerrstr_55[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'}; +static moo_ooch_t synerrstr_56[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'}; +static moo_ooch_t synerrstr_57[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'}; +static moo_ooch_t synerrstr_58[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'}; +static moo_ooch_t synerrstr_59[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','a','r','g','u','m','e','n','t',' ','d','e','f','i','n','i','t','i','o','n','\0'}; +static moo_ooch_t synerrstr_60[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_61[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'}; +static moo_ooch_t synerrstr_62[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_63[] = {'w','r','o','n','g',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_64[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l',' ','d','i','c','t','i','o','n','a','r','y',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_65[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_66[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'}; +static moo_ooch_t synerrstr_67[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'}; +static moo_ooch_t synerrstr_68[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'}; static moo_ooch_t* synerrstr[] = { synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7, @@ -147,7 +148,7 @@ static moo_ooch_t* synerrstr[] = synerrstr_40, synerrstr_41, synerrstr_42, synerrstr_43, synerrstr_44, synerrstr_45, synerrstr_46, synerrstr_47, synerrstr_48, synerrstr_49, synerrstr_50, synerrstr_51, synerrstr_52, synerrstr_53, synerrstr_54, synerrstr_55, synerrstr_56, synerrstr_57, synerrstr_58, synerrstr_59, synerrstr_60, synerrstr_61, synerrstr_62, synerrstr_63, - synerrstr_64, synerrstr_65, synerrstr_66, synerrstr_67 + synerrstr_64, synerrstr_65, synerrstr_66, synerrstr_67, synerrstr_68 }; #endif /* END: GENERATED WITH generr.moo */ diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 83538d1..73f2d11 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -1296,7 +1296,7 @@ static moo_pfrc_t pf_log (moo_t* moo, moo_ooi_t nargs) _class = MOO_CLASSOF(moo, msg); spec = MOO_OOP_TO_SMOOI(((moo_oop_class_t)_class)->spec); - if (MOO_CLASS_SPEC_NAMED_INSTVAR(spec) > 0 || !MOO_CLASS_SPEC_IS_INDEXED(spec)) goto dump_object; + if (MOO_CLASS_SPEC_NAMED_INSTVARS(spec) > 0 || !MOO_CLASS_SPEC_IS_INDEXED(spec)) goto dump_object; for (i = 0; i < MOO_OBJ_GET_SIZE(msg); i++) { @@ -1470,7 +1470,13 @@ static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs) return MOO_PF_FAILURE; } -/* TOOD: check if _class is set to be instantiatable... if not MOO_EPERM */ + /* check if #limited is set on the class */ + if (MOO_CLASS_SELFSPEC_FLAGS(MOO_OOP_TO_SMOOI(_class->selfspec)) & MOO_CLASS_SELFSPEC_FLAG_LIMITED) + { + MOO_DEBUG0 (moo, " Receiver is #limited\n"); + moo->errnum = MOO_EPERM; + return MOO_PF_FAILURE; + } if (nargs >= 1) { diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 286bbce..6b1a394 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -123,17 +123,17 @@ static kernel_class_info_t kernel_classes[] = * BOOTSTRAPPER * ----------------------------------------------------------------------- */ -static moo_oop_class_t alloc_kernel_class (moo_t* moo, moo_oow_t indexed_classvars, moo_oow_t spec) +static moo_oop_class_t alloc_kernel_class (moo_t* moo, int class_flags, moo_oow_t num_classvars, moo_oow_t spec) { moo_oop_class_t c; - c = (moo_oop_class_t)moo_allocoopobj (moo, MOO_CLASS_NAMED_INSTVARS + indexed_classvars); + c = (moo_oop_class_t)moo_allocoopobj (moo, MOO_CLASS_NAMED_INSTVARS + num_classvars); if (!c) return MOO_NULL; MOO_OBJ_SET_FLAGS_KERNEL (c, 1); MOO_OBJ_SET_CLASS (c, (moo_oop_t)moo->_class); c->spec = MOO_SMOOI_TO_OOP(spec); - c->selfspec = MOO_SMOOI_TO_OOP(MOO_CLASS_SELFSPEC_MAKE(indexed_classvars, 0)); + c->selfspec = MOO_SMOOI_TO_OOP(MOO_CLASS_SELFSPEC_MAKE(num_classvars, 0, class_flags)); return c; } @@ -153,7 +153,7 @@ static int ignite_1 (moo_t* moo) * The instance of Class can have indexed instance variables * which are actually class variables. * -------------------------------------------------------------- */ - moo->_class = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_CLASS_NAMED_INSTVARS, 1, MOO_OBJ_TYPE_OOP)); + moo->_class = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_CLASS_NAMED_INSTVARS, 1, MOO_OBJ_TYPE_OOP)); if (!moo->_class) return -1; MOO_ASSERT (moo, MOO_OBJ_GET_CLASS(moo->_class) == MOO_NULL); @@ -171,43 +171,52 @@ static int ignite_1 (moo_t* moo) * Character * SmallIntger * -------------------------------------------------------------- */ - moo->_apex = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); - moo->_undefined_object = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); - moo->_object = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); - moo->_string = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_CHAR)); + moo->_apex = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); + moo->_undefined_object = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); + moo->_object = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); + moo->_string = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_CHAR)); - moo->_symbol = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_CHAR)); - moo->_array = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_OOP)); - moo->_byte_array = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_BYTE)); - moo->_symbol_set = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - moo->_dictionary = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - moo->_system_dictionary = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_symbol = alloc_kernel_class (moo, + MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED, + 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_CHAR)); - moo->_namespace = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - moo->_pool_dictionary = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - moo->_method_dictionary = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - moo->_method = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_METHOD_NAMED_INSTVARS, 1, MOO_OBJ_TYPE_OOP)); - moo->_association = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_ASSOCIATION_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_array = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_OOP)); + moo->_byte_array = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_BYTE)); + moo->_symbol_set = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_dictionary = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_system_dictionary = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - moo->_method_context = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_CONTEXT_NAMED_INSTVARS, 1, MOO_OBJ_TYPE_OOP)); - moo->_block_context = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_CONTEXT_NAMED_INSTVARS, 1, MOO_OBJ_TYPE_OOP)); - moo->_process = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_PROCESS_NAMED_INSTVARS, 1, MOO_OBJ_TYPE_OOP)); - moo->_semaphore = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_SEMAPHORE_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - moo->_process_scheduler = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(MOO_PROCESS_SCHEDULER_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_namespace = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_pool_dictionary = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_method_dictionary = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SET_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_method = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_METHOD_NAMED_INSTVARS, 1, MOO_OBJ_TYPE_OOP)); + moo->_association = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_ASSOCIATION_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); - moo->_error_class = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); - moo->_true_class = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); - moo->_false_class = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); + moo->_method_context = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_CONTEXT_NAMED_INSTVARS, 1, MOO_OBJ_TYPE_OOP)); + moo->_block_context = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_CONTEXT_NAMED_INSTVARS, 1, MOO_OBJ_TYPE_OOP)); + + moo->_process = alloc_kernel_class (moo, + MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED, + 0, MOO_CLASS_SPEC_MAKE(MOO_PROCESS_NAMED_INSTVARS, 1, MOO_OBJ_TYPE_OOP)); + + moo->_semaphore = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(MOO_SEMAPHORE_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + moo->_process_scheduler = alloc_kernel_class (moo, + MOO_CLASS_SELFSPEC_FLAG_FINAL | MOO_CLASS_SELFSPEC_FLAG_LIMITED, + 0, MOO_CLASS_SPEC_MAKE(MOO_PROCESS_SCHEDULER_NAMED_INSTVARS, 0, MOO_OBJ_TYPE_OOP)); + + moo->_error_class = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); + moo->_true_class = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); + moo->_false_class = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); /* TOOD: what is a proper spec for Character and SmallInteger? * If the fixed part is 0, its instance must be an object of 0 payload fields. * Does this make sense? */ - moo->_character = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); - moo->_small_integer = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); - moo->_large_positive_integer = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_LIWORD)); - moo->_large_negative_integer = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_LIWORD)); + moo->_character = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); + moo->_small_integer = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); + moo->_large_positive_integer = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_LIWORD)); + moo->_large_negative_integer = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 1, MOO_OBJ_TYPE_LIWORD)); - moo->_small_pointer = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); - moo->_system = alloc_kernel_class (moo, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); + moo->_small_pointer = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); + moo->_system = alloc_kernel_class (moo, 0, 0, MOO_CLASS_SPEC_MAKE(0, 0, MOO_OBJ_TYPE_OOP)); if (!moo->_apex || !moo->_undefined_object || !moo->_object || !moo->_string || @@ -749,7 +758,7 @@ moo_oop_t moo_shallowcopy (moo_t* moo, moo_oop_t oop) c = MOO_OBJ_GET_CLASS(oop); moo_pushtmp (moo, &oop); - z = moo_instantiate (moo, (moo_oop_t)c, MOO_NULL, MOO_OBJ_GET_SIZE(oop) - MOO_CLASS_SPEC_NAMED_INSTVAR(MOO_OOP_TO_SMOOI(c->spec))); + z = moo_instantiate (moo, (moo_oop_t)c, MOO_NULL, MOO_OBJ_GET_SIZE(oop) - MOO_CLASS_SPEC_NAMED_INSTVARS(MOO_OOP_TO_SMOOI(c->spec))); moo_poptmp(moo); if (!z) return z; diff --git a/moo/lib/main.c b/moo/lib/main.c index 6c7b611..8ef7e47 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -1549,7 +1549,6 @@ int main (int argc, char* argv[]) } #endif - memset (&vmprim, 0, MOO_SIZEOF(vmprim)); vmprim.dl_open = dl_open; vmprim.dl_close = dl_close; diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 953b192..cb8edcb 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -156,9 +156,9 @@ (((moo_oow_t)(indexed_type)) << 1) | (((moo_oow_t)is_indexed) & 1) ) /* what is the number of named instance variables? - * MOO_CLASS_SPEC_NAMED_INSTVAR(MOO_OOP_TO_SMOOI(_class->spec)) + * MOO_CLASS_SPEC_NAMED_INSTVARS(MOO_OOP_TO_SMOOI(_class->spec)) */ -#define MOO_CLASS_SPEC_NAMED_INSTVAR(spec) \ +#define MOO_CLASS_SPEC_NAMED_INSTVARS(spec) \ (((moo_oow_t)(spec)) >> (MOO_OBJ_FLAGS_TYPE_BITS + 1)) /* is it a user-indexable class? @@ -179,10 +179,6 @@ * bits is to consider the sign bit of a small-integer which is a typical * type of the spec field in the class object. */ -/* -#define MOO_MAX_NAMED_INSTVARSVARS \ - MOO_BITS_MAX(moo_oow_t, MOO_OOW_BITS - MOO_OOP_TAG_BITS_LO - (MOO_OBJ_FLAGS_TYPE_BITS + 1) - 1) -*/ #define MOO_MAX_NAMED_INSTVARS \ MOO_BITS_MAX(moo_oow_t, MOO_SMOOI_ABS_BITS - (MOO_OBJ_FLAGS_TYPE_BITS + 1)) @@ -195,30 +191,38 @@ */ #define MOO_MAX_INDEXED_INSTVARS(named_instvar) (MOO_OBJ_SIZE_MAX - named_instvar) -/* -#define MOO_CLASS_SELFSPEC_MAKE(class_var,classinst_var) \ - (((moo_oow_t)class_var) << ((MOO_OOW_BITS - MOO_OOP_TAG_BITS_LO) / 2)) | ((moo_oow_t)classinst_var) -*/ -#define MOO_CLASS_SELFSPEC_MAKE(class_var,classinst_var) \ - (((moo_oow_t)class_var) << (MOO_SMOOI_BITS / 2)) | ((moo_oow_t)classinst_var) /* -#define MOO_CLASS_SELFSPEC_CLASSVAR(spec) ((moo_oow_t)spec >> ((MOO_OOW_BITS - MOO_OOP_TAG_BITS_LO) / 2)) -#define MOO_CLASS_SELFSPEC_CLASSINSTVAR(spec) (((moo_oow_t)spec) & MOO_LBMASK(moo_oow_t, (MOO_OOW_BITS - MOO_OOP_TAG_BITS_LO) / 2)) -*/ -#define MOO_CLASS_SELFSPEC_CLASSVAR(spec) ((moo_oow_t)spec >> (MOO_SMOOI_BITS / 2)) -#define MOO_CLASS_SELFSPEC_CLASSINSTVAR(spec) (((moo_oow_t)spec) & MOO_LBMASK(moo_oow_t, (MOO_SMOOI_BITS / 2))) - -/* - * yet another -1 in the calculation of the bit numbers for signed nature of - * a small-integer + * self-specification of a class + * | classinstvars | classvars | flags | + * + * When converted to a small integer + * | sign-bit | classinstvars | classvars | flags | tag | */ -/* -#define MOO_MAX_CLASSVARS MOO_BITS_MAX(moo_oow_t, (MOO_OOW_BITS - MOO_OOP_TAG_BITS_LO - 1) / 2) -#define MOO_MAX_CLASSINSTVARS MOO_BITS_MAX(moo_oow_t, (MOO_OOW_BITS - MOO_OOP_TAG_BITS_LO - 1) / 2) -*/ -#define MOO_MAX_CLASSVARS MOO_BITS_MAX(moo_oow_t, MOO_SMOOI_ABS_BITS / 2) -#define MOO_MAX_CLASSINSTVARS MOO_BITS_MAX(moo_oow_t, MOO_SMOOI_ABS_BITS / 2) +#define MOO_CLASS_SELFSPEC_FLAG_BITS (3) +#define MOO_CLASS_SELFSPEC_CLASSINSTVAR_BITS ((MOO_SMOOI_ABS_BITS - MOO_CLASS_SELFSPEC_FLAG_BITS) / 2) +#define MOO_CLASS_SELFSPEC_CLASSVAR_BITS (MOO_SMOOI_ABS_BITS - (MOO_CLASS_SELFSPEC_CLASSINSTVAR_BITS + MOO_CLASS_SELFSPEC_FLAG_BITS)) + +#define MOO_CLASS_SELFSPEC_MAKE(class_var,classinst_var,flag) \ + ((((moo_oow_t)class_var) << (MOO_CLASS_SELFSPEC_CLASSINSTVAR_BITS + MOO_CLASS_SELFSPEC_FLAG_BITS)) | \ + (((moo_oow_t)classinst_var) << (MOO_CLASS_SELFSPEC_FLAG_BITS)) | \ + (((moo_oow_t)flag) << (0))) + +#define MOO_CLASS_SELFSPEC_CLASSVARS(spec) \ + (((moo_oow_t)spec) >> (MOO_CLASS_SELFSPEC_CLASSINSTVAR_BITS + MOO_CLASS_SELFSPEC_FLAG_BITS)) + +#define MOO_CLASS_SELFSPEC_CLASSINSTVARS(spec) \ + ((((moo_oow_t)spec) >> MOO_CLASS_SELFSPEC_FLAG_BITS) & MOO_LBMASK(moo_oow_t, MOO_CLASS_SELFSPEC_CLASSINSTVAR_BITS)) + +#define MOO_CLASS_SELFSPEC_FLAGS(spec) \ + (((moo_oow_t)spec) & MOO_LBMASK(moo_oow_t, MOO_CLASS_SELFSPEC_FLAG_BITS)) + +#define MOO_CLASS_SELFSPEC_FLAG_FINAL (1 << 0) +#define MOO_CLASS_SELFSPEC_FLAG_LIMITED (1 << 1) + + +#define MOO_MAX_CLASSVARS MOO_BITS_MAX(moo_oow_t, MOO_CLASS_SELFSPEC_CLASSVAR_BITS) +#define MOO_MAX_CLASSINSTVARS MOO_BITS_MAX(moo_oow_t, MOO_CLASS_SELFSPEC_CLASSINSTVAR_BITS) #if defined(MOO_LIMIT_OBJ_SIZE) diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 591645c..b546ec2 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -1282,6 +1282,7 @@ enum moo_synerrnum_t MOO_SYNERR_CLASSCONTRA, /* contradictory class */ MOO_SYNERR_CLASSNAMEINVAL, /* wrong class name */ MOO_SYNERR_CLASSTRSIZE, /* non-pointer class inheriting a superclass with trailer size set */ + MOO_SYNERR_CLASSFINAL, /* cannot inherit a #final class */ MOO_SYNERR_VARDCLBANNED, /* variable declaration not allowed */ MOO_SYNERR_MODIFIER, /* modifier expected */ MOO_SYNERR_MODIFIERINVAL, /* wrong modifier */ diff --git a/moo/lib/obj.c b/moo/lib/obj.c index d6b34c0..f2faa13 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -187,7 +187,7 @@ static MOO_INLINE int decode_spec (moo_t* moo, moo_oop_class_t _class, moo_oow_t MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(_class->spec)); spec = MOO_OOP_TO_SMOOI(_class->spec); - named_instvar = MOO_CLASS_SPEC_NAMED_INSTVAR(spec); /* size of the named_instvar part */ + named_instvar = MOO_CLASS_SPEC_NAMED_INSTVARS(spec); /* size of the named_instvar part */ if (MOO_CLASS_SPEC_IS_INDEXED(spec)) { @@ -428,4 +428,3 @@ moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_class_t _class, moo_oo moo_poptmps (moo, tmp_count); return oop; } -