浏览代码

added hl_pad_struct (close #74)

Nicolas Cannasse 8 年之前
父节点
当前提交
7d6afbeadb
共有 3 个文件被更改,包括 35 次插入3 次删除
  1. 1 0
      src/hl.h
  2. 2 2
      src/std/obj.c
  3. 32 1
      src/std/types.c

+ 1 - 0
src/hl.h

@@ -328,6 +328,7 @@ C_FUNCTION_BEGIN
 
 HL_API int hl_type_size( hl_type *t );
 #define hl_pad_size(size,t)	((t)->kind == HVOID ? 0 : ((-(size)) & (hl_type_size(t) - 1)))
+HL_API int hl_pad_struct( int size, hl_type *t );
 HL_API int hl_stack_size( hl_type *t );
 
 HL_API hl_runtime_obj *hl_get_obj_rt( hl_type *ot );

+ 2 - 2
src/std/obj.c

@@ -219,7 +219,7 @@ HL_PRIM hl_runtime_obj *hl_get_obj_rt( hl_type *ot ) {
 	nlookup = 0;
 	for(i=0;i<o->nfields;i++) {
 		hl_type *ft = o->fields[i].t;
-		size += hl_pad_size(size,ft);
+		size += hl_pad_struct(size,ft);
 		t->fields_indexes[i+start] = size;
 		if( *o->fields[i].name )
 			hl_lookup_insert(t->lookup,nlookup++,o->fields[i].hashed_name,o->fields[i].t,size);
@@ -381,7 +381,7 @@ void hl_init_virtual( hl_type *vt, hl_module_context *ctx ) {
 	for(i=0;i<vt->virt->nfields;i++) {
 		hl_obj_field *f = vt->virt->fields + i;
 		hl_lookup_insert(l,i,f->hashed_name,f->t,i);
-		size += hl_pad_size(size, f->t);
+		size += hl_pad_struct(size, f->t);
 		indexes[i] = size;
 		size += hl_type_size(f->t);
 	}

+ 32 - 1
src/std/types.c

@@ -78,6 +78,37 @@ HL_PRIM int hl_stack_size( hl_type *t ) {
 	}
 }
 
+HL_PRIM int hl_pad_struct( int size, hl_type *t ) {
+	int align = sizeof(void*);
+#	define GET_ALIGN(type) { struct { unsigned char a; type b; } s = {0}; align = (unsigned char *)&s.b - (unsigned char*)&s; }
+	switch( t->kind ) {
+	case HVOID:
+		return 0;
+	case HUI8:
+		GET_ALIGN(unsigned char);
+		break;
+	case HUI16:
+		GET_ALIGN(unsigned short);
+		break;
+	case HI32:
+		GET_ALIGN(unsigned int);
+		break;
+	case HI64:
+		GET_ALIGN(int64);
+		break;
+	case HF32:
+		GET_ALIGN(float);
+		break;
+	case HF64:
+		GET_ALIGN(double);
+		break;
+	case HBOOL:
+		GET_ALIGN(bool);
+		break;
+	}
+	return (-size) & (align - 1);
+}
+
 HL_PRIM bool hl_same_type( hl_type *a, hl_type *b ) {
 	if( a == b )
 		return true;
@@ -317,7 +348,7 @@ HL_PRIM void hl_init_enum( hl_type *et, hl_module_context *m ) {
 		c->size = sizeof(venum); // t + index
 		for(j=0;j<c->nparams;j++) {
 			hl_type *t = c->params[j];
-			c->size += hl_pad_size(c->size,t);
+			c->size += hl_pad_struct(c->size,t);
 			c->offsets[j] = c->size;
 			if( hl_is_ptr(t) ) c->hasptr = true;
 			c->size += hl_type_size(t);