From 042edde3496a63d9b93886d3efce2f57f7f6ad7a Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Mon, 7 Oct 2019 16:50:17 +0000 Subject: [PATCH] compiler works in progress to support interface methods --- moo/lib/comp.c | 91 ++++++++++++++++++++++++-------------------------- moo/lib/dic.c | 9 +++-- 2 files changed, 51 insertions(+), 49 deletions(-) diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 169054d..f37b1d6 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -7602,11 +7602,8 @@ static moo_ooi_t compute_preamble (moo_t* moo, moo_method_data_t* md) return MOO_METHOD_MAKE_PREAMBLE(preamble_code, preamble_index, preamble_flags); } -static void add_method_info_to_dbgi (moo_t* moo, moo_method_data_t* md) +static void add_method_info_to_dbgi (moo_t* moo, moo_method_data_t* md, moo_oow_t class_offset, moo_oow_t* file_offset, moo_oow_t* method_offset) { -#if 0 - moo_oow_t file_offset; - moo_oow_t method_offset; const moo_ooch_t* file_name; MOO_ASSERT (moo, moo->dbgi != MOO_NULL); @@ -7614,31 +7611,28 @@ static void add_method_info_to_dbgi (moo_t* moo, moo_method_data_t* md) file_name = md->start_loc.file; if (!file_name) file_name = &_nul; - if (moo_addfiletodbgi(moo, file_name, &file_offset) <= -1) + if (moo_addfiletodbgi(moo, file_name, file_offset) <= -1) { /* TODO: warning */ - file_offset = 0; + *file_offset = 0; } - else if (file_offset > MOO_SMOOI_MAX) + else if (*file_offset > MOO_SMOOI_MAX) { /* TODO: warning */ - file_offset = 0; + *file_offset = 0; } - mth->dbgi_file_offset = MOO_SMOOI_TO_OOP(file_offset); /* TODO: preserve source text... */ - if (moo_addmethodtodbgi(moo, file_offset, cc->dbgi_class_offset, md->name.ptr, md->start_loc.line, md->code.locptr, md->code.len, MOO_NULL, 0, &method_offset) <= -1) + if (moo_addmethodtodbgi(moo, *file_offset, class_offset, md->name.ptr, md->start_loc.line, md->code.locptr, md->code.len, MOO_NULL, 0, method_offset) <= -1) { /* TODO: warning. no debug information about this method will be available */ - method_offset = 0; + *method_offset = 0; } - else if (method_offset > MOO_SMOOI_MAX) + else if (*method_offset > MOO_SMOOI_MAX) { - method_offset = 0; + *method_offset = 0; } - mth->dbgi_method_offset = MOO_SMOOI_TO_OOP(method_offset); -#endif } @@ -7679,42 +7673,14 @@ static int add_compiled_method_to_class (moo_t* moo) mth->tmpr_count = MOO_SMOOI_TO_OOP(cc->mth.tmpr_count); mth->tmpr_nargs = MOO_SMOOI_TO_OOP(cc->mth.tmpr_nargs); - if (moo->dbgi) add_method_info_to_dbgi (moo, &cc->mth); -#if 0 + if (moo->dbgi) { moo_oow_t file_offset; moo_oow_t method_offset; - const moo_ooch_t* file_name; - - file_name = cc->mth.start_loc.file; - if (!file_name) file_name = &_nul; - - if (moo_addfiletodbgi(moo, file_name, &file_offset) <= -1) - { - /* TODO: warning */ - file_offset = 0; - } - else if (file_offset > MOO_SMOOI_MAX) - { - /* TODO: warning */ - file_offset = 0; - } + add_method_info_to_dbgi (moo, &cc->mth, cc->dbgi_class_offset, &file_offset, &method_offset); mth->dbgi_file_offset = MOO_SMOOI_TO_OOP(file_offset); - -/* TODO: preserve source text... */ - if (moo_addmethodtodbgi(moo, file_offset, cc->dbgi_class_offset, cc->mth.name.ptr, cc->mth.start_loc.line, cc->mth.code.locptr, cc->mth.code.len, MOO_NULL, 0, &method_offset) <= -1) - { - /* TODO: warning. no debug information about this method will be available */ - method_offset = 0; - } - else if (method_offset > MOO_SMOOI_MAX) - { - method_offset = 0; - } - mth->dbgi_method_offset = MOO_SMOOI_TO_OOP(method_offset); } -#endif #if defined(MOO_DEBUG_COMPILER) moo_decode (moo, mth, &cc->fqn); @@ -7777,6 +7743,19 @@ static int add_compiled_method_to_interface (moo_t* moo) mth->tmpr_count = MOO_SMOOI_TO_OOP(ifce->mth.tmpr_count); mth->tmpr_nargs = MOO_SMOOI_TO_OOP(ifce->mth.tmpr_nargs); + if (moo->dbgi) + { + moo_oow_t file_offset; + moo_oow_t method_offset; + add_method_info_to_dbgi (moo, &ifce->mth, ifce->dbgi_interface_offset, &file_offset, &method_offset); + mth->dbgi_file_offset = MOO_SMOOI_TO_OOP(file_offset); + mth->dbgi_method_offset = MOO_SMOOI_TO_OOP(method_offset); + } + +#if defined(MOO_DEBUG_COMPILER) + moo_decode (moo, mth, &ifce->fqn); +#endif + if (ifce->mth.type == MOO_METHOD_DUAL) { if (!moo_putatdic(moo, ifce->self_oop->mthdic[MOO_METHOD_INSTANCE], (moo_oop_t)name, (moo_oop_t)mth)) goto oops; @@ -7853,7 +7832,6 @@ oops: 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); @@ -9100,10 +9078,22 @@ static int ciim_on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_associati name.ptr = MOO_OBJ_GET_CHAR_SLOT(ass->key); name.len = MOO_OBJ_GET_SIZE(ass->key); - /* [IMPORT] the method lookup logic should be the same as moo_findmethod() in exec.c */ + /* [IMPORTANT] the method lookup logic should be the same as moo_findmethod() in exec.c */ mth = moo_findmethodinclasschain(moo, ciim->_class, ciim->mth_type, &name); if (!mth) { + /* TODO: take methods from interface..*/ + if (MOO_CLASSOF(moo, ass->value) == moo->_method) + { + mth = (moo_oop_method_t)ass->value; + if (!moo_putatdic(moo, ciim->_class->mthdic[ciim->mth_type], (moo_oop_t)mth->name, (moo_oop_t)mth)) + { +/* TODO: error handling. GC safety, etc */ + } + + return 0; + } + moo_setsynerrbfmt (moo, MOO_SYNERR_CLASSNCIFCE, MOO_NULL, MOO_NULL, "%.*js not implementing %.*js>>%.*js", MOO_OBJ_GET_SIZE(ciim->_class->name), MOO_OBJ_GET_CHAR_SLOT(ciim->_class->name), @@ -9112,6 +9102,13 @@ static int ciim_on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_associati ); return -1; } + else + { + /* TODO: + * if the method is found in the class chain, also check if the method found + * has been taken from the interface. if so, multiple interfaces are defining + * the method. it's an error */ + } sig = (moo_oop_methsig_t)ass->value; if (MOO_METHOD_GET_PREAMBLE_FLAGS(MOO_OOP_TO_SMOOI(mth->preamble)) != MOO_METHOD_GET_PREAMBLE_FLAGS(MOO_OOP_TO_SMOOI(sig->preamble))) diff --git a/moo/lib/dic.c b/moo/lib/dic.c index c453e1b..7a945d4 100644 --- a/moo/lib/dic.c +++ b/moo/lib/dic.c @@ -345,21 +345,26 @@ int moo_walkdic (moo_t* moo, moo_oop_dic_t dic, moo_dic_walker_t walker, void* c moo_oow_t index, count; moo_oop_association_t ass; + moo_pushvolat (moo, &dic); /* in case the walker function triggers GC */ count = MOO_OBJ_GET_SIZE(dic->bucket); for (index = 0; index < count; index++) { ass = (moo_oop_association_t)MOO_OBJ_GET_OOP_VAL(dic->bucket, index); if ((moo_oop_t)ass != moo->_nil) { - MOO_ASSERT (moo, MOO_CLASSOF(moo,ass) == moo->_association); /*MOO_ASSERT (moo, MOO_CLASSOF(moo,ass->key) == moo->_symbol);*/ MOO_ASSERT (moo, MOO_OBJ_IS_CHAR_POINTER(ass->key)); - if (walker(moo, dic, ass, ctx) <= -1) return -1; + if (walker(moo, dic, ass, ctx) <= -1) + { + moo_popvolat (moo); + return -1; + } } } + moo_popvolat (moo); return 0; }