diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-11-27 17:26:25 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-11-27 17:26:25 -0800 |
commit | f5d9728cff02741a8e4dddc4e1da54602e88b718 (patch) | |
tree | dc77825f65df2b4b186b8754ae5e68680f86e055 /src | |
parent | 52cc5c714d852d39a8bfd652f331b4f9b76b2f36 (diff) |
fix global indexing bugs
Diffstat (limited to 'src')
-rw-r--r-- | src/jsifier.js | 19 | ||||
-rw-r--r-- | src/parseTools.js | 11 | ||||
-rw-r--r-- | src/utility.js | 8 |
3 files changed, 31 insertions, 7 deletions
diff --git a/src/jsifier.js b/src/jsifier.js index 591dccc4..74dec1e4 100644 --- a/src/jsifier.js +++ b/src/jsifier.js @@ -264,7 +264,7 @@ function JSify(data, functionsOnly, givenFunctions) { } else { var constant = null; var allocator = (BUILD_AS_SHARED_LIB && !item.external) ? 'ALLOC_NORMAL' : 'ALLOC_STATIC'; - var index = 0; + var index = null; if (item.external && BUILD_AS_SHARED_LIB) { // External variables in shared libraries should not be declared as // they would shadow similarly-named globals in the parent. @@ -324,11 +324,14 @@ function JSify(data, functionsOnly, givenFunctions) { constant = makePointer(constant, null, allocator, item.type, index); var js; - js = (index !== null ? '' : item.ident + '=') + constant + ';'; + js = (index !== null ? '' : item.ident + '=') + constant + ';'; // '\n Module.print("' + item.ident + ' :" + ' + makeGlobalUse(item.ident) + ');'; // Special case: class vtables. We make sure they are null-terminated, to allow easy runtime operations if (item.ident.substr(0, 5) == '__ZTV') { - js += '\n' + makePointer('[0]', null, allocator, ['void*'], getFastValue(index, '+', Runtime.alignMemory(calcAllocatedSize(Variables.globals[item.ident].type)))) + ';'; + if (!NAMED_GLOBALS) { + index = getFastValue(index, '+', Runtime.alignMemory(calcAllocatedSize(Variables.globals[item.ident].type))); + } + js += '\n' + makePointer('[0]', null, allocator, ['void*'], index) + ';'; } if (EXPORT_ALL || (item.ident in EXPORTED_GLOBALS)) { js += '\nModule["' + item.ident + '"] = ' + item.ident + ';'; @@ -1297,10 +1300,14 @@ function JSify(data, functionsOnly, givenFunctions) { var globalsData = analyzer(intertyper(data.unparsedGlobalss[0].lines, true), true); if (!NAMED_GLOBALS) { - for (var ident in Variables.globals) { + sortGlobals(globalsData.globalVariables).forEach(function(g) { + var ident = g.ident; Variables.indexedGlobals[ident] = Variables.nextIndexedOffset; Variables.nextIndexedOffset += Runtime.alignMemory(calcAllocatedSize(Variables.globals[ident].type)); - } + if (ident.substr(0, 5) == '__ZTV') { // leave room for null-terminating the vtable + Variables.nextIndexedOffset += Runtime.getNativeTypeSize('i32'); + } + }); } JSify(globalsData, true, Functions); @@ -1368,7 +1375,7 @@ function JSify(data, functionsOnly, givenFunctions) { substrate.addItems(data.functionStubs, 'FunctionStub'); assert(data.functions.length == 0); } else { - substrate.addItems(values(data.globalVariables), 'GlobalVariable'); + substrate.addItems(sortGlobals(data.globalVariables), 'GlobalVariable'); substrate.addItems(data.aliass, 'Alias'); substrate.addItems(data.functions, 'FunctionSplitter'); } diff --git a/src/parseTools.js b/src/parseTools.js index 78ff934e..5d0131dc 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -368,10 +368,19 @@ function makeGlobalDef(ident) { } function makeGlobalUse(ident) { - if (!NAMED_GLOBALS && isIndexableGlobal(ident)) return getFastValue('GLOBAL_BASE', '+', Variables.indexedGlobals[ident]); + if (!NAMED_GLOBALS && isIndexableGlobal(ident)) return '(' + getFastValue('GLOBAL_BASE', '+', Variables.indexedGlobals[ident]) + ')'; return ident; // TODO: add option for namespacing or offsetting to allow reducing the number of globals } +function sortGlobals(globals) { + var ks = keys(globals); + ks.sort(); + var inv = invertArray(ks); + return values(globals).sort(function(a, b) { + return inv[b.ident] - inv[a.ident]; + }); +} + function finalizeParam(param) { if (param.intertype in PARSABLE_LLVM_FUNCTIONS) { return finalizeLLVMFunctionCall(param); diff --git a/src/utility.js b/src/utility.js index f3ece90b..84b50ce9 100644 --- a/src/utility.js +++ b/src/utility.js @@ -282,6 +282,14 @@ function setIntersect(x, y) { return ret; } +function invertArray(x) { + var ret = {}; + for (var i = 0; i < x.length; i++) { + ret[x[i]] = i; + } + return ret; +} + function copy(x) { return JSON.parse(JSON.stringify(x)); } |