1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 
5 #include <stdarg.h>
6 #include <stdlib.h>
7 #include <stdint.h>
8 
9 #include "dllexport.h"
10 #include "jitinterface.h"
11 
12 typedef struct _GUID {
13     unsigned int Data1;
14     unsigned short Data2;
15     unsigned short Data3;
16     unsigned char Data4[8];
17 } GUID;
18 
19 class CORJIT_FLAGS
20 {
21 public:
CORJIT_FLAGS(const CORJIT_FLAGS & other)22     CORJIT_FLAGS(const CORJIT_FLAGS& other)
23     {
24         corJitFlags = other.corJitFlags;
25     }
26 private:
27     unsigned __int64 corJitFlags;
28 };
29 
30 static const GUID JITEEVersionIdentifier = { /* a6860f80-01cb-4f87-82c2-a8e5a744f2fa */
31     0xa6860f80,
32     0x01cb,
33     0x4f87,
34     {0x82, 0xc2, 0xa8, 0xe5, 0xa7, 0x44, 0xf2, 0xfa}
35 };
36 
37 class Jit
38 {
39 public:
40     virtual int __stdcall compileMethod(
41         void* compHnd,
42         void* methodInfo,
43         unsigned flags,
44         void* entryAddress,
45         void* nativeSizeOfCode) = 0;
46 
47     virtual void clearCache() = 0;
48     virtual unsigned isCacheCleanupRequired() = 0;
49     virtual void ProcessShutdownWork(void* info) = 0;
50 
51     // The EE asks the JIT for a "version identifier". This represents the version of the JIT/EE interface.
52     // If the JIT doesn't implement the same JIT/EE interface expected by the EE (because the JIT doesn't
53     // return the version identifier that the EE expects), then the EE fails to load the JIT.
54     //
55     virtual void getVersionIdentifier(GUID* versionIdentifier) = 0;
56 
57     // When the EE loads the System.Numerics.Vectors assembly, it asks the JIT what length (in bytes) of
58     // SIMD vector it supports as an intrinsic type.  Zero means that the JIT does not support SIMD
59     // intrinsics, so the EE should use the default size (i.e. the size of the IL implementation).
60     virtual unsigned getMaxIntrinsicSIMDVectorLength(CORJIT_FLAGS cpuCompileFlags) = 0;
61 };
62 
JitCompileMethod(CorInfoException ** ppException,Jit * pJit,void * thisHandle,void ** callbacks,void * methodInfo,unsigned flags,void * entryAddress,void * nativeSizeOfCode)63 DLL_EXPORT int JitCompileMethod(
64     CorInfoException **ppException,
65     Jit * pJit,
66     void * thisHandle,
67     void ** callbacks,
68     void* methodInfo,
69     unsigned flags,
70     void* entryAddress,
71     void* nativeSizeOfCode)
72 {
73     *ppException = nullptr;
74 
75     GUID versionId;
76     pJit->getVersionIdentifier(&versionId);
77     if (memcmp(&versionId, &JITEEVersionIdentifier, sizeof(GUID)) != 0)
78     {
79         // JIT and the compiler disagree on how the interface looks like.
80         // Either get a matching version of the JIT from the CoreCLR repo or update the interface
81         // on the CoreRT side. Under no circumstances should you comment this line out.
82         return 1;
83     }
84 
85     try
86     {
87         JitInterfaceWrapper jitInterfaceWrapper(thisHandle, callbacks);
88         return pJit->compileMethod(&jitInterfaceWrapper, methodInfo, flags, entryAddress, nativeSizeOfCode);
89     }
90     catch (CorInfoException *pException)
91     {
92         *ppException = pException;
93     }
94 
95     return 1;
96 }
97 
GetMaxIntrinsicSIMDVectorLength(Jit * pJit,CORJIT_FLAGS * flags)98 DLL_EXPORT unsigned GetMaxIntrinsicSIMDVectorLength(
99     Jit * pJit,
100     CORJIT_FLAGS * flags)
101 {
102     return pJit->getMaxIntrinsicSIMDVectorLength(*flags);
103 }
104