diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 8f7efe3..6febb5c 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -3201,8 +3201,8 @@ static moo_oop_nsdic_t add_namespace (moo_t* moo, moo_oop_nsdic_t dic, const moo if (!ass) goto oops; nsdic = (moo_oop_nsdic_t)ass->value; - nsdic->nsup = (moo_oop_t)dic; - nsdic->name = sym; + MOO_STORE_OOP (moo, &nsdic->nsup, (moo_oop_t)dic); + MOO_STORE_OOP (moo, (moo_oop_t*)&nsdic->name, (moo_oop_t)sym); moo_popvolats (moo, tmp_count); return nsdic; @@ -3222,8 +3222,8 @@ static moo_oop_nsdic_t attach_nsdic_to_class (moo_t* moo, moo_oop_class_t c) nsdic = moo_makensdic(moo, moo->_namespace, NAMESPACE_SIZE); if (!nsdic) goto oops; - nsdic->nsup = (moo_oop_t)c; /* it points to the owning class as it belongs to a class */ - nsdic->name = c->name; /* for convenience only */ + MOO_STORE_OOP (moo, &nsdic->nsup, (moo_oop_t)c); /* it points to the owning class as it belongs to a class */ + MOO_STORE_OOP (moo, (moo_oop_t*)&nsdic->name, (moo_oop_t)c->name); /* for convenience only */ c->nsdic = nsdic; moo_popvolats (moo, tmp_count); @@ -6632,8 +6632,8 @@ static int add_compiled_method (moo_t* moo) MOO_ASSERT (moo, MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(preamble_index)); - mth->owner = cc->self_oop; - mth->name = name; + 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_data[0] = MOO_SMOOI_TO_OOP(0); mth->preamble_data[1] = MOO_SMOOI_TO_OOP(0);*/ @@ -6645,7 +6645,7 @@ static int add_compiled_method (moo_t* moo) #if defined(MOO_USE_METHOD_TRAILER) /* do nothing */ #else - mth->code = code; + MOO_STORE_OOP (moo, (moo_oop_t*)&mth->code, (moo_oop_t)code); #endif /*TODO: preserve source??? mth->text = cc->mth.text @@ -8342,8 +8342,8 @@ static int add_method_signature (moo_t* moo) if (!mth) goto oops; moo_pushvolat (moo, (moo_oop_t*)&mth); tmp_count++; - mth->owner = ifce->self_oop; - mth->name = name; + MOO_STORE_OOP (moo, (moo_oop_t*)&mth->owner, (moo_oop_t)ifce->self_oop); + MOO_STORE_OOP (moo, (moo_oop_t*)&mth->name, (moo_oop_t)name); preamble_flags |= ifce->mth.variadic; /* MOO_METHOD_PREAMBLE_FLAG_VARIADIC or MOO_METHOD_PREAMBLE_FLAG_LIBERAL */ if (ifce->mth.lenient) preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_LENIENT; @@ -8429,18 +8429,18 @@ static int make_defined_interface (moo_t* moo) tmp = moo_makesymbol(moo, ifce->name.ptr, ifce->name.len); if (!tmp) return -1; - ifce->self_oop->name = (moo_oop_char_t)tmp; + MOO_STORE_OOP (moo, (moo_oop_t*)&ifce->self_oop->name, tmp); tmp = (moo_oop_t)moo_makedic(moo, moo->_method_dictionary, INSTANCE_METHOD_DICTIONARY_SIZE); if (!tmp) return -1; - ifce->self_oop->mthdic[MOO_METHOD_INSTANCE] = (moo_oop_dic_t)tmp; + MOO_STORE_OOP (moo, (moo_oop_t*)&ifce->self_oop->mthdic[MOO_METHOD_INSTANCE], tmp); tmp = (moo_oop_t)moo_makedic(moo, moo->_method_dictionary, CLASS_METHOD_DICTIONARY_SIZE); if (!tmp) return -1; - ifce->self_oop->mthdic[MOO_METHOD_CLASS] = (moo_oop_dic_t)tmp; + MOO_STORE_OOP (moo, (moo_oop_t*)&ifce->self_oop->mthdic[MOO_METHOD_CLASS], tmp); if (!moo_putatdic(moo, (moo_oop_dic_t)ifce->ns_oop, (moo_oop_t)ifce->self_oop->name, (moo_oop_t)ifce->self_oop)) return -1; - ifce->self_oop->nsup = ifce->ns_oop; + MOO_STORE_OOP (moo, (moo_oop_t*)&ifce->self_oop->nsup, (moo_oop_t)ifce->ns_oop); return 0; } diff --git a/moo/lib/dic.c b/moo/lib/dic.c index 0c4bca9..0ee6353 100644 --- a/moo/lib/dic.c +++ b/moo/lib/dic.c @@ -92,7 +92,7 @@ static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_dic_t dic, moo_ moo_ooi_t tally; moo_oow_t hv, index; moo_oop_association_t ass; - moo_oow_t tmp_count = 0; + moo_oow_t volat_count = 0; /* the builtin dictionary is not a generic dictionary. * it accepts only a symbol or something similar as a key. */ @@ -142,9 +142,9 @@ static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_dic_t dic, moo_ return MOO_NULL; } - moo_pushvolat (moo, (moo_oop_t*)&dic); tmp_count++; - moo_pushvolat (moo, (moo_oop_t*)&key); tmp_count++; - moo_pushvolat (moo, &value); tmp_count++; + moo_pushvolat (moo, (moo_oop_t*)&dic); volat_count++; + moo_pushvolat (moo, (moo_oop_t*)&key); volat_count++; + moo_pushvolat (moo, &value); volat_count++; /* no conversion to moo_oow_t is necessary for tally + 1. * the maximum value of tally is checked to be MOO_SMOOI_MAX - 1. @@ -152,7 +152,7 @@ static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_dic_t dic, moo_ * MOO_SMOOI_MAX is way smaller than MOO_TYPE_MAX(moo_ooi_t). */ if (tally + 1 >= MOO_OBJ_GET_SIZE(dic->bucket)) { - moo_oop_oop_t bucket; + moo_oop_oop_t tmp; /* TODO: make the growth policy configurable instead of growing it just before it gets full. The polcy can be grow it @@ -162,10 +162,10 @@ static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_dic_t dic, moo_ * make sure that it has at least one free slot left * after having added a new symbol. this is to help * traversal end at a _nil slot if no entry is found. */ - bucket = expand_bucket(moo, dic->bucket); - if (!bucket) goto oops; + tmp = expand_bucket(moo, dic->bucket); + if (!tmp) goto oops; - MOO_STORE_OOP (moo, &dic->bucket, bucket); + MOO_STORE_OOP (moo, (moo_oop_t*)&dic->bucket, (moo_oop_t)tmp); /* recalculate the index for the expanded bucket */ index = hv % MOO_OBJ_GET_SIZE(dic->bucket); @@ -188,11 +188,11 @@ static moo_oop_association_t find_or_upsert (moo_t* moo, moo_oop_dic_t dic, moo_ dic->tally = MOO_SMOOI_TO_OOP(tally + 1); /* no need to use MOO_STORE_OOP as the value is not a pointer object */ MOO_STORE_OOP (moo, MOO_OBJ_GET_OOP_PTR(dic->bucket, index), (moo_oop_t)ass); - moo_popvolats (moo, tmp_count); + moo_popvolats (moo, volat_count); return ass; oops: - moo_popvolats (moo, tmp_count); + moo_popvolats (moo, volat_count); return MOO_NULL; } @@ -380,7 +380,7 @@ moo_oop_dic_t moo_makedic (moo_t* moo, moo_oop_class_t _class, moo_oow_t size) if (!tmp) return MOO_NULL; dic->tally = MOO_SMOOI_TO_OOP(0); - dic->bucket = (moo_oop_oop_t)tmp; + MOO_STORE_OOP (moo, (moo_oop_t*)&dic->bucket, tmp); MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(dic) == MOO_CLASS_SPEC_NAMED_INSTVARS(MOO_OOP_TO_SMOOI(_class->spec))); MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(dic->bucket) == size); diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 9a1c16e..5908139 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -93,7 +93,7 @@ static MOO_INLINE const char* proc_state_to_string (int state) (moo)->active_method = (moo_oop_method_t)(moo)->active_context->origin->method_or_nargs; \ (moo)->active_code = MOO_METHOD_GET_CODE_BYTE((moo)->active_method); \ LOAD_ACTIVE_IP (moo); \ - (moo)->processor->active->current_context = (moo)->active_context; \ + MOO_STORE_OOP (moo, (moo_oop_t*)&(moo)->processor->active->current_context, (moo_oop_t)(moo)->active_context); \ } while (0) #define FETCH_BYTE_CODE(moo) ((moo)->active_code[(moo)->ip++]) @@ -2089,7 +2089,7 @@ static moo_pfrc_t pf_context_goto (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) return MOO_PF_FAILURE; } - ((moo_oop_context_t)rcv)->ip = pc; + ((moo_oop_context_t)rcv)->ip = pc; /* no need to MOO_STORE_OOP as pc is a small integer */ LOAD_ACTIVE_IP (moo); MOO_ASSERT (moo, nargs + 1 == 2); @@ -2164,8 +2164,8 @@ static moo_pfrc_t __block_value (moo_t* moo, moo_oop_context_t rcv_blkctx, moo_o MOO_STORE_OOP (moo, MOO_OBJ_GET_OOP_PTR(blkctx, i), MOO_OBJ_GET_OOP_VAL(rcv_blkctx, i)); } #else - blkctx->ip = rcv_blkctx->ip; - blkctx->ntmprs = rcv_blkctx->ntmprs; + blkctx->ip = rcv_blkctx->ip; /* no MOO_STORE_OOP() as it's a small integer */ + blkctx->ntmprs = rcv_blkctx->ntmprs; /* no MOO_STORE_OOP() as it's a small integer */ MOO_STORE_OOP (moo, &blkctx->method_or_nargs, rcv_blkctx->method_or_nargs); MOO_STORE_OOP (moo, &blkctx->receiver_or_source, (moo_oop_t)rcv_blkctx); MOO_STORE_OOP (moo, &blkctx->home, rcv_blkctx->home); @@ -3982,10 +3982,12 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs) tmp = moo_makestring(moo, moo->errmsg.buf, moo->errmsg.len); moo_popvolat (moo); /* [NOTE] carry on even if instantiation fails */ - moo->processor->active->perrmsg = tmp? tmp: moo->_nil; /* TODO: set to nil or set to an empty string if instantiation fails? */ + if (!tmp) goto no_perrmsg; + MOO_STORE_OOP (moo, &moo->processor->active->perrmsg, tmp); } else { + no_perrmsg: moo->processor->active->perrmsg = moo->_nil; } diff --git a/moo/lib/gc.c b/moo/lib/gc.c index 297099c..9116150 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -489,13 +489,32 @@ static int ignite_1 (moo_t* moo) static int ignite_2 (moo_t* moo) { moo_oop_t tmp; + int old_igniting = moo->igniting; /* Create 'true' and 'false objects */ moo->_true = moo_instantiate(moo, moo->_true_class, MOO_NULL, 0); moo->_false = moo_instantiate(moo, moo->_false_class, MOO_NULL, 0); if (!moo->_true || !moo->_false) return -1; -moo->igniting = 0; + /* Prevent the object instations in the permspace. + * + * 1. The symbol table is big and it may resize after ignition. + * the resizing operation will migrate the obejct out of the + * permspace. The space taken by the symbol table and the + * system dictionary is wasted. I'd rather allocate these + * in the normal space. + * + * 2. For compact_symbol_table() to work properly, moo_gc() must not + * scan the symbol table before it executes compact_symbol_table(). + * since moo_gc() scans the entire perspace, it naturally gets to + * moo->symtab, which causes problems in compact_symbol_table(). + * I may reserve a special space for only the symbol table + * to overcome this issue. + * + * For now, let's just allocate the symbol table and the system dictionary + * in the normal space */ + moo->igniting = 0; + /* Create the symbol table */ tmp = moo_instantiate(moo, moo->_symbol_table, MOO_NULL, 0); if (!tmp) return -1; @@ -510,13 +529,14 @@ moo->igniting = 0; tmp = moo_instantiate(moo, moo->_array, MOO_NULL, moo->option.dfl_symtab_size); if (!tmp) return -1; moo->symtab->bucket = (moo_oop_oop_t)tmp; -moo->igniting = 1; /* Create the system dictionary */ tmp = (moo_oop_t)moo_makensdic(moo, moo->_namespace, moo->option.dfl_sysdic_size); if (!tmp) return -1; moo->sysdic = (moo_oop_nsdic_t)tmp; + moo->igniting = old_igniting; /* back to the permspace */ + /* Create a nil process used to simplify nil check in GC. * only accessible by VM. not exported via the global dictionary. */ tmp = (moo_oop_t)moo_instantiate(moo, moo->_process, MOO_NULL, 0); @@ -558,17 +578,17 @@ static int ignite_3 (moo_t* moo) cls = *(moo_oop_class_t*)((moo_uint8_t*)moo + kernel_classes[i].offset); MOO_STORE_OOP (moo, (moo_oop_t*)&cls->name, sym); - cls->nsup = moo->sysdic; + MOO_STORE_OOP (moo, (moo_oop_t*)&cls->nsup, (moo_oop_t)moo->sysdic); if (!moo_putatsysdic(moo, sym, (moo_oop_t)cls)) return -1; } /* Attach the system dictionary to the nsdic field of the System class */ - moo->_system->nsdic = moo->sysdic; + MOO_STORE_OOP (moo, (moo_oop_t*)&moo->_system->nsdic, (moo_oop_t)moo->sysdic); /* Set the name field of the system dictionary */ - moo->sysdic->name = moo->_system->name; + MOO_STORE_OOP (moo, (moo_oop_t*)&moo->sysdic->name, (moo_oop_t)moo->_system->name); /* Set the owning class field of the system dictionary, it's circular here */ - moo->sysdic->nsup = (moo_oop_t)moo->_system; + MOO_STORE_OOP (moo, (moo_oop_t*)&moo->sysdic->nsup, (moo_oop_t)moo->_system); /* Make the process scheduler avaialble as the global name 'Processor' */ sym = moo_makesymbol(moo, str_processor, MOO_COUNTOF(str_processor)); diff --git a/moo/lib/sym.c b/moo/lib/sym.c index d4aa492..58b2368 100644 --- a/moo/lib/sym.c +++ b/moo/lib/sym.c @@ -130,7 +130,7 @@ static moo_oop_t find_or_make_symbol (moo_t* moo, const moo_ooch_t* ptr, moo_oow * MOO_SMOOI_MAX is way smaller than MOO_TYPE_MAX(moo_ooi_t). */ if (tally + 1 >= MOO_OBJ_GET_SIZE(moo->symtab->bucket)) { - moo_oop_oop_t bucket; + moo_oop_oop_t tmp; /* TODO: make the growth policy configurable instead of growing it just before it gets full. The polcy can be grow it @@ -140,10 +140,10 @@ static moo_oop_t find_or_make_symbol (moo_t* moo, const moo_ooch_t* ptr, moo_oow * make sure that it has at least one free slot left * after having added a new symbol. this is to help * traversal end at a _nil slot if no entry is found. */ - bucket = expand_bucket(moo, moo->symtab->bucket); - if (!bucket) return MOO_NULL; + tmp = expand_bucket(moo, moo->symtab->bucket); + if (!tmp) return MOO_NULL; - moo->symtab->bucket = bucket; + MOO_STORE_OOP (moo, (moo_oop_t*)&moo->symtab->bucket, (moo_oop_t)tmp); /* recalculate the index for the expanded bucket */ index = moo_hashoochars(ptr, len) % MOO_OBJ_GET_SIZE(moo->symtab->bucket); diff --git a/moo/mod/x11.c b/moo/mod/x11.c index 1f36e7e..8e536a4 100644 --- a/moo/mod/x11.c +++ b/moo/mod/x11.c @@ -223,7 +223,7 @@ static moo_pfrc_t pf_get_llevent (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs) e->window = MOO_SMOOI_TO_OOP(0); /* if the following is going to trigger GC directly or indirectly, - * e must be proteced with moo_pushtmp(). + * e must be proteced with moo_pushvolat(). * also x11, tr must be refetched from the stack. */ switch (event->type) @@ -812,7 +812,7 @@ static void gc_mod_x11 (moo_t* moo, moo_mod_t* mod) x11_modctx_t* ctx = mod->ctx; MOO_ASSERT (moo, ctx != MOO_NULL); - ctx->x11_class = (moo_oop_class_t)moo_moveoop (moo, (moo_oop_t)ctx->x11_class); + ctx->x11_class = (moo_oop_class_t)moo_moveoop(moo, (moo_oop_t)ctx->x11_class); } int moo_mod_x11 (moo_t* moo, moo_mod_t* mod) @@ -825,20 +825,22 @@ int moo_mod_x11 (moo_t* moo, moo_mod_t* mod) else { x11_modctx_t* ctx; + moo_oop_t tmp; static moo_ooch_t name_x11[] = { 'X','1','1','\0' }; ctx = moo_callocmem (moo, MOO_SIZEOF(*ctx)); if (!ctx) return -1; - ctx->x11_class = (moo_oop_class_t)moo_findclass (moo, moo->sysdic, name_x11); - if (!ctx->x11_class) + tmp = moo_findclass(moo, moo->sysdic, name_x11); + if (!tmp) { /* Not a single X11.XXX has been defined. */ MOO_DEBUG0 (moo, "X11 class not found\n"); moo_freemem (moo, ctx); return -1; } + MOO_STORE_OOP (moo, (moo_oop_t*)&ctx->x11_class, tmp); mod->gc = gc_mod_x11; mod->ctx = ctx;