public override bool Define() { if (!base.Define()) { return(false); } // SYNC_MOD_CTRL if ((ModFlags & Modifiers.SYNC) == Modifiers.SYNC) { Report.Error(3661, Location, "A sync modifier cannot be used in field declaration. "); } MetaType[] required_modifier = null; if ((ModFlags & Modifiers.VOLATILE) != 0) { var mod = Module.PredefinedTypes.IsVolatile.Resolve(); if (mod != null) { required_modifier = new MetaType[] { mod.GetMetaInfo() } } ; } FieldBuilder = Parent.TypeBuilder.DefineField( Name, member_type.GetMetaInfo(), required_modifier, null, ModifiersExtensions.FieldAttr(ModFlags)); spec = new FieldSpec(Parent.Definition, this, MemberType, FieldBuilder, ModFlags); // // Don't cache inaccessible fields except for struct where we // need them for definitive assignment checks // if ((ModFlags & Modifiers.BACKING_FIELD) == 0 || Parent.Kind == MemberKind.Struct) { Parent.MemberCache.AddMember(spec); } if (initializer != null) { Parent.RegisterFieldForInitialization(this, new FieldInitializer(this, initializer, TypeExpression.Location)); } if (declarators != null) { foreach (var d in declarators) { var f = new Field(Parent, d.GetFieldTypeExpression(this), ModFlags, new MemberName(d.Name.Value, d.Name.Location), OptAttributes); if (d.Initializer != null) { f.initializer = d.Initializer; } f.Define(); Parent.PartialContainer.Members.Add(f); } } return(true); }
static Field CreateSiteField(FullNamedExpression type) { TypeContainer site_container = CreateSiteContainer(); Field f = new Field(site_container, type, Modifiers.PUBLIC | Modifiers.STATIC, new MemberName("Site" + field_counter++), null); f.Define(); site_container.AddField(f); return(f); }
protected override Expression DoResolve(ResolveContext ec) { var expr = base.DoResolve(ec); if (expr == null) { return(null); } if (ec.IsInProbingMode) { return(expr); } // // Cache any static delegate creation // if (method_group.InstanceExpression != null) { return(expr); } // // Cannot easily cache types with MVAR // if (ContainsMethodTypeParameter(type)) { return(expr); } if (ContainsMethodTypeParameter(method_group.BestCandidate.DeclaringType)) { return(expr); } // // Create type level cache for a delegate instance // var parent = ec.CurrentMemberDefinition.Parent.PartialContainer; int id = parent.MethodGroupsCounter++; mg_cache = new Field(parent, new TypeExpression(type, loc), Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, new MemberName(CompilerGeneratedContainer.MakeName(null, "f", "mg$cache", id), loc), null); mg_cache.Define(); parent.AddField(mg_cache); return(expr); }
override public Expression DoResolveLValue(EmitContext ec, Expression right_side) { Expression ret = base.DoResolveLValue(ec, right_side); if (ret == null) { return(null); } Field f = new Field(container, new TypeExpression(ret.Type, Location), Modifiers.PUBLIC | Modifiers.STATIC, new MemberName(name, Location), null); container.AddField(f); if (f.Define()) { Evaluator.QueueField(f); } return(ret); }
static Field CreateSiteField(FullNamedExpression type) { TypeContainer site_container = CreateSiteContainer (); Field f = new Field (site_container, type, Modifiers.PUBLIC | Modifiers.STATIC, new MemberName ("Site" + field_counter++), null); f.Define (); site_container.AddField (f); return f; }
protected override Expression DoResolve (ResolveContext ec) { var expr = base.DoResolve (ec); if (expr == null) return ErrorExpression.Instance; if (ec.IsInProbingMode) return expr; // // Cache any static delegate creation // if (method_group.InstanceExpression != null) return expr; // // Cannot easily cache types with MVAR // if (!HasMvar ()) return expr; // // Create type level cache for a delegate instance // var parent = ec.CurrentMemberDefinition.Parent.PartialContainer; int id = parent.MethodGroupsCounter++; mg_cache = new Field (parent, new TypeExpression (type, loc), Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, new MemberName (CompilerGeneratedContainer.MakeName (null, "f", "mg$cache", id), loc), null); mg_cache.Define (); parent.AddField (mg_cache); return expr; }
public override bool Define() { if (!base.Define ()) return false; if (declarators != null) { var t = new TypeExpression (MemberType, TypeExpression.Location); int index = Parent.PartialContainer.Events.IndexOf (this); foreach (var d in declarators) { var ef = new EventField (Parent, t, ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes); if (d.Initializer != null) ef.initializer = d.Initializer; Parent.PartialContainer.Events.Insert (++index, ef); } } if (!HasBackingField) { SetIsUsed (); return true; } if (Add.IsInterfaceImplementation) SetIsUsed (); backing_field = new Field (Parent, new TypeExpression (MemberType, Location), Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)), MemberName, null); Parent.PartialContainer.AddField (backing_field); backing_field.Initializer = Initializer; backing_field.ModFlags &= ~Modifiers.COMPILER_GENERATED; // Call define because we passed fields definition backing_field.Define (); // Set backing field for event fields spec.BackingField = backing_field.Spec; return true; }
void CreateAutomaticProperty () { // Create backing field backing_field = new BackingField (this); if (!backing_field.Define ()) return; Parent.PartialContainer.Members.Add (backing_field); FieldExpr fe = new FieldExpr (backing_field, Location); if ((backing_field.ModFlags & Modifiers.STATIC) == 0) fe.InstanceExpression = new CompilerGeneratedThis (Parent.CurrentType, Location); // // Create get block but we careful with location to // emit only single sequence point per accessor. This allow // to set a breakpoint on it even with no user code // Get.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location.Null); Return r = new Return (fe, Get.Location); Get.Block.AddStatement (r); // Create set block Set.Block = new ToplevelBlock (Compiler, Set.ParameterInfo, Location.Null); Assign a = new SimpleAssign (fe, new SimpleName ("value", Location.Null), Location.Null); Set.Block.AddStatement (new StatementExpression (a, Set.Location)); }
void ResolveStringSwitchMap (ResolveContext ec) { FullNamedExpression string_dictionary_type; if (TypeManager.generic_ienumerable_type != null) { MemberAccess system_collections_generic = new MemberAccess (new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Collections", loc), "Generic", loc); string_dictionary_type = new MemberAccess (system_collections_generic, "Dictionary", new TypeArguments ( new TypeExpression (TypeManager.string_type, loc), new TypeExpression (TypeManager.int32_type, loc)), loc); } else { MemberAccess system_collections_generic = new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Collections", loc); string_dictionary_type = new MemberAccess (system_collections_generic, "Hashtable", loc); } var ctype = ec.CurrentMemberDefinition.Parent.PartialContainer; Field field = new Field (ctype, string_dictionary_type, Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, new MemberName (CompilerGeneratedClass.MakeName (null, "f", "switch$map", unique_counter++), loc), null); if (!field.Define ()) return; ctype.AddField (field); var init = new List<Expression> (); int counter = 0; Elements.Clear (); string value = null; foreach (SwitchSection section in Sections) { int last_count = init.Count; foreach (SwitchLabel sl in section.Labels) { if (sl.Label == null || sl.Converted == SwitchLabel.NullStringCase) continue; value = (string) sl.Converted; var init_args = new List<Expression> (2); init_args.Add (new StringLiteral (value, sl.Location)); init_args.Add (new IntConstant (counter, loc)); init.Add (new CollectionElementInitializer (init_args, loc)); } // // Don't add empty sections // if (last_count == init.Count) continue; Elements.Add (counter, section.Labels [0]); ++counter; } Arguments args = new Arguments (1); args.Add (new Argument (new IntConstant (init.Count, loc))); Expression initializer = new NewInitialize (string_dictionary_type, args, new CollectionOrObjectInitializers (init, loc), loc); switch_cache_field = new FieldExpr (field, loc); string_dictionary = new SimpleAssign (switch_cache_field, initializer.Resolve (ec)); }
public override bool Define () { if (!base.Define ()) return false; MetaType[] required_modifier = null; if ((ModFlags & Modifiers.VOLATILE) != 0) { var mod = Module.PredefinedTypes.IsVolatile.Resolve (); if (mod != null) required_modifier = new MetaType[] { mod.GetMetaInfo () }; } FieldBuilder = Parent.TypeBuilder.DefineField ( Name, member_type.GetMetaInfo (), required_modifier, null, ModifiersExtensions.FieldAttr (ModFlags)); spec = new FieldSpec (Parent.Definition, this, MemberType, FieldBuilder, ModFlags); // // Don't cache inaccessible fields except for struct where we // need them for definitive assignment checks // if ((ModFlags & Modifiers.BACKING_FIELD) == 0 || Parent.Kind == MemberKind.Struct) { Parent.MemberCache.AddMember (spec); } if (initializer != null) { Parent.RegisterFieldForInitialization (this, new FieldInitializer (this, initializer, TypeExpression.Location)); } if (declarators != null) { foreach (var d in declarators) { var t = new TypeExpression (MemberType, d.Name.Location); var f = new Field (Parent, t, ModFlags, new MemberName (d.Name.Value, d.Name.Location), OptAttributes); if (d.Initializer != null) f.initializer = d.Initializer; f.Define (); Parent.PartialContainer.Members.Add (f); } } return true; }
public override Expression DoResolveLValue(ResolveContext ec, Expression right_side) { Expression ret = base.DoResolveLValue (ec, right_side); if (ret == null) return null; Field f = new Field (container, new TypeExpression (ret.Type, Location), Modifiers.PUBLIC | Modifiers.STATIC, new MemberName (name, Location), null); container.AddField (f); if (f.Define ()) Evaluator.QueueField (f); return ret; }
public override void Emit (EmitContext ec) { // // Use same anonymous method implementation for scenarios where same // code is used from multiple blocks, e.g. field initializers // if (method == null) { // // Delay an anonymous method definition to avoid emitting unused code // for unreachable blocks or expression trees // method = DoCreateMethodHost (ec); method.Define (); } bool is_static = (method.ModFlags & Modifiers.STATIC) != 0; if (is_static && am_cache == null) { // // Creates a field cache to store delegate instance if it's not generic // if (!method.MemberName.IsGeneric) { TypeContainer parent = method.Parent.PartialContainer; int id = parent.Fields == null ? 0 : parent.Fields.Count; am_cache = new Field (parent, new TypeExpression (type, loc), Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, new MemberName (CompilerGeneratedClass.MakeName (null, "f", "am$cache", id), loc), null); am_cache.Define (); parent.AddField (am_cache); } else { // TODO: Implement caching of generated generic static methods // // Idea: // // Some extra class is needed to capture variable generic type // arguments. Maybe we could re-use anonymous types, with a unique // anonymous method id, but they are quite heavy. // // Consider : "() => typeof(T);" // // We need something like // static class Wrap<Tn, Tm, DelegateType> { // public static DelegateType cache; // } // // We then specialize local variable to capture all generic parameters // and delegate type, e.g. "Wrap<Ta, Tb, DelegateTypeInst> cache;" // } } ILGenerator ig = ec.ig; Label l_initialized = ig.DefineLabel (); if (am_cache != null) { ig.Emit (OpCodes.Ldsfld, am_cache.FieldBuilder); ig.Emit (OpCodes.Brtrue_S, l_initialized); } // // Load method delegate implementation // if (is_static) { ig.Emit (OpCodes.Ldnull); } else if (storey != null) { Expression e = storey.GetStoreyInstanceExpression (ec).Resolve (new ResolveContext (ec.MemberContext)); if (e != null) e.Emit (ec); } else { ig.Emit (OpCodes.Ldarg_0); } MethodInfo delegate_method = method.MethodBuilder; if (storey != null && storey.MemberName.IsGeneric) { Type t = storey.Instance.Type; // // Mutate anonymous method instance type if we are in nested // hoisted generic anonymous method storey // if (ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.Storey != null && ec.CurrentAnonymousMethod.Storey.IsGeneric) { t = storey.GetGenericStorey ().MutateType (t); } #if GMCS_SOURCE delegate_method = TypeBuilder.GetMethod (t, delegate_method); #else throw new NotSupportedException (); #endif } ig.Emit (OpCodes.Ldftn, delegate_method); ConstructorInfo constructor_method = Delegate.GetConstructor (RootContext.ToplevelTypes.Compiler, ec.CurrentType, type); #if MS_COMPATIBLE if (type.IsGenericType && type is TypeBuilder) constructor_method = TypeBuilder.GetConstructor (type, constructor_method); #endif ig.Emit (OpCodes.Newobj, constructor_method); if (am_cache != null) { ig.Emit (OpCodes.Stsfld, am_cache.FieldBuilder); ig.MarkLabel (l_initialized); ig.Emit (OpCodes.Ldsfld, am_cache.FieldBuilder); } }
void ResolveStringSwitchMap (EmitContext ec) { FullNamedExpression string_dictionary_type; #if GMCS_SOURCE MemberAccess system_collections_generic = new MemberAccess (new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Collections", loc), "Generic", loc); string_dictionary_type = new MemberAccess (system_collections_generic, "Dictionary", new TypeArguments ( new TypeExpression (TypeManager.string_type, loc), new TypeExpression (TypeManager.int32_type, loc)), loc); #else MemberAccess system_collections_generic = new MemberAccess ( new QualifiedAliasMember (QualifiedAliasMember.GlobalAlias, "System", loc), "Collections", loc); string_dictionary_type = new MemberAccess (system_collections_generic, "Hashtable", loc); #endif Field field = new Field (ec.TypeContainer, string_dictionary_type, Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, new MemberName (CompilerGeneratedClass.MakeName (null, "f", "switch$map", unique_counter++), loc), null); if (!field.Define ()) return; ec.TypeContainer.PartialContainer.AddField (field); ArrayList init = new ArrayList (); int counter = 0; Elements.Clear (); string value = null; foreach (SwitchSection section in Sections) { foreach (SwitchLabel sl in section.Labels) { if (sl.Label == null || sl.Converted == SwitchLabel.NullStringCase) { value = null; continue; } value = (string) sl.Converted; ArrayList init_args = new ArrayList (2); init_args.Add (new StringLiteral (value, sl.Location)); init_args.Add (new IntConstant (counter, loc)); init.Add (new CollectionElementInitializer (init_args, loc)); } if (value == null) continue; Elements.Add (counter, section.Labels [0]); ++counter; } ArrayList args = new ArrayList (1); args.Add (new Argument (new IntConstant (Sections.Count, loc))); Expression initializer = new NewInitialize (string_dictionary_type, args, new CollectionOrObjectInitializers (init, loc), loc); switch_cache_field = new FieldExpr (field.FieldBuilder, loc); string_dictionary = new SimpleAssign (switch_cache_field, initializer.Resolve (ec)); }
public override bool Define() { if (!base.Define ()) return false; if (Initializer != null && (ModFlags & Modifiers.ABSTRACT) != 0) { Report.Error (74, Location, "`{0}': abstract event cannot have an initializer", GetSignatureForError ()); } if (!HasBackingField) { SetIsUsed (); return true; } // FIXME: We are unable to detect whether generic event is used because // we are using FieldExpr instead of EventExpr for event access in that // case. When this issue will be fixed this hack can be removed. if (TypeManager.IsGenericType (MemberType) || Parent.IsGeneric) SetIsUsed (); if (Add.IsInterfaceImplementation) SetIsUsed (); BackingField = new Field (Parent, new TypeExpression (MemberType, Location), Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)), MemberName, null); Parent.PartialContainer.AddField (BackingField); BackingField.Initializer = Initializer; BackingField.ModFlags &= ~Modifiers.COMPILER_GENERATED; // Call define because we passed fields definition return BackingField.Define (); }
public override bool Define() { var mod_flags_src = ModFlags; if (!base.Define ()) return false; if (declarators != null) { if ((mod_flags_src & Modifiers.DEFAULT_ACCESS_MODIFER) != 0) mod_flags_src &= ~(Modifiers.AccessibilityMask | Modifiers.DEFAULT_ACCESS_MODIFER); var t = new TypeExpression (MemberType, TypeExpression.Location); foreach (var d in declarators) { var ef = new EventField (Parent, t, mod_flags_src, new MemberName (d.Name.Value, d.Name.Location), OptAttributes); if (d.Initializer != null) ef.initializer = d.Initializer; ef.Define (); Parent.PartialContainer.Members.Add (ef); } } if (!HasBackingField) { SetIsUsed (); return true; } if (Add.IsInterfaceImplementation) SetIsUsed (); backing_field = new Field (Parent, new TypeExpression (MemberType, Location), Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)), MemberName, null); Parent.PartialContainer.Members.Add (backing_field); backing_field.Initializer = Initializer; backing_field.ModFlags &= ~Modifiers.COMPILER_GENERATED; // Call define because we passed fields definition backing_field.Define (); // Set backing field for event fields spec.BackingField = backing_field.Spec; return true; }
public override void Emit (EmitContext ec) { // // Use same anonymous method implementation for scenarios where same // code is used from multiple blocks, e.g. field initializers // if (method == null) { // // Delay an anonymous method definition to avoid emitting unused code // for unreachable blocks or expression trees // method = DoCreateMethodHost (ec); method.Define (); } bool is_static = (method.ModFlags & Modifiers.STATIC) != 0; if (is_static && am_cache == null) { // // Creates a field cache to store delegate instance if it's not generic // if (!method.MemberName.IsGeneric) { var parent = method.Parent.PartialContainer; int id = parent.AnonymousMethodsCounter++; var cache_type = storey != null && storey.Mutator != null ? storey.Mutator.Mutate (type) : type; am_cache = new Field (parent, new TypeExpression (cache_type, loc), Modifiers.STATIC | Modifiers.PRIVATE | Modifiers.COMPILER_GENERATED, new MemberName (CompilerGeneratedContainer.MakeName (null, "f", "am$cache", id), loc), null); am_cache.Define (); parent.AddField (am_cache); } else { // TODO: Implement caching of generated generic static methods // // Idea: // // Some extra class is needed to capture variable generic type // arguments. Maybe we could re-use anonymous types, with a unique // anonymous method id, but they are quite heavy. // // Consider : "() => typeof(T);" // // We need something like // static class Wrap<Tn, Tm, DelegateType> { // public static DelegateType cache; // } // // We then specialize local variable to capture all generic parameters // and delegate type, e.g. "Wrap<Ta, Tb, DelegateTypeInst> cache;" // } } Label l_initialized = ec.DefineLabel (); if (am_cache != null) { ec.Emit (OpCodes.Ldsfld, am_cache.Spec); ec.Emit (OpCodes.Brtrue_S, l_initialized); } // // Load method delegate implementation // if (is_static) { ec.EmitNull (); } else if (storey != null) { Expression e = storey.GetStoreyInstanceExpression (ec).Resolve (new ResolveContext (ec.MemberContext)); if (e != null) { e.Emit (ec); } } else { ec.EmitThis (); // // Special case for value type storey where this is not lifted but // droped off to parent class // for (var b = Block.Parent; b != null; b = b.Parent) { if (b.ParametersBlock.StateMachine != null) { ec.Emit (OpCodes.Ldfld, b.ParametersBlock.StateMachine.HoistedThis.Field.Spec); break; } } } var delegate_method = method.Spec; if (storey != null && storey.MemberName.IsGeneric) { TypeSpec t = storey.Instance.Type; // // Mutate anonymous method instance type if we are in nested // hoisted generic anonymous method storey // if (ec.IsAnonymousStoreyMutateRequired) { t = storey.Mutator.Mutate (t); } ec.Emit (OpCodes.Ldftn, TypeBuilder.GetMethod (t.GetMetaInfo (), (MethodInfo) delegate_method.GetMetaInfo ())); } else { if (delegate_method.IsGeneric) delegate_method = delegate_method.MakeGenericMethod (ec.MemberContext, method.TypeParameters); ec.Emit (OpCodes.Ldftn, delegate_method); } var constructor_method = Delegate.GetConstructor (type); ec.Emit (OpCodes.Newobj, constructor_method); if (am_cache != null) { ec.Emit (OpCodes.Stsfld, am_cache.Spec); ec.MarkLabel (l_initialized); ec.Emit (OpCodes.Ldsfld, am_cache.Spec); } }
void CreateEvaluatorVariable (BlockContext bc, LocalVariable li) { var container = bc.CurrentMemberDefinition.Parent; Field f = new Field (container, new TypeExpression (li.Type, li.Location), Modifiers.PUBLIC | Modifiers.STATIC, new MemberName (li.Name, li.Location), null); container.AddField (f); f.Define (); Evaluator.QueueField (f); li.HoistedVariant = new HoistedEvaluatorVariable (f); li.SetIsUsed (); }