public bool TryCallIntrinsicsFunction(FunctionKey functionKey, CSharpSyntaxNode selfExpressionNode, IEnumerable <CSharpSyntaxNode> arguments) { var instrinsicDelegate = mFrontEnd.mCurrentLibrary.FindIntrinsicFunction(functionKey); if (instrinsicDelegate == null) { return(false); } // Build the arguments up var argumentIRs = new List <IShaderIR>(); // Visit the self if it exists if (selfExpressionNode != null) { var selfOp = WalkAndGetResult(selfExpressionNode); argumentIRs.Add(selfOp); } // Visit all the args if they exist if (arguments != null) { foreach (var argument in arguments) { argumentIRs.Add(WalkAndGetResult(argument)); } } instrinsicDelegate(mFrontEnd, argumentIRs, mContext); return(true); }
public void DefaultConstructType(INamedTypeSymbol typeSymbol, ShaderOp variableOp) { var defaultConstructorSymbol = FindDefaultConstructorSymbol(typeSymbol); if (defaultConstructorSymbol == null) { return; } var constructorKey = new FunctionKey(defaultConstructorSymbol); // If this is an intrinsic (defined by the compiler and not user defined) then invoke it. var constructorIntrinsic = mFrontEnd.mCurrentLibrary.FindIntrinsicFunction(constructorKey); if (constructorIntrinsic != null) { constructorIntrinsic(mFrontEnd, new List <IShaderIR>(), mContext); mFrontEnd.CreateStoreOp(mContext.mCurrentBlock, variableOp, mContext.Pop()); return; } // Otherwise see if this is user defined var constructorFn = mFrontEnd.mCurrentLibrary.FindFunction(constructorKey); if (constructorFn != null) { mFrontEnd.GenerateFunctionCall(constructorFn, variableOp, null, mContext); return; } var derefType = variableOp.mResultType.GetDereferenceType(); var defaultValue = mFrontEnd.DefaultConstructPrimitive(derefType, mContext); mFrontEnd.CreateStoreOp(mContext.mCurrentBlock, variableOp, defaultValue); }
public ShaderFunction CreateFunction(FunctionKey key) { ShaderFunction shaderFunction = new ShaderFunction(); mFunctionMap.Add(key, shaderFunction); return(shaderFunction); }
public ShaderFunction FindOrCreateFunction(FunctionKey key, bool checkDependencies = true) { var result = FindFunction(key, checkDependencies); if (result == null) { result = CreateFunction(key); } return(result); }
public ShaderFunction FindFunction(FunctionKey key, bool checkDependencies = true) { var result = mFunctionMap.GetValueOrDefault(key); if (result == null && checkDependencies && mDependencies != null) { result = mDependencies.FindFunction(key, checkDependencies); } return(result); }
public ShaderFunction FindFunction(FunctionKey key, bool checkDependencies = true) { foreach (var library in this) { var result = library.FindFunction(key, checkDependencies); if (result != null) { return(result); } } return(null); }
public override void VisitObjectCreationExpression(ObjectCreationExpressionSyntax node) { var symbol = GetSymbol(node); var fnKey = new FunctionKey(symbol); var resultSymbol = GetSymbol(node.Type); var resultType = mFrontEnd.mCurrentLibrary.FindType(new TypeKey(resultSymbol)); // Handle constructing intrinsics types if (TryCallIntrinsicsFunction(fnKey, null, node.ArgumentList.Arguments)) { return; } var fieldPtrType = resultType.FindPointerType(StorageClass.Function); var localVariableOp = mFrontEnd.CreateOpVariable(fieldPtrType, mContext); localVariableOp.DebugInfo.Name = "temp" + resultType.mMeta.mName; var shaderFunction = mFrontEnd.mCurrentLibrary.FindFunction(fnKey); if (shaderFunction == null && node.ArgumentList.Arguments.Count != 0) { throw new Exception("Failed to find function"); } // If this is a function call then invoke it if (shaderFunction != null) { var arguments = new List <CSharpSyntaxNode>(); foreach (var arg in node.ArgumentList.Arguments) { arguments.Add(arg); } GenerateFunctionCall(shaderFunction, localVariableOp, arguments); } // If there's an initializer expression then visit each one if (node.Initializer != null) { // The context of 'this' changes for the initializer expression var thisOp = mContext.mThisOp; mContext.mThisOp = localVariableOp; foreach (var initExpression in node.Initializer.Expressions) { Visit(initExpression); } mContext.mThisOp = thisOp; } mContext.Push(localVariableOp); }
public bool TryCallSetterFunction(FunctionKey functionKey, IShaderIR selfInstanceIR, IShaderIR rhsIR) { var setterShaderFunction = mFrontEnd.mCurrentLibrary.FindFunction(functionKey); if (setterShaderFunction == null) { return(false); } GenerateFunctionCall(setterShaderFunction, selfInstanceIR, new List <IShaderIR>() { rhsIR }); return(true); }
public bool TryCallIntrinsicsSetterFunction(FunctionKey functionKey, IShaderIR setter, IShaderIR argumentIR) { var instrinsicDelegate = mFrontEnd.mCurrentLibrary.FindIntrinsicSetterFunction(functionKey); if (instrinsicDelegate == null) { return(false); } // Build the arguments up var argumentIRs = new List <IShaderIR>(); instrinsicDelegate(mFrontEnd, setter, argumentIR, mContext); return(true); }
public InstrinsicSetterDelegate FindIntrinsicSetterFunction(FunctionKey key, bool checkDependencies = true) { var result = IntrinsicSetterFunctions.GetValueOrDefault(key, null); if (result == null && mDependencies != null) { foreach (var dependency in mDependencies) { result = dependency.FindIntrinsicSetterFunction(key, checkDependencies); if (result != null) { break; } } } return(result); }
public bool TryCallFunction(FunctionKey functionKey, CSharpSyntaxNode selfExpressionNode, CSharpSyntaxNode rhsNode) { var setterShaderFunction = mFrontEnd.mCurrentLibrary.FindFunction(functionKey); if (setterShaderFunction == null) { return(false); } var selfInstanceIR = WalkAndGetResult(selfExpressionNode); var rhsIR = WalkAndGetResult(rhsNode); GenerateFunctionCall(setterShaderFunction, selfInstanceIR, new List <IShaderIR>() { rhsIR }); return(true); }
public override void VisitAssignmentExpression(AssignmentExpressionSyntax node) { // Always get the right IR but not always the left. In some cases with setters we don't need the left. This avoids loading the left twice. IShaderIR leftIR = null; IShaderIR rightIR = WalkAndGetResult(node.Right); // If the token isn't the assignment op, then this must be a compound assignment (e.g. '+='). var token = node.OperatorToken.Text; if (token != "=") { // To do the compound we have to load the left now. leftIR = WalkAndGetResult(node.Left); var lhsType = GetSymbolType(node.Left); var rhsType = GetSymbolType(node.Right); // Generate the token for the binary op in the compound (just strip the '=' off) and then visit the binary expression. var binaryOp = token.Substring(0, token.Length - 1); VisitBinaryExpression(node, lhsType, leftIR, rhsType, rightIR, binaryOp); // Do whatever remaining logic for the assignment with the result of the binary expression. rightIR = mContext.Pop(); } // If the left side is actually a setter, then we have to flip the assignment around to call the setter var leftSymbol = GetSymbol(node.Left); // One complicated case is if the left is actually a member access (e.g. Vec3.XY = rhs). // In this case, we need to call the setter on Vec3 (the expression of the member access) if (node.Left is MemberAccessExpressionSyntax memberAccessNode && leftSymbol.IsStatic == false) { FunctionKey functionKey = null; // Try and get the function key for this symbol depending on if it's a field, property, etc... if (leftSymbol is IPropertySymbol propertySymbol && !propertySymbol.IsReadOnly) { functionKey = new FunctionKey(propertySymbol.SetMethod); }
/// <summary> /// Creates a simple intrinsic function (one whos ops are just value types of the args one-for-one) callback for the given symbol information. /// </summary> static public void CreateSimpleIntrinsicFunction(FrontEndTranslator translator, FunctionKey functionKey, OpInstructionType opType, ShaderType returnType) { ShaderLibrary.InstrinsicDelegate callback = (FrontEndTranslator translator, List <IShaderIR> arguments, FrontEndContext context) => { SimpleValueTypeIntrinsic(translator, context, opType, returnType, arguments); }; translator.mCurrentLibrary.CreateIntrinsicFunction(functionKey, callback); }
public void CreateIntrinsicSetterFunction(FunctionKey key, InstrinsicSetterDelegate intrinsic) { IntrinsicSetterFunctions.TryAdd(key, intrinsic); }
//---------------------------------------------------------------Functions public bool AddFunction(FunctionKey key, ShaderFunction shaderFunction) { return(mFunctionMap.TryAdd(key, shaderFunction)); }