Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,45 @@ static void Validate(ReadyToRunReader reader)
}
}

[Fact]
public void WasmWebcilModule()
{
var wasmWebcilModule = new CompiledAssembly
{
AssemblyName = nameof(WasmWebcilModule),
SourceResourceNames = ["Webcil/WasmWebcilModule.cs"],
};

new R2RTestRunner(_output).Run(new R2RTestCase(
nameof(WasmWebcilModule),
[
new(nameof(WasmWebcilModule), [new CrossgenAssembly(wasmWebcilModule)])
{
OutputFileExtension = ".wasm",
AdditionalArgs =
{
"--targetarch",
"wasm",
"--targetos",
"browser",
},
Validate = Validate,
},
]));

static void Validate(ReadyToRunReader reader)
{
Assert.Equal(WasmMachine.Wasm32, reader.Machine);
var webcilReader = Assert.IsType<WebcilImageReader>(reader.CompositeReader);
Assert.Equal(WasmMachine.Wasm32, webcilReader.Machine);
Assert.True(webcilReader.IsWasmWrapped);

var metadataReader = reader.GetGlobalMetadata().MetadataReader;
Assert.Contains(metadataReader.MethodDefinitions, methodHandle =>
metadataReader.GetString(metadataReader.GetMethodDefinition(methodHandle).Name) == "AddIntegers");
}
}

[Fact]
public void TransitiveReferences()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace Webcil;

