diff options
-rwxr-xr-x | emcc | 8 | ||||
-rw-r--r-- | src/preamble.js | 9 | ||||
-rwxr-xr-x | tests/runner.py | 9 |
3 files changed, 19 insertions, 7 deletions
@@ -193,10 +193,14 @@ Options that are modified or new in %s include: script to be run. --pre-js <file> A file whose contents are added before the - generated code + generated code. This is done *before* + optimization, so it will be minified + properly if closure compiler is run. --post-js <file> A file whose contents are added after the - generated code + generated code This is done *before* + optimization, so it will be minified + properly if closure compiler is run. --embed-file <file> A file to embed inside the generated JavaScript. The compiled code will be able diff --git a/src/preamble.js b/src/preamble.js index db092045..0e43af12 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -321,10 +321,11 @@ var globalScope = this; // Note that string arguments will be stored on the stack (the JS string will become a C string on the stack). // @return The return value, as a native JS value (as in returnType) function ccall(ident, returnType, argTypes, args) { + var stack = 0; function toC(value, type) { if (type == 'string') { - var ret = STACKTOP; - Runtime.stackAlloc(value.length+1); + if (!stack) stack = Runtime.stackSave(); + var ret = Runtime.stackAlloc(value.length+1); writeStringToMemory(value, ret); return ret; } @@ -348,7 +349,9 @@ function ccall(ident, returnType, argTypes, args) { var cArgs = args ? args.map(function(arg) { return toC(arg, argTypes[i++]); }) : []; - return fromC(func.apply(null, cArgs), returnType); + var ret = fromC(func.apply(null, cArgs), returnType); + if (stack) Runtime.stackRestore(stack); + return ret; } Module["ccall"] = ccall; diff --git a/tests/runner.py b/tests/runner.py index 99372553..aa83cf4f 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -5071,7 +5071,7 @@ Block 0: ''', post_build=post1) void KEEPALIVE print_int(int x) { printf("%d\n", x); } void KEEPALIVE print_float(float x) { printf("%.2f\n", x); } void KEEPALIVE print_string(char *x) { printf("%s\n", x); } - int KEEPALIVE multi(int x, float y, int z, char *str) { puts(str); return (x+y)*z; } + int KEEPALIVE multi(int x, float y, int z, char *str) { if (x) puts(str); return (x+y)*z; } int * KEEPALIVE pointer(int *in) { printf("%d\n", *in); static int ret = 21; return &ret; } } @@ -5112,6 +5112,11 @@ def process(filename): Module.print(multi(2, 1.4, 3, 'atr')); Module.print(multi(8, 5.4, 4, 'bret')); Module.print('*'); + // part 3: avoid stack explosion + for (var i = 0; i < TOTAL_STACK/60; i++) { + ccall('multi', 'number', ['number', 'number', 'number', 'string'], [0, 0, 0, '123456789012345678901234567890123456789012345678901234567890']); + } + Module.print('stack is ok.'); } }; \'\'\' + open(filename, 'r').read() @@ -5120,7 +5125,7 @@ def process(filename): Settings.EXPORTED_FUNCTIONS = ['_get_int', '_get_float', '_get_string', '_print_int', '_print_float', '_print_string', '_multi', '_pointer', '_malloc'] - self.do_run(src, '*\nnumber,5\nnumber,3.14\nstring,hello world\n12\nundefined\n14.56\nundefined\ncheez\nundefined\nmore\nnumber,10\n650\nnumber,21\n*\natr\n10\nbret\n53\n*\n', post_build=post) + self.do_run(src, '*\nnumber,5\nnumber,3.14\nstring,hello world\n12\nundefined\n14.56\nundefined\ncheez\nundefined\nmore\nnumber,10\n650\nnumber,21\n*\natr\n10\nbret\n53\n*\nstack is ok.\n', post_build=post) def test_scriptaclass(self): header_filename = os.path.join(self.get_dir(), 'header.h') |