#include "TransformContext.h" namespace hybridclr { namespace transform { EvalStackReduceDataType GetEvalStackReduceDataType(const Il2CppType* type) { if (type->byref) { return NATIVE_INT_REDUCE_TYPE; } switch (type->type) { case IL2CPP_TYPE_BOOLEAN: case IL2CPP_TYPE_I1: case IL2CPP_TYPE_U1: case IL2CPP_TYPE_CHAR: case IL2CPP_TYPE_I2: case IL2CPP_TYPE_U2: case IL2CPP_TYPE_I4: case IL2CPP_TYPE_U4: return EvalStackReduceDataType::I4; case IL2CPP_TYPE_R4: return EvalStackReduceDataType::R4; case IL2CPP_TYPE_I8: case IL2CPP_TYPE_U8: return EvalStackReduceDataType::I8; case IL2CPP_TYPE_R8: return EvalStackReduceDataType::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_CLASS: case IL2CPP_TYPE_ARRAY: case IL2CPP_TYPE_SZARRAY: case IL2CPP_TYPE_OBJECT: return NATIVE_INT_REDUCE_TYPE; case IL2CPP_TYPE_TYPEDBYREF: return EvalStackReduceDataType::Other; case IL2CPP_TYPE_VALUETYPE: { Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type); return klass->enumtype ? GetEvalStackReduceDataType(&klass->element_class->byval_arg) : EvalStackReduceDataType::Other; } case IL2CPP_TYPE_GENERICINST: { Il2CppGenericClass* genericClass = type->data.generic_class; if (genericClass->type->type == IL2CPP_TYPE_CLASS) { return NATIVE_INT_REDUCE_TYPE; } else { Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type); return klass->enumtype ? GetEvalStackReduceDataType(&klass->element_class->byval_arg) : EvalStackReduceDataType::Other; } } default: { RaiseExecutionEngineException("GetEvalStackReduceDataType invalid type"); return EvalStackReduceDataType::Other; } } } int32_t GetSizeByReduceType(EvalStackReduceDataType type) { switch (type) { case hybridclr::transform::EvalStackReduceDataType::I4: case hybridclr::transform::EvalStackReduceDataType::R4: return 4; case hybridclr::transform::EvalStackReduceDataType::I8: case hybridclr::transform::EvalStackReduceDataType::R8: return 8; default: { RaiseExecutionEngineException("GetSizeByReduceType not support type"); return PTR_SIZE; } } } LocationDescInfo ComputValueTypeDescInfo(int32_t size, bool hasReference) { #if HYBRIDCLR_ENABLE_WRITE_BARRIERS if (hasReference) { return { LocationDescType::StructContainsRef, size }; } #endif switch (size) { case 1: return { LocationDescType::U1, 0 }; case 2: return { LocationDescType::U2, 0 }; case 4: return { LocationDescType::I4, 0 }; case 8: return { LocationDescType::I8, 0 }; default: return { LocationDescType::S, size }; } } LocationDescInfo ComputLocationDescInfo(const Il2CppType* type) { if (type->byref) { return { NATIVE_INT_DESC_TYPE, 0 }; } switch (type->type) { case IL2CPP_TYPE_BOOLEAN: case IL2CPP_TYPE_U1: return{ LocationDescType::U1, 0 }; case IL2CPP_TYPE_I1: return{ LocationDescType::I1, 0 }; case IL2CPP_TYPE_I2: return{ LocationDescType::I2, 0 }; case IL2CPP_TYPE_CHAR: case IL2CPP_TYPE_U2: return{ LocationDescType::U2, 0 }; case IL2CPP_TYPE_I4: case IL2CPP_TYPE_U4: case IL2CPP_TYPE_R4: return{ LocationDescType::I4, 0 }; case IL2CPP_TYPE_I8: case IL2CPP_TYPE_U8: case IL2CPP_TYPE_R8: return{ LocationDescType::I8, 0 }; case IL2CPP_TYPE_I: case IL2CPP_TYPE_U: case IL2CPP_TYPE_FNPTR: case IL2CPP_TYPE_PTR: case IL2CPP_TYPE_BYREF: return{ NATIVE_INT_DESC_TYPE, 0 }; case IL2CPP_TYPE_STRING: case IL2CPP_TYPE_ARRAY: case IL2CPP_TYPE_SZARRAY: case IL2CPP_TYPE_OBJECT: case IL2CPP_TYPE_CLASS: return{ LocationDescType::Ref, 0 }; case IL2CPP_TYPE_TYPEDBYREF: return { LocationDescType::S, sizeof(Il2CppTypedRef) }; case IL2CPP_TYPE_VALUETYPE: { Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type); IL2CPP_ASSERT(IS_CLASS_VALUE_TYPE(klass)); if (klass->enumtype) { return ComputLocationDescInfo(&klass->castClass->byval_arg); } return ComputValueTypeDescInfo(il2cpp::vm::Class::GetValueSize(klass, nullptr), klass->has_references); } 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{ LocationDescType::Ref, 0 }; } else { Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type); IL2CPP_ASSERT(IS_CLASS_VALUE_TYPE(klass)); if (klass->enumtype) { return ComputLocationDescInfo(&klass->castClass->byval_arg); } return ComputValueTypeDescInfo(il2cpp::vm::Class::GetValueSize(klass, nullptr), klass->has_references); } } default: { RaiseExecutionEngineException("not support arg type"); return{ NATIVE_INT_DESC_TYPE, 0 }; } } } IRCommon* CreateLoadExpandDataToStackVarVar(TemporaryMemoryArena& pool, int32_t dstOffset, int32_t srcOffset, const Il2CppType* type, int32_t size) { if (type->byref) { CreateIR(ir, LdlocVarVar); ir->dst = dstOffset; ir->src = srcOffset; return ir; } switch (type->type) { case Il2CppTypeEnum::IL2CPP_TYPE_I1: { CreateIR(ir, LdlocExpandVarVar_i1); ir->dst = dstOffset; ir->src = srcOffset; return ir; } case Il2CppTypeEnum::IL2CPP_TYPE_BOOLEAN: case Il2CppTypeEnum::IL2CPP_TYPE_U1: { CreateIR(ir, LdlocExpandVarVar_u1); ir->dst = dstOffset; ir->src = srcOffset; return ir; } case Il2CppTypeEnum::IL2CPP_TYPE_I2: { CreateIR(ir, LdlocExpandVarVar_i2); ir->dst = dstOffset; ir->src = srcOffset; return ir; } case IL2CPP_TYPE_CHAR: case IL2CPP_TYPE_U2: { CreateIR(ir, LdlocExpandVarVar_u2); ir->dst = dstOffset; ir->src = srcOffset; return ir; } case IL2CPP_TYPE_VALUETYPE: { Il2CppClass* klass = il2cpp::vm::Class::FromIl2CppType(type); if (klass->enumtype) { return CreateLoadExpandDataToStackVarVar(pool, dstOffset, srcOffset, &klass->element_class->byval_arg, size); } break; } default: break; } if (size <= 8) { CreateIR(ir, LdlocVarVar); ir->dst = dstOffset; ir->src = srcOffset; return ir; } else { IL2CPP_ASSERT(size <= MAX_VALUE_TYPE_SIZE); CreateIR(ir, LdlocVarVarSize); ir->dst = dstOffset; ir->src = srcOffset; ir->size = size; return ir; } } IRCommon* CreateAssignVarVar(TemporaryMemoryArena& pool, int32_t dstOffset, int32_t srcOffset, int32_t size) { if (size <= 8) { CreateIR(ir, LdlocVarVar); ir->dst = dstOffset; ir->src = srcOffset; return ir; } else { IL2CPP_ASSERT(size <= MAX_VALUE_TYPE_SIZE); CreateIR(ir, LdlocVarVarSize); ir->dst = dstOffset; ir->src = srcOffset; ir->size = size; return ir; } } interpreter::IRCommon* CreateClassLdfld(TemporaryMemoryArena& pool, int32_t dstIdx, int32_t objIdx, const FieldInfo* fieldInfo) { uint16_t offset = (uint16_t)GetFieldOffset(fieldInfo); const Il2CppType* type = fieldInfo->type; LocationDescInfo desc = ComputLocationDescInfo(type); CreateIR(ir, LdfldVarVar_i1); ir->dst = dstIdx; ir->obj = objIdx; ir->offset = offset; switch (desc.type) { case LocationDescType::I1: { ir->type = HiOpcodeEnum::LdfldVarVar_i1; return ir; } case LocationDescType::U1: { ir->type = HiOpcodeEnum::LdfldVarVar_u1; return ir; } case LocationDescType::I2: { ir->type = HiOpcodeEnum::LdfldVarVar_i2; return ir; } case LocationDescType::U2: { ir->type = HiOpcodeEnum::LdfldVarVar_u2; return ir; } case LocationDescType::I4: { ir->type = HiOpcodeEnum::LdfldVarVar_i4; return ir; } case LocationDescType::I8: { ir->type = HiOpcodeEnum::LdfldVarVar_i8; return ir; } case LocationDescType::Ref: { ir->type = HYBRIDCLR_ARCH_64 ? HiOpcodeEnum::LdfldVarVar_i8 : HiOpcodeEnum::LdfldVarVar_i4; return ir; } case LocationDescType::S: case LocationDescType::StructContainsRef: { switch (desc.size) { case 12: { ir->type = HiOpcodeEnum::LdfldVarVar_size_12; return ir; } case 16: { ir->type = HiOpcodeEnum::LdfldVarVar_size_16; return ir; } case 20: { ir->type = HiOpcodeEnum::LdfldVarVar_size_20; return ir; } case 24: { ir->type = HiOpcodeEnum::LdfldVarVar_size_24; return ir; } case 28: { ir->type = HiOpcodeEnum::LdfldVarVar_size_28; return ir; } case 32: { ir->type = HiOpcodeEnum::LdfldVarVar_size_32; return ir; } default: { CreateIR(irn, LdfldVarVar_n_4); irn->dst = dstIdx; irn->obj = objIdx; irn->offset = offset; irn->size = desc.size; return irn; } } } default: { RaiseExecutionEngineException("field"); return ir; } } } interpreter::IRCommon* CreateValueTypeLdfld(TemporaryMemoryArena& pool, int32_t dstIdx, int32_t objIdx, const FieldInfo* fieldInfo) { uint16_t offset = (uint16_t)GetFieldOffset(fieldInfo); const Il2CppType* type = fieldInfo->type; LocationDescInfo desc = ComputLocationDescInfo(type); CreateIR(ir, LdfldValueTypeVarVar_i1); ir->dst = dstIdx; ir->obj = objIdx; ir->offset = offset; switch (desc.type) { case LocationDescType::I1: { ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_i1; return ir; } case LocationDescType::U1: { ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_u1; return ir; } case LocationDescType::I2: { ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_i2; return ir; } case LocationDescType::U2: { ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_u2; return ir; } case LocationDescType::I4: { ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_i4; return ir; } case LocationDescType::I8: { ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_i8; return ir; } case LocationDescType::Ref: { ir->type = HYBRIDCLR_ARCH_64 ? HiOpcodeEnum::LdfldValueTypeVarVar_i8 : HiOpcodeEnum::LdfldValueTypeVarVar_i4; return ir; } case LocationDescType::S: case LocationDescType::StructContainsRef: { switch (desc.size) { case 12: { ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_size_12; return ir; } case 16: { ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_size_16; return ir; } case 20: { ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_size_20; return ir; } case 24: { ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_size_24; return ir; } case 28: { ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_size_28; return ir; } case 32: { ir->type = HiOpcodeEnum::LdfldValueTypeVarVar_size_32; return ir; } default: { CreateIR(irn, LdfldValueTypeVarVar_n_4); irn->dst = dstIdx; irn->obj = objIdx; irn->offset = offset; irn->size = desc.size; return irn; } } } default: { RaiseExecutionEngineException("field"); return ir; } } } interpreter::IRCommon* CreateStfld(TemporaryMemoryArena& pool, int32_t objIdx, const FieldInfo* fieldInfo, int32_t dataIdx) { uint16_t offset = (uint16_t)GetFieldOffset(fieldInfo); const Il2CppType* type = fieldInfo->type; LocationDescInfo desc = ComputLocationDescInfo(type); CreateIR(ir, StfldVarVar_i1); ir->data = dataIdx; ir->obj = objIdx; ir->offset = offset; switch (desc.type) { case LocationDescType::I1: { ir->type = HiOpcodeEnum::StfldVarVar_i1; return ir; } case LocationDescType::U1: { ir->type = HiOpcodeEnum::StfldVarVar_u1; return ir; } case LocationDescType::I2: { ir->type = HiOpcodeEnum::StfldVarVar_i2; return ir; } case LocationDescType::U2: { ir->type = HiOpcodeEnum::StfldVarVar_u2; return ir; } case LocationDescType::I4: { ir->type = HiOpcodeEnum::StfldVarVar_i4; return ir; } case LocationDescType::I8: { ir->type = HiOpcodeEnum::StfldVarVar_i8; return ir; } case LocationDescType::Ref: { ir->type = HiOpcodeEnum::StfldVarVar_ref; return ir; } case LocationDescType::S: { switch (desc.size) { case 12: { ir->type = HiOpcodeEnum::StfldVarVar_size_12; return ir; } case 16: { ir->type = HiOpcodeEnum::StfldVarVar_size_16; return ir; } case 20: { ir->type = HiOpcodeEnum::StfldVarVar_size_20; return ir; } case 24: { ir->type = HiOpcodeEnum::StfldVarVar_size_24; return ir; } case 28: { ir->type = HiOpcodeEnum::StfldVarVar_size_28; return ir; } case 32: { ir->type = HiOpcodeEnum::StfldVarVar_size_32; return ir; } default: { CreateIR(irn, StfldVarVar_n_4); irn->data = dataIdx; irn->obj = objIdx; irn->offset = offset; irn->size = desc.size; return irn; } } } case LocationDescType::StructContainsRef: { CreateIR(irn, StfldVarVar_WriteBarrier_n_4); irn->data = dataIdx; irn->obj = objIdx; irn->offset = offset; irn->size = desc.size; return irn; } default: { RaiseExecutionEngineException("field"); return ir; } } } interpreter::IRCommon* CreateLdsfld(TemporaryMemoryArena& pool, int32_t dstIdx, const FieldInfo* fieldInfo, uint32_t parent) { IL2CPP_ASSERT(fieldInfo->offset < (1 << 16)); uint16_t offset = (uint16_t)fieldInfo->offset; const Il2CppType* type = fieldInfo->type; LocationDescInfo desc = ComputLocationDescInfo(type); CreateIR(ir, LdsfldVarVar_i1); ir->dst = dstIdx; ir->klass = parent; ir->offset = offset; switch (desc.type) { case LocationDescType::I1: { ir->type = HiOpcodeEnum::LdsfldVarVar_i1; return ir; } case LocationDescType::U1: { ir->type = HiOpcodeEnum::LdsfldVarVar_u1; return ir; } case LocationDescType::I2: { ir->type = HiOpcodeEnum::LdsfldVarVar_i2; return ir; } case LocationDescType::U2: { ir->type = HiOpcodeEnum::LdsfldVarVar_u2; return ir; } case LocationDescType::I4: { ir->type = HiOpcodeEnum::LdsfldVarVar_i4; return ir; } case LocationDescType::I8: { ir->type = HiOpcodeEnum::LdsfldVarVar_i8; return ir; } case LocationDescType::Ref: { ir->type = HYBRIDCLR_ARCH_64 ? HiOpcodeEnum::LdsfldVarVar_i8 : HiOpcodeEnum::LdsfldVarVar_i4; return ir; } case LocationDescType::S: case LocationDescType::StructContainsRef: { switch (desc.size) { case 12: { ir->type = HiOpcodeEnum::LdsfldVarVar_size_12; return ir; } case 16: { ir->type = HiOpcodeEnum::LdsfldVarVar_size_16; return ir; } case 20: { ir->type = HiOpcodeEnum::LdsfldVarVar_size_20; return ir; } case 24: { ir->type = HiOpcodeEnum::LdsfldVarVar_size_24; return ir; } case 28: { ir->type = HiOpcodeEnum::LdsfldVarVar_size_28; return ir; } case 32: { ir->type = HiOpcodeEnum::LdsfldVarVar_size_32; return ir; } default: { CreateIR(irn, LdsfldVarVar_n_4); irn->dst = dstIdx; irn->klass = parent; irn->offset = offset; irn->size = desc.size; return irn; } } } default: { RaiseExecutionEngineException("field"); return ir; } } } interpreter::IRCommon* CreateStsfld(TemporaryMemoryArena& pool, const FieldInfo* fieldInfo, uint32_t parent, int32_t dataIdx) { IL2CPP_ASSERT(fieldInfo->offset < (1 << 16)); uint16_t offset = (uint16_t)fieldInfo->offset; const Il2CppType* type = fieldInfo->type; LocationDescInfo desc = ComputLocationDescInfo(type); CreateIR(ir, StsfldVarVar_i1); ir->klass = parent; ir->offset = offset; ir->data = dataIdx; switch (desc.type) { case LocationDescType::I1: { ir->type = HiOpcodeEnum::StsfldVarVar_i1; return ir; } case LocationDescType::U1: { ir->type = HiOpcodeEnum::StsfldVarVar_u1; return ir; } case LocationDescType::I2: { ir->type = HiOpcodeEnum::StsfldVarVar_i2; return ir; } case LocationDescType::U2: { ir->type = HiOpcodeEnum::StsfldVarVar_u2; return ir; } case LocationDescType::I4: { ir->type = HiOpcodeEnum::StsfldVarVar_i4; return ir; } case LocationDescType::I8: { ir->type = HiOpcodeEnum::StsfldVarVar_i8; return ir; } case LocationDescType::Ref: { ir->type = HiOpcodeEnum::StsfldVarVar_ref; return ir; } case LocationDescType::S: { switch (desc.size) { case 12: { ir->type = HiOpcodeEnum::StsfldVarVar_size_12; return ir; } case 16: { ir->type = HiOpcodeEnum::StsfldVarVar_size_16; return ir; } case 20: { ir->type = HiOpcodeEnum::StsfldVarVar_size_20; return ir; } case 24: { ir->type = HiOpcodeEnum::StsfldVarVar_size_24; return ir; } case 28: { ir->type = HiOpcodeEnum::StsfldVarVar_size_28; return ir; } case 32: { ir->type = HiOpcodeEnum::StsfldVarVar_size_32; return ir; } default: { CreateIR(irn, StsfldVarVar_n_4); irn->klass = parent; irn->offset = offset; irn->data = dataIdx; irn->size = desc.size; return irn; } } } case LocationDescType::StructContainsRef: { CreateIR(irn, StsfldVarVar_WriteBarrier_n_4); irn->klass = parent; irn->offset = offset; irn->data = dataIdx; irn->size = desc.size; return irn; } default: { RaiseExecutionEngineException("field"); return ir; } } } interpreter::IRCommon* CreateLdthreadlocal(TemporaryMemoryArena& pool, int32_t dstIdx, const FieldInfo* fieldInfo, uint32_t parent) { IL2CPP_ASSERT(fieldInfo->offset == THREAD_STATIC_FIELD_OFFSET); int32_t offset = GetThreadStaticFieldOffset(fieldInfo); const Il2CppType* type = fieldInfo->type; LocationDescInfo desc = ComputLocationDescInfo(type); CreateIR(ir, LdthreadlocalVarVar_i1); ir->dst = dstIdx; ir->klass = parent; ir->offset = offset; switch (desc.type) { case LocationDescType::I1: { ir->type = HiOpcodeEnum::LdthreadlocalVarVar_i1; return ir; } case LocationDescType::U1: { ir->type = HiOpcodeEnum::LdthreadlocalVarVar_u1; return ir; } case LocationDescType::I2: { ir->type = HiOpcodeEnum::LdthreadlocalVarVar_i2; return ir; } case LocationDescType::U2: { ir->type = HiOpcodeEnum::LdthreadlocalVarVar_u2; return ir; } case LocationDescType::I4: { ir->type = HiOpcodeEnum::LdthreadlocalVarVar_i4; return ir; } case LocationDescType::I8: { ir->type = HiOpcodeEnum::LdthreadlocalVarVar_i8; return ir; } case LocationDescType::Ref: { ir->type = HYBRIDCLR_ARCH_64 ? HiOpcodeEnum::LdthreadlocalVarVar_i8 : HiOpcodeEnum::LdthreadlocalVarVar_i4; return ir; } case LocationDescType::S: case LocationDescType::StructContainsRef: { switch (desc.size) { case 12: { ir->type = HiOpcodeEnum::LdthreadlocalVarVar_size_12; return ir; } case 16: { ir->type = HiOpcodeEnum::LdthreadlocalVarVar_size_16; return ir; } case 20: { ir->type = HiOpcodeEnum::LdthreadlocalVarVar_size_20; return ir; } case 24: { ir->type = HiOpcodeEnum::LdthreadlocalVarVar_size_24; return ir; } case 28: { ir->type = HiOpcodeEnum::LdthreadlocalVarVar_size_28; return ir; } case 32: { ir->type = HiOpcodeEnum::LdthreadlocalVarVar_size_32; return ir; } default: { CreateIR(irn, LdthreadlocalVarVar_n_4); irn->dst = dstIdx; irn->klass = parent; irn->offset = offset; irn->size = desc.size; return irn; } } } default: { RaiseExecutionEngineException("field"); return ir; } } } interpreter::IRCommon* CreateStthreadlocal(TemporaryMemoryArena& pool, const FieldInfo* fieldInfo, uint32_t parent, int32_t dataIdx) { IL2CPP_ASSERT(fieldInfo->offset == THREAD_STATIC_FIELD_OFFSET); int32_t offset = GetThreadStaticFieldOffset(fieldInfo); const Il2CppType* type = fieldInfo->type; LocationDescInfo desc = ComputLocationDescInfo(type); CreateIR(ir, StthreadlocalVarVar_i1); ir->klass = parent; ir->offset = offset; ir->data = dataIdx; switch (desc.type) { case LocationDescType::I1: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_i1; return ir; } case LocationDescType::U1: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_u1; return ir; } case LocationDescType::I2: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_i2; return ir; } case LocationDescType::U2: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_u2; return ir; } case LocationDescType::I4: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_i4; return ir; } case LocationDescType::I8: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_i8; return ir; } case LocationDescType::Ref: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_ref; return ir; } case LocationDescType::S: { switch (desc.size) { case 12: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_size_12; return ir; } case 16: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_size_16; return ir; } case 20: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_size_20; return ir; } case 24: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_size_24; return ir; } case 28: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_size_28; return ir; } case 32: { ir->type = HiOpcodeEnum::StthreadlocalVarVar_size_32; return ir; } default: { CreateIR(irn, StthreadlocalVarVar_n_4); irn->klass = parent; irn->offset = offset; irn->data = dataIdx; irn->size = desc.size; return irn; } } } case LocationDescType::StructContainsRef: { CreateIR(irn, StthreadlocalVarVar_WriteBarrier_n_4); irn->klass = parent; irn->offset = offset; irn->data = dataIdx; irn->size = desc.size; return irn; } default: { RaiseExecutionEngineException("field"); return ir; } } } HiOpcodeEnum CalcGetMdArrElementVarVarOpcode(const Il2CppType* type) { LocationDescInfo desc = ComputLocationDescInfo(type); switch (desc.type) { case LocationDescType::I1: return HiOpcodeEnum::GetMdArrElementVarVar_i1; case LocationDescType::U1: return HiOpcodeEnum::GetMdArrElementVarVar_u1; case LocationDescType::I2: return HiOpcodeEnum::GetMdArrElementVarVar_i2; case LocationDescType::U2: return HiOpcodeEnum::GetMdArrElementVarVar_u2; case LocationDescType::I4: return HiOpcodeEnum::GetMdArrElementVarVar_i4; case LocationDescType::I8: return HiOpcodeEnum::GetMdArrElementVarVar_i8; case LocationDescType::Ref: return HYBRIDCLR_ARCH_64 ? HiOpcodeEnum::GetMdArrElementVarVar_i8 : HiOpcodeEnum::GetMdArrElementVarVar_i4; case LocationDescType::S: case LocationDescType::StructContainsRef: return HiOpcodeEnum::GetMdArrElementVarVar_n; default: { RaiseExecutionEngineException("CalcGetMdArrElementVarVarOpcode"); return (HiOpcodeEnum)0; } } } } }