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:
Diffstat (limited to 'src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs')
-rw-r--r--src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs88
1 files changed, 76 insertions, 12 deletions
diff --git a/src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs b/src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs
index de2cb4d51..df7a96159 100644
--- a/src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs
+++ b/src/ILCompiler.Compiler/src/CppCodeGen/ILToCppImporter.cs
@@ -389,6 +389,15 @@ namespace Internal.IL
}
/// <summary>
+ /// Append the typedef of the method to assist in function pointer conversion
+ /// </summary>
+ /// <param name="method">Method typedef</param>
+ private void AppendInterfaceCallTypeDef(MethodDesc method, string name)
+ {
+ _writer.AppendSignatureTypeDef(_builder, name, method.Signature, method.Signature.ReturnType);
+ }
+
+ /// <summary>
/// Increase level of indentation by one in <see cref="_builder"/>.
/// </summary>
public void Indent()
@@ -491,14 +500,9 @@ namespace Internal.IL
AddTypeReference(returnType, true);
}
var owningType = methodCodeNodeNeedingCode.Method.OwningType;
- if (methodCodeNodeNeedingCode.Method.IsNativeCallable || methodCodeNodeNeedingCode.Method.IsRuntimeExport || methodCodeNodeNeedingCode.Method.IsRuntimeImplemented)
- {
- AddTypeReference(owningType, true);
- }
- if (methodCodeNodeNeedingCode.Method.Signature.IsStatic)
- {
- AddTypeReference(owningType, true);
- }
+
+ AddTypeReference(owningType, true);
+
ImportBasicBlocks();
if (_sequencePoints != null && _sequencePoints[0].Document != null)
@@ -860,6 +864,7 @@ namespace Internal.IL
{
bool callViaSlot = false;
bool delegateInvoke = false;
+ bool callViaInterfaceDispatch = false;
DelegateCreationInfo delegateInfo = null;
MethodDesc method = (MethodDesc)_methodIL.GetObject(token);
@@ -936,17 +941,18 @@ namespace Internal.IL
if (!method.IsNewSlot)
throw new NotImplementedException();
- // TODO: Interface calls
if (method.OwningType.IsInterface)
- throw new NotImplementedException();
+ callViaInterfaceDispatch = true;
+
+ else
+ callViaSlot = true;
_dependencies.Add(_nodeFactory.VirtualMethodUse(method));
- callViaSlot = true;
}
}
- if (!callViaSlot && !delegateInvoke)
+ if (!callViaSlot && !delegateInvoke && !callViaInterfaceDispatch)
AddMethodReference(method);
if (opcode == ILOpcode.newobj)
@@ -961,6 +967,55 @@ namespace Internal.IL
StackValueKind retKind = StackValueKind.Unknown;
var needNewLine = false;
+ if (callViaInterfaceDispatch)
+ {
+ _dependencies.Add(_nodeFactory.ReadyToRunHelper(ReadyToRunHelperId.InterfaceDispatch, method));
+ ExpressionEntry v = (ExpressionEntry)_stack[_stack.Top - (methodSignature.Length + 1)];
+
+ string typeDefName = _writer.GetCppMethodName(method);
+ _writer.AppendSignatureTypeDef(_builder, typeDefName, method.Signature, method.OwningType);
+
+ string functionPtr = NewTempName();
+ AppendEmptyLine();
+
+ Append("void*");
+ Append(functionPtr);
+ Append(" = (void*) ((");
+ Append(typeDefName);
+ // Call method to find implementation address
+ Append(") System_Private_CoreLib::System::Runtime::DispatchResolve::FindInterfaceMethodImplementationTarget(");
+
+ // Get EEType of current object (interface implementation)
+ Append("::System_Private_CoreLib::System::Object::get_EEType((::System_Private_CoreLib::System::Object*)");
+ Append(v.Name);
+ Append(")");
+
+ Append(", ");
+
+ // Get EEType of interface
+ Append("((::System_Private_CoreLib::Internal::Runtime::EEType *)(");
+ Append(_writer.GetCppTypeName(method.OwningType));
+ Append("::__getMethodTable()))");
+
+ Append(", ");
+
+ // Get slot of implementation
+ Append("(uint16_t)");
+ Append("(");
+ Append(_writer.GetCppTypeName(method.OwningType));
+ Append("::");
+ Append("__getslot__");
+ Append(_writer.GetCppMethodName(method));
+ Append("(");
+ Append(v.Name);
+ Append("))");
+
+ Append("));");
+
+ PushExpression(StackValueKind.ByRef, functionPtr);
+
+ }
+
if (!retType.IsVoid)
{
retKind = GetStackValueKind(retType);
@@ -1048,6 +1103,15 @@ namespace Internal.IL
v.Name + ")->m_firstParameter";
}
}
+ else if (callViaInterfaceDispatch)
+ {
+ Append("((");
+ Append(_writer.GetCppMethodName(method));
+ Append(")");
+ ExpressionEntry v = (ExpressionEntry)_stack.Pop();
+ Append(v);
+ Append(")");
+ }
else
{
Append(_writer.GetCppTypeName(method.OwningType));