protected override void EmitOperation(EmitContext ec) { Label is_null_label = ec.DefineLabel(); Label end_label = ec.DefineLabel(); LocalTemporary lt = new LocalTemporary(type); // Value is on the stack lt.Store(ec); var call = new CallEmitter(); call.InstanceExpression = lt; call.EmitPredefined(ec, NullableInfo.GetHasValue(expr.Type), null); ec.Emit(OpCodes.Brfalse, is_null_label); call = new CallEmitter(); call.InstanceExpression = lt; call.EmitPredefined(ec, NullableInfo.GetGetValueOrDefault(expr.Type), null); lt.Release(ec); base.EmitOperation(ec); ec.Emit(OpCodes.Newobj, NullableInfo.GetConstructor(type)); ec.Emit(OpCodes.Br_S, end_label); ec.MarkLabel(is_null_label); LiftedNull.Create(type, loc).Emit(ec); ec.MarkLabel(end_label); }
public override void Emit(EmitContext ec) { Store(ec); var call = new CallEmitter(); call.InstanceExpression = this; // // Using GetGetValueOrDefault is prefered because JIT can possibly // inline it whereas Value property contains a throw which is very // unlikely to be inlined // if (useDefaultValue) { call.EmitPredefined(ec, NullableInfo.GetGetValueOrDefault(expr.Type), null); } else { call.EmitPredefined(ec, NullableInfo.GetValue(expr.Type), null); } }