public static class WasmWebcilModule
{
public static int AddIntegers(int left, int right)
{
return left + right;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,8 @@ internal enum Crossgen2Option
{
Composite,
InputBubble,
ObjectFormat,
HotColdSplitting,
Optimize,
TargetArch,
TargetOS,
}

internal static class Crossgen2OptionsExtensions
Expand All @@ -58,11 +55,8 @@ internal static class Crossgen2OptionsExtensions
{
Crossgen2Option.Composite => $"--composite",
Crossgen2Option.InputBubble => $"--input-bubble",
Crossgen2Option.ObjectFormat => $"--object-format",
Crossgen2Option.HotColdSplitting => $"--hot-cold-splitting",
Crossgen2Option.Optimize => $"--optimize",
Crossgen2Option.TargetArch => $"--target-arch",
Crossgen2Option.TargetOS => $"--target-os",
_ => throw new ArgumentOutOfRangeException(nameof(kind)),
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,14 @@ internal sealed class CrossgenCompilation(string name, List<CrossgenAssembly> as
/// to avoid colliding with component stubs that crossgen2 creates alongside the composite image.
/// </summary>
public string FilePath => _outputDir != null
? Path.Combine(_outputDir, "CG2", Name + (IsComposite ? "-composite" : "") + ".dll")
? Path.Combine(_outputDir, "CG2", Name + (IsComposite ? "-composite" : "") + OutputFileExtension)
: throw new InvalidOperationException("Output directory not set");

/// <summary>
/// File extension for the crossgen2 output image.
/// </summary>
public string OutputFileExtension { get; init; } = ".dll";

public void SetOutputDir(string outputDir)
{
_outputDir = outputDir;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ private static string GetRegisterName(int registerNumber, Machine machine)
case Machine.RiscV64:
return ((RiscV64.Registers)registerNumber).ToString();

case WasmMachine.Wasm32:
throw new NotImplementedException("No implementation for machine type Wasm32.");
default:
throw new NotImplementedException(machine.ToString());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ public string GetSlotState(GcSlotTable slotTable, Machine machine)
regType = typeof(RiscV64.Registers);
break;

case WasmMachine.Wasm32:
throw new NotImplementedException($"No implementation for machine type Wasm32.");

default:
throw new NotImplementedException();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ public static string GetPlatformSpecificRegister(Machine machine, int regnum)
return ((LoongArch64.Registers)regnum).ToString();
case Machine.RiscV64:
return ((RiscV64.Registers)regnum).ToString();
case WasmMachine.Wasm32:
throw new NotImplementedException($"No implementation for machine type {machine}.");
default:
throw new NotImplementedException($"No implementation for machine type {machine}.");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,34 @@ internal GcInfoTypes(Machine machine, bool denormalizeCodeOffsets)
STACK_BASE_REGISTER_ENCBASE = 2;
NUM_REGISTERS_ENCBASE = 3;
break;
case WasmMachine.Wasm32:
PSP_SYM_STACK_SLOT_ENCBASE = 6;
GENERICS_INST_CONTEXT_STACK_SLOT_ENCBASE = 6;
SECURITY_OBJECT_STACK_SLOT_ENCBASE = 6;
GS_COOKIE_STACK_SLOT_ENCBASE = 6;
CODE_LENGTH_ENCBASE = 6;
STACK_BASE_REGISTER_ENCBASE = 3;
SIZE_OF_STACK_AREA_ENCBASE = 6;
SIZE_OF_EDIT_AND_CONTINUE_PRESERVED_AREA_ENCBASE = 3;
REVERSE_PINVOKE_FRAME_ENCBASE = 6;
NUM_REGISTERS_ENCBASE = 3;
NUM_STACK_SLOTS_ENCBASE = 5;
NUM_UNTRACKED_SLOTS_ENCBASE = 5;
NORM_PROLOG_SIZE_ENCBASE = 4;
NORM_EPILOG_SIZE_ENCBASE = 3;
INTERRUPTIBLE_RANGE_DELTA1_ENCBASE = 5;
INTERRUPTIBLE_RANGE_DELTA2_ENCBASE = 5;
REGISTER_ENCBASE = 3;
REGISTER_DELTA_ENCBASE = REGISTER_ENCBASE;
STACK_SLOT_ENCBASE = 6;
STACK_SLOT_DELTA_ENCBASE = 4;
NUM_SAFE_POINTS_ENCBASE = 4;
NUM_INTERRUPTIBLE_RANGES_ENCBASE = 1;
POINTER_SIZE_ENCBASE = 3;
LIVESTATE_RLE_RUN_ENCBASE = 2;
LIVESTATE_RLE_SKIP_ENCBASE = 4;
break;

case Machine.I386:
CODE_LENGTH_ENCBASE = 6;
NORM_PROLOG_SIZE_ENCBASE = 4;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ public enum OperatingSystem
Unknown = -1
}

public static class WasmMachine
{
Comment on lines +36 to +37
public const Machine Wasm32 = (Machine)0xFFFE;
}

public struct InstanceMethod
{
public byte Bucket;
Expand Down Expand Up @@ -683,6 +688,7 @@ private unsafe void EnsureHeader()
case Machine.Arm:
case Machine.Thumb:
case Machine.ArmThumb2:
case WasmMachine.Wasm32:
_pointerSize = 4;
break;

Comment on lines 690 to 694
Expand Down Expand Up @@ -1532,6 +1538,7 @@ private void EnsureImportSectionsImpl()
{
case Machine.I386:
case Machine.ArmThumb2:
case WasmMachine.Wasm32:
entrySize = 4;
break;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ public static TransitionBlock FromReader(ReadyToRunReader reader)
case Machine.RiscV64:
return RiscV64TransitionBlock.Instance;

case WasmMachine.Wasm32:
return Wasm32TransitionBlock.Instance;

default:
throw new NotImplementedException();
}
Expand Down Expand Up @@ -100,6 +103,23 @@ public override int OffsetFromGCRefMapPos(int pos)
}
}

private sealed class Wasm32TransitionBlock : TransitionBlock
{
public static readonly TransitionBlock Instance = new Wasm32TransitionBlock();

public override int PointerSize => 4;
public override int NumArgumentRegisters => 0;
public override int NumCalleeSavedRegisters => 0;
// Argument registers, callee-save registers, return address
public override int SizeOfTransitionBlock => 8;
public override int OffsetOfArgumentRegisters => 0;

public override int OffsetFromGCRefMapPos(int pos)
{
return SizeOfTransitionBlock + pos * PointerSize;
}
}

private sealed class X64WindowsTransitionBlock : TransitionBlock
{
public static readonly TransitionBlock Instance = new X64WindowsTransitionBlock();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class WebcilImageReader : IBinaryImageReader
private readonly CorFlags _corFlags;
private readonly DirectoryEntry _managedNativeHeaderDirectory;

public Machine Machine => Machine.I386; // Webcil doesn't encode machine type; wasm targets use a placeholder
public Machine Machine => WasmMachine.Wasm32; // Webcil doesn't encode machine type; wasm targets use a placeholder
public OperatingSystem OperatingSystem => OperatingSystem.Unknown;
public ulong ImageBase => 0;

Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/tools/r2rdump/CoreDisTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ public static IntPtr GetDisasm(Machine machine)
case Machine.RiscV64:
target = TargetArch.Target_RiscV64;
break;
case WasmMachine.Wasm32:
return IntPtr.Zero;
Comment on lines 78 to +82
default:
Program.WriteWarning($"{machine} not supported on CoreDisTools");
return IntPtr.Zero;
Expand Down Expand Up @@ -187,6 +189,7 @@ private void SetIndentations()
// to 7 * 3 characters; see https://github.com/dotnet/llilc/blob/master/lib/CoreDisTools/coredistools.cpp.
Machine.I386 => 7 * 3,
Machine.Amd64 => 7 * 3,
WasmMachine.Wasm32 => 7 * 3,

// Instructions are either 2 or 4 bytes long
Machine.ArmThumb2 => 4 * 3,
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/tools/r2rdump/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ public void Dump(ReadyToRunReader r2r)
Machine.Arm64 => TargetArchitecture.ARM64,
Machine.LoongArch64 => TargetArchitecture.LoongArch64,
Machine.RiscV64 => TargetArchitecture.RiscV64,
WasmMachine.Wasm32 => TargetArchitecture.Wasm32,
_ => throw new NotImplementedException(r2r.Machine.ToString()),
};
TargetOS os = r2r.OperatingSystem switch
Expand Down Expand Up @@ -466,7 +467,7 @@ public int Run()
// parse the ReadyToRun image
ReadyToRunReader r2r = new(model, filename);
r2r.ValidateDebugInfo = Get(_command.ValidateDebugInfo);
if (disasm && !(r2r.CompositeReader is WebcilImageReader))
if (disasm)
{
disassembler = new Disassembler(r2r, model);
Comment on lines 468 to 472
}
Expand Down
Loading