Package edu.umass.bc

Source Code of edu.umass.bc.RuntimeCreator

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package edu.umass.bc;

import org.objectweb.asm.*;
import edu.umass.pql.*;
import edu.umass.pql.container.PSet;
import edu.umass.pql.il.Arithmetic;
import edu.umass.pql.il.Field;
import edu.umass.pql.il.NoFail.Bool;
import edu.umass.pql.il.ReductionImpl;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.objectweb.asm.util.TraceClassVisitor;

/**
*
* @author Hilmar
*/
public class RuntimeCreator implements Opcodes, VarConstants, BcFlags  {
   
    /*
     * compiler konnte erstellt werden => was weiter..?
     *
     * //benchmarks.webgraph.Generator.init(); in Bench.java musste auskommentiert werden => zuwenig heap..
     *
     * benchmarks in pql implementieren
     * R s <- (0.123, 0.3242, ..)
     * R boxplot(s)
     * in allen benchmarks Manual.java
     * versuchen, per makefile compiler zu erzeugen
     * bool nochmal richtig
     *
     * ==============
     *
     * code etwas "aufräumen"
     * Strings so einbauen, dass sie im Code der Ausgabe sichtbar sind..
     *
     * Notes:
     * noch nicht implementiert: arrays, die in N_map / Default_n_map als inner_reductor verwendet werden..
     * bei arrays, die %32 != 0 sind, kann es bei 0/0 abfragen zu problemen kommen.. (allgemein, darf auch nicht auf null abgefragt werden..)
     *
     * fehlende Implementierungen:
     * ========
     * (POLY_SIZE/SET_SIZE/MAP_SIZE/..S)
     * JAVA_TYPE / INT / CHAR => typ überprüfung
     * INSTANTIATE
     * DisjunctiveBlock / BOOL / NOFAIL / NOT / FORALL
     */
   
    public static final boolean quietRuntimeCreator = true;
    public static final boolean useRuntimeCreator = true;
    public static boolean alreadyInitialized = false;
   
    private static Method pql_eval = null;
    private static Join pql_query = null;
    private static ASMFlagTranslations ast = new ASMFlagTranslations ();
    private static ReturnBehaviorStack returnBehaviorStack;
    private static int usedLocalVariables;
    protected static ArrayList <Method> methods;
   
    public static void init (Join new_query) {
        pql_query = new_query;
        pql_eval = null;
        methods = new ArrayList <Method> ();
    }
   
