added more preamable codes.
enhanced the system to be able to attach trailing spaces to an object upon instantiation, especially for external modules to be able to secure GC-safe free workspace inside an instantiated object added moo_setclasstrsize(), moo_getobjtrailer() for the trailer feature
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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 */
|
||||
|
||||
103
moo/lib/exec.c
103
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, "<pf_basic_new> 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, "<pf_basic_new> 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, "<basic new> 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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
117
moo/lib/moo.h
117
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
|
||||
* ========================================================================= */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user