aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/compilers/dotnet.ts158
-rw-r--r--lib/parsers/asm-parser-dotnet.ts1
2 files changed, 88 insertions, 71 deletions
diff --git a/lib/compilers/dotnet.ts b/lib/compilers/dotnet.ts
index 5b767ceda..e21899a0b 100644
--- a/lib/compilers/dotnet.ts
+++ b/lib/compilers/dotnet.ts
@@ -49,10 +49,10 @@ class DotNetCompiler extends BaseCompiler {
private readonly buildConfig: string;
private readonly clrBuildDir: string;
private readonly langVersion: string;
- private readonly crossgen2Path: string;
- private readonly sdkMajorVersion: number;
+ private readonly corerunPath: string;
+ private readonly disassemblyLoaderPath: string;
- private crossgen2VersionString: string;
+ private versionString: string;
constructor(compilerInfo: PreliminaryCompilerInfo, env) {
super(compilerInfo, env);
@@ -62,15 +62,15 @@ class DotNetCompiler extends BaseCompiler {
const parts = this.sdkVersion.split('.');
this.targetFramework = `net${parts[0]}.${parts[1]}`;
- this.sdkMajorVersion = Number(parts[0]);
this.buildConfig = this.compilerProps<string>(`compiler.${this.compiler.id}.buildConfig`);
this.clrBuildDir = this.compilerProps<string>(`compiler.${this.compiler.id}.clrDir`);
this.langVersion = this.compilerProps<string>(`compiler.${this.compiler.id}.langVersion`);
- this.crossgen2Path = path.join(this.clrBuildDir, 'crossgen2', 'crossgen2');
+ this.corerunPath = path.join(this.clrBuildDir, 'corerun');
this.asm = new DotNetAsmParser();
- this.crossgen2VersionString = '';
+ this.versionString = '';
+ this.disassemblyLoaderPath = path.join(this.clrBuildDir, 'DisassemblyLoader', 'DisassemblyLoader.dll');
}
get compilerOptions() {
@@ -118,6 +118,7 @@ class DotNetCompiler extends BaseCompiler {
</PropertyGroup>
<ItemGroup>
<Compile Include="${sourceFile}" />
+ <Reference Include="DisassemblyLoader" HintPath="${this.disassemblyLoaderPath}" />
</ItemGroup>
</Project>
`;
@@ -162,7 +163,7 @@ class DotNetCompiler extends BaseCompiler {
const inputFilenameSafe = this.filename(inputFilename);
const sourceFile = path.basename(inputFilenameSafe);
await this.writeProjectfile(dirPath, true, sourceFile);
- return await this.buildToDll(compiler, options, inputFilename, execOptions);
+ return await this.buildToDll(compiler, inputFilename, execOptions);
}
override async doCompilation(inputFilename, dirPath, key, options, filters, backendOptions, libraries, tools) {
@@ -174,7 +175,6 @@ class DotNetCompiler extends BaseCompiler {
async buildToDll(
compiler: string,
- options: string[],
inputFilename: string,
execOptions: ExecutionOptions & {env: Record<string, string>},
): Promise<CompilationResult> {
@@ -285,46 +285,69 @@ class DotNetCompiler extends BaseCompiler {
inputFilename: string,
execOptions: ExecutionOptions & {env: Record<string, string>},
): Promise<CompilationResult> {
- let toolOptions: string[] = [];
- const toolSwitches: string[] = [];
- const configurableOptions = this.configurableOptions;
+ const corerunArgs: string[] = [];
+ const ilcOptions: string[] = [
+ '--codegenopt',
+ 'JitDisasm=*',
+ '--codegenopt',
+ 'JitDisasmDiffable=1',
+ '--parallelism',
+ '1',
+ ];
+ const ilcSwitches: string[] = [];
const programDir = path.dirname(inputFilename);
const programOutputPath = path.join(programDir, 'bin', this.buildConfig, this.targetFramework);
- const programDllPath = path.join(programOutputPath, `${AssemblyName}.dll`);
-
- for (const configurableOption of configurableOptions) {
- const optionIndex = options.indexOf(configurableOption);
- if (optionIndex === -1 || optionIndex === options.length - 1) {
- continue;
- }
- toolOptions.push(options[optionIndex], options[optionIndex + 1]);
- }
-
+ const programDllPath = path.join(programOutputPath, 'CompilerExplorer.dll');
+ const envVarFileContents = [
+ 'DOTNET_EnableWriteXorExecute=0',
+ 'DOTNET_JitDisasm=*',
+ 'DOTNET_JitDisasmAssemblies=CompilerExplorer',
+ 'DOTNET_TieredCompilation=0',
+ ];
let isAot = false;
- const configurableSwitches = this.configurableSwitches;
- for (const configurableSwitch of configurableSwitches) {
- const switchIndex = options.indexOf(configurableSwitch);
- if (switchIndex === -1) {
+
+ while (options.length > 0) {
+ const currentOption = options.shift();
+ if (!currentOption) {
continue;
}
- if (configurableSwitch === '--aot') {
- isAot = true;
- } else {
- toolSwitches.push(options[switchIndex]);
+ if (currentOption === '-e' || currentOption === '--env') {
+ const envVar = options.shift();
+ if (envVar) {
+ const [name] = envVar.split('=');
+ const normalizedName = name.trim().toUpperCase();
+ if (
+ normalizedName === 'DOTNET_JITDISASM' ||
+ normalizedName === 'DOTNET_JITDUMP' ||
+ normalizedName === 'DOTNET_JITDISASMASSEMBILES'
+ ) {
+ continue;
+ }
+ envVarFileContents.push(envVar);
+ }
+ } else if (currentOption === '-p' || currentOption === '--property') {
+ const property = options.shift();
+ if (property) {
+ corerunArgs.push('-p', property);
+ }
+ } else if (this.configurableSwitches.indexOf(currentOption)) {
+ if (currentOption === '--aot') {
+ isAot = true;
+ } else {
+ ilcSwitches.push(currentOption);
+ }
+ } else if (this.configurableOptions.indexOf(currentOption)) {
+ const value = options.shift();
+ if (value) {
+ ilcOptions.push(currentOption, value);
+ }
}
}
this.setCompilerExecOptions(execOptions, programDir);
-
- // prettier-ignore
- toolOptions = [
- '--codegenopt', this.sdkMajorVersion < 7 ? 'NgenDisasm=*' : 'JitDisasm=*',
- '--codegenopt', this.sdkMajorVersion < 8 ? 'JitDiffableDasm=1' : 'JitDisasmDiffable=1',
- '--parallelism', '1',
- ].concat(toolOptions);
-
let compilerResult;
+
if (isAot) {
if (!fs.existsSync(`${this.clrBuildDir}/aot`)) {
return {
@@ -336,24 +359,27 @@ class DotNetCompiler extends BaseCompiler {
};
}
- compilerResult = await this.publishAot(compiler, toolOptions, toolSwitches, inputFilename, execOptions);
+ compilerResult = await this.publishAot(compiler, ilcOptions, ilcSwitches, inputFilename, execOptions);
} else {
- compilerResult = await this.buildToDll(compiler, options, inputFilename, execOptions);
+ compilerResult = await this.buildToDll(compiler, inputFilename, execOptions);
if (compilerResult.code !== 0) {
return compilerResult;
}
- const crossgen2Result = await this.runCrossgen2(
+ const envVarFilePath = path.join(programDir, '.env');
+ await fs.writeFile(envVarFilePath, envVarFileContents.join('\n'));
+
+ const corerunResult = await this.runCorerunForDisasm(
execOptions,
this.clrBuildDir,
+ envVarFilePath,
programDllPath,
- toolOptions,
- toolSwitches,
+ corerunArgs,
this.getOutputFilename(programDir, this.outputFilebase),
);
- if (crossgen2Result.code !== 0) {
- return crossgen2Result;
+ if (corerunResult.code !== 0) {
+ return corerunResult;
}
}
@@ -385,9 +411,8 @@ class DotNetCompiler extends BaseCompiler {
execOptions.env.CORE_ROOT = this.clrBuildDir;
execOptions.input = executeParameters.stdin;
const execArgs = ['-p', 'System.Runtime.TieredCompilation=false', programDllPath, ...executeParameters.args];
- const corerun = path.join(this.clrBuildDir, 'corerun');
try {
- const execResult: UnprocessedExecResult = await exec.sandbox(corerun, execArgs, execOptions);
+ const execResult: UnprocessedExecResult = await exec.sandbox(this.corerunPath, execArgs, execOptions);
return this.processExecutionResult(execResult);
} catch (err: UnprocessedExecResult | any) {
if (err.code && err.stderr) {
@@ -403,48 +428,41 @@ class DotNetCompiler extends BaseCompiler {
}
}
- async ensureCrossgen2Version(execOptions: ExecutionOptions) {
- if (!this.crossgen2VersionString) {
- this.crossgen2VersionString = '// crossgen2 ';
+ async checkRuntimeVersion(execOptions: ExecutionOptions) {
+ if (!this.versionString) {
+ this.versionString = '// dotnet runtime ';
const versionFilePath = `${this.clrBuildDir}/version.txt`;
- const versionResult = await this.exec(this.crossgen2Path, ['--version'], execOptions);
- if (versionResult.code === 0) {
- this.crossgen2VersionString += versionResult.stdout;
- } else if (fs.existsSync(versionFilePath)) {
+ if (fs.existsSync(versionFilePath)) {
const versionString = await fs.readFile(versionFilePath);
- this.crossgen2VersionString += versionString;
+ this.versionString += versionString;
} else {
- this.crossgen2VersionString += '<unknown version>';
+ this.versionString += '<unknown version>';
}
}
}
- async runCrossgen2(
+ async runCorerunForDisasm(
execOptions: ExecutionOptions,
- bclPath: string,
+ coreRoot: string,
+ envPath: string,
dllPath: string,
- toolOptions: string[],
- toolSwitches: string[],
+ options: string[],
outputPath: string,
) {
- await this.ensureCrossgen2Version(execOptions);
+ await this.checkRuntimeVersion(execOptions);
- // prettier-ignore
- const crossgen2Options = [
- '-r', path.join(bclPath, '/'),
+ const corerunOptions = ['--clr-path', coreRoot, '--env', envPath].concat([
+ ...options,
+ this.disassemblyLoaderPath,
dllPath,
- '-o', `${AssemblyName}.r2r.dll`,
- '--inputbubble',
- '--compilebubblegenerics',
- ].concat(toolOptions).concat(toolSwitches);
-
- const compilerExecResult = await this.exec(this.crossgen2Path, crossgen2Options, execOptions);
+ ]);
+ const compilerExecResult = await this.exec(this.corerunPath, corerunOptions, execOptions);
const result = this.transformToCompilationResult(compilerExecResult, dllPath);
await fs.writeFile(
outputPath,
- `${this.crossgen2VersionString}\n\n${result.stdout.map(o => o.text).reduce((a, n) => `${a}\n${n}`, '')}`,
+ `${this.versionString}\n\n${result.stdout.map(o => o.text).reduce((a, n) => `${a}\n${n}`, '')}`,
);
return result;
diff --git a/lib/parsers/asm-parser-dotnet.ts b/lib/parsers/asm-parser-dotnet.ts
index d6e8a4186..1fe7ca016 100644
--- a/lib/parsers/asm-parser-dotnet.ts
+++ b/lib/parsers/asm-parser-dotnet.ts
@@ -117,7 +117,6 @@ export class DotNetAsmParser implements IAsmParser {
continue;
}
- if (line.startsWith('Emitting R2R PE file')) continue;
cleanedAsm.push(line);
}