[add] first

This commit is contained in:
2023-10-08 10:24:48 +08:00
commit b1ae0510a9
1048 changed files with 3254361 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
#pragma once
#include "os/WindowsRuntime.h"
#include "vm/ComObjectBase.h"
#include "vm/Exception.h"
#include "utils/Memory.h"
#include "utils/TemplateUtils.h"
#include "Baselib.h"
#include "Cpp/Atomic.h"
#include <new>
namespace il2cpp
{
namespace vm
{
template<typename TDerived>
struct NOVTABLE ActivationFactoryBase : public ComObjectBase, Il2CppIActivationFactory
{
private:
baselib::atomic<uint32_t> m_RefCount;
public:
ActivationFactoryBase() :
m_RefCount(1) // We start with a ref count of 1
{
Il2CppStaticAssert(utils::TemplateUtils::IsBaseOf<ActivationFactoryBase<TDerived>, TDerived>::value);
}
virtual il2cpp_hresult_t STDCALL ActivateInstance(Il2CppIInspectable** instance) IL2CPP_OVERRIDE
{
return IL2CPP_E_NOTIMPL;
}
IL2CPP_FORCE_INLINE uint32_t AddRefImpl()
{
return ++m_RefCount;
}
IL2CPP_FORCE_INLINE uint32_t ReleaseImpl()
{
const uint32_t count = --m_RefCount;
if (count == 0)
Destroy();
return count;
}
IL2CPP_FORCE_INLINE il2cpp_hresult_t GetRuntimeClassNameImpl(Il2CppHString* className)
{
utils::StringView<Il2CppNativeChar> classNameView(IL2CPP_NATIVE_STRING("System.Runtime.InteropServices.WindowsRuntime.IActivationFactory"));
return os::WindowsRuntime::CreateHString(classNameView, className);
}
IL2CPP_FORCE_INLINE static TDerived* __CreateInstance()
{
void* memory = utils::Memory::Malloc(sizeof(TDerived));
if (memory == NULL)
Exception::RaiseOutOfMemoryException();
return new(memory) TDerived;
}
private:
IL2CPP_FORCE_INLINE void Destroy()
{
IL2CPP_ASSERT(m_RefCount == 0);
TDerived* instance = static_cast<TDerived*>(this);
instance->~TDerived();
utils::Memory::Free(instance);
}
};
}
}

View File

@@ -0,0 +1,66 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
#include "gc/GarbageCollector.h"
struct Il2CppArray;
struct Il2CppObject;
struct Il2CppString;
struct Il2CppClass;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Array
{
public:
static Il2CppArray* Clone(Il2CppArray* arr);
static int32_t GetElementSize(const Il2CppClass *klass);
static uint32_t GetLength(Il2CppArray* array);
static uint32_t GetByteLength(Il2CppArray* array);
static Il2CppArray* New(Il2CppClass *elementTypeInfo, il2cpp_array_size_t length);
static Il2CppArray* NewSpecific(Il2CppClass *arrayTypeInfo, il2cpp_array_size_t length);
static Il2CppArray* NewFull(Il2CppClass *array_class, il2cpp_array_size_t *lengths, il2cpp_array_size_t *lower_bounds);
public:
// internal
static Il2CppArray* NewCached(Il2CppClass *elementTypeInfo, il2cpp_array_size_t length)
{
return New(elementTypeInfo, length);
}
static char* GetFirstElementAddress(Il2CppArray *array);
};
} /* namespace vm */
} /* namespace il2cpp */
extern "C"
{
IL2CPP_EXPORT int il2cpp_array_element_size(const Il2CppClass *ac);
}
#define il2cpp_array_setwithsize(array, elementSize, index, value) \
do { \
void*__p = (void*) il2cpp_array_addr_with_size ((array), elementSize, (index)); \
memcpy(__p, &(value), elementSize); \
} while (0)
#define il2cpp_array_setrefwithsize(array, elementSize, index, value) \
do { \
void* __p = (void*) il2cpp_array_addr_with_size ((array), elementSize, (index)); \
memcpy(__p, value, elementSize); \
il2cpp::gc::GarbageCollector::SetWriteBarrier((void**)__p, elementSize); \
} while (0)
#define il2cpp_array_addr(array, type, index) ((type*)(void*) il2cpp_array_addr_with_size (array, sizeof (type), index))
#define il2cpp_array_get(array, type, index) ( *(type*)il2cpp_array_addr ((array), type, (index)) )
#define il2cpp_array_set(array, type, index, value) \
do { \
type *__p = (type *) il2cpp_array_addr ((array), type, (index)); \
*__p = (value); \
} while (0)
#define il2cpp_array_setref(array, index, value) \
do { \
void* *__p = (void* *) il2cpp_array_addr ((array), void*, (index)); \
*__p = (value); \
il2cpp::gc::GarbageCollector::SetWriteBarrier(__p); \
} while (0)

View File

