Search in sources :

Example 1 with Array

use of java.lang.reflect.Array in project lucene-solr by apache.

the class RamUsageTester method measureObjectSize.

/*
   * Non-recursive version of object descend. This consumes more memory than recursive in-depth
   * traversal but prevents stack overflows on long chains of objects
   * or complex graphs (a max. recursion depth on my machine was ~5000 objects linked in a chain
   * so not too much).
   */
private static long measureObjectSize(Object root, Accumulator accumulator) {
    // Objects seen so far.
    final Set<Object> seen = Collections.newSetFromMap(new IdentityHashMap<Object, Boolean>());
    // Class cache with reference Field and precalculated shallow size. 
    final IdentityHashMap<Class<?>, ClassCache> classCache = new IdentityHashMap<>();
    // Stack of objects pending traversal. Recursion caused stack overflows. 
    final ArrayList<Object> stack = new ArrayList<>();
    stack.add(root);
    long totalSize = 0;
    while (!stack.isEmpty()) {
        final Object ob = stack.remove(stack.size() - 1);
        if (ob == null || seen.contains(ob)) {
            continue;
        }
        seen.add(ob);
        final Class<?> obClazz = ob.getClass();
        assert obClazz != null : "jvm bug detected (Object.getClass() == null). please report this to your vendor";
        if (obClazz.isArray()) {
            /*
         * Consider an array, possibly of primitive types. Push any of its references to
         * the processing stack and accumulate this array's shallow size. 
         */
            final long shallowSize = RamUsageEstimator.shallowSizeOf(ob);
            final int len = Array.getLength(ob);
            final List<Object> values;
            Class<?> componentClazz = obClazz.getComponentType();
            if (componentClazz.isPrimitive()) {
                values = Collections.emptyList();
            } else {
                values = new AbstractList<Object>() {

                    @Override
                    public Object get(int index) {
                        return Array.get(ob, index);
                    }

                    @Override
                    public int size() {
                        return len;
                    }
                };
            }
            totalSize += accumulator.accumulateArray(ob, shallowSize, values, stack);
        } else {
            /*
         * Consider an object. Push any references it has to the processing stack
         * and accumulate this object's shallow size. 
         */
            try {
                ClassCache cachedInfo = classCache.get(obClazz);
                if (cachedInfo == null) {
                    classCache.put(obClazz, cachedInfo = createCacheEntry(obClazz));
                }
                boolean needsReflection = true;
                if (Constants.JRE_IS_MINIMUM_JAVA9 && obClazz.getName().startsWith("java.")) {
                    // Java 9: Best guess for some known types, as we cannot precisely look into runtime classes:
                    final ToLongFunction<Object> func = SIMPLE_TYPES.get(obClazz);
                    if (func != null) {
                        // some simple type like String where the size is easy to get from public properties
                        totalSize += accumulator.accumulateObject(ob, cachedInfo.alignedShallowInstanceSize + func.applyAsLong(ob), Collections.emptyMap(), stack);
                        needsReflection = false;
                    } else if (ob instanceof Iterable) {
                        final List<Object> values = StreamSupport.stream(((Iterable<?>) ob).spliterator(), false).collect(Collectors.toList());
                        totalSize += accumulator.accumulateArray(ob, cachedInfo.alignedShallowInstanceSize + RamUsageEstimator.NUM_BYTES_ARRAY_HEADER, values, stack);
                        needsReflection = false;
                    } else if (ob instanceof Map) {
                        final List<Object> values = ((Map<?, ?>) ob).entrySet().stream().flatMap(e -> Stream.of(e.getKey(), e.getValue())).collect(Collectors.toList());
                        totalSize += accumulator.accumulateArray(ob, cachedInfo.alignedShallowInstanceSize + RamUsageEstimator.NUM_BYTES_ARRAY_HEADER, values, stack);
                        totalSize += RamUsageEstimator.NUM_BYTES_ARRAY_HEADER;
                        needsReflection = false;
                    }
                }
                if (needsReflection) {
                    final Map<Field, Object> fieldValues = new HashMap<>();
                    for (Field f : cachedInfo.referenceFields) {
                        fieldValues.put(f, f.get(ob));
                    }
                    totalSize += accumulator.accumulateObject(ob, cachedInfo.alignedShallowInstanceSize, fieldValues, stack);
                }
            } catch (IllegalAccessException e) {
                // this should never happen as we enabled setAccessible().
                throw new RuntimeException("Reflective field access failed?", e);
            }
        }
    }
    // Help the GC (?).
    seen.clear();
    stack.clear();
    classCache.clear();
    return totalSize;
}
Also used : Array(java.lang.reflect.Array) IdentityHashMap(java.util.IdentityHashMap) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Collection(java.util.Collection) AbstractList(java.util.AbstractList) Set(java.util.Set) HashMap(java.util.HashMap) Field(java.lang.reflect.Field) PrivilegedAction(java.security.PrivilegedAction) Collectors(java.util.stream.Collectors) File(java.io.File) ArrayList(java.util.ArrayList) List(java.util.List) Stream(java.util.stream.Stream) Modifier(java.lang.reflect.Modifier) Map(java.util.Map) StreamSupport(java.util.stream.StreamSupport) AccessController(java.security.AccessController) ToLongFunction(java.util.function.ToLongFunction) Path(java.nio.file.Path) Collections(java.util.Collections) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) IdentityHashMap(java.util.IdentityHashMap) ArrayList(java.util.ArrayList) Field(java.lang.reflect.Field) AbstractList(java.util.AbstractList) ArrayList(java.util.ArrayList) List(java.util.List) IdentityHashMap(java.util.IdentityHashMap) HashMap(java.util.HashMap) Map(java.util.Map)

Example 2 with Array

use of java.lang.reflect.Array in project intellij-community by JetBrains.

the class Test method counter.

private long counter(Class<? extends Array> list) {
    long count = 0L;
    for (Iterator<? extends Array> it = stream(list).iterator(); it.hasNext(); ) {
        Array array = it.next();
        count++;
    }
    return count;
}
Also used : Array(java.lang.reflect.Array)

Example 3 with Array

use of java.lang.reflect.Array in project groovity by disney.

the class GroovityObjectConverter method convert.

@SuppressWarnings({ "unchecked", "rawtypes" })
public static Object convert(Object in, Type type) {
    if (in == null) {
        return null;
    }
    Class<?> out;
    Type[] typeArguments = null;
    if (type instanceof ParameterizedType) {
        ParameterizedType pt = (ParameterizedType) type;
        out = (Class<?>) pt.getRawType();
        typeArguments = pt.getActualTypeArguments();
    } else {
        out = (Class<?>) type;
    }
    if (out.equals(Object.class)) {
        // special case, no conversion at all
        return in;
    }
    if (type.equals(in.getClass())) {
        return in;
    }
    if (typeArguments == null && out.isAssignableFrom(in.getClass())) {
        return in;
    }
    if (in.getClass().isArray()) {
        return convertIterable(new ArrayIterable(in), out, typeArguments);
    }
    if (List.class.isAssignableFrom(in.getClass())) {
        List inList = (List) in;
        return convertIterable(inList, out, typeArguments);
    }
    if (out.equals(String.class)) {
        return in.toString();
    }
    if (out.isArray()) {
        Object val = convert(in, out.getComponentType());
        if (val != null) {
            // if we're expecting an array back but the input is not an array, let's wrap it
            Object[] ra = (Object[]) Array.newInstance(out.getComponentType(), 1);
            ra[0] = val;
            return ra;
        }
        return Array.newInstance(out.getComponentType(), 0);
    }
    if (out.isEnum()) {
        Enum val = Enum.valueOf((Class<Enum>) out, in.toString());
        return val;
    }
    if (!Number.class.isAssignableFrom(in.getClass())) {
        if (Number.class.isAssignableFrom(out)) {
            String ps = getParseable(in);
            if (ps == null) {
                return null;
            }
            // groovy can only convert single digit number strings for some odd reason, so we have to roll our own
            if (Integer.class.isAssignableFrom(out)) {
                return Integer.parseInt(ps);
            }
            if (Long.class.isAssignableFrom(out)) {
                return Long.parseLong(ps);
            }
            if (Float.class.isAssignableFrom(out)) {
                return Float.parseFloat(ps);
            }
            if (Double.class.isAssignableFrom(out)) {
                return Double.parseDouble(ps);
            }
        }
        if (out.isPrimitive()) {
            String ps = getParseable(in);
            if (ps == null) {
                return null;
            }
            if (out.equals(Integer.TYPE)) {
                return Integer.parseInt(ps);
            }
            if (out.equals(Long.TYPE)) {
                return Long.parseLong(ps);
            }
            if (out.equals(Float.TYPE)) {
                return Float.parseFloat(ps);
            }
            if (out.equals(Double.TYPE)) {
                return Double.parseDouble(ps);
            }
        }
    }
    if (Boolean.class.equals(out) || out == Boolean.TYPE) {
        Class ic = in.getClass();
        if (!Boolean.class.equals(ic) && ic != Boolean.TYPE) {
            String ps = getParseable(in);
            if (ps != null) {
                return Boolean.parseBoolean(ps);
            }
        }
    }
    if (Map.class.isAssignableFrom(out)) {
        Map<Object, Object> result = null;
        if (!out.isInterface()) {
            try {
                result = (Map<Object, Object>) out.newInstance();
            } catch (Exception e) {
            }
        }
        if (result == null) {
            result = new LinkedHashMap<>();
        }
        Type kType;
        Type vType;
        if (typeArguments != null) {
            kType = typeArguments[0];
            vType = typeArguments[1];
        } else {
            kType = Object.class;
            vType = Object.class;
        }
        Map<Object, Object> finalResult = result;
        ModelConsumer consumer = (k, v) -> {
            finalResult.put(convert(k, kType), convert(v, vType));
        };
        consume(in, consumer);
        return finalResult;
    }
    // TODO special handling for string inputs, look for string-based constructors
    if (!out.isPrimitive() && !out.isInterface()) {
        try {
            Constructor<?> c = out.getConstructor();
            Object o = c.newInstance();
            if (o instanceof Model) {
                consume(in, ((Model) o)::put);
            } else {
                consume(in, (k, v) -> {
                    Model.put(o, k, v);
                });
            }
            // System.out.println("USED MODEL TO CONVERT "+in.getClass().getName()+" to "+out.getName());
            return o;
        } catch (Exception e) {
        // e.printStackTrace();
        }
    }
    return DefaultTypeTransformation.castToType(in, out);
}
Also used : LinkedHashMap(java.util.LinkedHashMap) List(java.util.List) DefaultTypeTransformation(org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation) Array(java.lang.reflect.Array) ParameterizedType(java.lang.reflect.ParameterizedType) Iterator(java.util.Iterator) Type(java.lang.reflect.Type) Map(java.util.Map) Model(com.disney.groovity.model.Model) Constructor(java.lang.reflect.Constructor) ModelConsumer(com.disney.groovity.model.ModelConsumer) ArrayList(java.util.ArrayList) ParameterizedType(java.lang.reflect.ParameterizedType) ParameterizedType(java.lang.reflect.ParameterizedType) Type(java.lang.reflect.Type) Model(com.disney.groovity.model.Model) List(java.util.List) ArrayList(java.util.ArrayList) ModelConsumer(com.disney.groovity.model.ModelConsumer)

