private void LoadIndirect(ITypeReference targetType) {
Contract.Requires(targetType != null);
OperationCode opcode;
switch (targetType.TypeCode) {
case PrimitiveTypeCode.Boolean: opcode = OperationCode.Ldind_U1; break;
case PrimitiveTypeCode.Char: opcode = OperationCode.Ldind_U2; break;
case PrimitiveTypeCode.Float32: opcode = OperationCode.Ldind_R4; break;
case PrimitiveTypeCode.Float64: opcode = OperationCode.Ldind_R8; break;
case PrimitiveTypeCode.Int16: opcode = OperationCode.Ldind_I2; break;
case PrimitiveTypeCode.Int32: opcode = OperationCode.Ldind_I4; break;
case PrimitiveTypeCode.Int64: opcode = OperationCode.Ldind_I8; break;
case PrimitiveTypeCode.Int8: opcode = OperationCode.Ldind_I1; break;
case PrimitiveTypeCode.IntPtr: opcode = OperationCode.Ldind_I; break;
case PrimitiveTypeCode.Pointer: opcode = OperationCode.Ldind_I; break;
case PrimitiveTypeCode.UInt16: opcode = OperationCode.Ldind_U2; break;
case PrimitiveTypeCode.UInt32: opcode = OperationCode.Ldind_U4; break;
case PrimitiveTypeCode.UInt64: opcode = OperationCode.Ldind_I8; break;
case PrimitiveTypeCode.UInt8: opcode = OperationCode.Ldind_U1; break;
case PrimitiveTypeCode.UIntPtr: opcode = OperationCode.Ldind_I; break;
default:
var ptr = targetType as IPointerTypeReference;
if (ptr != null) {
opcode = OperationCode.Ldind_I; break;
} else {
var mgdPtr = targetType as IManagedPointerTypeReference;
if (mgdPtr != null) {
opcode = OperationCode.Ldind_I; break;
}
}
//If type is a reference type, then Ldobj is equivalent to Lind_Ref, but the instruction is larger, so try to avoid it.
if (targetType.IsValueType || targetType is IGenericParameterReference) {
this.generator.Emit(OperationCode.Ldobj, targetType);
return;
}
opcode = OperationCode.Ldind_Ref; break;
}
this.generator.Emit(opcode);
}