diff --git a/src/std/array.c b/src/std/array.c index 317480e51..b20b221dd 100644 --- a/src/std/array.c +++ b/src/std/array.c @@ -54,6 +54,14 @@ DEFINE_PRIM(_VOID,array_blit,_ARR _I32 _ARR _I32 _I32); DEFINE_PRIM(_TYPE,array_type,_ARR); DEFINE_PRIM(_BYTES,array_bytes,_ARR); +#ifndef HL_DISABLE_COMPAT +typedef struct { + size_t size; + hl_type* type; +} hl_carray_footer; +#endif +#define HL_CARRAY_GET_FOOTER(arr) ((hl_carray_footer*)((char*)(arr) + hl_gc_get_memsize((arr)) - sizeof(hl_carray_footer))) + HL_PRIM void *hl_alloc_carray( hl_type *at, int size ) { if( at->kind != HOBJ && at->kind != HSTRUCT ) hl_error("Invalid array type"); @@ -62,7 +70,14 @@ HL_PRIM void *hl_alloc_carray( hl_type *at, int size ) { hl_runtime_obj *rt = at->obj->rt; if( rt == NULL || rt->methods == NULL ) rt = hl_get_obj_proto(at); +#ifdef HL_DISABLE_COMPAT char *arr = hl_gc_alloc_gen(at, size * rt->size, (rt->hasPtr ? MEM_KIND_RAW : MEM_KIND_NOPTR) | MEM_ZERO); +#else + char *arr = hl_gc_alloc_gen(at, size * rt->size + sizeof(hl_carray_footer), (rt->hasPtr ? MEM_KIND_RAW : MEM_KIND_NOPTR) | MEM_ZERO); + hl_carray_footer *footer = HL_CARRAY_GET_FOOTER(arr); + footer->size = size; + footer->type = at; +#endif if( at->kind == HOBJ || rt->nbindings ) { int i,k; for(k=0;ksize; +} + +HL_PRIM vdynamic *hl_carray_get( void *arr, int pos ) { + if (!hl_is_gc_ptr(arr)) { + hl_error("Cannot call hl_carray_get with external carray"); + } + + hl_carray_footer* footer = HL_CARRAY_GET_FOOTER(arr); + if (pos < 0 || pos >= footer->size) return NULL; + hl_type* type = footer->type; + void* element = (void*)((char*)arr + pos * type->obj->rt->size); + if (type->kind == HSTRUCT) { + vdynamic* dyn = hl_alloc_dynamic(type); + dyn->v.ptr = element; + return dyn; + } + return (vdynamic*)element; +} + +DEFINE_PRIM(_DYN,carray_get,_CARRAY _I32); +DEFINE_PRIM(_I32,carray_length,_CARRAY); +#endif