diff --git a/lib/compilers/hook.ts b/lib/compilers/hook.ts index c30c1a981df..10443c18924 100644 --- a/lib/compilers/hook.ts +++ b/lib/compilers/hook.ts @@ -28,6 +28,8 @@ import {CompilationResult, ExecutionOptions} from '../../types/compilation/compi import {ParseFiltersAndOutputOptions} from '../../types/features/filters.interfaces'; import {BaseCompiler} from '../base-compiler'; +import {AsmResultSource, ParsedAsmResultLine} from '../../types/asmresult/asmresult.interfaces'; + export class HookCompiler extends BaseCompiler { static get key(): string { return 'hook'; @@ -52,4 +54,33 @@ export class HookCompiler extends BaseCompiler { options.push(outputFilename); return super.runCompiler(compiler, options, inputFilename, execOptions); } + + override processAsm(result) { + const commentRegex = /^\s*;(.*)/; + const instructionRegex = /^\s{2}(\d+)(.*)/; + const lines = result.asm.split('\n'); + const asm: ParsedAsmResultLine[] = []; + let lastLineNo: number | undefined; + for (const line of lines) { + if (commentRegex.test(line)) { + asm.push({text: line, source: {line: undefined, file: null}}); + lastLineNo = undefined; + continue; + } + const match = line.match(instructionRegex); + if (match) { + const lineNo = parseInt(match[1]); + asm.push({text: line, source: {line: lineNo, file: null}}); + lastLineNo = lineNo; + continue; + } + if (line) { + asm.push({text: line, source: {line: lastLineNo, file: null}}); + continue; + } + asm.push({text: line, source: {line: undefined, file: null}}); + lastLineNo = undefined; + } + return {asm: asm}; + } } diff --git a/test/compilers/hook-tests.js b/test/compilers/hook-tests.js new file mode 100644 index 00000000000..550c1b962aa --- /dev/null +++ b/test/compilers/hook-tests.js @@ -0,0 +1,136 @@ +// Copyright (c) 2021, Compiler Explorer Authors +// 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. + +import {HookCompiler} from '../../lib/compilers'; +import {chai, makeCompilationEnvironment} from '../utils'; + +const expect = chai.expect; + +describe('Hook compiler', () => { + it('should return correct key', () => { + HookCompiler.key.should.equal('hook'); + }); + + const info = {remote: true, lang: 'hook'}; + const languages = {hook: {id: 'hook'}}; + const hook = new HookCompiler(info, makeCompilationEnvironment({languages})); + + it('should return correct options for filter', () => { + hook.optionsForFilter().should.deep.equal(['--dump']); + }); + + it('should return correct output filename', () => { + const dirPath = '/tmp'; + hook.getOutputFilename(dirPath).should.equal('/tmp/example.out'); + }); + + it('should process and return correct bytecode result', () => { + const asm = + '; main in /app/example.hk at 0x56554a556550\n' + + '; 0 parameter(s), 0 non-local(s), 0 constant(s), 0 function(s)\n' + + ' 1 0 Int 2\n' + + ' 3 Int 2\n' + + ' 6 Multiply\n' + + ' 2 7 Load 2\n' + + ' 9 Return\n' + + ' 10 ReturnNil\n' + + '; 6 instruction(s)\n'; + const expected = { + asm: [ + { + source: { + file: null, + line: undefined, + }, + text: '; main in /app/example.hk at 0x56554a556550', + }, + { + source: { + file: null, + line: undefined, + }, + text: '; 0 parameter(s), 0 non-local(s), 0 constant(s), 0 function(s)', + }, + { + source: { + file: null, + line: 1, + }, + text: ' 1 0 Int 2', + }, + { + source: { + file: null, + line: 1, + }, + text: ' 3 Int 2', + }, + { + source: { + file: null, + line: 1, + }, + text: ' 6 Multiply', + }, + { + source: { + file: null, + line: 2, + }, + text: ' 2 7 Load 2', + }, + { + source: { + file: null, + line: 2, + }, + text: ' 9 Return', + }, + { + source: { + file: null, + line: 2, + }, + text: ' 10 ReturnNil', + }, + { + source: { + file: null, + line: undefined, + }, + text: '; 6 instruction(s)', + }, + { + source: { + file: null, + line: undefined, + }, + text: '', + }, + ], + }; + const result = hook.processAsm({asm: asm}); + result.should.deep.equal(expected); + }); +}); diff --git a/views/resources/logos/hook.png b/views/resources/logos/hook.png index 719b7955ca3..478a3c29272 100644 Binary files a/views/resources/logos/hook.png and b/views/resources/logos/hook.png differ