added recast to speedup virtual access
@@ -457,6 +457,20 @@ vdynamic *hl_virtual_make_value( vvirtual *v ) {
return v->value;
}
+static bool should_recast( hl_type *t, hl_type *vt ) {
+ if( vt->kind == HF64 && t->kind == HI32 )
+ return true;
+ if( vt->kind == HNULL && vt->tparam->kind == t->kind )
+ return true;
+ if( vt->kind == HNULL && vt->tparam->kind == HF64 && t->kind == HI32 )
+ return true;
+ if( vt->kind == HVIRTUAL && t->kind == HDYNOBJ )
+ return true;
+ if( vt->kind == HOBJ && t->kind == HOBJ && vt->obj->rt->castFun )
+ return true;
+ return false;
+}
+
/**
Allocate a virtual fields mapping to a given value.
**/
@@ -493,6 +507,7 @@ vvirtual *hl_to_virtual( hl_type *vt, vdynamic *obj ) {
case HDYNOBJ:
{
int i;
+ int64 need_recast = 0;
vdynobj *o = (vdynobj*)obj;
v = o->virtuals;
while( v ) {
@@ -506,11 +521,28 @@ vvirtual *hl_to_virtual( hl_type *vt, vdynamic *obj ) {
v->value = obj;
for(i=0;i<vt->virt->nfields;i++) {
hl_field_lookup *f = hl_lookup_find(o->lookup,o->nfields,vt->virt->fields[i].hashed_name);
- hl_vfields(v)[i] = f == NULL || !hl_same_type(f->t,vt->virt->fields[i].t) ? NULL : hl_dynobj_field(o,f);
+ hl_type *vft = vt->virt->fields[i].t;
+ void *addr = f == NULL || !hl_same_type(f->t,vft) ? NULL : hl_dynobj_field(o,f);
+ // check if we will perform recast of some fields to match the virtual definition
+ // recast will not work for >64 fields, but this should be pretty rare
+ if( addr == NULL && f && !o->virtuals && should_recast(f->t,vft) )
+ need_recast |= ((int64)1) << ((int64)i);
+ hl_vfields(v)[i] = addr;
}
// add it to the list
v->next = o->virtuals;
o->virtuals = v;
+ // recast
+ if( need_recast ) {
+ for(i=0;i<vt->virt->nfields;i++)
+ if( need_recast & (((int64)1) << ((int64)i)) ) {
+ hl_obj_field *f = vt->virt->fields + i;
+ if( hl_is_ptr(f->t) )
+ hl_dyn_setp(obj,f->hashed_name,f->t,hl_dyn_getp(obj,f->hashed_name,f->t));
+ else if( f->t->kind == HF64 )
+ hl_dyn_setd(obj,f->hashed_name,hl_dyn_getd(obj,f->hashed_name));
+ }
+ }
}
break;
case HVIRTUAL:
