Package org.openquark.cal.internal.machine

Examples of org.openquark.cal.internal.machine.BasicOpTuple


        if (codeGenerationStats != null) {
            codeGenerationStats.incrementOptimizedAndOr();
        }

        // Unpack the basic op into subexpressions
        BasicOpTuple basicOpExpressions = BasicOpTuple.isAndOr (e);

        // Code a basic operation
        int op = basicOpExpressions.getPrimitiveOp ();
        int nArgs = basicOpExpressions.getNArguments ();

        if (nArgs < 0 || nArgs > 2) {
            throw new CodeGenerationException("Invalid basic operator arity: " + nArgs);
        }

        // The arguments for primitive ops are handled as a special case.
        // We want to avoid boxing/unboxing of primitive values wherever possible.
        Block generatedContext = new Block();
        JavaExpression args[] = new JavaExpression[nArgs];
        for (int i = 0; i < nArgs; ++i) {
            int argIndex = nArgs - i - 1;
            ExpressionContextPair pair = generateUnboxedPrimOpArgument(basicOpExpressions, basicOpExpressions.getArgument(argIndex), argIndex, variableContext);
            args[argIndex] = pair.getJavaExpression();
            generatedContext.addStatement(pair.getContextBlock());
        }

        JavaExpression javaExpression = PrimOp.getPrimOpDefinition(op, args);
