Skip to content

Commit

Permalink
keep ordering of dynobj fields in the order they were set
Browse files Browse the repository at this point in the history
  • Loading branch information
ncannasse committed Sep 16, 2023
1 parent a6fe9e8 commit ba0e666
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 10 deletions.
8 changes: 7 additions & 1 deletion src/std/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,12 +327,18 @@ static void hl_buffer_rec( hl_buffer *b, vdynamic *v, vlist *stack ) {
}
}
hl_buffer_char(b, '{');
int tmp[128];
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;
}
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) : (void*)(o->raw_data + f->field_index), f->t, &l);
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_char(b, '}');
}
Expand Down
36 changes: 27 additions & 9 deletions src/std/obj.c
Original file line number Diff line number Diff line change
Expand Up @@ -495,7 +495,10 @@ HL_API void hl_init_virtual( hl_type *vt, hl_module_context *ctx ) {
}
}

#define hl_dynobj_field(o,f) (hl_is_ptr((f)->t) ? (void*)((o)->values + (f)->field_index) : (void*) ((o)->raw_data + (f)->field_index))
#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)

vdynamic *hl_virtual_make_value( vvirtual *v ) {
vdynobj *o;
Expand All @@ -518,6 +521,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);
}
// copy the data & rebind virtual addresses
o->raw_data = hl_gc_alloc_noptr(raw_size);
Expand Down Expand Up @@ -681,7 +686,8 @@ 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;
int index = f->field_index;
unsigned int order = hl_dynobj_order(f);
int index = f->field_index & DYNOBJ_INDEX_MASK;
bool is_ptr = hl_is_ptr(f->t);
// erase data
if( is_ptr ) {
Expand All @@ -690,7 +696,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 > index )
if( hl_is_ptr(f->t) && (f->field_index&DYNOBJ_INDEX_MASK) > index )
f->field_index--;
}
} else {
Expand Down Expand Up @@ -720,6 +726,12 @@ static void hl_dynobj_delete_field( vdynobj *o, hl_field_lookup *f ) {
int field = (int)(f - o->lookup);
memmove(o->lookup + field, o->lookup + field + 1, (o->nfields - (field + 1)) * sizeof(hl_field_lookup));
o->nfields--;
// remap order indexes
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;
}
}

static hl_field_lookup *hl_dynobj_add_field( vdynobj *o, int hfield, hl_type *t ) {
Expand All @@ -728,9 +740,10 @@ 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");
void **nvalues = hl_gc_alloc_raw( (o->nvalues + 1) * sizeof(void*) );
memcpy(nvalues,o->values,o->nvalues * sizeof(void*));
index = o->nvalues;
nvalues[index] = NULL;
address_offset = (char*)nvalues - (char*)o->values;
o->values = nvalues;
Expand All @@ -748,18 +761,21 @@ static hl_field_lookup *hl_dynobj_add_field( vdynobj *o, int hfield, hl_type *t
raw_size = o->raw_size;
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");

char *newData = (char*)hl_gc_alloc_noptr(raw_size + pad + size);
if( raw_size == o->raw_size )
memcpy(newData,o->raw_data,o->raw_size);
else {
raw_size = 0;
for(i=0;i<o->nfields;i++) {
hl_field_lookup *f = o->lookup + i;
int index = f->field_index;
int index = f->field_index & 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;
f->field_index = raw_size | (hl_dynobj_order(f) << DYNOBJ_INDEX_SHIFT);
if( index != raw_size )
hl_dynobj_remap_virtuals(o, f, 0);
raw_size += hl_type_size(f->t);
Expand All @@ -780,7 +796,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;
f->field_index = index | (o->nfields << 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 Expand Up @@ -1221,8 +1237,10 @@ HL_PRIM varray *hl_obj_fields( vdynamic *obj ) {
vdynobj *o = (vdynobj*)obj;
int i;
a = hl_alloc_array(&hlt_bytes,o->nfields);
for(i=0;i<o->nfields;i++)
hl_aptr(a,vbyte*)[i] = (vbyte*)hl_field_name((o->lookup + i)->hashed_name);
for(i=0;i<o->nfields;i++) {
hl_field_lookup *f = o->lookup + i;
hl_aptr(a,vbyte*)[hl_dynobj_order(f)] = (vbyte*)hl_field_name(f->hashed_name);
}
}
break;
case HOBJ:
Expand Down

0 comments on commit ba0e666

Please sign in to comment.