Skip to content
Merged
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
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<PackageLicense>https://github.com/Washi1337/Echo/LICENSE.md</PackageLicense>
<RepositoryUrl>https://github.com/Washi1337/Echo</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<LangVersion>12</LangVersion>
<LangVersion>14</LangVersion>
<Nullable>enable</Nullable>
<VersionPrefix>1.0.0</VersionPrefix>
<VersionSuffix>alpha.1</VersionSuffix>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="AsmResolver.DotNet" Version="6.0.0-beta.4" />
<PackageReference Include="AsmResolver.DotNet" Version="6.0.0-rc.1" />
<PackageReference Include="Nullable" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@
/// <summary>
/// Creates a new CIL virtual machine.
/// </summary>
/// <param name="contextModule">The main module to base the context on.</param>

Check warning on line 36 in src/Platforms/Echo.Platforms.AsmResolver/Emulation/CilVirtualMachine.cs

View workflow job for this annotation

GitHub Actions / Build and Test

XML comment has a param tag for 'contextModule', but there is no parameter by that name

Check warning on line 36 in src/Platforms/Echo.Platforms.AsmResolver/Emulation/CilVirtualMachine.cs

View workflow job for this annotation

GitHub Actions / Build and Test

XML comment has a param tag for 'contextModule', but there is no parameter by that name
/// <param name="is32Bit">Indicates whether the virtual machine runs in 32-bit mode or 64-bit mode.</param>
public CilVirtualMachine(ModuleDefinition contextModule, bool is32Bit)
public CilVirtualMachine(RuntimeContext runtimeContext, bool is32Bit)

Check warning on line 38 in src/Platforms/Echo.Platforms.AsmResolver/Emulation/CilVirtualMachine.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Parameter 'runtimeContext' has no matching param tag in the XML comment for 'CilVirtualMachine.CilVirtualMachine(RuntimeContext, bool)' (but other parameters do)

Check warning on line 38 in src/Platforms/Echo.Platforms.AsmResolver/Emulation/CilVirtualMachine.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Parameter 'runtimeContext' has no matching param tag in the XML comment for 'CilVirtualMachine.CilVirtualMachine(RuntimeContext, bool)' (but other parameters do)
{
Memory = new VirtualMemory(is32Bit ? uint.MaxValue : long.MaxValue);
Loader = new PELoader(Memory);

ValueFactory = new ValueFactory(contextModule, is32Bit);
ValueFactory = new ValueFactory(runtimeContext, is32Bit);
HostObjects = new ObjectMapMemory<object, HostObject>(0x1000_0000, o => new HostObject(o, this));
ObjectMarshaller = new ObjectMarshaller(this);

Expand Down Expand Up @@ -114,11 +114,8 @@
get;
}

/// <summary>
/// Gets the main module the emulator is executing instructions for.
/// </summary>
public ModuleDefinition ContextModule => ValueFactory.ContextModule;

public RuntimeContext RuntimeContext => ValueFactory.RuntimeContext;

Check warning on line 117 in src/Platforms/Echo.Platforms.AsmResolver/Emulation/CilVirtualMachine.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Missing XML comment for publicly visible type or member 'CilVirtualMachine.RuntimeContext'

Check warning on line 117 in src/Platforms/Echo.Platforms.AsmResolver/Emulation/CilVirtualMachine.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Missing XML comment for publicly visible type or member 'CilVirtualMachine.RuntimeContext'