Example 4 with Array

use of java.lang.reflect.Array in project raml-module-builder by folio-org.

the class AnnotationGrabber method generateMappings.

// ^http.*?//.*?/apis/patrons/.*?/fines/.*
// ^http.*?\/\/.*?\/apis\/patrons\/?(.+?)*
// ^http.*?\/\/.*?\/apis\/([^\/]+)\/([^\/]+)(\?.*)
public static JsonObject generateMappings() throws Exception {
    /* this class is one of the drivers for the client generation
     * check if the plugin set the system property in the pom and only if
     * so generate */
    String clientGen = System.getProperty("client.generate");
    String modDescr = System.getProperty("modDescrptor.generate");
    if (clientGen != null) {
        generateClient = true;
    }
    if ("true".equals(modDescr)) {
        generateModDescrptor = true;
    }
    JsonObject globalClassMapping = new JsonObject();
    // get classes in generated package
    ClassPath classPath = ClassPath.from(Thread.currentThread().getContextClassLoader());
    ImmutableSet<ClassPath.ClassInfo> classes = classPath.getTopLevelClasses(RTFConsts.INTERFACE_PACKAGE);
    Collection<Object> classNames = Collections2.transform(classes, new Function<ClassPath.ClassInfo, Object>() {

        @Override
        public Object apply(ClassPath.ClassInfo input) {
            log.info("Mapping functions in " + input.getName() + " class to appropriate urls");
            // not needed - dont need transform function,
            return input.getName();
        // remove
        }
    });
    // loop over all the classes from the package
    classNames.forEach(val -> {
        try {
            ClientGenerator cGen = new ClientGenerator();
            // ----------------- class level annotations -----------------------//
            // -----------------------------------------------------------------//
            // will contain all mappings for a specific class in the package
            JsonObject classSpecificMapping = new JsonObject();
            // get annotations via reflection for a class
            Annotation[] annotations = Class.forName(val.toString()).getAnnotations();
            // create an entry for the class name = ex. "class":"com.sling.rest.jaxrs.resource.BibResource"
            classSpecificMapping.put(CLASS_NAME, val.toString());
            classSpecificMapping.put(INTERFACE_NAME, val.toString());
            // needed info - these are class level annotation - not method level
            for (int i = 0; i < annotations.length; i++) {
                // get the annotation type - example in jersey would we javax.ws.rs.Path
                Class<? extends Annotation> type = annotations[i].annotationType();
                // function
                for (Method method : type.getDeclaredMethods()) {
                    Object value = method.invoke(annotations[i], (Object[]) null);
                    if (type.isAssignableFrom(Path.class)) {
                        classSpecificMapping.put(CLASS_URL, "^/" + value);
                        if (generateClient) {
                            cGen.generateClassMeta(val.toString(), value);
                        }
                        if (generateModDescrptor && classSpecificMapping.getString(CLASS_URL) != null) {
                            String url = classSpecificMapping.getString(CLASS_URL).substring(2);
                            if (!url.contains("rmbtests")) {
                                MDGenerator.ProvidesEntry pe = MDGenerator.INSTANCE.new ProvidesEntry();
                                if (url.contains("_/tenant")) {
                                    url = "_tenant";
                                }
                                pe.setId(url);
                                MDGenerator.INSTANCE.addProvidesEntry(pe);
                            }
                        }
                    }
                }
            }
            // ----------------- method level annotations ------------ //
            // ------------------------------------------------------- //
            /**
             * will be used only if ModuleDescriptor generation is turned on
             * maps all http verbs to a single url
             */
            mdUrl2Verbs = new HashMap<>();
            JsonArray methodsInAPath;
            // iterate over all functions in the class
            Method[] methods = Class.forName(val.toString()).getMethods();
            for (int i = 0; i < methods.length; i++) {
                JsonObject methodObj = new JsonObject();
                JsonObject params = getParameterNames(methods[i]);
                // get annotations on the method and add all info per method to its
                // own methodObj
                Annotation[] methodAn = methods[i].getAnnotations();
                // System.out.println(methods[i].getName());
                // put the name of the function
                methodObj.put(FUNCTION_NAME, methods[i].getName());
                methodObj.put(METHOD_PARAMS, params);
                for (int j = 0; j < methodAn.length; j++) {
                    Class<? extends Annotation> type = methodAn[j].annotationType();
                    // System.out.println("Values of " + type.getName());
                    if (RTFConsts.POSSIBLE_HTTP_METHOD.contains(type.getName())) {
                        // put the method - get or post, etc..
                        methodObj.put(HTTP_METHOD, type.getName());
                    }
                    boolean replaceAccept = false;
                    if (type.isAssignableFrom(Produces.class)) {
                        // this is the accept header, right now can not send */*
                        // so if accept header equals any/ - change this to */*
                        replaceAccept = true;
                    }
                    for (Method method : type.getDeclaredMethods()) {
                        Object value = method.invoke(methodAn[j], (Object[]) null);
                        if (value.getClass().isArray()) {
                            List<Object> retList = new ArrayList<>();
                            for (int k = 0; k < Array.getLength(value); k++) {
                                if (replaceAccept) {
                                    // replace any/any with */* to allow declaring accpet */* which causes compilation issues
                                    // when declared in raml. so declare any/any in raml instead and replaced here
                                    retList.add(((String) Array.get(value, k)).replaceAll("any/any", ""));
                                } else {
                                    retList.add(Array.get(value, k));
                                }
                            }
                            // put generically things like consumes, produces as arrays
                            // since they can have multi values
                            methodObj.put(type.getName(), retList);
                        } else {
                            if (type.isAssignableFrom(Path.class)) {
                                String path = classSpecificMapping.getString(CLASS_URL) + URL_PATH_DELIMITER + value;
                                String regexPath = getRegexForPath(path);
                                // put path to function
                                methodObj.put(METHOD_URL, path);
                                // put regex path to function
                                methodObj.put(REGEX_URL, regexPath);
                            }
                        // System.out.println(" " + method.getName() + ": " + value.toString());
                        }
                    }
                }
                if (generateClient) {
                    cGen.generateMethodMeta(methodObj.getString(FUNCTION_NAME), methodObj.getJsonObject(METHOD_PARAMS), methodObj.getString(METHOD_URL), methodObj.getString(HTTP_METHOD), methodObj.getJsonArray(CONSUMES), methodObj.getJsonArray(PRODUCES));
                }
                // class
                if (methodObj.getString(METHOD_URL) == null) {
                    methodObj.put(METHOD_URL, classSpecificMapping.getString(CLASS_URL));
                    methodObj.put(REGEX_URL, getRegexForPath(classSpecificMapping.getString(CLASS_URL)));
                }
                if (generateModDescrptor) {
                    String verb = methodObj.getString(HTTP_METHOD);
                    verb = verb.substring(verb.lastIndexOf(".") + 1);
                    String rootURL4Service = classSpecificMapping.getString(CLASS_URL).substring(1);
                    /*if(mdUrl2Verbs.get(path.substring(1)) != null){
              mdUrl2Verbs.get(path.substring(1)).add(verb);
            } else {
              mdUrl2Verbs.put(path.substring(1), new JsonArray());
              mdUrl2Verbs.get(path.substring(1)).add(verb);
            }*/
                    if (mdUrl2Verbs.get(rootURL4Service) != null) {
                        mdUrl2Verbs.get(rootURL4Service).add(verb);
                    } else {
                        mdUrl2Verbs.put(rootURL4Service, new HashSet<String>());
                        mdUrl2Verbs.get(rootURL4Service).add(verb);
                    }
                }
                // this is the key - the regex path is the key to the functions
                // represented by this url
                // an array of functions which answer to this url (with get, delete,
                // post, etc... methods)
                methodsInAPath = classSpecificMapping.getJsonArray(methodObj.getString(REGEX_URL));
                if (methodsInAPath == null) {
                    methodsInAPath = new JsonArray();
                    classSpecificMapping.put(methodObj.getString(REGEX_URL), methodsInAPath);
                }
                methodsInAPath.add(methodObj);
            }
            // System.out.println( val.toString() );
            globalClassMapping.put(classSpecificMapping.getString(CLASS_URL), classSpecificMapping);
            if (generateClient) {
                cGen.generateClass(classSpecificMapping);
            }
            if (generateModDescrptor) {
                BiConsumer<String, Set<String>> biConsumer = (key, value) -> {
                    if (!key.contains("_/tenant") && !key.contains("rmbtests")) {
                        MDGenerator.RoutingEntry re = MDGenerator.INSTANCE.new RoutingEntry();
                        JsonArray ja = new JsonArray();
                        value.forEach(verb -> {
                            ja.add(verb);
                        });
                        re.setMethods(ja);
                        re.setEntryPath(key);
                        re.setLevel("30");
                        re.setType("request-response");
                        MDGenerator.INSTANCE.addRoutingEntry(re);
                    }
                };
                mdUrl2Verbs.forEach(biConsumer);
                MDGenerator.INSTANCE.generateMD();
                // this is needed when the MDGenerator is used to generate
                // partial MDs in submodules. the system variable is maintained
                // across the sub module builds and if not reset will generate a
                // partial MD for all sub modules
                System.setProperty("modDescrptor.generate", "false");
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    });
    // writeMappings(globalClassMapping);
    return globalClassMapping;
}
Also used : PathParam(javax.ws.rs.PathParam) Array(java.lang.reflect.Array) Produces(javax.ws.rs.Produces) Path(javax.ws.rs.Path) HashMap(java.util.HashMap) Collections2(com.google.common.collect.Collections2) LoggerFactory(io.vertx.core.logging.LoggerFactory) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) QueryParam(javax.ws.rs.QueryParam) Parameter(java.lang.reflect.Parameter) Map(java.util.Map) BiConsumer(java.util.function.BiConsumer) DefaultValue(javax.ws.rs.DefaultValue) HeaderParam(javax.ws.rs.HeaderParam) JsonObject(io.vertx.core.json.JsonObject) ClassPath(com.google.common.reflect.ClassPath) Logger(io.vertx.core.logging.Logger) Method(java.lang.reflect.Method) Function(com.google.common.base.Function) ImmutableSet(com.google.common.collect.ImmutableSet) Collection(java.util.Collection) Set(java.util.Set) JsonArray(io.vertx.core.json.JsonArray) List(java.util.List) Annotation(java.lang.annotation.Annotation) ClassPath(com.google.common.reflect.ClassPath) HashSet(java.util.HashSet) ImmutableSet(com.google.common.collect.ImmutableSet) Set(java.util.Set) ArrayList(java.util.ArrayList) JsonObject(io.vertx.core.json.JsonObject) Method(java.lang.reflect.Method) Annotation(java.lang.annotation.Annotation) JsonArray(io.vertx.core.json.JsonArray) JsonObject(io.vertx.core.json.JsonObject)

Example 5 with Array

use of java.lang.reflect.Array in project Bytecoder by mirkosertic.

the class NaiveProgramGenerator method initializeBlockWith.

private void initializeBlockWith(BytecodeClass aOwningClass, BytecodeMethod aMethod, RegionNode aTargetBlock, Function<BytecodeOpcodeAddress, BytecodeBasicBlock> aBlocksByAddress, ParsingHelper aHelper) {
    // Finally we can start to parse the program
    BytecodeBasicBlock theBytecodeBlock = aBlocksByAddress.apply(aTargetBlock.getStartAddress());
    for (BytecodeInstruction theInstruction : theBytecodeBlock.getInstructions()) {
        if (theInstruction instanceof BytecodeInstructionNOP) {
            BytecodeInstructionNOP theINS = (BytecodeInstructionNOP) theInstruction;
        // Completely ignored
        } else if (theInstruction instanceof BytecodeInstructionMONITORENTER) {
            BytecodeInstructionMONITORENTER theINS = (BytecodeInstructionMONITORENTER) theInstruction;
            // Pop the reference for the lock from the stack
            aHelper.pop();
        // Completely ignored
        } else if (theInstruction instanceof BytecodeInstructionMONITOREXIT) {
            BytecodeInstructionMONITOREXIT theINS = (BytecodeInstructionMONITOREXIT) theInstruction;
            // Pop the reference for the lock from the stack
            aHelper.pop();
        // Completely ignored
        } else if (theInstruction instanceof BytecodeInstructionCHECKCAST) {
            BytecodeInstructionCHECKCAST theINS = (BytecodeInstructionCHECKCAST) theInstruction;
            Value theValue = aHelper.peek();
            aTargetBlock.getExpressions().add(new CheckCastExpression(theValue, theINS.getTypeCheck()));
        } else if (theInstruction instanceof BytecodeInstructionPOP) {
            BytecodeInstructionPOP theINS = (BytecodeInstructionPOP) theInstruction;
            aHelper.pop();
        } else if (theInstruction instanceof BytecodeInstructionPOP2) {
            BytecodeInstructionPOP2 theINS = (BytecodeInstructionPOP2) theInstruction;
            Value theValue = aHelper.pop();
            switch(theValue.resolveType().resolve()) {
                case LONG:
                    break;
                case DOUBLE:
                    break;
                default:
                    aHelper.pop();
            }
        } else if (theInstruction instanceof BytecodeInstructionDUP) {
            BytecodeInstructionDUP theINS = (BytecodeInstructionDUP) theInstruction;
            Value theValue = aHelper.peek();
            aHelper.push(theValue);
        } else if (theInstruction instanceof BytecodeInstructionDUP2) {
            BytecodeInstructionDUP2 theINS = (BytecodeInstructionDUP2) theInstruction;
            Value theValue1 = aHelper.pop();
            if (theValue1.resolveType().resolve() == TypeRef.Native.LONG || theValue1.resolveType().resolve() == TypeRef.Native.DOUBLE) {
                // Category 2
                aHelper.push(theValue1);
                aHelper.push(theValue1);
            } else {
                // Category 1
                Value theValue2 = aHelper.pop();
                aHelper.push(theValue2);
                aHelper.push(theValue1);
                aHelper.push(theValue2);
                aHelper.push(theValue1);
            }
        } else if (theInstruction instanceof BytecodeInstructionDUP2X1) {
            BytecodeInstructionDUP2X1 theINS = (BytecodeInstructionDUP2X1) theInstruction;
            Value theValue1 = aHelper.pop();
            if (theValue1.resolveType().resolve() == TypeRef.Native.LONG || theValue1.resolveType().resolve() == TypeRef.Native.DOUBLE) {
                Value theValue2 = aHelper.pop();
                aHelper.push(theValue1);
                aHelper.push(theValue2);
                aHelper.push(theValue2);
            } else {
                Value theValue2 = aHelper.pop();
                Value theValue3 = aHelper.pop();
                aHelper.push(theValue2);
                aHelper.push(theValue1);
                aHelper.push(theValue3);
                aHelper.push(theValue2);
                aHelper.push(theValue2);
            }
        } else if (theInstruction instanceof BytecodeInstructionDUPX1) {
            BytecodeInstructionDUPX1 theINS = (BytecodeInstructionDUPX1) theInstruction;
            Value theValue1 = aHelper.pop();
            Value theValue2 = aHelper.pop();
            aHelper.push(theValue1);
            aHelper.push(theValue2);
            aHelper.push(theValue1);
        } else if (theInstruction instanceof BytecodeInstructionDUPX2) {
            BytecodeInstructionDUPX2 theINS = (BytecodeInstructionDUPX2) theInstruction;
            Value theValue1 = aHelper.pop();
            Value theValue2 = aHelper.pop();
            if (theValue2.resolveType().resolve() == TypeRef.Native.LONG || theValue2.resolveType().resolve() == TypeRef.Native.DOUBLE) {
                // Form 2
                aHelper.push(theValue1);
                aHelper.push(theValue2);
                aHelper.push(theValue1);
            } else {
                // Form 1
                Value theValue3 = aHelper.pop();
                aHelper.push(theValue1);
                aHelper.push(theValue3);
                aHelper.push(theValue2);
                aHelper.push(theValue1);
            }
        } else if (theInstruction instanceof BytecodeInstructionGETSTATIC) {
            BytecodeInstructionGETSTATIC theINS = (BytecodeInstructionGETSTATIC) theInstruction;
            GetStaticExpression theValue = new GetStaticExpression(theINS.getConstant());
            Variable theVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getConstant().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().fieldType()), theValue);
            aHelper.push(theVariable);
        } else if (theInstruction instanceof BytecodeInstructionASTORE) {
            BytecodeInstructionASTORE theINS = (BytecodeInstructionASTORE) theInstruction;
            Value theValue = aHelper.pop();
            aHelper.setLocalVariable(theInstruction.getOpcodeAddress(), theINS.getVariableIndex(), theValue);
        } else if (theInstruction instanceof BytecodeInstructionGenericSTORE) {
            BytecodeInstructionGenericSTORE theINS = (BytecodeInstructionGenericSTORE) theInstruction;
            Value theValue = aHelper.pop();
            Variable theOtherVariable = aTargetBlock.newVariable(theValue.resolveType().resolve(), theValue);
            aHelper.setLocalVariable(theInstruction.getOpcodeAddress(), theINS.getVariableIndex(), theOtherVariable);
        } else if (theInstruction instanceof BytecodeInstructionObjectArrayLOAD) {
            BytecodeInstructionObjectArrayLOAD theINS = (BytecodeInstructionObjectArrayLOAD) theInstruction;
            Value theIndex = aHelper.pop();
            Value theTarget = aHelper.pop();
            TypeRef theType = theTarget.resolveType();
            if (theType instanceof TypeRef.ArrayTypeRef) {
                TypeRef.ArrayTypeRef theArrayTypeRef = (TypeRef.ArrayTypeRef) theTarget.resolveType();
                Variable theVariable = aTargetBlock.newVariable(TypeRef.toType(theArrayTypeRef.arrayType()), new ArrayEntryExpression(TypeRef.Native.REFERENCE, theTarget, theIndex));
                aHelper.push(theVariable);
            } else {
                Variable theVariable = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, new ArrayEntryExpression(TypeRef.Native.REFERENCE, theTarget, theIndex));
                aHelper.push(theVariable);
            }
        } else if (theInstruction instanceof BytecodeInstructionGenericArrayLOAD) {
            BytecodeInstructionGenericArrayLOAD theINS = (BytecodeInstructionGenericArrayLOAD) theInstruction;
            Value theIndex = aHelper.pop();
            Value theTarget = aHelper.pop();
            Variable theVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new ArrayEntryExpression(TypeRef.toType(theINS.getType()), theTarget, theIndex));
            aHelper.push(theVariable);
        } else if (theInstruction instanceof BytecodeInstructionGenericArraySTORE) {
            BytecodeInstructionGenericArraySTORE theINS = (BytecodeInstructionGenericArraySTORE) theInstruction;
            Value theValue = aHelper.pop();
            Value theIndex = aHelper.pop();
            Value theTarget = aHelper.pop();
            aTargetBlock.getExpressions().add(new ArrayStoreExpression(TypeRef.toType(theINS.getType()), theTarget, theIndex, theValue));
        } else if (theInstruction instanceof BytecodeInstructionObjectArraySTORE) {
            BytecodeInstructionObjectArraySTORE theINS = (BytecodeInstructionObjectArraySTORE) theInstruction;
            Value theValue = aHelper.pop();
            Value theIndex = aHelper.pop();
            Value theTarget = aHelper.pop();
            aTargetBlock.getExpressions().add(new ArrayStoreExpression(TypeRef.Native.REFERENCE, theTarget, theIndex, theValue));
        } else if (theInstruction instanceof BytecodeInstructionACONSTNULL) {
            BytecodeInstructionACONSTNULL theINS = (BytecodeInstructionACONSTNULL) theInstruction;
            aHelper.push(new NullValue());
        } else if (theInstruction instanceof BytecodeInstructionPUTFIELD) {
            BytecodeInstructionPUTFIELD theINS = (BytecodeInstructionPUTFIELD) theInstruction;
            Value theValue = aHelper.pop();
            Value theTarget = aHelper.pop();
            aTargetBlock.getExpressions().add(new PutFieldExpression(theINS.getFieldRefConstant(), theTarget, theValue));
        } else if (theInstruction instanceof BytecodeInstructionGETFIELD) {
            BytecodeInstructionGETFIELD theINS = (BytecodeInstructionGETFIELD) theInstruction;
            Value theTarget = aHelper.pop();
            Variable theVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getFieldRefConstant().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().fieldType()), new GetFieldExpression(theINS.getFieldRefConstant(), theTarget));
            aHelper.push(theVariable);
        } else if (theInstruction instanceof BytecodeInstructionPUTSTATIC) {
            BytecodeInstructionPUTSTATIC theINS = (BytecodeInstructionPUTSTATIC) theInstruction;
            Value theValue = aHelper.pop();
            aTargetBlock.getExpressions().add(new PutStaticExpression(theINS.getConstant(), theValue));
        } else if (theInstruction instanceof BytecodeInstructionGenericLDC) {
            BytecodeInstructionGenericLDC theINS = (BytecodeInstructionGenericLDC) theInstruction;
            BytecodeConstant theConstant = theINS.constant();
            if (theConstant instanceof BytecodeDoubleConstant) {
                BytecodeDoubleConstant theC = (BytecodeDoubleConstant) theConstant;
                aHelper.push(new DoubleValue(theC.getDoubleValue()));
            } else if (theConstant instanceof BytecodeLongConstant) {
                BytecodeLongConstant theC = (BytecodeLongConstant) theConstant;
                aHelper.push(new LongValue(theC.getLongValue()));
            } else if (theConstant instanceof BytecodeFloatConstant) {
                BytecodeFloatConstant theC = (BytecodeFloatConstant) theConstant;
                aHelper.push(new FloatValue(theC.getFloatValue()));
            } else if (theConstant instanceof BytecodeIntegerConstant) {
                BytecodeIntegerConstant theC = (BytecodeIntegerConstant) theConstant;
                aHelper.push(new IntegerValue(theC.getIntegerValue()));
            } else if (theConstant instanceof BytecodeStringConstant) {
                BytecodeStringConstant theC = (BytecodeStringConstant) theConstant;
                Variable theVariable = aTargetBlock.newVariable(TypeRef.toType(BytecodeObjectTypeRef.fromRuntimeClass(String.class)), new StringValue(theC.getValue().stringValue()));
                aHelper.push(theVariable);
            } else if (theConstant instanceof BytecodeClassinfoConstant) {
                BytecodeClassinfoConstant theC = (BytecodeClassinfoConstant) theConstant;
                BytecodeUtf8Constant theUTF8 = theC.getConstant();
                if (theUTF8.stringValue().startsWith("[")) {
                    aHelper.push(new ClassReferenceValue(BytecodeObjectTypeRef.fromRuntimeClass(Array.class)));
                } else {
                    aHelper.push(new ClassReferenceValue(BytecodeObjectTypeRef.fromUtf8Constant(theC.getConstant())));
                }
            } else {
                throw new IllegalArgumentException("Unsupported constant type : " + theConstant);
            }
        } else if (theInstruction instanceof BytecodeInstructionBIPUSH) {
            BytecodeInstructionBIPUSH theINS = (BytecodeInstructionBIPUSH) theInstruction;
            aHelper.push(new IntegerValue(theINS.getByteValue()));
        } else if (theInstruction instanceof BytecodeInstructionSIPUSH) {
            BytecodeInstructionSIPUSH theINS = (BytecodeInstructionSIPUSH) theInstruction;
            aHelper.push(new IntegerValue(theINS.getShortValue()));
        } else if (theInstruction instanceof BytecodeInstructionICONST) {
            BytecodeInstructionICONST theINS = (BytecodeInstructionICONST) theInstruction;
            aHelper.push(new IntegerValue(theINS.getIntConst()));
        } else if (theInstruction instanceof BytecodeInstructionFCONST) {
            BytecodeInstructionFCONST theINS = (BytecodeInstructionFCONST) theInstruction;
            aHelper.push(new FloatValue(theINS.getFloatValue()));
        } else if (theInstruction instanceof BytecodeInstructionDCONST) {
            BytecodeInstructionDCONST theINS = (BytecodeInstructionDCONST) theInstruction;
            aHelper.push(new DoubleValue(theINS.getDoubleConst()));
        } else if (theInstruction instanceof BytecodeInstructionLCONST) {
            BytecodeInstructionLCONST theINS = (BytecodeInstructionLCONST) theInstruction;
            aHelper.push(new LongValue(theINS.getLongConst()));
        } else if (theInstruction instanceof BytecodeInstructionGenericNEG) {
            BytecodeInstructionGenericNEG theINS = (BytecodeInstructionGenericNEG) theInstruction;
            Value theValue = aHelper.pop();
            Variable theNegatedValue = aTargetBlock.newVariable(theValue.resolveType(), new NegatedExpression(theValue));
            aHelper.push(theNegatedValue);
        } else if (theInstruction instanceof BytecodeInstructionARRAYLENGTH) {
            BytecodeInstructionARRAYLENGTH theINS = (BytecodeInstructionARRAYLENGTH) theInstruction;
            Value theValue = aHelper.pop();
            Variable theNegatedValue = aTargetBlock.newVariable(TypeRef.Native.INT, new ArrayLengthExpression(theValue));
            aHelper.push(theNegatedValue);
        } else if (theInstruction instanceof BytecodeInstructionGenericLOAD) {
            BytecodeInstructionGenericLOAD theINS = (BytecodeInstructionGenericLOAD) theInstruction;
            Value theValue = aHelper.getLocalVariable(theINS.getVariableIndex());
            aHelper.push(theValue);
        } else if (theInstruction instanceof BytecodeInstructionALOAD) {
            BytecodeInstructionALOAD theINS = (BytecodeInstructionALOAD) theInstruction;
            Value theValue = aHelper.getLocalVariable(theINS.getVariableIndex());
            aHelper.push(theValue);
        } else if (theInstruction instanceof BytecodeInstructionGenericCMP) {
            BytecodeInstructionGenericCMP theINS = (BytecodeInstructionGenericCMP) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, new CompareExpression(theValue1, theValue2));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionLCMP) {
            BytecodeInstructionLCMP theINS = (BytecodeInstructionLCMP) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, new CompareExpression(theValue1, theValue2));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionIINC) {
            BytecodeInstructionIINC theINS = (BytecodeInstructionIINC) theInstruction;
            Value theValueToIncrement = aHelper.getLocalVariable(theINS.getIndex());
            Value theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, new BinaryExpression(TypeRef.Native.INT, theValueToIncrement, BinaryExpression.Operator.ADD, new IntegerValue(theINS.getConstant())));
            aHelper.setLocalVariable(theInstruction.getOpcodeAddress(), theINS.getIndex(), theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionGenericREM) {
            BytecodeInstructionGenericREM theINS = (BytecodeInstructionGenericREM) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.REMAINDER, theValue2));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionGenericADD) {
            BytecodeInstructionGenericADD theINS = (BytecodeInstructionGenericADD) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.ADD, theValue2));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionGenericDIV) {
            BytecodeInstructionGenericDIV theINS = (BytecodeInstructionGenericDIV) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable;
            Value theDivValue = new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.DIV, theValue2);
            switch(theINS.getType()) {
                case FLOAT:
                    theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), theDivValue);
                    break;
                case DOUBLE:
                    theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), theDivValue);
                    break;
                default:
                    theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new FloorExpression(theDivValue, TypeRef.toType(theINS.getType())));
                    break;
            }
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionGenericMUL) {
            BytecodeInstructionGenericMUL theINS = (BytecodeInstructionGenericMUL) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.MUL, theValue2));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionGenericSUB) {
            BytecodeInstructionGenericSUB theINS = (BytecodeInstructionGenericSUB) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.SUB, theValue2));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionGenericXOR) {
            BytecodeInstructionGenericXOR theINS = (BytecodeInstructionGenericXOR) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.BINARYXOR, theValue2));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionGenericOR) {
            BytecodeInstructionGenericOR theINS = (BytecodeInstructionGenericOR) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.BINARYOR, theValue2));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionGenericAND) {
            BytecodeInstructionGenericAND theINS = (BytecodeInstructionGenericAND) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.BINARYAND, theValue2));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionGenericSHL) {
            BytecodeInstructionGenericSHL theINS = (BytecodeInstructionGenericSHL) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.BINARYSHIFTLEFT, theValue2));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionGenericSHR) {
            BytecodeInstructionGenericSHR theINS = (BytecodeInstructionGenericSHR) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.BINARYSHIFTRIGHT, theValue2));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionGenericUSHR) {
            BytecodeInstructionGenericUSHR theINS = (BytecodeInstructionGenericUSHR) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getType()), new BinaryExpression(TypeRef.toType(theINS.getType()), theValue1, BinaryExpression.Operator.BINARYUNSIGNEDSHIFTRIGHT, theValue2));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionIFNULL) {
            BytecodeInstructionIFNULL theINS = (BytecodeInstructionIFNULL) theInstruction;
            Value theValue = aHelper.pop();
            FixedBinaryExpression theBinaryValue = new FixedBinaryExpression(theValue, FixedBinaryExpression.Operator.ISNULL);
            ExpressionList theExpressions = new ExpressionList();
            theExpressions.add(new GotoExpression(theINS.getJumpTarget()));
            aTargetBlock.getExpressions().add(new IFExpression(theINS.getOpcodeAddress(), theINS.getJumpTarget(), theBinaryValue, theExpressions));
        } else if (theInstruction instanceof BytecodeInstructionIFNONNULL) {
            BytecodeInstructionIFNONNULL theINS = (BytecodeInstructionIFNONNULL) theInstruction;
            Value theValue = aHelper.pop();
            FixedBinaryExpression theBinaryValue = new FixedBinaryExpression(theValue, FixedBinaryExpression.Operator.ISNONNULL);
            ExpressionList theExpressions = new ExpressionList();
            theExpressions.add(new GotoExpression(theINS.getJumpTarget()));
            aTargetBlock.getExpressions().add(new IFExpression(theINS.getOpcodeAddress(), theINS.getJumpTarget(), theBinaryValue, theExpressions));
        } else if (theInstruction instanceof BytecodeInstructionIFICMP) {
            BytecodeInstructionIFICMP theINS = (BytecodeInstructionIFICMP) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            BinaryExpression theBinaryValue;
            switch(theINS.getType()) {
                case lt:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.LESSTHAN, theValue2);
                    break;
                case eq:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.EQUALS, theValue2);
                    break;
                case gt:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.GREATERTHAN, theValue2);
                    break;
                case ge:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.GREATEROREQUALS, theValue2);
                    break;
                case le:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.LESSTHANOREQUALS, theValue2);
                    break;
                case ne:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.NOTEQUALS, theValue2);
                    break;
                default:
                    throw new IllegalStateException("Not supported operation : " + theINS.getType());
            }
            ExpressionList theExpressions = new ExpressionList();
            theExpressions.add(new GotoExpression(theINS.getJumpTarget()));
            aTargetBlock.getExpressions().add(new IFExpression(theINS.getOpcodeAddress(), theINS.getJumpTarget(), theBinaryValue, theExpressions));
        } else if (theInstruction instanceof BytecodeInstructionIFACMP) {
            BytecodeInstructionIFACMP theINS = (BytecodeInstructionIFACMP) theInstruction;
            Value theValue2 = aHelper.pop();
            Value theValue1 = aHelper.pop();
            BinaryExpression theBinaryValue;
            switch(theINS.getType()) {
                case eq:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.EQUALS, theValue2);
                    break;
                case ne:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue1, BinaryExpression.Operator.NOTEQUALS, theValue2);
                    break;
                default:
                    throw new IllegalStateException("Not supported operation : " + theINS.getType());
            }
            ExpressionList theExpressions = new ExpressionList();
            theExpressions.add(new GotoExpression(theINS.getJumpTarget()));
            aTargetBlock.getExpressions().add(new IFExpression(theINS.getOpcodeAddress(), theINS.getJumpTarget(), theBinaryValue, theExpressions));
        } else if (theInstruction instanceof BytecodeInstructionIFCOND) {
            BytecodeInstructionIFCOND theINS = (BytecodeInstructionIFCOND) theInstruction;
            Value theValue = aHelper.pop();
            BinaryExpression theBinaryValue;
            switch(theINS.getType()) {
                case lt:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue, BinaryExpression.Operator.LESSTHAN, new IntegerValue(0));
                    break;
                case eq:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue, BinaryExpression.Operator.EQUALS, new IntegerValue(0));
                    break;
                case gt:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue, BinaryExpression.Operator.GREATERTHAN, new IntegerValue(0));
                    break;
                case ge:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue, BinaryExpression.Operator.GREATEROREQUALS, new IntegerValue(0));
                    break;
                case le:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue, BinaryExpression.Operator.LESSTHANOREQUALS, new IntegerValue(0));
                    break;
                case ne:
                    theBinaryValue = new BinaryExpression(TypeRef.Native.BOOLEAN, theValue, BinaryExpression.Operator.NOTEQUALS, new IntegerValue(0));
                    break;
                default:
                    throw new IllegalStateException("Not supported operation : " + theINS.getType());
            }
            ExpressionList theExpressions = new ExpressionList();
            theExpressions.add(new GotoExpression(theINS.getJumpTarget()));
            aTargetBlock.getExpressions().add(new IFExpression(theINS.getOpcodeAddress(), theINS.getJumpTarget(), theBinaryValue, theExpressions));
        } else if (theInstruction instanceof BytecodeInstructionObjectRETURN) {
            BytecodeInstructionObjectRETURN theINS = (BytecodeInstructionObjectRETURN) theInstruction;
            Value theValue = aHelper.pop();
            aTargetBlock.getExpressions().add(new ReturnValueExpression(theValue));
        } else if (theInstruction instanceof BytecodeInstructionGenericRETURN) {
            BytecodeInstructionGenericRETURN theINS = (BytecodeInstructionGenericRETURN) theInstruction;
            Value theValue = aHelper.pop();
            aTargetBlock.getExpressions().add(new ReturnValueExpression(theValue));
        } else if (theInstruction instanceof BytecodeInstructionATHROW) {
            BytecodeInstructionATHROW theINS = (BytecodeInstructionATHROW) theInstruction;
            Value theValue = aHelper.pop();
            aTargetBlock.getExpressions().add(new ThrowExpression(theValue));
        } else if (theInstruction instanceof BytecodeInstructionRETURN) {
            BytecodeInstructionRETURN theINS = (BytecodeInstructionRETURN) theInstruction;
            aTargetBlock.getExpressions().add(new ReturnExpression());
        } else if (theInstruction instanceof BytecodeInstructionNEW) {
            BytecodeInstructionNEW theINS = (BytecodeInstructionNEW) theInstruction;
            BytecodeClassinfoConstant theClassInfo = theINS.getClassInfoForObjectToCreate();
            BytecodeObjectTypeRef theObjectType = BytecodeObjectTypeRef.fromUtf8Constant(theClassInfo.getConstant());
            if (Objects.equals(theObjectType.name(), Address.class.getName())) {
                // At this time the exact location is unknown, the value
                // will be set at constructor invocation time
                Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT);
                aHelper.push(theNewVariable);
            } else {
                if (Objects.equals(theObjectType, BytecodeObjectTypeRef.fromRuntimeClass(VM.RuntimeGeneratedType.class))) {
                    Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, new RuntimeGeneratedTypeExpression());
                    aHelper.push(theNewVariable);
                } else {
                    Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theObjectType), new NewObjectExpression(theClassInfo));
                    aHelper.push(theNewVariable);
                }
            }
        } else if (theInstruction instanceof BytecodeInstructionNEWARRAY) {
            BytecodeInstructionNEWARRAY theINS = (BytecodeInstructionNEWARRAY) theInstruction;
            Value theLength = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, new NewArrayExpression(theINS.getPrimitiveType(), theLength));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionNEWMULTIARRAY) {
            BytecodeInstructionNEWMULTIARRAY theINS = (BytecodeInstructionNEWMULTIARRAY) theInstruction;
            List<Value> theDimensions = new ArrayList<>();
            for (int i = 0; i < theINS.getDimensions(); i++) {
                theDimensions.add(aHelper.pop());
            }
            Collections.reverse(theDimensions);
            BytecodeTypeRef theTypeRef = linkerContext.getSignatureParser().toFieldType(new BytecodeUtf8Constant(theINS.getTypeConstant().getConstant().stringValue()));
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, new NewMultiArrayExpression(theTypeRef, theDimensions));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionANEWARRAY) {
            BytecodeInstructionANEWARRAY theINS = (BytecodeInstructionANEWARRAY) theInstruction;
            Value theLength = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, new NewArrayExpression(theINS.getObjectType(), theLength));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionGOTO) {
            BytecodeInstructionGOTO theINS = (BytecodeInstructionGOTO) theInstruction;
            aTargetBlock.getExpressions().add(new GotoExpression(theINS.getJumpAddress()));
        } else if (theInstruction instanceof BytecodeInstructionL2Generic) {
            BytecodeInstructionL2Generic theINS = (BytecodeInstructionL2Generic) theInstruction;
            Value theValue = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getTargetType()), new TypeConversionExpression(theValue, TypeRef.toType(theINS.getTargetType())));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionI2Generic) {
            BytecodeInstructionI2Generic theINS = (BytecodeInstructionI2Generic) theInstruction;
            Value theValue = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getTargetType()), new TypeConversionExpression(theValue, TypeRef.toType(theINS.getTargetType())));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionF2Generic) {
            BytecodeInstructionF2Generic theINS = (BytecodeInstructionF2Generic) theInstruction;
            Value theValue = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getTargetType()), new TypeConversionExpression(theValue, TypeRef.toType(theINS.getTargetType())));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionD2Generic) {
            BytecodeInstructionD2Generic theINS = (BytecodeInstructionD2Generic) theInstruction;
            Value theValue = aHelper.pop();
            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theINS.getTargetType()), new TypeConversionExpression(theValue, TypeRef.toType(theINS.getTargetType())));
            aHelper.push(theNewVariable);
        } else if (theInstruction instanceof BytecodeInstructionINVOKESPECIAL) {
            BytecodeInstructionINVOKESPECIAL theINS = (BytecodeInstructionINVOKESPECIAL) theInstruction;
            BytecodeMethodSignature theSignature = theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
            List<Value> theArguments = new ArrayList<>();
            BytecodeTypeRef[] theArgumentTypes = theSignature.getArguments();
            for (BytecodeTypeRef theArgumentType : theArgumentTypes) {
                theArguments.add(aHelper.pop());
            }
            Collections.reverse(theArguments);
            Variable theTarget = (Variable) aHelper.pop();
            BytecodeObjectTypeRef theType = BytecodeObjectTypeRef.fromUtf8Constant(theINS.getMethodReference().getClassIndex().getClassConstant().getConstant());
            if (Objects.equals(theType, BytecodeObjectTypeRef.fromRuntimeClass(VM.RuntimeGeneratedType.class))) {
                RuntimeGeneratedTypeExpression theValue = (RuntimeGeneratedTypeExpression) theTarget.incomingDataFlows().get(0);
                theValue.setType(theArguments.get(0));
                theValue.setMethodRef(theArguments.get(1));
            } else if (Objects.equals(theType, BytecodeObjectTypeRef.fromRuntimeClass(Address.class))) {
                theTarget.initializeWith(theArguments.get(0));
                aTargetBlock.getExpressions().add(new VariableAssignmentExpression(theTarget, theArguments.get(0)));
            } else {
                String theMethodName = theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue();
                if ("getClass".equals(theMethodName) && BytecodeLinkedClass.GET_CLASS_SIGNATURE.metchesExactlyTo(theSignature)) {
                    Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), new TypeOfExpression(theTarget));
                    aHelper.push(theNewVariable);
                } else {
                    DirectInvokeMethodExpression theExpression = new DirectInvokeMethodExpression(theType, theMethodName, theSignature, theTarget, theArguments);
                    if (theSignature.getReturnType().isVoid()) {
                        aTargetBlock.getExpressions().add(theExpression);
                    } else {
                        Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theExpression);
                        aHelper.push(theNewVariable);
                    }
                }
            }
        } else if (theInstruction instanceof BytecodeInstructionINVOKEVIRTUAL) {
            BytecodeInstructionINVOKEVIRTUAL theINS = (BytecodeInstructionINVOKEVIRTUAL) theInstruction;
            BytecodeMethodSignature theSignature = theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
            if (theSignature.metchesExactlyTo(BytecodeLinkedClass.GET_CLASS_SIGNATURE) && "getClass".equals(theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue())) {
                Value theValue = new TypeOfExpression(aHelper.pop());
                Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theValue);
                aHelper.push(theNewVariable);
                continue;
            }
            List<Value> theArguments = new ArrayList<>();
            BytecodeTypeRef[] theArgumentTypes = theSignature.getArguments();
            for (BytecodeTypeRef theArgumentType : theArgumentTypes) {
                theArguments.add(aHelper.pop());
            }
            Collections.reverse(theArguments);
            Value theTarget = aHelper.pop();
            InvokeVirtualMethodExpression theExpression = new InvokeVirtualMethodExpression(theINS.getMethodReference().getNameAndTypeIndex().getNameAndType(), theTarget, theArguments);
            if (theSignature.getReturnType().isVoid()) {
                aTargetBlock.getExpressions().add(theExpression);
            } else {
                Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theExpression);
                aHelper.push(theNewVariable);
            }
        } else if (theInstruction instanceof BytecodeInstructionINVOKEINTERFACE) {
            BytecodeInstructionINVOKEINTERFACE theINS = (BytecodeInstructionINVOKEINTERFACE) theInstruction;
            BytecodeMethodSignature theSignature = theINS.getMethodDescriptor().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
            List<Value> theArguments = new ArrayList<>();
            BytecodeTypeRef[] theArgumentTypes = theSignature.getArguments();
            for (BytecodeTypeRef theArgumentType : theArgumentTypes) {
                theArguments.add(aHelper.pop());
            }
            Collections.reverse(theArguments);
            Value theTarget = aHelper.pop();
            InvokeVirtualMethodExpression theExpression = new InvokeVirtualMethodExpression(theINS.getMethodDescriptor().getNameAndTypeIndex().getNameAndType(), theTarget, theArguments);
            if (theSignature.getReturnType().isVoid()) {
                aTargetBlock.getExpressions().add(theExpression);
            } else {
                Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theExpression);
                aHelper.push(theNewVariable);
            }
        } else if (theInstruction instanceof BytecodeInstructionINVOKESTATIC) {
            BytecodeInstructionINVOKESTATIC theINS = (BytecodeInstructionINVOKESTATIC) theInstruction;
            BytecodeMethodSignature theSignature = theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
            List<Value> theArguments = new ArrayList<>();
            BytecodeTypeRef[] theArgumentTypes = theSignature.getArguments();
            for (BytecodeTypeRef theArgumentType : theArgumentTypes) {
                theArguments.add(aHelper.pop());
            }
            Collections.reverse(theArguments);
            BytecodeClassinfoConstant theTargetClass = theINS.getMethodReference().getClassIndex().getClassConstant();
            BytecodeObjectTypeRef theObjectType = BytecodeObjectTypeRef.fromUtf8Constant(theTargetClass.getConstant());
            if (Objects.equals(theObjectType.name(), MemoryManager.class.getName()) && "initTestMemory".equals(theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue())) {
            // This invocation can be skipped!!!
            } else if (Objects.equals(theObjectType.name(), Address.class.getName())) {
                String theMethodName = theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue();
                switch(theMethodName) {
                    case "setIntValue":
                        {
                            Value theTarget = theArguments.get(0);
                            Value theOffset = theArguments.get(1);
                            Value theNewValue = theArguments.get(2);
                            ComputedMemoryLocationWriteExpression theLocation = new ComputedMemoryLocationWriteExpression(theTarget, theOffset);
                            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, theLocation);
                            aTargetBlock.getExpressions().add(new SetMemoryLocationExpression(theNewVariable, theNewValue));
                            break;
                        }
                    case "getStart":
                        {
                            Value theTarget = theArguments.get(0);
                            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, theTarget);
                            aHelper.push(theNewVariable);
                            break;
                        }
                    case "getStackTop":
                        {
                            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, new StackTopExpression());
                            aHelper.push(theNewVariable);
                            break;
                        }
                    case "getMemorySize":
                        {
                            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, new MemorySizeExpression());
                            aHelper.push(theNewVariable);
                            break;
                        }
                    case "getIntValue":
                        {
                            Value theTarget = theArguments.get(0);
                            Value theOffset = theArguments.get(1);
                            ComputedMemoryLocationReadExpression theLocation = new ComputedMemoryLocationReadExpression(theTarget, theOffset);
                            Variable theNewVariable = aTargetBlock.newVariable(TypeRef.Native.INT, theLocation);
                            aHelper.push(theNewVariable);
                            break;
                        }
                    case "unreachable":
                        {
                            aTargetBlock.getExpressions().add(new UnreachableExpression());
                            break;
                        }
                    default:
                        throw new IllegalStateException("Not implemented : " + theMethodName);
                }
            } else {
                BytecodeObjectTypeRef theClassToInvoke = BytecodeObjectTypeRef.fromUtf8Constant(theINS.getMethodReference().getClassIndex().getClassConstant().getConstant());
                linkerContext.resolveClass(theClassToInvoke).resolveStaticMethod(theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue(), theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature());
                BytecodeMethodSignature theCalledSignature = theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
                if ("sqrt".equals(theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue()) && "java.lang.StrictMath".equals(theClassToInvoke.name())) {
                    Value theValue = new SqrtExpression(TypeRef.toType(theCalledSignature.getReturnType()), theArguments.get(0));
                    Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theValue);
                    aHelper.push(theNewVariable);
                } else if ("newInstance".equals(theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue()) && "java.lang.reflect.Array".equals(theClassToInvoke.name())) {
                    Value theArrayType = theArguments.get(0);
                    Value theArraySize = theArguments.get(1);
                    Value theValue = new NewArrayExpression(BytecodeObjectTypeRef.fromRuntimeClass(Object.class), theArraySize);
                    Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theValue);
                    aHelper.push(theNewVariable);
                } else {
                    InvokeStaticMethodExpression theExpression = new InvokeStaticMethodExpression(theClassToInvoke, theINS.getMethodReference().getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue(), theCalledSignature, theArguments);
                    if (theSignature.getReturnType().isVoid()) {
                        aTargetBlock.getExpressions().add(theExpression);
                    } else {
                        Variable theNewVariable = aTargetBlock.newVariable(TypeRef.toType(theSignature.getReturnType()), theExpression);
                        aHelper.push(theNewVariable);
                    }
                }
            }
        } else if (theInstruction instanceof BytecodeInstructionINSTANCEOF) {
            BytecodeInstructionINSTANCEOF theINS = (BytecodeInstructionINSTANCEOF) theInstruction;
            Value theValueToCheck = aHelper.pop();
            InstanceOfExpression theValue = new InstanceOfExpression(theValueToCheck, theINS.getTypeRef());
            Variable theCheckResult = aTargetBlock.newVariable(TypeRef.Native.BOOLEAN, theValue);
            aHelper.push(theCheckResult);
        } else if (theInstruction instanceof BytecodeInstructionTABLESWITCH) {
            BytecodeInstructionTABLESWITCH theINS = (BytecodeInstructionTABLESWITCH) theInstruction;
            Value theValue = aHelper.pop();
            ExpressionList theDefault = new ExpressionList();
            theDefault.add(new GotoExpression(theINS.getDefaultJumpTarget()));
            Map<Long, ExpressionList> theOffsets = new HashMap<>();
            long[] theJumpTargets = theINS.getOffsets();
            for (int i = 0; i < theJumpTargets.length; i++) {
                ExpressionList theJump = new ExpressionList();
                theJump.add(new GotoExpression(theINS.getOpcodeAddress().add((int) theJumpTargets[i])));
                theOffsets.put((long) i, theJump);
            }
            aTargetBlock.getExpressions().add(new TableSwitchExpression(theValue, theINS.getLowValue(), theINS.getHighValue(), theDefault, theOffsets));
        } else if (theInstruction instanceof BytecodeInstructionLOOKUPSWITCH) {
            BytecodeInstructionLOOKUPSWITCH theINS = (BytecodeInstructionLOOKUPSWITCH) theInstruction;
            Value theValue = aHelper.pop();
            ExpressionList theDefault = new ExpressionList();
            theDefault.add(new GotoExpression(theINS.getDefaultJumpTarget()));
            Map<Long, ExpressionList> thePairs = new HashMap<>();
            for (BytecodeInstructionLOOKUPSWITCH.Pair thePair : theINS.getPairs()) {
                ExpressionList thePairExpressions = new ExpressionList();
                thePairExpressions.add(new GotoExpression(theINS.getOpcodeAddress().add((int) thePair.getOffset())));
                thePairs.put(thePair.getMatch(), thePairExpressions);
            }
            aTargetBlock.getExpressions().add(new LookupSwitchExpression(theValue, theDefault, thePairs));
        } else if (theInstruction instanceof BytecodeInstructionINVOKEDYNAMIC) {
            BytecodeInstructionINVOKEDYNAMIC theINS = (BytecodeInstructionINVOKEDYNAMIC) theInstruction;
            BytecodeInvokeDynamicConstant theConstant = theINS.getCallSite();
            BytecodeMethodSignature theInitSignature = theConstant.getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
            BytecodeBootstrapMethodsAttributeInfo theBootStrapMethods = aOwningClass.getAttributes().getByType(BytecodeBootstrapMethodsAttributeInfo.class);
            BytecodeBootstrapMethod theBootstrapMethod = theBootStrapMethods.methodByIndex(theConstant.getBootstrapMethodAttributeIndex().getIndex());
            BytecodeMethodHandleConstant theMethodRef = theBootstrapMethod.getMethodRef();
            BytecodeMethodRefConstant theBootstrapMethodToInvoke = (BytecodeMethodRefConstant) theMethodRef.getReferenceIndex().getConstant();
            Program theProgram = new Program();
            RegionNode theInitNode = theProgram.getControlFlowGraph().createAt(BytecodeOpcodeAddress.START_AT_ZERO, RegionNode.BlockType.NORMAL);
            switch(theMethodRef.getReferenceKind()) {
                case REF_invokeStatic:
                    {
                        BytecodeObjectTypeRef theClassWithBootstrapMethod = BytecodeObjectTypeRef.fromUtf8Constant(theBootstrapMethodToInvoke.getClassIndex().getClassConstant().getConstant());
                        BytecodeMethodSignature theSignature = theBootstrapMethodToInvoke.getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature();
                        List<Value> theArguments = new ArrayList<>();
                        // Add the three default constants
                        // TMethodHandles.Lookup aCaller,
                        theArguments.add(theInitNode.newVariable(TypeRef.Native.REFERENCE, new MethodHandlesGeneratedLookupExpression(theClassWithBootstrapMethod)));
                        theArguments.add(theInitNode.newVariable(TypeRef.Native.REFERENCE, new StringValue(theConstant.getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue())));
                        // TMethodType aInvokedType,
                        theArguments.add(theInitNode.newVariable(TypeRef.Native.REFERENCE, new MethodTypeExpression(theInitSignature)));
                        // Revolve the static arguments
                        for (BytecodeConstant theArgumentConstant : theBootstrapMethod.getArguments()) {
                            if (theArgumentConstant instanceof BytecodeMethodTypeConstant) {
                                BytecodeMethodTypeConstant theMethodType = (BytecodeMethodTypeConstant) theArgumentConstant;
                                theArguments.add(theInitNode.newVariable(TypeRef.Native.REFERENCE, new MethodTypeExpression(theMethodType.getDescriptorIndex().methodSignature())));
                                continue;
                            }
                            if (theArgumentConstant instanceof BytecodeStringConstant) {
                                BytecodeStringConstant thePrimitive = (BytecodeStringConstant) theArgumentConstant;
                                theArguments.add(theInitNode.newVariable(TypeRef.Native.REFERENCE, new StringValue(thePrimitive.getValue().stringValue())));
                                continue;
                            }
                            if (theArgumentConstant instanceof BytecodeLongConstant) {
                                BytecodeLongConstant thePrimitive = (BytecodeLongConstant) theArgumentConstant;
                                theArguments.add(theInitNode.newVariable(TypeRef.Native.LONG, new LongValue(thePrimitive.getLongValue())));
                                continue;
                            }
                            if (theArgumentConstant instanceof BytecodeIntegerConstant) {
                                BytecodeIntegerConstant thePrimitive = (BytecodeIntegerConstant) theArgumentConstant;
                                theArguments.add(theInitNode.newVariable(TypeRef.Native.INT, new LongValue(thePrimitive.getIntegerValue())));
                                continue;
                            }
                            if (theArgumentConstant instanceof BytecodeFloatConstant) {
                                BytecodeFloatConstant thePrimitive = (BytecodeFloatConstant) theArgumentConstant;
                                theArguments.add(theInitNode.newVariable(TypeRef.Native.FLOAT, new FloatValue(thePrimitive.getFloatValue())));
                                continue;
                            }
                            if (theArgumentConstant instanceof BytecodeDoubleConstant) {
                                BytecodeDoubleConstant thePrimitive = (BytecodeDoubleConstant) theArgumentConstant;
                                theArguments.add(theInitNode.newVariable(TypeRef.Native.DOUBLE, new DoubleValue(thePrimitive.getDoubleValue())));
                                continue;
                            }
                            if (theArgumentConstant instanceof BytecodeMethodHandleConstant) {
                                BytecodeMethodHandleConstant theMethodHandle = (BytecodeMethodHandleConstant) theArgumentConstant;
                                BytecodeReferenceIndex theReference = theMethodHandle.getReferenceIndex();
                                BytecodeMethodRefConstant theReferenceConstant = (BytecodeMethodRefConstant) theReference.getConstant();
                                theArguments.add(theInitNode.newVariable(TypeRef.Native.REFERENCE, new MethodRefExpression(theReferenceConstant)));
                                continue;
                            }
                            throw new IllegalStateException("Unsupported argument type : " + theArgumentConstant);
                        }
                        // Ok, is the last argument of the bootstrap method a vararg argument
                        BytecodeTypeRef theLastArgument = theSignature.getArguments()[theSignature.getArguments().length - 1];
                        if (theLastArgument.isArray()) {
                            // Yes, so we have to wrap everything from this position on in an array
                            int theSignatureLength = theSignature.getArguments().length;
                            int theArgumentsLength = theArguments.size();
                            int theVarArgsLength = theArgumentsLength - theSignatureLength + 1;
                            Variable theNewVarargsArray = theInitNode.newVariable(TypeRef.Native.REFERENCE, new NewArrayExpression(BytecodeObjectTypeRef.fromRuntimeClass(Object.class), new IntegerValue(theVarArgsLength)));
                            for (int i = theSignatureLength - 1; i < theArgumentsLength; i++) {
                                Value theVariable = theArguments.get(i);
                                theArguments.remove(theVariable);
                                theInitNode.getExpressions().add(new ArrayStoreExpression(TypeRef.Native.REFERENCE, theNewVarargsArray, new IntegerValue(i - theSignatureLength + 1), theVariable));
                            }
                            theArguments.add(theNewVarargsArray);
                        }
                        InvokeStaticMethodExpression theInvokeStaticValue = new InvokeStaticMethodExpression(BytecodeObjectTypeRef.fromUtf8Constant(theBootstrapMethodToInvoke.getClassIndex().getClassConstant().getConstant()), theBootstrapMethodToInvoke.getNameAndTypeIndex().getNameAndType().getNameIndex().getName().stringValue(), theBootstrapMethodToInvoke.getNameAndTypeIndex().getNameAndType().getDescriptorIndex().methodSignature(), theArguments);
                        Variable theNewVariable = theInitNode.newVariable(TypeRef.Native.REFERENCE, theInvokeStaticValue);
                        theInitNode.getExpressions().add(new ReturnValueExpression(theNewVariable));
                        // First step, we construct a callsite
                        ResolveCallsiteObjectExpression theValue = new ResolveCallsiteObjectExpression(aOwningClass.getThisInfo().getConstant().stringValue() + "_" + aMethod.getName().stringValue() + "_" + theINS.getOpcodeAddress().getAddress(), aOwningClass, theProgram, theInitNode);
                        Variable theCallsiteVariable = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, theValue);
                        List<Value> theInvokeArguments = new ArrayList<>();
                        Variable theArray = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, new NewArrayExpression(BytecodeObjectTypeRef.fromRuntimeClass(Object.class), new IntegerValue(theInitSignature.getArguments().length)));
                        for (int i = theInitSignature.getArguments().length - 1; i >= 0; i--) {
                            Value theIndex = new IntegerValue(i);
                            Value theStoredValue = aHelper.pop();
                            if (theStoredValue.resolveType() == TypeRef.Native.INT) {
                                // Create Integer object to contain int
                                BytecodeObjectTypeRef theType = BytecodeObjectTypeRef.fromRuntimeClass(Integer.class);
                                BytecodeTypeRef[] args_def = new BytecodeTypeRef[] { BytecodePrimitiveTypeRef.INT };
                                BytecodeMethodSignature sig = new BytecodeMethodSignature(theType, args_def);
                                List<Value> args = new ArrayList<>();
                                args.add(theStoredValue);
                                theStoredValue = new InvokeStaticMethodExpression(theType, "valueOf", sig, args);
                                theStoredValue = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, theStoredValue);
                            }
                            aTargetBlock.getExpressions().add(new ArrayStoreExpression(TypeRef.Native.REFERENCE, theArray, theIndex, theStoredValue));
                        }
                        theInvokeArguments.add(theArray);
                        InvokeVirtualMethodExpression theInvokeValue = new InvokeVirtualMethodExpression("invokeExact", new BytecodeMethodSignature(BytecodeObjectTypeRef.fromRuntimeClass(Object.class), new BytecodeTypeRef[] { new BytecodeArrayTypeRef(BytecodeObjectTypeRef.fromRuntimeClass(Object.class), 1) }), theCallsiteVariable, theInvokeArguments);
                        Variable theInvokeExactResult = aTargetBlock.newVariable(TypeRef.Native.REFERENCE, theInvokeValue);
                        aHelper.push(theInvokeExactResult);
                        break;
                    }
                default:
                    throw new IllegalStateException("Nut supported reference kind for invoke dynamic : " + theMethodRef.getReferenceKind());
            }
        } else {
            throw new IllegalArgumentException("Not implemented : " + theInstruction);
        }
    }
    aHelper.finalizeExportState();
}
Also used : BytecodeInstructionGenericArraySTORE(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericArraySTORE) BytecodeInstructionFCONST(de.mirkosertic.bytecoder.core.BytecodeInstructionFCONST) BytecodeInstructionINVOKEDYNAMIC(de.mirkosertic.bytecoder.core.BytecodeInstructionINVOKEDYNAMIC) BytecodeReferenceIndex(de.mirkosertic.bytecoder.core.BytecodeReferenceIndex) Address(de.mirkosertic.bytecoder.classlib.Address) BytecodeOpcodeAddress(de.mirkosertic.bytecoder.core.BytecodeOpcodeAddress) BytecodeInstructionATHROW(de.mirkosertic.bytecoder.core.BytecodeInstructionATHROW) ArrayList(java.util.ArrayList) BytecodeInstructionASTORE(de.mirkosertic.bytecoder.core.BytecodeInstructionASTORE) BytecodeInstructionDUP2X1(de.mirkosertic.bytecoder.core.BytecodeInstructionDUP2X1) BytecodeBasicBlock(de.mirkosertic.bytecoder.core.BytecodeBasicBlock) BytecodeInstructionGenericREM(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericREM) BytecodeInstructionGenericOR(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericOR) BytecodeInstructionF2Generic(de.mirkosertic.bytecoder.core.BytecodeInstructionF2Generic) BytecodeInstructionGenericSTORE(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericSTORE) BytecodeInstructionGenericDIV(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericDIV) BytecodeInstructionNOP(de.mirkosertic.bytecoder.core.BytecodeInstructionNOP) BytecodeInstructionGenericNEG(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericNEG) BytecodeInstructionGenericLOAD(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericLOAD) BytecodeInstructionIFICMP(de.mirkosertic.bytecoder.core.BytecodeInstructionIFICMP) BytecodeInstruction(de.mirkosertic.bytecoder.core.BytecodeInstruction) BytecodeInstructionIFACMP(de.mirkosertic.bytecoder.core.BytecodeInstructionIFACMP) BytecodeIntegerConstant(de.mirkosertic.bytecoder.core.BytecodeIntegerConstant) BytecodeInstructionGenericADD(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericADD) BytecodeInstructionCHECKCAST(de.mirkosertic.bytecoder.core.BytecodeInstructionCHECKCAST) BytecodeInstructionGETFIELD(de.mirkosertic.bytecoder.core.BytecodeInstructionGETFIELD) BytecodeTypeRef(de.mirkosertic.bytecoder.core.BytecodeTypeRef) BytecodeInstructionGenericSHR(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericSHR) BytecodeInstructionDCONST(de.mirkosertic.bytecoder.core.BytecodeInstructionDCONST) BytecodeInstructionGenericSHL(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericSHL) BytecodeInstructionINVOKESPECIAL(de.mirkosertic.bytecoder.core.BytecodeInstructionINVOKESPECIAL) Map(java.util.Map) HashMap(java.util.HashMap) BytecodeInstructionICONST(de.mirkosertic.bytecoder.core.BytecodeInstructionICONST) BytecodeInstructionIFCOND(de.mirkosertic.bytecoder.core.BytecodeInstructionIFCOND) BytecodeInstructionNEWARRAY(de.mirkosertic.bytecoder.core.BytecodeInstructionNEWARRAY) BytecodeBootstrapMethodsAttributeInfo(de.mirkosertic.bytecoder.core.BytecodeBootstrapMethodsAttributeInfo) BytecodeInstructionGenericRETURN(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericRETURN) BytecodeInstructionGenericCMP(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericCMP) BytecodeInstructionI2Generic(de.mirkosertic.bytecoder.core.BytecodeInstructionI2Generic) BytecodeInstructionINVOKEINTERFACE(de.mirkosertic.bytecoder.core.BytecodeInstructionINVOKEINTERFACE) BytecodeInstructionGOTO(de.mirkosertic.bytecoder.core.BytecodeInstructionGOTO) BytecodeInstructionARRAYLENGTH(de.mirkosertic.bytecoder.core.BytecodeInstructionARRAYLENGTH) BytecodeInstructionNEWMULTIARRAY(de.mirkosertic.bytecoder.core.BytecodeInstructionNEWMULTIARRAY) BytecodeInstructionLCMP(de.mirkosertic.bytecoder.core.BytecodeInstructionLCMP) BytecodeInstructionGenericSUB(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericSUB) BytecodeInstructionACONSTNULL(de.mirkosertic.bytecoder.core.BytecodeInstructionACONSTNULL) BytecodeInstructionSIPUSH(de.mirkosertic.bytecoder.core.BytecodeInstructionSIPUSH) BytecodeInstructionGenericXOR(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericXOR) BytecodeInstructionPUTSTATIC(de.mirkosertic.bytecoder.core.BytecodeInstructionPUTSTATIC) BytecodeInstructionRETURN(de.mirkosertic.bytecoder.core.BytecodeInstructionRETURN) BytecodeInstructionIFNONNULL(de.mirkosertic.bytecoder.core.BytecodeInstructionIFNONNULL) BytecodeInstructionNEW(de.mirkosertic.bytecoder.core.BytecodeInstructionNEW) BytecodeDoubleConstant(de.mirkosertic.bytecoder.core.BytecodeDoubleConstant) BytecodeStringConstant(de.mirkosertic.bytecoder.core.BytecodeStringConstant) BytecodeObjectTypeRef(de.mirkosertic.bytecoder.core.BytecodeObjectTypeRef) BytecodeInstructionPUTFIELD(de.mirkosertic.bytecoder.core.BytecodeInstructionPUTFIELD) BytecodeInstructionLCONST(de.mirkosertic.bytecoder.core.BytecodeInstructionLCONST) BytecodeMethodSignature(de.mirkosertic.bytecoder.core.BytecodeMethodSignature) BytecodeInstructionPOP2(de.mirkosertic.bytecoder.core.BytecodeInstructionPOP2) HashMap(java.util.HashMap) BytecodeArrayTypeRef(de.mirkosertic.bytecoder.core.BytecodeArrayTypeRef) BytecodeObjectTypeRef(de.mirkosertic.bytecoder.core.BytecodeObjectTypeRef) BytecodePrimitiveTypeRef(de.mirkosertic.bytecoder.core.BytecodePrimitiveTypeRef) BytecodeTypeRef(de.mirkosertic.bytecoder.core.BytecodeTypeRef) BytecodeInstructionL2Generic(de.mirkosertic.bytecoder.core.BytecodeInstructionL2Generic) BytecodeInstructionMONITOREXIT(de.mirkosertic.bytecoder.core.BytecodeInstructionMONITOREXIT) BytecodeInstructionPOP(de.mirkosertic.bytecoder.core.BytecodeInstructionPOP) BytecodeInstructionDUPX2(de.mirkosertic.bytecoder.core.BytecodeInstructionDUPX2) BytecodeFloatConstant(de.mirkosertic.bytecoder.core.BytecodeFloatConstant) ArrayList(java.util.ArrayList) List(java.util.List) BytecodeMethodRefConstant(de.mirkosertic.bytecoder.core.BytecodeMethodRefConstant) BytecodeInstructionANEWARRAY(de.mirkosertic.bytecoder.core.BytecodeInstructionANEWARRAY) BytecodeInstructionObjectArrayLOAD(de.mirkosertic.bytecoder.core.BytecodeInstructionObjectArrayLOAD) BytecodeProgram(de.mirkosertic.bytecoder.core.BytecodeProgram) BytecodeInstructionDUPX1(de.mirkosertic.bytecoder.core.BytecodeInstructionDUPX1) BytecodeInstructionObjectArraySTORE(de.mirkosertic.bytecoder.core.BytecodeInstructionObjectArraySTORE) BytecodeInstructionD2Generic(de.mirkosertic.bytecoder.core.BytecodeInstructionD2Generic) BytecodeInstructionINSTANCEOF(de.mirkosertic.bytecoder.core.BytecodeInstructionINSTANCEOF) BytecodeLongConstant(de.mirkosertic.bytecoder.core.BytecodeLongConstant) BytecodeInstructionTABLESWITCH(de.mirkosertic.bytecoder.core.BytecodeInstructionTABLESWITCH) BytecodeInstructionDUP2(de.mirkosertic.bytecoder.core.BytecodeInstructionDUP2) BytecodeArrayTypeRef(de.mirkosertic.bytecoder.core.BytecodeArrayTypeRef) VM(de.mirkosertic.bytecoder.classlib.VM) BytecodeConstant(de.mirkosertic.bytecoder.core.BytecodeConstant) BytecodeInstructionALOAD(de.mirkosertic.bytecoder.core.BytecodeInstructionALOAD) BytecodeInstructionGenericArrayLOAD(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericArrayLOAD) BytecodeInstructionINVOKESTATIC(de.mirkosertic.bytecoder.core.BytecodeInstructionINVOKESTATIC) BytecodeInstructionGenericMUL(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericMUL) BytecodeInstructionDUP(de.mirkosertic.bytecoder.core.BytecodeInstructionDUP) BytecodeInstructionIINC(de.mirkosertic.bytecoder.core.BytecodeInstructionIINC) BytecodeInstructionGETSTATIC(de.mirkosertic.bytecoder.core.BytecodeInstructionGETSTATIC) BytecodeInstructionGenericAND(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericAND) BytecodeInstructionObjectRETURN(de.mirkosertic.bytecoder.core.BytecodeInstructionObjectRETURN) BytecodeInvokeDynamicConstant(de.mirkosertic.bytecoder.core.BytecodeInvokeDynamicConstant) BytecodeClassinfoConstant(de.mirkosertic.bytecoder.core.BytecodeClassinfoConstant) BytecodeInstructionGenericLDC(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericLDC) BytecodeInstructionIFNULL(de.mirkosertic.bytecoder.core.BytecodeInstructionIFNULL) BytecodeArrayTypeRef(de.mirkosertic.bytecoder.core.BytecodeArrayTypeRef) BytecodeInstructionGenericUSHR(de.mirkosertic.bytecoder.core.BytecodeInstructionGenericUSHR) BytecodeMethodTypeConstant(de.mirkosertic.bytecoder.core.BytecodeMethodTypeConstant) BytecodeInstructionINVOKEVIRTUAL(de.mirkosertic.bytecoder.core.BytecodeInstructionINVOKEVIRTUAL) BytecodeBootstrapMethod(de.mirkosertic.bytecoder.core.BytecodeBootstrapMethod) BytecodeInstructionBIPUSH(de.mirkosertic.bytecoder.core.BytecodeInstructionBIPUSH) Array(java.lang.reflect.Array) BytecodeUtf8Constant(de.mirkosertic.bytecoder.core.BytecodeUtf8Constant) BytecodeInstructionMONITORENTER(de.mirkosertic.bytecoder.core.BytecodeInstructionMONITORENTER) BytecodeMethodHandleConstant(de.mirkosertic.bytecoder.core.BytecodeMethodHandleConstant) BytecodeInstructionLOOKUPSWITCH(de.mirkosertic.bytecoder.core.BytecodeInstructionLOOKUPSWITCH)

Aggregations

Array (java.lang.reflect.Array)29 Map (java.util.Map)15 HashMap (java.util.HashMap)14 List (java.util.List)14 ArrayList (java.util.ArrayList)12 Collection (java.util.Collection)7 Set (java.util.Set)7 LinkedHashMap (java.util.LinkedHashMap)5 Stream (java.util.stream.Stream)5 Method (java.lang.reflect.Method)4 BigDecimal (java.math.BigDecimal)4 HashSet (java.util.HashSet)4 Iterator (java.util.Iterator)4 Internal (org.apache.flink.annotation.Internal)4 ArrayType (org.apache.flink.table.types.logical.ArrayType)4 LogicalType (org.apache.flink.table.types.logical.LogicalType)4 RowType (org.apache.flink.table.types.logical.RowType)4 Serializable (java.io.Serializable)3 LocalTime (java.time.LocalTime)3 LinkedList (java.util.LinkedList)3