Inheritance: HoistedStoreyClass
Example #1
0
		public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
		{
			foreach (Argument a in arguments)
				a.Expr.MutateHoistedGenericType (storey);

			mg.MutateHoistedGenericType (storey);
		}
Example #2
0
		public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
		{
			expr.MutateHoistedGenericType (storey);
		}
Example #3
0
		public HoistedLocalVariable (AnonymousMethodStorey storey, LocalVariable local, string name)
			: base (storey, name, local.Type)
		{
		}
Example #4
0
		protected HoistedVariable (AnonymousMethodStorey storey, Field field)
		{
			this.storey = storey;
			this.field = field;
		}
Example #5
0
		//
		// Returns a field which holds referenced storey instance
		//
		Field GetReferencedStoreyField (AnonymousMethodStorey storey)
		{
			if (used_parent_storeys == null)
				return null;

			foreach (StoreyFieldPair sf in used_parent_storeys) {
				if (sf.Storey == storey)
					return sf.Field;
			}

			return null;
		}
Example #6
0
		public void AddParentStoreyReference (EmitContext ec, AnonymousMethodStorey storey)
		{
			CheckMembersDefined ();

			if (used_parent_storeys == null)
				used_parent_storeys = new List<StoreyFieldPair> ();
			else if (used_parent_storeys.Exists (i => i.Storey == storey))
				return;

			TypeExpr type_expr = storey.CreateStoreyTypeExpression (ec);
			Field f = AddCompilerGeneratedField ("<>f__ref$" + storey.ID, type_expr);
			used_parent_storeys.Add (new StoreyFieldPair (storey, f));
		}
Example #7
0
		//
		// Creates a host for the anonymous method
		//
		AnonymousMethodMethod DoCreateMethodHost (EmitContext ec)
		{
			//
			// Anonymous method body can be converted to
			//
			// 1, an instance method in current scope when only `this' is hoisted
			// 2, a static method in current scope when neither `this' nor any variable is hoisted
			// 3, an instance method in compiler generated storey when any hoisted variable exists
			//

			Modifiers modifiers;
			TypeDefinition parent = null;

			var src_block = Block.Original.Explicit;
			if (src_block.HasCapturedVariable || src_block.HasCapturedThis) {
				parent = storey = FindBestMethodStorey ();

				if (storey == null) {
					var sm = src_block.ParametersBlock.TopBlock.StateMachine;

					//
					// Remove hoisted this demand when simple instance method is enough (no hoisted variables only this)
					//
					if (src_block.HasCapturedThis && src_block.ParametersBlock.StateMachine == null) {
						src_block.ParametersBlock.TopBlock.RemoveThisReferenceFromChildrenBlock (src_block);

						//
						// Special case where parent class is used to emit instance method
						// because currect storey is of value type (async host) and we don't
						// want to create another childer storey to host this reference only
						//
						if (sm != null && sm.Kind == MemberKind.Struct)
							parent = sm.Parent.PartialContainer;
					}

					//
					// For iterators we can host everything in one class
					//
					if (sm is IteratorStorey)
						parent = storey = sm;
				}

				modifiers = storey != null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
			} else {
				if (ec.CurrentAnonymousMethod != null)
					parent = storey = ec.CurrentAnonymousMethod.Storey;

				modifiers = Modifiers.STATIC | Modifiers.PRIVATE;
			}

			if (parent == null)
				parent = ec.CurrentTypeDefinition.Parent.PartialContainer;

			string name = CompilerGeneratedContainer.MakeName (parent != storey ? block_name : null,
				"m", null, ec.Module.CounterAnonymousMethods++);

			MemberName member_name;
			if (storey == null && ec.CurrentTypeParameters != null) {

				var hoisted_tparams = ec.CurrentTypeParameters;
				var type_params = new TypeParameters (hoisted_tparams.Count);
				for (int i = 0; i < hoisted_tparams.Count; ++i) {
				    type_params.Add (hoisted_tparams[i].CreateHoistedCopy (null));
				}

				member_name = new MemberName (name, type_params, Location);
			} else {
				member_name = new MemberName (name, Location);
			}

			return new AnonymousMethodMethod (parent,
				this, storey, new TypeExpression (ReturnType, Location), modifiers,
				member_name, parameters);
		}
Example #8
0
		public void AddCapturedThisField (EmitContext ec, AnonymousMethodStorey parent)
		{
			TypeExpr type_expr = new TypeExpression (ec.CurrentType, Location);
			Field f = AddCompilerGeneratedField ("$this", type_expr);
			hoisted_this = new HoistedThis (this, f);

			initialize_hoisted_this = true;
			hoisted_this_parent = parent;
		}
Example #9
0
		public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
		{
			if (InstanceExpression != null)
				InstanceExpression.MutateHoistedGenericType (storey);

			type = storey.MutateType (type);
			if (getter != null)
				getter = storey.MutateGenericMethod (getter);
			if (setter != null)
				setter = storey.MutateGenericMethod (setter);
		}
Example #10
0
		public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
		{
			FieldInfo = storey.MutateField (FieldInfo);
			base.MutateHoistedGenericType (storey);
		}		
