aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jsifier.js17
-rwxr-xr-xtests/runner.py76
2 files changed, 92 insertions, 1 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index 1d70fd6f..c92526d2 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1238,6 +1238,7 @@ function JSify(data, functionsOnly, givenFunctions) {
+ (EXCEPTION_DEBUG ? 'Module.print("Exception: " + e + ", currently at: " + (new Error().stack)); ' : '')
+ 'return null } })();';
}
+ ret = makeVarArgsCleanup(ret);
if (item.assignTo) {
ret = 'var ' + item.assignTo + ' = ' + ret;
@@ -1562,10 +1563,24 @@ function JSify(data, functionsOnly, givenFunctions) {
return ret;
}
+
+ function makeVarArgsCleanup(js) {
+ if (js.indexOf('(tempVarArgs=') >= 0) {
+ if (js[js.length-1] == ';') {
+ return js + ' STACKTOP=tempVarArgs;';
+ } else {
+ assert(js.indexOf(';') < 0);
+ return '((' + js + '), STACKTOP=tempVarArgs)';
+ }
+ }
+ return js;
+ }
+
makeFuncLineActor('getelementptr', function(item) { return finalizeLLVMFunctionCall(item) });
makeFuncLineActor('call', function(item) {
if (item.standalone && LibraryManager.isStubFunction(item.ident)) return ';';
- return makeFunctionCall(item.ident, item.params, item.funcData, item.type, false, !!item.assignTo || !item.standalone) + (item.standalone ? ';' : '');
+ var ret = makeFunctionCall(item.ident, item.params, item.funcData, item.type, false, !!item.assignTo || !item.standalone) + (item.standalone ? ';' : '');
+ return makeVarArgsCleanup(ret);
});
makeFuncLineActor('unreachable', function(item) {
diff --git a/tests/runner.py b/tests/runner.py
index 8ab3609b..cbdacc2c 100755
--- a/tests/runner.py
+++ b/tests/runner.py
@@ -3719,6 +3719,82 @@ Exiting setjmp function, level: 0, prev_jmp: -1
Settings.TOTAL_STACK = 1024
self.do_run(src, 'ok!')
+ def test_stack_varargs2(self):
+ if self.emcc_args is None: return # too slow in other modes
+ Settings.TOTAL_STACK = 1024
+ src = r'''
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ void func(int i) {
+ }
+ int main() {
+ for (int i = 0; i < 1024; i++) {
+ printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
+ i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i);
+ }
+ printf("ok!\n");
+ return 0;
+ }
+ '''
+ self.do_run(src, 'ok!')
+
+ print 'with return'
+
+ src = r'''
+ #include <stdio.h>
+ #include <stdlib.h>
+
+ int main() {
+ for (int i = 0; i < 1024; i++) {
+ int j = printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
+ i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i);
+ printf(" (%d)\n", j);
+ }
+ printf("ok!\n");
+ return 0;
+ }
+ '''
+ self.do_run(src, 'ok!')
+
+ print 'with definitely no return'
+
+ src = r'''
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <stdarg.h>
+
+ void vary(const char *s, ...)
+ {
+ va_list v;
+ va_start(v, s);
+ char d[20];
+ vsnprintf(d, 20, s, v);
+ puts(d);
+
+ // Try it with copying
+ va_list tempva;
+ va_copy(tempva, v);
+ vsnprintf(d, 20, s, tempva);
+ puts(d);
+
+ va_end(v);
+ }
+
+ int main() {
+ for (int i = 0; i < 1024; i++) {
+ int j = printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",
+ i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i);
+ printf(" (%d)\n", j);
+ vary("*cheez: %d+%d*", 99, 24);
+ vary("*albeit*");
+ }
+ printf("ok!\n");
+ return 0;
+ }
+ '''
+ self.do_run(src, 'ok!')
+
def test_stack_void(self):
Settings.INLINING_LIMIT = 50