aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-03-15 20:13:57 -0700
committerAlon Zakai <alonzakai@gmail.com>2011-03-15 20:13:57 -0700
commit5524f8bf30941862789eadef176b254fe3186cdf (patch)
treed0fed0756943a15ac4ee6a259a8f462c92a8c543 /src
parent6c22a66671b6f42ad63044b0fd46a5dc892298b4 (diff)
stop using lots of memory to manage strings at the end of compilation
Diffstat (limited to 'src')
-rw-r--r--src/compiler.js2
-rw-r--r--src/jsifier.js47
-rw-r--r--src/library.js2
-rw-r--r--src/parseTools.js10
4 files changed, 41 insertions, 20 deletions
diff --git a/src/compiler.js b/src/compiler.js
index b60f650e..1a48fad2 100644
--- a/src/compiler.js
+++ b/src/compiler.js
@@ -58,5 +58,5 @@ do {
// Do it
-print(JSify(analyzer(intertyper(lines))));
+JSify(analyzer(intertyper(lines)));
diff --git a/src/jsifier.js b/src/jsifier.js
index 6742f33c..7a25983c 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -1135,28 +1135,39 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
});
items = null;
- var ret = [];
+ var generated = [];
if (!functionsOnly) {
- ret = ret.concat(itemsDict.type).concat(itemsDict.GlobalVariableStub).concat(itemsDict.functionStub);
+ generated = generated.concat(itemsDict.type).concat(itemsDict.GlobalVariableStub).concat(itemsDict.functionStub);
}
- ret = ret.concat(itemsDict.function).concat(data.unparsedFunctions);
-
- ret = ret.map(function(item) { return item.JS }).join('\n');
-
- if (functionsOnly) return ret;
+ generated = generated.concat(itemsDict.function).concat(data.unparsedFunctions);
+
+ if (functionsOnly) 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
+ // manipulations may create in-memory copies, and we may OOM.
+ //
+ // Final shape that we now create:
+ // shell
+ // (body)
+ // preamble
+ // runtime
+ // generated code
+ // postamble
+ // global_vars
- var pre = preprocess(read('preamble.js').replace('{{RUNTIME}}', getRuntime()), CONSTANTS);
- var post = preprocess(read('postamble.js'), CONSTANTS);
- ret = pre + ret + post;
- var globalVars = itemsDict.GlobalVariable.map(function(item) { return item.JS }).join('\n');
- var globalVarsPostSets = itemsDict.GlobalVariablePostSet.map(function(item) { return item.JS }).join('\n');
- ret = indentify(ret, 2);
- // ret may be a very large string at this point - we may not be able to allocate two of it. So must be careful in these last steps
var shellParts = read('shell.js').split('{{BODY}}');
- ret = shellParts[0] + ret + shellParts[1];
- globalVars = indentify(globalVars+'\n\n\n'+globalVarsPostSets, 4);
- ret = ret.replace('{{GLOBAL_VARS}}', globalVars);
- return processMacros(ret);
+ print(shellParts[0]);
+ var pre = processMacros(preprocess(read('preamble.js').replace('{{RUNTIME}}', getRuntime()), CONSTANTS));
+ print(pre);
+ generated.forEach(function(item) { print(indentify(item.JS || '', 2)); });
+
+ var postParts = processMacros(preprocess(read('postamble.js'), CONSTANTS)).split('{{GLOBAL_VARS}}');
+ print(postParts[0]);
+ itemsDict.GlobalVariable.forEach(function(item) { print(indentify(item.JS, 4)); });
+ itemsDict.GlobalVariablePostSet.forEach(function(item) { print(indentify(item.JS, 4)); });
+ print(postParts[1]);
+ print(shellParts[1]);
}
// Data
diff --git a/src/library.js b/src/library.js
index 1eadfa8b..81eb358a 100644
--- a/src/library.js
+++ b/src/library.js
@@ -1138,7 +1138,7 @@ var Library = {
// setjmp.h
_setjmp: function(env) {
- print('WARNING: setjmp() not really implemented, will fail if longjmp() is actually called');
+ // XXX print('WARNING: setjmp() not really implemented, will fail if longjmp() is actually called');
return 0;
},
diff --git a/src/parseTools.js b/src/parseTools.js
index 92041f21..94ea4f46 100644
--- a/src/parseTools.js
+++ b/src/parseTools.js
@@ -1,6 +1,15 @@
// Various tools for parsing LLVM. Utilities of various sorts, that are
// specific to Emscripten (and hence not in utility.js).
+// Does simple 'macro' substitution, using Django-like syntax,
+// {{{ code }}} will be replaced with |eval(code)|.
+function processMacros(text) {
+ return text.replace(/{{{[^}]+}}}/g, function(str) {
+ str = str.substr(3, str.length-6);
+ return eval(str).toString();
+ });
+}
+
// Simple #if/else/endif preprocessing for a file. Checks if the
// ident checked is true in our global. Also replaces some constants.
function preprocess(text, constants) {
@@ -545,6 +554,7 @@ function getActualLabelId(labelId) {
// Misc
function indentify(text, indent) {
+ if (text.length > 1024*1024) return text; // Don't try to indentify huge strings - we may run out of memory
if (typeof indent === 'number') {
var len = indent;
indent = '';