This commit is contained in:
Alex
2023-01-14 15:44:14 +01:00
committed by Matt Godbolt
parent 68713f6707
commit f6469b15e8
11 changed files with 312 additions and 0 deletions

3
.github/labeler.yml vendored
View File

@@ -101,6 +101,9 @@ lang-mlir:
lang-java:
- lib/compilers/java.js
- etc/config/java.*.properties
lang-julia:
- lib/compilers/julia.js
- etc/config/julia.*.properties
lang-kotlin:
- lib/compilers/kotlin.js
- etc/config/kotlin.*.properties

View File

@@ -0,0 +1,14 @@
# Default settings for Julia
compilers=&julia
defaultCompiler=julia_1_8_5
compilerType=julia
group.julia.compilers=julia_1_8_5:julia_1_7_3
group.julia.isSemVer=true
group.julia.baseName=Julia
compiler.julia_1_8_5.exe=/opt/compiler-explorer/julia-1.8.5/bin/julia
compiler.julia_1_8_5.semver=1.8.5
compiler.julia_1_8_5.alias=julia_1_8_5
compiler.julia_1_7_3.exe=/opt/compiler-explorer/julia-1.7.3/bin/julia
compiler.julia_1_7_3.semver=1.7.3
compiler.julia_1_7_3.alias=julia_1_7_3

View File

@@ -0,0 +1,6 @@
# Default settings for Julia
compilers=julia
defaultCompiler=julia
compilerType=julia
interpreted=true
supportsBinary=false

121
etc/scripts/julia_wrapper.jl Executable file
View File

@@ -0,0 +1,121 @@
doc = """Julia wrapper.
Usage:
julia_wrapper.jl <input_code> <output_path> [--format=<fmt>] [--debuginfo=<info>] [--optimize] [--verbose]
julia_wrapper.jl --help
Options:
-h --help Show this screen.
--format=<fmt> Set output format (One of "lowered", "typed", "warntype", "llvm", "native") [default: native]
lowered
typed
warntype
llvm
native
--debuginfo=<info> Controls amount of generated metadata (One of "default", "none") [default: default]
--optimize Sets whether "llvm" output should be optimized or not.
--verbose Prints some process info
"""
using InteractiveUtils
if length(ARGS) < 2
println(doc)
exit(1)
end
if length(ARGS) > 3 && ARGS[3] == "--help"
println(doc)
end
input_file = popfirst!(ARGS)
output_path = popfirst!(ARGS)
format = "native"
debuginfo = :default
optimize = false
verbose = false
for x in ARGS
if startswith(x, "--format=")
global format = x[10:end]
end
if startswith(x, "--debuginfo=")
if x[13:end] == "none"
global debuginfo = :none
end
end
if x == "--optimize"
global optimize = true
end
if x == "--verbose"
global verbose = true
end
end
# Include user code into module
m = Module(:Godbolt)
Base.include(m, input_file)
# Find functions and method specializations
m_methods = Any[]
for name in names(m, all=true)
local fun = getfield(m, name)
if fun isa Function
if verbose
println("Function: ", fun)
end
for me in methods(fun)
for s in me.specializations
if s != nothing
me_types = getindex(s.specTypes.parameters, 2:length(s.specTypes.parameters))
push!(m_methods, (fun, me_types, me))
if verbose
println(" Method types: ", me_types)
end
end
end
end
end
end
# Open output file
open(output_path, "w") do io
# For all found methods
for (me_fun, me_types, me) in m_methods
io_buf = IOBuffer() # string buffer
if format == "typed"
ir, retval = InteractiveUtils.code_typed(me_fun, me_types, debuginfo=debuginfo)[1]
Base.IRShow.show_ir(io_buf, ir)
elseif format == "lowered"
cl = Base.code_lowered(me_fun, me_types, debuginfo=debuginfo)
print(io_buf, cl)
elseif format == "llvm"
InteractiveUtils.code_llvm(io_buf, me_fun, me_types, optimize=optimize, debuginfo=debuginfo)
elseif format == "native"
InteractiveUtils.code_native(io_buf, me_fun, me_types, debuginfo=debuginfo)
elseif format == "warntype"
InteractiveUtils.code_warntype(io_buf, me_fun, me_types, debuginfo=debuginfo)
end
code = String(take!(io_buf))
line_num = count("\n",code)
# Print first line: <[source code line] [number of output lines] [function name] [method types]>
write(io, "<")
print(io, me.line)
print(io, " ")
print(io, line_num)
print(io, " ")
print(io, me_fun)
write(io, " ")
for i in 1:length(me_types)
print(io, me_types[i])
if i < length(me_types)
write(io, ", ")
end
end
write(io, ">\n")
# Print code for this method
write(io, code)
write(io, "\n")
end
end
exit(0)

View File

@@ -0,0 +1,5 @@
function square(x)
return x * x
end
precompile(square, (Int32,))

View File

@@ -64,6 +64,7 @@ export {HookCompiler} from './hook';
export {ISPCCompiler} from './ispc';
export {JaktCompiler} from './jakt';
export {JavaCompiler} from './java';
export {JuliaCompiler} from './julia';
export {KotlinCompiler} from './kotlin';
export {LDCCompiler} from './ldc';
export {LLCCompiler} from './llc';

141
lib/compilers/julia.ts Normal file
View File

