static tsf_bool_t native_type_can_blit_recurse()

in benchmarks/JetStream2/wasm/TSF/tsf_native.c [176:263]


static tsf_bool_t native_type_can_blit_recurse(tsf_type_t *dest,
                                               tsf_type_t *src,
                                               size_t dest_size) {
    uint32_t i;
    size_t sub_dest_size;
    if (dest->kind_code!=src->kind_code) {
        return tsf_false;
    }
    if (dest_size==0) {
        dest_size=tsf_native_type_get_size(dest);
    }
    if (tsf_native_type_get_size(src) > dest_size) {
        return tsf_false;
    }
    switch (dest->kind_code) {
        case TSF_TK_ARRAY:
        case TSF_TK_STRING:
        case TSF_TK_ANY:
            return tsf_false;
        case TSF_TK_CHOICE:
            if (tsf_choice_type_get_num_elements(src) >
                tsf_choice_type_get_num_elements(dest)) {
                return tsf_false;
            }
            if ((tsf_choice_type_has_non_void(src) &&
                 src->u.h.data_offset != dest->u.h.data_offset) ||
                src->u.h.value_offset != dest->u.h.value_offset) {
                return tsf_false;
            }
            if (dest->u.h.value_offset > dest->u.h.data_offset) {
                sub_dest_size=dest->u.h.value_offset-dest->u.h.data_offset;
            } else {
                sub_dest_size=dest->u.h.size-dest->u.h.data_offset;
            }
            for (i=0;i<tsf_choice_type_get_num_elements(src);++i) {
                tsf_named_type_t *sn=tsf_choice_type_get_element(src,i);
                tsf_named_type_t *dn=tsf_choice_type_get_element(dest,i);
                if (strcmp(sn->name,dn->name)) {
                    return tsf_false;
                }
                if (!native_type_can_blit_recurse(dn->type,
                                                  sn->type,
                                                  sub_dest_size)) {
                    return tsf_false;
                }
		if (dn->type->kind_code!=TSF_TK_VOID &&
		    (!tsf_native_choice_type_is_in_place(dest) ||
		     !tsf_native_choice_type_is_in_place(src))) {
		    return tsf_false;
		}
            }
            break;
        case TSF_TK_STRUCT:
            if (dest->u.s.constructor != NULL ||
                dest->u.s.pre_destructor != NULL) {
                return tsf_false;
            }
            
            for (i=0;i<tsf_struct_type_get_num_elements(dest);++i) {
                tsf_named_type_t *dn=tsf_struct_type_get_element(dest,i);
                tsf_named_type_t *sn;
                
                if (tsf_type_get_static_size(dn->type)==0) {
                    continue;
                }
                
                sn=tsf_struct_type_find_node(src,dn->name);
                if (sn==NULL) {
                    return tsf_false;
                }
                
                if (!native_type_can_blit_recurse(dn->type,
                                                  sn->type,
                                                  0)) {
                    return tsf_false;
                }
                
                if (dn->offset != sn->offset) {
                    return tsf_false;
                }
            }
            break;
        default:
            break;
    }
    
    return tsf_true;
}