#include "InterpreterUtil.h" #include "vm/Object.h" #include "../metadata/MetadataUtil.h" namespace hybridclr { namespace interpreter { TypeDesc GetValueTypeArgDescBySize(uint32_t size) { if (size <= 8) { return { LocationDataType::U8, 1 }; } return { LocationDataType::S_N, (uint32_t)metadata::GetStackSizeByByteSize(size) }; } TypeDesc GetTypeArgDesc(const Il2CppType* type) { if (type->byref) { return { LocationDataType::U8, 1 }; } switch (type->type) { case IL2CPP_TYPE_BOOLEAN: case IL2CPP_TYPE_U1: return{ LocationDataType::U1, 1 }; case IL2CPP_TYPE_I1: return{ LocationDataType::I1, 1 }; case IL2CPP_TYPE_I2: return{ LocationDataType::I2, 1 }; case IL2CPP_TYPE_CHAR: case IL2CPP_TYPE_U2: return{ LocationDataType::U2, 1 }; case IL2CPP_TYPE_I4: case IL2CPP_TYPE_U4: case IL2CPP_TYPE_R4: case IL2CPP_TYPE_I8: case IL2CPP_TYPE_U8: case IL2CPP_TYPE_R8: case IL2CPP_TYPE_I: case IL2CPP_TYPE_U: case IL2CPP_TYPE_FNPTR: case IL2CPP_TYPE_PTR: case IL2CPP_TYPE_BYREF: case IL2CPP_TYPE_STRING: case IL2CPP_TYPE_ARRAY: case IL2CPP_TYPE_SZARRAY: case IL2CPP_TYPE_OBJECT: case IL2CPP_TYPE_CLASS: return{ LocationDataType::U8, 1 }; case IL2CPP_TYPE_TYPEDBYREF: return GetValueTypeArgDescBySize(sizeof(Il2CppTypedRef)); case IL2CPP_TYPE_VALUETYPE: { Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type); IL2CPP_ASSERT(IS_CLASS_VALUE_TYPE(klass)); if (klass->enumtype) { return GetTypeArgDesc(&klass->castClass->byval_arg); } return GetValueTypeArgDescBySize(il2cpp::vm::Class::GetValueSize(klass, nullptr)); } case IL2CPP_TYPE_GENERICINST: { Il2CppGenericClass* genericClass = type->data.generic_class; if (genericClass->type->type == IL2CPP_TYPE_CLASS) { IL2CPP_ASSERT(!IS_CLASS_VALUE_TYPE(il2cpp::vm::Class::FromIl2CppType(type))); return{ LocationDataType::U8, 1 }; } else { Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type); IL2CPP_ASSERT(IS_CLASS_VALUE_TYPE(klass)); if (klass->enumtype) { return GetTypeArgDesc(&klass->castClass->byval_arg); } return GetValueTypeArgDescBySize(il2cpp::vm::Class::GetValueSize(klass, nullptr)); } } default: { RaiseExecutionEngineException("not support arg type"); return{ LocationDataType::U8, 1 }; } } } Il2CppObject* TranslateNativeValueToBoxValue(const Il2CppType* type, void* value) { if (type->byref) { RaiseExecutionEngineException("TranslateNativeValueToBoxValue can't box ref"); return nullptr; } Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type); return il2cpp::vm::Object::Box(klass, value); } } }