private CorInfoIntrinsics asCorInfoIntrinsic(IntrinsicMethodKind methodKind) { switch (methodKind) { case IntrinsicMethodKind.RuntimeHelpersInitializeArray: return CorInfoIntrinsics.CORINFO_INTRINSIC_InitializeArray; default: return CorInfoIntrinsics.CORINFO_INTRINSIC_Illegal; } }
private void ImportIntrinsicCall(IntrinsicMethodKind intrinsicClassification) { switch (intrinsicClassification) { case IntrinsicMethodKind.RuntimeHelpersInitializeArray: { var fieldSlot = Pop(); var arraySlot = Pop(); var fieldDesc = (TypeSystem.Ecma.EcmaField)fieldSlot.Value.Aux; int addr = fieldDesc.MetadataReader.GetFieldDefinition(fieldDesc.Handle).GetRelativeVirtualAddress(); var memBlock = fieldDesc.Module.PEReader.GetSectionData(addr).GetContent(); var fieldType = (TypeSystem.Ecma.EcmaType)fieldDesc.FieldType; int size = fieldType.MetadataReader.GetTypeDefinition(fieldType.Handle).GetLayout().Size; if (size == 0) throw new NotImplementedException(); // TODO: Need to do more for arches with different endianness? var preinitDataHolder = NewTempName(); Append("static const char "); Append(preinitDataHolder); Append("[] = { "); for (int i = 0; i < size; i++) { if (i != 0) Append(", "); Append(String.Format("0x{0:X}", memBlock[i])); } Append(" }"); Finish(); Append("memcpy((char*)"); Append(arraySlot.Value.Name); Append(" + ARRAY_BASE, "); Append(preinitDataHolder); Append(", "); Append(size.ToString()); Append(")"); Finish(); break; } default: throw new NotImplementedException(); } }