View Full Code Here


     * @throws CodeGenerationException
     */
    private ExpressionContextPair generatePrimitiveOp (Expression e, boolean boxResult, Scheme scheme, VariableContext variableContext) throws CodeGenerationException {

        // Unpack the basic op into subexpressions
        BasicOpTuple basicOpExpressions = BasicOpTuple.isBasicOp(e);

        if (!LECCMachineConfiguration.generateDirectPrimOpCalls()) {
            //when we are not generating direct primitive op calls we should not call this function,
            //other than the special case of generating code for the function that calls the primitive op
            //e.g. org.openquark.cal.internal.runtime.lecc.cal_Math.Sin will directly call java.lang.Math.sin but
            //we will not directly call java.lang.Math.sin anywhere else.

            if (!basicOpExpressions.getName().equals(getQualifiedName())) {
                throw new CodeGenerationException("Should not directly call a primitive operator when GEN_DIRECT_PRIMOP_CALLS is false.");
            }
        }

        // Code a basic operation
        int op = basicOpExpressions.getPrimitiveOp ();
        int nArgs = basicOpExpressions.getNArguments ();

        if (nArgs < 0) {
            throw new CodeGenerationException("Invalid basic operator arity: " + nArgs);
        }

        if (op == PrimOps.PRIMOP_FOREIGN_FUNCTION) {
            // This is a foreign function
            return generateForeignCall (e, boxResult, scheme, variableContext);
        }

        if (codeGenerationStats != null) {
            codeGenerationStats.incrementOptimizedPrimOp (basicOpExpressions.getName());
        }

        // The primitive op Prelude.eager is a special case.  We want to simply
        // compile the argument in a strict scheme.
        if (op == PrimOps.PRIMOP_EAGER) {
            return genS_E(basicOpExpressions.getArgument(0), variableContext);
        }

        // The arguments for primitive ops are handled as a special case.
        // We want to avoid boxing/unboxing of primitive values wherever possible.
        Block generatedContext = new Block();
        JavaExpression args[] = new JavaExpression[nArgs];
        for (int i = 0; i < nArgs; ++i) {
            int argIndex = nArgs - i - 1;
            ExpressionContextPair pair;
            if (op == PrimOps.PRIMOP_CAL_VALUE_TO_OBJECT) {
                //Prelude.calValueToObject is an unusual primitive op in that it is non-strict in its argument
                pair = genS_C(basicOpExpressions.getArgument(argIndex), variableContext);
            } else
            {
                pair = generateUnboxedPrimOpArgument(basicOpExpressions, basicOpExpressions.getArgument(argIndex), argIndex, variableContext);
            }

            args[argIndex] = pair.getJavaExpression();
            generatedContext.addStatement(pair.getContextBlock());
        }
View Full Code Here

            }

            // If the expression is a primitive op compile it as an unboxed op.
            //We would not want to directly call primitive operators when doing function tracing.
            //This will have the effect of ensuring that they get traced when called.
            BasicOpTuple bot;
            if (LECCMachineConfiguration.generateDirectPrimOpCalls() &&
                (bot = BasicOpTuple.isBasicOp(e)) != null) {

                // We need to be sure that the primitiveness of the operation/foreign function and the
                // desired unbox type match.  For example an operation that produces an int can either unbox to
                // an int or an Object.

                if (bot.getPrimitiveOp() == PrimOps.PRIMOP_FOREIGN_FUNCTION) {
                    // We know that this is an unboxed argument to a CAL function.
                    // The unboxed value cannot be void.  If we are calling a foreign
                    // function with return type of void we can't do a direct call.  We
                    // need to call the CAL wrapper function which will return the CAL
                    // equivalent to void. i.e. Unit
                    ForeignFunctionInfo ffi = bot.getForeignFunctionInfo();
                    Class<?> foreignReturnType = SCJavaDefn.getJavaReturnType(ffi);

                    verifyUnboxType(unboxType, JavaTypeName.make(foreignReturnType));


                    if(foreignReturnType.equals(void.class)) {
                        // This is the special case of a void foreign function.  The return type needs to
                        // be converted to the CAL Unit type.
                        // Compile the expression strictly, this will result in an RTValue which can be unboxed to the int equivalent
                        // of the unit type.
                        ExpressionContextPair argResult = genS_E (e, variableContext);
                        return new ExpressionContextPair(SCJavaDefn.unboxValue (unboxType, argResult.getJavaExpression()), argResult.getContextBlock());

                    } else if (bot.getPrimitiveOp() == PrimOps.PRIMOP_EAGER) {

                        throw new CodeGenerationException ("PRIMOP_EAGER encountered in generateUnboxedArgument.");

                    } else if (foreignReturnType.isPrimitive() == primitiveUnboxType){
                        // Using unsafeCoerce and input/output we can get CAL code that corresponds to
                        // treating primitives as objects and vice versa.  For example the Java primitive int and
                        // the Java class Integer get equated.
                        // We need to check that the foreign type of the expression being compiled has the same
                        // primitiveness as the unboxed type we are trying to generate.

                        return generatePrimitiveOp(e, false, Scheme.E_SCHEME, variableContext);
                    else {
                        throw new CodeGenerationException ("Primitivenes mismatch in " + getModuleName() + "." + getFunctionName() + " in generateUnboxedArgument.  Expression is " + foreignReturnType.toString() + " expected type is " + unboxType);
                    }
                } else {
                    if (bot.getPrimitiveOp() != PrimOps.PRIMOP_OBJECT_TO_CAL_VALUE &&
                        bot.getPrimitiveOp() != PrimOps.PRIMOP_CAL_VALUE_TO_OBJECT) {
                        verifyUnboxType (unboxType, PrimOp.getTypeNameForPrimOp(bot.getPrimitiveOp()));
                        return generatePrimitiveOp(e, false, Scheme.E_SCHEME, variableContext);
                    }
                }
            }
View Full Code Here

            }

            // If the expression is a primitive op compile it as an unboxed op.
            //we don't directly call primitive operators if doing function tracing.
            //This will have the effect of ensuring that they get traced when called.
            BasicOpTuple bot;
            if (LECCMachineConfiguration.generateDirectPrimOpCalls() &&
                (bot = BasicOpTuple.isBasicOp(e)) != null) {

                // Generally speaking if an argument to a foreign function is expressed as a primitive op/foreign function we can
                // assume that the unboxed return value of the argument expression is of the correct type to pass.
                // One exception is when dealing with an argument expression of type Prelude.CalValue.  In this case we need to
                // get the Prelude.CalValue, evaluate, and then unbox the actual type needed by the foreign function.
                // Another is when dealing with Prelude.eager
                // Finally we need to be sure that the primitiveness of the operation/foreign function and the
                // desired unbox type match.  For example an operation that produces an int can either unbox to
                // an int or an Object.
                if (bot.getPrimitiveOp() == PrimOps.PRIMOP_FOREIGN_FUNCTION) {
                    // If this foreign SC is of type internal value we can't just get the unboxed value and pass
                    final ForeignFunctionInfo ffi = bot.getForeignFunctionInfo();
                    final Class<?> foreignReturnType = SCJavaDefn.getJavaReturnType(ffi);

                    // If this foreign SC is of type Prelude.CalValue we can't just get the unboxed value and pass
                    final boolean hasCalValueReturnType = isCalValueClass(foreignReturnType);
                    if (hasCalValueReturnType){
                        ExpressionContextPair argResult = genS_E (e, variableContext);
                        return new ExpressionContextPair(unboxValue(unboxType, SCJavaDefn.createInvocation (argResult.getJavaExpression(), SCJavaDefn.EVALUATE, SCJavaDefn.EXECUTION_CONTEXT_VAR)), argResult.getContextBlock());
                    }
                    verifyUnboxType(unboxType, JavaTypeName.make(foreignReturnType));
                    return generatePrimitiveOp (e, false, Scheme.E_SCHEME, variableContext);
                } else
                if (bot.getPrimitiveOp() == PrimOps.PRIMOP_EAGER) {
                    throw new CodeGenerationException ("PRIMOP_EAGER encountered in generateUnboxedForeignFunctionArgument.");
                } else
                if (bot.getPrimitiveOp() != PrimOps.PRIMOP_OBJECT_TO_CAL_VALUE &&
                    bot.getPrimitiveOp() != PrimOps.PRIMOP_CAL_VALUE_TO_OBJECT) {
                    verifyUnboxType(unboxType, PrimOp.getTypeNameForPrimOp(bot.getPrimitiveOp()));
                    return generatePrimitiveOp(e, false, Scheme.E_SCHEME, variableContext);
                }
            }

            if (isNot(e)) {
View Full Code Here

TOP

Related Classes of org.openquark.cal.internal.machine.BasicOpTuple

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.