Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Greene <hippiehunterenator@gmail.com>2018-04-26 03:46:50 +0300
committerMorgan Brown <morganbr@users.noreply.github.com>2018-04-26 03:46:50 +0300
commitaad951a27e4774a68cfdc3b5167241d373e5c5c3 (patch)
tree19688fb87d2813ea550a5e3d7c78679e82c0fd9b /src/ILCompiler.WebAssembly
parent08d3d2c4a10c970cce291c748dd304a8a9c58b5e (diff)
Enable Interface dispatch for WASM (#5748)
Interface dispatch
Diffstat (limited to 'src/ILCompiler.WebAssembly')
-rw-r--r--src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs35
1 files changed, 19 insertions, 16 deletions
diff --git a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs
index c3ead694d..d96ff3123 100644
--- a/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs
+++ b/src/ILCompiler.WebAssembly/src/CodeGen/ILToWebAssemblyImporter.cs
@@ -313,7 +313,7 @@ namespace Internal.IL
{
if (_basicBlocks[_currentOffset].StartOffset == 0)
throw new InvalidProgramException();
-
+ MarkBasicBlock(_basicBlocks[_currentOffset]);
LLVM.BuildBr(_builder, GetLLVMBasicBlockForBlock(_basicBlocks[_currentOffset]));
}
}
@@ -1001,11 +1001,6 @@ namespace Internal.IL
{
targetMethod = parameterType.ResolveInterfaceMethodTarget(callee);
}
- else
- {
- //TODO: needs runtime support for DispatchByInterface
- throw new NotImplementedException("Interface call");
- }
}
else
{
@@ -1021,14 +1016,15 @@ namespace Internal.IL
return GetOrCreateLLVMFunction(_compilation.NameMangler.GetMangledMethodName(targetMethod).ToString());
}
- return GetCallableVirtualMethod(thisPointer.ValueAsType(LLVM.PointerType(LLVM.Int8Type(), 0), _builder), callee);
+ return GetCallableVirtualMethod(thisPointer, callee);
+
}
else
{
return GetOrCreateLLVMFunction(calleeName);
}
}
-
+
private LLVMValueRef GetOrCreateMethodSlot(MethodDesc method)
{
var vtableSlotSymbol = _compilation.NodeFactory.VTableSlot(method);
@@ -1037,24 +1033,30 @@ namespace Internal.IL
return LLVM.BuildLoad(_builder, slot, string.Empty);
}
- private LLVMValueRef GetCallableVirtualMethod(LLVMValueRef objectPtr, MethodDesc method)
+ private LLVMValueRef GetCallableVirtualMethod(StackEntry objectPtr, MethodDesc method)
{
Debug.Assert(method.IsVirtual);
+ LLVMValueRef slot = GetOrCreateMethodSlot(method);
+ var pointerSize = method.Context.Target.PointerSize;
+ LLVMTypeRef universalSignature = LLVM.FunctionType(LLVM.VoidType(), new LLVMTypeRef[] { LLVM.PointerType(LLVM.Int8Type(), 0), LLVM.PointerType(LLVM.Int8Type(), 0) }, false);
+ LLVMValueRef functionPtr;
if (method.OwningType.IsInterface)
{
- throw new NotImplementedException();
+ var eeTypeDesc = _compilation.TypeSystemContext.SystemModule.GetKnownType("System", "EETypePtr");
+ var interfaceEEType = new LoadExpressionEntry(StackValueKind.ValueType, "interfaceEEType", GetEETypePointerForTypeDesc(method.OwningType, true), eeTypeDesc);
+ var eeTypeExpression = new LoadExpressionEntry(StackValueKind.ValueType, "eeType", objectPtr.ValueAsType(LLVM.PointerType(LLVM.Int8Type(), 0), _builder), eeTypeDesc);
+ var targetEntry = CallRuntime(_compilation.TypeSystemContext, DispatchResolve, "FindInterfaceMethodImplementationTarget", new StackEntry[] { eeTypeExpression, interfaceEEType, new ExpressionEntry(StackValueKind.Int32, "slot", slot, GetWellKnownType(WellKnownType.UInt16)) });
+ functionPtr = targetEntry.ValueAsType(LLVM.PointerType(universalSignature, 0), _builder);
}
else
{
- LLVMValueRef slot = GetOrCreateMethodSlot(method);
- var pointerSize = method.Context.Target.PointerSize;
- LLVMTypeRef universalSignature = LLVM.FunctionType(LLVM.VoidType(), new LLVMTypeRef[] { LLVM.PointerType(LLVM.Int8Type(), 0), LLVM.PointerType(LLVM.Int8Type(), 0) }, false);
- var rawObjectPtr = CastIfNecessary(objectPtr, LLVM.PointerType(LLVM.PointerType(LLVM.PointerType(universalSignature, 0), 0), 0));
+ var rawObjectPtr = CastIfNecessary(objectPtr.ValueAsType(LLVM.PointerType(LLVM.Int8Type(), 0), _builder), LLVM.PointerType(LLVM.PointerType(LLVM.PointerType(universalSignature, 0), 0), 0));
var eeType = LLVM.BuildLoad(_builder, rawObjectPtr, "ldEEType");
var slotPtr = LLVM.BuildGEP(_builder, eeType, new LLVMValueRef[] { slot }, "__getslot__");
- var functionPtr = LLVM.BuildLoad(_builder, slotPtr, "ld__getslot__");
- return functionPtr;
+ functionPtr = LLVM.BuildLoad(_builder, slotPtr, "ld__getslot__");
}
+
+ return functionPtr;
}
private ExpressionEntry AllocateObject(TypeDesc type)
@@ -2582,6 +2584,7 @@ namespace Internal.IL
private const string RuntimeImport = "RuntimeImports";
private const string InternalCalls = "InternalCalls";
private const string TypeCast = "TypeCast";
+ private const string DispatchResolve = "DispatchResolve";
private ExpressionEntry CallRuntime(TypeSystemContext context, string className, string methodName, StackEntry[] arguments, TypeDesc forcedReturnType = null)
{
MetadataType helperType = context.SystemModule.GetKnownType("System.Runtime", className);