|
@@ -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;
|
|
@@ -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);
|
|
@@ -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 ) {
|
|
@@ -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 {
|
|
@@ -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 ) {
|
|
@@ -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;
|
|
@@ -748,6 +761,9 @@ 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);
|
|
@@ -755,11 +771,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;
|
|
|
+ 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);
|
|
@@ -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;
|
|
@@ -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:
|