@@ -0,0 +1,35 @@
#pragma once
#include <stdint.h>
#include <vector>
#include "il2cpp-config.h"
struct Il2CppAssembly;
struct Il2CppAssemblyName;
struct Il2CppImage;
struct Il2CppArray;
namespace il2cpp
{
namespace vm
{
typedef std::vector<const Il2CppAssembly*> AssemblyVector;
typedef std::vector<const Il2CppAssemblyName*> AssemblyNameVector;
class LIBIL2CPP_CODEGEN_API Assembly
{
// exported
public:
static Il2CppImage* GetImage(const Il2CppAssembly* assembly);
static void GetReferencedAssemblies(const Il2CppAssembly* assembly, AssemblyNameVector* target);
public:
static AssemblyVector* GetAllAssemblies();
static const Il2CppAssembly* GetLoadedAssembly(const char* name);
static const Il2CppAssembly* Load(const char* name);
static void Register(const Il2CppAssembly* assembly);
static void ClearAllAssemblies();
static void Initialize();
private:
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,26 @@
#pragma once
#include <stdint.h>
#include <vector>
#include <string>
#include "il2cpp-config.h"
struct Il2CppAssemblyName;
struct Il2CppReflectionAssemblyName;
struct Il2CppMonoAssemblyName;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API AssemblyName
{
// exported
public:
static void AssemblyNameReportChunked(const Il2CppAssemblyName & aname, void(*chunkReportFunction)(void *data, void *userData), void * userData);
static std::string AssemblyNameToString(const Il2CppAssemblyName& aname);
static bool ParseName(Il2CppReflectionAssemblyName* aname, std::string assemblyName);
static void FillNativeAssemblyName(const Il2CppAssemblyName& aname, Il2CppMonoAssemblyName* nativeName);
private:
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,33 @@
#pragma once
#include "gc/GarbageCollector.h"
struct Il2CppIUnknown;
struct Il2CppObject;
struct Il2CppException;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API CCW
{
public:
// CreateCCW returns upcasted Il2CppIManagedObjectHolder if the CCW is cachable!
static Il2CppIUnknown* CreateCCW(Il2CppObject* obj);
static inline Il2CppIUnknown* GetOrCreate(Il2CppObject* obj, const Il2CppGuid& iid)
{
return gc::GarbageCollector::GetOrCreateCCW(obj, iid);
}
static Il2CppObject* Unpack(Il2CppIUnknown* unknown);
static il2cpp_hresult_t HandleInvalidIPropertyConversion(const char* fromType, const char* toType);
static il2cpp_hresult_t HandleInvalidIPropertyConversion(Il2CppObject* value, const char* fromType, const char* toType);
static il2cpp_hresult_t HandleInvalidIPropertyArrayConversion(const char* fromArrayType, const char* fromElementType, const char* toElementType, il2cpp_array_size_t index);
static il2cpp_hresult_t HandleInvalidIPropertyArrayConversion(Il2CppObject* value, const char* fromArrayType, const char* fromElementType, const char* toElementType, il2cpp_array_size_t index);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,32 @@
#pragma once
#include "vm/ComObjectBase.h"
namespace il2cpp
{
namespace vm
{
struct LIBIL2CPP_CODEGEN_API NOVTABLE CCWBase : ComObjectBase, Il2CppIManagedObjectHolder, Il2CppIWeakReferenceSource
{
private:
Il2CppObject* m_ManagedObject;
public:
inline CCWBase(Il2CppObject* obj) :
m_ManagedObject(obj)
{
IL2CPP_ASSERT(obj != NULL);
}
IL2CPP_FORCE_INLINE Il2CppObject* GetManagedObjectInline() const
{
return m_ManagedObject;
}
il2cpp_hresult_t GetRuntimeClassNameImpl(Il2CppHString* className);
virtual Il2CppObject* STDCALL GetManagedObject() IL2CPP_OVERRIDE;
virtual il2cpp_hresult_t STDCALL GetWeakReference(Il2CppIWeakReference** weakReference) IL2CPP_FINAL IL2CPP_OVERRIDE;
};
}
}

View File

@@ -0,0 +1,45 @@
#pragma once
#include "il2cpp-class-internals.h"
#include "os/COM.h"
#include "vm/Exception.h"
struct Il2CppGuid;
struct Il2CppSafeArrayBound;
struct Il2CppSafeArray;
struct Il2CppIUnknown;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API COM
{
public:
static inline void CreateInstance(const Il2CppGuid& clsid, Il2CppIUnknown** object)
{
const il2cpp_hresult_t hr = os::COM::CreateInstance(clsid, object);
vm::Exception::RaiseIfFailed(hr, true);
}
static inline il2cpp_hresult_t CreateFreeThreadedMarshaler(Il2CppIUnknown* outer, Il2CppIUnknown** marshal)
{
return os::COM::CreateFreeThreadedMarshaler(outer, marshal);
}
static void MarshalVariant(Il2CppObject* obj, Il2CppVariant* variant);
static Il2CppObject* MarshalVariantResult(const Il2CppVariant* variant);
static void DestroyVariant(Il2CppVariant* variant);
static Il2CppSafeArray* MarshalSafeArray(uint16_t variantType, Il2CppArray* managedArray);
static Il2CppArray* MarshalSafeArrayResult(uint16_t variantType, Il2CppClass* type, Il2CppSafeArray* safeArray);
static Il2CppSafeArray* MarshalSafeArrayBString(Il2CppArray* managedArray);
static Il2CppArray* MarshalSafeArrayBStringResult(Il2CppClass* type, Il2CppSafeArray* safeArray);
static inline void DestroySafeArray(Il2CppSafeArray* safeArray)
{
const il2cpp_hresult_t hr = os::COM::SafeArrayDestroy(safeArray);
vm::Exception::RaiseIfFailed(hr, true);
}
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,12 @@
#pragma once
namespace il2cpp
{
namespace vm
{
struct LIBIL2CPP_CODEGEN_API COMEntryPoints
{
static void FreeCachedData();
};
}
}

View File

@@ -0,0 +1,104 @@
#pragma once
#include "gc/GCHandle.h"
#include "os/Atomic.h"
#include "vm/CCWBase.h"
#include "utils/Memory.h"
#include "utils/TemplateUtils.h"
#include "Baselib.h"
#include "Cpp/Atomic.h"
namespace il2cpp
{
namespace vm
{
// Alright, so the lifetime of this guy is pretty weird
// For a single managed object, the IUnknown of its COM Callable Wrapper must always be the same
// That means that we have to keep the same COM Callable Wrapper alive for an object once we create it
// They are cached in il2cpp::vm::g_CCWCache, which is managed by il2cpp::vm::CCW class
//
// Here comes the tricky part: when a native object has a reference to the COM Callable Wrapper,
// the managed object is not supposed to be garbage collected. However, when no native objects are referencing
// it, it should not prevent the GC from collecting the managed object. We implement this by keeping a GC handle
// on the managed object if our reference count is 1 or more. We acquire it when it gets increased from 0 (this
// is safe because such AddRef can only come when this object is retrieved from CCW Cache) and release the GC
// handle when our reference count gets decreased to 0. Here's a kicker: we don't destroy the COM Callable Wrapper
// when the reference count reaches 0; we instead rely on GC finalizer of the managed object to both remove it from
// CCW cache and also destroy it.
template<typename TDerived>
struct NOVTABLE CachedCCWBase : CCWBase
{
private:
baselib::atomic<uint32_t> m_RefCount;
uint32_t m_GCHandle;
public:
inline CachedCCWBase(Il2CppObject* obj) :
CCWBase(obj),
m_RefCount(0), // We do not hold any references upon its creation
m_GCHandle(0)
{
Il2CppStaticAssert(utils::TemplateUtils::IsBaseOf<CachedCCWBase<TDerived>, TDerived>::value);
}
virtual uint32_t STDCALL AddRef() IL2CPP_OVERRIDE
{
return AddRefImpl();
}
virtual uint32_t STDCALL Release() IL2CPP_OVERRIDE
{
return ReleaseImpl();
}
// AddRef can be called at any time whatsoever, as it's called when
// managed objects are passed to native code
IL2CPP_NO_INLINE uint32_t AddRefImpl()
{
const uint32_t refCount = ++m_RefCount;
if (refCount == 1)
{
// Since AddRef can be called at any time, it's possible that
// at this point we're in middle of ReleaseImpl call just after
// it decrements the gccount to 0 but hasn't released m_GCHandle
// yet. We spin until it is released.
uint32_t gcHandle = gc::GCHandle::New(GetManagedObjectInline(), false);
while (os::Atomic::CompareExchange(&m_GCHandle, gcHandle, 0) != 0) {}
}
return refCount;
}
// Release can be called only if m_RefCount is greater than 0,
// and the AddRef call that has increased the ref count above 0 has returned
IL2CPP_NO_INLINE uint32_t ReleaseImpl()
{
const uint32_t count = --m_RefCount;
if (count == 0)
{
// We decreased the ref count to 0, so we are responsible
// for freeing the handle. Only one ReleaseImpl that reduced
// ref count to 0 will ever be in flight at the same time
// because AddRefImpl that takes us out of this state halts until
// we set m_GCHandle to zero.
uint32_t gcHandle = os::Atomic::Exchange(&m_GCHandle, 0);
IL2CPP_ASSERT(gcHandle != 0);
gc::GCHandle::Free(gcHandle);
}
return count;
}
virtual void STDCALL Destroy() IL2CPP_FINAL IL2CPP_OVERRIDE
{
IL2CPP_ASSERT(m_RefCount == 0);
TDerived* instance = static_cast<TDerived*>(this);
instance->~TDerived();
utils::Memory::Free(instance);
}
};
}
}

View File

@@ -0,0 +1,213 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
#include "il2cpp-blob.h"
#include "il2cpp-class-internals.h"
#include "metadata/ArrayMetadata.h"
#include "metadata/Il2CppTypeCompare.h"
#include "utils/dynamic_array.h"
#include "il2cpp-class-internals.h"
#include "il2cpp-object-internals.h"
#include "Exception.h"
#include "GenericClass.h"
#include "Type.h"
#include "os/Mutex.h"
#include "vm/MetadataCache.h"
#include "il2cpp-tabledefs.h"
struct Il2CppClass;
struct EventInfo;
struct FieldInfo;
struct PropertyInfo;
struct MethodInfo;
struct Il2CppImage;
struct Il2CppReflectionType;
struct Il2CppType;
struct Il2CppGenericContainer;
struct Il2CppGenericContext;
struct MonoGenericParameterInfo;
namespace il2cpp
{
namespace vm
{
class TypeNameParseInfo;
enum TypeSearchFlags
{
kTypeSearchFlagNone = 0x0,
kTypeSearchFlagIgnoreCase = 0x1,
kTypeSearchFlagThrowOnError = 0x2,
kTypeSearchFlagDontUseExecutingImage = 0x4
};
class LIBIL2CPP_CODEGEN_API Class
{
public:
static Il2CppClass* FromIl2CppType(const Il2CppType* type, bool throwOnError = true);
static Il2CppClass* FromIl2CppTypeEnum(Il2CppTypeEnum type);
static Il2CppClass* FromName(const Il2CppImage* image, const char* namespaze, const char *name);
static Il2CppClass* FromSystemType(Il2CppReflectionType *type);
static Il2CppClass* FromGenericParameter(Il2CppMetadataGenericParameterHandle param);
static Il2CppClass* GetElementClass(Il2CppClass *klass);
static const Il2CppType* GetEnumBaseType(Il2CppClass *klass);
static const EventInfo* GetEvents(Il2CppClass *klass, void* *iter);
static FieldInfo* GetFields(Il2CppClass *klass, void* *iter);
static FieldInfo* GetFieldFromName(Il2CppClass *klass, const char* name);
static const MethodInfo* GetFinalizer(Il2CppClass *klass);
static int32_t GetInstanceSize(const Il2CppClass *klass);
static Il2CppClass* GetInterfaces(Il2CppClass *klass, void* *iter);
static const MethodInfo* GetMethods(Il2CppClass *klass, void* *iter);
static const MethodInfo* GetMethodFromName(Il2CppClass *klass, const char* name, int argsCount);
static const MethodInfo* GetMethodFromNameFlags(Il2CppClass *klass, const char* name, int argsCount, int32_t flags);
static const MethodInfo* GetMethodFromNameFlagsAndSig(Il2CppClass *klass, const char* name, int argsCount, int32_t flags, const Il2CppType** argTypes);
static const MethodInfo* GetGenericInstanceMethodFromDefintion(Il2CppClass* genericInstanceClass, const MethodInfo* methodDefinition);
static const char* GetName(Il2CppClass *klass);
static const char* GetNamespace(Il2CppClass *klass);
static Il2CppClass* GetNestedTypes(Il2CppClass *klass, void* *iter);
static size_t GetNumMethods(const Il2CppClass* klass);
static size_t GetNumProperties(const Il2CppClass* klass);
static size_t GetNumFields(const Il2CppClass* klass);
static Il2CppClass* GetParent(Il2CppClass *klass);
static const PropertyInfo* GetProperties(Il2CppClass *klass, void* *iter);
static const PropertyInfo* GetPropertyFromName(Il2CppClass *klass, const char* name);
static int32_t GetValueSize(Il2CppClass *klass, uint32_t *align);
//for Unsafe, but more performant version of HasParent, see ClassInlines.h
static bool HasParent(Il2CppClass *klass, Il2CppClass *parent);
static bool IsAssignableFrom(Il2CppClass *klass, Il2CppClass *oklass);
static bool IsAssignableFrom(Il2CppReflectionType *klass, Il2CppReflectionType *oklass);
static bool IsGeneric(const Il2CppClass *klass);
static bool IsInflated(const Il2CppClass *klass);
static bool IsGenericTypeDefinition(const Il2CppClass *klass);
static bool IsSubclassOf(Il2CppClass *klass, Il2CppClass *klassc, bool check_interfaces);
static bool IsValuetype(const Il2CppClass *klass);
static bool IsBlittable(const Il2CppClass *klass);
static bool HasDefaultConstructor(Il2CppClass* klass);
static int GetFlags(const Il2CppClass *klass);
static bool IsAbstract(const Il2CppClass *klass);
static bool IsInterface(const Il2CppClass *klass);
static bool IsNullable(const Il2CppClass *klass);
static Il2CppClass* GetNullableArgument(const Il2CppClass* klass);
static int GetArrayElementSize(const Il2CppClass *klass);
static const Il2CppType* GetByrefType(Il2CppClass *klass);
static const Il2CppType* GetType(Il2CppClass *klass);
static const Il2CppType* GetType(Il2CppClass *klass, const TypeNameParseInfo &info);
static bool HasAttribute(Il2CppClass *klass, Il2CppClass *attr_class);
static bool IsEnum(const Il2CppClass *klass);
static const Il2CppImage* GetImage(Il2CppClass* klass);
static const char *GetAssemblyName(const Il2CppClass *klass);
static const char *GetAssemblyNameNoExtension(const Il2CppClass *klass);
static Il2CppClass* GenericParamGetBaseType(Il2CppClass* klass);
static MonoGenericParameterInfo* GetOrCreateMonoGenericParameterInfo(Il2CppMetadataGenericParameterHandle parameterHandle);
static const int IgnoreNumberOfArguments;
public:
static void Init(Il2CppClass *klass);
static bool InitLocked(Il2CppClass* klass, const il2cpp::os::FastAutoLock& lock);
static Il2CppClass* GetArrayClass(Il2CppClass *element_class, uint32_t rank);
static Il2CppClass* GetBoundedArrayClass(Il2CppClass *element_class, uint32_t rank, bool bounded);
static Il2CppClass* GetInflatedGenericInstanceClass(Il2CppClass* klass, const Il2CppType** types, uint32_t typeCount);
static Il2CppClass* GetInflatedGenericInstanceClass(Il2CppClass* klass, const Il2CppGenericInst* genericInst);
static Il2CppClass* InflateGenericClass(Il2CppClass* klass, Il2CppGenericContext *context);
static const Il2CppType* InflateGenericType(const Il2CppType* type, Il2CppGenericContext *context);
static Il2CppMetadataGenericContainerHandle GetGenericContainer(Il2CppClass *klass);
static const MethodInfo* GetCCtor(Il2CppClass *klass);
static const char* GetFieldDefaultValue(const FieldInfo *field, const Il2CppType** type);
static int GetFieldMarshaledSize(const FieldInfo *field);
static int GetFieldMarshaledAlignment(const FieldInfo *field);
static Il2CppClass* GetPtrClass(const Il2CppType* type);
static Il2CppClass* GetPtrClass(Il2CppClass* elementClass);
static bool HasReferences(Il2CppClass *klass);
static void SetupEvents(Il2CppClass *klass);
static void SetupFields(Il2CppClass *klass);
static void SetupMethods(Il2CppClass *klass);
static void SetupNestedTypes(Il2CppClass *klass);
static void SetupProperties(Il2CppClass *klass);
static void SetupTypeHierarchy(Il2CppClass *klass);
static void SetupInterfaces(Il2CppClass *klass);
static const il2cpp::utils::dynamic_array<Il2CppClass*>& GetStaticFieldData();
static size_t GetBitmapSize(const Il2CppClass* klass);
static void GetBitmap(Il2CppClass* klass, size_t* bitmap, size_t& maxSetBit);
static const Il2CppType* il2cpp_type_from_type_info(const TypeNameParseInfo& info, TypeSearchFlags searchFlags);
static Il2CppClass* GetDeclaringType(Il2CppClass* klass);
static const MethodInfo* GetVirtualMethod(Il2CppClass* klass, const MethodInfo* virtualMethod);
static void SetClassInitializationError(Il2CppClass* klass, Il2CppException* error);
static void UpdateInitializedAndNoError(Il2CppClass *klass);
static IL2CPP_FORCE_INLINE bool IsGenericClassAssignableFrom(const Il2CppClass* klass, const Il2CppClass* oklass, const Il2CppClass* implementingClass = il2cpp_defaults.missing_class)
{
return klass == oklass || IsGenericClassAssignableFromVariance(klass, oklass, implementingClass);
}
static IL2CPP_FORCE_INLINE bool IsGenericClassAssignableFromVariance(const Il2CppClass* klass, const Il2CppClass* oklass, const Il2CppClass* implementingClass = il2cpp_defaults.missing_class)
{
IL2CPP_ASSERT(klass != oklass && "IsGenericClassAssignableFromVariance is for generic variance checks - you should call IsGenericClassAssignableFrom instead");
const Il2CppGenericClass* genericClass = klass->generic_class;
const Il2CppGenericClass* oGenericClass = oklass->generic_class;
if (oGenericClass == NULL || !GenericClass::HasSameGenericTypeDefinition(oGenericClass, genericClass))
return false;
const Il2CppGenericInst* genericInst = genericClass->context.class_inst;
const Il2CppGenericInst* oGenericInst = oGenericClass->context.class_inst;
Il2CppMetadataGenericContainerHandle genericContainer = MetadataCache::GetGenericContainerFromGenericClass(klass->image, klass->generic_class);
IL2CPP_ASSERT(oGenericInst->type_argc == genericInst->type_argc);
for (uint32_t i = 0; i < genericInst->type_argc; ++i)
{
uint16_t flags = MetadataCache::GetGenericParameterFlags(MetadataCache::GetGenericParameterFromIndex(genericContainer, i));
const int32_t parameterVariance = flags & IL2CPP_GENERIC_PARAMETER_ATTRIBUTE_VARIANCE_MASK;
Il2CppClass* genericParameterType = Class::FromIl2CppType(genericInst->type_argv[i]);
Il2CppClass* oGenericParameterType = Class::FromIl2CppType(oGenericInst->type_argv[i]);
if (parameterVariance == IL2CPP_GENERIC_PARAMETER_ATTRIBUTE_NON_VARIANT || Class::IsValuetype(genericParameterType) || Class::IsValuetype(oGenericParameterType))
{
if (genericParameterType != oGenericParameterType)
{
if (implementingClass->rank || implementingClass->declaringType == il2cpp_defaults.array_class)
{
// For arrays or System.Array/InternalEnumerator<T> we need to follow the array variance rules when looking for an
// generic interface i.e. Int32[] should be assignable to IEnumerable<UInt32>
IL2CPP_ASSERT(implementingClass->rank || strcmp(implementingClass->name, "InternalEnumerator`1") == 0);
if (metadata::ArrayMetadata::GetArrayVarianceReducedType(genericParameterType) != metadata::ArrayMetadata::GetArrayVarianceReducedType(oGenericParameterType))
return false;
}
else
{
return false;
}
}
}
else if (parameterVariance == IL2CPP_GENERIC_PARAMETER_ATTRIBUTE_COVARIANT)
{
if (!Class::IsAssignableFrom(genericParameterType, oGenericParameterType))
return false;
}
else
{
IL2CPP_ASSERT(parameterVariance == IL2CPP_GENERIC_PARAMETER_ATTRIBUTE_CONTRAVARIANT);
if (!Class::IsAssignableFrom(oGenericParameterType, genericParameterType))
return false;
}
}
return true;
}
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,83 @@
#pragma once
//This file should not include anything from VM. This is included by both libil2cpp and the codegen headers
#include "il2cpp-config.h"
#include "il2cpp-class-internals.h"
#include "il2cpp-object-internals.h"
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API ClassInlines
{
public:
// we assume that the Il2CppClass's have already been initialized in this case, like in code generation
static inline bool HasParentUnsafe(const Il2CppClass* klass, const Il2CppClass* parent) { return klass->typeHierarchyDepth >= parent->typeHierarchyDepth && klass->typeHierarchy[parent->typeHierarchyDepth - 1] == parent; }
// This function is critical for performance, before optimization it
// caused up to 20% of all CPU usage in code generated by il2cpp
static IL2CPP_FORCE_INLINE Il2CppClass* InitFromCodegen(Il2CppClass *klass)
{
if (klass->initialized_and_no_error)
return klass;
return InitFromCodegenSlow(klass);
}
static IL2CPP_FORCE_INLINE const MethodInfo* InitRgcxFromCodegen(const MethodInfo *method)
{
if (method->rgctx_data)
return method;
return InitRgctxFromCodegenSlow(method);
}
static IL2CPP_NO_INLINE Il2CppClass* InitFromCodegenSlow(Il2CppClass *klass);
static IL2CPP_NO_INLINE Il2CppClass* InitFromCodegenSlow(Il2CppClass *klass, bool throwOnError);
static IL2CPP_NO_INLINE const MethodInfo* InitRgctxFromCodegenSlow(const MethodInfo* method);
//internal
static IL2CPP_FORCE_INLINE const VirtualInvokeData& GetInterfaceInvokeDataFromVTable(Il2CppObject* obj, const Il2CppClass* itf, Il2CppMethodSlot slot)
{
const Il2CppClass* klass = obj->klass;
IL2CPP_ASSERT(klass->initialized);
IL2CPP_ASSERT(slot < itf->method_count);
for (uint16_t i = 0; i < klass->interface_offsets_count; i++)
{
if (klass->interfaceOffsets[i].interfaceType == itf)
{
int32_t offset = klass->interfaceOffsets[i].offset;
IL2CPP_ASSERT(offset != -1);
IL2CPP_ASSERT(offset + slot < klass->vtable_count);
return klass->vtable[offset + slot];
}
}
return GetInterfaceInvokeDataFromVTableSlowPath(obj, itf, slot);
}
static IL2CPP_FORCE_INLINE const VirtualInvokeData* GetInterfaceInvokeDataFromVTable(const Il2CppClass* klass, const Il2CppClass* itf, Il2CppMethodSlot slot)
{
IL2CPP_ASSERT(klass->is_vtable_initialized);
IL2CPP_ASSERT(slot < itf->method_count);
for (uint16_t i = 0; i < klass->interface_offsets_count; i++)
{
if (klass->interfaceOffsets[i].interfaceType == itf)
{
int32_t offset = klass->interfaceOffsets[i].offset;
IL2CPP_ASSERT(offset != -1);
IL2CPP_ASSERT(offset + slot < klass->vtable_count);
return &klass->vtable[offset + slot];
}
}
return GetInterfaceInvokeDataFromVTableSlowPath(klass, itf, slot);
}
// we don't want this method to get inlined because that makes GetInterfaceInvokeDataFromVTable method itself very large and performance suffers
static IL2CPP_NO_INLINE const VirtualInvokeData& GetInterfaceInvokeDataFromVTableSlowPath(Il2CppObject* obj, const Il2CppClass* itf, Il2CppMethodSlot slot);
static IL2CPP_NO_INLINE const VirtualInvokeData* GetInterfaceInvokeDataFromVTableSlowPath(const Il2CppClass* klass, const Il2CppClass* itf, Il2CppMethodSlot slot);
};
}
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include "il2cpp-config.h"
namespace il2cpp
{
namespace vm
{
class ClassLibraryPAL
{
public:
static void Initialize();
};
} // namespace vm
} // namepsace il2cpp

View File

@@ -0,0 +1,51 @@
#pragma once
#include "il2cpp-object-internals.h"
namespace il2cpp
{
namespace vm
{
struct LIBIL2CPP_CODEGEN_API NOVTABLE ComObjectBase : Il2CppIInspectable, Il2CppIMarshal
{
private:
Il2CppIMarshal* m_FreeThreadedMarshaler;
public:
inline ComObjectBase() :
m_FreeThreadedMarshaler(NULL)
{
}
inline ~ComObjectBase()
{
if (m_FreeThreadedMarshaler)
m_FreeThreadedMarshaler->Release();
}
virtual il2cpp_hresult_t STDCALL GetIids(uint32_t* iidCount, Il2CppGuid** iids) IL2CPP_OVERRIDE;
virtual il2cpp_hresult_t STDCALL GetRuntimeClassName(Il2CppHString* className) IL2CPP_OVERRIDE;
virtual il2cpp_hresult_t STDCALL GetTrustLevel(int32_t* trustLevel) IL2CPP_OVERRIDE;
virtual il2cpp_hresult_t STDCALL GetUnmarshalClass(const Il2CppGuid& iid, void* object, uint32_t context, void* reserved, uint32_t flags, Il2CppGuid* clsid) IL2CPP_OVERRIDE;
virtual il2cpp_hresult_t STDCALL GetMarshalSizeMax(const Il2CppGuid& iid, void* object, uint32_t context, void* reserved, uint32_t flags, uint32_t* size) IL2CPP_OVERRIDE;
virtual il2cpp_hresult_t STDCALL MarshalInterface(Il2CppIStream* stream, const Il2CppGuid& iid, void* object, uint32_t context, void* reserved, uint32_t flags) IL2CPP_OVERRIDE;
virtual il2cpp_hresult_t STDCALL UnmarshalInterface(Il2CppIStream* stream, const Il2CppGuid& iid, void** object) IL2CPP_OVERRIDE;
virtual il2cpp_hresult_t STDCALL ReleaseMarshalData(Il2CppIStream* stream) IL2CPP_OVERRIDE;
virtual il2cpp_hresult_t STDCALL DisconnectObject(uint32_t reserved) IL2CPP_OVERRIDE;
protected:
IL2CPP_FORCE_INLINE Il2CppIInspectable* GetIdentity()
{
return this;
}
il2cpp_hresult_t GetRuntimeClassNameImpl(Il2CppHString* className);
private:
ComObjectBase(const ComObjectBase&);
ComObjectBase& operator=(const ComObjectBase&);
il2cpp_hresult_t GetFreeThreadedMarshalerNoAddRef(Il2CppIMarshal** destination);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,25 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
struct Il2CppDomain;
struct Il2CppAppContext;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Domain
{
public:
static Il2CppDomain* GetCurrent();
static Il2CppDomain* GetRoot();
static void ContextInit(Il2CppDomain *domain);
static void ContextSet(Il2CppAppContext* context);
static Il2CppAppContext* ContextGet();
private:
static Il2CppDomain* S_domain;
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,17 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Enum
{
public:
// exported
static bool GetEnumValuesAndNames(Il2CppClass* enumType, Il2CppArray** values, Il2CppArray** names);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,19 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
struct EventInfo;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Event
{
public:
// exported
static uint32_t GetToken(const EventInfo *eventInfo);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,101 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
#include "utils/Il2CppError.h"
#include "utils/StringView.h"
#include "il2cpp-class-internals.h"
struct Il2CppException;
struct Il2CppImage;
struct Il2CppClass;
namespace il2cpp
{
namespace vm
{
class TypeNameParseInfo;
class LIBIL2CPP_CODEGEN_API Exception
{
// exported
public:
static Il2CppException* Get(il2cpp_hresult_t hresult, bool defaultToCOMException);
static void PrepareExceptionForThrow(Il2CppException* ex, MethodInfo* lastManagedFrame = NULL);
static NORETURN void Raise(Il2CppException* ex, MethodInfo* lastManagedFrame = NULL);
static NORETURN void Rethrow(Il2CppException* ex);
static NORETURN void RaiseOutOfMemoryException();
static NORETURN void RaiseOutOfMemoryException(const utils::StringView<Il2CppChar>& msg);
static NORETURN void RaiseNullReferenceException();
static NORETURN void RaiseNullReferenceException(const utils::StringView<Il2CppChar>& msg);
static NORETURN void RaiseDivideByZeroException();
static NORETURN void RaiseIndexOutOfRangeException();
static NORETURN void RaiseOverflowException();
static NORETURN void RaiseArgumentOutOfRangeException(const char* msg);
static NORETURN void Raise(il2cpp_hresult_t hresult, bool defaultToCOMException);
static void RaiseIfError(const utils::Il2CppError& error);
inline static void RaiseIfFailed(il2cpp_hresult_t hresult, bool defaultToCOMException)
{
if (IL2CPP_HR_FAILED(hresult))
Raise(hresult, defaultToCOMException);
}
////TODO: rename to NewFromClassNameAndMessage
static Il2CppException* FromNameMsg(const Il2CppImage* image, const char* name_space, const char* name, const char* msg);
static Il2CppException* FromNameMsg(const Il2CppImage* image, const char* name_space, const char* name, const utils::StringView<Il2CppChar>& msg);
static Il2CppException* FromNameMsg(const Il2CppImage* image, const char* name_space, const char* name, const utils::StringView<Il2CppChar>& msg, il2cpp_hresult_t hresult);
public:
////TODO: rename all of these to NewXXX
static Il2CppException* GetArgumentException(const char *arg, const char *msg);
static Il2CppException* GetArgumentException(const utils::StringView<Il2CppChar>& arg, const utils::StringView<Il2CppChar>& msg);
static Il2CppException* GetArgumentNullException(const char *arg);
static Il2CppException* GetArgumentOutOfRangeException(const char *arg);
static Il2CppException* GetTypeInitializationException(const char *msg, Il2CppException* innerException);
static Il2CppException* GetIndexOutOfRangeException();
static Il2CppException* GetIndexOutOfRangeException(const utils::StringView<Il2CppChar>& msg);
static Il2CppException* GetNullReferenceException(const utils::StringView<Il2CppChar>& msg);
static Il2CppException* GetInvalidCastException(const char* msg);
static Il2CppException* GetInvalidCastException(const utils::StringView<Il2CppChar>& msg);
static Il2CppException* GetTypeLoadException();
static Il2CppException* GetTypeLoadException(const TypeNameParseInfo& typeNameParseInfo);
static Il2CppException* GetTypeLoadException(const utils::StringView<char>& namespaze, const utils::StringView<char>& typeName, const utils::StringView<char>& assemblyName);
static Il2CppException* GetTypeLoadExceptionForWindowsRuntimeType(const utils::StringView<char>& namespaze, const utils::StringView<char>& typeName);
static Il2CppException* GetOutOfMemoryException(const utils::StringView<Il2CppChar>& msg);
static Il2CppException* GetOverflowException();
static Il2CppException* GetOverflowException(const char* msg);
static Il2CppException* GetFormatException(const char* msg);
static Il2CppException* GetSystemException();
static Il2CppException* GetNotSupportedException(const char* msg);
static Il2CppException* GetArrayTypeMismatchException();
static Il2CppException* GetTypeLoadException(const char* msg);
static Il2CppException* GetEntryPointNotFoundException(const char* msg);
static Il2CppException* GetAmbiguousImplementationException(const char* msg);
static Il2CppException* GetDllNotFoundException(const char* msg);
static Il2CppException* GetInvalidOperationException(const char* msg);
static Il2CppException* GetThreadInterruptedException();
static Il2CppException* GetThreadAbortException();
static Il2CppException* GetThreadStateException(const char* msg);
static Il2CppException* GetSynchronizationLockException(const char* msg);
static Il2CppException* GetMissingMethodException(const char* msg);
static Il2CppException* GetMarshalDirectiveException(const char* msg);
static Il2CppException* GetTargetException(const char* msg);
static Il2CppException* GetMethodAccessException(const char* msg);
static Il2CppException* GetExecutionEngineException(const char* msg);
static Il2CppException* GetUnauthorizedAccessException(const utils::StringView<Il2CppChar>& msg);
static Il2CppException* GetUnauthorizedAccessException(const char* msg);
static Il2CppException* GetDivideByZeroException();
static Il2CppException* GetPlatformNotSupportedException(const utils::StringView<Il2CppChar>& msg);
static Il2CppException* GetFileLoadException(const char* msg);
static Il2CppException* GetFileNotFoundException(const utils::StringView<Il2CppChar>& msg);
static Il2CppException* GetCustomAttributeFormatException(const char* msg);
static Il2CppException* GetMaximumNestedGenericsException();
static void StoreExceptionInfo(Il2CppException* ex, Il2CppString* exceptionString);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,51 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
struct FieldInfo;
struct Il2CppType;
struct Il2CppClass;
struct Il2CppObject;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Field
{
public:
// exported
static const Il2CppType* GetType(FieldInfo *field);
static Il2CppClass* GetParent(FieldInfo *field);
static int GetFlags(FieldInfo *field);
static const char* GetName(FieldInfo *field);
static size_t GetOffset(FieldInfo *field);
static void GetValue(Il2CppObject *obj, FieldInfo *field, void *value);
static uint32_t GetToken(const FieldInfo *field);
static Il2CppObject* GetValueObject(FieldInfo *field, Il2CppObject *obj);
static Il2CppObject* GetValueObjectForThread(FieldInfo *field, Il2CppObject *obj, Il2CppThread *thread);
static bool HasAttribute(FieldInfo *field, Il2CppClass *attr_class);
static bool IsDeleted(FieldInfo *field);
static void SetValue(Il2CppObject *obj, const FieldInfo *field, void *value);
static void StaticGetValue(FieldInfo *field, void *value);
static void StaticGetValueInternal(FieldInfo *field, void *value, void *threadStaticData);
static void StaticGetValueForThread(FieldInfo *field, void *value, Il2CppInternalThread *thread);
static void StaticSetValue(FieldInfo *field, void *value);
static void StaticSetValueForThread(FieldInfo *field, void *value, Il2CppThread *thread);
static void SetInstanceFieldValueObject(Il2CppObject* objectInstance, FieldInfo* field, Il2CppObject* value);
public:
// internal
static const char* GetData(FieldInfo *field);
static void GetDefaultFieldValue(FieldInfo *field, void *value);
static bool IsInstance(FieldInfo* field);
static bool IsNormalStatic(FieldInfo* field);
static bool IsThreadStatic(FieldInfo* field);
static void SetValueRaw(const Il2CppType *type, void *dest, void *value, bool deref_pointer);
static void* GetInstanceFieldDataPointer(void* instance, FieldInfo* field);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,43 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
struct Il2CppClass;
struct Il2CppGenericClass;
struct Il2CppGenericContext;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API GenericClass
{
public:
// exported
public:
//internal
static Il2CppClass* GetClass(Il2CppGenericClass *gclass, bool throwOnError = true);
static Il2CppGenericContext* GetContext(Il2CppGenericClass *gclass);
static Il2CppClass* GetTypeDefinition(Il2CppGenericClass *gclass);
static bool IsEnum(Il2CppGenericClass *gclass);
static bool IsValueType(Il2CppGenericClass *gclass);
static void SetupEvents(Il2CppClass* genericInstanceType);
static void SetupFields(Il2CppClass* genericInstanceType);
static void SetupMethods(Il2CppClass* genericInstanceType);
static void SetupProperties(Il2CppClass* genericInstanceType);
static bool HasSameGenericTypeDefinition(const Il2CppGenericClass* gclass1, const Il2CppGenericClass* gclass2)
{
IL2CPP_ASSERT(gclass1->type->type == IL2CPP_TYPE_VALUETYPE || gclass1->type->type == IL2CPP_TYPE_CLASS);
IL2CPP_ASSERT(gclass2->type->type == IL2CPP_TYPE_VALUETYPE || gclass2->type->type == IL2CPP_TYPE_CLASS);
return gclass1->type->data.typeHandle == gclass2->type->data.typeHandle;
}
private:
static Il2CppClass* CreateClass(Il2CppGenericClass *gclass, bool throwOnError = true);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,26 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
#include "il2cpp-metadata.h"
struct Il2CppClass;
struct Il2CppGenericContainer;
struct Il2CppGenericParameter;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API GenericContainer
{
public:
// exported
public:
//internal
static Il2CppClass* GetDeclaringType(Il2CppMetadataGenericContainerHandle handle);
static Il2CppMetadataGenericParameterHandle GetGenericParameter(Il2CppMetadataGenericContainerHandle handle, uint16_t index);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,128 @@
#pragma once
#include <stdint.h>
#include "Assembly.h"
#include "MetadataCache.h"
#include "StackTrace.h"
#include "il2cpp-class-internals.h"
#include "il2cpp-config.h"
#include "os/Mutex.h"
#include "utils/dynamic_array.h"
#include "vm-utils/MethodDefinitionKey.h"
struct MethodInfo;
struct Il2CppClass;
struct Il2CppGenericContext;
struct Il2CppGenericInst;
struct Il2CppGenericMethod;
struct Il2CppType;
struct Il2CppString;
namespace il2cpp
{
namespace vm
{
class GlobalMetadata
{
public:
static void Register(const Il2CppCodeRegistration* const codeRegistration, const Il2CppMetadataRegistration* const metadataRegistration, const Il2CppCodeGenOptions* const codeGenOptions);
static bool Initialize(int32_t* imagesCount, int32_t* assembliesCount);
static void InitializeAllMethodMetadata();
static void* InitializeRuntimeMetadata(uintptr_t* metadataPointer, bool throwOnError);
static void InitializeStringLiteralTable();
static void InitializeWindowsRuntimeTypeNamesTables(WindowsRuntimeTypeNameToClassMap& windowsRuntimeTypeNameToClassMap, ClassToWindowsRuntimeTypeNameMap& classToWindowsRuntimeTypeNameMap);
static void InitializeUnresolvedSignatureTable(Il2CppUnresolvedSignatureMap& unresolvedSignatureMap);
static void InitializeGenericMethodTable(Il2CppMethodTableMap& methodTableMap);
static void BuildIl2CppImage(Il2CppImage* image, ImageIndex imageIndex, AssemblyIndex* imageAssemblyIndex);
static void BuildIl2CppAssembly(Il2CppAssembly* assembly, AssemblyIndex assemblyIndex, ImageIndex* assemblyImageIndex);
static void Clear();
static const MethodInfo* GetAssemblyEntryPoint(const Il2CppImage* image);
static Il2CppMetadataTypeHandle GetAssemblyTypeHandle(const Il2CppImage* image, AssemblyTypeIndex index);
static const Il2CppAssembly* GetReferencedAssembly(const Il2CppAssembly* assembly, int32_t referencedAssemblyTableIndex, const Il2CppAssembly assembliesTable[], int assembliesCount);
static Il2CppMetadataTypeHandle GetAssemblyExportedTypeHandle(const Il2CppImage* image, AssemblyExportedTypeIndex index);
static Il2CppClass* GetTypeInfoFromType(const Il2CppType* type);
static Il2CppClass* GetTypeInfoFromTypeDefinitionIndex(TypeDefinitionIndex index);
static Il2CppClass* GetTypeInfoFromHandle(Il2CppMetadataTypeHandle handle);
static const Il2CppType* GetInterfaceFromOffset(const Il2CppClass* klass, TypeInterfaceIndex offset);
static Il2CppInterfaceOffsetInfo GetInterfaceOffsetInfo(const Il2CppClass* klass, TypeInterfaceOffsetIndex index);
static Il2CppMetadataTypeHandle GetTypeHandleFromIndex(TypeDefinitionIndex typeIndex);
static Il2CppMetadataTypeHandle GetTypeHandleFromType(const Il2CppType* type);
static bool TypeIsNested(Il2CppMetadataTypeHandle handle);
static bool TypeIsValueType(Il2CppMetadataTypeHandle handle);
static bool StructLayoutPackIsDefault(Il2CppMetadataTypeHandle handle);
static int32_t StructLayoutPack(Il2CppMetadataTypeHandle handle);
static bool StructLayoutSizeIsDefault(Il2CppMetadataTypeHandle handle);
static std::pair<const char*, const char*> GetTypeNamespaceAndName(Il2CppMetadataTypeHandle handle);
static Il2CppClass* GetNestedTypeFromOffset(const Il2CppClass* klass, TypeNestedTypeIndex offset);
static Il2CppMetadataTypeHandle GetNestedTypes(Il2CppMetadataTypeHandle handle, void** iter);
static CustomAttributesCache* GenerateCustomAttributesCache(const Il2CppImage* image, uint32_t token);
static CustomAttributesCache* GenerateCustomAttributesCache(Il2CppMetadataCustomAttributeHandle handle);
static Il2CppMetadataCustomAttributeHandle GetCustomAttributeTypeToken(const Il2CppImage* image, uint32_t token);
static std::tuple<void*, void*> GetCustomAttributeDataRange(const Il2CppImage* image, uint32_t token);
static bool HasAttribute(Il2CppMetadataCustomAttributeHandle token, Il2CppClass* attribute);
static bool HasAttribute(const Il2CppImage* image, uint32_t token, Il2CppClass* attribute);
static const MethodInfo* GetMethodInfoFromMethodHandle(Il2CppMetadataMethodDefinitionHandle handle);
static const MethodInfo* GetMethodInfoFromVTableSlot(const Il2CppClass* klass, int32_t vTableSlot);
static const uint8_t* GetParameterDefaultValue(const MethodInfo* method, int32_t parameterPosition, const Il2CppType** type, bool* isExplicitySetNullDefaultValue);
static const uint8_t* GetFieldDefaultValue(const FieldInfo* field, const Il2CppType** type);
static uint32_t GetFieldOffset(const Il2CppClass* klass, int32_t fieldIndexInType, FieldInfo* field);
static int GetFieldMarshaledSizeForField(const FieldInfo* field);
static Il2CppMetadataFieldInfo GetFieldInfo(const Il2CppClass* klass, TypeFieldIndex index);
static Il2CppMetadataMethodInfo GetMethodInfo(const Il2CppClass* klass, TypeMethodIndex index);
static Il2CppMetadataParameterInfo GetParameterInfo(const Il2CppClass* klass, Il2CppMetadataMethodDefinitionHandle handle, MethodParameterIndex index);
static Il2CppMetadataPropertyInfo GetPropertyInfo(const Il2CppClass* klass, TypePropertyIndex index);
static Il2CppMetadataEventInfo GetEventInfo(const Il2CppClass* klass, TypeEventIndex index);
static Il2CppMetadataGenericContainerHandle GetGenericContainerFromGenericClass(const Il2CppGenericClass* genericClass);
static Il2CppMetadataGenericContainerHandle GetGenericContainerFromMethod(Il2CppMetadataMethodDefinitionHandle handle);
static Il2CppMetadataGenericParameterHandle GetGenericParameterFromType(const Il2CppType* type);
static const MethodInfo* GetGenericInstanceMethod(const MethodInfo* genericMethodDefinition, const Il2CppGenericContext* context);
static const Il2CppType* GetTypeFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef);
static const Il2CppGenericMethod* GetGenericMethodFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef);
static std::pair<const Il2CppType*, const MethodInfo*> GetConstrainedCallFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef);
static Il2CppClass* GetContainerDeclaringType(Il2CppMetadataGenericContainerHandle handle);
static Il2CppClass* GetParameterDeclaringType(Il2CppMetadataGenericParameterHandle handle);
static Il2CppMetadataGenericParameterHandle GetGenericParameterFromIndex(Il2CppMetadataGenericContainerHandle handle, GenericContainerParameterIndex index);
static const Il2CppType* GetGenericParameterConstraintFromIndex(Il2CppMetadataGenericParameterHandle handle, GenericParameterConstraintIndex index);
static void MakeGenericArgType(Il2CppMetadataGenericContainerHandle containerHandle, Il2CppMetadataGenericParameterHandle paramHandle, Il2CppType* arg);
static uint32_t GetGenericContainerCount(Il2CppMetadataGenericContainerHandle handle);
static bool GetGenericContainerIsMethod(Il2CppMetadataGenericContainerHandle handle);
static const char* GetGenericParameterName(Il2CppMetadataGenericParameterHandle handle);
static Il2CppGenericParameterInfo GetGenericParameterInfo(Il2CppMetadataGenericParameterHandle handle);
static uint16_t GetGenericParameterFlags(Il2CppMetadataGenericParameterHandle handle);
static int16_t GetGenericConstraintCount(Il2CppMetadataGenericParameterHandle handle);
static const Il2CppGenericMethod* GetGenericMethodFromTokenMethodTuple(const Il2CppTokenIndexMethodTuple* tuple);
static const MethodInfo* GetMethodInfoFromCatchPoint(const Il2CppCatchPoint* cp);
static const MethodInfo* GetMethodInfoFromSequencePoint(const Il2CppSequencePoint* cp);
static Il2CppClass* GetTypeInfoFromTypeSourcePair(const Il2CppTypeSourceFilePair* pair);
static Il2CppClass* GetTypeInfoFromTypeIndex(TypeIndex index, bool throwOnError = true);
static const Il2CppType* GetIl2CppTypeFromIndex(TypeIndex index);
static const MethodInfo* GetMethodInfoFromMethodDefinitionIndex(MethodIndex index);
template<typename T>
static inline bool IsRuntimeMetadataInitialized(T item)
{
// Runtime metadata items are initialized to an encoded token with the low bit set
// on startup and when initialized are a pointer to an runtime metadata item
// So we can rely on pointer alignment being > 1 on our supported platforms
return !((uintptr_t)item & 1);
}
#if IL2CPP_ENABLE_NATIVE_STACKTRACES
static void GetAllManagedMethods(std::vector<MethodDefinitionKey>& managedMethods);
#endif
};
}
}

View File

@@ -0,0 +1,343 @@
#pragma once
#include "il2cpp-metadata.h"
// This file contains the structures specifying how we store converted metadata.
// These structures have 3 constraints:
// 1. These structures will be stored in an external file, and as such must not contain any pointers.
// All references to other metadata should occur via an index into a corresponding table.
// 2. These structures are assumed to be const. Either const structures in the binary or mapped as
// readonly memory from an external file. Do not add any 'calculated' fields which will be written to at runtime.
// 3. These structures should be optimized for size. Other structures are used at runtime which can
// be larger to store cached information
// Encoded index (1 bit)
// MethodDef - 0
// MethodSpec - 1
// We use the top 3 bits to indicate what table to index into
// Type Binary Hex
// Il2CppClass 001 0x20000000
// Il2CppType 010 0x40000000
// MethodInfo 011 0x60000000
// FieldInfo 100 0x80000000
// StringLiteral 101 0xA0000000
// MethodRef 110 0xC0000000
// FieldRVA 111 0xE0000000
typedef uint32_t EncodedMethodIndex;
enum Il2CppMetadataUsage
{
kIl2CppMetadataUsageInvalid,
kIl2CppMetadataUsageTypeInfo,
kIl2CppMetadataUsageIl2CppType,
kIl2CppMetadataUsageMethodDef,
kIl2CppMetadataUsageFieldInfo,
kIl2CppMetadataUsageStringLiteral,
kIl2CppMetadataUsageMethodRef,
kIl2CppMetadataUsageFieldRva
};
enum Il2CppInvalidMetadataUsageToken
{
kIl2CppInvalidMetadataUsageNoData = 0,
kIl2CppInvalidMetadataUsageAmbiguousMethod = 1,
};
#ifdef __cplusplus
static inline Il2CppMetadataUsage GetEncodedIndexType(EncodedMethodIndex index)
{
return (Il2CppMetadataUsage)((index & 0xE0000000) >> 29);
}
static inline uint32_t GetDecodedMethodIndex(EncodedMethodIndex index)
{
return (index & 0x1FFFFFFEU) >> 1;
}
#endif
typedef struct Il2CppInterfaceOffsetPair
{
TypeIndex interfaceTypeIndex;
int32_t offset;
} Il2CppInterfaceOffsetPair;
typedef struct Il2CppTypeDefinition
{
StringIndex nameIndex;
StringIndex namespaceIndex;
TypeIndex byvalTypeIndex;
TypeIndex declaringTypeIndex;
TypeIndex parentIndex;
TypeIndex elementTypeIndex; // we can probably remove this one. Only used for enums
GenericContainerIndex genericContainerIndex;
uint32_t flags;
FieldIndex fieldStart;
MethodIndex methodStart;
EventIndex eventStart;
PropertyIndex propertyStart;
NestedTypeIndex nestedTypesStart;
InterfacesIndex interfacesStart;
VTableIndex vtableStart;
InterfacesIndex interfaceOffsetsStart;
uint16_t method_count;
uint16_t property_count;
uint16_t field_count;
uint16_t event_count;
uint16_t nested_type_count;
uint16_t vtable_count;
uint16_t interfaces_count;
uint16_t interface_offsets_count;
// bitfield to portably encode boolean values as single bits
// 01 - valuetype;
// 02 - enumtype;
// 03 - has_finalize;
// 04 - has_cctor;
// 05 - is_blittable;
// 06 - is_import_or_windows_runtime;
// 07-10 - One of nine possible PackingSize values (0, 1, 2, 4, 8, 16, 32, 64, or 128)
// 11 - PackingSize is default
// 12 - ClassSize is default
// 13-16 - One of nine possible PackingSize values (0, 1, 2, 4, 8, 16, 32, 64, or 128) - the specified packing size (even for explicit layouts)
uint32_t bitfield;
uint32_t token;
} Il2CppTypeDefinition;
typedef struct Il2CppFieldDefinition
{
StringIndex nameIndex;
TypeIndex typeIndex;
uint32_t token;
} Il2CppFieldDefinition;
typedef struct Il2CppFieldDefaultValue
{
FieldIndex fieldIndex;
TypeIndex typeIndex;
DefaultValueDataIndex dataIndex;
} Il2CppFieldDefaultValue;
typedef struct Il2CppFieldMarshaledSize
{
FieldIndex fieldIndex;
TypeIndex typeIndex;
int32_t size;
} Il2CppFieldMarshaledSize;
typedef struct Il2CppFieldRef
{
TypeIndex typeIndex;
FieldIndex fieldIndex; // local offset into type fields
} Il2CppFieldRef;
typedef struct Il2CppParameterDefinition
{
StringIndex nameIndex;
uint32_t token;
TypeIndex typeIndex;
} Il2CppParameterDefinition;
typedef struct Il2CppParameterDefaultValue
{
ParameterIndex parameterIndex;
TypeIndex typeIndex;
DefaultValueDataIndex dataIndex;
} Il2CppParameterDefaultValue;
typedef struct Il2CppMethodDefinition
{
StringIndex nameIndex;
TypeDefinitionIndex declaringType;
TypeIndex returnType;
ParameterIndex parameterStart;
GenericContainerIndex genericContainerIndex;
uint32_t token;
uint16_t flags;
uint16_t iflags;
uint16_t slot;
uint16_t parameterCount;
} Il2CppMethodDefinition;
typedef struct Il2CppEventDefinition
{
StringIndex nameIndex;
TypeIndex typeIndex;
MethodIndex add;
MethodIndex remove;
MethodIndex raise;
uint32_t token;
} Il2CppEventDefinition;
typedef struct Il2CppPropertyDefinition
{
StringIndex nameIndex;
MethodIndex get;
MethodIndex set;
uint32_t attrs;
uint32_t token;
} Il2CppPropertyDefinition;
typedef struct Il2CppStringLiteral
{
uint32_t length;
StringLiteralIndex dataIndex;
} Il2CppStringLiteral;
typedef struct Il2CppAssemblyNameDefinition
{
StringIndex nameIndex;
StringIndex cultureIndex;
StringIndex publicKeyIndex;
uint32_t hash_alg;
int32_t hash_len;
uint32_t flags;
int32_t major;
int32_t minor;
int32_t build;
int32_t revision;
uint8_t public_key_token[PUBLIC_KEY_BYTE_LENGTH];
} Il2CppAssemblyNameDefinition;
typedef struct Il2CppImageDefinition
{
StringIndex nameIndex;
AssemblyIndex assemblyIndex;
TypeDefinitionIndex typeStart;
uint32_t typeCount;
TypeDefinitionIndex exportedTypeStart;
uint32_t exportedTypeCount;
MethodIndex entryPointIndex;
uint32_t token;
CustomAttributeIndex customAttributeStart;
uint32_t customAttributeCount;
} Il2CppImageDefinition;
typedef struct Il2CppAssemblyDefinition
{
ImageIndex imageIndex;
uint32_t token;
int32_t referencedAssemblyStart;
int32_t referencedAssemblyCount;
Il2CppAssemblyNameDefinition aname;
} Il2CppAssemblyDefinition;
typedef struct Il2CppCustomAttributeDataRange
{
uint32_t token;
uint32_t startOffset;
} Il2CppCustomAttributeDataRange;
typedef struct Il2CppMetadataRange
{
int32_t start;
int32_t length;
} Il2CppMetadataRange;
typedef struct Il2CppGenericContainer
{
/* index of the generic type definition or the generic method definition corresponding to this container */
int32_t ownerIndex; // either index into Il2CppClass metadata array or Il2CppMethodDefinition array
int32_t type_argc;
/* If true, we're a generic method, otherwise a generic type definition. */
int32_t is_method;
/* Our type parameters. */
GenericParameterIndex genericParameterStart;
} Il2CppGenericContainer;
typedef struct Il2CppGenericParameter
{
GenericContainerIndex ownerIndex; /* Type or method this parameter was defined in. */
StringIndex nameIndex;
GenericParameterConstraintIndex constraintsStart;
int16_t constraintsCount;
uint16_t num;
uint16_t flags;
} Il2CppGenericParameter;
typedef struct Il2CppWindowsRuntimeTypeNamePair
{
StringIndex nameIndex;
TypeIndex typeIndex;
} Il2CppWindowsRuntimeTypeNamePair;
#pragma pack(push, p1,4)
typedef struct Il2CppGlobalMetadataHeader
{
int32_t sanity;
int32_t version;
int32_t stringLiteralOffset; // string data for managed code
int32_t stringLiteralSize;
int32_t stringLiteralDataOffset;
int32_t stringLiteralDataSize;
int32_t stringOffset; // string data for metadata
int32_t stringSize;
int32_t eventsOffset; // Il2CppEventDefinition
int32_t eventsSize;
int32_t propertiesOffset; // Il2CppPropertyDefinition
int32_t propertiesSize;
int32_t methodsOffset; // Il2CppMethodDefinition
int32_t methodsSize;
int32_t parameterDefaultValuesOffset; // Il2CppParameterDefaultValue
int32_t parameterDefaultValuesSize;
int32_t fieldDefaultValuesOffset; // Il2CppFieldDefaultValue
int32_t fieldDefaultValuesSize;
int32_t fieldAndParameterDefaultValueDataOffset; // uint8_t
int32_t fieldAndParameterDefaultValueDataSize;
int32_t fieldMarshaledSizesOffset; // Il2CppFieldMarshaledSize
int32_t fieldMarshaledSizesSize;
int32_t parametersOffset; // Il2CppParameterDefinition
int32_t parametersSize;
int32_t fieldsOffset; // Il2CppFieldDefinition
int32_t fieldsSize;
int32_t genericParametersOffset; // Il2CppGenericParameter
int32_t genericParametersSize;
int32_t genericParameterConstraintsOffset; // TypeIndex
int32_t genericParameterConstraintsSize;
int32_t genericContainersOffset; // Il2CppGenericContainer
int32_t genericContainersSize;
int32_t nestedTypesOffset; // TypeDefinitionIndex
int32_t nestedTypesSize;
int32_t interfacesOffset; // TypeIndex
int32_t interfacesSize;
int32_t vtableMethodsOffset; // EncodedMethodIndex
int32_t vtableMethodsSize;
int32_t interfaceOffsetsOffset; // Il2CppInterfaceOffsetPair
int32_t interfaceOffsetsSize;
int32_t typeDefinitionsOffset; // Il2CppTypeDefinition
int32_t typeDefinitionsSize;
int32_t imagesOffset; // Il2CppImageDefinition
int32_t imagesSize;
int32_t assembliesOffset; // Il2CppAssemblyDefinition
int32_t assembliesSize;
int32_t fieldRefsOffset; // Il2CppFieldRef
int32_t fieldRefsSize;
int32_t referencedAssembliesOffset; // int32_t
int32_t referencedAssembliesSize;
int32_t attributeDataOffset;
int32_t attributeDataSize;
int32_t attributeDataRangeOffset;
int32_t attributeDataRangeSize;
int32_t unresolvedVirtualCallParameterTypesOffset; // TypeIndex
int32_t unresolvedVirtualCallParameterTypesSize;
int32_t unresolvedVirtualCallParameterRangesOffset; // Il2CppMetadataRange
int32_t unresolvedVirtualCallParameterRangesSize;
int32_t windowsRuntimeTypeNamesOffset; // Il2CppWindowsRuntimeTypeNamePair
int32_t windowsRuntimeTypeNamesSize;
int32_t windowsRuntimeStringsOffset; // const char*
int32_t windowsRuntimeStringsSize;
int32_t exportedTypeDefinitionsOffset; // TypeDefinitionIndex
int32_t exportedTypeDefinitionsSize;
} Il2CppGlobalMetadataHeader;
#pragma pack(pop, p1)

View File

@@ -0,0 +1,25 @@
#pragma once
#include <il2cpp-object-internals.h>
#include "utils/StringView.h"
namespace il2cpp
{
namespace vm
{
class Il2CppHStringReference
{
private:
Il2CppHString m_String;
Il2CppHStringHeader m_Header;
public:
Il2CppHStringReference(const utils::StringView<Il2CppNativeChar>& str);
inline operator Il2CppHString() const
{
return m_String;
}
};
}
}

View File

@@ -0,0 +1,78 @@
#pragma once
#include <stdint.h>
#include <string>
#include <vector>
#include "il2cpp-config.h"
struct Il2CppClass;
struct MethodInfo;
struct Il2CppAssembly;
struct Il2CppDelegate;
struct Il2CppImage;
struct Il2CppType;
struct Il2CppGenericContext;
struct Il2CppGenericContainer;
struct Il2CppReflectionAssembly;
struct Il2CppArray;
class AssemblyVector;
namespace il2cpp
{
namespace vm
{
typedef std::vector<const Il2CppClass*> TypeVector;
class TypeNameParseInfo;
struct EmbeddedResourceRecord
{
EmbeddedResourceRecord(const Il2CppImage* image, const std::string& name, uint32_t offset, uint32_t size)
: image(image), name(name), offset(offset), size(size)
{}
const Il2CppImage* image;
std::string name;
uint32_t offset;
uint32_t size;
};
class LIBIL2CPP_CODEGEN_API Image
{
// exported
public:
static Il2CppImage* GetCorlib();
public:
static const char * GetName(const Il2CppImage* image);
static const char * GetFileName(const Il2CppImage* image);
static const Il2CppAssembly* GetAssembly(const Il2CppImage* image);
static const MethodInfo* GetEntryPoint(const Il2CppImage* image);
static const Il2CppImage* GetExecutingImage();
static const Il2CppImage* GetCallingImage();
static uint32_t GetNumTypes(const Il2CppImage* image);
static const Il2CppClass* GetType(const Il2CppImage* image, AssemblyTypeIndex index);
static Il2CppClass* FromTypeNameParseInfo(const Il2CppImage* image, const TypeNameParseInfo &info, bool ignoreCase);
static Il2CppClass* ClassFromName(const Il2CppImage* image, const char* namespaze, const char *name);
static void GetTypes(const Il2CppImage* image, bool exportedOnly, TypeVector* target);
static Il2CppArray* GetTypes(const Il2CppImage* image, bool exportedOnly);
struct EmbeddedResourceData
{
EmbeddedResourceData(EmbeddedResourceRecord record, void* data)
: record(record), data(data)
{}
EmbeddedResourceRecord record;
void* data;
};
static void CacheMemoryMappedResourceFile(Il2CppReflectionAssembly* assembly, void* memoryMappedFile);
static void* GetCachedMemoryMappedResourceFile(Il2CppReflectionAssembly* assembly);
static void CacheResourceData(EmbeddedResourceRecord record, void* data);
static void* GetCachedResourceData(const Il2CppImage* image, const std::string& name);
static void ClearCachedResourceData();
static void InitNestedTypes(const Il2CppImage *image);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,17 @@
#pragma once
#include "il2cpp-config.h"
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API InternalCalls
{
public:
static void Init();
static void Add(const char* name, Il2CppMethodPointer method);
static Il2CppMethodPointer Resolve(const char* name);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,23 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API LastError
{
public:
static uint32_t GetLastError();
static void SetLastError(uint32_t error);
static void StoreLastError();
static void InitializeLastErrorThreadStatic();
private:
static int32_t s_LastErrorThreadLocalStorageOffset;
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,26 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
struct Il2CppClass;
struct Il2CppObject;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Liveness
{
public:
typedef void (*register_object_callback)(Il2CppObject** arr, int size, void* userdata);
typedef void*(*ReallocateArrayCallback)(void* ptr, size_t size, void* state);
static void* AllocateStruct(Il2CppClass* filter, int max_object_count, register_object_callback callback, void* userdata, ReallocateArrayCallback reallocateArray);
static void FreeStruct(void* state);
static void Finalize(void* state);
static void FromRoot(Il2CppObject* root, void* state);
static void FromStatics(void* state);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,32 @@
#pragma once
#include "il2cpp-config.h"
#if _DEBUG
#include <map>
#include "os/Mutex.h"
#endif
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API MarshalAlloc
{
public:
static void* Allocate(size_t size);
static void* ReAlloc(void* ptr, size_t size);
static void Free(void* ptr);
static void* AllocateHGlobal(size_t size);
static void* ReAllocHGlobal(void* ptr, size_t size);
static void FreeHGlobal(void* ptr);
#if _DEBUG
static void PushAllocationFrame();
static void PopAllocationFrame();
static bool HasUnfreedAllocations();
static void ClearAllTrackedAllocations();
#endif
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,118 @@
#pragma once
#include "il2cpp-config.h"
struct Il2CppMetadataField
{
uint32_t offset;
uint32_t typeIndex;
const char* name;
bool isStatic;
};
enum Il2CppMetadataTypeFlags
{
kNone = 0,
kValueType = 1 << 0,
kArray = 1 << 1,
kArrayRankMask = 0xFFFF0000
};
struct Il2CppMetadataType
{
Il2CppMetadataTypeFlags flags; // If it's an array, rank is encoded in the upper 2 bytes
Il2CppMetadataField* fields;
uint32_t fieldCount;
uint32_t staticsSize;
uint8_t* statics;
uint32_t baseOrElementTypeIndex;
char* name;
const char* assemblyName;
uint64_t typeInfoAddress;
uint32_t size;
};
struct Il2CppMetadataSnapshot
{
uint32_t typeCount;
Il2CppMetadataType* types;
};
struct Il2CppManagedMemorySection
{
uint64_t sectionStartAddress;
uint32_t sectionSize;
uint8_t* sectionBytes;
};
struct Il2CppManagedHeap
{
uint32_t sectionCount;
Il2CppManagedMemorySection* sections;
};
struct Il2CppStacks
{
uint32_t stackCount;
Il2CppManagedMemorySection* stacks;
};
struct NativeObject
{
uint32_t gcHandleIndex;
uint32_t size;
uint32_t instanceId;
uint32_t classId;
uint32_t referencedNativeObjectIndicesCount;
uint32_t* referencedNativeObjectIndices;
};
struct Il2CppGCHandles
{
uint32_t trackedObjectCount;
uint64_t* pointersToObjects;
};
struct Il2CppRuntimeInformation
{
uint32_t pointerSize;
uint32_t objectHeaderSize;
uint32_t arrayHeaderSize;
uint32_t arrayBoundsOffsetInHeader;
uint32_t arraySizeOffsetInHeader;
uint32_t allocationGranularity;
};
struct Il2CppManagedMemorySnapshot
{
Il2CppManagedHeap heap;
Il2CppStacks stacks;
Il2CppMetadataSnapshot metadata;
Il2CppGCHandles gcHandles;
Il2CppRuntimeInformation runtimeInformation;
void* additionalUserInformation;
};
namespace il2cpp
{
namespace vm
{
namespace MemoryInformation
{
typedef void(*ClassReportFunc)(Il2CppClass* klass, void* context);
typedef void(*DataReportFunc)(void* data, void* context);
struct IterationContext
{
DataReportFunc callback;
void* userData;
};
void ReportIL2CppClasses(ClassReportFunc callback, void* context);
void ReportGcHeapSection(void* context, void* start, void* end);
void ReportGcHandleTarget(Il2CppObject* obj, void* context);
Il2CppManagedMemorySnapshot* CaptureManagedMemorySnapshot();
void FreeCapturedManagedMemorySnapshot(Il2CppManagedMemorySnapshot* snapshot);
}
}
}

View File

@@ -0,0 +1,20 @@
#pragma once
#include "il2cpp-config.h"
struct Il2CppGenericClass;
struct Il2CppGenericMethod;
namespace il2cpp
{
namespace vm
{
void MetadataAllocInitialize();
void MetadataAllocCleanup();
// These allocators assume the g_MetadataLock lock is held
void* MetadataMalloc(size_t size);
void* MetadataCalloc(size_t count, size_t size);
// These metadata structures have their own locks, since they do lightweight initialization
Il2CppGenericClass* MetadataAllocGenericClass();
Il2CppGenericMethod* MetadataAllocGenericMethod();
} // namespace vm
} // namespace il2cpp

View File

@@ -0,0 +1,194 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
#include "Assembly.h"
#include "il2cpp-class-internals.h"
#include "utils/dynamic_array.h"
#include "utils/HashUtils.h"
#include "utils/Il2CppHashMap.h"
#include "utils/StringUtils.h"
#include "metadata/Il2CppGenericContextCompare.h"
#include "metadata/Il2CppGenericContextHash.h"
#include "metadata/Il2CppGenericInstCompare.h"
#include "metadata/Il2CppGenericInstHash.h"
#include "metadata/Il2CppGenericMethodCompare.h"
#include "metadata/Il2CppGenericMethodHash.h"
#include "metadata/Il2CppSignature.h"
#include "metadata/Il2CppTypeCompare.h"
#include "metadata/Il2CppTypeHash.h"
#include "vm-utils/VmStringUtils.h"
#include "os/Mutex.h"
namespace il2cpp
{
namespace vm
{
struct RGCTXCollection
{
int32_t count;
const Il2CppRGCTXDefinition* items;
};
typedef struct Il2CppGenericMethodPointers
{
Il2CppMethodPointer methodPointer;
Il2CppMethodPointer virtualMethodPointer;
InvokerMethod invoker_method;
bool isFullGenericShared;
} Il2CppGenericMethodPointers;
enum GenericParameterRestriction
{
GenericParameterRestrictionNone,
GenericParameterRestrictionValueType,
GenericParameterRestrictionReferenceType,
};
typedef Il2CppHashMap<const char*, Il2CppClass*, il2cpp::utils::StringUtils::StringHasher<const char*>, il2cpp::utils::VmStringUtils::CaseSensitiveComparer> WindowsRuntimeTypeNameToClassMap;
typedef Il2CppHashMap<const Il2CppClass*, const char*, il2cpp::utils::PointerHash<Il2CppClass> > ClassToWindowsRuntimeTypeNameMap;
typedef Il2CppHashMap<il2cpp::metadata::Il2CppSignature, Il2CppMethodPointer, il2cpp::metadata::Il2CppSignatureHash, il2cpp::metadata::Il2CppSignatureCompare> Il2CppUnresolvedSignatureMap;
typedef Il2CppHashMap<const Il2CppGenericMethod*, const Il2CppGenericMethodIndices*, il2cpp::metadata::Il2CppGenericMethodHash, il2cpp::metadata::Il2CppGenericMethodCompare> Il2CppMethodTableMap;
class LIBIL2CPP_CODEGEN_API MetadataCache
{
public:
static void Register(const Il2CppCodeRegistration * const codeRegistration, const Il2CppMetadataRegistration * const metadataRegistration, const Il2CppCodeGenOptions* const codeGenOptions);
static bool Initialize();
static void InitializeGCSafe();
static void Clear();
static void ExecuteEagerStaticClassConstructors();
static void ExecuteModuleInitializers();
static Il2CppClass* GetGenericInstanceType(Il2CppClass* genericTypeDefinition, const Il2CppType** genericArgumentTypes, uint32_t genericArgumentCount);
static const MethodInfo* GetGenericInstanceMethod(const MethodInfo* genericMethodDefinition, const Il2CppType** genericArgumentTypes, uint32_t genericArgumentCount);
static const Il2CppGenericContext* GetMethodGenericContext(const MethodInfo* method);
static const MethodInfo* GetGenericMethodDefinition(const MethodInfo* method);
static Il2CppClass* GetPointerType(Il2CppClass* type);
static Il2CppClass* GetWindowsRuntimeClass(const char* fullName);
static const char* GetWindowsRuntimeClassName(const Il2CppClass* klass);
static Il2CppMethodPointer GetWindowsRuntimeFactoryCreationFunction(const char* fullName);
static Il2CppClass* GetClassForGuid(const Il2CppGuid* guid);
static void AddPointerTypeLocked(Il2CppClass* type, Il2CppClass* pointerType, const il2cpp::os::FastAutoLock& lock);
static const Il2CppGenericInst* GetGenericInst(const Il2CppType* const* types, uint32_t typeCount);
static const Il2CppGenericMethod* GetGenericMethod(const MethodInfo* methodDefinition, const Il2CppGenericInst* classInst, const Il2CppGenericInst* methodInst);
static GenericParameterRestriction IsReferenceTypeGenericParameter(Il2CppMetadataGenericParameterHandle genericParameter);
static Il2CppGenericMethodPointers GetGenericMethodPointers(const MethodInfo* methodDefinition, const Il2CppGenericContext* context);
static const MethodInfo* GetMethodInfoFromVTableSlot(const Il2CppClass* klass, int32_t vTableSlot);
static const Il2CppType* GetTypeFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef);
static const Il2CppGenericMethod* GetGenericMethodFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef);
static std::pair<const Il2CppType*, const MethodInfo*> GetConstrainedCallFromRgctxDefinition(const Il2CppRGCTXDefinition* rgctxDef);
static void InitializeAllMethodMetadata();
static void* InitializeRuntimeMetadata(uintptr_t* metadataPointer);
static Il2CppMethodPointer GetAdjustorThunk(const Il2CppImage* image, uint32_t token);
static Il2CppMethodPointer GetMethodPointer(const Il2CppImage* image, uint32_t token);
static InvokerMethod GetMethodInvoker(const Il2CppImage* image, uint32_t token);
static const Il2CppInteropData* GetInteropDataForType(const Il2CppType* type);
static Il2CppMethodPointer GetReversePInvokeWrapper(const Il2CppImage* image, const MethodInfo* method);
static Il2CppMethodPointer GetUnresolvedVirtualCallStub(const MethodInfo* method);
static const Il2CppAssembly* GetAssemblyByName(const char* nameToFind);
static Il2CppClass* GetTypeInfoFromType(const Il2CppType* type);
static Il2CppMetadataGenericContainerHandle GetGenericContainerFromGenericClass(const Il2CppImage* image, const Il2CppGenericClass* genericClass);
static Il2CppMetadataGenericContainerHandle GetGenericContainerFromMethod(Il2CppMetadataMethodDefinitionHandle handle);
static Il2CppMetadataGenericParameterHandle GetGenericParameterFromType(const Il2CppType* type);
static Il2CppMetadataGenericParameterHandle GetGenericParameterFromIndex(Il2CppMetadataGenericContainerHandle handle, GenericContainerParameterIndex index);
static Il2CppClass* GetContainerDeclaringType(Il2CppMetadataGenericContainerHandle handle);
static Il2CppClass* GetParameterDeclaringType(Il2CppMetadataGenericParameterHandle handle);
static const Il2CppType* GetGenericParameterConstraintFromIndex(Il2CppMetadataGenericParameterHandle handle, GenericParameterConstraintIndex index);
static Il2CppClass* GetNestedTypeFromOffset(const Il2CppClass* klass, TypeNestedTypeIndex offset);
static const Il2CppType* GetInterfaceFromOffset(const Il2CppClass* klass, TypeInterfaceIndex index);
static Il2CppInterfaceOffsetInfo GetInterfaceOffsetInfo(const Il2CppClass* klass, TypeInterfaceOffsetIndex index);
static RGCTXCollection GetRGCTXs(const Il2CppImage* image, uint32_t token);
static const uint8_t* GetFieldDefaultValue(const FieldInfo* field, const Il2CppType** type);
static const uint8_t* GetParameterDefaultValue(const MethodInfo* method, int32_t parameterPosition, const Il2CppType** type, bool* isExplicitySetNullDefaultValue);
static int GetFieldMarshaledSizeForField(const FieldInfo* field);
static const MethodInfo* GetMethodInfoFromMethodHandle(Il2CppMetadataMethodDefinitionHandle handle);
// returns the compiler computed field offset for type definition fields
static int32_t GetFieldOffsetFromIndexLocked(const Il2CppClass* klass, int32_t fieldIndexInType, FieldInfo* field, const il2cpp::os::FastAutoLock& lock);
static int32_t GetThreadLocalStaticOffsetForField(FieldInfo* field);
static void AddThreadLocalStaticOffsetForFieldLocked(FieldInfo* field, int32_t offset, const il2cpp::os::FastAutoLock& lock);
static const Il2CppAssembly* GetReferencedAssembly(const Il2CppAssembly* assembly, int32_t referencedAssemblyTableIndex);
static Il2CppMetadataCustomAttributeHandle GetCustomAttributeTypeToken(const Il2CppImage* image, uint32_t token);
static std::tuple<void*, void*> GetCustomAttributeDataRange(const Il2CppImage* image, uint32_t token);
static CustomAttributesCache* GenerateCustomAttributesCache(Il2CppMetadataCustomAttributeHandle token);
static CustomAttributesCache* GenerateCustomAttributesCache(const Il2CppImage* image, uint32_t token);
static bool HasAttribute(Il2CppMetadataCustomAttributeHandle token, Il2CppClass* attribute);
static bool HasAttribute(const Il2CppImage* image, uint32_t token, Il2CppClass* attribute);
typedef void(*WalkTypesCallback)(Il2CppClass* type, void* context);
static void WalkPointerTypes(WalkTypesCallback callback, void* context);
static Il2CppMetadataTypeHandle GetTypeHandleFromType(const Il2CppType* type);
static bool TypeIsNested(Il2CppMetadataTypeHandle handle);
static bool TypeIsValueType(Il2CppMetadataTypeHandle handle);
static bool StructLayoutPackIsDefault(Il2CppMetadataTypeHandle handle);
static int32_t StructLayoutPack(Il2CppMetadataTypeHandle handle);
static bool StructLayoutSizeIsDefault(Il2CppMetadataTypeHandle handle);
static std::pair<const char*, const char*> GetTypeNamespaceAndName(Il2CppMetadataTypeHandle handle);
static Il2CppMetadataTypeHandle GetNestedTypes(Il2CppClass* klass, void** iter);
static Il2CppMetadataTypeHandle GetNestedTypes(Il2CppMetadataTypeHandle handle, void** iter);
static Il2CppMetadataFieldInfo GetFieldInfo(const Il2CppClass* klass, TypeFieldIndex index);
static Il2CppMetadataMethodInfo GetMethodInfo(const Il2CppClass* klass, TypeMethodIndex index);
static Il2CppMetadataParameterInfo GetParameterInfo(const Il2CppClass* klass, Il2CppMetadataMethodDefinitionHandle handle, MethodParameterIndex index);
static Il2CppMetadataPropertyInfo GetPropertyInfo(const Il2CppClass* klass, TypePropertyIndex index);
static Il2CppMetadataEventInfo GetEventInfo(const Il2CppClass* klass, TypeEventIndex index);
static void MakeGenericArgType(Il2CppMetadataGenericContainerHandle containerHandle, Il2CppMetadataGenericParameterHandle paramHandle, Il2CppType* arg);
static uint32_t GetGenericContainerCount(Il2CppMetadataGenericContainerHandle handle);
static bool GetGenericContainerIsMethod(Il2CppMetadataGenericContainerHandle handle);
static const char* GetGenericParameterName(Il2CppMetadataGenericParameterHandle handle);
static Il2CppGenericParameterInfo GetGenericParameterInfo(Il2CppMetadataGenericParameterHandle handle);
static uint16_t GetGenericParameterFlags(Il2CppMetadataGenericParameterHandle handle);
static int16_t GetGenericConstraintCount(Il2CppMetadataGenericParameterHandle handle);
static Il2CppClass* GetTypeInfoFromHandle(Il2CppMetadataTypeHandle handle);
static const MethodInfo* GetAssemblyEntryPoint(const Il2CppImage* image);
static Il2CppMetadataTypeHandle GetAssemblyTypeHandle(const Il2CppImage* image, AssemblyTypeIndex index);
static Il2CppMetadataTypeHandle GetAssemblyExportedTypeHandle(const Il2CppImage* image, AssemblyExportedTypeIndex index);
static const MethodInfo* GetMethodInfoFromCatchPoint(const Il2CppImage* image, const Il2CppCatchPoint* cp);
static const MethodInfo* GetMethodInfoFromSequencePoint(const Il2CppImage* image, const Il2CppSequencePoint* cp);
static Il2CppClass* GetTypeInfoFromTypeSourcePair(const Il2CppImage* image, const Il2CppTypeSourceFilePair* pair);
// The following methods still expose indexes - but only need to be public for debugger support (in il2cpp-mono-api.cpp & mono/mini/debugger-agent.c)
// Called from il2cpp_get_type_from_index
static const Il2CppType* GetIl2CppTypeFromIndex(const Il2CppImage* image, TypeIndex index);
// Called from il2cpp_get_class_from_index
static Il2CppClass* GetTypeInfoFromTypeIndex(const Il2CppImage* image, TypeIndex index);
static const MethodInfo* GetMethodInfoFromMethodDefinitionIndex(const Il2CppImage* image, MethodIndex index);
private:
static void InitializeUnresolvedSignatureTable();
static void InitializeGenericMethodTable();
static void InitializeGuidToClassTable();
static Il2CppImage* GetImageFromIndex(ImageIndex index);
static const Il2CppAssembly* GetAssemblyFromIndex(AssemblyIndex index);
static Il2CppMetadataTypeHandle GetTypeHandleFromIndex(const Il2CppImage* image, TypeDefinitionIndex typeIndex);
};
} // namespace vm
} // namespace il2cpp

View File

@@ -0,0 +1,15 @@
#pragma once
#include "il2cpp-config.h"
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API MetadataLoader
{
public:
static void* LoadMetadataFile(const char* fileName);
static void UnloadMetadataFile(void* fileBuffer);
};
} // namespace vm
} // namespace il2cpp

View File

@@ -0,0 +1,13 @@
#pragma once
#include "il2cpp-config.h"
#include "Baselib.h"
#include "Cpp/ReentrantLock.h"
namespace il2cpp
{
namespace vm
{
extern baselib::ReentrantLock g_MetadataLock;
} // namespace vm
} // namespace il2cpp

View File

@@ -0,0 +1,55 @@
#pragma once
#include <stdint.h>
#include <string>
#include "il2cpp-config.h"
struct MethodInfo;
struct PropertyInfo;
struct ParameterInfo;
struct Il2CppString;
struct Il2CppType;
struct Il2CppClass;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Method
{
public:
static const Il2CppType* GetReturnType(const MethodInfo* method);
static const char* GetName(const MethodInfo *method);
static std::string GetNameWithGenericTypes(const MethodInfo* method);
static std::string GetFullName(const MethodInfo* method);
static bool IsGeneric(const MethodInfo *method);
static bool IsInflated(const MethodInfo *method);
static bool IsInstance(const MethodInfo *method);
static bool IsGenericInstance(const MethodInfo *method);
static bool IsGenericInstanceMethod(const MethodInfo *method);
static bool IsDefaultInterfaceMethodOnGenericInstance(const MethodInfo* method);
static uint32_t GetParamCount(const MethodInfo *method);
static uint32_t GetGenericParamCount(const MethodInfo *method);
static const Il2CppType* GetParam(const MethodInfo *method, uint32_t index);
static Il2CppClass* GetClass(const MethodInfo *method);
static bool HasAttribute(const MethodInfo *method, Il2CppClass *attr_class);
static Il2CppClass *GetDeclaringType(const MethodInfo* method);
static uint32_t GetImplementationFlags(const MethodInfo *method);
static uint32_t GetFlags(const MethodInfo *method);
static uint32_t GetToken(const MethodInfo *method);
static const char* GetParamName(const MethodInfo *method, uint32_t index);
static bool IsSameOverloadSignature(const MethodInfo* method1, const MethodInfo* method2);
static bool IsSameOverloadSignature(const PropertyInfo* property1, const PropertyInfo* property2);
static int CompareOverloadSignature(const PropertyInfo* property1, const PropertyInfo* property2);
static const char* GetParameterDefaultValue(const MethodInfo *method, int32_t parameterPosition, const Il2CppType** type, bool* isExplicitySetNullDefaultValue);
static uint32_t GetParameterToken(const MethodInfo* method, int32_t parameterPosition);
static const MethodInfo* GetAmbiguousMethodInfo();
static const MethodInfo* GetEntryPointNotFoundMethodInfo();
static bool IsAmbiguousMethodInfo(const MethodInfo* method);
static bool IsEntryPointNotFoundMethodInfo(const MethodInfo* method);
static bool HasFullGenericSharingSignature(const MethodInfo* method);
static Il2CppMethodPointer GetVirtualCallMethodPointer(const MethodInfo* method);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,19 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
struct Il2CppImage;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Module
{
public:
// exported
static uint32_t GetToken(const Il2CppImage *image);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,84 @@
#pragma once
#include "il2cpp-config.h"
struct Il2CppObject;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Monitor
{
public:
static void Enter(Il2CppObject* object);
static bool TryEnter(Il2CppObject* object, uint32_t timeout);
static void Exit(Il2CppObject* object);
static void Pulse(Il2CppObject* object);
static void PulseAll(Il2CppObject* object);
static void Wait(Il2CppObject* object);
static bool TryWait(Il2CppObject* object, uint32_t timeout);
static bool IsAcquired(Il2CppObject* object);
static bool IsOwnedByCurrentThread(Il2CppObject* object);
};
#if !IL2CPP_SUPPORT_THREADS
inline void Monitor::Enter(Il2CppObject* object)
{
}
inline bool Monitor::TryEnter(Il2CppObject* object, uint32_t timeout)
{
return true;
}
inline void Monitor::Exit(Il2CppObject* object)
{
}
inline void Monitor::Pulse(Il2CppObject* object)
{
}
inline void Monitor::PulseAll(Il2CppObject* object)
{
}
inline void Monitor::Wait(Il2CppObject* object)
{
}
inline bool Monitor::TryWait(Il2CppObject* object, uint32_t timeout)
{
return true;
}
inline bool Monitor::IsAcquired(Il2CppObject* object)
{
return true;
}
inline bool Monitor::IsOwnedByCurrentThread(Il2CppObject* object)
{
return true;
}
#endif
struct MonitorHolder
{
MonitorHolder(Il2CppObject* obj) :
m_Object(obj)
{
Monitor::Enter(obj);
}
~MonitorHolder()
{
Monitor::Exit(m_Object);
}
private:
Il2CppObject* m_Object;
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,72 @@
#pragma once
#include "gc/GCHandle.h"
#include "vm/CCWBase.h"
#include "vm/Exception.h"
#include "utils/TemplateUtils.h"
#include "utils/Memory.h"
#include "Baselib.h"
#include "Cpp/Atomic.h"
namespace il2cpp
{
namespace vm
{
template<typename TDerived>
struct NOVTABLE NonCachedCCWBase : CCWBase
{
private:
baselib::atomic<uint32_t> m_RefCount;
uint32_t m_GCHandle;
public:
inline NonCachedCCWBase(Il2CppObject* obj) :
CCWBase(obj),
m_RefCount(1) // We start with a ref count of 1
{
m_GCHandle = gc::GCHandle::New(GetManagedObjectInline(), false);
IL2CPP_ASSERT(m_GCHandle != 0);
Il2CppStaticAssert(utils::TemplateUtils::IsBaseOf<NonCachedCCWBase<TDerived>, TDerived>::value);
}
inline ~NonCachedCCWBase()
{
IL2CPP_ASSERT(m_GCHandle != 0);
gc::GCHandle::Free(m_GCHandle);
m_GCHandle = 0;
}
IL2CPP_FORCE_INLINE uint32_t AddRefImpl()
{
return ++m_RefCount;
}
IL2CPP_FORCE_INLINE uint32_t ReleaseImpl()
{
const uint32_t count = --m_RefCount;
if (count == 0)
Destroy();
return count;
}
IL2CPP_FORCE_INLINE static TDerived* __CreateInstance(Il2CppObject* obj)
{
void* memory = utils::Memory::Malloc(sizeof(TDerived));
if (memory == NULL)
Exception::RaiseOutOfMemoryException();
return new(memory) TDerived(obj);
}
virtual void STDCALL Destroy() IL2CPP_FINAL IL2CPP_OVERRIDE
{
IL2CPP_ASSERT(m_RefCount == 0);
TDerived* instance = static_cast<TDerived*>(this);
instance->~TDerived();
utils::Memory::Free(instance);
}
};
}
}

View File

@@ -0,0 +1,48 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
struct Il2CppString;
struct Il2CppObject;
struct Il2CppClass;
struct MethodInfo;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Object
{
public:
static Il2CppObject* Box(Il2CppClass *klass, void* data);
static Il2CppClass* GetClass(Il2CppObject* obj);
static int32_t GetHash(Il2CppObject* obj);
static uint32_t GetSize(Il2CppObject* obj);
static const MethodInfo* GetVirtualMethod(Il2CppObject *obj, const MethodInfo *virtualMethod);
static Il2CppObject * IsInst(Il2CppObject *obj, Il2CppClass *klass);
static Il2CppObject* New(Il2CppClass *klass);
static void* Unbox(Il2CppObject* obj);
static void UnboxNullable(Il2CppObject* obj, Il2CppClass* nullableArgumentClass, void* storage);
static void UnboxNullableWithWriteBarrier(Il2CppObject* obj, Il2CppClass* nullableArgumentClass, void* storage);
static Il2CppObject * Clone(Il2CppObject *obj);
static Il2CppObject* NewPinned(Il2CppClass *klass);
static void NullableInit(uint8_t* buf, Il2CppObject* value, Il2CppClass* klass);
static bool NullableHasValue(Il2CppClass* klass, void* data);
private:
static Il2CppObject * NewAllocSpecific(Il2CppClass *klass);
static Il2CppObject* NewPtrFree(Il2CppClass *klass);
static Il2CppObject* Allocate(size_t size, Il2CppClass *typeInfo);
static Il2CppObject* AllocatePtrFree(size_t size, Il2CppClass *typeInfo);
static Il2CppObject* AllocateSpec(size_t size, Il2CppClass *typeInfo);
// Yo! Don't call this function! See the comments in the implementation if you do.
static uint32_t UnboxNullableGCUnsafe(Il2CppObject* obj, Il2CppClass* nullableArgumentClass, void* storage);
friend class Array;
friend class RCW;
friend class String;
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,18 @@
#pragma once
#include "il2cpp-config.h"
struct ParameterInfo;
struct Il2CppObject;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Parameter
{
public:
// internal
static Il2CppObject* GetDefaultParameterValueObject(const MethodInfo* method, int32_t parameterPosition, bool* isExplicitySetNullDefaultValue);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,19 @@
#pragma once
#include "il2cpp-config.h"
#include <string>
#undef GetTempPath // Get rid of windows.h #define.
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Path
{
public:
static void SetTempPath(const char* path);
static std::string GetTempPath();
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,77 @@
#pragma once
#include "il2cpp-config.h"
#include "il2cpp-blob.h"
#include "il2cpp-runtime-metadata.h"
#include "il2cpp-object-internals.h"
#include "vm/Array.h"
#include "vm/Class.h"
#include "vm/MarshalAlloc.h"
#include "vm/Object.h"
#include "vm/String.h"
#include "utils/StringView.h"
#include <vector>
#include <string>
struct Il2CppString;
struct Il2CppStringBuilder;
struct PInvokeArguments;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API PlatformInvoke
{
public:
static void SetFindPluginCallback(Il2CppSetFindPlugInCallback method);
static Il2CppMethodPointer Resolve(const PInvokeArguments& pinvokeArgs);
static void MarshalFree(void* ptr);
static char* MarshalCSharpStringToCppString(Il2CppString* managedString);
static void MarshalCSharpStringToCppStringFixed(Il2CppString* managedString, char* buffer, int numberOfCharacters);
static Il2CppChar* MarshalCSharpStringToCppWString(Il2CppString* managedString);
static void MarshalCSharpStringToCppWStringFixed(Il2CppString* managedString, Il2CppChar* buffer, int numberOfCharacters);
static il2cpp_hresult_t MarshalCSharpStringToCppBStringNoThrow(Il2CppString* managedString, Il2CppChar** bstr);
static Il2CppChar* MarshalCSharpStringToCppBString(Il2CppString* managedString);
static Il2CppString* MarshalCppStringToCSharpStringResult(const char* value);
static Il2CppString* MarshalCppWStringToCSharpStringResult(const Il2CppChar* value);
static Il2CppString* MarshalCppBStringToCSharpStringResult(const Il2CppChar* value);
static void MarshalFreeBString(Il2CppChar* value);
static char* MarshalEmptyStringBuilder(Il2CppStringBuilder* stringBuilder);
static Il2CppChar* MarshalEmptyWStringBuilder(Il2CppStringBuilder* stringBuilder);
static char* MarshalStringBuilder(Il2CppStringBuilder* stringBuilder);
static Il2CppChar* MarshalWStringBuilder(Il2CppStringBuilder* stringBuilder);
static void MarshalStringBuilderResult(Il2CppStringBuilder* stringBuilder, char* buffer);
static void MarshalWStringBuilderResult(Il2CppStringBuilder* stringBuilder, Il2CppChar* buffer);
#if !IL2CPP_TINY
static intptr_t MarshalDelegate(Il2CppDelegate* d);
static Il2CppDelegate* MarshalFunctionPointerToDelegate(void* functionPtr, Il2CppClass* delegateType);
static bool IsFakeDelegateMethodMarshaledFromNativeCode(const Il2CppDelegate* d);
#else
static intptr_t MarshalDelegate(Il2CppDelegate* d) { IL2CPP_ASSERT(false && "This should not be called on tiny"); return 0; }
static Il2CppDelegate* MarshalFunctionPointerToDelegate(void* functionPtr, Il2CppClass* delegateType) { IL2CPP_ASSERT(false && "This should not be called on tiny"); return NULL; }
static bool IsFakeDelegateMethodMarshaledFromNativeCode(const Il2CppDelegate* d) { IL2CPP_ASSERT(false && "This should not be called on tiny"); return NULL; }
#endif
template<typename T>
static T* MarshalAllocateStringBuffer(size_t numberOfCharacters)
{
return (T*)MarshalAlloc::Allocate(numberOfCharacters * sizeof(T));
}
private:
static char* MarshalEmptyStringBuilder(Il2CppStringBuilder* stringBuilder, size_t& stringLength, std::vector<std::string>& utf8Chunks, std::vector<Il2CppStringBuilder*>& builders);
static Il2CppChar* MarshalEmptyWStringBuilder(Il2CppStringBuilder* stringBuilder, size_t& stringLength);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,55 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
namespace il2cpp
{
namespace vm
{
#if IL2CPP_ENABLE_PROFILER
class LIBIL2CPP_CODEGEN_API Profiler
{
// exported
public:
static void Install(Il2CppProfiler *prof, Il2CppProfileFunc shutdownCallback);
static void SetEvents(Il2CppProfileFlags events);
static void InstallEnterLeave(Il2CppProfileMethodFunc enter, Il2CppProfileMethodFunc fleave);
static void InstallAllocation(Il2CppProfileAllocFunc callback);
static void InstallGC(Il2CppProfileGCFunc callback, Il2CppProfileGCResizeFunc heap_resize_callback);
static void InstallFileIO(Il2CppProfileFileIOFunc callback);
static void InstallThread(Il2CppProfileThreadFunc start, Il2CppProfileThreadFunc end);
// internal
public:
static void Allocation(Il2CppObject *obj, Il2CppClass *klass);
static void MethodEnter(const MethodInfo *method);
static void MethodExit(const MethodInfo *method);
static void GCEvent(Il2CppGCEvent eventType);
static void GCHeapResize(int64_t newSize);
static void FileIO(Il2CppProfileFileIOKind kind, int count);
static void ThreadStart(unsigned long tid);
static void ThreadEnd(unsigned long tid);
static Il2CppProfileFlags s_profilerEvents;
static inline bool ProfileAllocations()
{
return (s_profilerEvents & IL2CPP_PROFILE_ALLOCATIONS) != 0;
}
static inline bool ProfileFileIO()
{
return (s_profilerEvents & IL2CPP_PROFILE_FILEIO) != 0;
}
static void Shutdown();
private:
};
#endif
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,26 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
struct MethodInfo;
struct PropertyInfo;
struct Il2CppClass;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Property
{
public:
// exported
static uint32_t GetFlags(const PropertyInfo* prop);
static const MethodInfo* GetGetMethod(const PropertyInfo* prop);
static const MethodInfo* GetSetMethod(const PropertyInfo* prop);
static const char* GetName(const PropertyInfo* prop);
static Il2CppClass* GetParent(const PropertyInfo* prop);
static uint32_t GetToken(const PropertyInfo* prop);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,60 @@
#pragma once
#include "il2cpp-config.h"
#include "il2cpp-object-internals.h"
struct Il2CppComObject;
struct Il2CppGuid;
struct Il2CppIUnknown;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API RCW
{
public:
static void Register(Il2CppComObject* rcw);
static Il2CppObject* GetOrCreateFromIUnknown(Il2CppIUnknown* unknown, Il2CppClass* fallbackClass);
static Il2CppObject* GetOrCreateFromIInspectable(Il2CppIInspectable* inspectable, Il2CppClass* fallbackClass);
static Il2CppObject* GetOrCreateForSealedClass(Il2CppIUnknown* unknown, Il2CppClass* objectClass);
static void Cleanup(Il2CppComObject* rcw);
static bool CacheQueriedInterface(Il2CppComObject* rcw, const Il2CppGuid& iid, Il2CppIUnknown* queriedInterface);
static const VirtualInvokeData* GetComInterfaceInvokeData(Il2CppComObject* rcw, const Il2CppClass* targetInterface, Il2CppMethodSlot slot);
template<bool throwOnError>
inline static Il2CppIUnknown* QueryInterfaceNoAddRef(Il2CppComObject* rcw, const Il2CppGuid& iid)
{
IL2CPP_ASSERT(rcw);
IL2CPP_ASSERT(rcw->identity);
Il2CppIUnknown* result = QueryInterfaceCached(rcw, iid);
if (result != NULL)
return result;
const il2cpp_hresult_t hr = rcw->identity->QueryInterface(iid, reinterpret_cast<void**>(&result));
if (IL2CPP_HR_FAILED(hr))
{
if (throwOnError)
Exception::Raise(hr, true);
return NULL;
}
IL2CPP_ASSERT(result);
if (!CacheQueriedInterface(rcw, iid, result))
{
// We lost the race - another thread won it.
result->Release();
return QueryInterfaceCached(rcw, iid);
}
return result;
}
private:
static Il2CppIUnknown* QueryInterfaceCached(Il2CppComObject* rcw, const Il2CppGuid& iid);
static const VirtualInvokeData* GetComInterfaceInvokeData(Il2CppClass* queriedInterface, const Il2CppClass* targetInterface, Il2CppMethodSlot slot);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,19 @@
#pragma once
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Random
{
public:
static bool Open();
static void* Create();
static void Free(void* handle);
static bool TryGetBytes(void** handle, unsigned char *buffer, int buffer_size);
static bool TryGetUnsignedInt32(void** handle, uint32_t *val, uint32_t min, uint32_t max);
static uint32_t Next(void** handle, uint32_t min, uint32_t max);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,104 @@
#pragma once
#include <vector>
#include <stdint.h>
#include "il2cpp-config.h"
#include "il2cpp-metadata.h"
#include "metadata/CustomAttributeDataReader.h"
struct Il2CppString;
struct Il2CppArray;
struct Il2CppReflectionAssembly;
struct Il2CppReflectionAssemblyName;
struct Il2CppReflectionField;
struct Il2CppReflectionMethod;
struct Il2CppReflectionModule;
struct Il2CppReflectionProperty;
struct Il2CppReflectionEvent;
struct Il2CppReflectionType;
struct Il2CppReflectionParameter;
struct Il2CppClass;
struct FieldInfo;
struct MethodInfo;
struct PropertyInfo;
struct EventInfo;
struct Il2CppClass;
struct CustomAttributesCache;
struct CustomAttributeTypeCache;
struct Il2CppAssembly;
struct Il2CppAssemblyName;
struct Il2CppImage;
struct Il2CppType;
struct Il2CppObject;
struct MonoGenericParameterInfo;
struct Il2CppMonoAssemblyName;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Reflection
{
// exported
public:
static Il2CppReflectionAssembly* GetAssemblyObject(const Il2CppAssembly *assembly);
static Il2CppReflectionAssemblyName* GetAssemblyNameObject(const Il2CppAssemblyName *assemblyName);
static Il2CppReflectionField* GetFieldObject(Il2CppClass *klass, FieldInfo *field);
static Il2CppReflectionProperty* GetPropertyObject(Il2CppClass *klass, const PropertyInfo *property);
static Il2CppReflectionEvent* GetEventObject(Il2CppClass *klass, const EventInfo *event);
static Il2CppReflectionMethod* GetMethodObject(const MethodInfo *method, Il2CppClass *refclass);
static const MethodInfo* GetMethod(const Il2CppReflectionMethod* method);
static Il2CppReflectionModule* GetModuleObject(const Il2CppImage *image);
static Il2CppReflectionType* GetTypeObject(const Il2CppType *type);
static Il2CppArray* GetParamObjects(const MethodInfo *method, Il2CppClass *refclass);
static CustomAttributesCache* GetCustomAttrsInfo(Il2CppObject *obj);
static metadata::CustomAttributeDataReader GetCustomAttrsDataReader(Il2CppObject *obj);
static const MonoGenericParameterInfo* GetMonoGenericParameterInfo(Il2CppMetadataGenericParameterHandle param);
static void SetMonoGenericParameterInfo(Il2CppMetadataGenericParameterHandle param, const MonoGenericParameterInfo *monoParam);
static const Il2CppMonoAssemblyName* GetMonoAssemblyName(const Il2CppAssembly *assembly);
static void SetMonoAssemblyName(const Il2CppAssembly *assembly, const Il2CppMonoAssemblyName *aname);
static int GetMetadataToken(Il2CppObject* obj);
static bool HasAttribute(Il2CppObject *obj, Il2CppClass *attribute);
static bool HasAttribute(FieldInfo *field, Il2CppClass *attribute);
static bool HasAttribute(const MethodInfo *method, Il2CppClass *attribute);
static bool HasAttribute(Il2CppClass *klass, Il2CppClass *attribute);
static bool IsType(Il2CppObject *obj);
static bool IsField(Il2CppObject *obj);
static bool IsAnyMethod(Il2CppObject *obj);
static bool IsProperty(Il2CppObject *obj);
static bool IsEvent(Il2CppObject *obj);
static void ClearStatics();
// internal
public:
static void Initialize();
static Il2CppClass* TypeGetHandle(Il2CppReflectionType* ref);
static Il2CppObject* GetDBNullObject();
static Il2CppObject* GetCustomAttribute(Il2CppMetadataCustomAttributeHandle token, Il2CppClass* attribute);
static Il2CppArray* ConstructCustomAttributes(Il2CppMetadataCustomAttributeHandle token);
static CustomAttributesCache* GetCustomAttributesCacheFor(Il2CppClass *klass);
static CustomAttributesCache* GetCustomAttributesCacheFor(const MethodInfo *method);
private:
static bool HasAttribute(Il2CppReflectionParameter *parameter, Il2CppClass* attribute);
static CustomAttributesCache* GetCustomAttributesCacheFor(const PropertyInfo *property);
static CustomAttributesCache* GetCustomAttributesCacheFor(FieldInfo *field);
static CustomAttributesCache* GetCustomAttributesCacheFor(const EventInfo *event);
static CustomAttributesCache* GetCustomAttributesCacheFor(Il2CppReflectionParameter *param);
static CustomAttributesCache* GetCustomAttributesCacheFor(const Il2CppAssembly *assembly);
static std::tuple<void*, void*> GetCustomAttributesDataRangeFor(Il2CppClass *klass);
static std::tuple<void*, void*> GetCustomAttributesDataRangeFor(const MethodInfo *method);
static std::tuple<void*, void*> GetCustomAttributesDataRangeFor(const PropertyInfo *property);
static std::tuple<void*, void*> GetCustomAttributesDataRangeFor(FieldInfo *field);
static std::tuple<void*, void*> GetCustomAttributesDataRangeFor(const EventInfo *event);
static std::tuple<void*, void*> GetCustomAttributesDataRangeFor(Il2CppReflectionParameter *param);
static std::tuple<void*, void*> GetCustomAttributesDataRangeFor(const Il2CppAssembly *assembly);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,94 @@
#pragma once
#include <stdint.h>
#include <vector>
#include <string>
#include "il2cpp-config.h"
#include "il2cpp-metadata.h"
#include "il2cpp-object-internals.h"
#include "metadata/GenericMethod.h"
#include "vm/Exception.h"
#include "vm/Class.h"
#include "vm/MetadataCache.h"
#include "utils/StringUtils.h"
struct Il2CppArray;
struct Il2CppDelegate;
struct Il2CppObject;
struct MethodInfo;
struct Il2CppClass;
typedef void (*MetadataInitializerCleanupFunc)();
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API Runtime
{
public:
static bool Init(const char* domainName = "IL2CPP Root Domain");
static void Shutdown();
static bool IsShuttingDown();
static void SetConfigDir(const char *path);
static void SetConfigUtf16(const Il2CppChar* executablePath);
static void SetConfig(const char* executablePath);
static void SetUnityTlsInterface(const void* unitytlsInterface);
static std::string GetConfigDir();
static const void* GetUnityTlsInterface();
static const char *GetFrameworkVersion();
static const MethodInfo* GetDelegateInvoke(Il2CppClass* klass);
static Il2CppObject* DelegateInvoke(Il2CppDelegate *obj, void **params, Il2CppException **exc);
static Il2CppObject* Invoke(const MethodInfo *method, void *obj, void **params, Il2CppException **exc);
static Il2CppObject* InvokeWithThrow(const MethodInfo *method, void *obj, void **params);
static Il2CppObject* InvokeConvertArgs(const MethodInfo *method, void *obj, Il2CppObject **params, int paramCount, Il2CppException **exc);
static Il2CppObject* InvokeArray(const MethodInfo *method, void *obj, Il2CppArray *params, Il2CppException **exc);
static void ObjectInit(Il2CppObject* object);
static void ObjectInitException(Il2CppObject* object, Il2CppException **exc);
static void SetUnhandledExceptionPolicy(Il2CppRuntimeUnhandledExceptionPolicy value);
static void GetGenericVirtualMethod(const MethodInfo* vtableSlotMethod, const MethodInfo* genericVirtualmethod, VirtualInvokeData* invokeData);
static void AlwaysRaiseExecutionEngineException(const MethodInfo* method);
static void AlwaysRaiseExecutionEngineExceptionOnVirtualCall(const MethodInfo* method);
static inline bool IsFullGenericSharingEnabled()
{
return il2cpp_defaults.il2cpp_fully_shared_type != NULL;
}
static inline bool IsLazyRGCTXInflationEnabled()
{
return il2cpp_defaults.il2cpp_fully_shared_type != NULL;
}
public:
// internal
static Il2CppRuntimeUnhandledExceptionPolicy GetUnhandledExceptionPolicy();
static void UnhandledException(Il2CppException* exc);
static void ClassInit(Il2CppClass *klass);
static const char *GetBundledMachineConfig();
static void RegisterBundledMachineConfig(const char *config_xml);
static int32_t GetExitCode();
static void SetExitCode(int32_t value);
static InvokerMethod GetMissingMethodInvoker();
static void RaiseAmbiguousImplementationException(const MethodInfo* method);
static void RaiseExecutionEngineException(const MethodInfo* method, bool virtualCall);
static void RaiseExecutionEngineException(const MethodInfo* method, const char* methodFullName, bool virtualCall);
#if IL2CPP_TINY
static void FailFast(const std::string& message);
#endif
private:
static void CallUnhandledExceptionDelegate(Il2CppDomain* domain, Il2CppDelegate* delegate, Il2CppException* exc);
static Il2CppObject* CreateUnhandledExceptionEventArgs(Il2CppException* exc);
static void VerifyApiVersion();
static void RaiseExecutionEngineExceptionIfGenericVirtualMethodIsNotFound(const MethodInfo* method, const Il2CppGenericMethod* genericMethod, const MethodInfo* infaltedMethod);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,19 @@
#pragma once
struct Il2CppThread;
namespace il2cpp
{
namespace vm
{
class ScopedThreadAttacher
{
public:
ScopedThreadAttacher();
~ScopedThreadAttacher();
private:
Il2CppThread* m_AttachedThread;
};
}
}

View File

@@ -0,0 +1,49 @@
#pragma once
#include <stdint.h>
#include <vector>
#include "il2cpp-config.h"
#include "il2cpp-metadata.h"
#if IL2CPP_TINY_DEBUGGER
#include <string>
#endif
namespace il2cpp
{
namespace vm
{
typedef std::vector<Il2CppStackFrameInfo> StackFrames;
class LIBIL2CPP_CODEGEN_API StackTrace
{
public:
static void InitializeStackTracesForCurrentThread();
static void CleanupStackTracesForCurrentThread();
#if IL2CPP_TINY_DEBUGGER
static const char* GetStackTrace();
#endif
// Current thread functions
static const StackFrames* GetStackFrames();
static const StackFrames* GetCachedStackFrames(int32_t depth);
static bool GetStackFrameAt(int32_t depth, Il2CppStackFrameInfo& frame);
static void WalkFrameStack(Il2CppFrameWalkFunc callback, void* context);
inline static size_t GetStackDepth() { return GetStackFrames()->size(); }
inline static bool GetTopStackFrame(Il2CppStackFrameInfo& frame) { return GetStackFrameAt(0, frame); }
static void PushFrame(Il2CppStackFrameInfo& frame);
static void PopFrame();
static const void* GetStackPointer();
// Remote thread functions
static bool GetThreadStackFrameAt(Il2CppThread* thread, int32_t depth, Il2CppStackFrameInfo& frame);
static void WalkThreadFrameStack(Il2CppThread* thread, Il2CppFrameWalkFunc callback, void* context);
static int32_t GetThreadStackDepth(Il2CppThread* thread);
static bool GetThreadTopStackFrame(Il2CppThread* thread, Il2CppStackFrameInfo& frame);
};
}
}

View File

@@ -0,0 +1,34 @@
#pragma once
#include <stdint.h>
#include "il2cpp-config.h"
#include "utils/StringView.h"
struct Il2CppString;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API String
{
public:
//exported
static Il2CppString* Empty();
static int32_t GetLength(Il2CppString* str);
static int32_t GetHash(Il2CppString* str);
static Il2CppString* New(const char* str);
static Il2CppString* NewWrapper(const char* str);
static Il2CppString* NewLen(const char* str, uint32_t length);
static Il2CppString* NewSize(int32_t len);
static Il2CppString* NewUtf16(const Il2CppChar *text, int32_t len);
static Il2CppString* NewUtf16(const utils::StringView<Il2CppChar>& text);
public:
static void InitializeEmptyString(Il2CppClass* stringClass);
static void CleanupEmptyString();
static Il2CppString* Intern(Il2CppString* str);
static Il2CppString* IsInterned(Il2CppString* str);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,164 @@
#pragma once
#include <stdint.h>
#include <vector>
#include <string>
#include "il2cpp-config.h"
#include "os/Thread.h"
#include "utils/NonCopyable.h"
struct MethodInfo;
struct Il2CppArray;
struct Il2CppDomain;
struct Il2CppObject;
struct Il2CppThread;
struct Il2CppInternalThread;
struct Il2CppString;
namespace il2cpp
{
namespace vm
{
// System.Threading.ThreadState
enum ThreadState
{
kThreadStateRunning = 0x00000000,
kThreadStateStopRequested = 0x00000001,
kThreadStateSuspendRequested = 0x00000002,
kThreadStateBackground = 0x00000004,
kThreadStateUnstarted = 0x00000008,
kThreadStateStopped = 0x00000010,
kThreadStateWaitSleepJoin = 0x00000020,
kThreadStateSuspended = 0x00000040,
kThreadStateAbortRequested = 0x00000080,
kThreadStateAborted = 0x00000100,
// This enum is used with the ~ operator to clear values. to avoid undefined
// behavior in C++, the cleared state of each value should also be present
// in the enum.
kThreadStateRunningCleared = ~kThreadStateRunning,
kThreadStateStopRequestedCleared = ~kThreadStateStopRequested,
kThreadStateSuspendRequestedCleared = ~kThreadStateSuspendRequested,
kThreadStateBackgroundCleared = ~kThreadStateBackground,
kThreadStateUnstartedCleared = ~kThreadStateUnstarted,
kThreadStateStoppedCleared = ~kThreadStateStopped,
kThreadStateWaitSleepJoinCleared = ~kThreadStateWaitSleepJoin,
kThreadStateSuspendedCleared = ~kThreadStateSuspended,
kThreadStateAbortRequestedCleared = ~kThreadStateAbortRequested,
kThreadStateAbortedCleared = ~kThreadStateAborted,
};
// System.Threading.ApartmentState
enum ThreadApartmentState
{
kThreadApartmentStateSTA = 0x00000000,
kThreadApartmentStateMTA = 0x00000001,
kThreadApartmentStateUnknown = 0x00000002
};
class LIBIL2CPP_CODEGEN_API Thread
{
public:
static std::string GetName(Il2CppInternalThread* thread);
static void SetName(Il2CppThread* thread, Il2CppString* name);
static void SetName(Il2CppInternalThread* thread, Il2CppString* name);
static Il2CppThread* Current();
static Il2CppThread* Attach(Il2CppDomain *domain);
static void Detach(Il2CppThread *thread);
static void WalkFrameStack(Il2CppThread *thread, Il2CppFrameWalkFunc func, void *user_data);
static Il2CppThread** GetAllAttachedThreads(size_t &size);
static void AbortAllThreads();
static Il2CppThread* Main();
static bool IsVmThread(Il2CppThread *thread);
static uint64_t GetId(Il2CppThread *thread);
static uint64_t GetId(Il2CppInternalThread* thread);
static void RequestInterrupt(Il2CppThread* thread);
static void CheckCurrentThreadForInterruptAndThrowIfNecessary();
static bool RequestAbort(Il2CppThread* thread);
static void CheckCurrentThreadForAbortAndThrowIfNecessary();
static void ResetAbort(Il2CppThread* thread);
static bool RequestAbort(Il2CppInternalThread* thread);
static void ResetAbort(Il2CppInternalThread* thread);
static void SetPriority(Il2CppThread* thread, int32_t priority);
static int32_t GetPriority(Il2CppThread* thread);
struct NativeThreadAbortException {};
public:
// internal
static void Initialize();
static void Uninitialize();
static void AdjustStaticData();
static int32_t AllocThreadStaticData(int32_t size);
static void FreeThreadStaticData(Il2CppThread *thread);
static void* GetThreadStaticData(int32_t offset);
static void* GetThreadStaticDataForThread(int32_t offset, Il2CppThread* thread);
static void* GetThreadStaticDataForThread(int32_t offset, Il2CppInternalThread* thread);
static void Register(Il2CppThread *thread);
static void Unregister(Il2CppThread *thread);
static void SetupInternalManagedThread(Il2CppThread* thread, os::Thread* osThread);
/// Initialize and register thread.
/// NOTE: Must be called on thread!
static void InitializeManagedThread(Il2CppThread *thread, Il2CppDomain* domain);
static void UninitializeManagedThread(Il2CppThread *thread);
static void SetMain(Il2CppThread* thread);
static void SetState(Il2CppThread *thread, ThreadState value);
static ThreadState GetState(Il2CppThread *thread);
static void ClrState(Il2CppThread* thread, ThreadState clr);
static void FullMemoryBarrier();
static int32_t GetNewManagedId();
static Il2CppInternalThread* CurrentInternal();
static void ClrState(Il2CppInternalThread* thread, ThreadState clr);
static void SetState(Il2CppInternalThread *thread, ThreadState value);
static ThreadState GetState(Il2CppInternalThread *thread);
static bool TestState(Il2CppInternalThread* thread, ThreadState value);
static Il2CppInternalThread* CreateInternal(void(*func)(void*), void* arg, bool threadpool_thread, uint32_t stack_size);
static void Stop(Il2CppInternalThread* thread);
static void Sleep(uint32_t ms);
static bool YieldInternal();
static void SetDefaultAffinityMask(int64_t affinityMask);
private:
static Il2CppThread* s_MainThread;
};
class ThreadStateSetter : il2cpp::utils::NonCopyable
{
public:
ThreadStateSetter(ThreadState state) : m_State(state)
{
m_Thread = il2cpp::vm::Thread::Current();
Thread::SetState(m_Thread, m_State);
}
~ThreadStateSetter()
{
Thread::ClrState(m_Thread, m_State);
}
private:
ThreadState m_State;
Il2CppThread* m_Thread;
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,22 @@
#pragma once
#include "il2cpp-config.h"
#include "il2cpp-object-internals.h"
#include "il2cpp-class-internals.h"
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API ThreadPoolMs
{
public:
static Il2CppAsyncResult* DelegateBeginInvoke(Il2CppDelegate* delegate, void** params, Il2CppDelegate* asyncCallback, Il2CppObject* state);
static Il2CppObject* DelegateEndInvoke(Il2CppAsyncResult* asyncResult, void **out_args);
static Il2CppObject* MessageInvoke(Il2CppObject *target, Il2CppMethodMessage *msg, Il2CppObject **exc, Il2CppArray **out_args);
static void Suspend();
static void Resume();
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,251 @@
#pragma once
#include <stdint.h>
#include <string>
#include <list>
#include <vector>
#include <algorithm>
#include "il2cpp-config.h"
#include "il2cpp-class-internals.h"
#ifdef major
# undef major
# undef minor
#endif
struct FieldInfo;
struct Il2CppType;
struct Il2CppClass;
struct Il2CppString;
namespace il2cpp
{
namespace vm
{
static const int32_t kPublicKeyTokenLength = 17;
class TypeNameParseInfo
{
public:
struct AssemblyName
{
std::string name;
std::string culture;
std::string public_key;
char public_key_token[kPublicKeyTokenLength];
uint32_t hash_alg;
uint32_t hash_len;
uint32_t flags;
uint16_t major;
uint16_t minor;
uint16_t build;
uint16_t revision;
AssemblyName() :
hash_alg(0),
hash_len(0),
flags(0),
major(0),
minor(0),
build(0),
revision(0)
{
memset(public_key_token, 0, kPublicKeyTokenLength);
}
};
TypeNameParseInfo();
~TypeNameParseInfo();
inline const std::string &ns() const
{
return _namespace;
}
inline const std::string &name() const
{
return _name;
}
inline const AssemblyName &assembly_name() const
{
return _assembly_name;
}
inline const std::vector<int> &modifiers() const
{
return _modifiers;
}
inline const std::vector<TypeNameParseInfo> &type_arguments() const
{
return _type_arguments;
}
inline const std::vector<std::string> &nested() const
{
return _nested;
}
inline bool is_byref() const
{
return std::find(_modifiers.begin(), _modifiers.end(), 0) != _modifiers.end();
}
inline bool has_generic_arguments() const
{
return _type_arguments.size() > 0;
}
inline bool is_pointer() const
{
return std::find(_modifiers.begin(), _modifiers.end(), -1) != _modifiers.end();
}
inline bool is_bounded() const
{
return std::find(_modifiers.begin(), _modifiers.end(), -2) != _modifiers.end();
}
inline bool is_array() const
{
std::vector<int32_t>::const_iterator it = _modifiers.begin();
while (it != _modifiers.end())
{
if (*it > 0)
return true;
++it;
}
return false;
}
void SetAssemblyName(const AssemblyName& assemblyName)
{
_assembly_name = assemblyName;
}
private:
std::string _namespace;
std::string _name;
AssemblyName _assembly_name;
std::vector<int32_t> _modifiers;
std::vector<TypeNameParseInfo> _type_arguments;
std::vector<std::string> _nested;
friend class TypeNameParser;
};
class TypeNameParser
{
public:
TypeNameParser(const std::string &name, TypeNameParseInfo &info, bool is_nested);
TypeNameParser(std::string::const_iterator &begin, std::string::const_iterator &end, TypeNameParseInfo &info, bool is_nested);
bool Parse(bool acceptAssemblyName = true);
bool ParseAssembly();
private:
inline bool IsEOL() const
{
return _p >= _end;
}
inline bool CurrentIs(char v) const
{
if (IsEOL())
return false;
return *_p == v;
}
inline bool Next(bool skipWhites = false)
{
++_p;
if (skipWhites)
SkipWhites();
return !IsEOL();
}
bool NextWillBe(char v, bool skipWhites = false) const;
void InitializeParser();
void SkipWhites();
void ConsumeIdentifier();
void ConsumeAssemblyIdentifier();
void ConsumePropertyIdentifier();
void ConsumePropertyValue();
bool ConsumeNumber(int32_t &value);
bool ParseTypeName(int32_t &arity);
bool ParseNestedTypeOptional(int32_t &arity);
bool ParseTypeArgumentsOptional(int32_t &arity);
bool ParseAssemblyNameOptional();
bool ParseAssemblyName();
bool ParsePropertiesOptional();
bool ParseArrayModifierOptional();
bool ParsePointerModifiersOptional();
bool ParseByRefModifiersOptional();
static bool ParseVersion(const std::string& version, uint16_t& major, uint16_t& minor, uint16_t& build, uint16_t& revision);
TypeNameParseInfo &_info;
bool _is_nested;
bool _accept_assembly_name;
std::string::const_iterator _p;
std::string::const_iterator _end;
};
class LIBIL2CPP_CODEGEN_API Type
{
public:
// exported
static void GetNameChunkedRecurse(const Il2CppType * type, Il2CppTypeNameFormat format, void(*reportFunc)(void *data, void *userData), void * userData);
static std::string GetName(const Il2CppType *type, Il2CppTypeNameFormat format);
static int GetType(const Il2CppType *type);
static Il2CppClass* GetClassOrElementClass(const Il2CppType *type);
static const Il2CppType* GetUnderlyingType(const Il2CppType *type);
static uint32_t GetToken(const Il2CppType *type);
static bool IsGenericInstance(const Il2CppType *type);
static Il2CppReflectionType* GetDeclaringType(const Il2CppType* type);
static Il2CppArray* GetGenericArgumentsInternal(Il2CppReflectionType* type, bool runtimeArray);
static bool IsEqualToType(const Il2CppType *type, const Il2CppType *otherType);
static Il2CppReflectionType* GetTypeFromHandle(intptr_t handle);
public:
// internal
static void GetNameChunkedRecurseInternal(const Il2CppType * type, Il2CppTypeNameFormat format, bool is_nested, void(*reportFunc)(void *data, void *userData), void * userData);
static void GetNameInternal(std::string &oss, const Il2CppType *type, Il2CppTypeNameFormat format, bool is_nested);
static bool IsReference(const Il2CppType* type);
static bool IsStruct(const Il2CppType* type);
static bool GenericInstIsValuetype(const Il2CppType* type);
static bool HasVariableRuntimeSizeWhenFullyShared(const Il2CppType* type);
static bool IsEnum(const Il2CppType *type);
static bool IsValueType(const Il2CppType *type);
static bool IsPointerType(const Il2CppType *type);
static bool IsSystemDBNull(const Il2CppType *type);
static bool IsSystemDateTime(const Il2CppType *type);
static bool IsSystemDecimal(const Il2CppType *type);
static Il2CppClass* GetClass(const Il2CppType *type);
static Il2CppMetadataGenericParameterHandle GetGenericParameterHandle(const Il2CppType *type);
static Il2CppGenericParameterInfo GetGenericParameterInfo(const Il2CppType *type);
static const Il2CppType* GetGenericTypeDefintion(const Il2CppType* type);
static void ConstructDelegate(Il2CppDelegate* delegate, Il2CppObject* target, const MethodInfo* method);
static void ConstructClosedDelegate(Il2CppDelegate* delegate, Il2CppObject* target, Il2CppMethodPointer addr, const MethodInfo* method);
static void SetClosedDelegateInvokeMethod(Il2CppDelegate* delegate, Il2CppObject* target, Il2CppMethodPointer addr);
static Il2CppString* AppendAssemblyNameIfNecessary(Il2CppString* typeName, const MethodInfo* callingMethod);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,17 @@
#pragma once
struct Il2CppWaitHandle;
namespace il2cpp { namespace os { class Handle; } }
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API WaitHandle
{
public:
static Il2CppWaitHandle* NewManualResetEvent(bool initialState);
static os::Handle* GetPlatformHandle(Il2CppWaitHandle* waitHandle);
};
} /* namespace vm */
} /* namespace il2cpp */

View File

@@ -0,0 +1,28 @@
#pragma once
#include "il2cpp-object-internals.h"
#include "Baselib.h"
#include "Cpp/Atomic.h"
namespace il2cpp
{
namespace vm
{
struct WeakReference IL2CPP_FINAL : Il2CppIWeakReference
{
static il2cpp_hresult_t Create(Il2CppObject* managedObject, Il2CppIWeakReference** result);
WeakReference(Il2CppObject * managedObject);
virtual il2cpp_hresult_t STDCALL QueryInterface(const Il2CppGuid& iid, void** object) IL2CPP_FINAL IL2CPP_OVERRIDE;
virtual uint32_t STDCALL AddRef() IL2CPP_FINAL IL2CPP_OVERRIDE;
virtual uint32_t STDCALL Release() IL2CPP_FINAL IL2CPP_OVERRIDE;
virtual il2cpp_hresult_t STDCALL Resolve(const Il2CppGuid& iid, Il2CppIInspectable** object) IL2CPP_FINAL IL2CPP_OVERRIDE;
private:
uint32_t m_GCHandle;
baselib::atomic<uint32_t> m_RefCount;
};
}
}

View File

@@ -0,0 +1,90 @@
#pragma once
#include "os/WindowsRuntime.h"
#include "vm/Exception.h"
#include "vm/String.h"
#include "utils/StringView.h"
struct Il2CppIActivationFactory;
namespace il2cpp
{
namespace vm
{
class LIBIL2CPP_CODEGEN_API WindowsRuntime
{
public:
static Il2CppIActivationFactory* GetActivationFactory(const utils::StringView<Il2CppNativeChar>& runtimeClassName);
static inline void CreateHStringReference(const utils::StringView<Il2CppNativeChar>& str, Il2CppHStringHeader* header, Il2CppHString* hstring)
{
il2cpp_hresult_t hr = os::WindowsRuntime::CreateHStringReference(str, header, hstring);
vm::Exception::RaiseIfFailed(hr, false);
}
static inline Il2CppHString CreateHString(Il2CppString* str)
{
Il2CppHString result;
il2cpp_hresult_t hr = os::WindowsRuntime::CreateHString(utils::StringView<Il2CppChar>(str->chars, str->length), &result);
vm::Exception::RaiseIfFailed(hr, false);
return result;
}
static inline Il2CppHString CreateHString(const utils::StringView<Il2CppNativeChar>& str)
{
Il2CppHString result;
il2cpp_hresult_t hr = os::WindowsRuntime::CreateHString(str, &result);
vm::Exception::RaiseIfFailed(hr, false);
return result;
}
static inline void DeleteHString(Il2CppHString hstring)
{
il2cpp_hresult_t hr = os::WindowsRuntime::DeleteHString(hstring);
vm::Exception::RaiseIfFailed(hr, false);
}
static inline Il2CppString* HStringToManagedString(Il2CppHString hstring)
{
if (hstring == NULL)
return vm::String::Empty();
uint32_t length;
auto result = os::WindowsRuntime::GetHStringBuffer(hstring, &length);
vm::Exception::RaiseIfError(result.GetError());
return vm::String::NewUtf16(result.Get(), length);
}
static inline void* PreallocateHStringBuffer(uint32_t length, Il2CppNativeChar** buffer)
{
void* bufferHandle;
auto hr = os::WindowsRuntime::PreallocateHStringBuffer(length, buffer, &bufferHandle);
vm::Exception::RaiseIfError(hr.GetError());
vm::Exception::RaiseIfFailed(hr.Get(), false);
return bufferHandle;
}
static inline Il2CppHString PromoteHStringBuffer(void* bufferHandle)
{
Il2CppHString hstring;
auto hr = os::WindowsRuntime::PromoteHStringBuffer(bufferHandle, &hstring);
vm::Exception::RaiseIfError(hr.GetError());
if (IL2CPP_HR_FAILED(hr.Get()))
{
// Prevent memory leaks by deleting the hstring buffer that was supposed to be promoted before raising an exception
os::WindowsRuntime::DeleteHStringBuffer(bufferHandle);
vm::Exception::Raise(hr.Get(), false);
}
return hstring;
}
static void MarshalTypeToNative(const Il2CppType* type, Il2CppWindowsRuntimeTypeName& nativeType);
static const Il2CppType* MarshalTypeFromNative(Il2CppWindowsRuntimeTypeName& nativeType);
static inline void DeleteNativeType(Il2CppWindowsRuntimeTypeName& nativeType)
{
DeleteHString(nativeType.typeName);
}
};
}
}