diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/analyzer.js | 8 | ||||
-rw-r--r-- | src/compiler.html | 3 | ||||
-rw-r--r-- | src/compiler.js | 27 | ||||
-rw-r--r-- | src/framework.js | 6 | ||||
-rw-r--r-- | src/intertyper.js | 79 | ||||
-rw-r--r-- | src/jsifier.js | 186 | ||||
-rw-r--r-- | src/library.js | 2 | ||||
-rw-r--r-- | src/library_browser.js | 2 | ||||
-rw-r--r-- | src/library_gl.js | 2 | ||||
-rw-r--r-- | src/library_sdl.js | 2 | ||||
-rw-r--r-- | src/modules.js | 2 | ||||
-rw-r--r-- | src/runtime.js | 11 | ||||
-rw-r--r-- | src/settings.js | 328 | ||||
-rw-r--r-- | src/shell_sharedlib.js | 2 | ||||
-rw-r--r-- | src/utility.js | 19 |
15 files changed, 359 insertions, 320 deletions
diff --git a/src/analyzer.js b/src/analyzer.js index d8d285c4..7e3038cf 100644 --- a/src/analyzer.js +++ b/src/analyzer.js @@ -1,10 +1,12 @@ +//"use strict"; + // Analyze intertype data. Calculates things that are necessary in order // to do the final conversion into JavaScript later, for example, // properties of variables, loop structures of functions, etc. -VAR_NATIVE = 'native'; -VAR_NATIVIZED = 'nativized'; -VAR_EMULATED = 'emulated'; +var VAR_NATIVE = 'native'; +var VAR_NATIVIZED = 'nativized'; +var VAR_EMULATED = 'emulated'; function cleanFunc(func) { func.lines = func.lines.filter(function(line) { return line.intertype !== null }); diff --git a/src/compiler.html b/src/compiler.html index 69724076..2a268e81 100644 --- a/src/compiler.html +++ b/src/compiler.html @@ -5,7 +5,8 @@ Open the web console to see stderr output <hr> <pre id="output"></pre> <script> -arguments = ['', '../tests/cases/phicubed.ll']; +arguments = ['', '../poppler.ll']; +//arguments = ['', '../tests/cases/phicubed.ll']; </script> <script src="compiler.js"> </script> diff --git a/src/compiler.js b/src/compiler.js index dbd44f69..6264b583 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -1,3 +1,5 @@ +//"use strict"; + // LLVM => JavaScript compiler, main entry point try { @@ -5,18 +7,23 @@ try { gcparam('maxBytes', 1024*1024*1024); } catch(e) {} +var arguments_ = []; +var globalScope = this; + var ENVIRONMENT_IS_SHELL = typeof window === 'undefined'; if (ENVIRONMENT_IS_SHELL) { // Polyfill over SpiderMonkey/V8 differences - if (!this['load']) { - load = function(f) { eval(snarf(f)) }; - } if (!this['read']) { read = function(f) { snarf(f) }; } + + load = function(f) { eval.call(globalScope, read(f)) }; + if (!this['arguments']) { - arguments = scriptArgs; + arguments_ = scriptArgs; + } else { + arguments_ = arguments; } } else { // We are on the web. @@ -40,11 +47,11 @@ if (ENVIRONMENT_IS_SHELL) { load = function(url) { // We can't just eval naively, we need properties here to be added to the toplevel global. var src = read(url); - eval.call(null, src); + eval.call(globalScope, src); }; - if (!this['arguments']) { - arguments = []; + if (this['arguments']) { + arguments_ = arguments; } } @@ -56,8 +63,8 @@ load('utility.js'); load('settings.js'); -var settings_file = arguments[0]; -var ll_file = arguments[1]; +var settings_file = arguments_[0]; +var ll_file = arguments_[1]; if (settings_file) { var settings = JSON.parse(read(settings_file)); @@ -115,7 +122,7 @@ load('parseTools.js'); load('intertyper.js'); load('analyzer.js'); load('jsifier.js'); -eval(processMacros(preprocess(read('runtime.js')))); +eval.call(globalScope, processMacros(preprocess(read('runtime.js')))); //=============================== // Main diff --git a/src/framework.js b/src/framework.js index 7adf43d3..1a98ca16 100644 --- a/src/framework.js +++ b/src/framework.js @@ -1,3 +1,5 @@ +//"use strict"; + // // A framework to make building Emscripten easier. Lets you write modular // code to handle specific issues. @@ -84,7 +86,7 @@ var MemoryDebugger = { if (DEBUG_MEMORY) MemoryDebugger.clear(); -Substrate = function(name_) { +function Substrate(name_) { this.name_ = name_; this.actors = {}; this.currUid = 1; @@ -234,7 +236,7 @@ var Framework = { currItem: null }; -Actor = function() { }; +function Actor() { }; Actor.prototype = { process: function(items) { var ret = []; diff --git a/src/intertyper.js b/src/intertyper.js index ed2b3fb9..0f75edca 100644 --- a/src/intertyper.js +++ b/src/intertyper.js @@ -1,3 +1,5 @@ +//"use strict"; + // LLVM assembly => internal intermediate representation, which is ready // to be processed by the later stages. @@ -286,7 +288,7 @@ function intertyper(data, sidePass, baseLineNum) { } }); - MATHOPS = set(['add', 'sub', 'sdiv', 'udiv', 'mul', 'icmp', 'zext', 'urem', 'srem', 'fadd', 'fsub', 'fmul', 'fdiv', 'fcmp', 'uitofp', 'sitofp', 'fpext', 'fptrunc', 'fptoui', 'fptosi', 'trunc', 'sext', 'select', 'shl', 'shr', 'ashl', 'ashr', 'lshr', 'lshl', 'xor', 'or', 'and', 'ptrtoint', 'inttoptr']); + var MATHOPS = set(['add', 'sub', 'sdiv', 'udiv', 'mul', 'icmp', 'zext', 'urem', 'srem', 'fadd', 'fsub', 'fmul', 'fdiv', 'fcmp', 'uitofp', 'sitofp', 'fpext', 'fptrunc', 'fptoui', 'fptosi', 'trunc', 'sext', 'select', 'shl', 'shr', 'ashl', 'ashr', 'lshr', 'lshl', 'xor', 'or', 'and', 'ptrtoint', 'inttoptr']); substrate.addActor('Triager', { processItem: function(item) { @@ -373,6 +375,43 @@ function intertyper(data, sidePass, baseLineNum) { substrate.addActor('Global', { processItem: function(item) { function scanConst(value, type) { + // Gets an array of constant items, separated by ',' tokens + function handleSegments(tokens) { + // Handle a single segment (after comma separation) + function handleSegment(segment) { + if (segment[1].text == 'null') { + return { intertype: 'value', value: 0, type: 'i32' }; + } else if (segment[1].text == 'zeroinitializer') { + Types.needAnalysis[segment[0].text] = 0; + return { intertype: 'emptystruct', type: segment[0].text }; + } else if (segment[1].text in PARSABLE_LLVM_FUNCTIONS) { + return parseLLVMFunctionCall(segment); + } else if (segment[1].type && segment[1].type == '{') { + Types.needAnalysis[segment[0].text] = 0; + return { intertype: 'struct', type: segment[0].text, contents: handleSegments(segment[1].tokens) }; + } else if (segment[1].type && segment[1].type == '<') { + Types.needAnalysis[segment[0].text] = 0; + return { intertype: 'struct', type: segment[0].text, contents: handleSegments(segment[1].item.tokens[0].tokens) }; + } else if (segment[1].type && segment[1].type == '[') { + Types.needAnalysis[segment[0].text] = 0; + return { intertype: 'list', type: segment[0].text, contents: handleSegments(segment[1].item.tokens) }; + } else if (segment.length == 2) { + Types.needAnalysis[segment[0].text] = 0; + return { intertype: 'value', type: segment[0].text, value: toNiceIdent(segment[1].text) }; + } else if (segment[1].text === 'c') { + // string + var text = segment[2].text; + text = text.substr(1, text.length-2); + return { intertype: 'string', text: text, type: 'i8*' }; + } else if (segment[1].text === 'blockaddress') { + return parseBlockAddress(segment); + } else { + throw 'Invalid segment: ' + dump(segment); + } + }; + return splitTokenList(tokens).map(handleSegment); + } + Types.needAnalysis[type] = 0; if (Runtime.isNumberType(type) || pointingLevels(type) >= 1) { return { value: toNiceIdent(value.text), type: type }; @@ -381,42 +420,6 @@ function intertyper(data, sidePass, baseLineNum) { } else if (value.text && value.text[0] == '"') { return { intertype: 'string', text: value.text.substr(1, value.text.length-2) }; } else { - // Gets an array of constant items, separated by ',' tokens - function handleSegments(tokens) { - // Handle a single segment (after comma separation) - function handleSegment(segment) { - if (segment[1].text == 'null') { - return { intertype: 'value', value: 0, type: 'i32' }; - } else if (segment[1].text == 'zeroinitializer') { - Types.needAnalysis[segment[0].text] = 0; - return { intertype: 'emptystruct', type: segment[0].text }; - } else if (segment[1].text in PARSABLE_LLVM_FUNCTIONS) { - return parseLLVMFunctionCall(segment); - } else if (segment[1].type && segment[1].type == '{') { - Types.needAnalysis[segment[0].text] = 0; - return { intertype: 'struct', type: segment[0].text, contents: handleSegments(segment[1].tokens) }; - } else if (segment[1].type && segment[1].type == '<') { - Types.needAnalysis[segment[0].text] = 0; - return { intertype: 'struct', type: segment[0].text, contents: handleSegments(segment[1].item.tokens[0].tokens) }; - } else if (segment[1].type && segment[1].type == '[') { - Types.needAnalysis[segment[0].text] = 0; - return { intertype: 'list', type: segment[0].text, contents: handleSegments(segment[1].item.tokens) }; - } else if (segment.length == 2) { - Types.needAnalysis[segment[0].text] = 0; - return { intertype: 'value', type: segment[0].text, value: toNiceIdent(segment[1].text) }; - } else if (segment[1].text === 'c') { - // string - var text = segment[2].text; - text = text.substr(1, text.length-2); - return { intertype: 'string', text: text, type: 'i8*' }; - } else if (segment[1].text === 'blockaddress') { - return parseBlockAddress(segment); - } else { - throw 'Invalid segment: ' + dump(segment); - } - }; - return splitTokenList(tokens).map(handleSegment); - } if (value.type == '<') { // <{ i8 }> etc. value = value.item.tokens; } @@ -521,7 +524,7 @@ function intertyper(data, sidePass, baseLineNum) { } }); // function header - funcHeader = substrate.addActor('FuncHeader', { + var funcHeader = substrate.addActor('FuncHeader', { processItem: function(item) { item.tokens = item.tokens.filter(function(token) { return !(token.text in LLVM.LINKAGES || token.text in LLVM.PARAM_ATTR || token.text in set('hidden', 'nounwind', 'define', 'inlinehint', '{') || token.text in LLVM.CALLING_CONVENTIONS); diff --git a/src/jsifier.js b/src/jsifier.js index 3ba725bb..e138f6f4 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -1,3 +1,5 @@ +//"use strict"; + // Convert analyzed data to javascript. Everything has already been calculated // before this stage, which just does the final conversion to JavaScript. @@ -182,6 +184,32 @@ function JSify(data, functionsOnly, givenFunctions) { // Gets an entire constant expression function makeConst(value, type, ident) { + // Gets an array of constant items, separated by ',' tokens + function handleSegments(tokens) { + // Handle a single segment (after comma separation) + function handleSegment(segment) { + var ret; + if (segment.intertype === 'value') { + ret = segment.value.toString(); + } else if (segment.intertype === 'emptystruct') { + ret = makeEmptyStruct(segment.type); + } else if (segment.intertype in PARSABLE_LLVM_FUNCTIONS) { + ret = finalizeLLVMFunctionCall(segment); + } else if (segment.intertype in set('struct', 'list')) { + ret = alignStruct(handleSegments(segment.contents), segment.type); + } else if (segment.intertype === 'string') { + ret = parseLLVMString(segment.text); // + ' /* ' + text + '*/'; + } else if (segment.intertype === 'blockaddress') { + ret = finalizeBlockAddress(segment); + } else { + throw 'Invalid segment: ' + dump(segment); + } + assert(segment.type, 'Missing type for constant segment!'); + return indexizeFunctions(ret, segment.type); + }; + return tokens.map(handleSegment) + } + //dprint('jsifier const: ' + JSON.stringify(value) + ',' + type + '\n'); if (value.intertype in PARSABLE_LLVM_FUNCTIONS) { return [finalizeLLVMFunctionCall(value)]; @@ -193,31 +221,6 @@ function JSify(data, functionsOnly, givenFunctions) { return JSON.stringify(parseLLVMString(value.text)) + ' /* ' + value.text.substr(0, 20).replace(/\*/g, '_') + ' */'; // make string safe for inclusion in comment } else { - // Gets an array of constant items, separated by ',' tokens - function handleSegments(tokens) { - // Handle a single segment (after comma separation) - function handleSegment(segment) { - var ret; - if (segment.intertype === 'value') { - ret = segment.value.toString(); - } else if (segment.intertype === 'emptystruct') { - ret = makeEmptyStruct(segment.type); - } else if (segment.intertype in PARSABLE_LLVM_FUNCTIONS) { - ret = finalizeLLVMFunctionCall(segment); - } else if (segment.intertype in set('struct', 'list')) { - ret = alignStruct(handleSegments(segment.contents), segment.type); - } else if (segment.intertype === 'string') { - ret = parseLLVMString(segment.text); // + ' /* ' + text + '*/'; - } else if (segment.intertype === 'blockaddress') { - ret = finalizeBlockAddress(segment); - } else { - throw 'Invalid segment: ' + dump(segment); - } - assert(segment.type, 'Missing type for constant segment!'); - return indexizeFunctions(ret, segment.type); - }; - return tokens.map(handleSegment) - } return alignStruct(handleSegments(value.contents), type); } } @@ -233,6 +236,10 @@ function JSify(data, functionsOnly, givenFunctions) { // globalVariable substrate.addActor('GlobalVariable', { processItem: function(item) { + function needsPostSet(value) { + return value[0] in set('_', '(') || value.substr(0, 14) === 'CHECK_OVERFLOW'; + } + item.intertype = 'GlobalVariableStub'; assert(!item.lines); // FIXME remove this, after we are sure it isn't needed var ret = [item]; @@ -275,10 +282,6 @@ function JSify(data, functionsOnly, givenFunctions) { } return ret; } else { - function needsPostSet(value) { - return value[0] in set('_', '(') || value.substr(0, 14) === 'CHECK_OVERFLOW'; - } - constant = parseConst(item.value, item.type, item.ident); if (typeof constant === 'string' && constant[0] != '[') { constant = [constant]; // A single item. We may need a postset for it. @@ -340,6 +343,68 @@ function JSify(data, functionsOnly, givenFunctions) { // functionStub substrate.addActor('FunctionStub', { processItem: function(item) { + function addFromLibrary(ident) { + if (ident in addedLibraryItems) return ''; + // Don't replace implemented functions with library ones (which can happen when we add dependencies). + // Note: We don't return the dependencies here. Be careful not to end up where this matters + if (('_' + ident) in Functions.implementedFunctions) return ''; + + addedLibraryItems[ident] = true; + var snippet = LibraryManager.library[ident]; + var redirectedIdent = null; + var deps = LibraryManager.library[ident + '__deps'] || []; + var isFunction = false; + + if (typeof snippet === 'string') { + if (LibraryManager.library[snippet]) { + // Redirection for aliases. We include the parent, and at runtime make ourselves equal to it. + // This avoid having duplicate functions with identical content. + redirectedIdent = snippet; + deps.push(snippet); + snippet = '_' + snippet; + } + } else if (typeof snippet === 'object') { + snippet = stringifyWithFunctions(snippet); + } else if (typeof snippet === 'function') { + isFunction = true; + snippet = snippet.toString(); + assert(snippet.indexOf('XXX missing C define') == -1, + 'Trying to include a library function with missing C defines: ' + ident + ' | ' + snippet); + + // name the function; overwrite if it's already named + snippet = snippet.replace(/function(?:\s+([^(]+))?\s*\(/, 'function _' + ident + '('); + if (LIBRARY_DEBUG) { + snippet = snippet.replace('{', '{ print("[library call:' + ident + ']"); '); + } + } + + var postsetId = ident + '__postset'; + var postset = LibraryManager.library[postsetId]; + if (postset && !addedLibraryItems[postsetId]) { + addedLibraryItems[postsetId] = true; + ret.push({ + intertype: 'GlobalVariablePostSet', + JS: postset + }); + } + + if (redirectedIdent) { + deps = deps.concat(LibraryManager.library[redirectedIdent + '__deps'] || []); + } + // $ident's are special, we do not prefix them with a '_'. + if (ident[0] === '$') { + ident = ident.substr(1); + } else { + ident = '_' + ident; + } + var text = (deps ? '\n' + deps.map(addFromLibrary).join('\n') : ''); + text += isFunction ? snippet : 'var ' + ident + '=' + snippet + ';'; + if (ident in EXPORTED_FUNCTIONS) { + text += '\nModule["' + ident + '"] = ' + ident + ';'; + } + return text; + } + var ret = [item]; if (IGNORED_FUNCTIONS.indexOf(item.ident) >= 0) return null; var shortident = item.ident.substr(1); @@ -347,67 +412,6 @@ function JSify(data, functionsOnly, givenFunctions) { // Shared libraries reuse the runtime of their parents. item.JS = ''; } else if (LibraryManager.library.hasOwnProperty(shortident)) { - function addFromLibrary(ident) { - if (ident in addedLibraryItems) return ''; - // Don't replace implemented functions with library ones (which can happen when we add dependencies). - // Note: We don't return the dependencies here. Be careful not to end up where this matters - if (('_' + ident) in Functions.implementedFunctions) return ''; - - addedLibraryItems[ident] = true; - var snippet = LibraryManager.library[ident]; - var redirectedIdent = null; - var deps = LibraryManager.library[ident + '__deps'] || []; - var isFunction = false; - - if (typeof snippet === 'string') { - if (LibraryManager.library[snippet]) { - // Redirection for aliases. We include the parent, and at runtime make ourselves equal to it. - // This avoid having duplicate functions with identical content. - redirectedIdent = snippet; - deps.push(snippet); - snippet = '_' + snippet; - } - } else if (typeof snippet === 'object') { - snippet = stringifyWithFunctions(snippet); - } else if (typeof snippet === 'function') { - isFunction = true; - snippet = snippet.toString(); - assert(snippet.indexOf('XXX missing C define') == -1, - 'Trying to include a library function with missing C defines: ' + ident + ' | ' + snippet); - - // name the function; overwrite if it's already named - snippet = snippet.replace(/function(?:\s+([^(]+))?\s*\(/, 'function _' + ident + '('); - if (LIBRARY_DEBUG) { - snippet = snippet.replace('{', '{ print("[library call:' + ident + ']"); '); - } - } - - var postsetId = ident + '__postset'; - var postset = LibraryManager.library[postsetId]; - if (postset && !addedLibraryItems[postsetId]) { - addedLibraryItems[postsetId] = true; - ret.push({ - intertype: 'GlobalVariablePostSet', - JS: postset - }); - } - - if (redirectedIdent) { - deps = deps.concat(LibraryManager.library[redirectedIdent + '__deps'] || []); - } - // $ident's are special, we do not prefix them with a '_'. - if (ident[0] === '$') { - ident = ident.substr(1); - } else { - ident = '_' + ident; - } - var text = (deps ? '\n' + deps.map(addFromLibrary).join('\n') : ''); - text += isFunction ? snippet : 'var ' + ident + '=' + snippet + ';'; - if (ident in EXPORTED_FUNCTIONS) { - text += '\nModule["' + ident + '"] = ' + ident + ';'; - } - return text; - } item.JS = addFromLibrary(shortident); } else { item.JS = 'var ' + item.ident + '; // stub for ' + item.ident; @@ -776,7 +780,7 @@ function JSify(data, functionsOnly, givenFunctions) { }); var pre = '', post = '', idents; mainLoop: while ((idents = keys(deps)).length > 0) { - function remove(ident) { + var remove = function(ident) { for (var i = 0; i < idents.length; i++) { delete deps[idents[i]][ident]; } diff --git a/src/library.js b/src/library.js index 2a67ee88..113c955c 100644 --- a/src/library.js +++ b/src/library.js @@ -1,3 +1,5 @@ +//"use strict"; + // An implementation of a libc for the web. Basically, implementations of // the various standard C libraries, that can be called from compiled code, // and work using the actual JavaScript environment. diff --git a/src/library_browser.js b/src/library_browser.js index c4d1d768..9c3057b8 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -1,3 +1,5 @@ +//"use strict"; + // Utilities for browser environments mergeInto(LibraryManager.library, { diff --git a/src/library_gl.js b/src/library_gl.js index 20197141..f22eabcb 100644 --- a/src/library_gl.js +++ b/src/library_gl.js @@ -1,3 +1,5 @@ +//"use strict"; + // XXX FIXME Hardcoded '4' in many places, here and in library_SDL, for RGBA var LibraryGL = { diff --git a/src/library_sdl.js b/src/library_sdl.js index acc14fb9..45b0bb53 100644 --- a/src/library_sdl.js +++ b/src/library_sdl.js @@ -1,3 +1,5 @@ +//"use strict"; + // To use emscripten's SDL library here, you need to define // Module.canvas and at least one of Module.ctx2D, Module.ctxGL. // diff --git a/src/modules.js b/src/modules.js index 39baabba..bf1c0a7d 100644 --- a/src/modules.js +++ b/src/modules.js @@ -1,3 +1,5 @@ +//"use strict"; + // Various namespace-like modules var LLVM_STYLE = null; diff --git a/src/runtime.js b/src/runtime.js index 255b977e..7e28b08e 100644 --- a/src/runtime.js +++ b/src/runtime.js @@ -1,10 +1,12 @@ +//"use strict"; + // Implementation details for the 'runtime environment' we generate in // JavaScript. The Runtime object itself is used both during compilation, // and is available at runtime (dynamic compilation). The RuntimeGenerator // helps to create the Runtime object (written so that the Runtime object // itself is as optimized as possible - no unneeded runtime checks). -RuntimeGenerator = { +var RuntimeGenerator = { alloc: function(size, type, init) { var ret = type + 'TOP'; if (ASSERTIONS) { @@ -66,11 +68,12 @@ RuntimeGenerator = { }; function unInline(name_, params) { - var src = '(function ' + name_ + '(' + params + ') { var ret = ' + RuntimeGenerator[name_].apply(null, params) + '; return ret; })'; - return eval(src); + var src = '(function ' + name_ + '(' + params + ') { var ret = ' + RuntimeGenerator[name_].apply(globalScope, params) + '; return ret; })'; + var ret = eval.call(globalScope, src); + return ret; } -Runtime = { +var Runtime = { stackSave: function() { return STACKTOP; }, diff --git a/src/settings.js b/src/settings.js index acdb8c14..bcda4757 100644 --- a/src/settings.js +++ b/src/settings.js @@ -1,183 +1,185 @@ +//"use strict"; + // Tuning -QUANTUM_SIZE = 4; // This is the size of an individual field in a structure. 1 would - // lead to e.g. doubles and chars both taking 1 memory address. This - // is a form of 'compressed' memory, with shrinking and stretching - // according to the type, when compared to C/C++. On the other hand - // the normal value of 4 means all fields take 4 memory addresses, - // as per the norm on a 32-bit machine. - // - // 1 is somewhat faster than 4, but dangerous. - -CORRECT_SIGNS = 1; // Whether we make sure to convert unsigned values to signed values. - // Decreases performance with additional runtime checks. Might not be - // needed in some kinds of code. - // If equal to 2, done on a line-by-line basis according to - // CORRECT_SIGNS_LINES, correcting only the specified lines. - // If equal to 3, correcting all *but* the specified lines -CHECK_SIGNS = 0; // Runtime errors for signing issues that need correcting. - // It is recommended to use this in - // order to find if your code needs CORRECT_SIGNS. If you can get your - // code to run without CORRECT_SIGNS, it will run much faster - -ASSERTIONS = 1; // Whether we should add runtime assertions, for example to - // check that each allocation to the stack does not - // exceed it's size, whether all allocations (stack and static) are - // of positive size, etc., whether we should throw if we encounter a bad __label__, i.e., - // if code flow runs into a fault - -INVOKE_RUN = 1; // Whether we will call run(). Disable if you embed the generated - // code in your own, and will call run() yourself at the right time -INIT_STACK = 1; // Whether to initialize memory on the stack to 0. -INIT_HEAP = 0; // Whether to initialize memory anywhere other than the stack to 0. -FAST_MEMORY = 2*1024*1024; // The amount of memory to initialize to 0. This ensures it will be - // in a flat array. This only matters in non-typed array builds. -TOTAL_MEMORY = 50*1024*1024; // The total amount of memory to use. This mainly matters in - // typed array builds - accessing memory about this value will - // return undefined values and lead to serious problems, and there - // is currently no warning about that! +var QUANTUM_SIZE = 4; // This is the size of an individual field in a structure. 1 would + // lead to e.g. doubles and chars both taking 1 memory address. This + // is a form of 'compressed' memory, with shrinking and stretching + // according to the type, when compared to C/C++. On the other hand + // the normal value of 4 means all fields take 4 memory addresses, + // as per the norm on a 32-bit machine. + // + // 1 is somewhat faster than 4, but dangerous. + +var CORRECT_SIGNS = 1; // Whether we make sure to convert unsigned values to signed values. + // Decreases performance with additional runtime checks. Might not be + // needed in some kinds of code. + // If equal to 2, done on a line-by-line basis according to + // CORRECT_SIGNS_LINES, correcting only the specified lines. + // If equal to 3, correcting all *but* the specified lines +var CHECK_SIGNS = 0; // Runtime errors for signing issues that need correcting. + // It is recommended to use this in + // order to find if your code needs CORRECT_SIGNS. If you can get your + // code to run without CORRECT_SIGNS, it will run much faster + +var ASSERTIONS = 1; // Whether we should add runtime assertions, for example to + // check that each allocation to the stack does not + // exceed it's size, whether all allocations (stack and static) are + // of positive size, etc., whether we should throw if we encounter a bad __label__, i.e., + // if code flow runs into a fault + +var INVOKE_RUN = 1; // Whether we will call run(). Disable if you embed the generated + // code in your own, and will call run() yourself at the right time +var INIT_STACK = 1; // Whether to initialize memory on the stack to 0. +var INIT_HEAP = 0; // Whether to initialize memory anywhere other than the stack to 0. +var FAST_MEMORY = 2*1024*1024; // The amount of memory to initialize to 0. This ensures it will be + // in a flat array. This only matters in non-typed array builds. +var TOTAL_MEMORY = 50*1024*1024; // The total amount of memory to use. This mainly matters in + // typed array builds - accessing memory about this value will + // return undefined values and lead to serious problems, and there + // is currently no warning about that! // Code embetterments -MICRO_OPTS = 0; // Various micro-optimizations, like nativizing variables -RELOOP = 0; // Recreate js native loops from llvm data -USE_TYPED_ARRAYS = 0; // Try to use typed arrays for the heap - // 1 has two heaps, IHEAP (int32) and FHEAP (double), - // and addresses there are a match for normal addresses. This wastes memory but can be fast. - // 2 is a single heap, accessible through views as int8, int32, etc. This saves memory but - // has more overhead of pointer calculations. It also is limited to storing doubles as floats, - // simply because double stores are not necessarily 64-bit aligned, and we can only access - // 64-bit aligned values with a 64-bit typed array. Likewise int64s are stored as int32's, - // which is potentially very dangerous! - // TODO: require compiling with -malign-double, which does align doubles -USE_FHEAP = 1; // Relevant in USE_TYPED_ARRAYS == 1. If this is disabled, only IHEAP will be used, and FHEAP - // not generated at all. This is useful if your code is 100% ints without floats or doubles -I64_MODE = 0; // How to implement 64-bit integers: - // 0: As doubles. This will work up to about 53 bits. - // 1: As [low, high]. This will support all 64 bits for bit ops, etc. properly, but will still - // use doubles for addition etc., like mode 0. This mode is slower than - // mode 0, so its only benefit is proper support for 64 bit bitops. - // TODO: Full bignum support -EMULATE_UNALIGNED_ACCESSES = 1; // If set, the compiler will 'emulate' loads and stores that are not known to - // be sufficiently aligned, by working on individual bytes. This can be - // important in USE_TYPED_ARRAYS == 2, where unaligned accesses do not work, - // specifically in the case where unsafe LLVM optimizations have generated possibly - // unaligned code. (Without unsafe LLVM optimizations, there should be no - // need for this option.) - // Currently this only works for integers, not doubles and floats. - -SKIP_STACK_IN_SMALL = 1; // When enabled, does not push/pop the stack at all in - // functions that have no basic stack usage. But, they - // may allocate stack later, and in a loop, this can be - // very bad. In particular, when debugging, printf()ing - // a lot can exhaust the stack very fast, with this option. - // In particular, be careful with the autodebugger! -INLINE_LIBRARY_FUNCS = 1; // Will inline library functions that have __inline defined -CLOSURE_INLINE_PREVENTION_LINES = 50; // Functions of this number of lines or larger will have - // code generated that tells the closure compiler not to - // inline them. This is useful to prevent the generation of - // overly large functions. +var MICRO_OPTS = 0; // Various micro-optimizations, like nativizing variables +var RELOOP = 0; // Recreate js native loops from llvm data +var USE_TYPED_ARRAYS = 0; // Try to use typed arrays for the heap + // 1 has two heaps, IHEAP (int32) and FHEAP (double), + // and addresses there are a match for normal addresses. This wastes memory but can be fast. + // 2 is a single heap, accessible through views as int8, int32, etc. This saves memory but + // has more overhead of pointer calculations. It also is limited to storing doubles as floats, + // simply because double stores are not necessarily 64-bit aligned, and we can only access + // 64-bit aligned values with a 64-bit typed array. Likewise int64s are stored as int32's, + // which is potentially very dangerous! + // TODO: require compiling with -malign-double, which does align doubles +var USE_FHEAP = 1; // Relevant in USE_TYPED_ARRAYS == 1. If this is disabled, only IHEAP will be used, and FHEAP + // not generated at all. This is useful if your code is 100% ints without floats or doubles +var I64_MODE = 0; // How to implement 64-bit integers: + // 0: As doubles. This will work up to about 53 bits. + // 1: As [low, high]. This will support all 64 bits for bit ops, etc. properly, but will still + // use doubles for addition etc., like mode 0. This mode is slower than + // mode 0, so its only benefit is proper support for 64 bit bitops. + // TODO: Full bignum support +var EMULATE_UNALIGNED_ACCESSES = 1; // If set, the compiler will 'emulate' loads and stores that are not known to + // be sufficiently aligned, by working on individual bytes. This can be + // important in USE_TYPED_ARRAYS == 2, where unaligned accesses do not work, + // specifically in the case where unsafe LLVM optimizations have generated possibly + // unaligned code. (Without unsafe LLVM optimizations, there should be no + // need for this option.) + // Currently this only works for integers, not doubles and floats. + + |