diff options
-rw-r--r-- | src/analyzer.js | 5 | ||||
-rw-r--r-- | src/jsifier.js | 13 | ||||
-rw-r--r-- | src/parseTools.js | 1 | ||||
-rw-r--r-- | src/preamble.js | 2 | ||||
-rw-r--r-- | src/runtime.js | 30 | ||||
-rw-r--r-- | tests/runner.py | 2 | ||||
-rw-r--r-- | tools/shared.py | 2 |
7 files changed, 39 insertions, 16 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index 7d99ab69..4aac53a8 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -774,12 +774,15 @@ function analyzer(data, sidePass) { assert(isNumber(item.allocatedNum)); item.allocatedSize = func.variables[line.ident].impl === VAR_EMULATED ? calcAllocatedSize(item.allocatedType)*item.allocatedNum: 0; + if (USE_TYPED_ARRAYS === 2) { + // We need to keep the stack aligned + item.allocatedSize = Runtime.forceAlign(item.allocatedSize, QUANTUM_SIZE); + } } var index = 0; for (var i = 0; i < lines.length; i++) { var item = lines[i].value; if (!item || item.intertype != 'alloca') break; - if (USE_TYPED_ARRAYS === 2) index = Runtime.forceAlign(index, Math.min(item.allocatedSize, QUANTUM_SIZE)); item.allocatedIndex = index; index += item.allocatedSize; delete item.allocatedSize; diff --git a/src/jsifier.js b/src/jsifier.js index 3f41c179..501ed3f9 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1063,7 +1063,18 @@ function JSify(data, functionsOnly, givenFunctions) { varargs = [0]; varargsTypes = ['i32']; } - varargs = makePointer('[' + varargs + ']', 0, 'ALLOC_STACK', varargsTypes); + var offset = 0; + varargs = '(tempInt=' + RuntimeGenerator.stackAlloc(varargs.length, ',') + ',' + + varargs.map(function(arg, i) { + var type = varargsTypes[i]; + if (type == 0) return null; + if (I64_MODE == 1 && type == 'i64') type = 'i32'; // We have [i64, 0, 0, 0, i32, 0, 0, 0] in the layout at this point + var ret = makeSetValue(getFastValue('tempInt', '+', offset), 0, arg, type, null, null, QUANTUM_SIZE); + offset += Runtime.getNativeFieldSize(type); + return ret; + }).filter(function(arg) { + return arg !== null; + }).join(',') + ',tempInt)'; } args = args.concat(varargs); diff --git a/src/parseTools.js b/src/parseTools.js index 22c2f440..18ce807e 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -779,6 +779,7 @@ function generateStructTypes(type) { var start = index; for (var i = 0; i < typeData.fields.length; i++) { var type = typeData.fields[i]; + if (!SAFE_HEAP && isPointerType(type)) type = '*'; // do not include unneeded type names without safe heap if (Runtime.isNumberType(type) || isPointerType(type)) { if (I64_MODE == 1 && type == 'i64') { ret[index++] = 'i64'; diff --git a/src/preamble.js b/src/preamble.js index eb55defb..5bb904d5 100644 --- a/src/preamble.js +++ b/src/preamble.js @@ -643,7 +643,7 @@ Module['HEAPU32'] = HEAPU32; Module['HEAPF32'] = HEAPF32; #endif -STACK_ROOT = STACKTOP = alignMemoryPage(10); +STACK_ROOT = STACKTOP = Runtime.alignMemory(STATICTOP); STACK_MAX = STACK_ROOT + TOTAL_STACK; STATICTOP = alignMemoryPage(STACK_MAX); diff --git a/src/runtime.js b/src/runtime.js index 605de749..2b81258d 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -7,32 +7,40 @@ // itself is as optimized as possible - no unneeded runtime checks). var RuntimeGenerator = { - alloc: function(size, type, init) { + alloc: function(size, type, init, sep, ignoreAlign) { + sep = sep || ';'; var ret = type + 'TOP'; if (init) { - ret += '; _memset(' + type + 'TOP, 0, ' + size + ')'; + ret += sep + '_memset(' + type + 'TOP, 0, ' + size + ')'; } - ret += '; ' + type + 'TOP += ' + size; - if ({{{ QUANTUM_SIZE }}} > 1) { - ret += ';' + RuntimeGenerator.alignMemory(type + 'TOP', {{{ QUANTUM_SIZE }}}); + ret += sep + type + 'TOP += ' + size; + if ({{{ QUANTUM_SIZE }}} > 1 && !ignoreAlign) { + ret += sep + RuntimeGenerator.alignMemory(type + 'TOP', {{{ QUANTUM_SIZE }}}); } return ret; }, // An allocation that lives as long as the current function call - stackAlloc: function(size) { - if (USE_TYPED_ARRAYS === 2) 'STACKTOP += STACKTOP % ' + ({{{ QUANTUM_SIZE }}} - (isNumber(size) ? Math.min(size, {{{ QUANTUM_SIZE }}}) : {{{ QUANTUM_SIZE }}})) + ';'; - var ret = RuntimeGenerator.alloc(size, 'STACK', INIT_STACK); + stackAlloc: function(size, sep) { + sep = sep || ';'; + if (USE_TYPED_ARRAYS === 2) 'STACKTOP += STACKTOP % ' + ({{{ QUANTUM_SIZE }}} - (isNumber(size) ? Math.min(size, {{{ QUANTUM_SIZE }}}) : {{{ QUANTUM_SIZE }}})) + sep; + // The stack is always QUANTUM SIZE aligned, so we may not need to force alignment here + var ret = RuntimeGenerator.alloc(size, 'STACK', INIT_STACK, sep, USE_TYPED_ARRAYS != 2 || (isNumber(size) && parseInt(size) % {{{ QUANTUM_SIZE }}} == 0)); if (ASSERTIONS) { - ret += '; assert(STACKTOP < STACK_ROOT + STACK_MAX, "Ran out of stack")'; + ret += sep + 'assert(STACKTOP < STACK_ROOT + STACK_MAX, "Ran out of stack")'; } return ret; }, stackEnter: function(initial, force) { if (initial === 0 && SKIP_STACK_IN_SMALL && !force) return ''; - if (USE_TYPED_ARRAYS === 2) initial = Runtime.forceAlign(initial); var ret = 'var __stackBase__ = STACKTOP; STACKTOP += ' + initial; + if (USE_TYPED_ARRAYS == 2) { + assert(initial % QUANTUM_SIZE == 0); + if (ASSERTIONS) { + ret += '; assert(STACKTOP % {{{ QUANTUM_SIZE }}} == 0, "Stack is unaligned")'; + } + } if (ASSERTIONS) { ret += '; assert(STACKTOP < STACK_MAX, "Ran out of stack")'; } @@ -63,7 +71,7 @@ var RuntimeGenerator = { if (typeof quantum !== 'number') { quantum = '(quantum ? quantum : {{{ QUANTUM_SIZE }}})'; } - return target + ' = ' + Runtime.forceAlign(target, quantum) + ';'; + return target + ' = ' + Runtime.forceAlign(target, quantum); } }; diff --git a/tests/runner.py b/tests/runner.py index 67ba24dc..22e8ff1d 100644 --- a/tests/runner.py +++ b/tests/runner.py @@ -5465,7 +5465,7 @@ f.close() def test_eliminator(self): input = open(path_from_root('tools', 'eliminator', 'eliminator-test.js')).read() expected = open(path_from_root('tools', 'eliminator', 'eliminator-test-output.js')).read() - output = Popen([COFFEESCRIPT, VARIABLE_ELIMINATOR], stdin=PIPE, stdout=PIPE).communicate(input)[0] + output = Popen([NODE_JS, COFFEESCRIPT, VARIABLE_ELIMINATOR], stdin=PIPE, stdout=PIPE).communicate(input)[0] self.assertIdentical(expected, output) def test_js_optimizer(self): diff --git a/tools/shared.py b/tools/shared.py index 1d97ff4b..5fdfdfb8 100644 --- a/tools/shared.py +++ b/tools/shared.py @@ -632,7 +632,7 @@ class Building: coffee = path_from_root('tools', 'eliminator', 'node_modules', 'coffee-script', 'bin', 'coffee') eliminator = path_from_root('tools', 'eliminator', 'eliminator.coffee') input = open(filename, 'r').read() - output, err = Popen([coffee, eliminator], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(input) + output, err = Popen([NODE_JS, coffee, eliminator], stdin=PIPE, stdout=PIPE, stderr=PIPE).communicate(input) assert len(output) > 0, 'Error in eliminator: ' + err + '\n\n' + output filename += '.el.js' f = open(filename, 'w') |