added carray api
@@ -44,3 +44,64 @@ HL_PRIM hl_type *hl_array_type( varray *a ) {
DEFINE_PRIM(_ARR,alloc_array,_TYPE _I32);
DEFINE_PRIM(_VOID,array_blit,_ARR _I32 _ARR _I32 _I32);
DEFINE_PRIM(_TYPE,array_type,_ARR);
+
+typedef struct {
+ hl_type *at;
+ int osize;
+ int size;
+} hl_carray;
+
+HL_PRIM void *hl_alloc_carray( hl_type *at, int size ) {
+ if( at->kind != HOBJ && at->kind != HSTRUCT )
+ hl_error("Invalid array type");
+ if( size < 0 )
+ hl_error("Invalid array size");
+
+ hl_runtime_obj *rt = at->obj->rt;
+ if( rt == NULL || rt->methods == NULL ) rt = hl_get_obj_proto(at);
+ int osize = rt->size;
+ if( osize & (HL_WSIZE-1) ) osize += HL_WSIZE - (osize & (HL_WSIZE-1));
+ hl_carray *arr;
+ int header = sizeof(hl_carray);
+ if( at->kind == HSTRUCT ) {
+ header += sizeof(vdynamic) * size;
+ arr = (hl_carray*)hl_gc_alloc_gen(at, header + size * osize, (rt->hasPtr ? MEM_KIND_RAW : MEM_KIND_NOPTR) | MEM_ZERO);
+ arr->osize = sizeof(vdynamic);
+ } else {
+ arr = (hl_carray*)hl_gc_alloc_gen(at, header + size * osize, (rt->hasPtr ? MEM_KIND_DYNAMIC : MEM_KIND_NOPTR) | MEM_ZERO);
+ arr->osize = osize;
+ }
+ arr->size = size;
+ arr->at = at;
+
+ int i,k;
+ for(k=0;k<size;k++) {
+ vobj *o = (vobj*)((char*)arr + header + osize * k);
+ if( at->kind == HOBJ )
+ o->t = at;
+ else {
+ vdynamic *d = (vdynamic*)((char*)(arr + 1) + k * sizeof(vdynamic));
+ d->t = at;
+ d->v.ptr = o;
+ }
+ for(i=0;i<rt->nbindings;i++) {
+ hl_runtime_binding *b = rt->bindings + i;
+ *(void**)(((char*)o) + rt->fields_indexes[b->fid]) = b->closure ? hl_alloc_closure_ptr(b->closure,b->ptr,o) : b->ptr;
+ }
+ }
+ return arr;
+}
+
+HL_PRIM int hl_carray_length( hl_carray *arr ) {
+ return arr->size;
+}
+
+HL_PRIM vdynamic *hl_carray_get( hl_carray *arr, int pos ) {
+ if( pos < 0 || pos >= arr->size ) return NULL;
+ return (vdynamic*)((char*)(arr + 1) + pos * arr->osize);
+}
+
+#define _CARRAY _ABSTRACT(hl_carray)
+DEFINE_PRIM(_CARRAY,alloc_carray,_TYPE _I32);
+DEFINE_PRIM(_DYN,carray_get,_CARRAY _I32);
+DEFINE_PRIM(_I32,carray_length,_CARRAY);
