klisp

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

commit 9b4983c0ff03dfb6f205462c2a6f10581fdde7b8
parent 206e48f43dab4ae854a6d3024b42923e707466bf
Author: Andres Navarro <canavarro82@gmail.com>
Date:   Wed, 20 Apr 2011 10:40:38 -0300

Added assertions to kpair and added new set_car/cdr_unsafe for setting potentially immutable pairs (like in read and copy-es-immutable).

Diffstat:
Msrc/kgcombiners.c | 2+-
Msrc/kgenv_mut.h | 6++++--
Msrc/kgpair_mut.c | 6++++--
Msrc/kgports.c | 2+-
Msrc/kpair.c | 2+-
Msrc/kpair.h | 56+++++++++++++++++++++++++++++++++++++++++++++++++-------
Msrc/kread.c | 8++++----
7 files changed, 64 insertions(+), 18 deletions(-)

diff --git a/src/kgcombiners.c b/src/kgcombiners.c @@ -500,7 +500,7 @@ void do_map_cycle(klisp_State *K, TValue *xparams, TValue obj) /* 5.9.1 map */ void map(klisp_State *K, TValue *xparams, TValue ptree, TValue denv) { - (void) xparams; + UNUSED(xparams); bind_al1tp(K, "map", ptree, "applicative", ttisapplicative, app, lss); diff --git a/src/kgenv_mut.h b/src/kgenv_mut.h @@ -190,7 +190,8 @@ inline TValue check_copy_ptree(klisp_State *K, char *name, TValue ptree, /* only car was checked (not yet copied) */ if (kis_mutable(top)) { TValue copied_pair = kget_mark(top); - kset_car(copied_pair, copy); + /* copied_pair may be immutable */ + kset_car_unsafe(K, copied_pair, copy); } /* put the copied pair again, continue with the cdr */ ks_tbpush(K, ST_CDR); @@ -205,7 +206,8 @@ inline TValue check_copy_ptree(klisp_State *K, char *name, TValue ptree, kunmark(top); if (kis_mutable(top)) { - kset_cdr(copied_pair, copy); + /* copied_pair may be immutable */ + kset_cdr_unsafe(K, copied_pair, copy); } copy = copied_pair; } diff --git a/src/kgpair_mut.c b/src/kgpair_mut.c @@ -125,7 +125,8 @@ TValue copy_es_immutable_h(klisp_State *K, char *name, TValue obj, } else { /* last action was a pop */ TValue new_pair = kget_mark(top); if (state == ST_CAR) { - kset_car(new_pair, copy); + /* new_pair may be immutable */ + kset_car_unsafe(K, new_pair, copy); /* leave the pair on the stack, continue with the cdr */ ks_spush(K, top); ks_tbpush(K, ST_CDR); @@ -133,7 +134,8 @@ TValue copy_es_immutable_h(klisp_State *K, char *name, TValue obj, ks_spush(K, kcdr(top)); ks_tbpush(K, ST_PUSH); } else { - kset_cdr(new_pair, copy); + /* new_pair may be immutable */ + kset_cdr_unsafe(K, new_pair, copy); copy = new_pair; } } diff --git a/src/kgports.c b/src/kgports.c @@ -394,7 +394,7 @@ TValue read_all_expr(klisp_State *K, TValue port) return kcutoff_dummy1(K); } else { TValue new_pair = kimm_cons(K, obj, KNIL); - kset_cdr(tail, new_pair); + kset_cdr_unsafe(K, tail, new_pair); tail = new_pair; } } diff --git a/src/kpair.c b/src/kpair.c @@ -47,7 +47,7 @@ TValue klist_g(klisp_State *K, bool m, int32_t n, ...) for (int i = 0; i < n; i++) { TValue next_car = va_arg(argp, TValue); TValue np = kcons_g(K, m, next_car, KNIL); - kset_cdr(tail, np); + kset_cdr_unsafe(K, tail, np); tail = np; } va_end(argp); diff --git a/src/kpair.h b/src/kpair.h @@ -10,10 +10,27 @@ #include "kobject.h" #include "kstate.h" #include "klimits.h" +#include "kgc.h" -/* TODO: add type assertions */ -#define kcar(p_) (tv2pair(p_)->car) -#define kcdr(p_) (tv2pair(p_)->cdr) +/* can't be inlined... */ +bool kpairp(TValue obj); + +inline bool kmutable_pairp(TValue obj) +{ + return ttispair(obj) && kis_mutable(obj); +} + +inline TValue kcar(TValue p) +{ + klisp_assert(kpairp(p)); + return tv2pair(p)->car; +} + +inline TValue kcdr(TValue p) +{ + klisp_assert(kpairp(p)); + return tv2pair(p)->cdr; +} #define kcaar(p_) (kcar(kcar(p_))) #define kcadr(p_) (kcar(kcdr(p_))) @@ -48,8 +65,35 @@ #define kcddddr(p_) (kcdr(kcdr(kcdr(kcdr(p_))))) /* these will also work with immutable pairs */ -#define kset_car(p_, v_) (kcar(p_) = (v_)) -#define kset_cdr(p_, v_) (kcdr(p_) = (v_)) +inline void kset_car(TValue p, TValue v) +{ + klisp_assert(kmutable_pairp(p)); + tv2pair(p)->car = v; +} + +inline void kset_cdr(TValue p, TValue v) +{ + klisp_assert(kmutable_pairp(p)); + tv2pair(p)->cdr = v; +} + +/* These two are the same but can write immutable pairs, + use with care */ +inline void kset_car_unsafe(klisp_State *K, TValue p, TValue v) +{ + klisp_assert(kpairp(p)); + UNUSED(K); +/* klispC_barrier(K, gcvalue(p), v); */ + tv2pair(p)->car = v; +} + +inline void kset_cdr_unsafe(klisp_State *K, TValue p, TValue v) +{ + klisp_assert(kpairp(p)); + UNUSED(K); +/* klispC_barrier(K, gcvalue(p), v); */ + tv2pair(p)->cdr = v; +} /* GC: assumes car & cdr are rooted */ TValue kcons_g(klisp_State *K, bool m, TValue car, TValue cdr); @@ -66,8 +110,6 @@ TValue klist_g(klisp_State *K, bool m, int32_t n, ...); #define kget_source_info(p_) (UNUSED(p_), KNIL) #define kset_source_info(K_, p_, si_) (UNUSED(K_), UNUSED(p_), UNUSED(si_)) -bool kpairp(TValue obj); - inline TValue kget_dummy1(klisp_State *K) { klisp_assert(ttispair(K->dummy_pair1) && ttisnil(kcdr(K->dummy_pair1))); diff --git a/src/kread.c b/src/kread.c @@ -110,7 +110,7 @@ void try_shared_def(klisp_State *K, TValue def_token, TValue value) TValue new_tok = kcons(K, kcdr(def_token), value); krooted_tvs_push(K, new_tok); - K->shared_dict = kcons(K, new_tok, K->shared_dict); /* value is protected by cons */ + K->shared_dict = kcons(K, new_tok, K->shared_dict); krooted_tvs_pop(K); return; } @@ -392,7 +392,7 @@ TValue kread_fsm(klisp_State *K) times */ TValue fp_old_si = kget_source_info(fp); kset_source_info(K, fp, obj_si); - kset_car(fp, obj); + kset_car_unsafe(K, fp, obj); /* continue reading objects of list */ /* save first & last pair of the (still incomplete) list */ @@ -412,7 +412,7 @@ TValue kread_fsm(klisp_State *K) TValue np = kcons_g(K, K->read_mconsp, obj, KNIL); krooted_tvs_push(K, np); kset_source_info(K, np, obj_si); - kset_cdr(get_data(K), np); + kset_cdr_unsafe(K, get_data(K), np); /* replace last pair of the (still incomplete) read next obj */ pop_data(K); push_data(K, np); @@ -425,7 +425,7 @@ TValue kread_fsm(klisp_State *K) /* only change the state, keep the pair data to simplify the close paren code (same as for ST_MIDDLE_LIST) */ pop_state(K); - kset_cdr(get_data(K), obj); + kset_cdr_unsafe(K, get_data(K), obj); push_state(K, ST_PAST_LAST_ILIST); read_next_token = true; break;