Skip to content

Commit

Permalink
fixed some issues with dynobj field indexes
Browse files Browse the repository at this point in the history
  • Loading branch information
ncannasse committed Sep 19, 2023
1 parent 5845e87 commit 70841db
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 20 deletions.
3 changes: 3 additions & 0 deletions src/hl.h
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,9 @@ typedef struct {
vvirtual *virtuals;
} vdynobj;

#define HL_DYNOBJ_INDEX_SHIFT 17
#define HL_DYNOBJ_INDEX_MASK ((1 << HL_DYNOBJ_INDEX_SHIFT) - 1)

typedef struct _venum {
hl_type *t;
int index;
Expand Down
6 changes: 3 additions & 3 deletions src/std/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ static void hl_buffer_rec( hl_buffer *b, vdynamic *v, vlist *stack ) {
l.next = stack;
f = hl_lookup_find(o->lookup,o->nfields,hl_hash_gen(USTR("__string"),false));
if( f && f->t->kind == HFUN && f->t->fun->nargs == 0 && f->t->fun->ret->kind == HBYTES ) {
vclosure *v = (vclosure*)o->values[f->field_index];
vclosure *v = (vclosure*)o->values[f->field_index&HL_DYNOBJ_INDEX_MASK];
if( v ) {
hl_buffer_str(b, v->hasValue ? ((uchar*(*)(void*))v->fun)(v->value) : ((uchar*(*)())v->fun)());
break;
Expand All @@ -331,14 +331,14 @@ static void hl_buffer_rec( hl_buffer *b, vdynamic *v, vlist *stack ) {
int *indexes = o->nfields <= 128 ? tmp : (int*)hl_gc_alloc_noptr(sizeof(int) * o->nfields);
for(i=0;i<o->nfields;i++) {
hl_field_lookup *f = o->lookup + i;
indexes[((unsigned)f->field_index)>>17] = i;
indexes[((unsigned)f->field_index)>>HL_DYNOBJ_INDEX_SHIFT] = i;
}
for(i=0;i<o->nfields;i++) {
hl_field_lookup *f = o->lookup + indexes[i];
if( i ) hl_buffer_str_sub(b,USTR(", "),2);
hl_buffer_str(b,(uchar*)hl_field_name(f->hashed_name));
hl_buffer_str_sub(b,USTR(" : "),3);
hl_buffer_addr(b, hl_is_ptr(f->t) ? (void*)(o->values + (f->field_index&0x1FFFF)) : (void*)(o->raw_data + (f->field_index&0x1FFFF)), f->t, &l);
hl_buffer_addr(b, hl_is_ptr(f->t) ? (void*)(o->values + (f->field_index&HL_DYNOBJ_INDEX_MASK)) : (void*)(o->raw_data + (f->field_index&HL_DYNOBJ_INDEX_MASK)), f->t, &l);
}
hl_buffer_char(b, '}');
}
Expand Down
26 changes: 12 additions & 14 deletions src/std/obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,10 +495,8 @@ HL_API void hl_init_virtual( hl_type *vt, hl_module_context *ctx ) {
}
}

#define DYNOBJ_INDEX_SHIFT 17
#define DYNOBJ_INDEX_MASK ((1 << DYNOBJ_INDEX_SHIFT) - 1)
#define hl_dynobj_field(o,f) (hl_is_ptr((f)->t) ? (void*)((o)->values + ((f)->field_index&DYNOBJ_INDEX_MASK)) : (void*) ((o)->raw_data + ((f)->field_index&DYNOBJ_INDEX_MASK)))
#define hl_dynobj_order(f) (((unsigned)(f)->field_index) >> DYNOBJ_INDEX_SHIFT)
#define hl_dynobj_field(o,f) (hl_is_ptr((f)->t) ? (void*)((o)->values + ((f)->field_index&HL_DYNOBJ_INDEX_MASK)) : (void*) ((o)->raw_data + ((f)->field_index&HL_DYNOBJ_INDEX_MASK)))
#define hl_dynobj_order(f) (((unsigned)(f)->field_index) >> HL_DYNOBJ_INDEX_SHIFT)

vdynamic *hl_virtual_make_value( vvirtual *v ) {
vdynobj *o;
Expand All @@ -521,8 +519,8 @@ vdynamic *hl_virtual_make_value( vvirtual *v ) {
f->field_index = raw_size;
raw_size += hl_type_size(f->t);
}
if( f->field_index > DYNOBJ_INDEX_MASK ) hl_error("Too many dynobj fields");
f->field_index |= (i << DYNOBJ_INDEX_SHIFT);
if( f->field_index > HL_DYNOBJ_INDEX_MASK ) hl_error("Too many dynobj fields");
f->field_index |= (i << HL_DYNOBJ_INDEX_SHIFT);
}
// copy the data & rebind virtual addresses
o->raw_data = hl_gc_alloc_noptr(raw_size);
Expand Down Expand Up @@ -687,7 +685,7 @@ static void hl_dynobj_remap_virtuals( vdynobj *o, hl_field_lookup *f, int_val ad
static void hl_dynobj_delete_field( vdynobj *o, hl_field_lookup *f ) {
int i;
unsigned int order = hl_dynobj_order(f);
int index = f->field_index & DYNOBJ_INDEX_MASK;
int index = f->field_index & HL_DYNOBJ_INDEX_MASK;
bool is_ptr = hl_is_ptr(f->t);
// erase data
if( is_ptr ) {
Expand All @@ -696,7 +694,7 @@ static void hl_dynobj_delete_field( vdynobj *o, hl_field_lookup *f ) {
o->values[o->nvalues] = NULL;
for(i=0;i<o->nfields;i++) {
hl_field_lookup *f = o->lookup + i;
if( hl_is_ptr(f->t) && (f->field_index&DYNOBJ_INDEX_MASK) > index )
if( hl_is_ptr(f->t) && (f->field_index&HL_DYNOBJ_INDEX_MASK) > index )
f->field_index--;
}
} else {
Expand Down Expand Up @@ -730,7 +728,7 @@ static void hl_dynobj_delete_field( vdynobj *o, hl_field_lookup *f ) {
for(i=0;i<o->nfields;i++) {
hl_field_lookup *f = o->lookup + i;
if( hl_dynobj_order(f) > order )
f->field_index -= 1 << DYNOBJ_INDEX_SHIFT;
f->field_index -= 1 << HL_DYNOBJ_INDEX_SHIFT;
}
}

Expand All @@ -741,7 +739,7 @@ static hl_field_lookup *hl_dynobj_add_field( vdynobj *o, int hfield, hl_type *t
// expand data
if( hl_is_ptr(t) ) {
index = o->nvalues;
if( index > DYNOBJ_INDEX_MASK ) hl_error("Too many dynobj values");
if( index > HL_DYNOBJ_INDEX_MASK ) hl_error("Too many dynobj values");
void **nvalues = hl_gc_alloc_raw( (o->nvalues + 1) * sizeof(void*) );
memcpy(nvalues,o->values,o->nvalues * sizeof(void*));
nvalues[index] = NULL;
Expand All @@ -762,7 +760,7 @@ static hl_field_lookup *hl_dynobj_add_field( vdynobj *o, int hfield, hl_type *t
int pad = hl_pad_size(raw_size, t);
int size = hl_type_size(t);

if( raw_size + pad > DYNOBJ_INDEX_MASK ) hl_error("Too many dynobj values");
if( raw_size + pad > HL_DYNOBJ_INDEX_MASK ) hl_error("Too many dynobj values");

char *newData = (char*)hl_gc_alloc_noptr(raw_size + pad + size);
if( raw_size == o->raw_size )
Expand All @@ -771,11 +769,11 @@ static hl_field_lookup *hl_dynobj_add_field( vdynobj *o, int hfield, hl_type *t
raw_size = 0;
for(i=0;i<o->nfields;i++) {
hl_field_lookup *f = o->lookup + i;
int index = f->field_index & DYNOBJ_INDEX_MASK;
int index = f->field_index & HL_DYNOBJ_INDEX_MASK;
if( hl_is_ptr(f->t) ) continue;
raw_size += hl_pad_size(raw_size, f->t);
memcpy(newData + raw_size, o->raw_data + index, hl_type_size(f->t));
f->field_index = raw_size | (hl_dynobj_order(f) << DYNOBJ_INDEX_SHIFT);
f->field_index = raw_size | (hl_dynobj_order(f) << HL_DYNOBJ_INDEX_SHIFT);
if( index != raw_size )
hl_dynobj_remap_virtuals(o, f, 0);
raw_size += hl_type_size(f->t);
Expand All @@ -796,7 +794,7 @@ static hl_field_lookup *hl_dynobj_add_field( vdynobj *o, int hfield, hl_type *t
hl_field_lookup *f = new_lookup + field_pos;
f->t = t;
f->hashed_name = hfield;
f->field_index = index | (o->nfields << DYNOBJ_INDEX_SHIFT);
f->field_index = index | (o->nfields << HL_DYNOBJ_INDEX_SHIFT);
memcpy(new_lookup + (field_pos + 1),o->lookup + field_pos, (o->nfields - field_pos) * sizeof(hl_field_lookup));
o->nfields++;
o->lookup = new_lookup;
Expand Down
6 changes: 3 additions & 3 deletions src/std/types.c
Original file line number Diff line number Diff line change
Expand Up @@ -826,7 +826,7 @@ static void compact_write_content( mem_context *ctx, vdynamic *d ) {
for(i=0;i<obj->nvalues;i++) {
int j;
for(j=0;i<obj->nfields;j++) {
if( obj->lookup[j].field_index == i && hl_is_ptr(obj->lookup[j].t) ) {
if( (obj->lookup[j].field_index&HL_DYNOBJ_INDEX_MASK) == i && hl_is_ptr(obj->lookup[j].t) ) {
compact_write_data(ctx, obj->lookup[j].t, obj->values + i);
break;
}
Expand All @@ -836,9 +836,9 @@ static void compact_write_content( mem_context *ctx, vdynamic *d ) {
int save_pos = ctx->todos_pos;
for(i=0;i<obj->nfields;i++) {
hl_field_lookup *f = obj->lookup + i;
int idx = compact_lookup_ref(ctx, hl_is_ptr(f->t) ? (char*)(obj->values + f->field_index) : (char*)(obj->raw_data + f->field_index), false);
int idx = compact_lookup_ref(ctx, hl_is_ptr(f->t) ? (char*)(obj->values + (f->field_index&HL_DYNOBJ_INDEX_MASK)) : (char*)(obj->raw_data + (f->field_index&HL_DYNOBJ_INDEX_MASK)), false);
idx = -idx-1;
ctx->remap_target[idx] = hl_is_ptr(f->t) ? values_data + sizeof(void*)*f->field_index : raw_data + f->field_index;
ctx->remap_target[idx] = hl_is_ptr(f->t) ? values_data + sizeof(void*)*f->field_index : raw_data + (f->field_index&HL_DYNOBJ_INDEX_MASK);
}
ctx->todos_pos = save_pos;
break;
Expand Down

0 comments on commit 70841db

Please sign in to comment.