Example #11
0
		public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
		{
			base.MutateHoistedGenericType (storey);

			MethodInfo mi = best_candidate as MethodInfo;
			if (mi != null) {
				best_candidate = storey.MutateGenericMethod (mi);
				return;
			}

			best_candidate = storey.MutateConstructor ((ConstructorInfo) this);
		}
Example #12
0
		public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
		{
			extension_argument.Expr.MutateHoistedGenericType (storey);
			base.MutateHoistedGenericType (storey);
		}
Example #13
0
		public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
		{
			if (InstanceExpression != null)
				InstanceExpression.MutateHoistedGenericType (storey);
		}
Example #14
0
		public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
		{
			type = storey.MutateType (type);
		}
Example #15
0
		public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
		{
			throw new NotSupportedException ();
		}
Example #16
0
		//
		// Creates a host for the anonymous method
		//
		AnonymousMethodMethod DoCreateMethodHost (EmitContext ec)
		{
			//
			// Anonymous method body can be converted to
			//
			// 1, an instance method in current scope when only `this' is hoisted
			// 2, a static method in current scope when neither `this' nor any variable is hoisted
			// 3, an instance method in compiler generated storey when any hoisted variable exists
			//

			Modifiers modifiers;
			TypeDefinition parent = null;

			var src_block = Block.Original.Explicit;
			if (src_block.HasCapturedVariable || src_block.HasCapturedThis) {
				parent = storey = FindBestMethodStorey ();

				if (storey == null) {
					var top_block = src_block.ParametersBlock.TopBlock;
					var sm = top_block.StateMachine;

					if (src_block.HasCapturedThis) {
						//
						// Remove hoisted 'this' request when simple instance method is
						// enough. No hoisted variables only 'this' and don't need to
						// propagate this to value type state machine.
						//
						StateMachine sm_parent;
						var pb = src_block.ParametersBlock;
						do {
							sm_parent = pb.StateMachine;
							pb = pb.Parent == null ? null : pb.Parent.ParametersBlock;
						} while (sm_parent == null && pb != null);

						if (sm_parent == null) {
							top_block.RemoveThisReferenceFromChildrenBlock (src_block);
						} else if (sm_parent.Kind == MemberKind.Struct) {
							//
							// Special case where parent class is used to emit instance method
							// because currect storey is of value type (async host) and we cannot
							// use ldftn on non-boxed instances either to share mutated state
							//
							parent = sm_parent.Parent.PartialContainer;
						} else if (sm is IteratorStorey) {
							//
							// For iterators we can host everything in one class
							//
							parent = storey = sm;
						}
					}
				}

				modifiers = storey != null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
			} else {
				if (ec.CurrentAnonymousMethod != null)
					parent = storey = ec.CurrentAnonymousMethod.Storey;

				modifiers = Modifiers.STATIC | Modifiers.PRIVATE;
			}

			if (parent == null)
				parent = ec.CurrentTypeDefinition.Parent.PartialContainer;

			string name = CompilerGeneratedContainer.MakeName (parent != storey ? block_name : null,
				"m", null, parent.PartialContainer.CounterAnonymousMethods++);

			MemberName member_name;
			if (storey == null && ec.CurrentTypeParameters != null) {

				var hoisted_tparams = ec.CurrentTypeParameters;
				var type_params = new TypeParameters (hoisted_tparams.Count);
				for (int i = 0; i < hoisted_tparams.Count; ++i) {
				    type_params.Add (hoisted_tparams[i].CreateHoistedCopy (null));
				}

				member_name = new MemberName (name, type_params, Location);
			} else {
				member_name = new MemberName (name, Location);
			}

			return new AnonymousMethodMethod (parent,
				this, storey, new TypeExpression (ReturnType, Location), modifiers,
				member_name, parameters);
		}
Example #17
0
			public ThisInitializer (HoistedThis hoisted_this, AnonymousMethodStorey parent)
			{
				this.hoisted_this = hoisted_this;
				this.parent = parent;
			}
Example #18
0
		//
		// Creates anonymous method storey in current block
		//
		public AnonymousMethodStorey CreateAnonymousMethodStorey (ResolveContext ec)
		{
			//
			// When referencing a variable in iterator storey from children anonymous method
			//
			if (Toplevel.am_storey is IteratorStorey) {
				return Toplevel.am_storey;
			}

			//
			// An iterator has only 1 storey block
			//
			if (ec.CurrentIterator != null)
			    return ec.CurrentIterator.Storey;

			if (am_storey == null) {
				MemberBase mc = ec.MemberContext as MemberBase;
				GenericMethod gm = mc == null ? null : mc.GenericMethod;

				//
				// Creates anonymous method storey for this block
				//
				am_storey = new AnonymousMethodStorey (this, ec.CurrentMemberDefinition.Parent.PartialContainer, mc, gm, "AnonStorey");
			}

			return am_storey;
		}
