removed unused code of putting compiled method code into a separate array.

started implementing interface method support
This commit is contained in:
hyunghwan.chung 2019-10-04 18:32:38 +00:00
parent eb3461b588
commit 7b8b7d70fd
6 changed files with 112 additions and 126 deletions

View File

@ -321,7 +321,6 @@ class(#pointer) CompiledMethod(Object)
preamble_data_2,
ntmprs,
nargs,
//code, <-- only if moo is built with MOO_USE_METHOD_TRAILER disabled.
dbi_file_offset,
dbi_method_offset.

View File

@ -7451,70 +7451,30 @@ static int compile_method_statements (moo_t* moo)
return emit_byte_instruction(moo, BCODE_RETURN_RECEIVER, TOKEN_LOC(moo));
}
static int add_compiled_method_to_class (moo_t* moo)
static moo_ooi_t compute_preamble (moo_t* moo, moo_method_data_t* md)
{
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
moo_oop_char_t name; /* selector */
moo_oop_method_t mth; /* method */
#if defined(MOO_USE_METHOD_TRAILER)
/* nothing extra */
#else
moo_oop_byte_t code;
#endif
moo_oow_t tmp_count = 0;
moo_oow_t i;
moo_ooi_t preamble_code, preamble_index, preamble_flags;
MOO_ASSERT (moo, moo->c->cunit->cunit_type == MOO_CUNIT_CLASS);
name = (moo_oop_char_t)moo_makesymbol(moo, cc->mth.name.ptr, cc->mth.name.len);
if (!name) goto oops;
moo_pushvolat (moo, (moo_oop_t*)&name); tmp_count++;
/* The variadic data part passed to moo_instantiate() is not GC-safe.
* let's delay initialization of variadic data a bit. */
#if defined(MOO_USE_METHOD_TRAILER)
mth = (moo_oop_method_t)moo_instantiatewithtrailer(moo, moo->_method, cc->mth.literals.count, cc->mth.code.ptr, cc->mth.code.len);
#else
mth = (moo_oop_method_t)moo_instantiate(moo, moo->_method, MOO_NULL, cc->mth.literals.count);
#endif
if (!mth) goto oops;
for (i = 0; i < cc->mth.literals.count; i++)
{
/* let's do the variadic data initialization here */
MOO_STORE_OOP (moo, &mth->literal_frame[i], cc->mth.literals.ptr[i]);
}
moo_pushvolat (moo, (moo_oop_t*)&mth); tmp_count++;
#if defined(MOO_USE_METHOD_TRAILER)
/* do nothing */
#else
code = (moo_oop_byte_t)moo_instantiate(moo, moo->_byte_array, cc->mth.code.ptr, cc->mth.code.len);
if (!code) goto oops;
moo_pushvolat (moo, (moo_oop_t*)&code); tmp_count++;
#endif
preamble_code = MOO_METHOD_PREAMBLE_NONE;
preamble_index = 0;
preamble_flags = 0;
if (cc->mth.pftype <= 0)
if (md->pftype <= 0)
{
/* no primitive is set - perform some mutation for simplicity and efficiency */
if (cc->mth.code.len <= 0)
if (md->code.len <= 0)
{
preamble_code = MOO_METHOD_PREAMBLE_RETURN_RECEIVER;
}
else
{
if (cc->mth.code.ptr[0] == BCODE_RETURN_RECEIVER)
if (md->code.ptr[0] == BCODE_RETURN_RECEIVER)
{
preamble_code = MOO_METHOD_PREAMBLE_RETURN_RECEIVER;
}
else if (cc->mth.code.len > 1 && cc->mth.code.ptr[1] == BCODE_RETURN_STACKTOP)
else if (md->code.len > 1 && md->code.ptr[1] == BCODE_RETURN_STACKTOP)
{
switch (cc->mth.code.ptr[0])
switch (md->code.ptr[0])
{
case BCODE_PUSH_RECEIVER:
preamble_code = MOO_METHOD_PREAMBLE_RETURN_RECEIVER;
@ -7573,15 +7533,15 @@ static int add_compiled_method_to_class (moo_t* moo)
case BCODE_PUSH_INSTVAR_6:
case BCODE_PUSH_INSTVAR_7:
preamble_code = MOO_METHOD_PREAMBLE_RETURN_INSTVAR;
preamble_index = cc->mth.code.ptr[0] & 0x7; /* low 3 bits */
preamble_index = md->code.ptr[0] & 0x7; /* low 3 bits */
break;
}
}
else if (cc->mth.code.len > MOO_BCODE_LONG_PARAM_SIZE + 1 &&
cc->mth.code.ptr[MOO_BCODE_LONG_PARAM_SIZE + 1] == BCODE_RETURN_STACKTOP)
else if (md->code.len > MOO_BCODE_LONG_PARAM_SIZE + 1 &&
md->code.ptr[MOO_BCODE_LONG_PARAM_SIZE + 1] == BCODE_RETURN_STACKTOP)
{
int i;
switch (cc->mth.code.ptr[0])
switch (md->code.ptr[0])
{
case BCODE_PUSH_INSTVAR_X:
preamble_code = MOO_METHOD_PREAMBLE_RETURN_INSTVAR;
@ -7599,7 +7559,7 @@ static int add_compiled_method_to_class (moo_t* moo)
preamble_index = 0;
for (i = 1; i <= MOO_BCODE_LONG_PARAM_SIZE; i++)
{
preamble_index = (preamble_index << 8) | cc->mth.code.ptr[i];
preamble_index = (preamble_index << 8) | md->code.ptr[i];
}
if (!MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(preamble_index))
@ -7612,48 +7572,73 @@ static int add_compiled_method_to_class (moo_t* moo)
}
}
}
else if (cc->mth.pftype == PFTYPE_NUMBERED)
else if (md->pftype == PFTYPE_NUMBERED)
{
preamble_code = MOO_METHOD_PREAMBLE_PRIMITIVE;
preamble_index = cc->mth.pfnum;
preamble_index = md->pfnum;
}
else if (cc->mth.pftype == PFTYPE_NAMED)
else if (md->pftype == PFTYPE_NAMED)
{
preamble_code = MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE;
preamble_index = cc->mth.pfnum; /* index to literal frame */
preamble_index = md->pfnum; /* index to literal frame */
}
else if (cc->mth.pftype == PFTYPE_EXCEPTION)
else if (md->pftype == PFTYPE_EXCEPTION)
{
preamble_code = MOO_METHOD_PREAMBLE_EXCEPTION;
preamble_index = 0;
}
else
{
MOO_ASSERT (moo, cc->mth.pftype == PFTYPE_ENSURE);
MOO_ASSERT (moo, md->pftype == PFTYPE_ENSURE);
preamble_code = MOO_METHOD_PREAMBLE_ENSURE;
preamble_index = 0;
}
preamble_flags |= cc->mth.variadic; /* MOO_METHOD_PREAMBLE_FLAG_VARIADIC or MOO_METHOD_PREAMBLE_FLAG_LIBERAL */
if (cc->mth.type == MOO_METHOD_DUAL) preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_DUAL;
if (cc->mth.lenient) preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_LENIENT;
preamble_flags |= md->variadic; /* MOO_METHOD_PREAMBLE_FLAG_VARIADIC or MOO_METHOD_PREAMBLE_FLAG_LIBERAL */
if (md->type == MOO_METHOD_DUAL) preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_DUAL;
if (md->lenient) preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_LENIENT;
MOO_ASSERT (moo, MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(preamble_index));
return MOO_METHOD_MAKE_PREAMBLE(preamble_code, preamble_index, preamble_flags);
}
static int add_compiled_method_to_class (moo_t* moo)
{
moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit;
moo_oop_char_t name; /* selector */
moo_oop_method_t mth; /* method */
moo_oow_t tmp_count = 0;
moo_oow_t i;
moo_ooi_t preamble;
MOO_ASSERT (moo, moo->c->cunit->cunit_type == MOO_CUNIT_CLASS);
name = (moo_oop_char_t)moo_makesymbol(moo, cc->mth.name.ptr, cc->mth.name.len);
if (!name) goto oops;
moo_pushvolat (moo, (moo_oop_t*)&name); tmp_count++;
/* The variadic data part passed to moo_instantiate() is not GC-safe.
* let's delay initialization of variadic data a bit. */
mth = (moo_oop_method_t)moo_instantiatewithtrailer(moo, moo->_method, cc->mth.literals.count, cc->mth.code.ptr, cc->mth.code.len);
if (!mth) goto oops;
for (i = 0; i < cc->mth.literals.count; i++)
{
/* let's do the variadic data initialization here */
MOO_STORE_OOP (moo, &mth->literal_frame[i], cc->mth.literals.ptr[i]);
}
moo_pushvolat (moo, (moo_oop_t*)&mth); tmp_count++;
preamble = compute_preamble(moo, &cc->mth);
MOO_STORE_OOP (moo, (moo_oop_t*)&mth->owner, (moo_oop_t)cc->self_oop);
MOO_STORE_OOP (moo, (moo_oop_t*)&mth->name, (moo_oop_t)name);
mth->preamble = MOO_SMOOI_TO_OOP(MOO_METHOD_MAKE_PREAMBLE(preamble_code, preamble_index, preamble_flags));
mth->preamble = MOO_SMOOI_TO_OOP(preamble);
mth->preamble_data[0] = MOO_SMPTR_TO_OOP(0);
mth->preamble_data[1] = MOO_SMPTR_TO_OOP(0);
mth->tmpr_count = MOO_SMOOI_TO_OOP(cc->mth.tmpr_count);
mth->tmpr_nargs = MOO_SMOOI_TO_OOP(cc->mth.tmpr_nargs);
#if defined(MOO_USE_METHOD_TRAILER)
/* do nothing */
#else
MOO_STORE_OOP (moo, (moo_oop_t*)&mth->code, (moo_oop_t)code);
#endif
if (moo->dbgi)
{
moo_oow_t file_offset;
@ -7718,6 +7703,12 @@ oops:
return -1;
}
static int add_compiled_method_to_interface (moo_t* moo)
{
/* TODO: */
return -1;
}
static void clear_pooldic_import_data (moo_t* moo, moo_pooldic_import_data_t* pdimp)
{
if (pdimp->dcl.ptr) moo_freemem (moo, pdimp->dcl.ptr);
@ -9546,7 +9537,7 @@ oops:
static int __compile_method_signature (moo_t* moo)
{
/*moo_cunit_interface_t* ifce = (moo_cunit_interface_t*)moo->c->cunit;*/
moo_cunit_interface_t* ifce = (moo_cunit_interface_t*)moo->c->cunit;
MOO_ASSERT (moo, moo->c->cunit->cunit_type == MOO_CUNIT_INTERFACE);
@ -9558,17 +9549,42 @@ static int __compile_method_signature (moo_t* moo)
if (compile_method_name(moo) <= -1) return -1;
if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD)
if (TOKEN_TYPE(moo) == MOO_IOTOK_LBRACE)
{
/* . expected */
moo_setsynerr (moo, MOO_SYNERR_PERIOD, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
/* you can inlcude method body optionally */
GET_TOKEN (moo);
if (compile_method_temporaries(moo) <= -1 ||
compile_method_pragma(moo) <= -1 || /* TODO: disallow pragmas... */
compile_method_statements(moo) <= -1) return -1;
if (TOKEN_TYPE(moo) != MOO_IOTOK_RBRACE)
{
/* } expected */
moo_setsynerr (moo, MOO_SYNERR_RBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1;
}
/* end of method has been reached */
if (resolve_goto_labels(moo) <= -1) return -1;
GET_TOKEN (moo);
/* add a compiled method to the method dictionary */
if (add_compiled_method_to_interface(moo) <= -1) return -1;
return 0;
}
else if (TOKEN_TYPE(moo) == MOO_IOTOK_PERIOD)
{
if (add_method_signature(moo) <= -1) return -1;
GET_TOKEN (moo);
return 0;
}
if (add_method_signature(moo) <= -1) return -1;
GET_TOKEN (moo);
return 0;
/* . or { expected */
moo_setsynerrbfmt (moo, MOO_SYNERR_PERIOD, TOKEN_LOC(moo), TOKEN_NAME(moo), "period or left brace expected");
return -1;
}
static int compile_method_signature (moo_t* moo)
@ -10029,7 +10045,7 @@ static int __compile_pooldic_definition (moo_t* moo)
if (TOKEN_TYPE(moo) != MOO_IOTOK_COMMA)
{
moo_setsynerrbfmt (moo, MOO_SYNERR_COMMA, TOKEN_LOC(moo), TOKEN_NAME(moo), "comma expected");
moo_setsynerrbfmt (moo, MOO_SYNERR_COMMA, TOKEN_LOC(moo), TOKEN_NAME(moo), ", expected to separate pooldic items");
goto oops;
}
@ -10039,7 +10055,7 @@ static int __compile_pooldic_definition (moo_t* moo)
* to be followed by a comma. what is better? */
if (TOKEN_TYPE(moo) != MOO_IOTOK_IDENT)
{
moo_setsynerrbfmt (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo), "identifier expected after comma");
moo_setsynerrbfmt (moo, MOO_SYNERR_IDENT, TOKEN_LOC(moo), TOKEN_NAME(moo), "identifier expected after ,");
goto oops;
}
}

View File

@ -4815,12 +4815,8 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
moo->processor->active->perrmsg = moo->_nil;
}
#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 is not a small integer */
#else
if (method->code == moo->_nil)
#endif
{
/* no byte code to execute - invoke 'self primitiveFailed' */
moo_oow_t i;

View File

@ -486,16 +486,14 @@ static int ignite_1 (moo_t* moo)
MOO_OBJ_SET_CLASS (moo->_nil, (moo_oop_t)moo->_undefined_object);
#if defined(MOO_USE_METHOD_TRAILER)
/* an instance of a method class stores byte codes in the trailer space
* when compiled with MOO_USE_METHOD_TRAILER. unlike other classes with
* trailer size set, the size of the trailer space is not really determined
* by the traailer size set in the class. the compiler determines the
* actual size of the trailer space depending on the byte codes generated.
* i should set the following fields to avoid confusion at the GC phase. */
/* an instance of a method class stores byte codes in the trailer space.
* unlike other classes with trailer size set, the size of the trailer
* space is not really determined by the traailer size set in the class.
* the compiler determines the actual size of the trailer space depending
* on the byte codes generated. i should set the following fields to avoid
* confusion at the GC phase. */
moo->_method->trsize = MOO_SMOOI_TO_OOP(0);
moo->_method->trgc = MOO_SMPTR_TO_OOP(0);
#endif
return 0;
}

View File

@ -862,11 +862,7 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class, moo_met
}
moo_pushvolat (moo, (moo_oop_t*)&pfidsym); tmp_count++;
#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);
#endif
if (!mth)
{
MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - method instantiation failure\n", mthname, _class->name);

View File

@ -34,12 +34,6 @@
/* TODO: move this macro out to the build files.... */
#define MOO_INCLUDE_COMPILER
/* 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_METHOD_TRAILER
typedef struct moo_mod_t moo_mod_t;
/* ========================================================================== */
@ -569,11 +563,8 @@ struct moo_methsig_t
moo_oop_t tmpr_nargs; /* SmallInteger */
};
#if defined(MOO_USE_METHOD_TRAILER)
# define MOO_METHOD_NAMED_INSTVARS 9
#else
# define MOO_METHOD_NAMED_INSTVARS 10
#endif
#define MOO_METHOD_NAMED_INSTVARS 9
typedef struct moo_method_t moo_method_t;
typedef struct moo_method_t* moo_oop_method_t;
struct moo_method_t
@ -594,34 +585,24 @@ struct moo_method_t
/* number of arguments in temporaries */
moo_oop_t tmpr_nargs; /* SmallInteger */
#if defined(MOO_USE_METHOD_TRAILER)
/* no code field is used. it's placed after literal_frame. */
#else
moo_oop_byte_t code; /* ByteArray */
#endif
moo_oop_t dbgi_file_offset; /* SmallInteger. source file path that contains the definition of this method. offset from moo->dbgi. 0 if unavailable */
moo_oop_t dbgi_method_offset; /* SmallInteger */
/* == variable indexed part == */
moo_oop_t literal_frame[1]; /* it stores literals */
/* after the literal frame comes the actual byte code, if MOO_USE_METHOD_TRAILER is defined */
/* after the literal frame comes the actual byte code */
};
#if defined(MOO_USE_METHOD_TRAILER)
/* the first byte after the main payload is the trailer size
* the code bytes are placed after the trailer size.
*
* code bytes -> ((moo_oob_t*)&((moo_oop_oop_t)m)->slot[MOO_OBJ_GET_SIZE(m) + 1]) or
* ((moo_oob_t*)&((moo_oop_method_t)m)->literal_frame[MOO_OBJ_GET_SIZE(m) + 1 - MOO_METHOD_NAMED_INSTVARS])
* size -> ((moo_oow_t)((moo_oop_oop_t)m)->slot[MOO_OBJ_GET_SIZE(m)])*/
# define MOO_METHOD_GET_CODE_BYTE(m) MOO_OBJ_GET_TRAILER_BYTE(m)
# define MOO_METHOD_GET_CODE_SIZE(m) MOO_OBJ_GET_TRAILER_SIZE(m)
#else
# define MOO_METHOD_GET_CODE_BYTE(m) MOO_OBJ_GET_BYTE_SLOT(((m)->code)
# define MOO_METHOD_GET_CODE_SIZE(m) MOO_OBJ_GET_SIZE((m)->code)
#endif
/* the first byte after the main payload is the trailer size
* the code bytes are placed after the trailer size.
*
* code bytes -> ((moo_oob_t*)&((moo_oop_oop_t)m)->slot[MOO_OBJ_GET_SIZE(m) + 1]) or
* ((moo_oob_t*)&((moo_oop_method_t)m)->literal_frame[MOO_OBJ_GET_SIZE(m) + 1 - MOO_METHOD_NAMED_INSTVARS])
* size -> ((moo_oow_t)((moo_oop_oop_t)m)->slot[MOO_OBJ_GET_SIZE(m)])*/
#define MOO_METHOD_GET_CODE_BYTE(m) MOO_OBJ_GET_TRAILER_BYTE(m)
#define MOO_METHOD_GET_CODE_SIZE(m) MOO_OBJ_GET_TRAILER_SIZE(m)
/* The preamble field is composed of:
* 4-bit flag