aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-06-18 18:23:03 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-06-18 18:23:03 -0700
commit86462ba6a0fa81eec03afc32ee74ffa91928e004 (patch)
tree00b313771cf5340ce267dc764ead7fbb911ff11a
parentf144ebdbd829a9223e50d7858d7ba79e43030875 (diff)
parent819ccd4914ba1f5db1c21829cb4615886829f26e (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--AUTHORS5
-rw-r--r--src/jsifier.js6
-rw-r--r--src/library.js15
-rwxr-xr-xtests/runner.py53
4 files changed, 63 insertions, 16 deletions
diff --git a/AUTHORS b/AUTHORS
index 6dd9d53e..27206740 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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')