klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

commit 4630eb4a52d62f77e5355203443ac9543b2f9643
parent 4603438d9197a2f4b2cfcc7785ac271721a58c67
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Fri, 29 Apr 2011 15:33:46 -0300

Changed si mechanism. Now it is tracked in previous padding section of Object header. The table is gone. BUG Pending, GC fails with an assertion marking in tests.

Diffstat:
Msrc/keval.c | 5+++--
Msrc/kgc.c | 6+++++-
Msrc/kgcombiners.c | 5+----
Msrc/kobject.h | 12++++--------
Msrc/kstate.c | 32+-------------------------------
Msrc/kstate.h | 53+++++++++++++++++++++++++++++++++++++++++++----------
6 files changed, 57 insertions(+), 56 deletions(-)

diff --git a/src/keval.c b/src/keval.c @@ -144,8 +144,9 @@ void keval_ofn(klisp_State *K, TValue *xparams, TValue obj, TValue env) switch(ttype(obj)) { case K_TPAIR: { - TValue new_cont = kmake_continuation(K, kget_cc(K), combine_cfn, 3, - kcdr(obj), env, obj); + TValue new_cont = + kmake_continuation(K, kget_cc(K), combine_cfn, 3, kcdr(obj), + env, ktry_get_si(K, obj)); kset_cc(K, new_cont); ktail_eval(K, kcar(obj), env); break; diff --git a/src/kgc.c b/src/kgc.c @@ -235,6 +235,10 @@ static int32_t propagatemark (klisp_State *K) { K->gray = o->gch.gclist; klisp_assert(isgray(o)); gray2black(o); + /* all types have si pointers */ + if (o->gch.si != NULL) { + markobject(K, o->gch.si); + } uint8_t type = o->gch.tt; switch (type) { @@ -552,7 +556,6 @@ static void markroot (klisp_State *K) { /* TEMP: this is quite awfull, think of other way to do this */ /* MAYBE: some of these could be FIXED */ markvalue(K, K->name_table); - markvalue(K, K->si_table); markvalue(K, K->curr_cont); markvalue(K, K->next_obj); markvalue(K, K->next_value); @@ -765,6 +768,7 @@ void klispC_link (klisp_State *K, GCObject *o, uint8_t tt, uint8_t kflags) { o->gch.gct = klispC_white(K); o->gch.tt = tt; o->gch.kflags = kflags; + o->gch.si = NULL; /* NOTE that o->gch.gclist doesn't need to be setted */ } diff --git a/src/kgcombiners.c b/src/kgcombiners.c @@ -61,7 +61,6 @@ void Svau(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) TValue si = kget_csi(K); if (!ttisnil(si)) { krooted_tvs_push(K, new_op); - gcvalue(new_op)->gch.kflags |= K_FLAG_HAS_SI; kset_source_info(K, new_op, si); krooted_tvs_pop(K); } @@ -129,7 +128,6 @@ void wrap(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) TValue si = kget_csi(K); if (!ttisnil(si)) { krooted_tvs_push(K, new_app); - gcvalue(new_app)->gch.kflags |= K_FLAG_HAS_SI; kset_source_info(K, new_app, si); krooted_tvs_pop(K); } @@ -149,7 +147,6 @@ void unwrap(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) /* 5.3.1 $vau */ /* DONE: above, together with 4.10.4 */ - /* 5.3.2 $lambda */ void Slambda(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) { @@ -171,9 +168,9 @@ void Slambda(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) /* save as source code info the info from the expression whose evaluation got us here */ TValue si = kget_csi(K); + if (!ttisnil(si)) { krooted_tvs_push(K, new_app); - gcvalue(new_app)->gch.kflags |= K_FLAG_HAS_SI; kset_source_info(K, new_app, si); krooted_tvs_pop(K); } diff --git a/src/kobject.h b/src/kobject.h @@ -45,7 +45,7 @@ typedef union GCObject GCObject; ** included in other objects) */ #define CommonHeader GCObject *next; uint8_t tt; uint8_t kflags; \ - uint16_t gct; uint32_t padding; GCObject *gclist; + uint16_t gct; GCObject *si; GCObject *gclist; /* NOTE: the gc flags are called marked in lua, but we reserve that them for marks used in cycle traversal. The field kflags is also missing @@ -62,11 +62,7 @@ typedef union GCObject GCObject; ** state struct. Likewise, during the tracing phase, gray objects are linked ** by means of the gclist pointer. Technically this is necessary only for ** objects that have references, but in klisp all objects except strings -** have them so it is easier to just put it here. Re the use of the padding, -** this is necessary (TODO add 32-bit check) in 32 bits because of the packed -** attribute. Otherwise, all TValues would be misaligned. All of this, -** assuming the compiler complies with it, but if not the padding doesn't -** hurt. +** have them so it is easier to just put it here. */ /* @@ -683,9 +679,9 @@ int32_t kmark_count; #define K_FLAG_HAS_SI 0x20 -/* for now only used in assertions to avoid problems */ #define kcan_have_si(o_) (iscollectable(o_)) -#define khas_si(o_) ((tv_get_kflags(o_)) & K_FLAG_HAS_SI) +#define khas_si(o_) ((iscollectable(o_) && \ + (tv_get_kflags(o_)) & K_FLAG_HAS_SI)) #define K_FLAG_IMMUTABLE 0x10 diff --git a/src/kstate.c b/src/kstate.c @@ -132,15 +132,12 @@ klisp_State *klisp_newstate (klisp_Alloc f, void *ud) { K->strt.hash = NULL; klispS_resize(K, MINSTRTABSIZE); - /* initialize name & source code info tables */ + /* initialize name info table */ /* needs weak keys, otherwise every named object would be fixed! */ K->name_table = klispH_new(K, 0, MINNAMETABSIZE, K_FLAG_WEAK_KEYS); - K->si_table = klispH_new(K, 0, MINSITABSIZE, - K_FLAG_WEAK_KEYS); - /* Empty string */ /* MAYBE: fix it so we can remove empty_string from roots */ K->empty_string = kstring_new_b_imm(K, ""); @@ -555,30 +552,3 @@ void klisp_close (klisp_State *K) /* NOTE: this needs to be done "by hand" */ (*(K->frealloc))(K->ud, K, state_size(), 0); } - -#if KTRACK_SI -/* -** Source code tracking -** MAYBE: add source code tracking to symbols -*/ -TValue kget_source_info(klisp_State *K, TValue obj) -{ - const TValue *node = klispH_get(tv2table(K->si_table), obj); - return (node == &kfree)? KNIL : *node; -} - -/* GC: Assumes obj and si are rooted */ -void kset_source_info(klisp_State *K, TValue obj, TValue si) -{ - klisp_assert(kcan_have_si(obj)); - gcvalue(obj)->gch.kflags |= K_FLAG_HAS_SI; - TValue *node = klispH_set(K, tv2table(K->si_table), obj); - *node = si; -} - -TValue kget_csi(klisp_State *K) -{ - return (kcan_have_si(K->next_si))? kget_source_info(K, K->next_si) : KNIL; -} - -#endif /* KTRACK_SI */ diff --git a/src/kstate.h b/src/kstate.h @@ -47,7 +47,6 @@ typedef struct stringtable { struct klisp_State { stringtable strt; /* hash table for immutable strings & symbols */ TValue name_table; /* hash tables for naming objects */ - TValue si_table; /* hash tables for source code info */ TValue curr_cont; /* @@ -61,7 +60,8 @@ struct klisp_State { TValue next_value; /* the value to be passed to the next function */ TValue next_env; /* either NIL or an environment for next operative */ TValue *next_xparams; - TValue next_si; /* The object with the source code info for this call */ + /* TODO replace with GCObject *next_si */ + TValue next_si; /* the source code info for this call */ TValue eval_op; /* the operative for evaluation */ TValue list_app; /* the applicative for list evaluation */ @@ -353,12 +353,40 @@ typedef void (*klisp_Ofunc) (klisp_State *K, TValue *ud, TValue ptree, ** MAYBE: add source code tracking to symbols */ #if KTRACK_SI -TValue kget_source_info(klisp_State *K, TValue pair); -void kset_source_info(klisp_State *K, TValue pair, TValue si); -TValue kget_csi(klisp_State *K); -#endif +inline TValue kget_source_info(klisp_State *K, TValue obj) +{ + UNUSED(K); + klisp_assert(khas_si(obj)); + GCObject *si = gcvalue(obj)->gch.si; + klisp_assert(si != NULL); + return gc2pair(si); +} + +inline void kset_source_info(klisp_State *K, TValue obj, TValue si) +{ + UNUSED(K); + klisp_assert(kcan_have_si(obj)); + klisp_assert(ttisnil(si) || ttispair(si)); + if (ttisnil(si)) { + gcvalue(obj)->gch.si = NULL; + gcvalue(obj)->gch.kflags &= ~(K_FLAG_HAS_SI); + } else { + gcvalue(obj)->gch.si = gcvalue(si); + gcvalue(obj)->gch.kflags |= K_FLAG_HAS_SI; + } +} -#define kget_csi_obj(K_) (K_->next_si) +inline TValue ktry_get_si(klisp_State *K, TValue obj) +{ + UNUSED(K); + return (khas_si(obj))? gc2pair(gcvalue(obj)->gch.si) : KNIL; +} + +inline TValue kget_csi(klisp_State *K) +{ + return K->next_si; +} +#endif /* ** Functions to manipulate the current continuation and calling @@ -387,7 +415,7 @@ inline void klispS_apply_cc(klisp_State *K, TValue val) K->next_env = KNIL; K->next_xparams = cont->extra; K->curr_cont = cont->parent; - K->next_si = K->next_obj; + K->next_si = ktry_get_si(K, K->next_obj); } #define kapply_cc(K_, val_) klispS_apply_cc((K_), (val_)); return @@ -435,12 +463,17 @@ inline void klispS_tail_call_si(klisp_State *K, TValue top, TValue ptree, { klispS_tail_call_si((K_), (op_), (p_), (e_), (si_)); return; } /* if no source info is needed */ -#define ktail_call(K_, op_, p_, e_) (ktail_call_si(K_, op_, p_, e_, KNIL)) +#define ktail_call(K_, op_, p_, e_) \ + { klisp_State *K__ = (K_); \ + TValue op__ = (op_); \ + (ktail_call_si(K__, op__, p_, e_, ktry_get_si(K__, op__))); } \ #define ktail_eval(K_, p_, e_) \ { klisp_State *K__ = (K_); \ TValue p__ = (p_); \ - klispS_tail_call_si(K__, K__->eval_op, p__, (e_), p__); return; } + klispS_tail_call_si(K__, K__->eval_op, p__, (e_), \ + ktry_get_si(K__, p__)); \ + return; } /* helper for continuation->applicative & kcall_cont */ void cont_app(klisp_State *K, TValue *xparams, TValue ptree, TValue denv);