コード例 #1
0
        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);
        }
コード例 #2
0
 public virtual void WriteCallShader(CallShader s, ExpressionUsage u)
 {
     Write(s.Function.Name);
     WriteArguments(s.Function, s.Arguments, true);
 }