Beispiel #1
0
        private AstNode VectorConstruction(CallExpression node)
        {
            // Begin the node.
            builder.BeginNode(node);

            // Retrieve the types.
            IChelaType targetType = node.GetNodeType();
            IChelaType coercionType = node.GetCoercionType();

            // Push the arguments.
            AstNode argExpr = node.GetArguments();
            while(argExpr != null)
            {
                // Visit the argument.
                argExpr.Accept(this);

                // Coerce it.
                IChelaType argExprType = argExpr.GetNodeType();
                if(argExprType != coercionType)
                {
                    // De-ref and de-const
                    IChelaType argCoercionType = argExprType;
                    if(argCoercionType.IsReference())
                        argCoercionType = DeReferenceType(argCoercionType);
                    if(argCoercionType.IsConstant())
                        argCoercionType = DeConstType(argCoercionType);

                    if(argCoercionType.IsPrimitive())
                    {
                        // Use normal casting.
                        Cast(node, argExpr.GetNodeValue(), argExprType, coercionType);
                    }
                    else
                    {
                        // Coercion to a vector with the same size.
                        VectorType argVector = (VectorType)argCoercionType;
                        argCoercionType = VectorType.Create(coercionType, argVector.GetNumComponents());
                        if(argCoercionType != argExprType)
                            Cast(node, argExpr.GetNodeValue(), argExprType, argCoercionType);
                    }

                }

                // Process the next argument.
                argExpr = argExpr.GetNext();
            }

            // Create the vector.
            if(targetType.IsVector())
                builder.CreateNewVector(targetType);
            else
                builder.CreateNewMatrix(targetType);
            return builder.EndNode();
        }
Beispiel #2
0
        public override AstNode Visit(CallExpression node)
        {
            if(node.IsVectorConstruction())
                return VectorConstruction(node);

            // Begin the node.
            builder.BeginNode(node);

            // Get the functional expression.
            Expression functionalExpression = node.GetFunction();

            // Get the function type.
            FunctionType functionType = (FunctionType)node.GetCoercionType();

            // Visit the functional expression.
            functionalExpression.Accept(this);

            // Check if suppressing virtual calls.
            FunctionGroupSelector selector = functionalExpression.GetNodeValue() as FunctionGroupSelector;
            bool implicitThis = node.HasImplicitArgument();
            bool suppressVirtual = false;
            Function function = node.GetSelectedFunction();
            if(selector != null)
            {
                suppressVirtual = selector.SuppressVirtual;
                implicitThis = implicitThis || (selector.ImplicitThis && !function.IsStatic());
            }

            // Cast the function expression.
            IChelaType exprType = functionalExpression.GetNodeType();
            IChelaType functionCoercion = exprType;

            // Load variables.
            if(functionCoercion.IsReference())
               functionCoercion = DeReferenceType(exprType);
            if(exprType != functionCoercion)
                Cast(node, functionalExpression.GetNodeValue(), exprType, functionCoercion);

            // Push the arguments.
            AstNode argExpr = node.GetArguments();
            int index = implicitThis ? 1 : 0;
            while(argExpr != null)
            {
                // Visit the argument.
                argExpr.Accept(this);

                // Don't cast reference argument
                Variable argVariable = argExpr.GetNodeValue() as Variable;
                bool refArg = argVariable != null && argVariable.IsTemporalReferencedSlot();

                // Coerce it.
                IChelaType argExprType = argExpr.GetNodeType();
                IChelaType argType = functionType.GetArgument(index++);
                if(argType != argExprType && !refArg)
                    Cast(node, argExpr.GetNodeValue(), argExprType, argType);

                // Push the next argument.
                argExpr = argExpr.GetNext();
            }

            // Store the number of arguments.
            int numargs = index;

            // Perform a call if the function is known, otherwise an indirect call.
            if(function != null)
            {
                // Use different opcode for virtual calls.
                if(function.IsKernelEntryPoint())
                {
                    KernelEntryPoint entryPoint = (KernelEntryPoint)function;
                    builder.CreateBindKernel(DeReferenceType(node.GetNodeType()), entryPoint.Kernel);
                }
                else if(function.IsConstructor())
                    builder.CreateNewStruct(node.GetNodeType(), function, (uint)(numargs-1));
                else if(!function.IsVirtualCallable() || function.GetParentScope().IsStructure() || suppressVirtual)
                    builder.CreateCall(function, (uint)numargs);
                else
                    builder.CreateCallVirtual(function, (uint)numargs);
            }
            else
            {
                // Call the object.
                builder.CreateCallIndirect((uint)numargs);
            }

            return builder.EndNode();
        }