summaryrefslogtreecommitdiff
path: root/libstd/varargs.myr
diff options
context:
space:
mode:
authorOri Bernstein <orib@google.com>2012-09-27 14:25:36 -0400
committerOri Bernstein <orib@google.com>2012-09-27 14:25:36 -0400
commite7753379f41991512b2ba815d879800e1b7c725b (patch)
treed4588d723907a26676abc206bbd55169e045f2c5 /libstd/varargs.myr
parentc827bfd2eb941cfdccf9cb2a1b6e50c24af5049e (diff)
downloadmc-e7753379f41991512b2ba815d879800e1b7c725b.tar.gz
Match the name of the directory to the name of the lib
We generate libstd, not libmyr. This gets installed to $PREFIX/myr/$LIBNAME, so this fairly generic name should not conflict with the system.
Diffstat (limited to 'libstd/varargs.myr')
-rw-r--r--libstd/varargs.myr52
1 files changed, 52 insertions, 0 deletions
diff --git a/libstd/varargs.myr b/libstd/varargs.myr
new file mode 100644
index 0000000..96c7b38
--- /dev/null
+++ b/libstd/varargs.myr
@@ -0,0 +1,52 @@
+use "types.use"
+
+pkg std =
+ type valist
+
+ const vastart : (args : ...* -> valist)
+ generic vanext : (ap : valist -> [@a, valist])
+;;
+
+type valist = byte*
+
+/*
+ * a valist is really just a pointer to the varargs.
+ * we assume that these sit on the stack nicely,
+ * and don't need special handling to get to.
+ *
+ * This will be a problem when we switch to a
+ * register based convention. We might want to
+ * force varargs onto the stack regardless.
+ */
+const vastart = {args
+ -> args castto(valist)
+}
+
+generic vanext = {ap -> [@a, valist]
+ var v : @a
+ var align
+ var p
+
+ /*
+ Assumptions about the ABI:
+ * all types smaller than a word are
+ * aligned to their own size. Larger
+ * types are aligned to word size.
+ */
+ if sizeof(@a) > 8
+ align = 8
+ else
+ align = sizeof(@a)
+ ;;
+
+ /* apply the alignment to the arg pointer */
+ p = ap castto(intptr)
+ p = (p + align - 1) & ~(align - 1)
+ ap = p castto(valist)
+
+ v = *(ap castto(@a*))
+
+ /* only move on after we read through the value */
+ ap = ((p castto(intptr)) + sizeof(@a)) castto(valist)
+ -> (v, ap)
+}