Statement CompileFixedArrayDeclaration(AstFixedArrayDeclaration e) { var s = e.Type; var size = s.OptionalSize != null ? CompileImplicitCast(s.OptionalSize.Source, Essentials.Int, CompileExpression(s.OptionalSize)) : null; var elementType = NameResolver.GetType(Namescope, s.ElementType); var dt = new FixedArrayType(s.Source, elementType, size, Essentials.Int); VerifyVariableName(e.Source, e.Name.Symbol); var fixedInit = e.OptionalValue as AstFixedArrayInitializer; if (fixedInit != null) { return(CompileFixedArrayDeclaration(e.Source, dt, e.Name.Symbol, fixedInit)); } var var = new Variable(e.Source, Function, e.Name.Symbol, dt, 0, e.OptionalValue != null ? CompileImplicitCast(e.Source, dt, CompileExpression(e.OptionalValue)) : null); CurrentVariableScope.Variables[e.Name.Symbol] = var; return(new FixedArrayDeclaration(var, null)); }
DataType ParameterizeType(Dictionary <DataType, DataType> map, DataType arg) { if (arg == null) { return(null); } DataType result; if (map.TryGetValue(arg, out result)) { return(result); } if (arg is RefArrayType) { result = GetArray(ParameterizeType(map, arg.ElementType)); } else if (arg is FixedArrayType) { result = new FixedArrayType( arg.Source, ParameterizeType(map, arg.ElementType), ((FixedArrayType)arg).OptionalSize, _ilf.Essentials.Int); } else if (arg.IsNestedType && arg.ParentType.IsFlattenedParameterization) { var p = ParameterizeType(map, arg.ParentType); if (arg.IsGenericParameter && p.IsGenericDefinition) { // Should not be necessary foreach (var pp in p.GenericParameters) { if (pp.UnoName == arg.UnoName) { result = pp; break; } } } else { bool innerTypeFound = false; foreach (var it in p.NestedTypes) { if (arg.MasterDefinition == it.MasterDefinition) { if (it.IsGenericDefinition) { var pargs = new DataType[arg.GenericArguments.Length]; for (int i = 0, l = pargs.Length; i < l; i++) { pargs[i] = ParameterizeType(map, arg.GenericArguments[i]); } result = Parameterize(it.Source, it, pargs); } else { result = it; } innerTypeFound = true; break; } } if (!innerTypeFound) { // Should not be necessary foreach (var m in p.Methods) { if (m.IsGenericDefinition && m.GenericType.MasterDefinition == arg.MasterDefinition) { result = m.GenericType; break; } } } } } else if (arg.IsGenericParameterization) { var pargs = new DataType[arg.GenericArguments.Length]; for (int i = 0, l = pargs.Length; i < l; i++) { pargs[i] = ParameterizeType(map, arg.GenericArguments[i]); } result = Parameterize(arg.Source, arg.GenericDefinition, pargs); } else { result = arg; } if (result != null) { map.Add(arg, result); return(result); } throw new FatalException(arg.Source, ErrorCode.I0000, "Failed to parameterize " + arg.Quote()); }
internal StageValue ProcessStageChange(StageValue s, MetaStage fromStage, MetaStage toStage, MetaLocation loc, MetaProperty mp) { if (s.Value == null) { return(new StageValue(null, toStage)); } if (s.MinStage > fromStage) { Log.Error(s.Value.Source, ErrorCode.I5016, "Stage error"); return(new StageValue(Expression.Invalid, toStage)); } switch (toStage) { case MetaStage.Pixel: case MetaStage.Vertex: if (fromStage == MetaStage.Vertex && toStage == MetaStage.Pixel) { // Vertex -> Pixel: Varying var key = s.Value.ToString(); int index; if (!Varyings.TryGetValue(key, out index)) { index = DrawState.Varyings.Count; DrawState.Varyings.Add(new ShaderVariable(s.Value.ReturnType, CreateShaderName(mp, loc, s.Value), s.Value)); Varyings.Add(key, index); } return(new StageValue(new LoadVarying(s.Value.Source, DrawState, index), MetaStage.Pixel, MetaStage.Pixel)); } else if (s.Value.ReturnType == Essentials.Bool || s.Value.ReturnType == Essentials.Int) { return(ProcessShaderConstant(s, loc, mp)); } else { // Init,Frame -> Vertex,Pixel: Uniform s = ProcessStage(s, MetaStage.Volatile, MetaStage.Volatile); var val = s.Value.ActualValue; var dt = val.ReturnType; var key = val.ToString(); int index; if (!Uniforms.TryGetValue(key, out index)) { index = DrawState.Uniforms.Count; switch (dt.TypeType) { case TypeType.FixedArray: // Ugly workaround. ResolvedMetaPropertyValue could already be an address if (!(val is PlaceholderValue && (val as PlaceholderValue).Value is AddressOf)) { val = new AddressOf(val.ActualValue, AddressType.Const); } break; case TypeType.RefArray: var at = dt as RefArrayType; var et = at.ElementType; var size = ProcessShaderConstant( new StageValue(ILFactory.GetProperty(s.Value.Source, s.Value, "Length"), s.MinStage, s.MaxStage), loc, mp).Value; dt = new FixedArrayType(s.Value.Source, et, size, Essentials.Int); break; } DrawState.Uniforms.Add(new ShaderVariable(dt, CreateShaderName(mp, loc, val), val)); Uniforms.Add(key, index); } Expression u = new LoadUniform(s.Value.Source, DrawState, index); if (u.ReturnType.IsFixedArray) { u = new AddressOf(u, AddressType.Const); } return(new StageValue(u, MetaStage.Vertex, MetaStage.Pixel)); } case MetaStage.Volatile: if (fromStage <= MetaStage.ReadOnly) { // Init -> Frame: Field var src = s.Value.Source; var dt = Path.DrawBlock.Method.DeclaringType; var obj = new This(src, dt).Address; var key = s.Value.ToString(); Field field; if (!Fields.TryGetValue(key, out field)) { for (int i = 0; i < InitScope.Statements.Count; i++) { if (InitScope.Statements[i] is StoreField) { var sf = InitScope.Statements[i] as StoreField; if (sf.Field.ReturnType.Equals(s.Value.ReturnType) && sf.Value.ToString() == key) { field = sf.Field; } } } if (field == null) { field = new Field(src, dt, CreateFieldName(mp, loc, s.Value), null, Modifiers.Private | Modifiers.Generated, 0, s.Value.ReturnType); dt.Fields.Add(field); InitScope.Statements.Add(new StoreField(src, obj, field, s.Value)); } Fields.Add(key, field); } return(new StageValue(new LoadField(src, obj, field), MetaStage.ReadOnly, MetaStage.Volatile)); } break; case MetaStage.ReadOnly: return(s); } Log.Error(s.Value.Source, ErrorCode.E5017, fromStage.ToLiteral().Quote() + " cannot be accessed from " + toStage.ToLiteral() + " stage while processing " + mp.Name.Quote() + " at " + mp.Source + " in " + Path.Quote() + " at " + Path.Source); return(new StageValue(Expression.Invalid, MetaStage.Const)); }
DataType GetTypeInternal(DataType dt) { DataType result; if (SwapTypes.TryGetValue(dt, out result)) { return(result); } switch (dt.TypeType) { case TypeType.GenericParameter: { SwapTypes.Add(dt, dt); return(dt); } case TypeType.RefArray: { var at = TypeBuilder.GetArray(GetType(dt.ElementType)); SwapTypes.Add(dt, at); return(at); } case TypeType.FixedArray: { var at = (FixedArrayType)dt; at = new FixedArrayType(at.Source, GetType(at.ElementType), at.OptionalSize, Essentials.Int); SwapTypes.Add(dt, at); return(at); } } result = dt; if (dt.IsNestedType) { if (!dt.IsGenericParameterization && dt.IsFlattenedParameterization) { var def = GetType(dt.MasterDefinition); // Transformed type was unnested if (!def.IsNestedType) { if (def.IsGenericDefinition) { var args = new DataType[dt.FlattenedArguments.Length]; for (int i = 0; i < dt.FlattenedArguments.Length; i++) { args[i] = GetType(dt.FlattenedArguments[i]); } result = TypeBuilder.Parameterize(result.Source, def, args); TypeBuilder.BuildTypes(); SwapTypes.Add(dt, result); return(result); } // Unnested enum SwapTypes.Add(dt, def); return(def); } } var pt = GetType(dt.ParentType); if (pt != dt.Parent) { foreach (var it in pt.NestedTypes) { if (it.MasterDefinition == dt.MasterDefinition) { result = pt; break; } } } } if (dt.IsGenericParameterization) { var args = new DataType[dt.GenericArguments.Length]; for (int i = 0; i < dt.GenericArguments.Length; i++) { args[i] = GetType(dt.GenericArguments[i]); } var def = result.IsGenericDefinition ? result : GetType(dt.GenericDefinition); result = TypeBuilder.Parameterize(dt.Source, def, args); TypeBuilder.BuildTypes(); } SwapTypes.Add(dt, result); return(result); }