    public static boolean test (Env env) {
        try {
            if (pql_eval == null) {
                RuntimeClassLoader cl = new RuntimeClassLoader ();
                Class c = cl.defineClass("Evaluator", genEvalFor(pql_query) );

                for (int i=0; i<c.getMethods().length; i++) {
                    if (c.getMethods()[i].getName().equals("evaluate")) {
                        pql_eval = c.getMethods()[i];
                        break;
                    }
                }
            }
            /*Method methodArg [] = new Method [methods.size()];
            for (int i=0; i<methods.size(); i++)
                methodArg[i] = methods.get(i);*/
            Boolean result = (Boolean)pql_eval.invoke(null, new Object[] { env  });
            if (!quietRuntimeCreator)
                System.out.println("  Ergebnis: " + result);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
   
    private static byte[] genEvalFor (Join pql_query) throws Exception {
       
        /*
        ClassReader cr2 = new ClassReader("bc.RuntimeCreator");
        ClassVisitor cv2 = new ClassWriter(cr2, 0);
        PrintWriter pw2 = new PrintWriter(System.out);
        TraceClassVisitor cw2 = new TraceClassVisitor(cv2, pw2);
        cr2.accept(cw2, 0);
        int i=0;
        if (i != 3452) {
            Thread.sleep(100);
        throw new Exception("BREAK");
        }*/
       
        usedLocalVariables = 1;
        returnBehaviorStack = new ReturnBehaviorStack ();
       
        ClassWriter cv;
        ClassVisitor cw = null;
        //=====
        if (quietRuntimeCreator) {
            cv = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
            cw = cv;
        } else {
            cv = new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
            PrintWriter pw = new PrintWriter(System.out);
            cw = new TraceClassVisitor(cv, pw);
        }
        FieldVisitor fv;
        MethodVisitor mv;
        AnnotationVisitor av0;

        cw.visit(V1_6, ACC_PUBLIC, "Evaluator", null, "java/lang/Object", null);

        cw.visitSource("Evaluator.java", null);

        {
            mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
            mv.visitCode();
            Label l0 = new Label();
            mv.visitLabel(l0);
            mv.visitLineNumber(1, l0);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
            mv.visitInsn(RETURN);
            Label l1 = new Label();
            mv.visitLabel(l1);
            mv.visitLocalVariable("this", "LEvaluator;", null, l0, l1, 0);
            mv.visitMaxs(1, 1);
            mv.visitEnd();
        }
        {
            mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "evaluate", "(Ledu/umass/pql/Env;)Z", null, null);
            mv.visitCode();
           
            createASMCode (pql_query, mv);
            mv.visitLdcInsn(new Integer(1));
            mv.visitInsn(IRETURN);
            //returnBehaviorStack.insertReturnCode(true, mv);
          
            mv.visitMaxs(0, 0);
            mv.visitEnd();    
        }
        cw.visitEnd();

        return cv.toByteArray();
    }
   
    private static void createASMCode (Join query, MethodVisitor mv) throws Exception {
        int flags = -1;
        flags = query.accept(new JoinFlagsVisitor());
        if ((flags & 0xE000) == 0) {
            if ((flags & 0xFF00) <= TYPE_BITSSHR)
                createArithmeticCode(mv, query, flags);
            else
                createComparisonCode(mv, query, flags);
        }
        else
            createSpecialInstructionCode(mv, query, flags);       
    }
   
    private static void createSpecialInstructionCode (MethodVisitor mv, Join query, int flags) throws Exception {
       
        int type = flags & 0xFF;
        int instruction = (flags & 0xFF00);
       
        switch (instruction) {
            case TYPE_CONJUCTIVE:
                /*int backupUsedLocalVariables = usedLocalVariables, stackSizeBefore = returnBehaviorStack.getSize();
                Join [] elements = ((AbstractBlock.PreConjunctive)query).getComponents();
                Label endLabelConjuctive = new Label();
                returnBehaviorStack.push(ReturnBehavior.getJumpBehavior(endLabelConjuctive));
                for (int i=0; i<elements.length; i++ ) {
                    createASMCode(elements[i], mv);
                }
                usedLocalVariables = backupUsedLocalVariables;
                while (returnBehaviorStack.getSize() > stackSizeBefore)
                    returnBehaviorStack.pop();
                mv.visitLabel(endLabelConjuctive);
                returnBehaviorStack.insertReturnCode(true, mv, returnBehaviorStack.getSize());*/
               
                //int stackSizeBefore = returnBehaviorStack.getSize();
                returnBehaviorStack.saveStack();
                Join [] elements = ((AbstractBlock.PreConjunctive)query).getComponents();
                for (int i=0; i<elements.length; i++ ) {
                    createASMCode(elements[i], mv);
                }
               
                returnBehaviorStack.restoreStack();
                //returnBehaviorStack.insertReturnCode(true, mv);
                break;
               
            case TYPE_BOOL:
                createASMCode( ((Bool)query).getComponentInternal(0), mv);
                /*Label endLabelBool = new Label();
                int backupUsedLocalVariablesBool = usedLocalVariables, stackSizeBeforeBool = returnBehaviorStack.getSize();
                returnBehaviorStack.push(ReturnBehavior.getJumpBehavior(endLabelBool));
                preliminaryStoreValue(mv, query.getArg(0));
                mv.visitLdcInsn(new Integer(0));
                storeValue(mv, query.getArg(0), TYPE_INT);
                createASMCode( ((Bool)query).getComponentInternal(0), mv);
                preliminaryStoreValue(mv, query.getArg(0));
                mv.visitLdcInsn(new Integer(1));
                storeValue(mv, query.getArg(0), TYPE_INT);
                mv.visitLabel(endLabelBool);
                usedLocalVariables = backupUsedLocalVariablesBool;
                while (returnBehaviorStack.getSize() > stackSizeBeforeBool)
                    returnBehaviorStack.pop();*/
                break;
             
            case TYPE_RANGE_CONTAINS:
               
                if ((query.getArg(2) & VAR_READ_FLAG) != 0) {
                    Label checkedLabel = new Label();
                    //check the range
                    for (int i=0; i<2; i++) {
                        pushValue(mv, query.getArg(i), type);
                        pushValue(mv, query.getArg(2), type);
                        if (type == TYPE_INT)   mv.visitJumpInsn( (i == 0 ? IF_ICMPGE : IF_ICMPLE), checkedLabel);
                        else {
                            mv.visitInsn(LCMP);
                            mv.visitJumpInsn( (i == 0 ? IFGE : IFLE), checkedLabel);
                        }
                    }
                    returnBehaviorStack.insertReturnCode(false, mv);
                    mv.visitLabel(checkedLabel);
                }
                else {
                    pushValue(mv, query.getArg(1), type);
                    mv.visitVarInsn(ast.getSpecialCommand(TYPE_STORE, type), 1 + usedLocalVariables);
                    pushValue(mv, query.getArg(0), type);
                    mv.visitVarInsn(ast.getSpecialCommand(TYPE_STORE, type), (type == TYPE_LONG ? 3 : 2) + usedLocalVariables );
                    Label iterationLabel = new Label();
                    Label checkLabel = new Label();
                    Label endLabel = new Label();                   
                    mv.visitJumpInsn(GOTO, checkLabel);
                   
                    mv.visitLabel(iterationLabel);
                    mv.visitVarInsn(ast.getSpecialCommand(TYPE_LOAD, type), (type == TYPE_LONG ? 3 : 2) + usedLocalVariables );
                    if (type == TYPE_INT)       mv.visitLdcInsn(new Integer(1));
                    else                        mv.visitLdcInsn(new Long(1));
                    mv.visitInsn( ast.getArithmeticInstruction(TYPE_ADD, type) );
                    mv.visitVarInsn(ast.getSpecialCommand(TYPE_STORE, type), (type == TYPE_LONG ? 3 : 2) + usedLocalVariables );
                   
                    mv.visitLabel(checkLabel);
                    //mv.visitInsn( ast.getStackCommand(DUP, type) );
                    preliminaryStoreValue(mv, query.getArg(2));
                    mv.visitVarInsn(ast.getSpecialCommand(TYPE_LOAD, type), (type == TYPE_LONG ? 3 : 2) + usedLocalVariables );
                    storeValue(mv, query.getArg(2), type);
                    mv.visitVarInsn(ast.getSpecialCommand(TYPE_LOAD, type), 1 + usedLocalVariables );
                    mv.visitVarInsn(ast.getSpecialCommand(TYPE_LOAD, type), (type == TYPE_LONG ? 3 : 2) + usedLocalVariables );
                    //storeValueWithoutPreliminary(mv, query.getArg(2), type);
                    //mv.visitInsn( ast.getStackCommand(DUP_X1, type) );
                    //mv.visitInsn( ast.getStackCommand(DUP_X1, type) );
                    if (type == TYPE_INT)   mv.visitJumpInsn(IF_ICMPGE, endLabel);
                    else {
                        mv.visitInsn(LCMP);
                        mv.visitJumpInsn(IFGE, endLabel);
                    }       
                    //mv.visitInsn( ast.getStackCommand(POP, type) );
                    //mv.visitInsn( ast.getStackCommand(POP, type) );
                   
                    returnBehaviorStack.insertReturnCode(false, mv);
                   
                   
                    mv.visitLabel(endLabel);
                    returnBehaviorStack.push( ReturnBehavior.getJumpBehavior(iterationLabel) );
                    usedLocalVariables += (type == TYPE_LONG ? 4 : 2);
                }
                break;
               
            case TYPE_REDUCTION:
                /*ReductionImpl extends Reduction
                    {
                    public static final boolean DEBUG = false;

                    protected Join body;
                    protected int initialised_count;
                    protected Reductor[] reductors;*/
                Join body = ((ReductionImpl)query).getComponentInternal(0);
                Reductor[] reductors = ((ReductionImpl)query).getReductors();
               
                int startUsedLocalVariables = usedLocalVariables;
                int reductorsArguments [][] = new int [reductors.length][3];
                for (int i=0; i<reductors.length; i++) {
                    int reductorFlags = reductors[i].accept(new ReductorFlagsVisitor() );
                    if ((reductorFlags & 0xFF00) == REDUCTOR_EXISTS) {
                        preliminaryStoreValue(mv, reductors[i].getArg( 1 ));
                        mv.visitLdcInsn(new Integer(0));
                        storeValue(mv, reductors[i].getArg( 1 ), TYPE_INT);
                        //reductorsArguments[i][0] = reductors[i].getArg( 0 );
                        reductorsArguments[i][1] = reductors[i].getArg( 1 );
                        reductorsArguments[i][2] = reductorFlags;
                    } else if ((reductorFlags & 0xFF00) == REDUCTOR_METHOD_ADAPTER) {
                        reductorsArguments[i][0] = reductors[i].getArg( 0 );
                        reductorsArguments[i][1] = reductors[i].getArg( 1 );
                        reductorsArguments[i][2] = reductorFlags;
                    } else {
                        if ((reductorFlags & 0xFF00) == REDUCTOR_ARRAY)
                        {
                            mv.visitLdcInsn(0);
                            mv.visitVarInsn(ISTORE, 1 + usedLocalVariables );
                            ++usedLocalVariables;
                            mv.visitIntInsn(BIPUSH, 32);
                            if ((reductorFlags & 0xFF) == TYPE_OBJECT)
                                mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
                            else
                                mv.visitIntInsn(NEWARRAY, ast.getReductorArray(reductorFlags));
                        }
                        else {
                            mv.visitTypeInsn(NEW, ast.getReductorTypeName(reductorFlags));
                            mv.visitInsn(DUP);
                            if ((reductorFlags & 0xFF00) != REDUCTOR_DEFAULTMAP)
                                mv.visitMethodInsn(INVOKESPECIAL, ast.getReductorTypeName(reductorFlags), "<init>", "()V");
                            else {
                                pushValue(mv, reductors[i].getArg(0), TYPE_OBJECT);
                                mv.visitMethodInsn(INVOKESPECIAL, ast.getReductorTypeName(reductorFlags), "<init>", "(Ljava/lang/Object;)V");
                            }
                        }

                        mv.visitVarInsn(ASTORE, 1 + usedLocalVariables );
                        preliminaryStoreValue (mv, reductors[i].getArg( ((reductorFlags & 0xFF00) == REDUCTOR_SET ? 1 : 2) + ((reductorFlags & 0xFF00) == REDUCTOR_DEFAULTMAP ? 1 : 0) ) );
                        mv.visitVarInsn(ALOAD, 1 + usedLocalVariables );
                        storeValue (mv, reductors[i].getArg( ((reductorFlags & 0xFF00) == REDUCTOR_SET ? 1 : 2) + ((reductorFlags & 0xFF00) == REDUCTOR_DEFAULTMAP ? 1 : 0) ), TYPE_OBJECT);
                        reductorsArguments[i][0] = reductors[i].getArg( 0 + ((reductorFlags & 0xFF00) == REDUCTOR_DEFAULTMAP ? 1 : 0) );
                        if ((reductorFlags & 0xFF00) != REDUCTOR_SET)
                            reductorsArguments[i][1] = reductors[i].getArg( 1 + ((reductorFlags & 0xFF00) == REDUCTOR_DEFAULTMAP ? 1 : 0) );
                        reductorsArguments[i][2] = reductorFlags;
                        ++usedLocalVariables;
                        if ((reductorFlags & 0xFF0000) == WITH_INNER_REDUCTOR)
                            reductors[i] = reductors[i].getInnerReductor();
                    }
                }
               
                Label endLabelReduction = new Label();
                returnBehaviorStack.saveStack();
                returnBehaviorStack.push( ReturnBehavior.getReductionBehavior(endLabelReduction, startUsedLocalVariables, reductorsArguments, reductors ) );
                createASMCode(body, mv);
                returnBehaviorStack.insertReturnCode(true, mv);
                returnBehaviorStack.restoreStack();
                //usedLocalVariables = startUsedLocalVariables;
                mv.visitLabel(endLabelReduction);
                returnBehaviorStack.insertReturnCode(true, mv);
                break;
               
            case TYPE_CONTAINS:
            case TYPE_LOOKUP:
            case TYPE_ARRAY_LOOKUP:
               
                //final int startIndex = (instruction == TYPE_CONTAINS ? 5 : 10);
                final int elementLength = (instruction == TYPE_CONTAINS ? 1 : 2);
               
                insertComment(mv, (instruction == TYPE_CONTAINS ? "START CONTAINS" : "START LOOKUP") );
                int source_ty = (query.getArg(1) >> VAR_TABLE_SHIFT) & VAR_TABLE_MASK;
                if (instruction == TYPE_ARRAY_LOOKUP)
                    source_ty = type;
                Label nextIteration = new Label();
                Label finishContains = new Label();
                pushValue(mv, query.getArg(0), TYPE_OBJECT);               
               
                if (instruction != TYPE_ARRAY_LOOKUP) {
                    mv.visitInsn(DUP);
                    mv.visitTypeInsn(INSTANCEOF, ast.getContainerName(flags));
                    Label isInstance = new Label();
                    mv.visitJumpInsn(IFNE, isInstance);

                    //mv.visitTypeInsn(CHECKCAST, ast.getJavaContainerName(flags) );
                    //mv.visitTypeInsn(CHECKCAST, "java/util/HashSet" );
                    pushValue(mv, query.getArg(1), TYPE_OBJECT);
                    mv.visitMethodInsn(INVOKEINTERFACE, ast.getJavaContainerName(flags), ast.getJavaContainerMethodName(flags), (instruction == TYPE_CONTAINS ? "(Ljava/lang/Object;)Z" : "(Ljava/lang/Object;)Ljava/lang/Object;") );
                    //mv.visitMethodInsn(INVOKEVIRTUAL, ast.getJavaContainerName(flags), ast.getJavaContainerMethodName(flags), (instruction == TYPE_CONTAINS ? "(Ljava/lang/Object;)Z" : "(Ljava/lang/Object;)Ljava/lang/Object;") );
                    Label javaComparisonFailed = new Label();
                    if (instruction == TYPE_CONTAINS)
                        mv.visitJumpInsn(IFEQ, javaComparisonFailed);
                    else {
                        mv.visitInsn(DUP);
                        Label javaComparisonNotNull = new Label();
                        mv.visitJumpInsn(IFNONNULL, javaComparisonNotNull);
                        mv.visitInsn(POP);
                        mv.visitJumpInsn(GOTO, javaComparisonFailed);

                        mv.visitLabel(javaComparisonNotNull);
                        pushValue(mv, query.getArg(2), TYPE_OBJECT);
                        //returnBehaviorStack.saveStack();               
                        //returnBehaviorStack.push(ReturnBehavior.getJumpBehavior(javaComparisonFailed));                                   
                        createComparisonCode(mv, null, TYPE_EQ | TYPE_OBJECT, ReturnBehavior.getJumpBehavior(javaComparisonFailed));
                        //returnBehaviorStack.restoreStack();
                    }

                    returnBehaviorStack.insertReturnCode(true, mv);
                    mv.visitJumpInsn(GOTO, finishContains);
                    mv.visitLabel(javaComparisonFailed);
                    returnBehaviorStack.insertReturnCode(false, mv);
                    mv.visitJumpInsn(GOTO, finishContains);

                    mv.visitLabel(isInstance);
                    mv.visitTypeInsn(CHECKCAST, ast.getContainerName(flags) );
                }
               
                //returnBehaviorStack.saveStack();               
                //returnBehaviorStack.push(ReturnBehavior.getJumpBehavior(nextIteration));               
               
                if (instruction != TYPE_ARRAY_LOOKUP)
                    mv.visitMethodInsn(INVOKEVIRTUAL, ast.getContainerName(flags), "getRepresentation", "()[Ljava/lang/Object;" );                                   
                mv.visitInsn(DUP);
                mv.visitVarInsn(ASTORE, 1 + usedLocalVariables );
                if (instruction == TYPE_ARRAY_LOOKUP)
                    mv.visitTypeInsn(CHECKCAST, "[" + ast.getTypeSpecifier( (type) ) );
                mv.visitInsn(ARRAYLENGTH);
                //mv.visitLdcInsn(new Integer(arrayLength));
                //mv.visitInsn(ISUB);
                //mv.visitLdcInsn( new Integer(startIndex) );             
                mv.visitLdcInsn( new Integer(0) );
                Label startLoop = new Label();
                mv.visitLabel(startLoop);
                mv.visitInsn(DUP2);
               
                Label endArrayCheck = new Label();  
                mv.visitJumpInsn(IF_ICMPEQ, endArrayCheck);
               
                mv.visitInsn(DUP);
                mv.visitVarInsn(ALOAD, 1 + usedLocalVariables );
                if (instruction == TYPE_ARRAY_LOOKUP)
                    mv.visitTypeInsn(CHECKCAST, "[" + ast.getTypeSpecifier( (type) ) );
                mv.visitInsn(SWAP);
                mv.visitInsn(ast.getArrayInstruction(ARRAY_INSTR_LOAD| (instruction != TYPE_ARRAY_LOOKUP ? TYPE_OBJECT : type) ));
                Label elementIsNull = new Label();
                if ((instruction != TYPE_ARRAY_LOOKUP ? TYPE_OBJECT : type) == TYPE_OBJECT) {
                    mv.visitInsn(DUP);                   
                    mv.visitJumpInsn(IFNULL, elementIsNull);
                }
               
                if ( (query.getArg(1) & VAR_READ_FLAG) != 0 ) {
                //if (((query.getArg(1) >> VAR_TABLE_SHIFT) & VAR_TABLE_MASK) != TYPE_WILDCARD) {
                    if (instruction != TYPE_ARRAY_LOOKUP)
                        castValue(mv, TYPE_OBJECT, source_ty );
                    pushValue(mv, query.getArg(1), source_ty);               
                    createComparisonCode(mv, null, TYPE_EQ | source_ty, ReturnBehavior.getJumpBehavior(nextIteration));              
                } else
                    mv.visitInsn(POP);
               
                if (instruction == TYPE_LOOKUP || instruction == TYPE_ARRAY_LOOKUP) {
                    mv.visitInsn(DUP);
                    mv.visitLdcInsn(new Integer(1));
                    mv.visitInsn(IADD);
                    mv.visitVarInsn(ALOAD, 1 + usedLocalVariables );
                    if (instruction == TYPE_ARRAY_LOOKUP)
                        mv.visitTypeInsn(CHECKCAST, "[" + ast.getTypeSpecifier( (type) ) );
                    mv.visitInsn(SWAP);
                    mv.visitInsn(ast.getArrayInstruction(ARRAY_INSTR_LOAD|(instruction != TYPE_ARRAY_LOOKUP ? TYPE_OBJECT : type)));
                    if ((instruction != TYPE_ARRAY_LOOKUP ? TYPE_OBJECT : type) == TYPE_OBJECT) {
                        mv.visitInsn(DUP);                   
                        mv.visitJumpInsn(IFNULL, elementIsNull);
                    }

                    if ( (query.getArg(2) & VAR_READ_FLAG) != 0 ) {
                    //if (((query.getArg(1) >> VAR_TABLE_SHIFT) & VAR_TABLE_MASK) != TYPE_WILDCARD) {
                        if (instruction != TYPE_ARRAY_LOOKUP)
                            castValue(mv, TYPE_OBJECT, source_ty );
                        pushValue(mv, query.getArg(2), source_ty);
                        createComparisonCode(mv, null, TYPE_EQ | source_ty, ReturnBehavior.getJumpBehavior(nextIteration));
                    } else
                        mv.visitInsn(POP);
                }
               
                //returnBehaviorStack.restoreStack();
               
                mv.visitInsn(POP);
                mv.visitInsn(POP);
                returnBehaviorStack.insertReturnCode(true, mv);
                mv.visitJumpInsn(GOTO, finishContains);
                mv.visitLabel(elementIsNull);
                mv.visitInsn(POP);
                mv.visitLabel(nextIteration);
                mv.visitLdcInsn(new Integer(elementLength));
                mv.visitInsn(IADD);
                mv.visitJumpInsn(GOTO, startLoop);
               
                mv.visitLabel(endArrayCheck);
                mv.visitInsn(POP);
                mv.visitInsn(POP);
                returnBehaviorStack.insertReturnCode(false, mv);
                mv.visitLabel(finishContains);
                break;
               
            case TYPE_POLY_LOOKUP:
                insertComment(mv, "START POLY_LOOKUP" );
                pushValue(mv, query.getArg(0), TYPE_OBJECT);
               
                /*
                 * case TYPE_INT:
                return "I";
            case TYPE_LONG:
                return "J";
            case TYPE_DOUBLE:
                return "D";
            case TYPE_OBJECT:
                return "Ljava/lang/Object;";
            case TYPE_STRING:
                return "Ljava/lang/String;";
            case TYPE_CHAR:
                return "C";
            case TYPE_SHORT:
                return "S";
            case TYPE_BYTE:
                return "B";
            case TYPE_BOOLEAN:
                return "Z";
            case TYPE_FLOAT:
                return "F";
                 */
                final String [][] checkInstances = { {"java/util/Map", "java/util/Set", "edu/umass/pql/container/PMap", "edu/umass/pql/container/PDefaultMap"}, {"[I"}, {"[J"}, {"[D"}, {"[C"}, {"[S"}, {"[B"}, {"[Z"}, {"[F"}, {"[Ljava/lang/Object;"} };
                final int [] instanceFlags = {TYPE_LOOKUP, TYPE_ARRAY_LOOKUP|TYPE_INT, TYPE_ARRAY_LOOKUP|TYPE_LONG, TYPE_ARRAY_LOOKUP|TYPE_DOUBLE, TYPE_ARRAY_LOOKUP|TYPE_CHAR, TYPE_ARRAY_LOOKUP|TYPE_SHORT, TYPE_ARRAY_LOOKUP|TYPE_BYTE, TYPE_ARRAY_LOOKUP|TYPE_BOOLEAN, TYPE_ARRAY_LOOKUP|TYPE_FLOAT, TYPE_ARRAY_LOOKUP|TYPE_OBJECT};
                Label endCheck = new Label();
                for (int i=0; i<checkInstances.length; i++) {
                    Label nextCheck = new Label();
                    Label validSubCheck = new Label();
                    for (int j=0; j<checkInstances[i].length; j++) {                       
                        mv.visitInsn(DUP);
                        mv.visitTypeInsn(INSTANCEOF, checkInstances[i][j]);
                        mv.visitJumpInsn(IFNE, validSubCheck);
                        if (j == checkInstances[i].length-1)
                            mv.visitJumpInsn(GOTO, nextCheck);
                    }
                    mv.visitLabel(validSubCheck);
                    mv.visitInsn(POP);
                    createSpecialInstructionCode(mv, query, instanceFlags[i]);
                    mv.visitJumpInsn(GOTO, endCheck);
                    mv.visitLabel(nextCheck);
                }
                mv.visitInsn(POP);
                mv.visitTypeInsn(NEW, "java/lang/Exception");
                mv.visitInsn(DUP);
                mv.visitLdcInsn(new String("the specified object is not a valid object for POLY_LOOKUP."));
                mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Exception", "<init>", "(Ljava/lang/String;)V");
                mv.visitInsn(ATHROW);               
                mv.visitLabel(endCheck);
                break;
               
            case TYPE_COERCION:
                insertComment(mv, "START COERCION" );
                preliminaryStoreValue(mv, query.getArg(1));
                pushValue(mv, query.getArg(0), (type != TYPE_FLOAT ? TYPE_INT : TYPE_DOUBLE));               
                castValue(mv, (type != TYPE_FLOAT ? TYPE_INT : TYPE_DOUBLE), type);
                storeValue(mv, query.getArg(1), (type != TYPE_FLOAT ? TYPE_INT : TYPE_FLOAT) );
                break;
               
            case TYPE_FIELD:
                insertComment(mv, "START FIELD" );
                Object preField = ((Field)query).getField();
                if (!(preField instanceof java.lang.reflect.Field))
                    throw new Exception("Field member has to be instance of java.lang.reflect.Field");
                java.lang.reflect.Field field = ((java.lang.reflect.Field)preField);
                       
                String fieldName = field.getType().getName();
                Label notInstance = new Label();

                if ( (query.getArg(1) & VAR_READ_FLAG) == 0 ) {
                    preliminaryStoreValue(mv, query.getArg(1));
                    pushValue(mv, query.getArg(0), TYPE_OBJECT);
                    mv.visitInsn(DUP);
                    mv.visitTypeInsn(INSTANCEOF, field.getDeclaringClass().getName().replace(".", "/") );                   
                    Label isInstance = new Label();
                    mv.visitJumpInsn(IFNE, isInstance);                   
                    mv.visitInsn(POP);
                    mv.visitInsn(POP);
                    mv.visitJumpInsn(GOTO, notInstance);    
                    mv.visitLabel(isInstance);
                    mv.visitTypeInsn(CHECKCAST, field.getDeclaringClass().getName().replace(".", "/") );
                    mv.visitFieldInsn(GETFIELD, field.getDeclaringClass().getName().replace(".", "/"), field.getName(), ast.fieldNameToTypeName(fieldName) );
                    storeValue(mv, query.getArg(1), ast.fieldNameToType(fieldName));                   
                } else {                   
                    pushValue(mv, query.getArg(0), TYPE_OBJECT);
                    mv.visitInsn(DUP);
                    mv.visitTypeInsn(INSTANCEOF, field.getDeclaringClass().getName().replace(".", "/") );                   
                    mv.visitJumpInsn(IFEQ, notInstance);
                    mv.visitTypeInsn(CHECKCAST, field.getDeclaringClass().getName().replace(".", "/") );
                    mv.visitFieldInsn(GETFIELD, field.getDeclaringClass().getName().replace(".", "/"), field.getName(), ast.fieldNameToTypeName(fieldName) );
                    pushValue(mv, query.getArg(1), ast.fieldNameToType(fieldName));
                    createComparisonCode(mv, null, TYPE_EQ | ast.fieldNameToType(fieldName));
                }
               
                Label endField = new Label();
                mv.visitJumpInsn(GOTO, endField);
                mv.visitLabel(notInstance);
                mv.visitInsn(POP);
                returnBehaviorStack.insertReturnCode(false, mv);
                mv.visitLabel(endField);
                       
                break;
               
            default:
                throw new Exception("unknown instruction (code: " + instruction + ")");
        }
       
    }
   
    private static void createArithmeticCode (MethodVisitor mv, Join query, int flags) throws Exception {
   
        int type = flags & 0xFF;
        int instruction = (flags & 0xFF00);
        int totalArgs = ((instruction != TYPE_BITINV && instruction != TYPE_NEG) ? 3 : 2);
       
        if ( (query.getArg(totalArgs-1) & VAR_READ_FLAG) == 0 )
            preliminaryStoreValue(mv, query.getArg(totalArgs-1))

        //push one or two values to calculate (argument-amount depends on the operator)
        pushValue(mv, query.getArg(0), type);
        if (instruction != TYPE_BITINV && instruction != TYPE_NEG) {
            if ((instruction == TYPE_BITSHL || instruction == TYPE_BITSHR || instruction == TYPE_BITSSHR) && type == TYPE_LONG)
                pushValue(mv, query.getArg(1), TYPE_INT);
            else
                pushValue(mv, query.getArg(1), type);
        }
        if (instruction == TYPE_BITINV) {
            if (type == TYPE_INT) mv.visitLdcInsn(new Integer(-1));
            else if (type == TYPE_LONG) mv.visitLdcInsn(new Long(-1));
            else throw new Exception("this combination of instruction and type is not implemented (yet).");
        }
       
        //divisor = 0 ?
        if (instruction == TYPE_DIV || instruction == TYPE_MOD) {
            Label l1 = new Label();
            if (type == TYPE_DOUBLE) {
                mv.visitInsn(DUP2);
                mv.visitInsn(DCONST_0);
                mv.visitInsn(DCMPG);
            } else if (type == TYPE_LONG) {
                mv.visitInsn(DUP2);
                mv.visitInsn(LCONST_0);
                mv.visitInsn(LCMP);
            } else if (type == TYPE_INT)
                mv.visitInsn(DUP);
            mv.visitJumpInsn(IFNE, l1);
            for (int i=0; i<2; i++) {
                if (type == TYPE_INT)
                    mv.visitInsn(POP);
                else
                    mv.visitInsn(POP2);
            }
            //pop values, before return
            if ( (query.getArg(totalArgs-1) & VAR_READ_FLAG) == 0 ) {
                mv.visitInsn(POP);
                mv.visitInsn(POP);
            }
            returnBehaviorStack.insertReturnCode(false, mv);
            mv.visitLabel(l1);
        }
       
        //calculate solution
        mv.visitInsn( ast.getArithmeticInstruction( instruction, type) );
       
        //write-flag => write and return true / otherwise check and return true when solution is correct
        if ( (query.getArg(totalArgs-1) & VAR_READ_FLAG) == 0 )
            storeValue(mv, query.getArg(totalArgs-1), type);   
        else {
            pushValue(mv, query.getArg(totalArgs-1), type);
            Label l0 = new Label();

            if (type == TYPE_DOUBLE)
                mv.visitInsn(DCMPG);
            else if (type == TYPE_LONG)
                mv.visitInsn(LCMP);
            else if (type == TYPE_INT)
                mv.visitInsn( ast.getArithmeticInstruction( TYPE_SUB, type) );
            mv.visitJumpInsn(IFEQ, l0);
            returnBehaviorStack.insertReturnCode(false, mv);
            mv.visitLabel(l0);
        }

        returnBehaviorStack.insertReturnCode(true, mv);
    }
   
    private static void createComparisonCode (MethodVisitor mv, Join query, int flags) throws Exception {
        createComparisonCode (mv, query, flags, null);
    }
   
    private static void createComparisonCode (MethodVisitor mv, Join query, int flags, ReturnBehavior individualReturnBehavior) throws Exception {
   
        int type = flags & 0xFF;
        int instruction = (flags & 0xFF00);
       
        /*pushValue(mv, query.getArg(0), type);
        insertDebugInformation(mv, "Nummer 1: ");
        insertDebugInformation(mv, TYPE_DOUBLE);       
        pushValue(mv, query.getArg(1), type);
        insertDebugInformation(mv, "Nummer 2: ");
        insertDebugInformation(mv, TYPE_DOUBLE);*/
        Label endComparisonLabel = new Label();

        if (query != null && (query.getArg(1) & VAR_READ_FLAG) == 0 && instruction == TYPE_EQ) {
            preliminaryStoreValue (mv, query.getArg(1));
            pushValue(mv, query.getArg(0), type);
            storeValue (mv, query.getArg(1), type);
        } else {
            if (query != null) {
                pushValue(mv, query.getArg(0), type);
                pushValue(mv, query.getArg(1), type);
            }
            Label falseLabel = new Label();
            Label endLabel = new Label();
            if (type == TYPE_FLOAT) {
                mv.visitInsn(F2D);
                mv.visitInsn(DUP2_X1);
                mv.visitInsn(POP2);
                mv.visitInsn(F2D);
                mv.visitInsn(DUP2_X2);
                mv.visitInsn(POP2);
                type = TYPE_DOUBLE;
            }
            if (type == TYPE_LONG || type == TYPE_DOUBLE) {
                mv.visitInsn( (type == TYPE_LONG ? LCMP : DCMPG) );
                switch (instruction) {
                    case TYPE_EQ: mv.visitJumpInsn(IFEQ, endLabel); break;
                    case TYPE_NEQ: mv.visitJumpInsn(IFNE, endLabel); break;
                    case TYPE_LT: mv.visitJumpInsn(IFLT, endLabel); break;
                    case TYPE_LTE: mv.visitJumpInsn(IFLE, endLabel); break;
                    default: throw new Exception("this combination of instruction and type is not implemented (yet).");
                }
            }
            else if (type == TYPE_INT || type == TYPE_CHAR || type == TYPE_BOOLEAN || type == TYPE_BYTE || type == TYPE_SHORT) {
                switch (instruction) {
                    case TYPE_EQ: mv.visitJumpInsn(IF_ICMPEQ, endLabel); break;
                    case TYPE_NEQ: mv.visitJumpInsn(IF_ICMPNE, endLabel); break;
                    case TYPE_LT: mv.visitJumpInsn(IF_ICMPLT, endLabel); break;
                    case TYPE_LTE: mv.visitJumpInsn(IF_ICMPLE, endLabel); break;
                    default: throw new Exception("this combination of instruction and type is not implemented (yet).");
                }
            }
            //else if (type == TYPE_OBJECT || type == TYPE_STRING) {
            else if (type == TYPE_OBJECT) {
                mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z");               
                switch (instruction) {
                    case TYPE_EQ: mv.visitJumpInsn(IFNE, endLabel); break;
                    case TYPE_NEQ: mv.visitJumpInsn(IFEQ, endLabel); break;
                    default: throw new Exception("this combination of instruction and type is not implemented (yet).");
                }
            }
            else if (type == TYPE_STRING) {
                //mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
                switch (instruction) {
                    case TYPE_EQ: mv.visitJumpInsn(IF_ACMPEQ, endLabel); break;
                    case TYPE_NEQ: mv.visitJumpInsn( (type == TYPE_OBJECT ? IF_ACMPNE : IF_ACMPEQ) , endLabel); break;
                    default: throw new Exception("this combination of instruction and type is not implemented (yet).");
                    /*case TYPE_EQ: mv.visitJumpInsn(IF_ICMPEQ, endLabel); break;
                    case TYPE_NEQ: mv.visitJumpInsn(IF_ICMPNE, endLabel); break;
                    default: throw new Exception("this combination of instruction and type is not implemented (yet).");*/
                }
                if (type == TYPE_STRING) {
                    pushValue(mv, query.getArg(0), type);
                    mv.visitJumpInsn( IFNULL, falseLabel);
                    pushValue(mv, query.getArg(0), type);
                    pushValue(mv, query.getArg(1), type);
                    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
                    mv.visitJumpInsn(IFNE, endLabel);
                    mv.visitLabel(falseLabel);
                }
            } else
                throw new Exception("this combination of instruction and type is not implemented (yet).");

            if (individualReturnBehavior == null)
                returnBehaviorStack.insertReturnCode( (type == TYPE_STRING && instruction == TYPE_NEQ), mv);
            else
                individualReturnBehavior.insertReturnCode( (type == TYPE_STRING && instruction == TYPE_NEQ), mv, null);
            mv.visitJumpInsn(GOTO, endComparisonLabel);
            mv.visitLabel(endLabel);           
        }
        if (individualReturnBehavior == null)
            returnBehaviorStack.insertReturnCode(!(type == TYPE_STRING && instruction == TYPE_NEQ), mv);
        else
            individualReturnBehavior.insertReturnCode( !(type == TYPE_STRING && instruction == TYPE_NEQ), mv, null);
        mv.visitLabel(endComparisonLabel);
    }
   
    protected static void pushValue (MethodVisitor mv, int val, int type) throws Exception {
       
        if (type == TYPE_STRING)
            type = TYPE_OBJECT;
       
        final int index = val >> VAR_INDEX_SHIFT;
        final int source_ty = (val >> VAR_TABLE_SHIFT) & VAR_TABLE_MASK;
       
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, "edu/umass/pql/Env", ast.getTypeArrayName(source_ty), "[" + ast.getTypeSpecifier(source_ty) );
        mv.visitLdcInsn(new Integer(index));
        mv.visitInsn( ast.getArrayInstruction(source_ty|ARRAY_INSTR_LOAD));
        castValue(mv, source_ty, type);
    }
   
