summaryrefslogtreecommitdiffstats
path: root/struct.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-11-23 20:59:43 -0800
committerKaz Kylheku <kaz@kylheku.com>2015-11-23 20:59:43 -0800
commit3343e230783eefbf3c479f00e46164a2407c2019 (patch)
treebb05c593035819eac2a76aa0c518c37e9986a1fa /struct.c
parent9c050d2fdca0b4fa525a3dc6d99cec9d17ec703e (diff)
downloadtxr-3343e230783eefbf3c479f00e46164a2407c2019.tar.gz
txr-3343e230783eefbf3c479f00e46164a2407c2019.tar.bz2
txr-3343e230783eefbf3c479f00e46164a2407c2019.zip
Struct instances now point directly to low level type.
This change eliminates numerous cast expressions and a pointer chase from some operations, though some, like the struct_type function, end up chasing an extra pointer. * struct.c (struct struct_type): New member, self. (struct struct_inst): Type member changed from val to struct struct_type *. (make_struct_type): Initialize new self member. (super): Obtain type from si->type->self rather than si->type. There appears to be a bug here. (make_struct, lazy_struct_init): Initialize type field with struct pointer rather than type object. Add an assertion which references the type parameter, to prevent the cobj call from garbage collecting type. (copy_struct, clear_struct, replace_struct, reset_struct, (lookup_slot, slot, slotset, struct_type, uslot_fun, umethod_fun, struct_inst_print, struct_inst_mark, struct_inst_equal, struct_inst_hash, struct_inst_equalsub): All updated to new way of referencing type structure and type object.
Diffstat (limited to 'struct.c')
-rw-r--r--struct.c70
1 files changed, 35 insertions, 35 deletions
diff --git a/struct.c b/struct.c
index 5ccd68b7..187c4618 100644
--- a/struct.c
+++ b/struct.c
@@ -51,6 +51,7 @@
#define STATIC_SLOT_BASE 0x10000000
struct struct_type {
+ val self;
val name;
cnum id;
cnum nslots;
@@ -67,7 +68,7 @@ struct struct_type {
};
struct struct_inst {
- val type;
+ struct struct_type *type;
cnum id : sizeof (cnum) * CHAR_BIT - 1 ;
unsigned lazy : 1;
val slot[1];
@@ -231,6 +232,7 @@ val make_struct_type(val name, val super,
cnum sl, stsl;
val null_ptr = 0;
+ st->self = stype;
st->name = name;
st->id = c_num(id);
st->nslots = st->nstslots = st->eqmslot = 0;
@@ -302,7 +304,7 @@ val super(val type)
{
if (structp(type)) {
struct struct_inst *si = coerce(struct struct_inst *, type->co.handle);
- return si->type;
+ return si->type->self;
} else {
struct struct_type *st = stype_handle(&type, lit("super"));
return st->super;
@@ -368,13 +370,13 @@ val make_struct(val type, val plist, struct args *args)
for (sl = 0; sl < nslots; sl++)
si->slot[sl] = nil;
- si->type = nil;
+ si->type = st;
si->id = st->id;
si->lazy = 0;
sinst = cobj(coerce(mem_t *, si), st->name, &struct_inst_ops);
- si->type = type;
+ bug_unless (type == st->self);
uw_simple_catch_begin;
@@ -405,7 +407,7 @@ val make_struct(val type, val plist, struct args *args)
static void lazy_struct_init(val sinst, struct struct_inst *si)
{
val self = lit("make-lazy-struct");
- struct struct_type *st = coerce(struct struct_type *, si->type->co.handle);
+ struct struct_type *st = si->type;
volatile val inited = nil;
val cell = funcall(si->slot[0]);
cons_bind (plist, args, cell);
@@ -459,13 +461,14 @@ val make_lazy_struct(val type, val argfun)
for (sl = 0; sl < nslots; sl++)
si->slot[sl] = nil;
- si->type = nil;
+ si->type = st;
si->id = st->id;
si->lazy = 1;
sinst = cobj(coerce(mem_t *, si), st->name, &struct_inst_ops);
- si->type = type;
+ bug_unless (type == st->self);
+
si->slot[0] = argfun;
return sinst;
@@ -484,7 +487,7 @@ val copy_struct(val strct)
const val self = lit("copy-struct");
val copy;
struct struct_inst *si = struct_handle(strct, self);
- struct struct_type *st = coerce(struct struct_type *, si->type->co.handle);
+ struct struct_type *st = si->type;
cnum nslots = st->nslots;
size_t size = offsetof(struct struct_inst, slot) + sizeof (val) * nslots;
struct struct_inst *si_copy = coerce(struct struct_inst *, chk_malloc(size));
@@ -499,7 +502,7 @@ val clear_struct(val strct, val value)
{
const val self = lit("clear-struct");
struct struct_inst *si = struct_handle(strct, self);
- struct struct_type *st = coerce(struct struct_type *, si->type->co.handle);
+ struct struct_type *st = si->type;
val clear_val = default_bool_arg(value);
cnum i;
@@ -516,7 +519,7 @@ val replace_struct(val target, val source)
const val self = lit("replace-struct");
struct struct_inst *tsi = struct_handle(target, self);
struct struct_inst *ssi = struct_handle(source, self);
- struct struct_type *sst = coerce(struct struct_type *, ssi->type->co.handle);
+ struct struct_type *sst = ssi->type;
cnum nslots = sst->nslots;
size_t size = offsetof(struct struct_inst, slot) + sizeof (val) * nslots;
struct struct_inst *ssi_copy = coerce(struct struct_inst *, chk_malloc(size));
@@ -535,7 +538,7 @@ val reset_struct(val strct)
{
const val self = lit("reset-struct");
struct struct_inst *si = struct_handle(strct, self);
- struct struct_type *st = coerce(struct struct_type *, si->type->co.handle);
+ struct struct_type *st = si->type;
cnum i;
check_init_lazy_struct(strct, si);
@@ -606,9 +609,8 @@ static loc lookup_slot(val inst, struct struct_inst *si, val sym)
cnum slot = cache_set_lookup(*set, id);
if (slot >= STATIC_SLOT_BASE) {
- val type = si->type;
- struct struct_type *st = coerce(struct struct_type *, type->co.handle);
- return mkloc(st->stslot[slot - STATIC_SLOT_BASE], type);
+ struct struct_type *st = si->type;
+ return mkloc(st->stslot[slot - STATIC_SLOT_BASE], st->self);
} else if (slot >= 0) {
return mkloc(si->slot[slot], inst);
} else {
@@ -618,9 +620,8 @@ static loc lookup_slot(val inst, struct struct_inst *si, val sym)
if (sl) {
cache_set_insert(*set, id, slnum);
if (slnum >= STATIC_SLOT_BASE) {
- val type = si->type;
- struct struct_type *st = coerce(struct struct_type *, type->co.handle);
- return mkloc(st->stslot[slnum - STATIC_SLOT_BASE], type);
+ struct struct_type *st = si->type;
+ return mkloc(st->stslot[slnum - STATIC_SLOT_BASE], st->self);
}
return mkloc(si->slot[slnum], inst);
}
@@ -639,9 +640,8 @@ static loc lookup_slot(val inst, struct struct_inst *si, val sym)
if (sl) {
cache_set_insert(*set, id, slnum);
if (slnum >= STATIC_SLOT_BASE) {
- val type = si->type;
- struct struct_type *st = coerce(struct struct_type *, type->co.handle);
- return mkloc(st->stslot[slnum - STATIC_SLOT_BASE], type);
+ struct struct_type *st = si->type;
+ return mkloc(st->stslot[slnum - STATIC_SLOT_BASE], st->self);
}
return mkloc(si->slot[slnum], inst);
}
@@ -709,7 +709,7 @@ val slot(val strct, val sym)
return deref(ptr);
}
- no_such_slot(self, si->type, sym);
+ no_such_slot(self, si->type->self, sym);
}
val slotset(val strct, val sym, val newval)
@@ -723,7 +723,7 @@ val slotset(val strct, val sym, val newval)
return set(ptr, newval);
}
- no_such_slot(self, si->type, sym);
+ no_such_slot(self, si->type->self, sym);
}
val static_slot(val stype, val sym)
@@ -859,7 +859,7 @@ val struct_type(val strct)
{
const val self = lit("struct-type");
struct struct_inst *si = struct_handle(strct, self);
- return si->type;
+ return si->type->self;
}
static val method_fun(val env, varg args)
@@ -893,7 +893,7 @@ static val uslot_fun(val sym, val strct)
return deref(ptr);
}
- no_such_slot(self, si->type, sym);
+ no_such_slot(self, si->type->self, sym);
}
val uslot(val slot)
@@ -918,7 +918,7 @@ static val umethod_fun(val sym, struct args *args)
return generic_funcall(deref(ptr), args);
}
- no_such_slot(self, si->type, sym);
+ no_such_slot(self, si->type->self, sym);
}
}
@@ -930,7 +930,7 @@ val umethod(val slot)
static void struct_inst_print(val obj, val out, val pretty)
{
struct struct_inst *si = coerce(struct struct_inst *, obj->co.handle);
- struct struct_type *st = coerce(struct struct_type *, si->type->co.handle);
+ struct struct_type *st = si->type;
val save_mode = test_set_indent_mode(out, num_fast(indent_off),
num_fast(indent_data));
val save_indent, iter, once;
@@ -941,7 +941,7 @@ static void struct_inst_print(val obj, val out, val pretty)
for (iter = st->slots, once = t; iter; iter = cdr(iter)) {
val sym = car(iter);
- if (!static_slot_p(si->type, sym)) {
+ if (!static_slot_p(st->self, sym)) {
if (once) {
put_char(chr(' '), out);
once = nil;
@@ -961,7 +961,7 @@ static void struct_inst_print(val obj, val out, val pretty)
static void struct_inst_mark(val obj)
{
struct struct_inst *si = coerce(struct struct_inst *, obj->co.handle);
- struct struct_type *st = coerce(struct struct_type *, si->type->co.handle);
+ struct struct_type *st = si->type;
cnum sl, nslots = st->nslots;
if (si->lazy)
@@ -969,17 +969,17 @@ static void struct_inst_mark(val obj)
for (sl = 0; sl < nslots; sl++)
gc_mark(si->slot[sl]);
- gc_mark(si->type);
+ gc_mark(st->self);
}
static val struct_inst_equal(val left, val right)
{
struct struct_inst *ls = coerce(struct struct_inst *, left->co.handle);
struct struct_inst *rs = coerce(struct struct_inst *, right->co.handle);
- struct struct_type *st = coerce(struct struct_type *, ls->type->co.handle);
+ struct struct_type *st = ls->type;
cnum nslots = st->nslots, sl;
- if (rs->type != ls->type)
+ if (st != rs->type)
return nil;
check_init_lazy_struct(left, ls);
@@ -997,8 +997,8 @@ static val struct_inst_equal(val left, val right)
static cnum struct_inst_hash(val obj)
{
struct struct_inst *si = coerce(struct struct_inst *, obj->co.handle);
- struct struct_type *st = coerce(struct struct_type *, si->type->co.handle);
- cnum nslots = st->nslots, sl, out = c_num(hash_equal(si->type));
+ struct struct_type *st = si->type;
+ cnum nslots = st->nslots, sl, out = c_num(hash_equal(st->self));
check_init_lazy_struct(obj, si);
@@ -1031,13 +1031,13 @@ static val get_equal_method(val stype, struct struct_type *st)
static val struct_inst_equalsub(val obj)
{
struct struct_inst *si = coerce(struct struct_inst *, obj->co.handle);
- struct struct_type *st = coerce(struct struct_type *, si->type->co.handle);
+ struct struct_type *st = si->type;
val equal_method = get_equal_method(obj, st);
if (equal_method) {
val sub = funcall1(equal_method, obj);
if (nilp(sub)) {
uw_throwf(error_s, lit("equal method on type ~s returned nil"),
- si->type, nao);
+ st->self, nao);
}
return sub;
}