From 06f4ad2ea190e6606afa0ddb99de4d2fb5878874 Mon Sep 17 00:00:00 2001 From: "John Chen (JOCHEN7)" Date: Wed, 30 Sep 2015 15:45:41 -0700 Subject: [PATCH] Implement simple casting --- src/ILToNative/reproNative/common.h | 4 +-- src/ILToNative/reproNative/main.cpp | 4 +-- src/ILToNative/src/Compiler/AsmWriter.cs | 28 ++++++++++++++++++- .../src/Compiler/ReadyToRunHelper.cs | 8 +++++- src/JitInterface/src/CorInfoImpl.cs | 21 +++++++++++++- 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/src/ILToNative/reproNative/common.h b/src/ILToNative/reproNative/common.h index 4c86d6cce9b..eb212ef7316 100644 --- a/src/ILToNative/reproNative/common.h +++ b/src/ILToNative/reproNative/common.h @@ -43,8 +43,8 @@ extern "C" Object * __allocate_array(MethodTable * pMT, size_t elements); __declspec(noreturn) void __throw_exception(void * pEx); Object * __load_string_literal(const char * string); -Object * __castclass_class(void * p, MethodTable * pMT); -Object * __isinst_class(void * p, MethodTable * pMT); +extern "C" Object * __castclass_class(void * p, MethodTable * pMT); +extern "C" Object * __isinst_class(void * p, MethodTable * pMT); void __range_check(void * a, size_t elem); diff --git a/src/ILToNative/reproNative/main.cpp b/src/ILToNative/reproNative/main.cpp index 253f2dba517..2f72050d832 100644 --- a/src/ILToNative/reproNative/main.cpp +++ b/src/ILToNative/reproNative/main.cpp @@ -239,7 +239,7 @@ Object * __load_string_literal(const char * string) // TODO: Rewrite in C# -Object * __castclass_class(void * p, MethodTable * pTargetMT) +extern "C" Object * __castclass_class(void * p, MethodTable * pTargetMT) { Object * o = (Object *)p; @@ -259,7 +259,7 @@ Object * __castclass_class(void * p, MethodTable * pTargetMT) throw 1; } -Object * __isinst_class(void * p, MethodTable * pTargetMT) +extern "C" Object * __isinst_class(void * p, MethodTable * pTargetMT) { Object * o = (Object *)p; diff --git a/src/ILToNative/src/Compiler/AsmWriter.cs b/src/ILToNative/src/Compiler/AsmWriter.cs index 7c61891926f..773b8ea0a5e 100644 --- a/src/ILToNative/src/Compiler/AsmWriter.cs +++ b/src/ILToNative/src/Compiler/AsmWriter.cs @@ -200,12 +200,28 @@ void OutputReadyToHelpers() } Debug.Assert(methodSlot != -1); - Out.Write(8 /* sizeof(EEType */ + (baseSlots + methodSlot) * _typeSystemContext.Target.PointerSize); + Out.Write(16 /* sizeof(EEType */ + (baseSlots + methodSlot) * _typeSystemContext.Target.PointerSize); } Out.WriteLine("(%rax)"); break; + case ReadyToRunHelperId.IsInstanceOf: + Out.Write("leaq __EEType_"); + Out.Write(GetMangledTypeName((TypeDesc)helper.Target)); + Out.WriteLine("(%rip), %rdx"); + + Out.WriteLine("jmp __isinst_class"); + break; + + case ReadyToRunHelperId.CastClass: + Out.Write("leaq __EEType_"); + Out.Write(GetMangledTypeName((TypeDesc)helper.Target)); + Out.WriteLine("(%rip), %rdx"); + + Out.WriteLine("jmp __castclass_class"); + break; + default: throw new NotImplementedException(); } @@ -227,6 +243,16 @@ void OutputEETypes() Out.WriteLine(".int 0, 24"); + if (t.Type.BaseType != null) + { + Out.Write(".quad __EEType_"); + Out.WriteLine(GetMangledTypeName(t.Type.BaseType)); + } + else + { + Out.WriteLine(".quad 0"); + } + if (t.Constructed) OutputVirtualSlots(t.Type, t.Type); diff --git a/src/ILToNative/src/Compiler/ReadyToRunHelper.cs b/src/ILToNative/src/Compiler/ReadyToRunHelper.cs index 494cffaaf91..797c995899e 100644 --- a/src/ILToNative/src/Compiler/ReadyToRunHelper.cs +++ b/src/ILToNative/src/Compiler/ReadyToRunHelper.cs @@ -14,7 +14,9 @@ namespace ILToNative public enum ReadyToRunHelperId { NewHelper, - VirtualCall + VirtualCall, + IsInstanceOf, + CastClass, } class ReadyToRunHelper @@ -42,6 +44,10 @@ public string MangledName return "__NewHelper_" + _compilation.GetMangledTypeName((TypeDesc)this.Target); case ReadyToRunHelperId.VirtualCall: return "__VirtualCall_" + _compilation.GetMangledMethodName((MethodDesc)this.Target); + case ReadyToRunHelperId.IsInstanceOf: + return "__IsInstanceOf_" + _compilation.GetMangledTypeName((TypeDesc)this.Target); + case ReadyToRunHelperId.CastClass: + return "__CastClass_" + _compilation.GetMangledTypeName((TypeDesc)this.Target); default: throw new NotImplementedException(); } diff --git a/src/JitInterface/src/CorInfoImpl.cs b/src/JitInterface/src/CorInfoImpl.cs index e13828c8736..6a99659b57b 100644 --- a/src/JitInterface/src/CorInfoImpl.cs +++ b/src/JitInterface/src/CorInfoImpl.cs @@ -704,6 +704,22 @@ void getReadyToRunHelper(IntPtr _this, ref CORINFO_RESOLVED_TOKEN pResolvedToken pLookup.addr = (void*)ObjectToHandle(_compilation.GetReadyToRunHelper(ReadyToRunHelperId.NewHelper, type)); } break; + case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_ISINSTANCEOF: + { + var type = HandleToObject(pResolvedToken.hClass); + _compilation.AddType(type); + + pLookup.addr = (void*)ObjectToHandle(_compilation.GetReadyToRunHelper(ReadyToRunHelperId.IsInstanceOf, type)); + } + break; + case CorInfoHelpFunc.CORINFO_HELP_READYTORUN_CHKCAST: + { + var type = HandleToObject(pResolvedToken.hClass); + _compilation.AddType(type); + + pLookup.addr = (void*)ObjectToHandle(_compilation.GetReadyToRunHelper(ReadyToRunHelperId.CastClass, type)); + } + break; default: throw new NotImplementedException(); } @@ -749,7 +765,10 @@ uint getArrayRank(IntPtr _this, CORINFO_CLASS_STRUCT_* cls) void* getArrayInitializationData(IntPtr _this, CORINFO_FIELD_STRUCT_* field, uint size) { throw new NotImplementedException(); } CorInfoIsAccessAllowedResult canAccessClass(IntPtr _this, ref CORINFO_RESOLVED_TOKEN pResolvedToken, CORINFO_METHOD_STRUCT_* callerHandle, ref CORINFO_HELPER_DESC pAccessHelper) - { throw new NotImplementedException(); } + { + // TODO: Access check + return CorInfoIsAccessAllowedResult.CORINFO_ACCESS_ALLOWED; + } byte* getFieldName(IntPtr _this, CORINFO_FIELD_STRUCT_* ftn, byte** moduleName) {