bool TryProcessFunctionCall(ref Expression e, Function f, Expression[] args, Expression optionalValueOrObject = null, Expression optionalObject = null) { // Special case for T[].get_Length() if (f.DeclaringType.IsRefArray && optionalValueOrObject != null && optionalValueOrObject.ReturnType.IsFixedArray && f.Name == "get_Length" && f.Parameters.Length == 0) { var fat = (FixedArrayType)optionalValueOrObject.ReturnType; e = fat.OptionalSize ?? Expression.Invalid; return(true); } if (Backend.ShaderBackend.IsIntrinsic(f)) { return(false); } var processedArgs = ProcessArguments(args, optionalValueOrObject, optionalObject); ShaderFunction result; if (!ProcessedFunctions.TryGetValue(f, out result)) { // TODO: This code doesn't handle: // - Recursion // - Multiple uses of function with array in parameterlist if (!f.HasBody) { Log.Error(e.Source, ErrorCode.E5010, f.Quote() + " is pure intrinsic and is not supported by current shader backend (in " + Generator.Path.Quote() + ")"); return(false); } result = new ShaderFunction(f.Source, Shader, f.UnoName.ToIdentifier() + "_" + Generator.ShaderGlobalCounter++, f.ReturnType, null); var state = new CopyState(result); var parameterList = TryProcessParameterList(f, processedArgs, state); if (parameterList == null) { return(false); } result.SetParameters(parameterList); result.SetBody(f.Body.CopyNullable(state)); if (!f.IsStatic) { if (f.IsConstructor) { result.ReturnType = f.DeclaringType; var var = new Variable(f.Source, f, "__this", f.DeclaringType); result.Body.Statements.Insert(0, new VariableDeclaration(var)); result.Body.Statements.Add(new Return(f.Source, new This(f.Source, f.DeclaringType))); result.Body.Visit(new ThisSwapper(this, new LoadLocal(f.Source, var))); } else { result.Body.Visit(new ThisSwapper(this, new LoadArgument(f.Source, result, f.Parameters.Length))); } } ProcessedFunctions.Add(f, result); result.Visit(this); Shader.Functions.Add(result); // add after process } e = new CallShader(e.Source, result, processedArgs); return(true); }
public virtual void WriteCallShader(CallShader s, ExpressionUsage u) { Write(s.Function.Name); WriteArguments(s.Function, s.Arguments, true); }