From 7b8b7d70fdf8f22b41f576e527c126cfc6621e19 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Fri, 4 Oct 2019 18:32:38 +0000 Subject: [PATCH] removed unused code of putting compiled method code into a separate array. started implementing interface method support --- moo/kernel/Context.moo | 1 - moo/lib/comp.c | 172 ++++++++++++++++++++++------------------- moo/lib/exec.c | 4 - moo/lib/gc.c | 14 ++-- moo/lib/moo.c | 4 - moo/lib/moo.h | 43 +++-------- 6 files changed, 112 insertions(+), 126 deletions(-) diff --git a/moo/kernel/Context.moo b/moo/kernel/Context.moo index ff26271..c543b93 100644 --- a/moo/kernel/Context.moo +++ b/moo/kernel/Context.moo @@ -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. diff --git a/moo/lib/comp.c b/moo/lib/comp.c index a5591e4..7d8903d 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -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; } } diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 1c52c63..f62f301 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -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; diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 759602f..d91ddcd 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -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; } diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 0e169f2..7bad723 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -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); diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 915fef5..24d86ba 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -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