浏览代码

added carray api

Nicolas Cannasse 3 年之前
父节点
当前提交
92bcfc081b
共有 1 个文件被更改,包括 61 次插入0 次删除
  1. 61 0
      src/std/array.c

+ 61 - 0
src/std/array.c

@@ -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);