From 9579837a6d267cd289d92ca7607fe5e645a6703c Mon Sep 17 00:00:00 2001 From: Beuc Date: Thu, 5 Jul 2018 19:11:56 +0200 Subject: [PATCH] emterpreter: explicit error message on emterpreter stack overflow (#6754) (#6774) --- emscripten.py | 2 ++ src/preamble.js | 6 ++++++ tools/emterpretify.py | 10 ++++++---- tools/js-optimizer.js | 4 +++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/emscripten.py b/emscripten.py index 0db04ff3d12f..4ca8dc65ac02 100755 --- a/emscripten.py +++ b/emscripten.py @@ -1224,6 +1224,8 @@ def create_basic_funcs(function_table_sigs): basic_funcs += ['abortOnCannotGrowMemory'] if shared.Settings.STACK_OVERFLOW_CHECK: basic_funcs += ['abortStackOverflow'] + if shared.Settings.EMTERPRETIFY: + basic_funcs += ['abortStackOverflowEmterpreter'] if shared.Settings.SAFE_HEAP: if asm_safe_heap(): basic_funcs += ['segfault', 'alignfault', 'ftfault'] diff --git a/src/preamble.js b/src/preamble.js index 55b6ab5cf4e2..41acd4514c9c 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -938,6 +938,12 @@ function abortStackOverflow(allocSize) { } #endif +#if EMTERPRETIFY +function abortStackOverflowEmterpreter() { + abort("Emterpreter stack overflow! Decrease the recursion level or increase EMT_STACK_MAX in tools/emterpretify.py (current value " + EMT_STACK_MAX + ")."); +} +#endif + #if ABORTING_MALLOC function abortOnCannotGrowMemory() { #if WASM diff --git a/tools/emterpretify.py b/tools/emterpretify.py index b6225dc9567e..98d4e6a14947 100755 --- a/tools/emterpretify.py +++ b/tools/emterpretify.py @@ -479,8 +479,9 @@ def handle_async_post_call(): CASES[ROPCODES['INTCALL']] = ''' lz = HEAPU8[(HEAP32[pc + 4 >> 2] | 0) + 1 | 0] | 0; // FUNC inst, see definition above; we read params here - ly = 0; - assert(((EMTSTACKTOP + 8|0) <= (EMT_STACK_MAX|0))|0); // for return value + ly = 0;''' + (''' + if (((EMTSTACKTOP + 8|0) > (EMT_STACK_MAX|0))|0) // for return value + abortStackOverflowEmterpreter(); ''' if ASSERTIONS else '') + ''' %s %s while ((ly|0) < (lz|0)) { @@ -701,8 +702,9 @@ def process(code): '' if not ASYNC else 'HEAP32[EMTSTACKTOP>>2] = pc;\n', push_stacktop(zero), ROPCODES['FUNC'], - (''' EMTSTACKTOP = EMTSTACKTOP + (lx ''' + (' + 1 ' if ASYNC else '') + '''<< 3) | 0; - assert(((EMTSTACKTOP|0) <= (EMT_STACK_MAX|0))|0);\n''' + (' if ((asyncState|0) != 2) {' if ASYNC else '')) if not zero else '', + (''' EMTSTACKTOP = EMTSTACKTOP + (lx ''' + (' + 1 ' if ASYNC else '') + '''<< 3) | 0;\n''' + + (''' if (((EMTSTACKTOP|0) > (EMT_STACK_MAX|0))|0) abortStackOverflowEmterpreter();\n''' if ASSERTIONS else '') + + (' if ((asyncState|0) != 2) {' if ASYNC else '')) if not zero else '', ' } else { pc = (HEAP32[sp - 4 >> 2] | 0) - 8 | 0; }' if ASYNC else '', main_loop, )) diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index b5ef85f702f5..a3ff77abaa0a 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -7574,7 +7574,9 @@ function emterpretify(ast) { func[3].push(srcToStat('sp = EMTSTACKTOP;')); var stackBytes = finalLocals*8; func[3].push(srcToStat('EMTSTACKTOP = EMTSTACKTOP + ' + stackBytes + ' | 0;')); - func[3].push(srcToStat('assert(((EMTSTACKTOP|0) <= (EMT_STACK_MAX|0))|0);')); + if (ASSERTIONS) { + func[3].push(srcToStat('if (((EMTSTACKTOP|0) > (EMT_STACK_MAX|0))|0) abortStackOverflowEmterpreter();')); + } asmData.vars['x'] = ASM_INT; func[3].push(srcToStat('while ((x | 0) < ' + stackBytes + ') { HEAP32[sp + x >> 2] = HEAP32[x >> 2] | 0; x = x + 4 | 0; }')); }