Example #19
0
			public AnonymousMethodMethod (TypeDefinition parent, AnonymousExpression am, AnonymousMethodStorey storey,
							  TypeExpr return_type,
							  Modifiers mod, MemberName name,
							  ParametersCompiled parameters)
				: base (parent, return_type, mod | Modifiers.COMPILER_GENERATED,
						name, parameters, null)
			{
				this.AnonymousMethod = am;
				this.Storey = storey;

				Parent.PartialContainer.Members.Add (this);
				Block = new ToplevelBlock (am.block, parameters);
			}
Example #20
0
		//
		// Creates anonymous method storey in current block
		//
		public AnonymousMethodStorey CreateAnonymousMethodStorey (ResolveContext ec)
		{
			//
			// An iterator has only 1 storey block
			//
			if (ec.CurrentIterator != null)
			    return ec.CurrentIterator.Storey;

			//
			// When referencing a variable in iterator storey from children anonymous method
			//
			if (ParametersBlock.am_storey is IteratorStorey) {
				return ParametersBlock.am_storey;
			}

			if (am_storey == null) {
				MemberBase mc = ec.MemberContext as MemberBase;

				//
				// Creates anonymous method storey for this block
				//
				am_storey = new AnonymousMethodStorey (this, ec.CurrentMemberDefinition.Parent.PartialContainer, mc, ec.CurrentTypeParameters, "AnonStorey");
			}

			return am_storey;
		}
Example #21
0
			public StoreyFieldPair (AnonymousMethodStorey storey, Field field)
			{
				this.Storey = storey;
				this.Field = field;
			}
Example #22
0
		public HoistedLocalVariable (AnonymousMethodStorey scope, LocalInfo local, string name)
			: base (scope, name, local.VariableType)
		{
			this.name = local.Name;
		}
Example #23
0
		public void SetNestedStoryParent (AnonymousMethodStorey parentStorey)
		{
			Parent = parentStorey;
			spec.IsGeneric = false;
			spec.DeclaringType = parentStorey.CurrentType;
			MemberName.TypeParameters = null;
		}
Example #24
0
			public AnonymousMethodMethod (DeclSpace parent, AnonymousExpression am, AnonymousMethodStorey storey,
							  GenericMethod generic, TypeExpr return_type,
							  Modifiers mod, string real_name, MemberName name,
							  ParametersCompiled parameters)
				: base (parent, generic, return_type, mod | Modifiers.COMPILER_GENERATED,
						name, parameters, null)
			{
				this.AnonymousMethod = am;
				this.Storey = storey;
				this.RealName = real_name;

				Parent.PartialContainer.AddMethod (this);
				Block = new ToplevelBlock (am.block, parameters);
			}
Example #25
0
		protected HoistedVariable (AnonymousMethodStorey storey, string name, TypeSpec type)
			: this (storey, storey.AddCapturedVariable (name, type))
		{
		}
Example #26
0
		//
		// Creates a host for the anonymous method
		//
		AnonymousMethodMethod DoCreateMethodHost (EmitContext ec)
		{
			//
			// Anonymous method body can be converted to
			//
			// 1, an instance method in current scope when only `this' is hoisted
			// 2, a static method in current scope when neither `this' nor any variable is hoisted
			// 3, an instance method in compiler generated storey when any hoisted variable exists
			//

			Modifiers modifiers;
			if (Block.HasCapturedVariable || Block.HasCapturedThis) {
				storey = FindBestMethodStorey ();
				modifiers = storey != null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
			} else {
				if (ec.CurrentAnonymousMethod != null)
					storey = ec.CurrentAnonymousMethod.Storey;

				modifiers = Modifiers.STATIC | Modifiers.PRIVATE;
			}

			TypeContainer parent = storey != null ? storey : ec.CurrentTypeDefinition.Parent.PartialContainer;

			MemberCore mc = ec.MemberContext as MemberCore;
			string name = CompilerGeneratedClass.MakeName (parent != storey ? block_name : null,
				"m", null, unique_id++);

			MemberName member_name;
			if (storey == null && ec.CurrentTypeParameters != null) {

				var hoisted_tparams = ec.CurrentTypeParameters;
				var type_params = new TypeParameters (hoisted_tparams.Count);
				for (int i = 0; i < hoisted_tparams.Count; ++i) {
				    type_params.Add (hoisted_tparams[i].CreateHoistedCopy (null));
				}

				member_name = new MemberName (name, type_params, Location);
			} else {
				member_name = new MemberName (name, Location);
			}

			string real_name = String.Format (
				"{0}~{1}{2}", mc.GetSignatureForError (), GetSignatureForError (),
				parameters.GetSignatureForError ());

			return new AnonymousMethodMethod (parent,
				this, storey, new TypeExpression (ReturnType, Location), modifiers,
				real_name, member_name, parameters);
		}
Example #27
0
		public HoistedParameter (AnonymousMethodStorey scope, ParameterReference par)
			: base (scope, par.Name, par.Type)
		{
			this.parameter = par;
		}
Example #28
0
		//
		// For compiler generated local variables
		//
		public HoistedLocalVariable (AnonymousMethodStorey storey, Field field)
			: base (storey, field)
		{
		}
Example #29
0
		public HoistedThis (AnonymousMethodStorey storey, Field field)
			: base (storey, field)
		{
		}
		public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
		{
			// A constant cannot be of generic type
		}