diff options
author | Rubén Rincón Blanco <ruben@rinconblanco.es> | 2022-08-25 21:45:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-25 21:45:44 +0200 |
commit | 7c6a5291abdae74270c4462de29b086bdd67bb30 (patch) | |
tree | 760b710f49dcf4a66ff3d5ab62a4185b922aba11 | |
parent | 44aa191cad2ca5571e870bb098a84b6d77ac2300 (diff) | |
download | compiler-explorer-7c6a5291abdae74270c4462de29b086bdd67bb30.tar.gz compiler-explorer-7c6a5291abdae74270c4462de29b086bdd67bb30.zip |
Move compilers/golang to Typescript (#3980)gh-4020
* Rename golang.js to golang.ts
* Move golang to Typescript
* Add types to base postProcess so golang knows about them
* Remove CompilationResult type from signature
* Remove asmSize, leave it for the other PR
-rw-r--r-- | lib/base-compiler.ts | 2 | ||||
-rw-r--r-- | lib/compilers/golang.ts (renamed from lib/compilers/golang.js) | 136 |
2 files changed, 79 insertions, 59 deletions
diff --git a/lib/base-compiler.ts b/lib/base-compiler.ts index 34b56643c..892d62220 100644 --- a/lib/base-compiler.ts +++ b/lib/base-compiler.ts @@ -2375,7 +2375,7 @@ but nothing was dumped. Possible causes are: return source; } - async postProcess(result, outputFilename, filters) { + async postProcess(result, outputFilename: string, filters: ParseFilters) { const postProcess = _.compact(this.compiler.postProcess); const maxSize = this.env.ceProps('max-asm-size', 64 * 1024 * 1024); const optPromise = result.hasOptOutput ? this.processOptOutput(result.optPath) : ''; diff --git a/lib/compilers/golang.js b/lib/compilers/golang.ts index 8aa0fd985..b0abb1498 100644 --- a/lib/compilers/golang.js +++ b/lib/compilers/golang.ts @@ -1,4 +1,4 @@ -// Copyright (c) 2016, Compiler Explorer Authors +// Copyright (c) 2022, Compiler Explorer Authors // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -24,6 +24,7 @@ import _ from 'underscore'; +import {ResultLine} from '../../types/resultline/resultline.interfaces'; import {BaseCompiler} from '../base-compiler'; import * as utils from '../utils'; @@ -34,40 +35,61 @@ import {ClangParser} from './argument-parsers'; // x86 -> j, b // arm -> cb, tb // s390x -> cmpb, cmpub -const jumpRe = /^(j|b|cb|tb|cmpb|cmpub).*/i; +const JUMP_RE = /^(j|b|cb|tb|cmpb|cmpub).*/i; +const LINE_RE = /^\s+(0[Xx]?[\dA-Za-z]+)?\s?(\d+)\s*\(([^:]+):(\d+)\)\s*([A-Z]+)(.*)/; +const UNKNOWN_RE = /^\s+(0[Xx]?[\dA-Za-z]+)?\s?(\d+)\s*\(<unknown line number>\)\s*([A-Z]+)(.*)/; +const FUNC_RE = /TEXT\s+[".]*(\S+)\(SB\)/; +const LOGGING_RE = /^[^:]+:\d+:(\d+:)?\s.*/; +const DECIMAL_RE = /(\s+)(\d+)(\s?)$/; + +type GoEnv = { + GOROOT?: string; + GOARCH?: string; + GOOS?: string; +}; export class GolangCompiler extends BaseCompiler { + private readonly GOENV: GoEnv; + static get key() { return 'golang'; } constructor(compilerInfo, env) { super(compilerInfo, env); - this.goroot = this.compilerProps(`compiler.${this.compiler.id}.goroot`); - this.goarch = this.compilerProps(`compiler.${this.compiler.id}.goarch`); - this.goos = this.compilerProps(`compiler.${this.compiler.id}.goos`); + const goroot = this.compilerProps(`compiler.${this.compiler.id}.goroot`); + const goarch = this.compilerProps(`compiler.${this.compiler.id}.goarch`); + const goos = this.compilerProps(`compiler.${this.compiler.id}.goos`); + + this.GOENV = {}; + if (goroot) { + this.GOENV.GOROOT = goroot; + } + if (goarch) { + this.GOENV.GOARCH = goarch; + } + if (goos) { + this.GOENV.GOOS = goos; + } } - convertNewGoL(code) { - const re = /^\s+(0[Xx]?[\dA-Za-z]+)?\s?(\d+)\s*\(([^:]+):(\d+)\)\s*([A-Z]+)(.*)/; - const reUnknown = /^\s+(0[Xx]?[\dA-Za-z]+)?\s?(\d+)\s*\(<unknown line number>\)\s*([A-Z]+)(.*)/; - const reFunc = /TEXT\s+[".]*(\S+)\(SB\)/; - let prevLine = null; - let file = null; + convertNewGoL(code: ResultLine[]): string { + let prevLine: string | null = null; + let file: string | null = null; let fileCount = 0; - let func = null; - const funcCollisions = {}; - const labels = {}; - const usedLabels = {}; + let func: string | null = null; + const funcCollisions: Record<string, number> = {}; + const labels: Record<string, boolean> = {}; + const usedLabels: Record<string, boolean> = {}; const lines = code.map(obj => { - let pcMatch = null; - let fileMatch = null; - let lineMatch = null; - let ins = null; - let args = null; + let pcMatch: string | null = null; + let fileMatch: string | null = null; + let lineMatch: string | null = null; + let ins: string | null = null; + let args: string | null = null; const line = obj.text; - let match = line.match(re); + let match = line.match(LINE_RE); if (match) { pcMatch = match[2]; fileMatch = match[3]; @@ -75,17 +97,17 @@ export class GolangCompiler extends BaseCompiler { ins = match[5]; args = match[6]; } else { - match = line.match(reUnknown); + match = line.match(UNKNOWN_RE); if (match) { pcMatch = match[2]; ins = match[3]; args = match[4]; } else { - return null; + return []; } } - match = line.match(reFunc); + match = line.match(FUNC_RE); if (match) { // Normalize function name. func = match[1].replace(/[()*.]+/g, '_'); @@ -103,12 +125,12 @@ export class GolangCompiler extends BaseCompiler { funcCollisions[func] = collisions; } - let res = []; + const res: string[] = []; if (pcMatch && !labels[pcMatch]) { // Create pseudo-label. let label = pcMatch.replace(/^0{0,4}/, ''); let suffix = ''; - if (funcCollisions[func] > 0) { + if (func && funcCollisions[func] > 0) { suffix = `_${funcCollisions[func]}`; } @@ -130,32 +152,37 @@ export class GolangCompiler extends BaseCompiler { prevLine = lineMatch; } - args = this.replaceJump(func, funcCollisions[func], ins, args, usedLabels); - res.push(`\t${ins}${args}`); + if (func) { + args = this.replaceJump(func, funcCollisions[func], ins, args, usedLabels); + res.push(`\t${ins}${args}`); + } return res; }); // Find unused pseudo-labels so they can be filtered out. const unusedLabels = _.mapObject(labels, (val, key) => !usedLabels[key]); - return _.chain(lines) - .flatten() - .compact() + return lines + .flat() .filter(line => !unusedLabels[line]) - .value() .join('\n'); } - replaceJump(func, collisions, ins, args, usedLabels) { + replaceJump( + func: string, + collisions: number, + ins: string, + args: string, + usedLabels: Record<string, boolean>, + ): string { // Check if last argument is a decimal number. - const re = /(\s+)(\d+)(\s?)$/; - const match = args.match(re); + const match = args.match(DECIMAL_RE); if (!match) { return args; } // Check instruction has a jump prefix - if (jumpRe.test(ins)) { + if (JUMP_RE.test(ins)) { let label = `${func}_pc${match[2]}`; if (collisions > 0) { label += `_${collisions}`; @@ -167,16 +194,16 @@ export class GolangCompiler extends BaseCompiler { return args; } - extractLogging(stdout) { - let filepath = `./${this.compileFilename}`; - const reLogging = /^[^:]+:\d+:(\d+:)?\s.*/; + extractLogging(stdout: ResultLine[]): string { + const filepath = `./${this.compileFilename}`; + return stdout - .filter(obj => obj.text.match(reLogging)) + .filter(obj => obj.text.match(LOGGING_RE)) .map(obj => obj.text.replace(filepath, '<source>')) .join('\n'); } - async postProcess(result) { + override async postProcess(result) { let out = result.stderr; if (this.compiler.id === '6g141') { out = result.stdout; @@ -185,14 +212,14 @@ export class GolangCompiler extends BaseCompiler { result.asm = this.convertNewGoL(out); result.stderr = null; result.stdout = utils.parseOutput(logging, result.inputFilename); - return [result, '']; + return Promise.all([result, '']); } - getSharedLibraryPathsAsArguments() { + override getSharedLibraryPathsAsArguments() { return []; } - optionsForFilter(filters, outputFilename, userOptions) { + override optionsForFilter(filters, outputFilename, userOptions) { // If we're dealing with an older version... if (this.compiler.id === '6g141') { return ['tool', '6g', '-g', '-o', outputFilename, '-S']; @@ -206,7 +233,7 @@ export class GolangCompiler extends BaseCompiler { } } - filterUserOptions(userOptions) { + override filterUserOptions(userOptions) { if (this.compiler.id === '6g141') { return userOptions; } @@ -214,21 +241,14 @@ export class GolangCompiler extends BaseCompiler { return []; } - getDefaultExecOptions() { - const execOptions = super.getDefaultExecOptions(); - if (this.goroot) { - execOptions.env.GOROOT = this.goroot; - } - if (this.goarch) { - execOptions.env.GOARCH = this.goarch; - } - if (this.goos) { - execOptions.env.GOOS = this.goos; - } - return execOptions; + override getDefaultExecOptions() { + return { + ...super.getDefaultExecOptions(), + ...this.GOENV, + }; } - getArgumentParser() { + override getArgumentParser() { return ClangParser; } } |