diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-11-12 21:10:04 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-11-12 21:10:04 -0800 |
commit | eb6144f24f3379b6de5e59a3811dcaa1514c2b00 (patch) | |
tree | 252f711a8c8b83e43f9bd62110751fe0e8aa2dd1 | |
parent | 8beb2562056702c3a7b057fa17ab496758cccb1e (diff) |
handle byval varargs; fixes #705
-rw-r--r-- | src/jsifier.js | 26 | ||||
-rwxr-xr-x | tests/runner.py | 72 |
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 |