diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-06-18 18:23:03 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-06-18 18:23:03 -0700 |
commit | 86462ba6a0fa81eec03afc32ee74ffa91928e004 (patch) | |
tree | 00b313771cf5340ce267dc764ead7fbb911ff11a | |
parent | f144ebdbd829a9223e50d7858d7ba79e43030875 (diff) | |
parent | 819ccd4914ba1f5db1c21829cb4615886829f26e (diff) |
Merge pull request #1301 from Manny-MADE/va_lists_fix
BUGFIX: lists cannot be copied as "llvm_va_copy" was broken, didn't copy list offset
-rw-r--r-- | AUTHORS | 5 | ||||
-rw-r--r-- | src/jsifier.js | 6 | ||||
-rw-r--r-- | src/library.js | 15 | ||||
-rwxr-xr-x | tests/runner.py | 53 |
4 files changed, 63 insertions, 16 deletions
@@ -84,7 +84,4 @@ a license to everyone to use it as detailed in LICENSE.) * Marc Feeley <mfeeley@mozilla.com> (copyright owned by Mozilla Foundation) * Ludovic Perrine <jazzzz@gmail.com> * David Barksdale <david.barksdale@adcedosolutions.com> - - - - +* Manfred Manik Nerurkar <nerurkar*at*made-apps.biz> (copyright owned by MADE, GmbH) diff --git a/src/jsifier.js b/src/jsifier.js index faef88d5..88b9d9f6 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1310,8 +1310,10 @@ function JSify(data, functionsOnly, givenFunctions) { assert(TARGET_LE32); var ident = item.value.ident; var move = Runtime.STACK_ALIGN; - return '(tempInt=' + makeGetValue(ident, 4, '*') + ',' + - makeSetValue(ident, 4, 'tempInt + ' + move, '*') + ',' + + + // store current list offset in tempInt, advance list offset by STACK_ALIGN, return list entry stored at tempInt + return '(tempInt=' + makeGetValue(ident, Runtime.QUANTUM_SIZE, '*') + ',' + + makeSetValue(ident, Runtime.QUANTUM_SIZE, 'tempInt + ' + move, '*') + ',' + makeGetValue(makeGetValue(ident, 0, '*'), 'tempInt', item.type) + ')'; }); diff --git a/src/library.js b/src/library.js index 151cf3e5..33dcbd5f 100644 --- a/src/library.js +++ b/src/library.js @@ -4999,22 +4999,19 @@ LibraryManager.library = { return makeSetValue(ptr, 0, 'varrp', 'void*'); #endif #if TARGET_LE32 - // 4-word structure: start, current offset - return makeSetValue(ptr, 0, 'varrp', 'void*') + ';' + makeSetValue(ptr, 4, 0, 'void*'); + // 2-word structure: struct { void* start; void* currentOffset; } + return makeSetValue(ptr, 0, 'varrp', 'void*') + ';' + makeSetValue(ptr, Runtime.QUANTUM_SIZE, 0, 'void*'); #endif }, llvm_va_end: function() {}, llvm_va_copy: function(ppdest, ppsrc) { + // copy the list start {{{ makeCopyValues('ppdest', 'ppsrc', Runtime.QUANTUM_SIZE, 'null', null, 1) }}}; - /* Alternate implementation that copies the actual DATA; it assumes the va_list is prefixed by its size - var psrc = IHEAP[ppsrc]-1; - var num = IHEAP[psrc]; // right before the data, is the number of (flattened) values - var pdest = _malloc(num+1); - _memcpy(pdest, psrc, num+1); - IHEAP[ppdest] = pdest+1; - */ + + // copy the list's current offset (will be advanced with each call to va_arg) + {{{ makeCopyValues('(ppdest+'+Runtime.QUANTUM_SIZE+')', '(ppsrc+'+Runtime.QUANTUM_SIZE+')', Runtime.QUANTUM_SIZE, 'null', null, 1) }}}; }, llvm_bswap_i16: function(x) { diff --git a/tests/runner.py b/tests/runner.py index 72c9afd1..830b2e18 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -4343,6 +4343,53 @@ def process(filename): puts(d); va_end(v); } + + void varargs_listoffsets_list_evaluate(int count, va_list ap, int vaIteration) + { + while(count > 0) + { + const char* string = va_arg(ap, const char*); + printf("%s", string); + count--; + } + printf("\\n"); + } + + void varags_listoffsets_list_copy(int count, va_list ap, int iteration) + { + va_list ap_copy; + va_copy(ap_copy, ap); + varargs_listoffsets_list_evaluate(count, ap_copy, iteration); + va_end(ap_copy); + } + + void varargs_listoffsets_args(int type, int count, ...) + { + va_list ap; + va_start(ap, count); + + // evaluate a copied list + varags_listoffsets_list_copy(count, ap, 1); + varags_listoffsets_list_copy(count, ap, 2); + varags_listoffsets_list_copy(count, ap, 3); + varags_listoffsets_list_copy(count, ap, 4); + + varargs_listoffsets_list_evaluate(count, ap, 1); + + // NOTE: we expect this test to fail, so we will check the stdout for <BAD+0><BAD+1>..... + varargs_listoffsets_list_evaluate(count, ap, 2); + + // NOTE: this test has to work again, as we restart the list + va_end(ap); + va_start(ap, count); + varargs_listoffsets_list_evaluate(count, ap, 3); + va_end(ap); + } + + void varargs_listoffsets_main() + { + varargs_listoffsets_args(0, 5, "abc", "def", "ghi", "jkl", "mno", "<BAD+0>", "<BAD+1>", "<BAD+2>", "<BAD+3>", "<BAD+4>", "<BAD+5>", "<BAD+6>", "<BAD+7>", "<BAD+8>", "<BAD+9>", "<BAD+10>", "<BAD+11>", "<BAD+12>", "<BAD+13>", "<BAD+14>", "<BAD+15>", "<BAD+16>"); + } #define GETMAX(pref, type) \ type getMax##pref(int num, ...) \ @@ -4375,10 +4422,14 @@ def process(filename): void (*vfp)(const char *s, ...) = argc == 1211 ? NULL : vary; vfp("*vfp:%d,%d*", 22, 199); + // ensure lists work properly when copied, reinited etc. + varargs_listoffsets_main(); + return 0; } ''' - 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') + 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'+ + 'abcdefghijklmno\nabcdefghijklmno\nabcdefghijklmno\nabcdefghijklmno\nabcdefghijklmno\n<BAD+0><BAD+1><BAD+2><BAD+3><BAD+4>\nabcdefghijklmno\n') def test_varargs_byval(self): if Settings.USE_TYPED_ARRAYS != 2: return self.skip('FIXME: Add support for this') |