aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xemcc8
-rw-r--r--src/preamble.js9
-rwxr-xr-xtests/runner.py9
3 files changed, 19 insertions, 7 deletions
diff --git a/emcc b/emcc
index 114483cb..596a9c33 100755
--- a/emcc
+++ b/emcc
@@ -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')