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>2017-09-18 22:11:38 +0300
committerJan Kotas <jkotas@microsoft.com>2017-09-18 22:11:38 +0300
commit4c92bb34a99c2ef2c3f4ccf897dde7600072e6e3 (patch)
treed75438c68e533887765e00a78f2ffa708f74aa11 /src/ILCompiler.CppCodeGen
parentcb4c34eabe549d999d9af2439578606bb38e87b8 (diff)
Added support for ldvirtftn instruction to CppCodeGen (#4556)
Diffstat (limited to 'src/ILCompiler.CppCodeGen')
-rw-r--r--src/ILCompiler.CppCodeGen/src/CppCodeGen/ILToCppImporter.cs128
1 files changed, 84 insertions, 44 deletions
diff --git a/src/ILCompiler.CppCodeGen/src/CppCodeGen/ILToCppImporter.cs b/src/ILCompiler.CppCodeGen/src/CppCodeGen/ILToCppImporter.cs
index 88faf7d41..9f9d90a66 100644
--- a/src/ILCompiler.CppCodeGen/src/CppCodeGen/ILToCppImporter.cs
+++ b/src/ILCompiler.CppCodeGen/src/CppCodeGen/ILToCppImporter.cs
@@ -1046,44 +1046,15 @@ namespace Internal.IL
ExpressionEntry v = (ExpressionEntry)_stack[_stack.Top - (methodSignature.Length + 1)];
string typeDefName = _writer.GetCppMethodName(method);
- _writer.AppendSignatureTypeDef(_builder, typeDefName, method.Signature, method.OwningType);
+ _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("));");
+ Append(" = (void*) ");
+ GetFunctionPointerForInterfaceMethod(method, v, typeDefName);
PushExpression(StackValueKind.ByRef, functionPtr);
}
@@ -1236,6 +1207,41 @@ namespace Internal.IL
}
}
+ private void GetFunctionPointerForInterfaceMethod(MethodDesc method, ExpressionEntry v, string typeDefName)
+ {
+ Append("((");
+ 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("));");
+ }
+
private void PassCallArguments(MethodSignature methodSignature, TypeDesc thisArgument)
{
int signatureLength = methodSignature.Length;
@@ -1325,22 +1331,51 @@ namespace Internal.IL
{
MethodDesc method = (MethodDesc)_methodIL.GetObject(token);
- if (opCode == ILOpcode.ldvirtftn)
+ if (opCode == ILOpcode.ldvirtftn && method.IsVirtual && method.OwningType.IsInterface)
{
- if (method.IsVirtual)
- throw new NotImplementedException();
- }
+ AddVirtualMethodReference(method);
+ var entry = new LdTokenEntry<MethodDesc>(StackValueKind.NativeInt, NewTempName(), method);
+ ExpressionEntry v = (ExpressionEntry)_stack.Pop();
+ string typeDefName = _writer.GetCppMethodName(method);
+ _writer.AppendSignatureTypeDef(_builder, typeDefName, method.Signature, method.OwningType);
- AddMethodReference(method);
+ AppendEmptyLine();
- var entry = new LdTokenEntry<MethodDesc>(StackValueKind.NativeInt, NewTempName(), method);
- PushTemp(entry);
- Append("(intptr_t)&");
- Append(_writer.GetCppTypeName(method.OwningType));
- Append("::");
- Append(_writer.GetCppMethodName(method));
+ PushTemp(entry);
+ Append("(intptr_t) ");
+ GetFunctionPointerForInterfaceMethod(method, v, typeDefName);
+ }
+ else
+ {
+ AddMethodReference(method);
+ var entry = new LdTokenEntry<MethodDesc>(StackValueKind.NativeInt, NewTempName(), method);
+
+ if (opCode == ILOpcode.ldvirtftn && method.IsVirtual)
+ {
+ //ldvirtftn requires an object instance, we have to pop one off the stack
+ //then call the associated getslot method passing in the object instance to get the real function pointer
+ ExpressionEntry v = (ExpressionEntry)_stack.Pop();
+ PushTemp(entry);
+ Append("(intptr_t)");
+ Append(_writer.GetCppTypeName(method.OwningType));
+ Append("::__getslot__");
+ Append(_writer.GetCppMethodName(method));
+ Append("(");
+ Append(v.Name);
+ Append(")");
+ AppendSemicolon();
+ }
+ else
+ {
+ PushTemp(entry);
+ Append("(intptr_t)&");
+ Append(_writer.GetCppTypeName(method.OwningType));
+ Append("::");
+ Append(_writer.GetCppMethodName(method));
- AppendSemicolon();
+ AppendSemicolon();
+ }
+ }
}
private void ImportLoadInt(long value, StackValueKind kind)
@@ -2675,6 +2710,11 @@ namespace Internal.IL
_dependencies.Add(_nodeFactory.MethodEntrypoint(method));
}
+ private void AddVirtualMethodReference(MethodDesc method)
+ {
+ _dependencies.Add(_nodeFactory.VirtualMethodUse(method));
+ }
+
private void AddFieldReference(FieldDesc field)
{
if (field.IsStatic)