aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-11-12 21:10:04 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-11-12 21:10:04 -0800
commiteb6144f24f3379b6de5e59a3811dcaa1514c2b00 (patch)
tree252f711a8c8b83e43f9bd62110751fe0e8aa2dd1
parent8beb2562056702c3a7b057fa17ab496758cccb1e (diff)
handle byval varargs; fixes #705
-rw-r--r--src/jsifier.js26
-rwxr-xr-xtests/runner.py72
2 files changed, 94 insertions, 4 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index 9c022efb..feb7b74d 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1148,6 +1148,7 @@ function JSify(data, functionsOnly, givenFunctions) {
var argsTypes = [];
var varargs = [];
var varargsTypes = [];
+ var varargsByVals = {};
var ignoreFunctionIndexizing = [];
var useJSArgs = (shortident + '__jsargs') in LibraryManager.library;
var hasVarArgs = isVarArgsFunctionType(type);
@@ -1159,10 +1160,18 @@ function JSify(data, functionsOnly, givenFunctions) {
args.push(val);
argsTypes.push(param.type);
} else {
+ var size;
+ if (param.byVal) {
+ varargsByVals[varargs.length] = param.byVal;
+ size = calcAllocatedSize(removeAllPointing(param.type));
+ } else {
+ size = Runtime.getNativeFieldSize(param.type);
+ }
varargs.push(val);
- varargs = varargs.concat(zeros(Runtime.getNativeFieldSize(param.type)-1));
+ varargs = varargs.concat(zeros(size-1));
+ // TODO: replace concats like this with push
varargsTypes.push(param.type);
- varargsTypes = varargsTypes.concat(zeros(Runtime.getNativeFieldSize(param.type)-1));
+ varargsTypes = varargsTypes.concat(zeros(size-1));
}
});
@@ -1182,8 +1191,17 @@ function JSify(data, functionsOnly, givenFunctions) {
varargs.map(function(arg, i) {
var type = varargsTypes[i];
if (type == 0) return null;
- var ret = makeSetValue(getFastValue('tempInt', '+', offset), 0, arg, type, null, null, QUANTUM_SIZE, null, ',');
- offset += Runtime.getNativeFieldSize(type);
+ var ret;
+ if (!varargsByVals[i]) {
+ ret = makeSetValue(getFastValue('tempInt', '+', offset), 0, arg, type, null, null, QUANTUM_SIZE, null, ',');
+ offset += Runtime.getNativeFieldSize(type);
+ } else {
+ assert(offset % 4 == 0); // varargs must be aligned
+ var size = calcAllocatedSize(removeAllPointing(type));
+ assert(size % 4 == 0); // varargs must stay aligned
+ ret = makeCopyValues(getFastValue('tempInt', '+', offset), arg, size, null, null, varargsByVals[i], ',');
+ offset += size;
+ }
return ret;
}).filter(function(arg) {
return arg !== null;
diff --git a/tests/runner.py b/tests/runner.py
index 3844845f..7fc2f284 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -3012,6 +3012,78 @@ def process(filename):
'''
self.do_run(src, '*cheez: 0+24*\n*cheez: 0+24*\n*albeit*\n*albeit*\nQ85*\nmaxxi:21*\nmaxxD:22.10*\n*vfp:22,199*\n*vfp:22,199*\n')
+ def test_varargs_byval(self):
+ if Settings.USE_TYPED_ARRAYS != 2: return self.skip('FIXME: Add support for this')
+
+ src = r'''
+ #include <stdio.h>
+ #include <stdarg.h>
+
+ typedef struct type_a {
+ union {
+ double f;
+ void *p;
+ int i;
+ short sym;
+ } value;
+ } type_a;
+
+ enum mrb_vtype {
+ MRB_TT_FALSE = 0, /* 0 */
+ MRB_TT_CLASS = 9 /* 9 */
+ };
+
+ typedef struct type_b {
+ enum mrb_vtype tt:8;
+ } type_b;
+
+ void print_type_a(int argc, ...);
+ void print_type_b(int argc, ...);
+
+ int main(int argc, char *argv[])
+ {
+ type_a a;
+ type_b b;
+ a.value.p = (void*) 0x12345678;
+ b.tt = MRB_TT_CLASS;
+
+ printf("The original address of a is: %p\n", a.value.p);
+ printf("The original type of b is: %d\n", b.tt);
+
+ print_type_a(1, a);
+ print_type_b(1, b);
+
+ return 0;
+ }
+
+ void print_type_a(int argc, ...) {
+ va_list ap;
+ type_a a;
+
+ va_start(ap, argc);
+ a = va_arg(ap, type_a);
+ va_end(ap);
+
+ printf("The current address of a is: %p\n", a.value.p);
+ }
+
+ void print_type_b(int argc, ...) {
+ va_list ap;
+ type_b b;
+
+ va_start(ap, argc);
+ b = va_arg(ap, type_b);
+ va_end(ap);
+
+ printf("The current type of b is: %d\n", b.tt);
+ }
+ '''
+ self.do_run(src, '''The original address of a is: 0x12345678
+The original type of b is: 9
+The current address of a is: 0x12345678
+The current type of b is: 9
+''')
+
def test_structbyval(self):
# part 1: make sure that normally, passing structs by value works