/// <summary>
/// Gets the service that is responsible for mapping executable files in memory.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ private TypeSignature GetElementType(TypeSignature type)
case ElementType.ValueType:
if (!_resolvedTypes.TryGetValue(type, out var definition))
{
definition = type.Resolve();
if (definition is not null)
if (type.TryResolve(_valueFactory.RuntimeContext, out definition))
_resolvedTypes.Add(type, definition);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ protected override CilDispatchResult DispatchInternal(CilExecutionContext contex

private static TypeSignature GetElementType(CilExecutionContext context, CilInstruction instruction)
{
var factory = context.Machine.ValueFactory.ContextModule.CorLibTypeFactory;
var factory = context.Machine.ValueFactory.CorLibTypeFactory;
return instruction.OpCode.Code switch
{
CilCode.Ldelem => ((ITypeDefOrRef) instruction.Operand!).ToTypeSignature(),
CilCode.Ldelem => ((ITypeDefOrRef) instruction.Operand!).ToTypeSignature(context.Machine.RuntimeContext),
CilCode.Ldelem_I => factory.IntPtr,
CilCode.Ldelem_I1 => factory.SByte,
CilCode.Ldelem_I2 => factory.Int16,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ protected override CilDispatchResult DispatchInternal(CilExecutionContext contex
var genericContext = GenericContext.FromMethod(context.CurrentFrame.Method);

// Determine parameters.
var elementType = ((ITypeDefOrRef) instruction.Operand!).ToTypeSignature().InstantiateGenericTypes(genericContext);
var elementType = ((ITypeDefOrRef) instruction.Operand!)
.ToTypeSignature(context.RuntimeContext)
.InstantiateGenericTypes(genericContext);

var arrayIndex = stack.Pop();
var arrayAddress = stack.Pop();
var result = factory.RentNativeInteger(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Cil;
using Echo.Memory;
using Echo.Platforms.AsmResolver.Emulation.Stack;

namespace Echo.Platforms.AsmResolver.Emulation.Dispatch.Arrays
Expand All @@ -19,8 +18,10 @@ protected override CilDispatchResult DispatchInternal(CilExecutionContext contex
var factory = context.Machine.ValueFactory;
var genericContext = GenericContext.FromMethod(context.CurrentFrame.Method);

var elementType = ((ITypeDefOrRef)instruction.Operand!).ToTypeSignature().InstantiateGenericTypes(genericContext);
var elementCount = stack.Pop();
var elementType = ((ITypeDefOrRef)instruction.Operand!)
.ToTypeSignature(context.RuntimeContext)
.InstantiateGenericTypes(genericContext);

try
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ protected override CilDispatchResult DispatchInternal(CilExecutionContext contex

private static TypeSignature GetElementType(CilExecutionContext context, CilInstruction instruction)
{
var factory = context.Machine.ValueFactory.ContextModule.CorLibTypeFactory;
var factory = context.Machine.ValueFactory.CorLibTypeFactory;
return instruction.OpCode.Code switch
{
CilCode.Stelem => ((ITypeDefOrRef) instruction.Operand!).ToTypeSignature(),
CilCode.Stelem => ((ITypeDefOrRef) instruction.Operand!).ToTypeSignature(context.RuntimeContext),
CilCode.Stelem_I => factory.IntPtr,
CilCode.Stelem_I1 => factory.SByte,
CilCode.Stelem_I2 => factory.Int16,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading;
using AsmResolver.DotNet;
using Echo.Platforms.AsmResolver.Emulation.Stack;

namespace Echo.Platforms.AsmResolver.Emulation.Dispatch
Expand Down Expand Up @@ -44,5 +45,7 @@
{
get;
}

public RuntimeContext RuntimeContext => Machine.RuntimeContext;

Check warning on line 49 in src/Platforms/Echo.Platforms.AsmResolver/Emulation/Dispatch/CilExecutionContext.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Missing XML comment for publicly visible type or member 'CilExecutionContext.RuntimeContext'

Check warning on line 49 in src/Platforms/Echo.Platforms.AsmResolver/Emulation/Dispatch/CilExecutionContext.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Missing XML comment for publicly visible type or member 'CilExecutionContext.RuntimeContext'
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public CilDispatchResult Dispatch(CilExecutionContext context, CilInstruction in
if (index != -1 && body.Instructions[index].OpCode.Code == CilCode.Newobj)
{
var resultingType = calleeFrame.Method.DeclaringType!
.ToTypeSignature()
.ToTypeSignature(context.RuntimeContext)
.InstantiateGenericTypes(genericContext);

var slot = CreateResultingStackSlot(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ private static (StackSlot Result, Trilean Overflow) HandleKnownFloatConversion(

private static TypeSignature GetTargetType(CilExecutionContext context, CilCode code)
{
var factory = context.Machine.ContextModule.CorLibTypeFactory;
var factory = context.Machine.ValueFactory.CorLibTypeFactory;

return code switch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class BoxHandler : FallThroughOpCodeHandler
protected override CilDispatchResult DispatchInternal(CilExecutionContext context, CilInstruction instruction)
{
var genericContext = GenericContext.FromMethod(context.CurrentFrame.Method);
var type = ((ITypeDefOrRef)instruction.Operand!).ToTypeSignature();
var type = ((ITypeDefOrRef)instruction.Operand!).ToTypeSignature(context.RuntimeContext);

type = type.InstantiateGenericTypes(genericContext);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ protected override MethodDevirtualizationResult DevirtualizeMethodInternal(
IList<BitVector> arguments)
{
// If we are constraining on a specific declaring type, we need to simulate a "virtual dispatch" on that type.
if (context.CurrentFrame.ConstrainedType?.Resolve() is { } constrainedType)
if (context.CurrentFrame.ConstrainedType?.TryResolve(context.RuntimeContext, out var constrainedType) is true)
{
var resolvedBaseMethod = method.Resolve();
if (resolvedBaseMethod is { IsVirtual: true })
if (method.TryResolve(context.RuntimeContext, out var resolvedBaseMethod) && resolvedBaseMethod.IsVirtual)
{
var implementationMethod = FindMethodImplementationInType(constrainedType, resolvedBaseMethod);
var implementationMethod = FindMethodImplementationInType(context.RuntimeContext, constrainedType, resolvedBaseMethod);
if (implementationMethod is not null)
return MethodDevirtualizationResult.Success(implementationMethod);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@
var factory = context.Machine.ValueFactory;
var stack = context.CurrentFrame.EvaluationStack;

var declaringType = method.DeclaringType?.ToTypeSignature() ?? factory.ContextModule.CorLibTypeFactory.Object;
var declaringType = method.DeclaringType?.ToTypeSignature(context.RuntimeContext) ?? factory.CorLibTypeFactory.Object;
return stack.Pop(declaringType);
}

Expand Down Expand Up @@ -273,7 +273,7 @@
/// <param name="type">The type to search in.</param>
/// <param name="baseMethod">The method to find an implementation for.</param>
/// <returns>The method, or <c>null</c> if none is found.</returns>
protected static MethodDefinition? FindMethodImplementationInType(TypeDefinition? type, MethodDefinition? baseMethod)
protected static MethodDefinition? FindMethodImplementationInType(RuntimeContext context, TypeDefinition? type, MethodDefinition? baseMethod)

Check warning on line 276 in src/Platforms/Echo.Platforms.AsmResolver/Emulation/Dispatch/ObjectModel/CallHandlerBase.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Parameter 'context' has no matching param tag in the XML comment for 'CallHandlerBase.FindMethodImplementationInType(RuntimeContext, TypeDefinition?, MethodDefinition?)' (but other parameters do)

Check warning on line 276 in src/Platforms/Echo.Platforms.AsmResolver/Emulation/Dispatch/ObjectModel/CallHandlerBase.cs

View workflow job for this annotation

GitHub Actions / Build and Test

Parameter 'context' has no matching param tag in the XML comment for 'CallHandlerBase.FindMethodImplementationInType(RuntimeContext, TypeDefinition?, MethodDefinition?)' (but other parameters do)
{
if (type is null || baseMethod is null || !baseMethod.IsVirtual)
return baseMethod;
Expand All @@ -290,15 +290,15 @@
if (baseMethod.IsStatic)
{
// Static base methods can only be implemented through explicit interface implementation.
implementation = TryFindExplicitInterfaceImplementationInType(type, baseMethod);
implementation = TryFindExplicitInterfaceImplementationInType(context, type, baseMethod);
}
else
{
// Prioritize interface implementations.
if (declaringType.IsInterface)
{
implementation = TryFindExplicitInterfaceImplementationInType(type, baseMethod)
?? TryFindImplicitInterfaceImplementationInType(type, baseMethod);
implementation = TryFindExplicitInterfaceImplementationInType(context, type, baseMethod)
?? TryFindImplicitInterfaceImplementationInType(context, type, baseMethod);
}

// Try to find other implicit implementations.
Expand All @@ -309,7 +309,10 @@
break;

// Move up type hierarchy tree.
type = type.BaseType?.Resolve();
if (type.BaseType is null)
break;

type.BaseType.TryResolve(context, out type);
}

// If there's no override, just use the base implementation (if available).
Expand All @@ -334,13 +337,13 @@
return null;
}

private static MethodDefinition? TryFindImplicitInterfaceImplementationInType(TypeDefinition type, MethodDefinition baseMethod)
private static MethodDefinition? TryFindImplicitInterfaceImplementationInType(RuntimeContext context, TypeDefinition type, MethodDefinition baseMethod)
{
// Find the correct interface implementation and instantiate any generics.
MethodSignature? baseMethodSig = null;
foreach (var interfaceImpl in type.Interfaces)
{
if (SignatureComparer.Default.Equals(interfaceImpl.Interface?.ToTypeSignature().GetUnderlyingTypeDefOrRef(), baseMethod.DeclaringType))
if (context.SignatureComparer.Equals(interfaceImpl.Interface?.ToTypeSignature(context).GetUnderlyingTypeDefOrRef(), baseMethod.DeclaringType))
{
baseMethodSig = baseMethod.Signature?.InstantiateGenericTypes(GenericContext.FromType(interfaceImpl.Interface!));
break;
Expand All @@ -356,7 +359,7 @@
// Only public virtual instance methods can implicity implement interface methods. (ECMA-335, 6th edition, II.12.2)
if (method is { IsPublic: true, IsVirtual: true, IsStatic: false }
&& method.Name == baseMethod.Name
&& SignatureComparer.Default.Equals(method.Signature, baseMethodSig))
&& context.SignatureComparer.Equals(method.Signature, baseMethodSig))
{
return method;
}
Expand All @@ -365,7 +368,7 @@
return null;
}

private static MethodDefinition? TryFindExplicitInterfaceImplementationInType(TypeDefinition type, MethodDefinition baseMethod)
private static MethodDefinition? TryFindExplicitInterfaceImplementationInType(RuntimeContext context, TypeDefinition type, MethodDefinition baseMethod)
{
for (int i = 0; i < type.MethodImplementations.Count; i++)
{
Expand All @@ -374,15 +377,18 @@
continue;

// Compare underlying TypeDefOrRef and instantiate any generics to ensure correct comparison.
var declaringType = impl.Declaration?.DeclaringType?.ToTypeSignature().GetUnderlyingTypeDefOrRef();
if (!SignatureComparer.Default.Equals(declaringType, baseMethod.DeclaringType))
var declaringType = impl.Declaration?.DeclaringType?.ToTypeSignature(context).GetUnderlyingTypeDefOrRef();
if (!context.SignatureComparer.Equals(declaringType, baseMethod.DeclaringType))
continue;

var context = GenericContext.FromMethod(impl.Declaration!);
var implMethodSig = impl.Declaration!.Signature?.InstantiateGenericTypes(context);
var baseMethodSig = baseMethod.Signature?.InstantiateGenericTypes(context);
if (SignatureComparer.Default.Equals(baseMethodSig, implMethodSig))
return impl.Body?.Resolve();
var genericContext = GenericContext.FromMethod(impl.Declaration!);
var implMethodSig = impl.Declaration!.Signature?.InstantiateGenericTypes(genericContext);
var baseMethodSig = baseMethod.Signature?.InstantiateGenericTypes(genericContext);
if (context.SignatureComparer.Equals(baseMethodSig, implMethodSig)
&& impl.Body?.TryResolve(context, out var definition) is true)
{
return definition;
}
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ protected override MethodDevirtualizationResult DevirtualizeMethodInternal(
?? objectPointer.AsObjectHandle(context.Machine).GetObjectType();

// Find the implementation.
var implementation = FindMethodImplementationInType(objectType.Resolve(), method.Resolve());
if (implementation is null)
if (!objectType.TryResolve(context.RuntimeContext, out var objectTypeDefinition)
|| !method.TryResolve(context.RuntimeContext, out var methodDefinition)
|| FindMethodImplementationInType(context.RuntimeContext, objectTypeDefinition, methodDefinition) is not { } implementation)
{
// There is no implementation for the method.
return MethodDevirtualizationResult.Exception(
Expand All @@ -51,7 +52,7 @@ protected override MethodDevirtualizationResult DevirtualizeMethodInternal(
.AsObjectHandle(context.Machine)
);
}

// Instantiate any generics.
var genericContext = GenericContext.FromMethod(method);
if (genericContext.IsEmpty)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ protected override CilDispatchResult DispatchInternal(CilExecutionContext contex
var genericContext = GenericContext.FromMethod(context.CurrentFrame.Method);

var value = stack.Pop();
var targetType = ((ITypeDefOrRef) instruction.Operand!).ToTypeSignature().InstantiateGenericTypes(genericContext);
var targetType = ((ITypeDefOrRef) instruction.Operand!)
.ToTypeSignature(context.RuntimeContext)
.InstantiateGenericTypes(genericContext);

try
{
Expand All @@ -43,10 +45,10 @@ protected override CilDispatchResult DispatchInternal(CilExecutionContext contex
case { } actualAddress:
// A non-null reference was passed.
var handle = actualAddress.AsObjectHandle(context.Machine);
var objectType = handle.GetObjectType().ToTypeSignature();
var objectType = handle.GetObjectType().ToTypeSignature(context.RuntimeContext);

// TODO: handle full verifier-assignable-to operation.
return objectType.IsAssignableTo(targetType)
return objectType.IsAssignableTo(targetType, context.RuntimeContext)
? HandleSuccessfulCast(context, handle, targetType)
: HandleFailedCast(context, objectType, targetType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ protected override CilDispatchResult DispatchInternal(CilExecutionContext contex
{
var genericContext = GenericContext.FromMethod(context.CurrentFrame.Method);
context.CurrentFrame.ConstrainedType = ((ITypeDescriptor)instruction.Operand!)
.ToTypeSignature()
.ToTypeSignature(context.RuntimeContext)
.InstantiateGenericTypes(genericContext);

return CilDispatchResult.Success();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ public CilDispatchResult Dispatch(CilExecutionContext context, CilInstruction in
&& field.DeclaringType is { } declaringType)
{
var genericContext = GenericContext.FromMember(context.CurrentFrame.Method);
var instantiated = declaringType.ToTypeSignature().InstantiateGenericTypes(genericContext);
var instantiated = declaringType
.ToTypeSignature(context.RuntimeContext)
.InstantiateGenericTypes(genericContext);

var initResult = context.Machine.TypeManager.HandleInitialization(context.Thread, instantiated);
if (!initResult.IsNoAction)
return initResult.ToDispatchResult();
Expand Down
Loading
Loading