@@ -0,0 +1,141 @@
// Copyright (c) 2018, 2023, Elliot Saba & 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 e from 'express';
import fs from 'fs';
import path from 'path';
import {ParsedAsmResultLine} from '../../types/asmresult/asmresult.interfaces';
import {CompilationResult, ExecutionOptions} from '../../types/compilation/compilation.interfaces';
import {BaseCompiler} from '../base-compiler';
import {logger} from '../logger';
import * as utils from '../utils';
import {BaseParser} from './argument-parsers';
export class JuliaCompiler extends BaseCompiler {
private compilerWrapperPath: string;
static get key() {
return 'julia';
}
constructor(info, env) {
super(info, env);
this.compiler.demangler = '';
this.demanglerClass = null;
this.compilerWrapperPath =
this.compilerProps('compilerWrapper', '') ||
utils.resolvePathFromAppRoot('etc', 'scripts', 'julia_wrapper.jl');
}
// No demangling for now
override postProcessAsm(result) {
return result;
}
override getSharedLibraryPathsAsArguments() {
return [];
}
override processAsm(result, filters, options) {
const lineRe = /^<(\d+) (\d+) ([^ ]+) ([^>]*)>$/;
const bytecodeLines = result.asm.split('\n');
const bytecodeResult: ParsedAsmResultLine[] = [];
// Every method block starts with a introductory line
// <[source code line] [output line number] [function name] [method types]>
// Check for the starting line, add the method block, skip other lines
let i = 0;
while (i < bytecodeLines.length) {
const line = bytecodeLines[i];
const match = line.match(lineRe);
if (match) {
const source = parseInt(match[1]);
let linenum = parseInt(match[2]);
linenum = Math.min(linenum, bytecodeLines.length);
const funname = match[3];
const types = match[4];
let j = 0;
bytecodeResult.push({text: '<' + funname + ' ' + types + '>', source: {line: source, file: null}});
while (j < linenum) {
bytecodeResult.push({text: bytecodeLines[i + 1 + j], source: {line: source, file: null}});
j++;
}
bytecodeResult.push({text: '', source: {file: null}});
i += linenum + 1;
continue;
}
i++;
}
return {asm: bytecodeResult};
}
override optionsForFilter(filters, outputFilename) {
return [];
}
override getArgumentParser() {
return BaseParser;
}
override fixExecuteParametersForInterpreting(executeParameters, outputFilename, key) {
super.fixExecuteParametersForInterpreting(executeParameters, outputFilename, key);
executeParameters.args.unshift('--');
}
override async runCompiler(
compiler: string,
options: string[],
inputFilename: string,
execOptions: ExecutionOptions,
): Promise<CompilationResult> {
if (!execOptions) {
execOptions = this.getDefaultExecOptions();
}
const dirPath = path.dirname(inputFilename);
if (!execOptions.customCwd) {
execOptions.customCwd = dirPath;
}
// compiler wrapper, then input should be first argument, not last
const wrapperOptions = options.filter(opt => opt !== inputFilename);
const juliaOptions = [this.compilerWrapperPath, '--'];
if (options.includes('-h') || options.includes('--help')) {
juliaOptions.push('--help');
} else {
wrapperOptions.unshift(inputFilename, this.getOutputFilename(dirPath, this.outputFilebase));
juliaOptions.push(...wrapperOptions);
}
const execResult = await this.exec(compiler, juliaOptions, execOptions);
return {
compilationOptions: juliaOptions,
...this.transformToCompilationResult(execResult, inputFilename),
};
}
}

View File

@@ -385,6 +385,17 @@ const definitions: Record<LanguageKey, LanguageDefinition> = {
previewFilter: null,
monacoDisassembly: null,
},
julia: {
name: 'Julia',
monaco: 'julia',
extensions: ['.jl'],
alias: [],
logoUrl: 'julia.svg',
logoUrlDark: null,
formatter: null,
previewFilter: null,
monacoDisassembly: null,
},
kotlin: {
name: 'Kotlin',
monaco: 'kotlin',

View File

@@ -53,6 +53,7 @@ export type LanguageKey =
| 'ispc'
| 'jakt'
| 'java'
| 'julia'
| 'kotlin'
| 'llvm'
| 'mlir'

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="325pt" height="300pt" viewBox="0 0 325 300" version="1.1">
<g id="surface91">
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(79.6%,23.5%,20%);fill-opacity:1;" d="M 150.898438 225 C 150.898438 266.421875 117.320312 300 75.898438 300 C 34.476562 300 0.898438 266.421875 0.898438 225 C 0.898438 183.578125 34.476562 150 75.898438 150 C 117.320312 150 150.898438 183.578125 150.898438 225 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(22%,59.6%,14.9%);fill-opacity:1;" d="M 237.5 75 C 237.5 116.421875 203.921875 150 162.5 150 C 121.078125 150 87.5 116.421875 87.5 75 C 87.5 33.578125 121.078125 0 162.5 0 C 203.921875 0 237.5 33.578125 237.5 75 "/>
<path style=" stroke:none;fill-rule:nonzero;fill:rgb(58.4%,34.5%,69.8%);fill-opacity:1;" d="M 324.101562 225 C 324.101562 266.421875 290.523438 300 249.101562 300 C 207.679688 300 174.101562 266.421875 174.101562 225 C 174.101562 183.578125 207.679688 150 249.101562 150 C 290.523438 150 324.101562 183.578125 324.101562 225 "/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -67,6 +67,7 @@ const plugins = [
'rust',
'swift',
'java',
'julia',
'kotlin',
'scala',
'ruby',