Skip to content

Commit

Permalink
handle byval varargs; fixes #705
Browse files Browse the repository at this point in the history
kripken committed Nov 13, 2012
1 parent 8beb256 commit eb6144f
Showing 2 changed files with 94 additions and 4 deletions.
26 changes: 22 additions & 4 deletions src/jsifier.js
Original file line number Diff line number Diff line change
@@ -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;
72 changes: 72 additions & 0 deletions tests/runner.py
Original file line number Diff line number Diff line change
@@ -3012,6 +3012,78 @@ def test_varargs(self):
'''
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

0 comments on commit eb6144f

Please sign in to comment.