diff options
author | partouf <partouf@gmail.com> | 2017-11-28 03:11:16 +0100 |
---|---|---|
committer | partouf <partouf@gmail.com> | 2017-11-28 03:11:16 +0100 |
commit | fe63adc4bc7fb06c5b88faddd3cca3c38bd0dee4 (patch) | |
tree | 7fbaa0547d82d2011b620ff71e50f62648e1a6ce /lib/compilers/pascal.js | |
parent | b6beea085a93c1f30df5b5a003eae12e9464a1e7 (diff) | |
download | compiler-explorer-fe63adc4bc7fb06c5b88faddd3cca3c38bd0dee4.tar.gz compiler-explorer-fe63adc4bc7fb06c5b88faddd3cca3c38bd0dee4.zip |
seperated pascal demangler from pascal compiler, added unit tests and bugfixed some demangling
Diffstat (limited to 'lib/compilers/pascal.js')
-rw-r--r-- | lib/compilers/pascal.js | 171 |
1 files changed, 104 insertions, 67 deletions
diff --git a/lib/compilers/pascal.js b/lib/compilers/pascal.js index 0099d7c7c..62b09cd60 100644 --- a/lib/compilers/pascal.js +++ b/lib/compilers/pascal.js @@ -21,6 +21,7 @@ // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. +"use strict"; var Compile = require('../base-compiler'), logger = require('../logger').logger, @@ -28,46 +29,82 @@ var Compile = require('../base-compiler'), fs = require("fs"), path = require("path"); -function compileFPC(info, env) { - var compiler = new Compile(info, env); - compiler.supportsOptOutput = false; +class PascalDemangler { + constructor() { + this.symbolcache = {}; + this.sortedsymbolcache = []; + this.fixedsymbols = {}; + this.ignoredsymbols = []; + + this.initBasicSymbols(); + } + + initBasicSymbols() { + this.fixedsymbols.OUTPUT_$$_init = 'unit_initialization'; + this.fixedsymbols.OUTPUT_$$_finalize = 'unit_finalization'; + this.fixedsymbols.OUTPUT_$$_init_implicit = 'unit_initialization_implicit'; + this.fixedsymbols.OUTPUT_$$_finalize_implicit ='unit_finalization_implicit'; + this.fixedsymbols.OUTPUT_init = 'unit_initialization'; + this.fixedsymbols.OUTPUT_finalize = 'unit_finalization'; + this.fixedsymbols.OUTPUT_init_implicit = 'unit_initialization_implicit'; + this.fixedsymbols.OUTPUT_finalize_implicit = 'unit_finalization_implicit'; + + this.ignoredsymbols = [ + ".L", + "VMT_$", "INIT_$", "INIT$_$", "FINALIZE$_$", "RTTI_$", + "VMT_OUTPUT_", "INIT$_OUTPUT", "RTTI_OUTPUT_", "FINALIZE$_OUTPUT", + "_$", + "DEBUGSTART_$", "DEBUGEND_$", "DBG_$", "DBG2_$", "DBGREF_$", + "DEBUGSTART_OUTPUT", "DEBUGEND_OUTPUT", "DBG_OUTPUT_", "DBG2_OUTPUT_", "DBGREF_OUTPUT_" + ]; + } + + shouldIgnoreSymbol(text) { + for (var k in this.ignoredsymbols) { + if (text.startsWith(this.ignoredsymbols[k])) { + return true; + } + } - var originalExecBinary = compiler.execBinary; + return false; + } + + composeReadableMethodSignature(unitname, classname, methodname, params) { + var signature = ""; - var symbolcache = {}; - var sortedsymbolcache = []; - var fixedsymbols = {}; - var ignoredsymbols = []; + if (classname != "") signature = classname.toLowerCase() + "."; - fixedsymbols.OUTPUT_$$_init = 'unit_initialization'; - fixedsymbols.OUTPUT_$$_finalize = 'unit_finalization'; - fixedsymbols.OUTPUT_$$_init_implicit = 'unit_initialization_implicit'; - fixedsymbols.OUTPUT_$$_finalize_implicit ='unit_finalization_implicit'; + signature = signature + methodname.toLowerCase(); + signature = signature + "(" + params.toLowerCase() + ")"; - ignoredsymbols = [ - ".L", "VMT_$", "INIT_$", "INIT$_$", "FINALIZE$_$", "RTTI_$", "_$", - "DEBUGSTART_$", "DEBUGEND_$", "DBG_$", "DBG2_$", "DBGREF_$"]; + return signature; + } - var addDemangleToCache = function(text) { + demangle(text) { if (text.endsWith(':')) { - if (shouldIgnoreSymbol(text)) { - return; + if (this.shouldIgnoreSymbol(text)) { + return false; } - for (var k in fixedsymbols) { - if (text.startsWith(k)) { - text = text.replace(k, fixedsymbols[k]); - symbolcache[k] = fixedsymbols[k]; - return; + text = text.substr(0, text.length - 1); + + for (var k in this.fixedsymbols) { + if (text == k) { + text = text.replace(k, this.fixedsymbols[k]); + this.symbolcache[k] = this.fixedsymbols[k]; + return this.fixedsymbols[k]; } } - text = text.substr(0, text.length - 1); - + var unmangledglobalvar; if (text.startsWith("U_$OUTPUT_$$_")) { - var unmangledglobalvar = text.substr(13).toLowerCase(); - symbolcache[text] = unmangledglobalvar; - return; + unmangledglobalvar = text.substr(13).toLowerCase(); + this.symbolcache[text] = unmangledglobalvar; + return unmangledglobalvar; + } else if (text.startsWith("U_OUTPUT_")) { + unmangledglobalvar = text.substr(9).toLowerCase(); + this.symbolcache[text] = unmangledglobalvar; + return unmangledglobalvar; } var idx, paramtype = "", signature = "", phase = 0; @@ -128,67 +165,67 @@ function compileFPC(info, env) { } } - symbolcache[text] = composeReadableMethodSignature(unitname, classname, methodname, params); + this.symbolcache[text] = this.composeReadableMethodSignature(unitname, classname, methodname, params); + return this.symbolcache[text]; } - }; - - var composeReadableMethodSignature = function (unitname, classname, methodname, params) { - var signature = ""; - - if (classname != "") signature = classname.toLowerCase() + "."; - signature = signature + methodname.toLowerCase(); - signature = signature + "(" + params.toLowerCase() + ")"; + return false; + } - return signature; - }; + addDemangleToCache(text) { + this.demangle(text); + } - var shouldIgnoreSymbol = function(text) { - for (var k in ignoredsymbols) { - if (text.startsWith(ignoredsymbols[k])) { - return true; - } + buildOrderedCache() { + this.sortedsymbolcache = []; + for (var symbol in this.symbolcache) { + this.sortedsymbolcache.push([symbol, this.symbolcache[symbol]]); } - return false; - }; + this.sortedsymbolcache = this.sortedsymbolcache.sort(function(a, b) { + return b[0].length - a[0].length; + }); + + this.symbolcache = {}; + } - var demangleIfNeeded = function(text) { + demangleIfNeeded(text) { if (text.includes('$')) { - if (shouldIgnoreSymbol(text)) { + if (this.shouldIgnoreSymbol(text)) { return text; } - for (var idx in sortedsymbolcache) { - text = text.replace(sortedsymbolcache[idx][0], sortedsymbolcache[idx][1]); + for (var idx in this.sortedsymbolcache) { + text = text.replace(this.sortedsymbolcache[idx][0], this.sortedsymbolcache[idx][1]); } return text; } else { return text; } - }; + } +} - var buildOrderedCache = function () { - sortedsymbolcache = []; - for (var symbol in symbolcache) { - sortedsymbolcache.push([symbol, symbolcache[symbol]]); - } +function compileFPC(info, env) { + var demangler = new PascalDemangler(); - sortedsymbolcache = sortedsymbolcache.sort(function(a, b) { - return b[0].length - a[0].length; - }); + if (info === undefined) { + // for unittest + return demangler; + } - symbolcache = {}; - }; + var compiler = new Compile(info, env); + compiler.supportsOptOutput = false; + + var originalExecBinary = compiler.execBinary; compiler.postProcessAsm = function (result) { if (!result.okToCache) return result; - buildOrderedCache(); + demangler.buildOrderedCache(); for (var j = 0; j < result.asm.length; ++j) - result.asm[j].text = demangleIfNeeded(result.asm[j].text); + result.asm[j].text = demangler.demangleIfNeeded(result.asm[j].text); return result; }; @@ -263,7 +300,7 @@ function compileFPC(info, env) { i++; asmLines.splice(i, 0, extraHint); } else { - addDemangleToCache(asmLines[i]); + demangler.addDemangleToCache(asmLines[i]); } i++; @@ -281,12 +318,12 @@ function compileFPC(info, env) { return this.exec(this.compiler.objdumper, args, {maxOutput: maxSize}) .then(function (objResult) { if (objResult.code !== 0) { - result.asm = "<No output: objdump returned " + objResult.code + ">"; + objResult.asm = "<No output: objdump returned " + objResult.code + ">"; } else { - result.asm = preProcessBinaryAsm(objResult.stdout); + objResult.asm = preProcessBinaryAsm(objResult.stdout); } - return result; + return objResult; }); }; |