aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/jsifier.js9
-rw-r--r--src/modules.js3
-rw-r--r--tools/eliminator/eliminator-test.js2
-rw-r--r--tools/eliminator/eliminator.coffee26
4 files changed, 28 insertions, 12 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index bd432001..6cbc0eb9 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -931,7 +931,12 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
}
generated = generated.concat(itemsDict.function).concat(data.unparsedFunctions);
- if (!mainPass) return generated.map(function(item) { return item.JS }).join('\n');
+ if (!mainPass) {
+ Functions.allIdents = Functions.allIdents.concat(itemsDict.function.map(function(func) {
+ return func.ident;
+ }));
+ return generated.map(function(item) { return item.JS }).join('\n');
+ }
// We are ready to print out the data, but must do so carefully - we are
// dealing with potentially *huge* strings. Convenient replacements and
@@ -967,6 +972,8 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
print(Functions.generateIndexing()); // done last, as it may rely on aliases set in postsets
print(postParts[1]);
print(shellParts[1]);
+ // Print out some useful metadata (for additional optimizations later, like the eliminator)
+ print('// EMSCRIPTEN_GENERATED_FUNCTIONS: ' + JSON.stringify(Functions.allIdents) + '\n');
return null;
}
diff --git a/src/modules.js b/src/modules.js
index 3b370878..f04731f8 100644
--- a/src/modules.js
+++ b/src/modules.js
@@ -228,6 +228,9 @@ var Functions = {
// All functions that will be implemented in this file
implementedFunctions: null,
+ // All the function idents seen so far
+ allIdents: [],
+
indexedFunctions: [0, 0], // Start at a non-0 (even, see below) value
// Mark a function as needing indexing, and returns the index
diff --git a/tools/eliminator/eliminator-test.js b/tools/eliminator/eliminator-test.js
index 8a364c0a..d3ee88cb 100644
--- a/tools/eliminator/eliminator-test.js
+++ b/tools/eliminator/eliminator-test.js
@@ -91,3 +91,5 @@ function py() {
var $8 = $4 + 12;
HEAP[$8] = $7;
}
+// EMSCRIPTEN_GENERATED_FUNCTIONS: ["f", "g", "h"]
+
diff --git a/tools/eliminator/eliminator.coffee b/tools/eliminator/eliminator.coffee
index c07e5974..891718e2 100644
--- a/tools/eliminator/eliminator.coffee
+++ b/tools/eliminator/eliminator.coffee
@@ -20,6 +20,10 @@
uglify = require 'uglify-js'
fs = require 'fs'
+# Functions which have been generated by Emscripten. We optimize only those.
+generatedFunctions = []
+GENERATED_FUNCTIONS_MARKER = '// EMSCRIPTEN_GENERATED_FUNCTIONS:'
+
# Maximum number of uses to consider a variable not worth eliminating.
MAX_USES = 3
@@ -79,6 +83,8 @@ traverse = (node, callback) ->
# function/defun node and call run() to apply the optimization (in-place).
class Eliminator
constructor: (func) ->
+ @ident = func[1]
+
# The statements of the function to analyze.
@body = func[3]
@@ -107,7 +113,7 @@ class Eliminator
# @returns: The number of variables eliminated, or undefined if skipped.
run: ->
# Our optimization does not account for closures.
- if @hasClosures @body then return undefined
+ if not @isGenerated then return undefined
@calculateBasicVarStats()
@analyzeInitialValues()
@@ -128,16 +134,8 @@ class Eliminator
return eliminated
# Determines if a function is Emscripten-generated.
- hasClosures: ->
- closureFound = false
-
- traverse @body, (node, type) ->
- if type in ['defun', 'function', 'with']
- closureFound = true
- return false
- return undefined
-
- return closureFound
+ isGenerated: ->
+ return @ident in generatedFunctions
# Runs the basic variable scan pass. Fills the following member variables:
# isLocal
@@ -337,6 +335,12 @@ class Eliminator
main = ->
# Get the parse tree.
src = fs.readFileSync('/dev/stdin').toString()
+
+ throw 'Cannot identify generated functions' if GENERATED_FUNCTIONS_MARKER in src
+ generatedFunctionsLine = src.split('\n').filter (line) ->
+ return line.indexOf(GENERATED_FUNCTIONS_MARKER) == 0
+ generatedFunctions = eval(generatedFunctionsLine[0].replace(GENERATED_FUNCTIONS_MARKER, ''))
+
ast = uglify.parser.parse src
# Run the eliminator on all functions.