aboutsummaryrefslogtreecommitdiff
path: root/lib/compilers/pascal.js
diff options
context:
space:
mode:
authorpartouf <partouf@gmail.com>2017-11-28 03:11:16 +0100
committerpartouf <partouf@gmail.com>2017-11-28 03:11:16 +0100
commitfe63adc4bc7fb06c5b88faddd3cca3c38bd0dee4 (patch)
tree7fbaa0547d82d2011b620ff71e50f62648e1a6ce /lib/compilers/pascal.js
parentb6beea085a93c1f30df5b5a003eae12e9464a1e7 (diff)
downloadcompiler-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.js171
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;
});
};