protected override void DoEmit(EmitContext ec) { for (int i = 0; i < fields.Length; ++i) { var field = fields[i]; if (field == null) { continue; } ec.EmitArgumentLoad(thisParameterIndex); ec.EmitArgumentLoad(i); if (parametersTypes[i] is ReferenceContainer) { ec.EmitLoadFromPtr(field.MemberType); } ec.Emit(OpCodes.Stfld, field); } }
public void Emit(EmitContext ec, bool conditionalAccess) { Label NullOperatorLabel; Nullable.Unwrap unwrap; if (conditionalAccess && Expression.IsNeverNull(instance)) { conditionalAccess = false; } if (conditionalAccess) { NullOperatorLabel = ec.DefineLabel(); unwrap = instance as Nullable.Unwrap; } else { NullOperatorLabel = new Label(); unwrap = null; } IMemoryLocation instance_address = null; bool conditional_access_dup = false; if (unwrap != null) { unwrap.Store(ec); unwrap.EmitCheck(ec); ec.Emit(OpCodes.Brtrue_S, NullOperatorLabel); } else { if (conditionalAccess && addressRequired) { // // Don't allocate temp variable when instance load is cheap and load and load-address // operate on same memory // instance_address = instance as VariableReference; if (instance_address == null) { instance_address = instance as LocalTemporary; } if (instance_address == null) { EmitLoad(ec, false); ec.Emit(OpCodes.Dup); ec.EmitLoadFromPtr(instance.Type); conditional_access_dup = true; } else { instance.Emit(ec); } } else { EmitLoad(ec, !conditionalAccess); if (conditionalAccess) { conditional_access_dup = !IsInexpensiveLoad(); if (conditional_access_dup) { ec.Emit(OpCodes.Dup); } } } if (conditionalAccess) { if (instance.Type.Kind == MemberKind.TypeParameter) { ec.Emit(OpCodes.Box, instance.Type); } ec.Emit(OpCodes.Brtrue_S, NullOperatorLabel); if (conditional_access_dup) { ec.Emit(OpCodes.Pop); } } } if (conditionalAccess) { if (!ec.ConditionalAccess.Statement) { if (ec.ConditionalAccess.Type.IsNullableType) { Nullable.LiftedNull.Create(ec.ConditionalAccess.Type, Location.Null).Emit(ec); } else { ec.EmitNull(); } } ec.Emit(OpCodes.Br, ec.ConditionalAccess.EndLabel); ec.MarkLabel(NullOperatorLabel); if (instance_address != null) { instance_address.AddressOf(ec, AddressOp.Load); } else if (unwrap != null) { unwrap.Emit(ec); var tmp = ec.GetTemporaryLocal(unwrap.Type); ec.Emit(OpCodes.Stloc, tmp); ec.Emit(OpCodes.Ldloca, tmp); ec.FreeTemporaryLocal(tmp, unwrap.Type); } else if (!conditional_access_dup) { instance.Emit(ec); } } }
public void Emit (EmitContext ec, bool conditionalAccess) { Label NullOperatorLabel; Nullable.Unwrap unwrap; if (conditionalAccess && Expression.IsNeverNull (instance)) conditionalAccess = false; if (conditionalAccess) { NullOperatorLabel = ec.DefineLabel (); unwrap = instance as Nullable.Unwrap; } else { NullOperatorLabel = new Label (); unwrap = null; } IMemoryLocation instance_address = null; bool conditional_access_dup = false; if (unwrap != null) { unwrap.Store (ec); unwrap.EmitCheck (ec); ec.Emit (OpCodes.Brtrue_S, NullOperatorLabel); } else { if (conditionalAccess && addressRequired) { // // Don't allocate temp variable when instance load is cheap and load and load-address // operate on same memory // instance_address = instance as VariableReference; if (instance_address == null) instance_address = instance as LocalTemporary; if (instance_address == null) { EmitLoad (ec, false); ec.Emit (OpCodes.Dup); ec.EmitLoadFromPtr (instance.Type); conditional_access_dup = true; } else { instance.Emit (ec); } } else { EmitLoad (ec, !conditionalAccess); if (conditionalAccess) { conditional_access_dup = !IsInexpensiveLoad (); if (conditional_access_dup) ec.Emit (OpCodes.Dup); } } if (conditionalAccess) { if (instance.Type.Kind == MemberKind.TypeParameter) ec.Emit (OpCodes.Box, instance.Type); ec.Emit (OpCodes.Brtrue_S, NullOperatorLabel); if (conditional_access_dup) ec.Emit (OpCodes.Pop); } } if (conditionalAccess) { if (!ec.ConditionalAccess.Statement) { if (ec.ConditionalAccess.Type.IsNullableType) Nullable.LiftedNull.Create (ec.ConditionalAccess.Type, Location.Null).Emit (ec); else ec.EmitNull (); } ec.Emit (OpCodes.Br, ec.ConditionalAccess.EndLabel); ec.MarkLabel (NullOperatorLabel); if (instance_address != null) { instance_address.AddressOf (ec, AddressOp.Load); } else if (unwrap != null) { unwrap.Emit (ec); var tmp = ec.GetTemporaryLocal (unwrap.Type); ec.Emit (OpCodes.Stloc, tmp); ec.Emit (OpCodes.Ldloca, tmp); ec.FreeTemporaryLocal (tmp, unwrap.Type); } else if (!conditional_access_dup) { instance.Emit (ec); } } }
public void Emit(EmitContext ec, bool leave_copy) { bool is_volatile = false; if ((spec.Modifiers & Modifiers.VOLATILE) != 0) is_volatile = true; spec.MemberDefinition.SetIsUsed (); if (IsStatic){ if (is_volatile) ec.Emit (OpCodes.Volatile); ec.Emit (OpCodes.Ldsfld, spec); } else { if (!prepared) EmitInstance (ec, false); // Optimization for build-in types if (TypeManager.IsStruct (type) && TypeManager.IsEqual (type, ec.MemberContext.CurrentType) && TypeManager.IsEqual (InstanceExpression.Type, type)) { ec.EmitLoadFromPtr (type); } else { var ff = spec as FixedFieldSpec; if (ff != null) { ec.Emit (OpCodes.Ldflda, spec); ec.Emit (OpCodes.Ldflda, ff.Element); } else { if (is_volatile) ec.Emit (OpCodes.Volatile); ec.Emit (OpCodes.Ldfld, spec); } } } if (leave_copy) { ec.Emit (OpCodes.Dup); if (!IsStatic) { temp = new LocalTemporary (this.Type); temp.Store (ec); } } }
public override void Emit(EmitContext ec) { Expression argExp; TypeSpec typeSpec; switch (mg.Name) { case "Emit": if (arguments.Count == 1) { ec.Emit(opcode); } break; case "Load": argExp = arguments [0].Expr; if (argExp is BoxedCast) { argExp = ((BoxedCast)argExp).Child; } argExp.Emit(ec); break; case "LoadAddr": argExp = arguments [0].Expr; if (argExp is BoxedCast) { argExp = ((BoxedCast)argExp).Child; } var memloc = argExp as IMemoryLocation; memloc.AddressOf(ec, AddressOp.Load | AddressOp.Store); break; case "LoadInd": if ((bool)(arguments [1].Expr as BoolConstant).GetValue()) { ec.Emit(OpCodes.Dup); } typeSpec = ((TypeOf)arguments [0].Expr).TypeArgument; ec.EmitLoadFromPtr(typeSpec); break; case "Store": argExp = arguments [0].Expr; if (argExp is BoxedCast) { argExp = ((BoxedCast)argExp).Child; } var t = argExp as IAssignMethod; t.EmitAssign(ec, _dummyExpr, (bool)(arguments [1].Expr as BoolConstant).GetValue(), false); break; case "StoreInd": if ((bool)(arguments [1].Expr as BoolConstant).GetValue()) { ec.Emit(OpCodes.Dup); } typeSpec = ((TypeOf)arguments [0].Expr).TypeArgument; ec.EmitStoreFromPtr(typeSpec); break; } }
public override void Emit (EmitContext ec) { Expression argExp; TypeSpec typeSpec; switch (mg.Name) { case "Emit": if (arguments.Count == 1) { ec.Emit (opcode); } break; case "Load": argExp = arguments [0].Expr; if (argExp is BoxedCast) argExp = ((BoxedCast)argExp).Child; argExp.Emit (ec); break; case "LoadAddr": argExp = arguments [0].Expr; if (argExp is BoxedCast) argExp = ((BoxedCast)argExp).Child; var memloc = argExp as IMemoryLocation; memloc.AddressOf (ec, AddressOp.Load | AddressOp.Store); break; case "LoadInd": if ((bool)(arguments [1].Expr as BoolConstant).GetValue ()) ec.Emit (OpCodes.Dup); typeSpec = ((TypeOf)arguments [0].Expr).TypeArgument; ec.EmitLoadFromPtr (typeSpec); break; case "Store": argExp = arguments [0].Expr; if (argExp is BoxedCast) argExp = ((BoxedCast)argExp).Child; var t = argExp as IAssignMethod; t.EmitAssign (ec, _dummyExpr, (bool)(arguments [1].Expr as BoolConstant).GetValue (), false); break; case "StoreInd": if ((bool)(arguments [1].Expr as BoolConstant).GetValue ()) ec.Emit (OpCodes.Dup); typeSpec = ((TypeOf)arguments [0].Expr).TypeArgument; ec.EmitStoreFromPtr (typeSpec); break; } }