StageValue Process() { Method.Body.Visit(this); var min = MinStage; var max = MaxStage; for (int i = 0; i < Arguments.Count; i++) { if (Arguments[i].Value.MinStage > min) { min = Arguments[i].Value.MinStage; } if (Arguments[i].Value.MaxStage < max) { max = Arguments[i].Value.MaxStage; } if (Arguments[i].Value.MinStage > MaxStage) { Log.Error(Arguments[i].Source, ErrorCode.E5009, "Cannot access " + min.Quote() + " symbol from stage " + MaxStage.Quote()); } } if (max < min) { max = min; } var pl = new List <Parameter>(); var al = new List <Expression>(); var map = new Dictionary <int, Expression>(); for (int i = 0; i < Arguments.Count; i++) { var e = Generator.ProcessStage(Arguments[i].Value, min, max).Value; if (min >= MetaStage.Vertex && Expressions.IsVariableOrGlobal(e)) { map.Add(i, e); continue; } pl.Add(new Parameter(Arguments[i].Source, AttributeList.Empty, e.ReturnType is FixedArrayType ? ParameterModifier.Ref : 0, e.ReturnType, Generator.CreateShaderName(Property, Location, Arguments[i].Value.Value), null)); al.Add(e); map.Add(i, new LoadArgument(e.Source, Method, pl.Count - 1)); } Method.SetParameters(pl.ToArray()); if (min <= MetaStage.Volatile) { // See if an equivalent method is already generated on this class scope foreach (var m in Generator.Path.DrawBlock.Method.DeclaringType.Methods) { if (m.Source == Method.Source && m.Modifiers == Method.Modifiers && m.ReturnType == Method.ReturnType && m.CompareParameters(Method)) { return(new StageValue(new CallMethod(m.Source, m.IsStatic ? null : new This(m.Source, m.DeclaringType), m, al.ToArray()), min, max)); } } Generator.Path.DrawBlock.Method.DeclaringType.Methods.Add(Method); } else { Method.SetName(Generator.CreateShaderName(Property, Location)); } Method.Body.Visit(new ArgumentResolver(this, map)); return(new StageValue(new CallMethod(Method.Source, Method.IsStatic ? null : new This(Method.Source, Method.DeclaringType), Method, al.ToArray()), min, max)); }