diff options
author | RabsRincon <rubrinbla@gmail.com> | 2018-01-18 19:43:10 +0100 |
---|---|---|
committer | RabsRincon <rubrinbla@gmail.com> | 2018-01-18 19:43:10 +0100 |
commit | a54faefb4c8668d9c9f93c78bd6bc639d1f0c219 (patch) | |
tree | 6465bf3e1d8e270cc53e67c04277c5773b16f7d6 /lib/compilers | |
parent | 7bd30b4c4b10f93f26db81fbbe492149b8d487eb (diff) | |
download | compiler-explorer-a54faefb4c8668d9c9f93c78bd6bc639d1f0c219.tar.gz compiler-explorer-a54faefb4c8668d9c9f93c78bd6bc639d1f0c219.zip |
ES6fy compilers inheritance
Diffstat (limited to 'lib/compilers')
-rw-r--r-- | lib/compilers/WSL-CL.js | 75 | ||||
-rw-r--r-- | lib/compilers/Wine-CL.js | 75 | ||||
-rw-r--r-- | lib/compilers/argument-parsers.js | 65 | ||||
-rw-r--r-- | lib/compilers/assembly.js | 64 | ||||
-rw-r--r-- | lib/compilers/default.js | 14 | ||||
-rw-r--r-- | lib/compilers/fake-for-test.js | 38 | ||||
-rw-r--r-- | lib/compilers/gcc.js | 34 | ||||
-rw-r--r-- | lib/compilers/golang.js | 34 | ||||
-rw-r--r-- | lib/compilers/haskell.js | 41 | ||||
-rw-r--r-- | lib/compilers/ispc.js | 41 | ||||
-rw-r--r-- | lib/compilers/ldc.js | 31 | ||||
-rw-r--r-- | lib/compilers/pascal.js | 222 | ||||
-rw-r--r-- | lib/compilers/rust.js | 28 | ||||
-rw-r--r-- | lib/compilers/swift.js | 42 |
14 files changed, 481 insertions, 323 deletions
diff --git a/lib/compilers/WSL-CL.js b/lib/compilers/WSL-CL.js index 1a3e37ec1..675c163ba 100644 --- a/lib/compilers/WSL-CL.js +++ b/lib/compilers/WSL-CL.js @@ -28,68 +28,73 @@ // Don't run under Wine (obviously) // Translate compiler path from Unix mounted volume (/mnt/c/tmp) to Windows (c:/tmp) -const Compile = require('../base-compiler'), - asm = require('../asm-cl'), +const BaseCompiler = require('../base-compiler'), + asmCl = require('../asm-cl'), temp = require('temp'), - RunCLDemangler = require('../cl-support').RunCLDemangler; + RunCLDemangler = require('../cl-support').RunCLDemangler, + argumentParsers = require("./argument-parsers"); -function compileCl(info, env) { - var compile = new Compile(info, env); - compile.asm = new asm.AsmParser(compile.compilerProps); - info.supportsFiltersInBinary = true; - if ((process.platform === "linux") || (process.platform === "darwin")) { - const origExec = compile.exec; - compile.exec = function (command, args, options) { - return origExec(command, args, options); - }; - compile.filename = function (fn) { - // AP: Need to translate compiler paths from what the Node.js process sees +class WSLCLCompiler extends BaseCompiler { + constructor(info, env) { + info.supportsFiltersInBinary = true; + super(info, env); + this.asm = new asmCl.AsmParser(); + + if (info.unitTestMode) { + this.initialise(); + return this; + } else { + return this.initialise(); + } + } + + filename(fn) { + if (process.platform === "linux" || process.platform === "darwin") { + // AP: Need to translate compiler paths from what the Node.js process sees // on a Unix mounted volume (/mnt/c/tmp) to what CL sees on Windows (c:/tmp) // We know process.env.tmpDir is of format /mnt/X/dir where X is drive letter. const driveLetter = process.env.winTmp.substring(5, 6); const directoryPath = process.env.winTmp.substring(7); const windowsStyle = driveLetter.concat(":/", directoryPath); return fn.replace(process.env.winTmp, windowsStyle); - }; + } else { + return super.filename(fn); + } } + // AP: Create CE temp directory in winTmp directory instead of the tmpDir directory. // NPM temp package: https://www.npmjs.com/package/temp, see Affixes - compile.newTempDir = function () { - return new Promise(function (resolve, reject) { - temp.mkdir({prefix: 'compiler-explorer-compiler', dir: process.env.winTmp}, function (err, dirPath) { + newTempDir () { + return new Promise((resolve, reject) => { + temp.mkdir({prefix: 'compiler-explorer-compiler', dir: process.env.winTmp}, (err, dirPath) => { if (err) - reject("Unable to open temp file: " + err); + reject(`Unable to open temp file: ${err}`); else resolve(dirPath); }); }); - }; - compile.supportsObjdump = function () { + } + + supportsObjdump() { return false; - }; + } - compile.getArgumentParser = () => (compiler) => compiler; + getArgumentParser() { + return argumentParsers.Base; + } - compile.postProcessAsm = function(result) { + postProcessAsm(result) { return RunCLDemangler(this, result); - }; + } - compile.optionsForFilter = function (filters, outputFilename) { + optionsForFilter(filters, outputFilename) { return [ '/FAsc', '/c', '/Fa' + this.filename(outputFilename), '/Fo' + this.filename(outputFilename + '.obj') ]; - }; - - if (info.unitTestMode) { - compile.initialise(); - - return compile; - } else { - return compile.initialise(); } } -module.exports = compileCl; +module.exports = WSLCLCompiler; diff --git a/lib/compilers/Wine-CL.js b/lib/compilers/Wine-CL.js index c2cd4eaa3..1bce97e65 100644 --- a/lib/compilers/Wine-CL.js +++ b/lib/compilers/Wine-CL.js @@ -22,54 +22,59 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -var Compile = require('../base-compiler'); -var asm = require('../asm-cl'); -var RunCLDemangler = require('../cl-support').RunCLDemangler; +const BaseCompiler = require('../base-compiler'), + asmCl = require('../asm-cl'), + RunCLDemangler = require('../cl-support').RunCLDemangler, + argumentParsers = require("./argument-parsers"); -function compileCl(info, env) { - var compile = new Compile(info, env); - compile.asm = new asm.AsmParser(compile.compilerProps); - info.supportsFiltersInBinary = true; - if ((process.platform === "linux") || (process.platform === "darwin")) { - var wine = env.ceProps("wine"); - var origExec = compile.exec; - compile.exec = function (command, args, options) { - if (command.toLowerCase().endsWith(".exe")) { - args.unshift(command); - command = wine; - } - return origExec(command, args, options); - }; - compile.filename = function (fn) { - return 'Z:' + fn; - }; + +class CLCompiler extends BaseCompiler { + constructor(info, env) { + info.supportsFiltersInBinary = true; + super(info, env); + this.asm = new asmCl.AsmParser(); + + if (info.unitTestMode) { + this.initialise(); + return this; + } else { + return this.initialise(); + } + } + + exec(command, args, options) { + if ((process.platform === "linux" || process.platform === "darwin") && command.toLowerCase().endsWith(".exe")) { + args.unshift(command); + command = this.env.ceProps("wine"); + } + return super.exec(command, args, options); } - compile.supportsObjdump = function () { + + filename(fn) { + return process.platform === "linux" || process.platform === "darwin" ? 'Z:' + fn : super.filename(fn); + } + + supportsObjdump() { return false; - }; + } - compile.getArgumentParser = () => (compiler) => compiler; + getArgumentParser() { + return argumentParsers.Base; + } - compile.postProcessAsm = function(result) { + postProcessAsm(result) { return RunCLDemangler(this, result); - }; + } - compile.optionsForFilter = function (filters, outputFilename, userOptions) { + optionsForFilter(filters, outputFilename, userOptions) { return [ '/FAsc', '/c', '/Fa' + this.filename(outputFilename), '/Fo' + this.filename(outputFilename + '.obj') ]; - }; - - if (info.unitTestMode) { - compile.initialise(); - - return compile; - } else { - return compile.initialise(); } + } -module.exports = compileCl; +module.exports = CLCompiler; diff --git a/lib/compilers/argument-parsers.js b/lib/compilers/argument-parsers.js index a0803a676..bf26271e5 100644 --- a/lib/compilers/argument-parsers.js +++ b/lib/compilers/argument-parsers.js @@ -26,9 +26,9 @@ const _ = require('underscore-node'), logger = require('../logger').logger, utils = require('../utils'); -const getOptions = function (compiler, helpArg) { - return compiler.exec(compiler.compiler.exe, [helpArg]) - .then(result => { +class BaseParser { + static getOptions(compiler, helpArg) { + return compiler.exec(compiler.compiler.exe, [helpArg]).then(result => { const options = {}; if (result.code === 0) { const optionFinder = /^\s*(--?[-a-zA-Z]+)/; @@ -41,13 +41,18 @@ const getOptions = function (compiler, helpArg) { } return options; }); -}; + } + static parse(compiler) { + return compiler; + } +} -const gccParser = function (compiler) { - return Promise.all([ - getOptions(compiler, "--target-help"), - getOptions(compiler, "--help=common")]) - .then(results => { +class GCCParser extends BaseParser { + static parse(compiler) { + return Promise.all([ + GCCParser.getOptions(compiler, "--target-help"), + GCCParser.getOptions(compiler, "--help=common") + ]).then(results => { const options = _.extend.apply(_.extend, results); compiler.compiler.supportsGccDump = true; logger.debug("gcc-like compiler options: ", _.keys(options).join(" ")); @@ -61,26 +66,28 @@ const gccParser = function (compiler) { } return compiler; }); -}; - -const clangParser = function (compiler) { - return getOptions(compiler, "--help").then(options => { - logger.debug("clang-like compiler options: ", _.keys(options).join(" ")); - if (options['-fsave-optimization-record']) { - compiler.compiler.optArg = "-fsave-optimization-record"; - compiler.compiler.supportsOptOutput = true; - } - if (options['-fcolor-diagnostics']) { - if (compiler.compiler.options) compiler.compiler.options += " "; - compiler.compiler.options += "-fcolor-diagnostics"; - } - return compiler; - }); -}; + } +} +class ClangParser extends BaseParser { + static parse(compiler) { + return ClangParser.getOptions(compiler, "--help").then(options => { + logger.debug("clang-like compiler options: ", _.keys(options).join(" ")); + if (options['-fsave-optimization-record']) { + compiler.compiler.optArg = "-fsave-optimization-record"; + compiler.compiler.supportsOptOutput = true; + } + if (options['-fcolor-diagnostics']) { + if (compiler.compiler.options) compiler.compiler.options += " "; + compiler.compiler.options += "-fcolor-diagnostics"; + } + return compiler; + }); + } +} module.exports = { - getOptions: getOptions, - clang: clangParser, - gcc: gccParser -};
\ No newline at end of file + Base: BaseParser, + Clang: ClangParser, + GCC: GCCParser +}; diff --git a/lib/compilers/assembly.js b/lib/compilers/assembly.js index e2f6d9d88..6fa2971d0 100644 --- a/lib/compilers/assembly.js +++ b/lib/compilers/assembly.js @@ -23,62 +23,71 @@ // POSSIBILITY OF SUCH DAMAGE. "use strict"; -var Compile = require('../base-compiler'), - logger = require('../logger').logger, +const BaseCompiler = require('../base-compiler'), AsmRaw = require('../asm-raw').AsmParser, utils = require('../utils'), fs = require("fs"), - path = require("path"); + path = require("path"), + argumentParsers = require("./argument-parsers"); -function compileAssembly(info, env) { - var compiler = new Compile(info, env); - compiler.asm = new AsmRaw(); +class AssemblyCompiler extends BaseCompiler { + constructor(info, env) { + super(info, env); + this.asm = new AsmRaw(); - compiler.getArgumentParser = () => (compiler) => compiler; + if (info.unitTestMode) { + this.initialise(); + return this; + } else { + return this.initialise(); + } + } - compiler.optionsForFilter = function (filters, outputFilename, userOptions) { - filters.binary = true; + getArgumentParser() { + return argumentParsers.Base; + } + optionsForFilter(filters, outputFilename, userOptions) { + filters.binary = true; return []; - }; + } - compiler.runCompiler = function (compiler, options, inputFilename, execOptions) { + runCompiler(compiler, options, inputFilename, execOptions) { if (!execOptions) { execOptions = this.getDefaultExecOptions(); } execOptions.customCwd = path.dirname(inputFilename); - - return this.exec(compiler, options, execOptions).then(function (result) { + + return this.exec(compiler, options, execOptions).then(result => { result.inputFilename = inputFilename; result.stdout = utils.parseOutput(result.stdout, inputFilename); result.stderr = utils.parseOutput(result.stderr, inputFilename); return result; }); - }; + } - function getGeneratedOutputfilename(inputFilename) { + getGeneratedOutputfilename(inputFilename) { const outputFolder = path.dirname(inputFilename); return new Promise((resolve, reject) => { fs.readdir(outputFolder, (err, files) => { files.forEach(file => { - if (file !== compiler.compileFilename) { + if (file !== this.compileFilename) { resolve(path.join(outputFolder, file)); } }); - reject("No output file was generated"); }); }); } - compiler.objdump = function (outputFilename, result, maxSize, intelAsm, demangle) { - return getGeneratedOutputfilename(outputFilename).then((realOutputFilename) => { + objdump(outputFilename, result, maxSize, intelAsm, demangle) { + return this.getGeneratedOutputfilename(outputFilename).then((realOutputFilename) => { let args = ["-d", realOutputFilename, "-l", "--insn-width=16"]; if (demangle) args = args.concat("-C"); if (intelAsm) args = args.concat(["-M", "intel"]); return this.exec(this.compiler.objdumper, args, {maxOutput: maxSize}) - .then(function (objResult) { + .then(objResult => { result.asm = objResult.stdout; if (objResult.code !== 0) { result.asm = "<No output: objdump returned " + objResult.code + ">"; @@ -86,17 +95,8 @@ function compileAssembly(info, env) { return result; }); }); - }; - - compiler.getOutputFilename = function (dirPath, outputFilebase) { - return path.join(dirPath, this.compileFilename); - }; - - if (info.unitTestMode) { - compiler.initialise(); - return compiler; - } else - return compiler.initialise(); + } } -module.exports = compileAssembly; + +module.exports = AssemblyCompiler; diff --git a/lib/compilers/default.js b/lib/compilers/default.js index bc65d81d6..f9ad44fff 100644 --- a/lib/compilers/default.js +++ b/lib/compilers/default.js @@ -22,9 +22,13 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -const Compile = require('../base-compiler'); +const BaseCompier = require('../base-compiler'); -module.exports = function (info, env) { - var comp = new Compile(info, env); - return comp.initialise(); -};
\ No newline at end of file +class DefaultCompiler extends BaseCompier { + constructor(info, env) { + super(info, env); + return this.initialise(); + } +} + +module.exports = DefaultCompiler; diff --git a/lib/compilers/fake-for-test.js b/lib/compilers/fake-for-test.js index e698a9366..4ac03c4b1 100644 --- a/lib/compilers/fake-for-test.js +++ b/lib/compilers/fake-for-test.js @@ -24,22 +24,36 @@ const _ = require('underscore-node'); -module.exports = (info, env) => { - return { - compiler: { +class FakeCompiler { + constructor(info) { + this.compiler = { id: info.id || 'fake-for-test', - lang: info.lang || 'fake-lang' - }, - getInfo: () => null, - getDefaultFilters: () => [], - getRemote: () => null, - compile: (source, options, backendOptions, filters) => Promise.resolve(_.extend(info.fakeResult || {}, { + lang: info.lang || 'fake-lang', + options: info.options || '' + }; + this.info = info; + } + + getInfo() { + return null; + } + getDefaultFilters() { + return []; + } + getRemote() { + return null; + } + compile(source, options, backendOptions, filters) { + return Promise.resolve(_.extend(this.info.fakeResult || {}, { input: { source: source, options: options, backendOptions: backendOptions, filters: filters } - })) - }; -};
\ No newline at end of file + })); + } +} + + +module.exports = FakeCompiler;
\ No newline at end of file diff --git a/lib/compilers/gcc.js b/lib/compilers/gcc.js index e69de29bb..012490789 100644 --- a/lib/compilers/gcc.js +++ b/lib/compilers/gcc.js @@ -0,0 +1,34 @@ +// Copyright (c) 2012-2018, Rubén Rincón +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// 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. + +const BaseCompiler = require('../base-compiler'); + +class GCCCompiler extends BaseCompiler { + constructor(info, env) { + super(info, env); + return this.initialise(); + } +} + +module.exports = GCCCompiler; diff --git a/lib/compilers/golang.js b/lib/compilers/golang.js index ee6fd8096..4490b52a0 100644 --- a/lib/compilers/golang.js +++ b/lib/compilers/golang.js @@ -22,19 +22,21 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -const Compile = require('../base-compiler'), +const BaseCompiler = require('../base-compiler'), _ = require('underscore-node'); -function compilenewgol(info, env) { - const compiler = new Compile(info, env); - compiler.originalGetDefaultExecOptions = compiler.getDefaultExecOptions; +class GolangCompiler extends BaseCompiler { + constructor(info, env) { + super(info, env); + return this.initialise(); + } - function convertNewGoL(code) { + convertNewGoL(code) { const re = /^\s+(0[xX]?[0-9A-Za-z]+)?\s?[0-9]+\s*\(([^:]+):([0-9]+)\)\s*([A-Z]+)(.*)/; let prevLine = null; let file = null; let fileCount = 0; - return _.compact(code.map(function (obj) { + return _.compact(code.map(obj => { const line = obj.text; const match = line.match(re); if (match) { @@ -54,30 +56,28 @@ function compilenewgol(info, env) { })).join("\n"); } - compiler.postProcess = function (result, outputFilename, filters) { - result.asm = convertNewGoL(result.stdout); + postProcess(result, outputFilename, filters) { + result.asm = this.convertNewGoL(result.stdout); result.stdout = []; return Promise.resolve(result); - }; + } - compiler.optionsForFilter = function (filters, outputFilename, userOptions) { + optionsForFilter(filters, outputFilename, userOptions) { // If we're dealing with an older version... if (this.compiler.id === '6g141') { return ['tool', '6g', '-g', '-o', outputFilename, '-S']; } return ['tool', 'compile', '-o', outputFilename, '-S']; - }; + } - compiler.getDefaultExecOptions = function () { - const execOptions = this.originalGetDefaultExecOptions(); + getDefaultExecOptions() { + const execOptions = super.getDefaultExecOptions(); const goroot = this.compilerProps("compiler." + this.compiler.id + ".goroot"); if (goroot) { execOptions.env.GOROOT = goroot; } return execOptions; - }; - - return compiler.initialise(); + } } -module.exports = compilenewgol; +module.exports = GolangCompiler; diff --git a/lib/compilers/haskell.js b/lib/compilers/haskell.js index a4080192f..1399c62e1 100644 --- a/lib/compilers/haskell.js +++ b/lib/compilers/haskell.js @@ -1,11 +1,38 @@ -var Compile = require('../base-compiler'); +// Copyright (c) 2012-2018, Rubén Rincón +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// 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. -function compileHaskell(info, env) { - var compiler = new Compile(info, env); - compiler.optionsForFilter = function (filters, outputFilename, userOptions) { +const BaseCompiler = require('../base-compiler'); + +class HaskellCompiler extends BaseCompiler { + constructor(info, env) { + super(info, env); + return this.initialise(); + } + + optionsForFilter(filters, outputFilename, userOptions) { return ['-S', '-g', '-o', this.filename(outputFilename)]; - }; - return compiler.initialise(); + } } -module.exports = compileHaskell; +module.exports = HaskellCompiler; diff --git a/lib/compilers/ispc.js b/lib/compilers/ispc.js index 3bb0f124f..ec3a249e3 100644 --- a/lib/compilers/ispc.js +++ b/lib/compilers/ispc.js @@ -1,11 +1,38 @@ -var Compile = require('../base-compiler'); +// Copyright (c) 2012-2018, Matt Godbolt & Rubén Rincón +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// 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. -function compileISPC(info, env) { - var compiler = new Compile(info, env); - compiler.optionsForFilter = function (filters, outputFilename, userOptions) { +const BaseCompiler = require('../base-compiler'); + +class ISPCCompiler extends BaseCompiler { + constructor(info, env) { + super(info, env); + return this.initialise(); + } + + optionsForFilter(filters, outputFilename, userOptions) { return ['--target=sse2-i32x4', '--emit-asm', '-g', '-o', this.filename(outputFilename)]; - }; - return compiler.initialise(); + } } -module.exports = compileISPC; +module.exports = ISPCCompiler; diff --git a/lib/compilers/ldc.js b/lib/compilers/ldc.js index 1d2933f7a..5d540a8e8 100644 --- a/lib/compilers/ldc.js +++ b/lib/compilers/ldc.js @@ -22,25 +22,30 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -const Compile = require('../base-compiler'), +const BaseCompiler = require('../base-compiler'), argumentParsers = require("./argument-parsers"); -function compileLdc(info, env) { - const compiler = new Compile(info, env); - compiler.compiler.supportsIntel = true; - compiler.optionsForFilter = function (filters, outputFilename, userOptions) { +class LDCCompiler extends BaseCompiler { + constructor(info, env) { + super(info, env); + this.compiler.supportsIntel = true; + return this.initialise(); + } + + optionsForFilter(filters, outputFilename, userOptions) { let options = ['-g', '-of', this.filename(outputFilename)]; if (filters.intel && !filters.binary) options = options.concat('-x86-asm-syntax=intel'); if (!filters.binary) options = options.concat('-output-s'); return options; - }; - compiler.getArgumentParser = function () { - return argumentParsers.clang; - }; - compiler.filterUserOptions = function (userOptions) { + } + + getArgumentParser() { + return argumentParsers.Clang; + } + + filterUserOptions(userOptions) { return userOptions.filter(option => option !== '-run'); - }; - return compiler.initialise(); + } } -module.exports = compileLdc; +module.exports = LDCCompiler; diff --git a/lib/compilers/pascal.js b/lib/compilers/pascal.js index 3fa0d3821..cfe4065cf 100644 --- a/lib/compilers/pascal.js +++ b/lib/compilers/pascal.js @@ -23,66 +23,62 @@ // POSSIBILITY OF SUCH DAMAGE. "use strict"; -var Compile = require('../base-compiler'), +const BaseCompiler = require('../base-compiler'), PascalDemangler = require('../pascal-support').demangler, utils = require('../utils'), fs = require("fs"), - path = require("path"); - -function compileFPC(info, env) { - var demangler = new PascalDemangler(); - var compiler = new Compile(info, env); - compiler.compileFilename = "output.pas"; - compiler.supportsOptOutput = false; - - var originalExecBinary = compiler.execBinary; - var currentlyActiveFilters = {}; + path = require("path"), + argumentParsers = require("./argument-parsers"); + +class FPCCompiler extends BaseCompiler { + constructor(info, env) { + super(info, env); + this.demangler = new PascalDemangler(); + this.compileFilename = 'output.pas'; + this.supportsOptOutput = false; + + if (info.unitTestMode) { + this.initialise(); + return this; + } else { + return this.initialise(); + } + } - compiler.postProcessAsm = function (result) { + postProcessAsm(result, filters) { if (!result.okToCache) return result; - if (currentlyActiveFilters.binary) { - preProcessAsm(result.asm); + if (filters.binary) { + for (let j = 0; j < result.asm.length; ++j) { + this.demangler.addDemangleToCache(result.asm[j].text); + } } - for (var j = 0; j < result.asm.length; ++j) - result.asm[j].text = demangler.demangleIfNeeded(result.asm[j].text); + for (let j = 0; j < result.asm.length; ++j) + result.asm[j].text = this.demangler.demangleIfNeeded(result.asm[j].text); return result; - }; + } - compiler.optionsForFilter = function (filters, outputFilename, userOptions) { - var options = ['-g']; + optionsForFilter(filters, outputFilename, userOptions) { + let options = ['-g']; if (this.compiler.intelAsm && filters.intel && !filters.binary) { options = options.concat(this.compiler.intelAsm.split(" ")); } - currentlyActiveFilters = filters; - filters.preProcessLines = preProcessLines; - return options; - }; - - compiler.getOutputFilename = function (dirPath, outputFilebase) { - return path.join(dirPath, path.basename(this.compileFilename, this.lang.extensions[0]) + ".s"); - }; + } - var saveDummyProjectFile = function (filename) { - const unitName = path.basename(compiler.compileFilename, compiler.lang.extensions[0]); + getOutputFilename(dirPath, outputFilebase) { + return path.join(dirPath, `${path.basename(this.compileFilename, this.lang.extensions[0])}.s`); + } - fs.writeFileSync(filename, - "program prog; " + - "uses " + unitName + " in '" + compiler.compileFilename + "'; " + - "begin " + - "end.", function() {}); - }; - - var preProcessBinaryAsm = function (input) { - var relevantAsmStartsAt = input.indexOf("<OUTPUT"); - if (relevantAsmStartsAt != -1) { - var lastLinefeedBeforeStart = input.lastIndexOf("\n", relevantAsmStartsAt); - if (lastLinefeedBeforeStart != -1) { + static preProcessBinaryAsm(input) { + const relevantAsmStartsAt = input.indexOf("<OUTPUT"); + if (relevantAsmStartsAt !== -1) { + const lastLinefeedBeforeStart = input.lastIndexOf("\n", relevantAsmStartsAt); + if (lastLinefeedBeforeStart !== -1) { input = input.substr(0, input.indexOf("00000000004")) + "\n" + input.substr(lastLinefeedBeforeStart + 1); @@ -92,15 +88,79 @@ function compileFPC(info, env) { input.substr(relevantAsmStartsAt); } } - return input; - }; + } + + objdump(outputFilename, result, maxSize, intelAsm, demangle) { + outputFilename = path.join(path.dirname(outputFilename), "prog"); + let args = ["-d", outputFilename, "-l", "--insn-width=16"]; + if (demangle) args = args.concat(["-C"]); + if (intelAsm) args = args.concat(["-M", "intel"]); + return this.exec(this.compiler.objdumper, args, {maxOutput: maxSize}).then(objResult => { + if (objResult.code !== 0) { + result.asm = "<No output: objdump returned " + objResult.code + ">"; + } else { + result.asm = FPCCompiler.preProcessBinaryAsm(objResult.stdout); + } + return result; + }); + } + + saveDummyProjectFile(filename) { + const unitName = path.basename(this.compileFilename, this.lang.extensions[0]); + + fs.writeFileSync(filename, + "program prog; " + + "uses " + unitName + " in '" + this.compileFilename + "'; " + + "begin " + + "end.", () => {}); + } + + runCompiler(compiler, options, inputFilename, execOptions) { + if (!execOptions) { + execOptions = this.getDefaultExecOptions(); + } + + const tempPath = path.dirname(inputFilename); + const projectFile = path.join(tempPath, "prog.dpr"); + + this.saveDummyProjectFile(projectFile); + + options.pop(); + options.push('-FE' + tempPath); + options.push('-B'); + options.push(projectFile); + + return this.exec(compiler, options, execOptions).then(result => { + result.inputFilename = inputFilename; + result.stdout = utils.parseOutput(result.stdout, inputFilename); + result.stderr = utils.parseOutput(result.stderr, inputFilename); + return result; + }); + } + + execBinary(executable, result, maxSize) { + executable = path.join(path.dirname(executable), "prog"); + + super.execBinary(executable, result, maxSize); + } + + getArgumentParser() { + return argumentParsers.Base; + } +} +/*function compileFPC(info, env) { + const demangler = new PascalDemangler(); + const compiler = new Compile(info, env); + + const - var getExtraAsmHint = function (asm) { + + const getExtraAsmHint = asm => { if (asm.startsWith("# [")) { - var bracketEndPos = asm.indexOf("]", 3); - var valueInBrackets = asm.substr(3, bracketEndPos - 3); - var colonPos = valueInBrackets.indexOf(":"); + const bracketEndPos = asm.indexOf("]", 3); + let valueInBrackets = asm.substr(3, bracketEndPos - 3); + const colonPos = valueInBrackets.indexOf(":"); if (colonPos != -1) { valueInBrackets = valueInBrackets.substr(0, colonPos - 1); } @@ -119,11 +179,11 @@ function compileFPC(info, env) { } }; - var preProcessLines = function(asmLines) { - var i = 0; + var preProcessLines = asmLines => { + let i = 0; while (i < asmLines.length) { - var extraHint = getExtraAsmHint(asmLines[i]); + const extraHint = getExtraAsmHint(asmLines[i]); if (extraHint) { i++; asmLines.splice(i, 0, extraHint); @@ -137,64 +197,6 @@ function compileFPC(info, env) { return asmLines; }; - var preProcessAsm = function(asm) { - for (var j = 0; j < asm.length; ++j) demangler.addDemangleToCache(asm[j].text); - }; - - compiler.objdump = function (outputFilename, result, maxSize, intelAsm, demangle) { - outputFilename = path.join(path.dirname(outputFilename), "prog"); - - var args = ["-d", outputFilename, "-l", "--insn-width=16"]; - if (demangle) args = args.concat(["-C"]); - if (intelAsm) args = args.concat(["-M", "intel"]); - return this.exec(this.compiler.objdumper, args, {maxOutput: maxSize}) - .then(function (objResult) { - if (objResult.code !== 0) { - result.asm = "<No output: objdump returned " + objResult.code + ">"; - } else { - result.asm = preProcessBinaryAsm(objResult.stdout); - } - - return result; - }); - }; - - compiler.runCompiler = function (compiler, options, inputFilename, execOptions) { - if (!execOptions) { - execOptions = this.getDefaultExecOptions(); - } - - var tempPath = path.dirname(inputFilename); - var projectFile = path.join(tempPath, "prog.dpr"); - - saveDummyProjectFile(projectFile); - - options.pop(); - options.push('-FE' + tempPath); - options.push('-B'); - options.push(projectFile); - - return this.exec(compiler, options, execOptions).then(function (result) { - result.inputFilename = inputFilename; - result.stdout = utils.parseOutput(result.stdout, inputFilename); - result.stderr = utils.parseOutput(result.stderr, inputFilename); - return result; - }); - }; - - compiler.execBinary = function (executable, result, maxSize) { - executable = path.join(path.dirname(executable), "prog"); - - originalExecBinary(executable, result, maxSize); - }; - - compiler.getArgumentParser = () => (compiler) => compiler; - - if (info.unitTestMode) { - compiler.initialise(); - return compiler; - } else - return compiler.initialise(); -} +}*/ -module.exports = compileFPC; +module.exports = FPCCompiler; diff --git a/lib/compilers/rust.js b/lib/compilers/rust.js index 8b11d2dfe..c7f16bc1f 100644 --- a/lib/compilers/rust.js +++ b/lib/compilers/rust.js @@ -22,18 +22,21 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. -var Compile = require('../base-compiler'), +const BaseCompiler = require('../base-compiler'), _ = require('underscore-node'); -function compileRust(info, env) { - var compiler = new Compile(info, env); - compiler.compiler.supportsIntel = true; - compiler.optionsForFilter = function (filters, outputFilename, userOptions) { - var options = ['-C', 'debuginfo=1', '-o', this.filename(outputFilename)]; - - var userRequestedEmit = _.any(userOptions, function(opt) { - return opt.indexOf("--emit") > -1; - }); +class RustCompiler extends BaseCompiler { + constructor(info, env) { + super(info, env); + this.compiler.supportsIntel = true; + + return this.initialise(); + } + + optionsForFilter(filters, outputFilename, userOptions) { + let options = ['-C', 'debuginfo=1', '-o', this.filename(outputFilename)]; + + let userRequestedEmit = _.any(userOptions, opt => opt.indexOf("--emit") > -1); //TODO: Binary not supported (?) if (!filters.binary) { if(!userRequestedEmit) { @@ -43,8 +46,7 @@ function compileRust(info, env) { } options = options.concat(['--crate-type', 'rlib']); return options; - }; - return compiler.initialise(); + } } -module.exports = compileRust; +module.exports = RustCompiler; diff --git a/lib/compilers/swift.js b/lib/compilers/swift.js index 884828852..832608eba 100644 --- a/lib/compilers/swift.js +++ b/lib/compilers/swift.js @@ -1,19 +1,45 @@ -const Compile = require('../base-compiler'), +// Copyright (c) 2012-2018, Matt Godbolt & Rubén Rincón +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// 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. + +const BaseCompiler = require('../base-compiler'), logger = require('../logger').logger; -function compileSwift(info, env) { - const compiler = new Compile(info, env); +class SwiftCompiler extends BaseCompiler { + constructor(info, env) { + super(info, env); + return this.initialise(); + } - compiler.handlePostProcessResult = function (result, postResult) { + handlePostProcessResult(result, postResult) { result.asm = postResult.stdout; - // Seems swift-demangle like to exit with error 1 + // Seems swift-demangle likes to exit with error 1 if (postResult.code !== 0 && !result.asm) { result.asm = "<Error during post processing: " + postResult.code + ">"; logger.error("Error during post-processing", result); } return result; - }; - return compiler.initialise(); + } } -module.exports = compileSwift; +module.exports = SwiftCompiler; |