diff --git a/moo/kernel/Apex.moo b/moo/kernel/Apex.moo index 72ce83a..07fe91e 100644 --- a/moo/kernel/Apex.moo +++ b/moo/kernel/Apex.moo @@ -31,15 +31,20 @@ class Apex(nil) ## ------------------------------------------------------- ## ------------------------------------------------------- + method(#class) __trailer_size + { + ^0 + } + method(#class) basicNew { self primitiveFailed. } - - method(#class) basicNew: anInteger + + method(#class) basicNew: size { - + self primitiveFailed. } @@ -51,7 +56,7 @@ class Apex(nil) method(#class) ngcNew: anInteger { - + self primitiveFailed. } diff --git a/moo/kernel/Class.moo b/moo/kernel/Class.moo index af7ed93..3ae00c5 100644 --- a/moo/kernel/Class.moo +++ b/moo/kernel/Class.moo @@ -4,7 +4,7 @@ ## class(#pointer) Class(Apex) { - dcl spec selfspec superclass subclasses name instvars classvars classinstvars pooldics instmthdic classmthdic nsdic. + dcl spec selfspec superclass subclasses name instvars classvars classinstvars pooldics instmthdic classmthdic nsdic trsize. method(#class) basicNew { diff --git a/moo/kernel/Except.moo b/moo/kernel/Except.moo index 271ee87..ae0481d 100644 --- a/moo/kernel/Except.moo +++ b/moo/kernel/Except.moo @@ -187,14 +187,14 @@ extend MethodContext { method isExceptionContext { - ## 10 - MOO_METHOD_PREAMBLE_EXCEPTION in VM. - ^self.method preambleCode == 10. + ## 12 - MOO_METHOD_PREAMBLE_EXCEPTION in VM. + ^self.method preambleCode == 12. } method isEnsureContext { - ## 10 - MOO_METHOD_PREAMBLE_ENSURE in VM. - ^self.method preambleCode == 11 + ## 13 - MOO_METHOD_PREAMBLE_ENSURE in VM. + ^self.method preambleCode == 13 } method ensureBlock @@ -208,7 +208,7 @@ extend MethodContext * 8 instance variables, the ensure block must be at the 9th position * which translates to index 8 *) - (self.method preambleCode == 11) ifFalse: [^nil]. + (self.method preambleCode == 13) ifFalse: [^nil]. ^self basicAt: 8. } diff --git a/moo/kernel/FFI.moo b/moo/kernel/FFI.moo index 67d2b28..7225353 100644 --- a/moo/kernel/FFI.moo +++ b/moo/kernel/FFI.moo @@ -1,4 +1,4 @@ -class(#byte) _FFI(Module) from 'ffi' +class _FFI(Object) from 'ffi' { (* * the ffi module installs the following methods diff --git a/moo/kernel/Module.moo b/moo/kernel/Module.moo deleted file mode 100644 index 60f4ae0..0000000 --- a/moo/kernel/Module.moo +++ /dev/null @@ -1,18 +0,0 @@ -class(#byte) Module(Object) -{ - method(#class) _newInstSize - { - self subclassResponsibility: #_newInstSize - } - - method(#class) new: size - { - ## ignore the specified size - ^(super new: (self _newInstSize)) - } - - method(#class) new - { - ^(super new: (self _newInstSize)) - } -} \ No newline at end of file diff --git a/moo/kernel/Moo.moo b/moo/kernel/Moo.moo index 69c992c..8a921ba 100644 --- a/moo/kernel/Moo.moo +++ b/moo/kernel/Moo.moo @@ -8,8 +8,6 @@ #include 'Process.moo'. (* -------------------------------------------------------------------------- *) -#include 'Module.moo'. - #include 'FFI.moo'. #include 'Stdio.moo'. #include 'Console.moo'. diff --git a/moo/kernel/Stdio.moo b/moo/kernel/Stdio.moo index 247407a..3cf652d 100644 --- a/moo/kernel/Stdio.moo +++ b/moo/kernel/Stdio.moo @@ -1,5 +1,5 @@ -class(#byte) Stdio(Module) from 'stdio' +class Stdio(Object) from 'stdio' { dcl(#class) in out err. @@ -63,7 +63,7 @@ extend Stdio } } -class(#byte) Stdio2(Stdio) +class Stdio2(Stdio) { method(#class) new { diff --git a/moo/kernel/generr.moo b/moo/kernel/generr.moo index ae4ca12..f8be819 100644 --- a/moo/kernel/generr.moo +++ b/moo/kernel/generr.moo @@ -73,6 +73,7 @@ class MyObject(Object) 'duplicate class' 'contradictory class definition' 'wrong class name' + 'non-pointer class inheriting superclass with trailer size set' 'dcl not allowed' 'wrong method name' 'duplicate method name' diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 390ec2e..6a1d074 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -5555,7 +5555,7 @@ static int add_compiled_method (moo_t* moo) { moo_oop_char_t name; /* selector */ moo_oop_method_t mth; /* method */ -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) /* nothing extra */ #else moo_oop_byte_t code; @@ -5569,7 +5569,7 @@ static int add_compiled_method (moo_t* moo) moo_pushtmp (moo, (moo_oop_t*)&name); tmp_count++; /* The variadic data part passed to moo_instantiate() is not GC-safe */ -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) mth = (moo_oop_method_t)moo_instantiatewithtrailer (moo, moo->_method, moo->c->mth.literal_count, moo->c->mth.code.ptr, moo->c->mth.code.len); #else mth = (moo_oop_method_t)moo_instantiate (moo, moo->_method, MOO_NULL, moo->c->mth.literal_count); @@ -5583,7 +5583,7 @@ static int add_compiled_method (moo_t* moo) } moo_pushtmp (moo, (moo_oop_t*)&mth); tmp_count++; -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) /* do nothing */ #else code = (moo_oop_byte_t)moo_instantiate (moo, moo->_byte_array, moo->c->mth.code.ptr, moo->c->mth.code.len); @@ -5616,6 +5616,14 @@ static int add_compiled_method (moo_t* moo) preamble_code = MOO_METHOD_PREAMBLE_RETURN_RECEIVER; break; + case BCODE_PUSH_CONTEXT: + preamble_code = MOO_METHOD_PREAMBLE_RETURN_CONTEXT; + break; + + case BCODE_PUSH_PROCESS: + preamble_code = MOO_METHOD_PREAMBLE_RETURN_PROCESS; + break; + case BCODE_PUSH_NIL: preamble_code = MOO_METHOD_PREAMBLE_RETURN_NIL; break; @@ -5731,7 +5739,7 @@ static int add_compiled_method (moo_t* moo) mth->tmpr_count = MOO_SMOOI_TO_OOP(moo->c->mth.tmpr_count); mth->tmpr_nargs = MOO_SMOOI_TO_OOP(moo->c->mth.tmpr_nargs); -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) /* do nothing */ #else mth->code = code; @@ -5927,6 +5935,9 @@ static int make_defined_class (moo_t* moo) moo->c->cls.self_oop->mthdic[MOO_METHOD_CLASS] = (moo_oop_set_t)tmp; #endif + /* [NOTE] don't create a dictionary on the nsdic. keep it to be nil */ + /* [NOTE] don't set the trsize field yet here. */ + /* TODO: initialize more fields??? whatelse. */ /* TODO: update the subclasses field of the superclass if it's not nil */ @@ -6167,7 +6178,6 @@ static int __compile_class_definition (moo_t* moo, int extend) } else { - /* ass = moo_lookupsysdic(moo, &moo->c->cls.supername); */ ass = moo_lookupdic (moo, moo->c->cls.superns_oop, &moo->c->cls.supername); if (!ass && moo->c->cls.superns_oop != moo->sysdic) ass = moo_lookupdic (moo, moo->sysdic, &moo->c->cls.supername); @@ -6176,8 +6186,21 @@ static int __compile_class_definition (moo_t* moo, int extend) MOO_OBJ_GET_FLAGS_KERNEL(ass->value) != 1) { /* the value found must be a class and it must not be - * an incomplete internal class object */ + * an incomplete internal class object. + * 0(non-kernel object) + * 1(incomplete kernel object), + * 2(complete kernel object) */ moo->c->cls.super_oop = ass->value; + + /* the superclass became known. */ + if (((moo_oop_class_t)moo->c->cls.super_oop)->trsize != moo->_nil && + (moo->c->cls.flags & CLASS_INDEXED) && + moo->c->cls.indexed_type != MOO_OBJ_TYPE_OOP) + { + /* non-pointer object cannot inherit from a superclass with trailer size set */ + set_syntax_error (moo, MOO_SYNERR_CLASSTRSIZE, &moo->c->cls.fqn_loc, &moo->c->cls.fqn); + return -1; + } } else { @@ -6320,6 +6343,15 @@ static int __compile_class_definition (moo_t* moo, int extend) { if (moo_importmod (moo, (moo_oop_t)moo->c->cls.self_oop, modname, modnamelen) <= -1) return -1; } + + if (moo->c->cls.self_oop->trsize == moo->_nil && + moo->c->cls.self_oop->superclass != moo->_nil) + { + /* [NOTE] + * update the trailer size field after module importing + * as the importer can set the trailer size legitimately */ + moo->c->cls.self_oop->trsize = ((moo_oop_class_t)moo->c->cls.self_oop->superclass)->trsize; + } } while (is_token_word(moo, VOCA_METHOD)) diff --git a/moo/lib/err.c b/moo/lib/err.c index 0578d3f..bf440c5 100644 --- a/moo/lib/err.c +++ b/moo/lib/err.c @@ -99,38 +99,39 @@ 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[] = {'d','c','l',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'}; -static moo_ooch_t synerrstr_32[] = {'w','r','o','n','g',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_33[] = {'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_34[] = {'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_35[] = {'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_36[] = {'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_37[] = {'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_38[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'}; -static moo_ooch_t synerrstr_39[] = {'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_40[] = {'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_41[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'}; -static moo_ooch_t synerrstr_42[] = {'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_43[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; -static moo_ooch_t synerrstr_44[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'}; -static moo_ooch_t synerrstr_45[] = {'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_46[] = {'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_47[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'}; -static moo_ooch_t synerrstr_48[] = {'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_49[] = {'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_50[] = {'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_51[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_52[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'}; -static moo_ooch_t synerrstr_53[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'}; -static moo_ooch_t synerrstr_54[] = {'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_55[] = {'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_56[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'}; -static moo_ooch_t synerrstr_57[] = {'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_58[] = {'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_59[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'}; -static moo_ooch_t synerrstr_60[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n',' ','k','e','y','\0'}; -static moo_ooch_t synerrstr_61[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n',' ','v','a','l','u','e','\0'}; -static moo_ooch_t synerrstr_62[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n','\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[] = {'d','c','l',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'}; +static moo_ooch_t synerrstr_33[] = {'w','r','o','n','g',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_34[] = {'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_35[] = {'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_36[] = {'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_37[] = {'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_38[] = {'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_39[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'}; +static moo_ooch_t synerrstr_40[] = {'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_41[] = {'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_42[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'}; +static moo_ooch_t synerrstr_43[] = {'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_44[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; +static moo_ooch_t synerrstr_45[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'}; +static moo_ooch_t synerrstr_46[] = {'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_47[] = {'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_48[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'}; +static moo_ooch_t synerrstr_49[] = {'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_50[] = {'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_51[] = {'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_52[] = {'w','r','o','n','g',' ','m','o','d','u','l','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_53[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'}; +static moo_ooch_t synerrstr_54[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'}; +static moo_ooch_t synerrstr_55[] = {'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_56[] = {'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_57[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_58[] = {'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_59[] = {'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_60[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'}; +static moo_ooch_t synerrstr_61[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n',' ','k','e','y','\0'}; +static moo_ooch_t synerrstr_62[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n',' ','v','a','l','u','e','\0'}; +static moo_ooch_t synerrstr_63[] = {'m','i','s','s','i','n','g',' ','a','s','s','o','c','i','a','t','i','o','n','\0'}; static moo_ooch_t* synerrstr[] = { synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7, @@ -140,7 +141,7 @@ static moo_ooch_t* synerrstr[] = synerrstr_32, synerrstr_33, synerrstr_34, synerrstr_35, synerrstr_36, synerrstr_37, synerrstr_38, synerrstr_39, 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_56, synerrstr_57, synerrstr_58, synerrstr_59, synerrstr_60, synerrstr_61, synerrstr_62, synerrstr_63 }; #endif /* END: GENERATED WITH generr.st */ diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 6e5dbd4..9073ee5 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -1350,59 +1350,48 @@ static moo_pfrc_t pf_class (moo_t* moo, moo_ooi_t nargs) return MOO_PF_SUCCESS; } -static moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs) +static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs) { - moo_oop_t rcv, obj; + moo_oop_t _class, szoop, obj; + moo_oow_t size = 0, trsz = 0; - MOO_ASSERT (moo, nargs == 0); - - rcv = MOO_STACK_GETRCV (moo, nargs); - if (MOO_CLASSOF(moo, rcv) != moo->_class) + _class = MOO_STACK_GETRCV(moo, nargs); + if (MOO_CLASSOF(moo, _class) != moo->_class) { /* the receiver is not a class object */ - return MOO_PF_FAILURE; + MOO_DEBUG0 (moo, " Receiver is not a class\n"); + goto inval; } - obj = moo_instantiate (moo, rcv, MOO_NULL, 0); - if (!obj) return MOO_PF_HARD_FAILURE; - - MOO_STACK_SETRET (moo, nargs, obj); - return MOO_PF_SUCCESS; -} - -static moo_pfrc_t pf_basic_new_with_size (moo_t* moo, moo_ooi_t nargs) -{ - moo_oop_t rcv, szoop, obj; - moo_oow_t size; - - MOO_ASSERT (moo, nargs == 1); - - rcv = MOO_STACK_GETRCV(moo, nargs); - if (MOO_CLASSOF(moo, rcv) != moo->_class) + if (nargs >= 1) { - /* the receiver is not a class object */ - return MOO_PF_FAILURE; + szoop = MOO_STACK_GETARG(moo, nargs, 0); + if (moo_inttooow (moo, szoop, &size) <= 0) + { + /* integer out of range or not integer */ + MOO_DEBUG0 (moo, " Size out of range or not integer\n"); + goto inval; + } } - szoop = MOO_STACK_GETARG(moo, nargs, 0); - if (moo_inttooow (moo, szoop, &size) <= 0) - { - /* integer out of range or not integer */ - return MOO_PF_FAILURE; - } + if (MOO_OOP_IS_SMOOI(((moo_oop_class_t)_class)->trsize)) + trsz = MOO_OOP_TO_SMOOI(((moo_oop_class_t)_class)->trsize); /* moo_instantiate() ignores size if the instance specification * disallows indexed(variable) parts. */ /* TODO: should i check the specification before calling * moo_instantiate()? */ - obj = moo_instantiate (moo, rcv, MOO_NULL, size); - if (!obj) - { - return MOO_PF_HARD_FAILURE; - } +MOO_DEBUG2 (moo, " SIZE ... %d TRSZ %d\n", (int)size, (int)trsz); + obj = trsz <= 0? moo_instantiate (moo, _class, MOO_NULL, size): + moo_instantiatewithtrailer (moo, _class, size, MOO_NULL, trsz); + if (!obj) return MOO_PF_HARD_FAILURE; MOO_STACK_SETRET (moo, nargs, obj); return MOO_PF_SUCCESS; + +inval: + moo->errnum = MOO_EINVAL; + return MOO_PF_FAILURE; } static moo_pfrc_t pf_ngc_new (moo_t* moo, moo_ooi_t nargs) @@ -1416,11 +1405,6 @@ static moo_pfrc_t pf_ngc_new (moo_t* moo, moo_ooi_t nargs) } -static moo_pfrc_t pf_ngc_new_with_size (moo_t* moo, moo_ooi_t nargs) -{ - return pf_basic_new_with_size (moo, nargs); -} - static moo_pfrc_t pf_ngc_dispose (moo_t* moo, moo_ooi_t nargs) { moo_oop_t rcv; @@ -1827,7 +1811,7 @@ static moo_pfrc_t __block_value (moo_t* moo, moo_oop_context_t rcv_blkctx, moo_o moo_oop_oop_t xarg; MOO_ASSERT (moo, nargs == 1); xarg = (moo_oop_oop_t)MOO_STACK_GETTOP (moo); - MOO_ASSERT (moo, MOO_ISTYPEOF(moo,xarg,MOO_OBJ_TYPE_OOP)); + MOO_ASSERT (moo, MOO_OBJ_IS_OOP_POINTER(xarg)); MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(xarg) == num_first_arg_elems); for (i = 0; i < num_first_arg_elems; i++) { @@ -1890,6 +1874,7 @@ static moo_pfrc_t pf_block_new_process (moo_t* moo, moo_ooi_t nargs) { /* too many arguments */ /* TODO: proper error handling */ + moo->errnum = MOO_EINVAL; return MOO_PF_FAILURE; } @@ -1898,10 +1883,11 @@ static moo_pfrc_t pf_block_new_process (moo_t* moo, moo_ooi_t nargs) moo_oop_t xarg; xarg = MOO_STACK_GETARG(moo, nargs, 0); - if (!MOO_ISTYPEOF(moo,xarg,MOO_OBJ_TYPE_OOP)) + if (!MOO_OBJ_IS_OOP_POINTER(xarg)) { /* the only optional argument must be an OOP-indexable * object like an array */ + moo->errnum = MOO_EINVAL; return MOO_PF_FAILURE; } @@ -1914,6 +1900,7 @@ static moo_pfrc_t pf_block_new_process (moo_t* moo, moo_ooi_t nargs) /* the receiver must be a block context */ MOO_LOG2 (moo, MOO_LOG_PRIMITIVE | MOO_LOG_ERROR, "Error(%hs) - invalid receiver, not a block context - %O\n", __PRIMITIVE_NAME__, rcv_blkctx); + moo->errnum = MOO_EINVAL; return MOO_PF_FAILURE; } @@ -2657,10 +2644,8 @@ static pf_t pftab[] = { 1, 1, pf_not_equal, "_not_equal" }, { 0, 0, pf_class, "_class" }, - { 0, 0, pf_basic_new, "_basic_new" }, - { 1, 1, pf_basic_new_with_size, "_basic_new_with_size" }, - { 0, 0, pf_ngc_new, "_ngc_new" }, - { 1, 1, pf_ngc_new_with_size, "_ngc_new_with_size" }, + { 0, 1, pf_basic_new, "_basic_new" }, + { 0, 1, pf_ngc_new, "_ngc_new" }, { 0, 0, pf_ngc_dispose, "_ngc_dispose" }, { 0, 0, pf_shallow_copy, "_shallow_copy" }, @@ -2771,6 +2756,21 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs) MOO_STACK_POPS (moo, nargs); /* pop arguments only*/ break; + /* [NOTE] this is useless becuase it returns a caller's context + * as the callee's context has not been created yet. + case MOO_METHOD_PREAMBLE_RETURN_CONTEXT: + LOG_INST_0 (moo, "preamble_return_context"); + MOO_STACK_POPS (moo, nargs); + MOO_STACK_SETTOP (moo, (moo_oop_t)moo->active_context); + break; + */ + + case MOO_METHOD_PREAMBLE_RETURN_PROCESS: + LOG_INST_0 (moo, "preamble_return_process"); + MOO_STACK_POPS (moo, nargs); + MOO_STACK_SETTOP (moo, (moo_oop_t)moo->processor->active); + break; + case MOO_METHOD_PREAMBLE_RETURN_NIL: LOG_INST_0 (moo, "preamble_return_nil"); MOO_STACK_POPS (moo, nargs); @@ -2877,7 +2877,7 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs) MOO_ASSERT (moo, pf_name_index >= 0); name = method->slot[pf_name_index]; - MOO_ASSERT (moo, MOO_ISTYPEOF(moo,name,MOO_OBJ_TYPE_CHAR)); + MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(name)); MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_EXTRA(name)); MOO_ASSERT (moo, MOO_CLASSOF(moo,name) == moo->_symbol); #endif @@ -2930,7 +2930,7 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs) MOO_DEBUG2 (moo, "Soft failure for non-existent primitive function - %.*js\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot); } - #if defined(MOO_USE_OBJECT_TRAILER) + #if defined(MOO_USE_METHOD_TRAILER) MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_TRAILER(method)); if (MOO_METHOD_GET_CODE_SIZE(method) == 0) /* this trailer size field not a small integer */ #else @@ -2954,8 +2954,9 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs) default: MOO_ASSERT (moo, preamble_code == MOO_METHOD_PREAMBLE_NONE || - preamble_code == MOO_METHOD_PREAMBLE_EXCEPTION || - preamble_code == MOO_METHOD_PREAMBLE_ENSURE); + preamble_code == MOO_METHOD_PREAMBLE_RETURN_CONTEXT || + preamble_code == MOO_METHOD_PREAMBLE_EXCEPTION || + preamble_code == MOO_METHOD_PREAMBLE_ENSURE); if (activate_new_method (moo, method, nargs) <= -1) return -1; break; } diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 95ae67f..d0107e7 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -408,7 +408,7 @@ static MOO_INLINE moo_oow_t get_payload_bytes (moo_t* moo, moo_oop_t oop) { moo_oow_t nbytes_aligned; -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) if (MOO_OBJ_GET_FLAGS_TRAILER(oop)) { moo_oow_t nbytes; @@ -438,7 +438,7 @@ static MOO_INLINE moo_oow_t get_payload_bytes (moo_t* moo, moo_oop_t oop) #endif /* calculate the payload size in bytes */ nbytes_aligned = MOO_ALIGN (MOO_OBJ_BYTESOF(oop), MOO_SIZEOF(moo_oop_t)); -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) } #endif @@ -506,7 +506,7 @@ static moo_uint8_t* scan_new_heap (moo_t* moo, moo_uint8_t* ptr) oop = (moo_oop_t)ptr; - #if defined(MOO_USE_OBJECT_TRAILER) + #if defined(MOO_USE_METHOD_TRAILER) if (MOO_OBJ_GET_FLAGS_TRAILER(oop)) { moo_oow_t nbytes; @@ -523,7 +523,7 @@ static moo_uint8_t* scan_new_heap (moo_t* moo, moo_uint8_t* ptr) { #endif nbytes_aligned = MOO_ALIGN (MOO_OBJ_BYTESOF(oop), MOO_SIZEOF(moo_oop_t)); - #if defined(MOO_USE_OBJECT_TRAILER) + #if defined(MOO_USE_METHOD_TRAILER) } #endif diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 97dddd9..995309a 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -562,7 +562,7 @@ struct moo_oochbuf_t #endif -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) /* let it point to the trailer of the method */ # define SET_ACTIVE_METHOD_CODE(moo) ((moo)->active_code = (moo_oob_t*)&(moo)->active_method->slot[MOO_OBJ_GET_SIZE((moo)->active_method) + 1 - MOO_METHOD_NAMED_INSTVARS]) #else @@ -949,7 +949,7 @@ moo_oop_t moo_allocoopobj ( moo_oow_t size ); -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) moo_oop_t moo_allocoopobjwithtrailer ( moo_t* moo, moo_oow_t size, @@ -982,7 +982,7 @@ moo_oop_t moo_allocwordobj ( moo_oow_t len ); -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) moo_oop_t moo_instantiatewithtrailer ( moo_t* moo, moo_oop_t _class, diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 2f1bf1f..3cf7428 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -537,7 +537,7 @@ int moo_importmod (moo_t* moo, moo_oop_t _class, const moo_ooch_t* name, moo_oow moo_mod_data_t* mdp; int r = 0; - /* moo_openmod(), moo_closemod(), etc calls a user-defined callback. + /* moo_openmod(), moo_closemod(), etc call a user-defined callback. * i need to protect _class in case the user-defined callback allocates * a OOP memory chunk and GC occurs */ moo_pushtmp (moo, &_class); @@ -706,8 +706,6 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, moo_method_ty return -1; } -MOO_DEBUG3 (moo, ">>>> PFGEN X11 [%.*js] %js\n", moo->sbuf[0].len, moo->sbuf[0].ptr, mod->name); - pfidsym = (moo_oop_char_t)moo_makesymbol (moo, moo->sbuf[0].ptr, moo->sbuf[0].len); if (!pfidsym) { @@ -716,7 +714,7 @@ MOO_DEBUG3 (moo, ">>>> PFGEN X11 [%.*js] %js\n", moo->sbuf[0].len, moo->sbuf[0]. } moo_pushtmp (moo, (moo_oop_t*)&pfidsym); tmp_count++; -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) mth = (moo_oop_method_t)moo_instantiatewithtrailer (moo, moo->_method, 1, MOO_NULL, 0); #else mth = (moo_oop_method_t)moo_instantiate (moo, moo->_method, MOO_NULL, 1); @@ -757,3 +755,78 @@ oops: moo_poptmps (moo, tmp_count); return -1; } + +int moo_setclasstrsize (moo_t* moo, moo_oop_t _class, moo_oow_t size) +{ + register moo_oop_class_t c; + moo_oop_class_t sc; + moo_oow_t spec; + + MOO_ASSERT (moo, MOO_CLASSOF(moo, _class) == moo->_class); + MOO_ASSERT (moo, size <= MOO_SMOOI_MAX); + + c = (moo_oop_class_t)_class; + if ((moo_oop_t)c == moo->_method) + { + /* the bytes code emitted by the compiler go to the trailer part + * regardless of the trailer size. you're not allowed to change it */ + MOO_DEBUG3 (moo, "Not allowed to set trailer size to %zu on the %.*js class\n", + size, + MOO_OBJ_GET_SIZE(c->name), + MOO_OBJ_GET_CHAR_SLOT(c->name)); + goto eperm; + } + + spec = MOO_OOP_TO_SMOOI(c->spec); + if (MOO_CLASS_SPEC_IS_INDEXED(spec) && MOO_CLASS_SPEC_INDEXED_TYPE(spec) != MOO_OBJ_TYPE_OOP) + { + MOO_DEBUG3 (moo, "Not allowed to set trailer size to %zu on the %.*js class representing a non-pointer object\n", + size, + MOO_OBJ_GET_SIZE(c->name), + MOO_OBJ_GET_CHAR_SLOT(c->name)); + goto eperm; + } + + if (c->trsize != moo->_nil) + { + MOO_DEBUG3 (moo, "Not allowed to reset trailer size to %zu on the %.*js class\n", + size, + MOO_OBJ_GET_SIZE(c->name), + MOO_OBJ_GET_CHAR_SLOT(c->name)); + goto eperm; + } + + + sc = (moo_oop_class_t)c->superclass; + if (MOO_OOP_IS_SMOOI(sc->trsize) && size < MOO_OOP_TO_SMOOI(sc->trsize)) + { + MOO_DEBUG6 (moo, "Not allowed to set the trailer size of %.*js to be smaller(%zu) than that(%zu) of the superclass %.*js\n", + size, + MOO_OBJ_GET_SIZE(c->name), + MOO_OBJ_GET_CHAR_SLOT(c->name), + MOO_OOP_TO_SMOOI(sc->trsize), + MOO_OBJ_GET_SIZE(sc->name), + MOO_OBJ_GET_CHAR_SLOT(sc->name)); + goto eperm; + } + + /* you can only set the trailer size once when it's not set yet */ + c->trsize = MOO_SMOOI_TO_OOP(size); + MOO_DEBUG3 (moo, "Set trailer size to %zu on the %.*js class\n", + size, + MOO_OBJ_GET_SIZE(c->name), + MOO_OBJ_GET_CHAR_SLOT(c->name)); + return 0; + +eperm: + moo->errnum = MOO_EPERM; + return -1; +} + +void* moo_getobjtrailer (moo_t* moo, moo_oop_t obj, moo_oow_t* size) +{ + if (!MOO_OBJ_IS_OOP_POINTER(obj) || !MOO_OBJ_GET_FLAGS_TRAILER(obj)) return MOO_NULL; + + if (size) *size = MOO_OBJ_GET_TRAILER_SIZE(obj); + return MOO_OBJ_GET_TRAILER_BYTE(obj); +} diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 30c69e4..7e0a913 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -36,7 +36,7 @@ /* define this to allow an pointer(OOP) object to have trailing bytes * this is used to embed bytes codes into the back of a compile method * object instead of putting in in a separate byte array. */ -#define MOO_USE_OBJECT_TRAILER +#define MOO_USE_METHOD_TRAILER /* ========================================================================== */ /** @@ -187,7 +187,7 @@ typedef enum moo_method_type_t moo_method_type_t; * but some simple numeric values are also encoded into OOP using a simple * bit-shifting and masking. * - * A real OOP is stored without any bit-shifting while a non-OOP value encoded + * A real OOP is stored without any bit-shifting while a non-pointer value encoded * in an OOP is bit-shifted to the left by 2 and the 2 least-significant bits * are set to 1 or 2. * @@ -286,9 +286,10 @@ typedef enum moo_obj_type_t moo_obj_type_t; * item than the value of the size field. used for a * terminating null in a variable-character object. internel * use only. - * kernel: 0 or 1. indicates that the object is a kernel object. + * kernel: 0, 1, or 2. indicates that the object is a kernel object. * VM disallows layout changes of a kernel object. - * internal use only. + * internal use only. during ignition, it's set to 1. + * when full definition is available, it's set to 2. * moved: 0 or 1. used by GC. internal use only. * ngc: 0 or 1, used by GC. internal use only. * trailer: 0 or 1. indicates that there are trailing bytes @@ -360,6 +361,7 @@ typedef enum moo_obj_type_t moo_obj_type_t; /* [NOTE] this macro doesn't include the size of the trailer */ #define MOO_OBJ_BYTESOF(oop) ((MOO_OBJ_GET_SIZE(oop) + MOO_OBJ_GET_FLAGS_EXTRA(oop)) * MOO_OBJ_GET_FLAGS_UNIT(oop)) +#define MOO_OBJ_IS_OOP_POINTER(oop) (MOO_OOP_IS_POINTER(oop) && (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_OOP)) #define MOO_OBJ_IS_CHAR_POINTER(oop) (MOO_OOP_IS_POINTER(oop) && (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_CHAR)) #define MOO_OBJ_IS_BYTE_POINTER(oop) (MOO_OOP_IS_POINTER(oop) && (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_BYTE)) #define MOO_OBJ_IS_HALFWORD_POINTER(oop) (MOO_OOP_IS_POINTER(oop) && (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_HALFWORD)) @@ -431,6 +433,8 @@ struct moo_trailer_t moo_oob_t slot[1]; }; +#define MOO_OBJ_GET_TRAILER_BYTE(oop) ((moo_oob_t*)&((moo_oop_oop_t)oop)->slot[MOO_OBJ_GET_SIZE(oop) + 1]) +#define MOO_OBJ_GET_TRAILER_SIZE(oop) ((moo_oow_t)((moo_oop_oop_t)oop)->slot[MOO_OBJ_GET_SIZE(oop)]) #define MOO_SET_NAMED_INSTVARS 2 typedef struct moo_set_t moo_set_t; @@ -442,7 +446,7 @@ struct moo_set_t moo_oop_oop_t bucket; /* Array */ }; -#define MOO_CLASS_NAMED_INSTVARS 12 +#define MOO_CLASS_NAMED_INSTVARS 13 typedef struct moo_class_t moo_class_t; typedef struct moo_class_t* moo_oop_class_t; struct moo_class_t @@ -469,8 +473,8 @@ struct moo_class_t * [1] - class methods, MethodDictionary */ moo_oop_set_t mthdic[MOO_METHOD_TYPE_COUNT]; - /* dictionary used for namespacing */ - moo_oop_set_t nsdic; + moo_oop_set_t nsdic; /* dictionary used for namespacing */ + moo_oop_t trsize; /* trailer size for new instances */ /* indexed part afterwards */ moo_oop_t slot[1]; /* class instance variables and class variables. */ @@ -486,7 +490,7 @@ struct moo_association_t moo_oop_t value; }; -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) # define MOO_METHOD_NAMED_INSTVARS 8 #else # define MOO_METHOD_NAMED_INSTVARS 9 @@ -511,7 +515,7 @@ struct moo_method_t /* number of arguments in temporaries */ moo_oop_t tmpr_nargs; /* SmallInteger */ -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) /* no code field is used */ #else moo_oop_byte_t code; /* ByteArray */ @@ -523,14 +527,17 @@ struct moo_method_t moo_oop_t slot[1]; /* it stores literals */ }; -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) /* if m is to be type-cast to moo_oop_method_t, the macro must be * redefined to this: * (&((moo_oop_method_t)m)>slot[MOO_OBJ_GET_SIZE(m) + 1 - MOO_METHOD_NAMED_INSTVARS]) */ -# define MOO_METHOD_GET_CODE_BYTE(m) ((moo_oob_t*)&((moo_oop_oop_t)m)->slot[MOO_OBJ_GET_SIZE(m) + 1]) -# define MOO_METHOD_GET_CODE_SIZE(m) ((moo_oow_t)((moo_oop_oop_t)m)->slot[MOO_OBJ_GET_SIZE(m)]) + + /*((moo_oob_t*)&((moo_oop_oop_t)m)->slot[MOO_OBJ_GET_SIZE(m) + 1])*/ +# define MOO_METHOD_GET_CODE_BYTE(m) MOO_OBJ_GET_TRAILER_BYTE(m) + /*((moo_oow_t)((moo_oop_oop_t)m)->slot[MOO_OBJ_GET_SIZE(m)])*/ +# define MOO_METHOD_GET_CODE_SIZE(m) MOO_OBJ_GET_TRAILER_SIZE(m) #else # define MOO_METHOD_GET_CODE_BYTE(m) ((m)->code->slot) # define MOO_METHOD_GET_CODE_SIZE(m) MOO_OBJ_GET_SIZE((m)->code) @@ -544,16 +551,18 @@ struct moo_method_t * The code can be one of the following values: * 0 - no special action * 1 - return self - * 2 - return nil - * 3 - return true - * 4 - return false - * 5 - return index. - * 6 - return -index. - * 7 - return instvar[index] - * 8 - do primitive[index] - * 9 - do named primitive[index] - * 10 - exception handler - * 11 - ensure block + * 2 - return thisContext (not used) + * 3 - return thisProcess + * 4 - return nil + * 5 - return true + * 6 - return false + * 7 - return index. + * 8 - return -index. + * 9 - return instvar[index] + * 10 - do primitive[index] + * 11 - do named primitive[index] + * 12 - exception handler + * 13 - ensure block */ /* NOTE: changing preamble code bit structure requires changes to CompiledMethod>>preambleCode */ @@ -563,19 +572,21 @@ struct moo_method_t #define MOO_METHOD_GET_PREAMBLE_FLAGS(preamble) (((moo_ooi_t)preamble) & 0x3) /* preamble codes */ -#define MOO_METHOD_PREAMBLE_NONE 0 -#define MOO_METHOD_PREAMBLE_RETURN_RECEIVER 1 -#define MOO_METHOD_PREAMBLE_RETURN_NIL 2 -#define MOO_METHOD_PREAMBLE_RETURN_TRUE 3 -#define MOO_METHOD_PREAMBLE_RETURN_FALSE 4 -#define MOO_METHOD_PREAMBLE_RETURN_INDEX 5 -#define MOO_METHOD_PREAMBLE_RETURN_NEGINDEX 6 -#define MOO_METHOD_PREAMBLE_RETURN_INSTVAR 7 -#define MOO_METHOD_PREAMBLE_PRIMITIVE 8 -#define MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE 9 /* index is an index to the symbol table */ +#define MOO_METHOD_PREAMBLE_NONE 0 +#define MOO_METHOD_PREAMBLE_RETURN_RECEIVER 1 +#define MOO_METHOD_PREAMBLE_RETURN_CONTEXT 2 +#define MOO_METHOD_PREAMBLE_RETURN_PROCESS 3 +#define MOO_METHOD_PREAMBLE_RETURN_NIL 4 +#define MOO_METHOD_PREAMBLE_RETURN_TRUE 5 +#define MOO_METHOD_PREAMBLE_RETURN_FALSE 6 +#define MOO_METHOD_PREAMBLE_RETURN_INDEX 7 +#define MOO_METHOD_PREAMBLE_RETURN_NEGINDEX 8 +#define MOO_METHOD_PREAMBLE_RETURN_INSTVAR 9 +#define MOO_METHOD_PREAMBLE_PRIMITIVE 10 +#define MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE 11 /* index is an index to the symbol table */ -#define MOO_METHOD_PREAMBLE_EXCEPTION 10 /* NOTE changing this requires changes in Except.st */ -#define MOO_METHOD_PREAMBLE_ENSURE 11 /* NOTE changing this requires changes in Except.st */ +#define MOO_METHOD_PREAMBLE_EXCEPTION 12 /* NOTE changing this requires changes in Except.st */ +#define MOO_METHOD_PREAMBLE_ENSURE 13 /* NOTE changing this requires changes in Except.st */ /* the index is an 16-bit unsigned integer. */ #define MOO_METHOD_PREAMBLE_INDEX_MIN 0x0000 @@ -718,11 +729,6 @@ struct moo_process_scheduler_t #define MOO_BYTESOF(moo,oop) \ (MOO_OOP_IS_NUMERIC(oop)? MOO_SIZEOF(moo_oow_t): MOO_OBJ_BYTESOF(oop)) -/** - * The MOO_ISTYPEOF() macro is a safe replacement for MOO_OBJ_GET_FLAGS_TYPE() - */ -#define MOO_ISTYPEOF(moo,oop,type) \ - (!MOO_OOP_IS_NUMERIC(oop) && MOO_OBJ_GET_FLAGS_TYPE(oop) == (type)) typedef struct moo_heap_t moo_heap_t; @@ -1042,7 +1048,7 @@ struct moo_t #define MOO_STACK_ISEMPTY(moo) ((moo)->sp <= -1) #define MOO_STACK_GETARG(moo,nargs,idx) MOO_STACK_GET(moo, (moo)->sp - ((nargs) - (idx) - 1)) -#define MOO_STACK_GETRCV(moo,nargs) MOO_STACK_GET(moo, (moo)->sp - nargs); +#define MOO_STACK_GETRCV(moo,nargs) MOO_STACK_GET(moo, (moo)->sp - nargs) /* you can't access arguments and receiver after this macro. * also you must not call this macro more than once */ @@ -1180,6 +1186,7 @@ enum moo_synerrnum_t MOO_SYNERR_CLASSDUP, /* duplicate class */ MOO_SYNERR_CLASSCONTRA, /* contradictory class */ MOO_SYNERR_CLASSNAME, /* wrong class name */ + MOO_SYNERR_CLASSTRSIZE, /* non-pointer class inheriting a superclass with trailer size set */ MOO_SYNERR_DCLBANNED, /* #dcl not allowed */ MOO_SYNERR_MTHNAME, /* wrong method name */ MOO_SYNERR_MTHNAMEDUP, /* duplicate method name */ @@ -1323,13 +1330,15 @@ MOO_EXPORT void moo_gc ( /** - * The moo_instantiate() function creates a new object of the class + * The moo_instantiate() function creates a new object instance of the class * \a _class. The size of the fixed part is taken from the information - * contained in the class defintion. The \a vlen parameter specifies - * the length of the variable part. The \a vptr parameter points to - * the memory area to copy into the variable part of the new object. - * If \a vptr is #MOO_NULL, the variable part is initialized to 0 or - * an equivalent value depending on the type. + * contained in the class defintion. The \a vlen parameter specifies the length + * of the variable part. The \a vptr parameter points to the memory area to + * copy into the variable part of the new object. If \a vptr is #MOO_NULL, + * the variable part is initialized to 0 or an equivalent value depending + * on the type. \a vptr is not used when the new instance is of the + * #MOO_OBJ_TYPE_OOP type. + * */ MOO_EXPORT moo_oop_t moo_instantiate ( moo_t* moo, @@ -1417,6 +1426,22 @@ MOO_EXPORT int moo_inttoooi ( moo_ooi_t* i ); + +/* ========================================================================= + * TRAILER MANAGEMENT + * ========================================================================= */ +MOO_EXPORT int moo_setclasstrsize ( + moo_t* moo, + moo_oop_t _class, + moo_oow_t size +); + +MOO_EXPORT void* moo_getobjtrailer ( + moo_t* moo, + moo_oop_t obj, + moo_oow_t* size +); + /* ========================================================================= * TEMPORARY OOP MANAGEMENT FUNCTIONS * ========================================================================= */ diff --git a/moo/lib/obj.c b/moo/lib/obj.c index fc771da..7a0f333 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -72,7 +72,7 @@ moo_oop_t moo_allocoopobj (moo_t* moo, moo_oow_t size) return (moo_oop_t)hdr; } -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) moo_oop_t moo_allocoopobjwithtrailer (moo_t* moo, moo_oow_t size, const moo_oob_t* bptr, moo_oow_t blen) { moo_oop_oop_t hdr; @@ -333,7 +333,7 @@ moo_oop_t moo_instantiate2 (moo_t* moo, moo_oop_t _class, const void* vptr, moo_ switch (type) { case MOO_OBJ_TYPE_OOP: - /* NOTE: vptr is not used for GC unsafety */ + /* [NOTE] vptr is not used for GC unsafety. read comment in moo_instantiate() */ oop = moo_allocoopobj (moo, alloclen); break; @@ -365,7 +365,7 @@ moo_oop_t moo_instantiate2 (moo_t* moo, moo_oop_t _class, const void* vptr, moo_ } -#if defined(MOO_USE_OBJECT_TRAILER) +#if defined(MOO_USE_METHOD_TRAILER) moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_t _class, moo_oow_t vlen, const moo_oob_t* tptr, moo_oow_t tlen) { @@ -387,12 +387,16 @@ moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_t _class, moo_oow_t vl switch (type) { case MOO_OBJ_TYPE_OOP: - /* NOTE: vptr is not used for GC unsafety */ oop = moo_allocoopobjwithtrailer(moo, alloclen, tptr, tlen); break; default: - moo->errnum = MOO_EINTERN; + MOO_DEBUG3 (moo, "Not allowed to instantiate a non-pointer object of the %.*js class with trailer %zu\n", + MOO_OBJ_GET_SIZE(((moo_oop_class_t)_class)->name), + MOO_OBJ_GET_CHAR_SLOT(((moo_oop_class_t)_class)->name), + tlen); + + moo->errnum = MOO_EPERM; oop = MOO_NULL; break; } diff --git a/moo/mod/ffi.c b/moo/mod/ffi.c index bdf464a..1f1e047 100644 --- a/moo/mod/ffi.c +++ b/moo/mod/ffi.c @@ -47,7 +47,6 @@ struct link_t typedef struct ffi_t ffi_t; struct ffi_t { - MOO_OBJ_HEADER; void* handle; #if defined(USE_DYNCALL) @@ -75,16 +74,9 @@ static void free_linked_cas (moo_t* moo, ffi_t* ffi) } } -static moo_pfrc_t pf_newinstsize (moo_t* moo, moo_ooi_t nargs) -{ - moo_ooi_t newinstsize = MOO_SIZEOF(ffi_t) - MOO_SIZEOF(moo_obj_t); - MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(newinstsize)); - return MOO_PF_SUCCESS; -} - static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs) { - ffi_t* rcv; + ffi_t* ffi; moo_oop_t name; void* handle; #if defined(USE_DYNCALL) @@ -97,10 +89,10 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs) goto softfail; } - rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); + ffi = (ffi_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); name = MOO_STACK_GETARG(moo, nargs, 0); - if (!MOO_ISTYPEOF(moo, name, MOO_OBJ_TYPE_CHAR)) + if (!MOO_OBJ_IS_CHAR_POINTER(name)) { moo_seterrnum (moo, MOO_EINVAL); goto softfail; @@ -112,7 +104,7 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs) goto softfail; } - if (rcv->handle) + if (ffi->handle) { moo_seterrnum (moo, MOO_EPERM); /* no allowed to open again */ goto softfail; @@ -131,13 +123,13 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs) } #endif - rcv->handle = handle; + ffi->handle = handle; #if defined(USE_DYNCALL) - rcv->dc = dc; + ffi->dc = dc; #endif - MOO_DEBUG3 (moo, " %.*js => %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, rcv->handle); + MOO_DEBUG3 (moo, " %.*js => %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, ffi->handle); MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; @@ -148,7 +140,7 @@ softfail: static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs) { - ffi_t* rcv; + ffi_t* ffi; if (nargs != 0) { @@ -156,7 +148,7 @@ static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs) goto softfail; } - rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); + ffi = (ffi_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); if (!moo->vmprim.dl_open) { @@ -164,17 +156,17 @@ static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs) goto softfail; } - MOO_DEBUG1 (moo, " %p\n", rcv->handle); + MOO_DEBUG1 (moo, " %p\n", ffi->handle); - free_linked_cas (moo, rcv); + free_linked_cas (moo, ffi); #if defined(USE_DYNCALL) - dcFree (rcv->dc); - rcv->dc = MOO_NULL; + dcFree (ffi->dc); + ffi->dc = MOO_NULL; #endif - moo->vmprim.dl_close (moo, rcv->handle); - rcv->handle = MOO_NULL; + moo->vmprim.dl_close (moo, ffi->handle); + ffi->handle = MOO_NULL; MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; @@ -187,14 +179,14 @@ softfail: static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) { #if defined(USE_DYNCALL) - ffi_t* rcv; + ffi_t* ffi; moo_oop_t fun, sig, args; moo_oow_t i, j; void* f; moo_oop_oop_t arr; int ellipsis = 0; - rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); + ffi = (ffi_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); if (nargs < 3) goto inval; fun = MOO_STACK_GETARG(moo, nargs, 0); @@ -203,7 +195,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) /* the signature must not be empty. at least the return type must be * specified */ - if (!MOO_ISTYPEOF(moo, sig, MOO_OBJ_TYPE_CHAR) || MOO_OBJ_GET_SIZE(sig) <= 0) goto inval; + if (!MOO_OBJ_IS_CHAR_POINTER(sig) || MOO_OBJ_GET_SIZE(sig) <= 0) goto inval; #if 0 /* TODO: check if arr is a kind of array??? or check if it's indexed */ @@ -213,19 +205,19 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) f = MOO_OOP_TO_SMPTR(fun); arr = (moo_oop_oop_t)args; - MOO_DEBUG2 (moo, " %p in %p\n", f, rcv->handle); + MOO_DEBUG2 (moo, " %p in %p\n", f, ffi->handle); - dcMode (rcv->dc, DC_CALL_C_DEFAULT); - dcReset (rcv->dc); + dcMode (ffi->dc, DC_CALL_C_DEFAULT); + dcReset (ffi->dc); i = 0; if (i < MOO_OBJ_GET_SIZE(sig) && ((moo_oop_char_t)sig)->slot[i] == '|') { - dcMode (rcv->dc, DC_CALL_C_ELLIPSIS); + dcMode (ffi->dc, DC_CALL_C_ELLIPSIS); /* the error code should be DC_ERROR_UNSUPPORTED_MODE */ - if (dcGetError(rcv->dc) != DC_ERROR_NONE) goto noimpl; - dcReset (rcv->dc); + if (dcGetError(ffi->dc) != DC_ERROR_NONE) goto noimpl; + dcReset (ffi->dc); ellipsis = 1; i++; } @@ -246,10 +238,10 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) { if (ellipsis) { - dcMode (rcv->dc, DC_CALL_C_ELLIPSIS_VARARGS); + dcMode (ffi->dc, DC_CALL_C_ELLIPSIS_VARARGS); /* the error code should be DC_ERROR_UNSUPPORTED_MODE */ - if (dcGetError(rcv->dc) != DC_ERROR_NONE) goto noimpl; + if (dcGetError(ffi->dc) != DC_ERROR_NONE) goto noimpl; } continue; } @@ -263,7 +255,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) /* TODO: support more types... */ case 'c': if (!MOO_OOP_IS_CHAR(arg)) goto inval; - dcArgChar (rcv->dc, MOO_OOP_TO_CHAR(arr->slot[j])); + dcArgChar (ffi->dc, MOO_OOP_TO_CHAR(arr->slot[j])); j++; break; @@ -272,7 +264,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) { moo_ooi_t v; if (moo_inttoooi(moo, arg, &v) == 0) goto inval; - dcArgInt (rcv->dc, i); + dcArgInt (ffi->dc, i); j++; break; } @@ -282,7 +274,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) moo_ooi_t v; arg_as_long: if (moo_inttoooi(moo, arg, &v) == 0) goto inval; - dcArgLong (rcv->dc, v); + dcArgLong (ffi->dc, v); j++; break; } @@ -298,7 +290,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) if (moo_inttointmax (moo, arg, &v) == 0) goto inval; */ # error UNSUPPORTED MOO_SIZEOF_LONG_LONG. # endif - dcArgLongLong (rcv->dc, v); + dcArgLongLong (ffi->dc, v); j++; break; #else @@ -313,19 +305,19 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) { moo_bch_t* ptr; - if (!MOO_ISTYPEOF(moo,arg,MOO_OBJ_TYPE_CHAR)) goto inval; + if (!MOO_OBJ_IS_CHAR_POINTER(arg)) goto inval; #if defined(MOO_OOCH_IS_UCH) ptr = moo_dupootobcharswithheadroom (moo, MOO_SIZEOF_VOID_P, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg), MOO_NULL); if (!ptr) goto softfail; /* out of system memory or conversion error - soft failure */ - link_ca (rcv, ptr); + link_ca (ffi, ptr); #else ptr = MOO_OBJ_GET_CHAR_SLOT(arg); /*ptr = moo_dupoochars (moo, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg)); if (!ptr) goto softfail;*/ /* out of system memory or conversion error - soft failure */ #endif - dcArgPointer (rcv->dc, ptr); + dcArgPointer (ffi->dc, ptr); j++; break; } @@ -334,7 +326,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) { moo_uch_t* ptr; - if (!MOO_ISTYPEOF(moo,arg,MOO_OBJ_TYPE_CHAR)) goto inval; + if (!MOO_OBJ_IS_CHAR_POINTER(arg)) goto inval; #if defined(MOO_OOCH_IS_UCH) ptr = MOO_OBJ_GET_CHAR_SLOT(arg); @@ -343,10 +335,10 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) #else ptr = moo_dupootoucharswithheadroom (moo, MOO_SIZEOF_VOID_P, MOO_OBJ_GET_CHAR_SLOT(arg), MOO_OBJ_GET_SIZE(arg), MOO_NULL); if (!ptr) goto softfail; /* out of system memory or conversion error - soft failure */ - link_ca (rcv, ptr); + link_ca (ffi, ptr); #endif - dcArgPointer (rcv->dc, ptr); + dcArgPointer (ffi->dc, ptr); j++; break; } @@ -365,7 +357,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) /* TODO: proper return value conversion */ case 'c': { - char r = dcCallChar (rcv->dc, f); + char r = dcCallChar (ffi->dc, f); MOO_STACK_SETRET (moo, nargs, MOO_CHAR_TO_OOP(r)); break; } @@ -374,7 +366,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) { moo_oop_t r; - r = moo_ooitoint (moo, dcCallInt (rcv->dc, f)); + r = moo_ooitoint (moo, dcCallInt (ffi->dc, f)); if (!r) goto hardfail; MOO_STACK_SETRET (moo, nargs, r); break; @@ -384,7 +376,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) { moo_oop_t r; ret_as_long: - r = moo_ooitoint (moo, dcCallLong (rcv->dc, f)); + r = moo_ooitoint (moo, dcCallLong (ffi->dc, f)); if (!r) goto hardfail; MOO_STACK_SETRET (moo, nargs, r); break; @@ -395,7 +387,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) #if (MOO_SIZEOF_LONG_LONG > 0) moo_oop_t r; # if (MOO_SIZEOF_LONG_LONG <= MOO_SIZEOF_OOI_T) - r = moo_ooitoint (moo, dcCallLongLong (rcv->dc, f)); + r = moo_ooitoint (moo, dcCallLongLong (ffi->dc, f)); # else # error UNSUPPORTED MOO_SIZEOF_LONG_LONG # endif @@ -419,7 +411,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) moo_oop_t s; moo_bch_t* r; - r = dcCallPointer (rcv->dc, f); + r = dcCallPointer (ffi->dc, f); #if defined(MOO_OOCH_IS_UCH) s = moo_makestringwithbchars (moo, r, moo_countbcstr(r)); @@ -441,7 +433,7 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) moo_oop_t s; moo_uch_t* r; - r = dcCallPointer (rcv->dc, f); + r = dcCallPointer (ffi->dc, f); #if defined(MOO_OOCH_IS_UCH) s = moo_makestring(moo, r, moo_countucstr(r)); @@ -460,12 +452,12 @@ static moo_pfrc_t pf_call (moo_t* moo, moo_ooi_t nargs) default: call_void: - dcCallVoid (rcv->dc, f); + dcCallVoid (ffi->dc, f); MOO_STACK_SETRETTORCV (moo, nargs); break; } - free_linked_cas (moo, rcv); + free_linked_cas (moo, ffi); return MOO_PF_SUCCESS; noimpl: @@ -477,12 +469,12 @@ inval: goto softfail; softfail: - free_linked_cas (moo, rcv); + free_linked_cas (moo, ffi); MOO_STACK_SETRETTOERROR (moo, nargs); return MOO_PF_SUCCESS; hardfail: - free_linked_cas (moo, rcv); + free_linked_cas (moo, ffi); return MOO_PF_HARD_FAILURE; #else @@ -494,7 +486,7 @@ hardfail: static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs) { - ffi_t* rcv; + ffi_t* ffi; moo_oop_t name; void* sym; @@ -504,10 +496,10 @@ static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs) goto softfail; } - rcv = (ffi_t*)MOO_STACK_GETRCV(moo, nargs); + ffi = (ffi_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); name = MOO_STACK_GETARG(moo, nargs, 0); - if (!MOO_ISTYPEOF(moo,name,MOO_OBJ_TYPE_CHAR)) + if (!MOO_OBJ_IS_CHAR_POINTER(name)) { moo_seterrnum (moo, MOO_EINVAL); goto softfail; @@ -519,10 +511,10 @@ static moo_pfrc_t pf_getsym (moo_t* moo, moo_ooi_t nargs) goto softfail; } - sym = moo->vmprim.dl_getsym (moo, rcv->handle, ((moo_oop_char_t)name)->slot); + sym = moo->vmprim.dl_getsym (moo, ffi->handle, ((moo_oop_char_t)name)->slot); if (!sym) goto softfail; - MOO_DEBUG4 (moo, " %.*js => %p in %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, sym, rcv->handle); + MOO_DEBUG4 (moo, " %.*js => %p in %p\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, sym, ffi->handle); MOO_ASSERT (moo, MOO_IN_SMPTR_RANGE(sym)); MOO_STACK_SETRET (moo, nargs, MOO_SMPTR_TO_OOP(sym)); @@ -549,7 +541,6 @@ struct fnctab_t static fnctab_t fnctab[] = { - { C, { '_','n','e','w','I','n','s','t','S','i','z','e','\0' }, 0, pf_newinstsize }, { I, { 'c','a','l','l','\0' }, 1, pf_call }, { I, { 'c','a','l','l',':','s','i','g',':','w','i','t','h',':','\0' }, 0, pf_call }, { I, { 'c','l','o','s','e','\0' }, 0, pf_close }, @@ -564,6 +555,8 @@ static int import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class) int ret = 0; moo_oow_t i; + if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(ffi_t)) <= -1) return -1; + moo_pushtmp (moo, &_class); for (i = 0; i < MOO_COUNTOF(fnctab); i++) { diff --git a/moo/mod/stdio.c b/moo/mod/stdio.c index 439e1d8..22ce667 100644 --- a/moo/mod/stdio.c +++ b/moo/mod/stdio.c @@ -39,30 +39,22 @@ typedef struct stdio_t stdio_t; struct stdio_t { - MOO_OBJ_HEADER; FILE* fp; }; -static moo_pfrc_t pf_newinstsize (moo_t* moo, moo_ooi_t nargs) -{ - moo_ooi_t newinstsize = MOO_SIZEOF(stdio_t) - MOO_SIZEOF(moo_obj_t); - MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(newinstsize)); - return MOO_PF_SUCCESS; -} - static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs) { moo_oop_char_t name; moo_oop_char_t mode; - stdio_t* rcv; + stdio_t* stdio; #if defined(MOO_OOCH_IS_UCH) moo_oow_t ucslen, bcslen; moo_bch_t namebuf[PATH_MAX]; - moo_bch_t modebuf[32]; /* TODO: dynamic-sized conversion?? */ + moo_bch_t modebuf[32]; /* TODO: mode should not be long but use dynamic-sized conversion?? */ #endif - rcv = (stdio_t*)MOO_STACK_GETRCV(moo, nargs); + stdio = (stdio_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); name = (moo_oop_char_t)MOO_STACK_GETARG(moo, nargs, 0); mode = (moo_oop_char_t)MOO_STACK_GETARG(moo, nargs, 1); @@ -77,11 +69,11 @@ static moo_pfrc_t pf_open (moo_t* moo, moo_ooi_t nargs) if (moo_convootobchars (moo, mode->slot, &ucslen, modebuf, &bcslen) <= -1) goto softfail; modebuf[bcslen] = '\0'; - rcv->fp = fopen (namebuf, modebuf); + stdio->fp = fopen (namebuf, modebuf); #else - rcv->fp = fopen (name->slot, mode->slot); + stdio->fp = fopen (name->slot, mode->slot); #endif - if (!rcv->fp) + if (!stdio->fp) { moo_seterrnum (moo, moo_syserrtoerrnum(errno)); goto softfail; @@ -97,13 +89,13 @@ softfail: static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs) { - stdio_t* rcv; + stdio_t* stdio; - rcv = (stdio_t*)MOO_STACK_GETRCV(moo, nargs); - if (rcv->fp) + stdio = (stdio_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); + if (stdio->fp) { - fclose (rcv->fp); - rcv->fp = NULL; + fclose (stdio->fp); + stdio->fp = NULL; } MOO_STACK_SETRETTORCV (moo, nargs); @@ -112,17 +104,17 @@ static moo_pfrc_t pf_close (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t pf_gets (moo_t* moo, moo_ooi_t nargs) { - /* return how many bytes have been written.. */ + /* TODO: ...*/ MOO_STACK_SETRETTORCV (moo, nargs); return MOO_PF_SUCCESS; } static moo_pfrc_t __pf_puts (moo_t* moo, moo_ooi_t nargs, moo_oow_t limit) { - stdio_t* rcv; + stdio_t* stdio; moo_ooi_t i; - rcv = (stdio_t*)MOO_STACK_GETRCV(moo, nargs); + stdio = (stdio_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); for (i = 0; i < nargs; i++) { @@ -163,7 +155,7 @@ static moo_pfrc_t __pf_puts (moo_t* moo, moo_ooi_t nargs, moo_oow_t limit) if (n != -2 || ucslen <= 0) goto softfail; } - if (fwrite (bcs, 1, bcslen, rcv->fp) < bcslen) + if (fwrite (bcs, 1, bcslen, stdio->fp) < bcslen) { moo_seterrnum (moo, moo_syserrtoerrnum(errno)); goto softfail; @@ -175,7 +167,7 @@ static moo_pfrc_t __pf_puts (moo_t* moo, moo_ooi_t nargs, moo_oow_t limit) } #else puts_string: - if (fwrite (x->slot, 1, MOO_OBJ_GET_SIZE(x), rcv->fp) < MOO_OBJ_GET_SIZE(x)) + if (fwrite (x->slot, 1, MOO_OBJ_GET_SIZE(x), stdio->fp) < MOO_OBJ_GET_SIZE(x)) { moo_seterrnum (moo, moo_syserrtoerrnum(errno)); moo_seterrnum (moo, moo_syserrtoerrnum(errno)); @@ -228,7 +220,6 @@ struct fnctab_t static fnctab_t fnctab[] = { - { C, { '_','n','e','w','I','n','s','t','S','i','z','e','\0' }, 0, pf_newinstsize }, { I, { 'c','l','o','s','e','\0' }, 0, pf_close }, { I, { 'g','e','t','s','\0' }, 0, pf_gets }, { I, { 'o','p','e','n',':','f','o','r',':','\0' }, 0, pf_open }, @@ -245,6 +236,8 @@ static int import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class) int ret = 0; moo_oow_t i; + if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(stdio_t)) <= -1) return -1; + moo_pushtmp (moo, &_class); for (i = 0; i < MOO_COUNTOF(fnctab); i++) { diff --git a/moo/mod/x11.c b/moo/mod/x11.c index b2791ab..747c958 100644 --- a/moo/mod/x11.c +++ b/moo/mod/x11.c @@ -48,26 +48,17 @@ struct fnctab_t typedef struct x11_t x11_t; struct x11_t { - MOO_OBJ_HEADER; xcb_connection_t* c; }; -typedef struct x11_window_t x11_window_t; -struct x11_window_t +typedef struct x11_win_t x11_win_t; +struct x11_win_t { - MOO_OBJ_HEADER; xcb_window_t w; }; /* ------------------------------------------------------------------------ */ -static moo_pfrc_t pf_newinstsize (moo_t* moo, moo_ooi_t nargs) -{ - moo_ooi_t newinstsize = MOO_SIZEOF(x11_t) - MOO_SIZEOF(moo_obj_t); - MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(newinstsize)); - return MOO_PF_SUCCESS; -} - static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs) { x11_t* x11; @@ -84,7 +75,7 @@ static moo_pfrc_t pf_connect (moo_t* moo, moo_ooi_t nargs) /* name = MOO_STACK_GETARG(moo, nargs, 0); - if (!MOO_ISTYPEOF(moo, name, MOO_OBJ_TYPE_CHAR)) + if (!MOO_OBJ_IS_CHAR_POINTER(name)) { moo_seterrnum (moo, MOO_EINVAL); goto softfail; @@ -135,14 +126,6 @@ softfail: /* ------------------------------------------------------------------------ */ -static moo_pfrc_t pf_win_newinstsize (moo_t* moo, moo_ooi_t nargs) -{ - moo_ooi_t newinstsize = MOO_SIZEOF(x11_window_t) - MOO_SIZEOF(moo_obj_t); - MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(newinstsize)); -MOO_DEBUG0 (moo, "x11.window.newinstsize....\n"); - return MOO_PF_SUCCESS; -} - static moo_pfrc_t pf_win_create (moo_t* moo, moo_ooi_t nargs) { MOO_STACK_SETRET (moo, nargs, moo->_nil); @@ -181,7 +164,6 @@ MOO_DEBUG0 (moo, "x11.window.destroy....\n"); /* ------------------------------------------------------------------------ */ - static moo_pfimpl_t search_fnctab (moo_t* moo, const fnctab_t* fnctab, moo_oow_t fnclen, const moo_ooch_t* name) { int left, right, mid, n; @@ -230,13 +212,13 @@ static int import_fnctab (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, const fn static fnctab_t x11_fnctab[] = { - { C, { '_','n','e','w','I','n','s','t','S','i','z','e','\0' }, 0, pf_newinstsize }, { I, { 'c','o','n','n','e','c','t','\0' }, 0, pf_connect }, { I, { 'd','i','s','c','o','n','n','e','c','t','\0' }, 0, pf_disconnect } }; static int x11_import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class) { + if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(x11_t)) <= -1) return -1; return import_fnctab (moo, mod, _class, x11_fnctab, MOO_COUNTOF(x11_fnctab)); } @@ -263,13 +245,13 @@ int moo_mod_x11 (moo_t* moo, moo_mod_t* mod) static fnctab_t x11_win_fnctab[] = { - { C, { '_','n','e','w','I','n','s','t','S','i','z','e','\0' }, 0, pf_win_newinstsize }, { I, { 'c','r','e','a','t','e','\0' }, 0, pf_win_create }, { I, { 'd','i','s','t','r','o','y','\0' }, 0, pf_win_destroy } }; static int x11_win_import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class) { + if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(x11_win_t)) <= -1) return -1; return import_fnctab (moo, mod, _class, x11_win_fnctab, MOO_COUNTOF(x11_win_fnctab)); }