    protected static void preliminaryStoreValue (MethodVisitor mv, int val) throws Exception {
       
        final int index = val >> VAR_INDEX_SHIFT;
        final int source_ty = (val >> VAR_TABLE_SHIFT) & VAR_TABLE_MASK;
       
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, "edu/umass/pql/Env", ast.getTypeArrayName(source_ty)"[" + ast.getTypeSpecifier(source_ty) );
        mv.visitLdcInsn(new Integer(index));
    }
   
    protected static void storeValue (MethodVisitor mv, int val, int type) throws Exception {
        final int source_ty = (val >> VAR_TABLE_SHIFT) & VAR_TABLE_MASK;
        storeValue(mv, val, type, source_ty);
    }
   
    protected static void storeValue (MethodVisitor mv, int val, int type, int sourceType) throws Exception {
       
        //final int index = val >> VAR_INDEX_SHIFT;
       
        final int source_ty = (val >> VAR_TABLE_SHIFT) & VAR_TABLE_MASK;
        castValue(mv, type, sourceType);
        if (sourceType != source_ty)
            castValue(mv, sourceType, source_ty);
       
        /*if (source_ty == TYPE_DOUBLE)
            mv.visitVarInsn(DSTORE, 1);
        else if (source_ty == TYPE_LONG)
            mv.visitVarInsn(LSTORE, 1);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, "edu/umass/pql/Env", ast.getTypeArrayName(source_ty),  "[" + ast.getTypeSpecifier(source_ty) );
        if (source_ty == TYPE_INT || source_ty == TYPE_OBJECT)
            mv.visitInsn(SWAP);
        mv.visitLdcInsn(new Integer(index));
        if (source_ty == TYPE_INT || source_ty == TYPE_OBJECT)
            mv.visitInsn(SWAP);
        else if (source_ty == TYPE_DOUBLE)
            mv.visitVarInsn(DLOAD, 1);
        else if (source_ty == TYPE_LONG)
            mv.visitVarInsn(LLOAD, 1);*/
        mv.visitInsn(ast.getArrayInstruction(source_ty|ARRAY_INSTR_STORE));
    }
   
    /*protected static void storeValueWithoutPreliminary (MethodVisitor mv, int val, int type) throws Exception {
       
        final int index = val >> VAR_INDEX_SHIFT;
        final int source_ty = (val >> VAR_TABLE_SHIFT) & VAR_TABLE_MASK;
        castValue(mv, type, source_ty);
       
        if (source_ty == TYPE_DOUBLE)
            mv.visitVarInsn(DSTORE, 1);
        else if (source_ty == TYPE_LONG)
            mv.visitVarInsn(LSTORE, 1);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, "edu/umass/pql/Env", ast.getTypeArrayName(source_ty),  "[" + ast.getTypeSpecifier(source_ty) );
        if (source_ty == TYPE_INT || source_ty == TYPE_OBJECT)
            mv.visitInsn(SWAP);
        mv.visitLdcInsn(new Integer(index));
        if (source_ty == TYPE_INT || source_ty == TYPE_OBJECT)
            mv.visitInsn(SWAP);
        else if (source_ty == TYPE_DOUBLE)
            mv.visitVarInsn(DLOAD, 1);
        else if (source_ty == TYPE_LONG)
            mv.visitVarInsn(LLOAD, 1);
        mv.visitInsn(ast.getArrayInstruction(source_ty|ARRAY_INSTR_STORE));
    }*/
   
    protected static void insertSpecialTypeCast (MethodVisitor mv, int from, int to) throws Exception {
        insertComment(mv, "InsertSpecialTypeCast");
        if (from != TYPE_STRING && from != TYPE_FLOAT && from != -1)
            return;
        if (from == TYPE_STRING)
            mv.visitTypeInsn(CHECKCAST, "java/lang/Object");
        else if (to == TYPE_STRING)
            mv.visitTypeInsn(CHECKCAST, "java/lang/String");
        else if (to == TYPE_BOOLEAN) {
            Label noChange = new Label();
            mv.visitInsn(DUP);
            mv.visitJumpInsn(IFEQ, noChange);
            mv.visitInsn(POP);
            mv.visitLdcInsn(new Integer(1));
            mv.visitLabel(noChange);
        }           
        else {
            mv.visitInsn(ast.insertSpecialTypeCast(from, to));
        }
    }
   
    protected static void castValue (MethodVisitor mv, int from, int to) throws Exception {
        if (from != to) {
            if (from >= 5 || to >= 5) {
                int tmpType [] = {TYPE_OBJECT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_INT, TYPE_DOUBLE};
                if (from >= 5) {
                    insertSpecialTypeCast(mv, from, -1);
                    castValue(mv, tmpType[from-5], to);
                } else if (to >= 5) {
                    castValue(mv, from, tmpType[to-5]);
                    insertSpecialTypeCast(mv, -1, to);                   
                }
            }
            else if ( to == TYPE_OBJECT ) {
                switch (from) {
                    case TYPE_INT:
                        mv.visitMethodInsn(INVOKESTATIC, "edu/umass/pql/Env", "canonicalInteger", "(I)Ljava/lang/Integer;");
                        break;
                    case TYPE_LONG:
                        mv.visitMethodInsn(INVOKESTATIC, "edu/umass/pql/Env", "canonicalLong", "(J)Ljava/lang/Long;");
                        break;
                    case TYPE_DOUBLE:
                        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "valueof", "(D)Ljava/lang/Double;");
                        break;
                    default:
                        throw new Exception("the specified type ('" + from + "') is not supported (yet).");
                }
            } else if ( from == TYPE_OBJECT ) {
                String [] checkInstances = {"java/lang/Number", "java/lang/Boolean", "java/lang/Character"};
                Label endCheck = new Label();
                for (int i=0; i<checkInstances.length; i++) {
                    mv.visitInsn(DUP);
                    mv.visitTypeInsn(INSTANCEOF, checkInstances[i]);
                    Label notInstance = new Label();
                    mv.visitJumpInsn(IFEQ, notInstance);
                   
                    mv.visitTypeInsn(CHECKCAST, checkInstances[i]);
                    if (i == 0)
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", ast.getFullTypeSpecifier(to) + "Value", "()" + ast.getTypeSpecifier(to));
                    else if (i == 1) {
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z");
                        if (to != TYPE_INT)
                            mv.visitInsn(ast.getTypeCastFlag("I2" + ast.getTypeSpecifier(to)));
                    } else if (i == 2) {
                        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C");
                        if (to != TYPE_INT)
                            mv.visitInsn(ast.getTypeCastFlag("I2" + ast.getTypeSpecifier(to)));
                    }
                   
                    mv.visitJumpInsn(GOTO, endCheck);
                    mv.visitLabel(notInstance);
                }
                mv.visitTypeInsn(NEW, "java/lang/Exception");
                mv.visitInsn(DUP);
                mv.visitLdcInsn(new String("the specified object cannot be converted in a numerical value."));
                mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Exception", "<init>", "(Ljava/lang/String;)V");
                mv.visitInsn(ATHROW);
                mv.visitLabel(endCheck);
            }
            else
                mv.visitInsn( ast.getTypeCastFlag(ast.getTypeSpecifier(from) + "2" + ast.getTypeSpecifier(to)) );
        }
    }
   
    protected static void insertDebugInformation(MethodVisitor mv, String str) {
        mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        mv.visitLdcInsn(str);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
    }
   
    protected static void insertDebugInformation(MethodVisitor mv, int type) throws Exception {
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/String", "valueOf", "(" + ast.getTypeSpecifier(type) + ")Ljava/lang/String;");
        mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        mv.visitInsn(SWAP);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
    }
   
    protected static void insertComment (MethodVisitor mv, String comment) throws Exception {
        mv.visitLdcInsn(comment);
        mv.visitInsn(POP);
    }
   
}
TOP

Related Classes of edu.umass.bc.RuntimeCreator

TOP
Copyright © 2018 www.massapi.com. 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.