shithub: mc

Download patch

ref: b15530cbcde987747b8506125b73c70ca7656438
parent: 95b07cdf3e64cd181229e1be1079c265a363675c
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Feb 22 16:20:47 EST 2016

Align to struct alignment before entering struct.

	Structs may have different alignments from their first
	element, so if we don't align on entry, we can be reading
	things at the wrong offset.

	Fixes #88

--- a/lib/std/varargs.myr
+++ b/lib/std/varargs.myr
@@ -55,14 +55,29 @@
 
 extern const put	: (fmt : byte[:], args : ... -> size)
 const vaenter = {ap
-	match typedesc(vatype(ap))
+	var ty
+
+	ty = vatype(ap)
+	match typedesc(ty)
 	| `Tyslice enc:	-> [.args=sliceptr(ap.args), .tc=[.nelt=slicelen(ap.args), .rem=enc, .isiter=false]]
 	| `Tytuple tc:	-> [.args=ap.args, .tc=tc]
-	| `Tystruct tc:	-> [.args=ap.args, .tc=tc]
+	| `Tystruct tc:	-> [.args=cursoralign(ap.args, ty), .tc=tc]
 	| `Tyarray (sz, enc):	-> [.args=ap.args, .tc=[.nelt=sz, .rem=enc, .isiter=false]]
 	| `Tyname (name, enc):	-> [.args=ap.args, .tc=typeenccursor(enc)]
 	| _:	std.die("unable to enter type\n")
 	;;
+}
+
+const cursoralign = {arg, ty
+	var ti, align, p
+
+	ti = typeinfo(ty)
+
+	/* apply the alignment to the arg pointer */
+	align = ti.align castto(intptr)
+	p = arg castto(intptr)
+	p = (p + align - 1) & ~(align - 1)
+	-> p castto(byte#)
 }
 
 const vaenterunion = {ap, elt