public void Emit(ILGenerator gen) { right.Emit(gen); if (fromType == target) { return; } if (fromType.IsByRef) { fromType = fromType.GetElementType(); } if (target.IsByRef) { target = target.GetElementType(); } if (target.IsValueType) { if (fromType.IsValueType) { throw new NotImplementedException("Cannot convert between distinct value types"); } else { // Unbox conversion // Assumes fromType is a boxed value // if we can, we emit a box and ldind, otherwise, we will use unbox.any if (LdindOpCodesDictionary.Instance[target] != LdindOpCodesDictionary.EmptyOpCode) { gen.Emit(OpCodes.Unbox, target); OpCodeUtil.EmitLoadIndirectOpCodeForType(gen, target); } else { gen.Emit(OpCodes.Unbox_Any, target); } } } else { if (fromType.IsValueType) { // Box conversion gen.Emit(OpCodes.Box, fromType); EmitCastIfNeeded(typeof(object), target, gen); } else { // Possible down-cast EmitCastIfNeeded(fromType, target, gen); } } }
public override void Emit(IEasyMember member, ILGenerator gen) { _right.Emit(member, gen); if (_fromType == _target) { return; } if (_fromType.IsByRef) { throw new NotSupportedException("Cannot convert from ByRef types"); } if (_target.IsByRef) { throw new NotSupportedException("Cannot convert to ByRef types"); } if (_target.IsValueType) { if (_fromType.IsValueType) { throw new NotImplementedException("Cannot convert between distinct value types at the moment"); } else { // Unbox conversion // Assumes fromType is a boxed value gen.Emit(OpCodes.Unbox, _target); OpCodeUtil.EmitLoadIndirectOpCodeForType(gen, _target); } } else { if (_fromType.IsValueType) { // Box conversion gen.Emit(OpCodes.Box, _fromType); EmitCastIfNeeded(typeof(object), _target, gen); } else { // Possible down-cast EmitCastIfNeeded(_fromType, _target, gen); } } }
// TODO: Better name public override void LoadReference(ILGenerator gen) { OpCodeUtil.EmitLoadIndirectOpCodeForType(gen, Type); }