100fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com/*
200fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * [The "BSD licence"]
300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * Copyright (c) 2010 Ben Gruver (JesusFreke)
400fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * All rights reserved.
500fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com *
600fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * Redistribution and use in source and binary forms, with or without
700fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * modification, are permitted provided that the following conditions
800fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * are met:
900fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * 1. Redistributions of source code must retain the above copyright
1000fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com *    notice, this list of conditions and the following disclaimer.
1100fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * 2. Redistributions in binary form must reproduce the above copyright
1200fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com *    notice, this list of conditions and the following disclaimer in the
1300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com *    documentation and/or other materials provided with the distribution.
1400fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * 3. The name of the author may not be used to endorse or promote products
1500fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com *    derived from this software without specific prior written permission.
1600fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com *
1700fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1800fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1900fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2000fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2100fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2200fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2300fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2400fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2500fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2600fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2700fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com */
2800fc68adf2e39aeb9fed35293f2576bbe729ec4bJesusFreke@JesusFreke.com
29d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.compackage org.jf.dexlib.Code.Analysis;
30d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
31fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.comimport org.jf.dexlib.*;
32fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.comimport org.jf.dexlib.Code.*;
330c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.comimport org.jf.dexlib.Code.Format.*;
34b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport org.jf.dexlib.Util.AccessFlags;
35b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport org.jf.dexlib.Util.ExceptionWithContext;
36b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport org.jf.dexlib.Util.SparseArray;
37d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
38b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport java.util.BitSet;
39b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport java.util.EnumSet;
40b3abca4c90929e31e6a8c52bc0178c44e3e53c6bJesusFreke@JesusFreke.comimport java.util.List;
41d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com/**
437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * The MethodAnalyzer performs several functions. It "analyzes" the instructions and infers the register types
447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * for each register, it can deodex odexed instructions, and it can verify the bytecode. The analysis and verification
457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * are done in two separate passes, because the analysis has to process instructions multiple times in some cases, and
467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * there's no need to perform the verification multiple times, so we wait until the method is fully analyzed and then
477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * verify it.
487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com *
497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * Before calling the analyze() method, you must have initialized the ClassPath by calling
507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com * ClassPath.InitializeClassPath
517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com */
52d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.compublic class MethodAnalyzer {
53d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    private final ClassDataItem.EncodedMethod encodedMethod;
54d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
550c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com    private final DeodexUtil deodexUtil;
560c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
57fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private SparseArray<AnalyzedInstruction> instructions;
58fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
597974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com    private static final int NOT_ANALYZED = 0;
607974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com    private static final int ANALYZED = 1;
617974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com    private static final int VERIFIED = 2;
627974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com    private int analyzerState = NOT_ANALYZED;
63d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private BitSet analyzedInstructions;
65c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
66c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com    private ValidationException validationException = null;
67300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com
68d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    //This is a dummy instruction that occurs immediately before the first real instruction. We can initialize the
69d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    //register types for this instruction to the parameter types, in order to have them propagate to all of its
70d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    //successors, e.g. the first real instruction, the first instructions in any exception handlers covering the first
71d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    //instruction, etc.
72d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    private AnalyzedInstruction startOfMethod;
73d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
745967598d012839eb25d50d9fa63952ac802e05ddBen Gruver    public MethodAnalyzer(ClassDataItem.EncodedMethod encodedMethod, boolean deodex,
755967598d012839eb25d50d9fa63952ac802e05ddBen Gruver                          InlineMethodResolver inlineResolver) {
76d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        if (encodedMethod == null) {
77d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            throw new IllegalArgumentException("encodedMethod cannot be null");
78d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        }
79fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (encodedMethod.codeItem == null || encodedMethod.codeItem.getInstructions().length == 0) {
80d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            throw new IllegalArgumentException("The method has no code");
81d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        }
82d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        this.encodedMethod = encodedMethod;
83fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
840c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (deodex) {
855967598d012839eb25d50d9fa63952ac802e05ddBen Gruver            if (inlineResolver != null) {
865967598d012839eb25d50d9fa63952ac802e05ddBen Gruver                this.deodexUtil = new DeodexUtil(encodedMethod.method.getDexFile(), inlineResolver);
875967598d012839eb25d50d9fa63952ac802e05ddBen Gruver            } else {
885967598d012839eb25d50d9fa63952ac802e05ddBen Gruver                this.deodexUtil = new DeodexUtil(encodedMethod.method.getDexFile());
895967598d012839eb25d50d9fa63952ac802e05ddBen Gruver            }
900c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        } else {
910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            this.deodexUtil = null;
920c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
930c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
94fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        //override AnalyzedInstruction and provide custom implementations of some of the methods, so that we don't
95fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        //have to handle the case this special case of instruction being null, in the main class
96fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        startOfMethod = new AnalyzedInstruction(null, -1, encodedMethod.codeItem.getRegisterCount()) {
97fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            public boolean setsRegister() {
98fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                return false;
99fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            }
100fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
101fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            @Override
102fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            public boolean setsWideRegister() {
103fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                return false;
104fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            }
105fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
106fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            @Override
107fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            public boolean setsRegister(int registerNumber) {
108fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                return false;
109fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            }
110fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
111fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            @Override
112fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            public int getDestinationRegister() {
113fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                assert false;
114fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                return -1;
115fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            };
116fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        };
117300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com
1187e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com        buildInstructionList();
1197e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com
1207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        analyzedInstructions = new BitSet(instructions.size());
121d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    }
122d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
1237974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com    public boolean isAnalyzed() {
1247974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com        return analyzerState >= ANALYZED;
1257974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com    }
1267974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com
1277974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com    public boolean isVerified() {
1287974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com        return analyzerState == VERIFIED;
1297974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com    }
1307974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com
131ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com    public void analyze() {
132fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        assert encodedMethod != null;
133fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        assert encodedMethod.codeItem != null;
134fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1357974e53f152a584020af1db6ef3e7612ed714ce8JesusFreke@JesusFreke.com        if (analyzerState >= ANALYZED) {
136ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com            //the instructions have already been analyzed, so there is nothing to do
137ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com            return;
138fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
139fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
140fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        CodeItem codeItem = encodedMethod.codeItem;
141fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        MethodIdItem methodIdItem = encodedMethod.method;
142fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
143fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        int totalRegisters = codeItem.getRegisterCount();
144fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        int parameterRegisters = methodIdItem.getPrototype().getParameterRegisterCount();
145fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
146eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com        int nonParameterRegisters = totalRegisters - parameterRegisters;
147eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com
148db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com        for (AnalyzedInstruction instruction: instructions.getValues()) {
149db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com            instruction.dead = true;
150db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com        }
151db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com
152fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        //if this isn't a static method, determine which register is the "this" register and set the type to the
153fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        //current class
154fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if ((encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) == 0) {
155eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com            nonParameterRegisters--;
156fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            int thisRegister = totalRegisters - parameterRegisters - 1;
157fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
158fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            //if this is a constructor, then set the "this" register to an uninitialized reference of the current class
159fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            if ((encodedMethod.accessFlags & AccessFlags.CONSTRUCTOR.getValue()) != 0) {
1600c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister,
161c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                        RegisterType.getRegisterType(RegisterType.Category.UninitThis,
162fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                            ClassPath.getClassDef(methodIdItem.getContainingClass())));
163fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            } else {
1640c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister,
165fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                        RegisterType.getRegisterType(RegisterType.Category.Reference,
166fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                            ClassPath.getClassDef(methodIdItem.getContainingClass())));
167fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            }
168fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
169fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
170fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        TypeListItem parameters = methodIdItem.getPrototype().getParameters();
171fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (parameters != null) {
172fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType[] parameterTypes = getParameterTypes(parameters, parameterRegisters);
173fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            for (int i=0; i<parameterTypes.length; i++) {
174fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                RegisterType registerType = parameterTypes[i];
175fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                int registerNum = (totalRegisters - parameterRegisters) + i;
1760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                setPostRegisterTypeAndPropagateChanges(startOfMethod, registerNum, registerType);
177fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            }
178fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
179fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
180eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com        RegisterType uninit = RegisterType.getRegisterType(RegisterType.Category.Uninit, null);
181eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com        for (int i=0; i<nonParameterRegisters; i++) {
1820c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            setPostRegisterTypeAndPropagateChanges(startOfMethod, i, uninit);
183eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com        }
184eac512ae67c994d4332c0421f369e026681ee0d5JesusFreke@JesusFreke.com
1857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        BitSet instructionsToAnalyze = new BitSet(instructions.size());
186300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com
187300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com        //make sure all of the "first instructions" are marked for processing
188300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com        for (AnalyzedInstruction successor: startOfMethod.successors) {
189c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            instructionsToAnalyze.set(successor.instructionIndex);
190300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com        }
191300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com
192e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com        BitSet undeodexedInstructions = new BitSet(instructions.size());
1930c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
1940c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        do {
1950c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            boolean didSomething = false;
1960c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
1970c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            while (!instructionsToAnalyze.isEmpty()) {
1980c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                for(int i=instructionsToAnalyze.nextSetBit(0); i>=0; i=instructionsToAnalyze.nextSetBit(i+1)) {
1990c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    instructionsToAnalyze.clear(i);
2007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    if (analyzedInstructions.get(i)) {
2010c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                        continue;
2020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    }
2037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    AnalyzedInstruction instructionToAnalyze = instructions.valueAt(i);
204db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com                    instructionToAnalyze.dead = false;
2050c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    try {
2067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        if (instructionToAnalyze.originalInstruction.opcode.odexOnly()) {
207e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com                            //if we had deodexed an odex instruction in a previous pass, we might have more specific
208e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com                            //register information now, so let's restore the original odexed instruction and
209e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com                            //re-deodex it
2107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                            instructionToAnalyze.restoreOdexedInstruction();
2110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                        }
2120c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
2137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        if (!analyzeInstruction(instructionToAnalyze)) {
214e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com                            undeodexedInstructions.set(i);
2150c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                            continue;
2160c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                        } else {
2170c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                            didSomething = true;
218e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com                            undeodexedInstructions.clear(i);
2190c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                        }
2200c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    } catch (ValidationException ex) {
2210c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                        this.validationException = ex;
2227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        int codeAddress = getInstructionAddress(instructionToAnalyze);
2230c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                        ex.setCodeAddress(codeAddress);
2247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        ex.addContext(String.format("opcode: %s", instructionToAnalyze.instruction.opcode.name));
2250c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                        ex.addContext(String.format("CodeAddress: %d", codeAddress));
2260c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                        ex.addContext(String.format("Method: %s", encodedMethod.method.getMethodString()));
2270c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                        break;
2280c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    }
2290c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
2307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    analyzedInstructions.set(instructionToAnalyze.getInstructionIndex());
2310c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
2327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    for (AnalyzedInstruction successor: instructionToAnalyze.successors) {
2330c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                        instructionsToAnalyze.set(successor.getInstructionIndex());
2340c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    }
235c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                }
2360c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                if (validationException != null) {
237c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                    break;
238c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                }
2390c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            }
240c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
2410c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            if (!didSomething) {
2420c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                break;
2430c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            }
244c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
245e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com            if (!undeodexedInstructions.isEmpty()) {
246e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com                for (int i=undeodexedInstructions.nextSetBit(0); i>=0; i=undeodexedInstructions.nextSetBit(i+1)) {
2470c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    instructionsToAnalyze.set(i);
248c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                }
249c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            }
2500c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        } while (true);
251300ad56aa3c343a84017ae7a2267dc516b5b6202JesusFreke@JesusFreke.com
252ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        //Now, go through and fix up any unresolvable odex instructions. These are usually odex instructions
253ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        //that operate on a null register, and thus always throw an NPE. They can also be any sort of odex instruction
254ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        //that occurs after an unresolvable odex instruction. We deodex if possible, or replace with an
255ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        //UnresolvableOdexInstruction
256e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com        for (int i=0; i<instructions.size(); i++) {
257ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver            AnalyzedInstruction analyzedInstruction = instructions.valueAt(i);
258cbc21d5ece82734c479ae52d8f7fa91baf2281e9JesusFreke@JesusFreke.com
259ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver            Instruction instruction = analyzedInstruction.getInstruction();
260ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver
261ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver            if (instruction.opcode.odexOnly()) {
262ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                int objectRegisterNumber;
263ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                switch (instruction.getFormat()) {
264ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                    case Format10x:
265ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        analyzeReturnVoidBarrier(analyzedInstruction, false);
266ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        continue;
267ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                    case Format21c:
268ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                    case Format22c:
269ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        analyzePutGetVolatile(analyzedInstruction, false);
270ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        continue;
271ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                    case Format35c:
272ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        analyzeInvokeDirectEmpty(analyzedInstruction, false);
273ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        continue;
274ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                    case Format3rc:
275ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        analyzeInvokeObjectInitRange(analyzedInstruction, false);
276ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        continue;
277ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                    case Format22cs:
278ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        objectRegisterNumber = ((Instruction22cs)instruction).getRegisterB();
279ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        break;
280ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                    case Format35mi:
281ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                    case Format35ms:
282ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        objectRegisterNumber = ((FiveRegisterInstruction)instruction).getRegisterD();
283ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        break;
284ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                    case Format3rmi:
285ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                    case Format3rms:
286ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        objectRegisterNumber = ((RegisterRangeInstruction)instruction).getStartRegister();
287ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        break;
288ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                    default:
289ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                        continue;
290ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                }
291cbc21d5ece82734c479ae52d8f7fa91baf2281e9JesusFreke@JesusFreke.com
292ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver                analyzedInstruction.setDeodexedInstruction(new UnresolvedOdexInstruction(instruction, objectRegisterNumber));
293ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver            }
294cbc21d5ece82734c479ae52d8f7fa91baf2281e9JesusFreke@JesusFreke.com        }
295cbc21d5ece82734c479ae52d8f7fa91baf2281e9JesusFreke@JesusFreke.com
2967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        analyzerState = ANALYZED;
2977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
2987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
2997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    public void verify() {
3007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        if (analyzerState < ANALYZED) {
3017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            throw new ExceptionWithContext("You must call analyze() before calling verify().");
3027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
3037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
3047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        if (analyzerState == VERIFIED) {
3057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            //we've already verified the bytecode. nothing to do
3067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            return;
3077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
3080c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        BitSet instructionsToVerify = new BitSet(instructions.size());
3107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        BitSet verifiedInstructions = new BitSet(instructions.size());
3110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        //make sure all of the "first instructions" are marked for processing
3137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        for (AnalyzedInstruction successor: startOfMethod.successors) {
3147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            instructionsToVerify.set(successor.instructionIndex);
3157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
3160c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        while (!instructionsToVerify.isEmpty()) {
3187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            for (int i=instructionsToVerify.nextSetBit(0); i>=0; i=instructionsToVerify.nextSetBit(i+1)) {
3197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                instructionsToVerify.clear(i);
3200c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                if (verifiedInstructions.get(i)) {
3217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    continue;
3220c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                }
3237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                AnalyzedInstruction instructionToVerify = instructions.valueAt(i);
3247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                try {
3257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    verifyInstruction(instructionToVerify);
3267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                } catch (ValidationException ex) {
3277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    this.validationException = ex;
3287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    int codeAddress = getInstructionAddress(instructionToVerify);
3297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    ex.setCodeAddress(codeAddress);
3307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    ex.addContext(String.format("opcode: %s", instructionToVerify.instruction.opcode.name));
3317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    ex.addContext(String.format("CodeAddress: %d", codeAddress));
3327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    ex.addContext(String.format("Method: %s", encodedMethod.method.getMethodString()));
3337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    break;
33420cfe7aa0f979fdcdeaffaaaab55c035c12bdbecJesusFreke@JesusFreke.com                }
3350c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifiedInstructions.set(instructionToVerify.getInstructionIndex());
3370c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                for (AnalyzedInstruction successor: instructionToVerify.successors) {
3397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    instructionsToVerify.set(successor.getInstructionIndex());
3407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                }
3417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            }
3427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            if (validationException != null) {
3437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                break;
34420cfe7aa0f979fdcdeaffaaaab55c035c12bdbecJesusFreke@JesusFreke.com            }
34520cfe7aa0f979fdcdeaffaaaab55c035c12bdbecJesusFreke@JesusFreke.com        }
34620cfe7aa0f979fdcdeaffaaaab55c035c12bdbecJesusFreke@JesusFreke.com
3477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        analyzerState = VERIFIED;
348fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
349fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
350fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private int getThisRegister() {
351fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        assert (encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) == 0;
352fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
353fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        CodeItem codeItem = encodedMethod.codeItem;
354fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        assert codeItem != null;
355fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
356fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        MethodIdItem methodIdItem = encodedMethod.method;
357fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        assert methodIdItem != null;
358fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
359fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        int totalRegisters = codeItem.getRegisterCount();
360fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (totalRegisters == 0) {
361fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            throw new ValidationException("A non-static method must have at least 1 register");
362fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
363fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
364fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        int parameterRegisters = methodIdItem.getPrototype().getParameterRegisterCount();
365fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
366fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        return totalRegisters - parameterRegisters - 1;
367fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
368fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
369fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private boolean isInstanceConstructor() {
370fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        return (encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) == 0 &&
371fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com               (encodedMethod.accessFlags & AccessFlags.CONSTRUCTOR.getValue()) != 0;
372fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
373fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
374fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private boolean isStaticConstructor() {
375fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        return (encodedMethod.accessFlags & AccessFlags.STATIC.getValue()) != 0 &&
376fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com               (encodedMethod.accessFlags & AccessFlags.CONSTRUCTOR.getValue()) != 0;
377fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
378fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
3791c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com    public AnalyzedInstruction getStartOfMethod() {
3801c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com        return startOfMethod;
3811c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com    }
3821c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com
383ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com    /**
384ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com     * @return a read-only list containing the instructions for tihs method.
385ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com     */
386ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com    public List<AnalyzedInstruction> getInstructions() {
387ef24b31c9872b24f60c88bdae9b2d8c93eb36feeJesusFreke@JesusFreke.com        return instructions.getValues();
388fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
389fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
3906eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com    public ClassDataItem.EncodedMethod getMethod() {
3916eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com        return this.encodedMethod;
3926eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com    }
3936eae34831fee1f116f3a453bdc5e143d68e05e03JesusFreke@JesusFreke.com
394c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com    public ValidationException getValidationException() {
395c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com        return validationException;
396c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com    }
397c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
398fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private static RegisterType[] getParameterTypes(TypeListItem typeListItem, int parameterRegisterCount) {
399fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        assert typeListItem != null;
400fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        assert parameterRegisterCount == typeListItem.getRegisterCount();
401fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
402fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        RegisterType[] registerTypes = new RegisterType[parameterRegisterCount];
403fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
404fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        int registerNum = 0;
405fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        for (TypeIdItem type: typeListItem.getTypes()) {
406fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            if (type.getRegisterCount() == 2) {
407fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                registerTypes[registerNum++] = RegisterType.getWideRegisterTypeForTypeIdItem(type, true);
408fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                registerTypes[registerNum++] = RegisterType.getWideRegisterTypeForTypeIdItem(type, false);
409fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            } else {
410c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                registerTypes[registerNum++] = RegisterType.getRegisterTypeForTypeIdItem(type);
411fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            }
412fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
413fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
414fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        return registerTypes;
415fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
416fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
4171c56c7e7507dc24ae1ed2f693c793d94df814c76JesusFreke@JesusFreke.com    public int getInstructionAddress(AnalyzedInstruction instruction) {
418fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        return instructions.keyAt(instruction.instructionIndex);
419fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
420fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
421fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private void setDestinationRegisterTypeAndPropagateChanges(AnalyzedInstruction analyzedInstruction,
422fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                                                               RegisterType registerType) {
4230c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        setPostRegisterTypeAndPropagateChanges(analyzedInstruction, analyzedInstruction.getDestinationRegister(),
424fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                registerType);
425fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
426fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
4270c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com    private void setPostRegisterTypeAndPropagateChanges(AnalyzedInstruction analyzedInstruction, int registerNumber,
428fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                                                RegisterType registerType) {
429fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
430fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        BitSet changedInstructions = new BitSet(instructions.size());
431fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
4320c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (!analyzedInstruction.setPostRegisterType(registerNumber, registerType)) {
433fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            return;
434fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
435fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
43685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        propagateRegisterToSuccessors(analyzedInstruction, registerNumber, changedInstructions);
437fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
4380c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        //Using a for loop inside the while loop optimizes for the common case of the successors of an instruction
439fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        //occurring after the instruction. Any successors that occur prior to the instruction will be picked up on
440fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        //the next iteration of the while loop.
4410c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        //This could also be done recursively, but in large methods it would likely cause very deep recursion,
4420c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        //which requires the user to specify a larger stack size. This isn't really a problem, but it is slightly
4430c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        //annoying.
444fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        while (!changedInstructions.isEmpty()) {
445fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            for (int instructionIndex=changedInstructions.nextSetBit(0);
446fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                     instructionIndex>=0;
4477e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                     instructionIndex=changedInstructions.nextSetBit(instructionIndex+1)) {
448fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
449fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                changedInstructions.clear(instructionIndex);
450fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
451fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                propagateRegisterToSuccessors(instructions.valueAt(instructionIndex), registerNumber,
452fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                        changedInstructions);
453fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            }
454fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
45585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com
45685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        if (registerType.category == RegisterType.Category.LongLo) {
45785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            checkWidePair(registerNumber, analyzedInstruction);
4580c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1,
45985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                    RegisterType.getRegisterType(RegisterType.Category.LongHi, null));
46085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        } else if (registerType.category == RegisterType.Category.DoubleLo) {
46185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            checkWidePair(registerNumber, analyzedInstruction);
4620c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            setPostRegisterTypeAndPropagateChanges(analyzedInstruction, registerNumber+1,
46385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                    RegisterType.getRegisterType(RegisterType.Category.DoubleHi, null));
46485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        }
465d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    }
466d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
467fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private void propagateRegisterToSuccessors(AnalyzedInstruction instruction, int registerNumber,
468fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                                               BitSet changedInstructions) {
4690c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        RegisterType postRegisterType = instruction.getPostInstructionRegisterType(registerNumber);
470fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        for (AnalyzedInstruction successor: instruction.successors) {
4717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            if (successor.mergeRegister(registerNumber, postRegisterType, analyzedInstructions)) {
4720c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                changedInstructions.set(successor.instructionIndex);
473fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            }
474fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
475fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
476fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
477d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    private void buildInstructionList() {
478d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        assert encodedMethod != null;
479d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        assert encodedMethod.codeItem != null;
480fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        int registerCount = encodedMethod.codeItem.getRegisterCount();
481d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
482d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        Instruction[] insns = encodedMethod.codeItem.getInstructions();
483d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
484fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        instructions = new SparseArray<AnalyzedInstruction>(insns.length);
485d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
486d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        //first, create all the instructions and populate the instructionAddresses array
487d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        int currentCodeAddress = 0;
488d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        for (int i=0; i<insns.length; i++) {
489fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            instructions.append(currentCodeAddress, new AnalyzedInstruction(insns[i], i, registerCount));
490fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            assert instructions.indexOfKey(currentCodeAddress) == i;
491d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            currentCodeAddress += insns[i].getSize(currentCodeAddress);
492d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        }
493d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
494d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        //next, populate the exceptionHandlers array. The array item for each instruction that can throw an exception
495d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        //and is covered by a try block should be set to a list of the first instructions of each exception handler
496d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        //for the try block covering the instruction
497d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        CodeItem.TryItem[] tries = encodedMethod.codeItem.getTries();
498d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        int triesIndex = 0;
499d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        CodeItem.TryItem currentTry = null;
500fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        AnalyzedInstruction[] currentExceptionHandlers = null;
501fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        AnalyzedInstruction[][] exceptionHandlers = new AnalyzedInstruction[insns.length][];
502d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
5037e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com        if (tries != null) {
5047e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            for (int i=0; i<instructions.size(); i++) {
5057e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                AnalyzedInstruction instruction = instructions.valueAt(i);
5067e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                Opcode instructionOpcode = instruction.instruction.opcode;
507c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                currentCodeAddress = getInstructionAddress(instruction);
508d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
5097e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                //check if we have gone past the end of the current try
5107e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                if (currentTry != null) {
5117e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    if (currentTry.getStartCodeAddress() + currentTry.getTryLength() <= currentCodeAddress) {
5127e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                        currentTry = null;
5137e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                        triesIndex++;
5147e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    }
515d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com                }
516d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
5177e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                //check if the next try is applicable yet
5187e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                if (currentTry == null && triesIndex < tries.length) {
5197e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    CodeItem.TryItem tryItem = tries[triesIndex];
5207e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    if (tryItem.getStartCodeAddress() <= currentCodeAddress) {
5217e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                        assert(tryItem.getStartCodeAddress() + tryItem.getTryLength() > currentCodeAddress);
522d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
5237e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                        currentTry = tryItem;
524d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
5257e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                        currentExceptionHandlers = buildExceptionHandlerArray(tryItem);
5267e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    }
527d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com                }
528d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
5297e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                //if we're inside a try block, and the instruction can throw an exception, then add the exception handlers
5307e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                //for the current instruction
5317e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                if (currentTry != null && instructionOpcode.canThrow()) {
5327e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    exceptionHandlers[i] = currentExceptionHandlers;
5337e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                }
534d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            }
535d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        }
536d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
5370c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        //finally, populate the successors and predecessors for each instruction. We start at the fake "StartOfMethod"
5380c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        //instruction and follow the execution path. Any unreachable code won't have any predecessors or successors,
5390c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        //and no reachable code will have an unreachable predessor or successor
540fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        assert instructions.size() > 0;
5410c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        BitSet instructionsToProcess = new BitSet(insns.length);
542fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
5430c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        addPredecessorSuccessor(startOfMethod, instructions.valueAt(0), exceptionHandlers, instructionsToProcess);
5440c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        while (!instructionsToProcess.isEmpty()) {
5450c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            int currentInstructionIndex = instructionsToProcess.nextSetBit(0);
5460c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            instructionsToProcess.clear(currentInstructionIndex);
5470c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
5480c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            AnalyzedInstruction instruction = instructions.valueAt(currentInstructionIndex);
549d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            Opcode instructionOpcode = instruction.instruction.opcode;
550fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            int instructionCodeAddress = getInstructionAddress(instruction);
551d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
552d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            if (instruction.instruction.opcode.canContinue()) {
553c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                if (instruction.instruction.opcode != Opcode.NOP ||
554c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                    !instruction.instruction.getFormat().variableSizeFormat) {
555c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
5560c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    if (currentInstructionIndex == instructions.size() - 1) {
557c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                        throw new ValidationException("Execution can continue past the last instruction");
558c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                    }
559c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
5600c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    AnalyzedInstruction nextInstruction = instructions.valueAt(currentInstructionIndex+1);
5610c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    addPredecessorSuccessor(instruction, nextInstruction, exceptionHandlers, instructionsToProcess);
562d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com                }
563d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            }
564d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
5657e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            if (instruction.instruction instanceof OffsetInstruction) {
5667e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                OffsetInstruction offsetInstruction = (OffsetInstruction)instruction.instruction;
567d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
568d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com                if (instructionOpcode == Opcode.PACKED_SWITCH || instructionOpcode == Opcode.SPARSE_SWITCH) {
569d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com                    MultiOffsetInstruction switchDataInstruction =
570fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                            (MultiOffsetInstruction)instructions.get(instructionCodeAddress +
571d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com                                    offsetInstruction.getTargetAddressOffset()).instruction;
572d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com                    for (int targetAddressOffset: switchDataInstruction.getTargets()) {
573fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                        AnalyzedInstruction targetInstruction = instructions.get(instructionCodeAddress +
574d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com                                targetAddressOffset);
575d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
5760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                        addPredecessorSuccessor(instruction, targetInstruction, exceptionHandlers,
5770c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                                instructionsToProcess);
578d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com                    }
579d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com                } else {
580d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com                    int targetAddressOffset = offsetInstruction.getTargetAddressOffset();
581fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                    AnalyzedInstruction targetInstruction = instructions.get(instructionCodeAddress +
582fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                            targetAddressOffset);
5830c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    addPredecessorSuccessor(instruction, targetInstruction, exceptionHandlers, instructionsToProcess);
584d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com                }
585d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            }
586d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        }
587d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    }
588d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
589d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    private void addPredecessorSuccessor(AnalyzedInstruction predecessor, AnalyzedInstruction successor,
5900c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                                                AnalyzedInstruction[][] exceptionHandlers,
5910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                                                BitSet instructionsToProcess) {
5920c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        addPredecessorSuccessor(predecessor, successor, exceptionHandlers, instructionsToProcess, false);
593fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
594fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
595fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private void addPredecessorSuccessor(AnalyzedInstruction predecessor, AnalyzedInstruction successor,
5960c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                                                AnalyzedInstruction[][] exceptionHandlers,
5970c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                                                BitSet instructionsToProcess, boolean allowMoveException) {
598fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
599fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (!allowMoveException && successor.instruction.opcode == Opcode.MOVE_EXCEPTION) {
600fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            throw new ValidationException("Execution can pass from the " + predecessor.instruction.opcode.name +
601fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                    " instruction at code address 0x" + Integer.toHexString(getInstructionAddress(predecessor)) +
602fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                    " to the move-exception instruction at address 0x" +
603fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                    Integer.toHexString(getInstructionAddress(successor)));
604fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
605d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
6060c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (!successor.addPredecessor(predecessor)) {
607d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            return;
608d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        }
609d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
6100c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        predecessor.addSuccessor(successor);
6110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        instructionsToProcess.set(successor.getInstructionIndex());
6120c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
613d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
614d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        //if the successor can throw an instruction, then we need to add the exception handlers as additional
615d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        //successors to the predecessor (and then apply this same logic recursively if needed)
6160c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        //Technically, we should handle the monitor-exit instruction as a special case. The exception is actually
6170c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        //thrown *after* the instruction executes, instead of "before" the instruction executes, lke for any other
6180c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        //instruction. But since it doesn't modify any registers, we can treat it like any other instruction.
619fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        AnalyzedInstruction[] exceptionHandlersForSuccessor = exceptionHandlers[successor.instructionIndex];
620d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        if (exceptionHandlersForSuccessor != null) {
621d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            //the item for this instruction in exceptionHandlersForSuccessor should only be set if this instruction
622d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            //can throw an exception
623c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            assert successor.instruction.opcode.canThrow();
624d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
625fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            for (AnalyzedInstruction exceptionHandler: exceptionHandlersForSuccessor) {
6260c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                addPredecessorSuccessor(predecessor, exceptionHandler, exceptionHandlers, instructionsToProcess, true);
627d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            }
628d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        }
629d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    }
630d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
631fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private AnalyzedInstruction[] buildExceptionHandlerArray(CodeItem.TryItem tryItem) {
632d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        int exceptionHandlerCount = tryItem.encodedCatchHandler.handlers.length;
633d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        int catchAllHandler = tryItem.encodedCatchHandler.getCatchAllHandlerAddress();
634d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        if (catchAllHandler != -1) {
635d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            exceptionHandlerCount++;
636d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        }
637d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
638fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        AnalyzedInstruction[] exceptionHandlers = new AnalyzedInstruction[exceptionHandlerCount];
639d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        for (int i=0; i<tryItem.encodedCatchHandler.handlers.length; i++) {
640fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            exceptionHandlers[i] = instructions.get(tryItem.encodedCatchHandler.handlers[i].getHandlerAddress());
641d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        }
642d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
643d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        if (catchAllHandler != -1) {
644fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            exceptionHandlers[exceptionHandlers.length - 1] = instructions.get(catchAllHandler);
645d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        }
646d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
647d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        return exceptionHandlers;
648d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    }
649d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
650e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com    /**
651e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com     * @return false if analyzedInstruction is an odex instruction that couldn't be deodexed, due to its
652e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com     * object register being null
653e01409c11f10de58a47df9bc02c6c715b75c6289JesusFreke@JesusFreke.com     */
6540c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com    private boolean analyzeInstruction(AnalyzedInstruction analyzedInstruction) {
655fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        Instruction instruction = analyzedInstruction.instruction;
656fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
657fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        switch (instruction.opcode) {
658fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case NOP:
6590c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
660fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE:
661fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE_FROM16:
662fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE_16:
663fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE_WIDE:
664fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE_WIDE_FROM16:
665fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE_WIDE_16:
666fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE_OBJECT:
667fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE_OBJECT_FROM16:
668fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE_OBJECT_16:
6697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeMove(analyzedInstruction);
6700c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
671fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE_RESULT:
672fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE_RESULT_WIDE:
673fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE_RESULT_OBJECT:
6747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeMoveResult(analyzedInstruction);
6750c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
676fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MOVE_EXCEPTION:
6777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeMoveException(analyzedInstruction);
6780c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
679fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case RETURN_VOID:
680fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case RETURN:
681fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case RETURN_WIDE:
682fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case RETURN_OBJECT:
6830c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
6844a5692f8275048c564abc617b91ae72bb008fccaBen Gruver            case RETURN_VOID_BARRIER:
6854a5692f8275048c564abc617b91ae72bb008fccaBen Gruver                analyzeReturnVoidBarrier(analyzedInstruction);
6864a5692f8275048c564abc617b91ae72bb008fccaBen Gruver                return true;
687fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case CONST_4:
688fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case CONST_16:
689fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case CONST:
6907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeConst(analyzedInstruction);
6910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
692fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case CONST_HIGH16:
6937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeConstHigh16(analyzedInstruction);
6940c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
695fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case CONST_WIDE_16:
696fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case CONST_WIDE_32:
697fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case CONST_WIDE:
698fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case CONST_WIDE_HIGH16:
6997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeWideConst(analyzedInstruction);
7000c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
701fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case CONST_STRING:
702fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case CONST_STRING_JUMBO:
7037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeConstString(analyzedInstruction);
7040c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
705fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case CONST_CLASS:
7069a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case CONST_CLASS_JUMBO:
7077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeConstClass(analyzedInstruction);
7080c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
709fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MONITOR_ENTER:
710fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case MONITOR_EXIT:
7110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
712fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case CHECK_CAST:
7139a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case CHECK_CAST_JUMBO:
7147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeCheckCast(analyzedInstruction);
7150c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
716fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case INSTANCE_OF:
7179a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case INSTANCE_OF_JUMBO:
7187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeInstanceOf(analyzedInstruction);
7190c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
720fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case ARRAY_LENGTH:
7217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeArrayLength(analyzedInstruction);
7220c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
723fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case NEW_INSTANCE:
7249a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case NEW_INSTANCE_JUMBO:
7257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeNewInstance(analyzedInstruction);
7260c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
727fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            case NEW_ARRAY:
7289a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case NEW_ARRAY_JUMBO:
7297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeNewArray(analyzedInstruction);
7300c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
7319e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com            case FILLED_NEW_ARRAY:
732ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com            case FILLED_NEW_ARRAY_RANGE:
7339a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case FILLED_NEW_ARRAY_JUMBO:
734db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com                return true;
735472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            case FILL_ARRAY_DATA:
736db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com                analyzeArrayDataOrSwitch(analyzedInstruction);
737ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com            case THROW:
738898edda7cea48c02687bb71804a98cfd6e260b89JesusFreke@JesusFreke.com            case GOTO:
739898edda7cea48c02687bb71804a98cfd6e260b89JesusFreke@JesusFreke.com            case GOTO_16:
740898edda7cea48c02687bb71804a98cfd6e260b89JesusFreke@JesusFreke.com            case GOTO_32:
741db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com                return true;
742cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com            case PACKED_SWITCH:
743cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com            case SPARSE_SWITCH:
744db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com                analyzeArrayDataOrSwitch(analyzedInstruction);
7450c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
746f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com            case CMPL_FLOAT:
747f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com            case CMPG_FLOAT:
748f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com            case CMPL_DOUBLE:
749f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com            case CMPG_DOUBLE:
750f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com            case CMP_LONG:
7517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeFloatWideCmp(analyzedInstruction);
7520c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
753aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com            case IF_EQ:
754aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com            case IF_NE:
755150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com            case IF_LT:
756150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com            case IF_GE:
757150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com            case IF_GT:
758150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com            case IF_LE:
759cb00252b6aed86cd3e7c426015cea83fcdbaa806JesusFreke@JesusFreke.com            case IF_EQZ:
760cb00252b6aed86cd3e7c426015cea83fcdbaa806JesusFreke@JesusFreke.com            case IF_NEZ:
76116a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com            case IF_LTZ:
76216a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com            case IF_GEZ:
76316a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com            case IF_GTZ:
76416a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com            case IF_LEZ:
7650c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
766b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            case AGET:
7677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Integer);
7680c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
769b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            case AGET_BOOLEAN:
7707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Boolean);
7710c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
772b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            case AGET_BYTE:
7737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Byte);
7740c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
775b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            case AGET_CHAR:
7767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Char);
7770c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
778b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            case AGET_SHORT:
7797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Short);
7800c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
781c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com            case AGET_WIDE:
7827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeAgetWide(analyzedInstruction);
7830c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
784461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            case AGET_OBJECT:
7857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeAgetObject(analyzedInstruction);
7860c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
787c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            case APUT:
788c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            case APUT_BOOLEAN:
789c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            case APUT_BYTE:
790c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            case APUT_CHAR:
791c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            case APUT_SHORT:
79255d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            case APUT_WIDE:
793898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            case APUT_OBJECT:
7940c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
7954f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com            case IGET:
7969a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_JUMBO:
7977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Integer);
7980c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
7994f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com            case IGET_BOOLEAN:
8009a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_BOOLEAN_JUMBO:
8017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Boolean);
8020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
8034f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com            case IGET_BYTE:
8049a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_BYTE_JUMBO:
8057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Byte);
8060c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
8074f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com            case IGET_CHAR:
8089a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_CHAR_JUMBO:
8097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Char);
8100c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
8114f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com            case IGET_SHORT:
8129a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_SHORT_JUMBO:
8137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Short);
8140c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
8159d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com            case IGET_WIDE:
8169a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_WIDE_JUMBO:
8177a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com            case IGET_OBJECT:
8189a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_OBJECT_JUMBO:
8197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeIgetWideObject(analyzedInstruction);
8200c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
8219971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com            case IPUT:
8229a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_JUMBO:
8239971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com            case IPUT_BOOLEAN:
8249a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_BOOLEAN_JUMBO:
8259971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com            case IPUT_BYTE:
8269a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_BYTE_JUMBO:
8279971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com            case IPUT_CHAR:
8289a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_CHAR_JUMBO:
8299971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com            case IPUT_SHORT:
8309a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_SHORT_JUMBO:
83192616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com            case IPUT_WIDE:
8329a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_WIDE_JUMBO:
83350ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com            case IPUT_OBJECT:
8349a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_OBJECT_JUMBO:
8350c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
836052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com            case SGET:
8379a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_JUMBO:
8387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Integer);
8390c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
840052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com            case SGET_BOOLEAN:
8419a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_BOOLEAN_JUMBO:
8427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Boolean);
8430c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
844052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com            case SGET_BYTE:
8459a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_BYTE_JUMBO:
8467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Byte);
8470c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
848052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com            case SGET_CHAR:
8499a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_CHAR_JUMBO:
8507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Char);
8510c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
852052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com            case SGET_SHORT:
8539a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_SHORT_JUMBO:
8547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyze32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Short);
8550c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
8562f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com            case SGET_WIDE:
8579a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_WIDE_JUMBO:
8582d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com            case SGET_OBJECT:
8599a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_OBJECT_JUMBO:
8607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeSgetWideObject(analyzedInstruction);
8610c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
8629d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com            case SPUT:
8639a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_JUMBO:
8649d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com            case SPUT_BOOLEAN:
8659a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_BOOLEAN_JUMBO:
8669d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com            case SPUT_BYTE:
8679a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_BYTE_JUMBO:
8689d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com            case SPUT_CHAR:
8699a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_CHAR_JUMBO:
8709d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com            case SPUT_SHORT:
8719a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_SHORT_JUMBO:
872f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com            case SPUT_WIDE:
8739a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_WIDE_JUMBO:
87451cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com            case SPUT_OBJECT:
8759a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_OBJECT_JUMBO:
8760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
87789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            case INVOKE_VIRTUAL:
87889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            case INVOKE_SUPER:
8790c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
88089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            case INVOKE_DIRECT:
8817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeInvokeDirect(analyzedInstruction);
8820c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
88389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            case INVOKE_STATIC:
88489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            case INVOKE_INTERFACE:
88589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            case INVOKE_VIRTUAL_RANGE:
8869a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case INVOKE_VIRTUAL_JUMBO:
88789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            case INVOKE_SUPER_RANGE:
8889a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case INVOKE_SUPER_JUMBO:
8890c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
89089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            case INVOKE_DIRECT_RANGE:
8919a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case INVOKE_DIRECT_JUMBO:
8927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeInvokeDirectRange(analyzedInstruction);
8930c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
89489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            case INVOKE_STATIC_RANGE:
8959a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case INVOKE_STATIC_JUMBO:
89689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            case INVOKE_INTERFACE_RANGE:
8979a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case INVOKE_INTERFACE_JUMBO:
8980c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
8991483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case NEG_INT:
9001483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case NOT_INT:
9017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Integer);
9020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9031483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case NEG_LONG:
9041483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case NOT_LONG:
9057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.LongLo);
9060c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9071483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case NEG_FLOAT:
9087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Float);
9090c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9101483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case NEG_DOUBLE:
9117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.DoubleLo);
9120c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9131483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case INT_TO_LONG:
9147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.LongLo);
9150c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9161483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case INT_TO_FLOAT:
9177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Float);
9180c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9191483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case INT_TO_DOUBLE:
9207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.DoubleLo);
9210c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9221483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case LONG_TO_INT:
9231483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case DOUBLE_TO_INT:
9247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Integer);
9250c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9261483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case LONG_TO_FLOAT:
9271483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case DOUBLE_TO_FLOAT:
9287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Float);
9290c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9301483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case LONG_TO_DOUBLE:
9317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.DoubleLo);
9320c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9331483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case FLOAT_TO_INT:
9347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Integer);
9350c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9361483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case FLOAT_TO_LONG:
9377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.LongLo);
9380c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9391483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case FLOAT_TO_DOUBLE:
9407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.DoubleLo);
9410c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9421483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case DOUBLE_TO_LONG:
9437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.LongLo);
9440c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9451483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case INT_TO_BYTE:
9467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Byte);
9470c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9481483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case INT_TO_CHAR:
9497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Char);
9500c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
9511483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com            case INT_TO_SHORT:
9527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeUnaryOp(analyzedInstruction, RegisterType.Category.Short);
9530c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
954195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case ADD_INT:
955195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case SUB_INT:
956195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case MUL_INT:
957195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case DIV_INT:
958195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case REM_INT:
959195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case SHL_INT:
960195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case SHR_INT:
961195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case USHR_INT:
9627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeBinaryOp(analyzedInstruction, RegisterType.Category.Integer, false);
9630c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
964195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case AND_INT:
965195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case OR_INT:
966195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case XOR_INT:
9677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeBinaryOp(analyzedInstruction, RegisterType.Category.Integer, true);
9680c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
969195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case ADD_LONG:
970195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case SUB_LONG:
971195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case MUL_LONG:
972195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case DIV_LONG:
973195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case REM_LONG:
974195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case AND_LONG:
975195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case OR_LONG:
976195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case XOR_LONG:
977195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case SHL_LONG:
978195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case SHR_LONG:
979195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case USHR_LONG:
9807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeBinaryOp(analyzedInstruction, RegisterType.Category.LongLo, false);
9810c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
982195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case ADD_FLOAT:
983195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case SUB_FLOAT:
984195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case MUL_FLOAT:
985195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case DIV_FLOAT:
986195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case REM_FLOAT:
9877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeBinaryOp(analyzedInstruction, RegisterType.Category.Float, false);
9880c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
989195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case ADD_DOUBLE:
990195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case SUB_DOUBLE:
991195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case MUL_DOUBLE:
992195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case DIV_DOUBLE:
993195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            case REM_DOUBLE:
9947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeBinaryOp(analyzedInstruction, RegisterType.Category.DoubleLo, false);
9950c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
996122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case ADD_INT_2ADDR:
997122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case SUB_INT_2ADDR:
998122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case MUL_INT_2ADDR:
999122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case DIV_INT_2ADDR:
1000122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case REM_INT_2ADDR:
1001122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case SHL_INT_2ADDR:
1002122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case SHR_INT_2ADDR:
1003122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case USHR_INT_2ADDR:
10047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeBinary2AddrOp(analyzedInstruction, RegisterType.Category.Integer, false);
10050c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1006122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case AND_INT_2ADDR:
1007122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case OR_INT_2ADDR:
1008122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case XOR_INT_2ADDR:
10097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeBinary2AddrOp(analyzedInstruction, RegisterType.Category.Integer, true);
10100c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1011122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case ADD_LONG_2ADDR:
1012122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case SUB_LONG_2ADDR:
1013122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case MUL_LONG_2ADDR:
1014122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case DIV_LONG_2ADDR:
1015122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case REM_LONG_2ADDR:
1016122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case AND_LONG_2ADDR:
1017122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case OR_LONG_2ADDR:
1018122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case XOR_LONG_2ADDR:
1019122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case SHL_LONG_2ADDR:
1020122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case SHR_LONG_2ADDR:
1021122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case USHR_LONG_2ADDR:
10227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeBinary2AddrOp(analyzedInstruction, RegisterType.Category.LongLo, false);
10230c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1024122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case ADD_FLOAT_2ADDR:
1025122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case SUB_FLOAT_2ADDR:
1026122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case MUL_FLOAT_2ADDR:
1027122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case DIV_FLOAT_2ADDR:
1028122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case REM_FLOAT_2ADDR:
10297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeBinary2AddrOp(analyzedInstruction, RegisterType.Category.Float, false);
10300c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1031122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case ADD_DOUBLE_2ADDR:
1032122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case SUB_DOUBLE_2ADDR:
1033122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case MUL_DOUBLE_2ADDR:
1034122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case DIV_DOUBLE_2ADDR:
1035122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            case REM_DOUBLE_2ADDR:
10367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeBinary2AddrOp(analyzedInstruction, RegisterType.Category.DoubleLo, false);
10370c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1038caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case ADD_INT_LIT16:
1039caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case RSUB_INT:
1040caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case MUL_INT_LIT16:
1041caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case DIV_INT_LIT16:
1042caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case REM_INT_LIT16:
10437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeLiteralBinaryOp(analyzedInstruction, RegisterType.Category.Integer, false);
10440c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1045caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case AND_INT_LIT16:
1046caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case OR_INT_LIT16:
1047caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case XOR_INT_LIT16:
10487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeLiteralBinaryOp(analyzedInstruction, RegisterType.Category.Integer, true);
10490c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1050caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case ADD_INT_LIT8:
1051caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case RSUB_INT_LIT8:
1052caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case MUL_INT_LIT8:
1053caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case DIV_INT_LIT8:
1054caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case REM_INT_LIT8:
1055caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case SHL_INT_LIT8:
10567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeLiteralBinaryOp(analyzedInstruction, RegisterType.Category.Integer, false);
10570c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1058caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case AND_INT_LIT8:
1059caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case OR_INT_LIT8:
1060caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case XOR_INT_LIT8:
10617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeLiteralBinaryOp(analyzedInstruction, RegisterType.Category.Integer, true);
10620c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1063caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case SHR_INT_LIT8:
10647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeLiteralBinaryOp(analyzedInstruction, getDestTypeForLiteralShiftRight(analyzedInstruction, true),
10657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        false);
10660c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1067caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case USHR_INT_LIT8:
10687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeLiteralBinaryOp(analyzedInstruction, getDestTypeForLiteralShiftRight(analyzedInstruction, false),
10697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        false);
10700c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1071d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com
1072d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            /*odexed instructions*/
1073d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case IGET_VOLATILE:
1074d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case IPUT_VOLATILE:
1075d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case SGET_VOLATILE:
1076d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case SPUT_VOLATILE:
1077d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case IGET_OBJECT_VOLATILE:
1078d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case IGET_WIDE_VOLATILE:
1079d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case IPUT_WIDE_VOLATILE:
1080d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case SGET_WIDE_VOLATILE:
1081d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case SPUT_WIDE_VOLATILE:
1082d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com                analyzePutGetVolatile(analyzedInstruction);
1083d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com                return true;
10848e51717604ca39549da64834f4136d4a2b6d4ed9Ben Gruver            case THROW_VERIFICATION_ERROR:
10858e51717604ca39549da64834f4136d4a2b6d4ed9Ben Gruver                return true;
10860c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case EXECUTE_INLINE:
10877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeExecuteInline(analyzedInstruction);
10880c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
10890c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case EXECUTE_INLINE_RANGE:
10907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeExecuteInlineRange(analyzedInstruction);
10910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
10920c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case INVOKE_DIRECT_EMPTY:
10937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                analyzeInvokeDirectEmpty(analyzedInstruction);
10940c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1095ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver            case INVOKE_OBJECT_INIT_RANGE:
1096ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver                analyzeInvokeObjectInitRange(analyzedInstruction);
1097ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver                return true;
10980c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case IGET_QUICK:
10990c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case IGET_WIDE_QUICK:
11000c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case IGET_OBJECT_QUICK:
11010c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case IPUT_QUICK:
11020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case IPUT_WIDE_QUICK:
11030c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case IPUT_OBJECT_QUICK:
1104d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com                return analyzeIputIgetQuick(analyzedInstruction);
11050c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case INVOKE_VIRTUAL_QUICK:
11067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return analyzeInvokeVirtualQuick(analyzedInstruction, false, false);
11070c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case INVOKE_SUPER_QUICK:
11087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return analyzeInvokeVirtualQuick(analyzedInstruction, true, false);
11090c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case INVOKE_VIRTUAL_QUICK_RANGE:
11107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return analyzeInvokeVirtualQuick(analyzedInstruction, false, true);
11110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case INVOKE_SUPER_QUICK_RANGE:
11127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return analyzeInvokeVirtualQuick(analyzedInstruction, true, true);
1113d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case IPUT_OBJECT_VOLATILE:
1114d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case SGET_OBJECT_VOLATILE:
1115d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case SPUT_OBJECT_VOLATILE:
1116d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com                analyzePutGetVolatile(analyzedInstruction);
1117d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com                return true;
11189a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case INVOKE_OBJECT_INIT_JUMBO:
11199a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                analyzeInvokeObjectInitJumbo(analyzedInstruction);
11209a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                return true;
11219a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_VOLATILE_JUMBO:
11229a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_WIDE_VOLATILE_JUMBO:
11239a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_OBJECT_VOLATILE_JUMBO:
11249a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_VOLATILE_JUMBO:
11259a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_WIDE_VOLATILE_JUMBO:
11269a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_OBJECT_VOLATILE_JUMBO:
11279a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_VOLATILE_JUMBO:
11289a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_WIDE_VOLATILE_JUMBO:
11299a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_OBJECT_VOLATILE_JUMBO:
11309a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_VOLATILE_JUMBO:
11319a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_WIDE_VOLATILE_JUMBO:
11329a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_OBJECT_VOLATILE_JUMBO:
11339a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                analyzePutGetVolatile(analyzedInstruction);
11349a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                return true;
1135caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            default:
1136caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                assert false;
11370c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                return true;
1138fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
1139fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1140fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
11417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
11424a5692f8275048c564abc617b91ae72bb008fccaBen Gruver    private void verifyInstruction(AnalyzedInstruction analyzedInstruction) {
11437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        Instruction instruction = analyzedInstruction.instruction;
11447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
11457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        switch (instruction.opcode) {
11467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case NOP:
11477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE:
11497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE_FROM16:
11507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE_16:
11517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyMove(analyzedInstruction, Primitive32BitCategories);
11527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE_WIDE:
11547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE_WIDE_FROM16:
11557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE_WIDE_16:
11567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyMove(analyzedInstruction, WideLowCategories);
11577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE_OBJECT:
11597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE_OBJECT_FROM16:
11607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE_OBJECT_16:
11617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyMove(analyzedInstruction, ReferenceOrUninitCategories);
11627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE_RESULT:
11647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyMoveResult(analyzedInstruction, Primitive32BitCategories);
11657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE_RESULT_WIDE:
11677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyMoveResult(analyzedInstruction, WideLowCategories);
11687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE_RESULT_OBJECT:
11707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyMoveResult(analyzedInstruction, ReferenceCategories);
11717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MOVE_EXCEPTION:
11737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyMoveException(analyzedInstruction);
11747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case RETURN_VOID:
11764a5692f8275048c564abc617b91ae72bb008fccaBen Gruver            case RETURN_VOID_BARRIER:
11777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyReturnVoid(analyzedInstruction);
11787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case RETURN:
11807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyReturn(analyzedInstruction, Primitive32BitCategories);
11817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case RETURN_WIDE:
11837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyReturn(analyzedInstruction, WideLowCategories);
11847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case RETURN_OBJECT:
11867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyReturn(analyzedInstruction, ReferenceCategories);
11877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CONST_4:
11897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CONST_16:
11907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CONST:
11917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CONST_HIGH16:
11927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CONST_WIDE_16:
11937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CONST_WIDE_32:
11947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CONST_WIDE:
11957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CONST_WIDE_HIGH16:
11967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CONST_STRING:
11977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CONST_STRING_JUMBO:
11987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
11997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CONST_CLASS:
12009a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case CONST_CLASS_JUMBO:
12017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyConstClass(analyzedInstruction);
12027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MONITOR_ENTER:
12047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MONITOR_EXIT:
12057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyMonitor(analyzedInstruction);
12067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CHECK_CAST:
12089a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case CHECK_CAST_JUMBO:
12097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyCheckCast(analyzedInstruction);
12107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INSTANCE_OF:
12129a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case INSTANCE_OF_JUMBO:
12137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyInstanceOf(analyzedInstruction);
12147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case ARRAY_LENGTH:
12167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyArrayLength(analyzedInstruction);
12177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case NEW_INSTANCE:
12199a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case NEW_INSTANCE_JUMBO:
12207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyNewInstance(analyzedInstruction);
12217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case NEW_ARRAY:
12237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyNewArray(analyzedInstruction);
12247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case FILLED_NEW_ARRAY:
12267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyFilledNewArray(analyzedInstruction);
12277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case FILLED_NEW_ARRAY_RANGE:
12297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyFilledNewArrayRange(analyzedInstruction);
12307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case FILL_ARRAY_DATA:
12327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyFillArrayData(analyzedInstruction);
12337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case THROW:
12357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyThrow(analyzedInstruction);
12367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case GOTO:
12387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case GOTO_16:
12397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case GOTO_32:
12407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case PACKED_SWITCH:
12427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifySwitch(analyzedInstruction, Format.PackedSwitchData);
12437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SPARSE_SWITCH:
12457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifySwitch(analyzedInstruction, Format.SparseSwitchData);
12467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CMPL_FLOAT:
12487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CMPG_FLOAT:
12497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyFloatWideCmp(analyzedInstruction, Primitive32BitCategories);
12507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CMPL_DOUBLE:
12527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CMPG_DOUBLE:
12537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case CMP_LONG:
12547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyFloatWideCmp(analyzedInstruction, WideLowCategories);
12557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IF_EQ:
12577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IF_NE:
12587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyIfEqNe(analyzedInstruction);
12597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IF_LT:
12617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IF_GE:
12627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IF_GT:
12637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IF_LE:
12647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyIf(analyzedInstruction);
12657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IF_EQZ:
12677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IF_NEZ:
12687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyIfEqzNez(analyzedInstruction);
12697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IF_LTZ:
12717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IF_GEZ:
12727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IF_GTZ:
12737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IF_LEZ:
12747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyIfz(analyzedInstruction);
12757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AGET:
12777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Integer);
12787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AGET_BOOLEAN:
12807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Boolean);
12817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AGET_BYTE:
12837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Byte);
12847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AGET_CHAR:
12867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Char);
12877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AGET_SHORT:
12897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveAget(analyzedInstruction, RegisterType.Category.Short);
12907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AGET_WIDE:
12927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyAgetWide(analyzedInstruction);
12937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AGET_OBJECT:
12957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyAgetObject(analyzedInstruction);
12967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
12977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case APUT:
12987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveAput(analyzedInstruction, RegisterType.Category.Integer);
12997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case APUT_BOOLEAN:
13017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveAput(analyzedInstruction, RegisterType.Category.Boolean);
13027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case APUT_BYTE:
13047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveAput(analyzedInstruction, RegisterType.Category.Byte);
13057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case APUT_CHAR:
13077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveAput(analyzedInstruction, RegisterType.Category.Char);
13087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case APUT_SHORT:
13107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveAput(analyzedInstruction, RegisterType.Category.Short);
13117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case APUT_WIDE:
13137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyAputWide(analyzedInstruction);
13147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case APUT_OBJECT:
13167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyAputObject(analyzedInstruction);
13177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IGET:
13197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Integer);
13207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IGET_BOOLEAN:
13227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Boolean);
13237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IGET_BYTE:
13257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Byte);
13267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IGET_CHAR:
13287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Char);
13297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IGET_SHORT:
13317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveIget(analyzedInstruction, RegisterType.Category.Short);
13327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IGET_WIDE:
13347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyIgetWide(analyzedInstruction);
13357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IGET_OBJECT:
13377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyIgetObject(analyzedInstruction);
13387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IPUT:
13407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveIput(analyzedInstruction, RegisterType.Category.Integer);
13417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IPUT_BOOLEAN:
13437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveIput(analyzedInstruction, RegisterType.Category.Boolean);
13447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IPUT_BYTE:
13467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveIput(analyzedInstruction, RegisterType.Category.Byte);
13477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IPUT_CHAR:
13497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveIput(analyzedInstruction, RegisterType.Category.Char);
13507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IPUT_SHORT:
13527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveIput(analyzedInstruction, RegisterType.Category.Short);
13537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IPUT_WIDE:
13557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyIputWide(analyzedInstruction);
13567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IPUT_OBJECT:
13587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyIputObject(analyzedInstruction);
13597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SGET:
13617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Integer);
13627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SGET_BOOLEAN:
13647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Boolean);
13657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SGET_BYTE:
13677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Byte);
13687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SGET_CHAR:
13707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Char);
13717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SGET_SHORT:
13737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveSget(analyzedInstruction, RegisterType.Category.Short);
13747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SGET_WIDE:
13767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifySgetWide(analyzedInstruction);
13777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SGET_OBJECT:
13797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifySgetObject(analyzedInstruction);
13807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SPUT:
13827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveSput(analyzedInstruction, RegisterType.Category.Integer);
13837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SPUT_BOOLEAN:
13857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveSput(analyzedInstruction, RegisterType.Category.Boolean);
13867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SPUT_BYTE:
13887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveSput(analyzedInstruction, RegisterType.Category.Byte);
13897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SPUT_CHAR:
13917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveSput(analyzedInstruction, RegisterType.Category.Char);
13927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SPUT_SHORT:
13947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verify32BitPrimitiveSput(analyzedInstruction, RegisterType.Category.Short);
13957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SPUT_WIDE:
13977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifySputWide(analyzedInstruction);
13987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
13997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SPUT_OBJECT:
14007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifySputObject(analyzedInstruction);
14017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_VIRTUAL:
14037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyInvoke(analyzedInstruction, INVOKE_VIRTUAL);
14047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_SUPER:
14067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyInvoke(analyzedInstruction, INVOKE_SUPER);
14077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_DIRECT:
14097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyInvoke(analyzedInstruction, INVOKE_DIRECT);
14107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_STATIC:
14127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyInvoke(analyzedInstruction, INVOKE_STATIC);
14137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_INTERFACE:
14157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyInvoke(analyzedInstruction, INVOKE_INTERFACE);
14167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_VIRTUAL_RANGE:
14187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyInvokeRange(analyzedInstruction, INVOKE_VIRTUAL);
14197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_SUPER_RANGE:
14217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyInvokeRange(analyzedInstruction, INVOKE_SUPER);
14227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_DIRECT_RANGE:
14247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyInvokeRange(analyzedInstruction, INVOKE_DIRECT);
14257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_STATIC_RANGE:
14277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyInvokeRange(analyzedInstruction, INVOKE_STATIC);
14287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_INTERFACE_RANGE:
14307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyInvokeRange(analyzedInstruction, INVOKE_INTERFACE);
14317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case NEG_INT:
14337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case NOT_INT:
14347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, Primitive32BitCategories);
14357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case NEG_LONG:
14377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case NOT_LONG:
14387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, WideLowCategories);
14397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case NEG_FLOAT:
14417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, Primitive32BitCategories);
14427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case NEG_DOUBLE:
14447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, WideLowCategories);
14457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INT_TO_LONG:
14477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, Primitive32BitCategories);
14487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INT_TO_FLOAT:
14507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, Primitive32BitCategories);
14517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INT_TO_DOUBLE:
14537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, Primitive32BitCategories);
14547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case LONG_TO_INT:
14567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DOUBLE_TO_INT:
14577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, WideLowCategories);
14587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case LONG_TO_FLOAT:
14607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DOUBLE_TO_FLOAT:
14617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, WideLowCategories);
14627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case LONG_TO_DOUBLE:
14647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, WideLowCategories);
14657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case FLOAT_TO_INT:
14677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, Primitive32BitCategories);
14687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case FLOAT_TO_LONG:
14707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, Primitive32BitCategories);
14717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case FLOAT_TO_DOUBLE:
14737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, Primitive32BitCategories);
14747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DOUBLE_TO_LONG:
14767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, WideLowCategories);
14777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INT_TO_BYTE:
14797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, Primitive32BitCategories);
14807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INT_TO_CHAR:
14827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, Primitive32BitCategories);
14837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INT_TO_SHORT:
14857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyUnaryOp(analyzedInstruction, Primitive32BitCategories);
14867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
14877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case ADD_INT:
14887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SUB_INT:
14897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MUL_INT:
14907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DIV_INT:
14917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case REM_INT:
14927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SHL_INT:
14937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SHR_INT:
14947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case USHR_INT:
14957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AND_INT:
14967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case OR_INT:
14977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case XOR_INT:
14987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyBinaryOp(analyzedInstruction, Primitive32BitCategories, Primitive32BitCategories);
14997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case ADD_LONG:
15017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SUB_LONG:
15027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MUL_LONG:
15037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DIV_LONG:
15047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case REM_LONG:
15057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AND_LONG:
15067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case OR_LONG:
15077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case XOR_LONG:
15087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyBinaryOp(analyzedInstruction, WideLowCategories, WideLowCategories);
15097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SHL_LONG:
15117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SHR_LONG:
15127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case USHR_LONG:
15137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyBinaryOp(analyzedInstruction, WideLowCategories, Primitive32BitCategories);
15147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case ADD_FLOAT:
15167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SUB_FLOAT:
15177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MUL_FLOAT:
15187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DIV_FLOAT:
15197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case REM_FLOAT:
15207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyBinaryOp(analyzedInstruction, Primitive32BitCategories, Primitive32BitCategories);
15217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case ADD_DOUBLE:
15237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SUB_DOUBLE:
15247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MUL_DOUBLE:
15257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DIV_DOUBLE:
15267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case REM_DOUBLE:
15277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyBinaryOp(analyzedInstruction, WideLowCategories, WideLowCategories);
15287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case ADD_INT_2ADDR:
15307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SUB_INT_2ADDR:
15317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MUL_INT_2ADDR:
15327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DIV_INT_2ADDR:
15337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case REM_INT_2ADDR:
15347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SHL_INT_2ADDR:
15357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SHR_INT_2ADDR:
15367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case USHR_INT_2ADDR:
15377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AND_INT_2ADDR:
15387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case OR_INT_2ADDR:
15397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case XOR_INT_2ADDR:
15407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyBinary2AddrOp(analyzedInstruction, Primitive32BitCategories, Primitive32BitCategories);
15417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case ADD_LONG_2ADDR:
15437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SUB_LONG_2ADDR:
15447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MUL_LONG_2ADDR:
15457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DIV_LONG_2ADDR:
15467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case REM_LONG_2ADDR:
15477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AND_LONG_2ADDR:
15487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case OR_LONG_2ADDR:
15497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case XOR_LONG_2ADDR:
15507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyBinary2AddrOp(analyzedInstruction, WideLowCategories, WideLowCategories);
15517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SHL_LONG_2ADDR:
15537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SHR_LONG_2ADDR:
15547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case USHR_LONG_2ADDR:
15557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyBinary2AddrOp(analyzedInstruction, WideLowCategories, Primitive32BitCategories);
15567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case ADD_FLOAT_2ADDR:
15587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SUB_FLOAT_2ADDR:
15597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MUL_FLOAT_2ADDR:
15607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DIV_FLOAT_2ADDR:
15617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case REM_FLOAT_2ADDR:
15627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyBinary2AddrOp(analyzedInstruction, Primitive32BitCategories, Primitive32BitCategories);
15637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case ADD_DOUBLE_2ADDR:
15657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SUB_DOUBLE_2ADDR:
15667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MUL_DOUBLE_2ADDR:
15677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DIV_DOUBLE_2ADDR:
15687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case REM_DOUBLE_2ADDR:
15697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyBinary2AddrOp(analyzedInstruction, WideLowCategories, WideLowCategories);
15707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case ADD_INT_LIT16:
15727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case RSUB_INT:
15737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MUL_INT_LIT16:
15747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DIV_INT_LIT16:
15757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case REM_INT_LIT16:
15767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyLiteralBinaryOp(analyzedInstruction);
15777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AND_INT_LIT16:
15797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case OR_INT_LIT16:
15807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case XOR_INT_LIT16:
15817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyLiteralBinaryOp(analyzedInstruction);
15827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case ADD_INT_LIT8:
15847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case RSUB_INT_LIT8:
15857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case MUL_INT_LIT8:
15867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case DIV_INT_LIT8:
15877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case REM_INT_LIT8:
15887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SHL_INT_LIT8:
15897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyLiteralBinaryOp(analyzedInstruction);
15907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case AND_INT_LIT8:
15927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case OR_INT_LIT8:
15937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case XOR_INT_LIT8:
15947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyLiteralBinaryOp(analyzedInstruction);
15957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case SHR_INT_LIT8:
15977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyLiteralBinaryOp(analyzedInstruction);
15987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
15997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case USHR_INT_LIT8:
16007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                verifyLiteralBinaryOp(analyzedInstruction);
16017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
1602d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case IGET_VOLATILE:
1603d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case IPUT_VOLATILE:
1604d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case SGET_VOLATILE:
1605d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case SPUT_VOLATILE:
1606d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case IGET_OBJECT_VOLATILE:
1607d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case IGET_WIDE_VOLATILE:
1608d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case IPUT_WIDE_VOLATILE:
1609d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case SGET_WIDE_VOLATILE:
1610d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case SPUT_WIDE_VOLATILE:
16118e51717604ca39549da64834f4136d4a2b6d4ed9Ben Gruver            case THROW_VERIFICATION_ERROR:
16127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case EXECUTE_INLINE:
16137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case EXECUTE_INLINE_RANGE:
16147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_DIRECT_EMPTY:
1615ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver            case INVOKE_OBJECT_INIT_RANGE:
16167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IGET_QUICK:
16177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IGET_WIDE_QUICK:
16187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IGET_OBJECT_QUICK:
16197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IPUT_QUICK:
16207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IPUT_WIDE_QUICK:
16217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case IPUT_OBJECT_QUICK:
16227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_VIRTUAL_QUICK:
16237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_SUPER_QUICK:
16247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_VIRTUAL_QUICK_RANGE:
16257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            case INVOKE_SUPER_QUICK_RANGE:
1626d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case IPUT_OBJECT_VOLATILE:
1627d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case SGET_OBJECT_VOLATILE:
1628d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            case SPUT_OBJECT_VOLATILE:
16299a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case INVOKE_OBJECT_INIT_JUMBO:
16309a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_VOLATILE_JUMBO:
16319a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_WIDE_VOLATILE_JUMBO:
16329a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IGET_OBJECT_VOLATILE_JUMBO:
16339a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_VOLATILE_JUMBO:
16349a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_WIDE_VOLATILE_JUMBO:
16359a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case IPUT_OBJECT_VOLATILE_JUMBO:
16369a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_VOLATILE_JUMBO:
16379a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_WIDE_VOLATILE_JUMBO:
16389a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SGET_OBJECT_VOLATILE_JUMBO:
16399a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_VOLATILE_JUMBO:
16409a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_WIDE_VOLATILE_JUMBO:
16419a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            case SPUT_OBJECT_VOLATILE_JUMBO:
16427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                //TODO: throw validation exception?
16437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            default:
16447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                assert false;
16457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                return;
16467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
16477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
16487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
1649fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private static final EnumSet<RegisterType.Category> Primitive32BitCategories = EnumSet.of(
1650fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.Null,
16517e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            RegisterType.Category.One,
1652fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.Boolean,
1653fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.Byte,
16547e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            RegisterType.Category.PosByte,
1655fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.Short,
16567e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            RegisterType.Category.PosShort,
1657fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.Char,
1658fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.Integer,
1659fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.Float);
1660fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1661fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private static final EnumSet<RegisterType.Category> WideLowCategories = EnumSet.of(
1662fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.LongLo,
1663fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.DoubleLo);
1664fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1665fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private static final EnumSet<RegisterType.Category> WideHighCategories = EnumSet.of(
1666fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.LongHi,
1667fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.DoubleHi);
1668fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1669fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    private static final EnumSet<RegisterType.Category> ReferenceCategories = EnumSet.of(
1670fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.Null,
1671fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType.Category.Reference);
1672fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1673c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com    private static final EnumSet<RegisterType.Category> ReferenceOrUninitThisCategories = EnumSet.of(
1674c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            RegisterType.Category.Null,
1675c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            RegisterType.Category.UninitThis,
1676c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            RegisterType.Category.Reference);
1677c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
16787e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com    private static final EnumSet<RegisterType.Category> ReferenceOrUninitCategories = EnumSet.of(
16797e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            RegisterType.Category.Null,
16807e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            RegisterType.Category.UninitRef,
1681c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            RegisterType.Category.UninitThis,
16827e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            RegisterType.Category.Reference);
16837e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com
168485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com    private static final EnumSet<RegisterType.Category> ReferenceAndPrimitive32BitCategories = EnumSet.of(
168585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            RegisterType.Category.Null,
16867e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            RegisterType.Category.One,
168785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            RegisterType.Category.Boolean,
168885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            RegisterType.Category.Byte,
16897e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            RegisterType.Category.PosByte,
169085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            RegisterType.Category.Short,
16917e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            RegisterType.Category.PosShort,
169285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            RegisterType.Category.Char,
169385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            RegisterType.Category.Integer,
169485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            RegisterType.Category.Float,
169585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            RegisterType.Category.Reference);
1696fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1697195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com    private static final EnumSet<RegisterType.Category> BooleanCategories = EnumSet.of(
1698195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            RegisterType.Category.Null,
1699195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            RegisterType.Category.One,
1700195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            RegisterType.Category.Boolean);
1701fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
17027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeMove(AnalyzedInstruction analyzedInstruction) {
1703fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
1704fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
17057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
1706fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, sourceRegisterType);
1707fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1708fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
17097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyMove(AnalyzedInstruction analyzedInstruction, EnumSet validCategories) {
17107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
17117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
17127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validCategories);
17137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
17147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
17157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeMoveResult(AnalyzedInstruction analyzedInstruction) {
17167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        AnalyzedInstruction previousInstruction = instructions.valueAt(analyzedInstruction.instructionIndex-1);
17177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        if (!previousInstruction.instruction.opcode.setsResult()) {
17187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            throw new ValidationException(analyzedInstruction.instruction.opcode.name + " must occur after an " +
17197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    "invoke-*/fill-new-array instruction");
17207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
17217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
17227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType resultRegisterType;
17237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        InstructionWithReference invokeInstruction = (InstructionWithReference)previousInstruction.instruction;
17247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        Item item = invokeInstruction.getReferencedItem();
17257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
17267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        if (item.getItemType() == ItemType.TYPE_METHOD_ID_ITEM) {
17277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            resultRegisterType = RegisterType.getRegisterTypeForTypeIdItem(
17287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    ((MethodIdItem)item).getPrototype().getReturnType());
17297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        } else {
17307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM;
17317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            resultRegisterType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item);
17327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
1733fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
17347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, resultRegisterType);
17357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
1736fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
17377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyMoveResult(AnalyzedInstruction analyzedInstruction,
17387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                                     EnumSet<RegisterType.Category> allowedCategories) {
1739fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (analyzedInstruction.instructionIndex == 0) {
1740fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            throw new ValidationException(analyzedInstruction.instruction.opcode.name + " cannot be the first " +
1741fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                    "instruction in a method. It must occur after an invoke-*/fill-new-array instruction");
1742fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
1743fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1744fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        AnalyzedInstruction previousInstruction = instructions.valueAt(analyzedInstruction.instructionIndex-1);
1745fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1746fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (!previousInstruction.instruction.opcode.setsResult()) {
1747fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            throw new ValidationException(analyzedInstruction.instruction.opcode.name + " must occur after an " +
1748fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                    "invoke-*/fill-new-array instruction");
1749fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
1750fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1751fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        //TODO: does dalvik allow a move-result after an invoke with a void return type?
175285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        RegisterType resultRegisterType;
1753fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
17547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        InstructionWithReference invokeInstruction = (InstructionWithReference)previousInstruction.getInstruction();
1755fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        Item item = invokeInstruction.getReferencedItem();
1756fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1757fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (item instanceof MethodIdItem) {
175885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            resultRegisterType = RegisterType.getRegisterTypeForTypeIdItem(
1759fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                    ((MethodIdItem)item).getPrototype().getReturnType());
1760fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        } else {
1761fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            assert item instanceof TypeIdItem;
176285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            resultRegisterType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item);
176385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        }
176485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com
176585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        if (!allowedCategories.contains(resultRegisterType.category)) {
176685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Wrong move-result* instruction for return value %s",
176785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                    resultRegisterType.toString()));
1768fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
17697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
1770fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
17717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeMoveException(AnalyzedInstruction analyzedInstruction) {
17727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        CodeItem.TryItem[] tries = encodedMethod.codeItem.getTries();
17737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        int instructionAddress = getInstructionAddress(analyzedInstruction);
17747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
17757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        if (tries == null) {
17767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            throw new ValidationException("move-exception must be the first instruction in an exception handler block");
17777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
17787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
17797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType exceptionType = null;
17807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
17817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        for (CodeItem.TryItem tryItem: encodedMethod.codeItem.getTries()) {
17827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            if (tryItem.encodedCatchHandler.getCatchAllHandlerAddress() == instructionAddress) {
17837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                exceptionType = RegisterType.getRegisterType(RegisterType.Category.Reference,
17847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        ClassPath.getClassDef("Ljava/lang/Throwable;"));
17857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                break;
17867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            }
17877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            for (CodeItem.EncodedTypeAddrPair handler: tryItem.encodedCatchHandler.handlers) {
17887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                if (handler.getHandlerAddress() == instructionAddress) {
17897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    exceptionType = RegisterType.getRegisterTypeForTypeIdItem(handler.exceptionType)
17907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                            .merge(exceptionType);
17917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                }
17927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            }
17937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
17947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
17957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        if (exceptionType == null) {
17967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            throw new ValidationException("move-exception must be the first instruction in an exception handler block");
17977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
17987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
17997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, exceptionType);
1800fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1801fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
18027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyMoveException(AnalyzedInstruction analyzedInstruction) {
1803fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        CodeItem.TryItem[] tries = encodedMethod.codeItem.getTries();
1804fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        int instructionAddress = getInstructionAddress(analyzedInstruction);
1805fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1806fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (tries == null) {
1807fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            throw new ValidationException("move-exception must be the first instruction in an exception handler block");
1808fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
1809fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1810fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        RegisterType exceptionType = null;
1811fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1812fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        for (CodeItem.TryItem tryItem: encodedMethod.codeItem.getTries()) {
1813fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            if (tryItem.encodedCatchHandler.getCatchAllHandlerAddress() == instructionAddress) {
1814fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                exceptionType = RegisterType.getRegisterType(RegisterType.Category.Reference,
1815fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                        ClassPath.getClassDef("Ljava/lang/Throwable;"));
1816fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                break;
1817fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            }
1818fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            for (CodeItem.EncodedTypeAddrPair handler: tryItem.encodedCatchHandler.handlers) {
1819fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                if (handler.getHandlerAddress() == instructionAddress) {
1820fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                    exceptionType = RegisterType.getRegisterTypeForTypeIdItem(handler.exceptionType)
1821fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                            .merge(exceptionType);
1822fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                }
1823fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            }
1824fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
1825fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
182685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        if (exceptionType == null) {
182785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            throw new ValidationException("move-exception must be the first instruction in an exception handler block");
182885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        }
182985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com
1830fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        //TODO: check if the type is a throwable. Should we throw a ValidationException or print a warning? (does dalvik validate that it's a throwable? It doesn't in CodeVerify.c, but it might check in DexSwapVerify.c)
183185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        if (exceptionType.category != RegisterType.Category.Reference) {
183285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Exception type %s is not a reference type",
183385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                    exceptionType.toString()));
183485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        }
1835fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1836fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
18374a5692f8275048c564abc617b91ae72bb008fccaBen Gruver    private void analyzeReturnVoidBarrier(AnalyzedInstruction analyzedInstruction) {
1838ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        analyzeReturnVoidBarrier(analyzedInstruction, true);
1839ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver    }
1840ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver
1841ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver    private void analyzeReturnVoidBarrier(AnalyzedInstruction analyzedInstruction, boolean analyzeResult) {
18424a5692f8275048c564abc617b91ae72bb008fccaBen Gruver        Instruction10x instruction = (Instruction10x)analyzedInstruction.instruction;
18434a5692f8275048c564abc617b91ae72bb008fccaBen Gruver
18444a5692f8275048c564abc617b91ae72bb008fccaBen Gruver        Instruction10x deodexedInstruction = new Instruction10x(Opcode.RETURN_VOID);
18454a5692f8275048c564abc617b91ae72bb008fccaBen Gruver
18464a5692f8275048c564abc617b91ae72bb008fccaBen Gruver        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
18474a5692f8275048c564abc617b91ae72bb008fccaBen Gruver
1848ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        if (analyzeResult) {
1849ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver            analyzeInstruction(analyzedInstruction);
1850ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        }
18514a5692f8275048c564abc617b91ae72bb008fccaBen Gruver    }
18524a5692f8275048c564abc617b91ae72bb008fccaBen Gruver
18537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyReturnVoid(AnalyzedInstruction analyzedInstruction) {
1854fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        TypeIdItem returnType = encodedMethod.method.getPrototype().getReturnType();
1855fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (returnType.getTypeDescriptor().charAt(0) != 'V') {
1856fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            //TODO: could add which return-* variation should be used instead
1857fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            throw new ValidationException("Cannot use return-void with a non-void return type (" +
1858fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                returnType.getTypeDescriptor() + ")");
1859fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
1860fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1861fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
18627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyReturn(AnalyzedInstruction analyzedInstruction, EnumSet validCategories) {
1863c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com        /*if (this.isInstanceConstructor()) {
1864ee7ca05c819845d013d0b15f9c75a92fea6a3b3dJesusFreke@JesusFreke.com            checkConstructorReturn(analyzedInstruction);
1865c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com        }*/
1866fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1867fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
186885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        int returnRegister = instruction.getRegisterA();
186985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        RegisterType returnRegisterType = getAndCheckSourceRegister(analyzedInstruction, returnRegister,
187085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                validCategories);
1871fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1872fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        TypeIdItem returnType = encodedMethod.method.getPrototype().getReturnType();
1873fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (returnType.getTypeDescriptor().charAt(0) == 'V') {
1874fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            throw new ValidationException("Cannot use return with a void return type. Use return-void instead");
1875fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
1876fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
187785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        RegisterType methodReturnRegisterType = RegisterType.getRegisterTypeForTypeIdItem(returnType);
1878fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
187985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        if (!validCategories.contains(methodReturnRegisterType.category)) {
1880fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            //TODO: could add which return-* variation should be used instead
188185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use %s with return type %s",
188285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                    analyzedInstruction.instruction.opcode.name, returnType.getTypeDescriptor()));
1883fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
1884fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
188585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        if (validCategories == ReferenceCategories) {
188685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            if (methodReturnRegisterType.type.isInterface()) {
1887c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                if (returnRegisterType.category != RegisterType.Category.Null &&
1888c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                    !returnRegisterType.type.implementsInterface(methodReturnRegisterType.type)) {
188985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                    //TODO: how to handle warnings?
189085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                }
189185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            } else {
1892c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                if (returnRegisterType.category == RegisterType.Category.Reference &&
1893c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                    !returnRegisterType.type.extendsClass(methodReturnRegisterType.type)) {
1894c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
189585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                    throw new ValidationException(String.format("The return value in register v%d (%s) is not " +
189685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                            "compatible with the method's return type %s", returnRegister,
189785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                            returnRegisterType.type.getClassType(), methodReturnRegisterType.type.getClassType()));
189885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                }
1899fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            }
1900fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
1901fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1902fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
19037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeConst(AnalyzedInstruction analyzedInstruction) {
1904fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        LiteralInstruction instruction = (LiteralInstruction)analyzedInstruction.instruction;
1905fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1906fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        RegisterType newDestinationRegisterType = RegisterType.getRegisterTypeForLiteral(instruction.getLiteral());
1907fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1908fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        //we assume that the literal value is a valid value for the given instruction type, because it's impossible
1909fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        //to store an invalid literal with the instruction. so we don't need to check the type of the literal
1910fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, newDestinationRegisterType);
1911fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1912fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
19137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeConstHigh16(AnalyzedInstruction analyzedInstruction) {
19147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        //the literal value stored in the instruction is a 16-bit value. When shifted left by 16, it will always be an
19157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        //integer
19167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
19177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                RegisterType.getRegisterType(RegisterType.Category.Integer, null));
1918fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1919fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
19207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeWideConst(AnalyzedInstruction analyzedInstruction) {
192185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
1922fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                RegisterType.getRegisterType(RegisterType.Category.LongLo, null));
1923fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1924fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
19257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeConstString(AnalyzedInstruction analyzedInstruction) {
1926fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        ClassPath.ClassDef stringClassDef = ClassPath.getClassDef("Ljava/lang/String;");
1927fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        RegisterType stringType = RegisterType.getRegisterType(RegisterType.Category.Reference, stringClassDef);
1928fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, stringType);
1929fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1930fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
19317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeConstClass(AnalyzedInstruction analyzedInstruction) {
19327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        ClassPath.ClassDef classClassDef = ClassPath.getClassDef("Ljava/lang/Class;");
19337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType classType = RegisterType.getRegisterType(RegisterType.Category.Reference, classClassDef);
19347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
19357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, classType);
19367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
19377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
19387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
19397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyConstClass(AnalyzedInstruction analyzedInstruction) {
1940fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        ClassPath.ClassDef classClassDef = ClassPath.getClassDef("Ljava/lang/Class;");
1941fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        RegisterType classType = RegisterType.getRegisterType(RegisterType.Category.Reference, classClassDef);
1942fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1943fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction;
1944fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        Item item = instruction.getReferencedItem();
1945fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM;
1946fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1947fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        //TODO: need to check class access
1948c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com        //make sure the referenced class is resolvable
1949c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com        ClassPath.getClassDef((TypeIdItem)item);
1950fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1951fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
19527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyMonitor(AnalyzedInstruction analyzedInstruction) {
195385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
195485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), ReferenceCategories);
1955fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1956fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
19577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeCheckCast(AnalyzedInstruction analyzedInstruction) {
19587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction;
19597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
19607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        Item item = instruction.getReferencedItem();
19617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM;
19627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
19637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType castRegisterType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item);
19647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, castRegisterType);
19657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
19667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
19677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyCheckCast(AnalyzedInstruction analyzedInstruction) {
1968fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        {
1969fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            //ensure the "source" register is a reference type
1970fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
1971fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
197285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            RegisterType registerType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(),
197385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                    ReferenceCategories);
1974fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
1975fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1976fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        {
1977fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            //resolve and verify the class that we're casting to
1978fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction;
1979fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1980fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            Item item = instruction.getReferencedItem();
1981fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM;
1982fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
1983fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            //TODO: need to check class access
198485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            RegisterType castRegisterType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item);
198585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            if (castRegisterType.category != RegisterType.Category.Reference) {
1986fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                //TODO: verify that dalvik allows a non-reference type..
1987fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                //TODO: print a warning, but don't re-throw the exception. dalvik allows a non-reference type during validation (but throws an exception at runtime)
1988fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            }
1989fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
1990fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
1991fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
19927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeInstanceOf(AnalyzedInstruction analyzedInstruction) {
19937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
19947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                RegisterType.getRegisterType(RegisterType.Category.Boolean, null));
19957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
19967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
19977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyInstanceOf(AnalyzedInstruction analyzedInstruction) {
1998fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        {
1999fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            //ensure the register that is being checks is a reference type
200085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
2001fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
200285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), ReferenceCategories);
2003fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
2004fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
2005fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        {
2006fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            //resolve and verify the class that we're checking against
2007fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction;
2008fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
2009fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            Item item = instruction.getReferencedItem();
2010fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            assert  item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM;
2011fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            RegisterType registerType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item);
201285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            if (registerType.category != RegisterType.Category.Reference) {
201385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use instance-of with a non-reference type %s",
201485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                        registerType.toString()));
201585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            }
2016fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
2017fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            //TODO: is it valid to use an array type?
2018fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            //TODO: could probably do an even more sophisticated check, where we check the possible register types against the specified type. In some cases, we could determine that it always fails, and print a warning to that effect.
2019fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
2020fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
2021fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
20227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeArrayLength(AnalyzedInstruction analyzedInstruction) {
20237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
20247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                RegisterType.getRegisterType(RegisterType.Category.Integer, null));
20257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
20267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
20277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyArrayLength(AnalyzedInstruction analyzedInstruction) {
202885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
2029fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
2030fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        int arrayRegisterNumber = instruction.getRegisterB();
203185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        RegisterType arrayRegisterType = getAndCheckSourceRegister(analyzedInstruction, arrayRegisterNumber,
203285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                ReferenceCategories);
2033fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
2034fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (arrayRegisterType.type != null) {
2035fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            if (arrayRegisterType.type.getClassType().charAt(0) != '[') {
203685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use array-length with non-array type %s",
203785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                        arrayRegisterType.type.getClassType()));
2038d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com            }
2039c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef;
2040d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        }
20417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
20427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
20437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeNewInstance(AnalyzedInstruction analyzedInstruction) {
20447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction;
20457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
20467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA();
20477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType destRegisterType = analyzedInstruction.getPostInstructionRegisterType(register);
20487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        if (destRegisterType.category != RegisterType.Category.Unknown) {
20497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            assert destRegisterType.category == RegisterType.Category.UninitRef;
20507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
20517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            //the post-instruction destination register will only be set if we have already analyzed this instruction
20527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            //at least once. If this is the case, then the uninit reference has already been propagated to all
20537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            //successors and nothing else needs to be done.
20547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            return;
20557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
20567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
20577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        Item item = instruction.getReferencedItem();
20587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM;
20597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
20607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType classType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item);
2061d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
2062fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
20637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                RegisterType.getUnitializedReference(classType.type));
2064fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
2065fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
20667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyNewInstance(AnalyzedInstruction analyzedInstruction) {
2067fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction;
2068fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
2069a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com        int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA();
2070a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com        RegisterType destRegisterType = analyzedInstruction.postRegisterMap[register];
2071a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com        if (destRegisterType.category != RegisterType.Category.Unknown) {
2072a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com            assert destRegisterType.category == RegisterType.Category.UninitRef;
2073a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com
2074a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com            //the "post-instruction" destination register will only be set if we've gone over
2075a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com            //this instruction at least once before. If this is the case, then we need to check
2076a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com            //all the other registers, and make sure that none of them contain the same
2077a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com            //uninitialized reference that is in the destination register.
2078a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com
2079a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com            for (int i=0; i<analyzedInstruction.postRegisterMap.length; i++) {
2080a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com                if (i==register) {
2081a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com                    continue;
2082a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com                }
2083a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com
2084a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com                if (analyzedInstruction.getPreInstructionRegisterType(i) == destRegisterType) {
2085a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com                    throw new ValidationException(String.format("Register v%d contains an uninitialized reference " +
2086a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com                            "that was created by this new-instance instruction.", i));
2087a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com                }
2088a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com            }
2089c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
2090c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            return;
2091a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com        }
2092a0314c265e76426e3e05e615cc713cf36c78cb85JesusFreke@JesusFreke.com
2093fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        Item item = instruction.getReferencedItem();
2094fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM;
2095fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
2096fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        //TODO: need to check class access
2097fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        RegisterType classType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item);
209885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        if (classType.category != RegisterType.Category.Reference) {
209985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use new-instance with a non-reference type %s",
210085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                    classType.toString()));
210185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        }
210285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com
2103fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (((TypeIdItem)item).getTypeDescriptor().charAt(0) == '[') {
2104fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            throw new ValidationException("Cannot use array type \"" + ((TypeIdItem)item).getTypeDescriptor() +
2105fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                    "\" with new-instance. Use new-array instead.");
2106d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com        }
21077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
2108d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
21097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeNewArray(AnalyzedInstruction analyzedInstruction) {
21107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction;
21117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
21127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        Item item = instruction.getReferencedItem();
21137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM;
21147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
21157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType arrayType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item);
21167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        assert arrayType.type instanceof ClassPath.ArrayClassDef;
21177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
21187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, arrayType);
2119fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
2120fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
21217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyNewArray(AnalyzedInstruction analyzedInstruction) {
2122fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        {
2123fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
212485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), Primitive32BitCategories);
2125fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
2126fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
2127fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction;
2128fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
2129fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        Item item = instruction.getReferencedItem();
2130fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        assert item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM;
2131fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
2132fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        RegisterType arrayType = RegisterType.getRegisterTypeForTypeIdItem((TypeIdItem)item);
2133fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        assert arrayType.type instanceof ClassPath.ArrayClassDef;
2134d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
213585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        if (arrayType.category != RegisterType.Category.Reference) {
213685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use new-array with a non-reference type %s",
213785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                    arrayType.toString()));
213885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        }
2139fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        if (arrayType.type.getClassType().charAt(0) != '[') {
2140fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com            throw new ValidationException("Cannot use non-array type \"" + arrayType.type.getClassType() +
2141fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com                    "\" with new-array. Use new-instance instead.");
2142fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
2143fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com    }
2144fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
21457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyFilledNewArrayCommon(AnalyzedInstruction analyzedInstruction,
2146ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com                                               RegisterIterator registerIterator) {
2147ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction;
2148ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com
21499e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com        RegisterType arrayType;
21509e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com        RegisterType arrayImmediateElementType;
21519e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com
2152ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        Item item = instruction.getReferencedItem();
2153ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        assert  item.getItemType() == ItemType.TYPE_TYPE_ID_ITEM;
21549e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com
2155ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        ClassPath.ClassDef classDef = ClassPath.getClassDef((TypeIdItem)item);
21569e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com
2157ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        if (classDef.getClassType().charAt(0) != '[') {
2158ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com            throw new ValidationException("Cannot use non-array type \"" + classDef.getClassType() +
2159ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com                "\" with new-array. Use new-instance instead.");
21609e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com        }
21619e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com
2162ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)classDef;
2163ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        arrayType = RegisterType.getRegisterType(RegisterType.Category.Reference, classDef);
2164ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        arrayImmediateElementType = RegisterType.getRegisterTypeForType(
2165ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com                arrayClassDef.getImmediateElementClass().getClassType());
2166ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        String baseElementType = arrayClassDef.getBaseElementClass().getClassType();
2167ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        if (baseElementType.charAt(0) == 'J' || baseElementType.charAt(0) == 'D') {
2168ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com            throw new ValidationException("Cannot use filled-new-array to create an array of wide values " +
2169ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com                    "(long or double)");
2170ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        }
21719e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com
2172ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        do {
2173ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com            int register = registerIterator.getRegister();
21749e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com            RegisterType elementType = analyzedInstruction.getPreInstructionRegisterType(register);
21759e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com            assert elementType != null;
21769e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com
21779e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com            if (!elementType.canBeAssignedTo(arrayImmediateElementType)) {
21789e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com                throw new ValidationException("Register v" + Integer.toString(register) + " is of type " +
21799e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com                        elementType.toString() + " and is incompatible with the array type " +
21809e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com                        arrayType.type.getClassType());
21819e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com            }
2182ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        } while (registerIterator.moveNext());
21839e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com    }
21849e5dd85d837501e84e18617fc136c8203ab1f183JesusFreke@JesusFreke.com
21857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyFilledNewArray(AnalyzedInstruction analyzedInstruction) {
2186ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        FiveRegisterInstruction instruction = (FiveRegisterInstruction)analyzedInstruction.instruction;
21877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        verifyFilledNewArrayCommon(analyzedInstruction, new Format35cRegisterIterator(instruction));
2188ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com    }
2189ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com
21907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyFilledNewArrayRange(AnalyzedInstruction analyzedInstruction) {
2191b615ba6f51a42428937236a640480d6f7f9dc511JesusFreke@JesusFreke.com        RegisterRangeInstruction instruction = (RegisterRangeInstruction)analyzedInstruction.instruction;
2192ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com
2193ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        //instruction.getStartRegister() and instruction.getRegCount() both return an int value, but are actually
2194ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        //unsigned 16 bit values, so we don't have to worry about overflowing an int when adding them together
2195ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        if (instruction.getStartRegister() + instruction.getRegCount() >= 1<<16) {
2196ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com            throw new ValidationException(String.format("Invalid register range {v%d .. v%d}. The ending register " +
2197472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                    "is larger than the largest allowed register of v65535.",
2198ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com                    instruction.getStartRegister(),
2199ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com                    instruction.getStartRegister() + instruction.getRegCount() - 1));
2200ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com        }
2201ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com
22027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        verifyFilledNewArrayCommon(analyzedInstruction, new Format3rcRegisterIterator(instruction));
2203ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com    }
2204ac8785e5d550c2ec7c7d02dd2990f859a78c111cJesusFreke@JesusFreke.com
22057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyFillArrayData(AnalyzedInstruction analyzedInstruction) {
2206472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
2207472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com
2208472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        int register = instruction.getRegisterA();
2209472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(register);
2210472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        assert registerType != null;
2211472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com
2212ee7ca05c819845d013d0b15f9c75a92fea6a3b3dJesusFreke@JesusFreke.com        if (registerType.category == RegisterType.Category.Null) {
2213ee7ca05c819845d013d0b15f9c75a92fea6a3b3dJesusFreke@JesusFreke.com            return;
2214472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        }
2215472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com
2216472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        if (registerType.category != RegisterType.Category.Reference) {
2217472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use fill-array-data with non-array register v%d of " +
2218472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                    "type %s", register, registerType.toString()));
2219472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        }
2220472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com
2221472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        assert registerType.type instanceof ClassPath.ArrayClassDef;
2222472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)registerType.type;
2223472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com
2224472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        if (arrayClassDef.getArrayDimensions() != 1) {
2225472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use fill-array-data with array type %s. It can only " +
2226472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                    "be used with a one-dimensional array of primitives.", arrayClassDef.getClassType()));
2227472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        }
2228472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com
2229472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        int elementWidth;
2230472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        switch (arrayClassDef.getBaseElementClass().getClassType().charAt(0)) {
2231472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            case 'Z':
2232472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            case 'B':
2233472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                elementWidth = 1;
2234472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                break;
2235472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            case 'C':
2236472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            case 'S':
2237472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                elementWidth = 2;
2238472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                break;
2239472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            case 'I':
2240472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            case 'F':
2241472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                elementWidth = 4;
2242472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                break;
2243472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            case 'J':
2244472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            case 'D':
2245472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                elementWidth = 8;
2246472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                break;
2247472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            default:
2248472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use fill-array-data with array type %s. It can " +
2249472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                        "only be used with a one-dimensional array of primitives.", arrayClassDef.getClassType()));
2250472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        }
2251472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com
2252472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com
2253b7e78115277e30c71e6e991da3f31c5a1403c634JesusFreke@JesusFreke.com        int arrayDataAddressOffset = ((OffsetInstruction)analyzedInstruction.instruction).getTargetAddressOffset();
2254b7e78115277e30c71e6e991da3f31c5a1403c634JesusFreke@JesusFreke.com        int arrayDataCodeAddress = getInstructionAddress(analyzedInstruction) + arrayDataAddressOffset;
2255b7e78115277e30c71e6e991da3f31c5a1403c634JesusFreke@JesusFreke.com        AnalyzedInstruction arrayDataInstruction = this.instructions.get(arrayDataCodeAddress);
2256472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        if (arrayDataInstruction == null || arrayDataInstruction.instruction.getFormat() != Format.ArrayData) {
2257472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            throw new ValidationException(String.format("Could not find an array data structure at code address 0x%x",
2258b7e78115277e30c71e6e991da3f31c5a1403c634JesusFreke@JesusFreke.com                    arrayDataCodeAddress));
2259472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        }
2260472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com
2261472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        ArrayDataPseudoInstruction arrayDataPseudoInstruction =
2262472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                (ArrayDataPseudoInstruction)arrayDataInstruction.instruction;
2263472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com
2264472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        if (elementWidth != arrayDataPseudoInstruction.getElementWidth()) {
2265472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com            throw new ValidationException(String.format("The array data at code address 0x%x does not have the " +
2266472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                    "correct element width for array type %s. Expecting element width %d, got element width %d.",
2267b7e78115277e30c71e6e991da3f31c5a1403c634JesusFreke@JesusFreke.com                    arrayDataCodeAddress, arrayClassDef.getClassType(), elementWidth,
2268472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com                    arrayDataPseudoInstruction.getElementWidth()));
2269472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com        }
2270472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com    }
2271472d3ea58455ebf43d21819b2701fad98b5a0f9cJesusFreke@JesusFreke.com
22727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyThrow(AnalyzedInstruction analyzedInstruction) {
2273ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com        int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA();
2274ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com
2275ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com        RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(register);
2276ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com        assert registerType != null;
2277ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com
2278ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com        if (registerType.category == RegisterType.Category.Null) {
2279ee7ca05c819845d013d0b15f9c75a92fea6a3b3dJesusFreke@JesusFreke.com            return;
2280ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com        }
2281ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com
2282ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com        if (registerType.category != RegisterType.Category.Reference) {
2283ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use throw with non-reference type %s in register v%d",
2284ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com                    registerType.toString(), register));
2285ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com        }
2286ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com
2287ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com        assert registerType.type != null;
2288ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com
2289ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com        if (!registerType.type.extendsClass(ClassPath.getClassDef("Ljava/lang/Throwable;"))) {
2290ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use throw with non-throwable type %s in register v%d",
2291ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com                    registerType.type.getClassType(), register));
2292ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com        }
2293ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com    }
2294ed140ca3e4fa66a03970affb3415a9fe2a924312JesusFreke@JesusFreke.com
2295db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com    private void analyzeArrayDataOrSwitch(AnalyzedInstruction analyzedInstruction) {
2296db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com        int dataAddressOffset = ((OffsetInstruction)analyzedInstruction.instruction).getTargetAddressOffset();
2297db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com
2298db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com        int dataCodeAddress = this.getInstructionAddress(analyzedInstruction) + dataAddressOffset;
2299db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com        AnalyzedInstruction dataAnalyzedInstruction = instructions.get(dataCodeAddress);
2300db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com
2301db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com        if (dataAnalyzedInstruction != null) {
2302db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com            dataAnalyzedInstruction.dead = false;
2303db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com
2304db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com            //if there is a preceding nop, it's deadness should be the same
2305db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com            AnalyzedInstruction priorInstruction =
2306db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com                    instructions.valueAt(dataAnalyzedInstruction.getInstructionIndex()-1);
2307db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com            if (priorInstruction.getInstruction().opcode == Opcode.NOP &&
2308db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com                    !priorInstruction.getInstruction().getFormat().variableSizeFormat) {
2309db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com
2310db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com                priorInstruction.dead = false;
2311db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com            }
2312db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com        }
2313db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com    }
2314db26b663aa3b5bb721185b8798b6767710d3c243JesusFreke@JesusFreke.com
23157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifySwitch(AnalyzedInstruction analyzedInstruction, Format expectedSwitchDataFormat) {
2316cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com        int register = ((SingleRegisterInstruction)analyzedInstruction.instruction).getRegisterA();
2317cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com        int switchCodeAddressOffset = ((OffsetInstruction)analyzedInstruction.instruction).getTargetAddressOffset();
2318cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com
231985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, register, Primitive32BitCategories);
2320cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com
2321cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com        int switchDataCodeAddress = this.getInstructionAddress(analyzedInstruction) + switchCodeAddressOffset;
2322cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com        AnalyzedInstruction switchDataAnalyzedInstruction = instructions.get(switchDataCodeAddress);
2323cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com
2324cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com        if (switchDataAnalyzedInstruction == null ||
2325cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com            switchDataAnalyzedInstruction.instruction.getFormat() != expectedSwitchDataFormat) {
2326cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com            throw new ValidationException(String.format("There is no %s structure at code address 0x%x",
2327cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com                    expectedSwitchDataFormat.name(), switchDataCodeAddress));
2328cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com        }
2329cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com    }
2330cda44f70cfebfae4875cd77455a171075aebac4dJesusFreke@JesusFreke.com
23317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeFloatWideCmp(AnalyzedInstruction analyzedInstruction) {
23327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
23337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                RegisterType.getRegisterType(RegisterType.Category.Byte, null));
23347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
23357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
23367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyFloatWideCmp(AnalyzedInstruction analyzedInstruction, EnumSet validCategories) {
2337f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com        ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;
2338f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com
233985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validCategories);
234085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), validCategories);
2341f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com    }
2342f1a74cea19f10e9059e05f1cee6ae45baf118108JesusFreke@JesusFreke.com
23437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyIfEqNe(AnalyzedInstruction analyzedInstruction) {
2344aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
2345aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com
2346aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com        RegisterType registerType1 = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA());
2347aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com        assert registerType1 != null;
2348aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com
2349aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com        RegisterType registerType2 = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
2350aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com        assert registerType2 != null;
2351aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com
2352aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com        if (!(
2353aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com                (ReferenceCategories.contains(registerType1.category) &&
2354aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com                ReferenceCategories.contains(registerType2.category))
2355aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com                    ||
2356aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com                (Primitive32BitCategories.contains(registerType1.category) &&
2357aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com                Primitive32BitCategories.contains(registerType2.category))
2358aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com              )) {
2359aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com
2360aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com            throw new ValidationException(String.format("%s cannot be used on registers of dissimilar types %s and " +
2361aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com                    "%s. They must both be a reference type or a primitive 32 bit type.",
2362aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com                    analyzedInstruction.instruction.opcode.name, registerType1.toString(), registerType2.toString()));
2363aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com        }
2364aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com    }
2365aba6bb0bbd1537a6df9614ee579773e4a8af70ffJesusFreke@JesusFreke.com
23667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyIf(AnalyzedInstruction analyzedInstruction) {
2367150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
2368150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com
236985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), Primitive32BitCategories);
237085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), Primitive32BitCategories);
2371150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com    }
2372150acd9db94f9886f6fc32e89acc15a1a5c1466fJesusFreke@JesusFreke.com
23737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyIfEqzNez(AnalyzedInstruction analyzedInstruction) {
2374cb00252b6aed86cd3e7c426015cea83fcdbaa806JesusFreke@JesusFreke.com        SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
2375cb00252b6aed86cd3e7c426015cea83fcdbaa806JesusFreke@JesusFreke.com
237685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(),
237785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                ReferenceAndPrimitive32BitCategories);
2378cb00252b6aed86cd3e7c426015cea83fcdbaa806JesusFreke@JesusFreke.com    }
2379cb00252b6aed86cd3e7c426015cea83fcdbaa806JesusFreke@JesusFreke.com
23807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyIfz(AnalyzedInstruction analyzedInstruction) {
238116a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com        SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
238216a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com
238385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), Primitive32BitCategories);
238416a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com    }
238516a709ba046343bfefc15a6cdb0be38282126223JesusFreke@JesusFreke.com
23867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyze32BitPrimitiveAget(AnalyzedInstruction analyzedInstruction,
23877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                                             RegisterType.Category instructionCategory) {
23887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
23897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                RegisterType.getRegisterType(instructionCategory, null));
23907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
23917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
23927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verify32BitPrimitiveAget(AnalyzedInstruction analyzedInstruction,
2393b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com                                             RegisterType.Category instructionCategory) {
2394b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com        ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;
2395b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com
239685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories);
2397b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com
2398b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com        RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
2399b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com        assert arrayRegisterType != null;
2400b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com
2401b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com        if (arrayRegisterType.category != RegisterType.Category.Null) {
2402b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            if (arrayRegisterType.category != RegisterType.Category.Reference) {
2403b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with non-array type %s",
2404b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com                        analyzedInstruction.instruction.opcode.name, arrayRegisterType.category.toString()));
2405b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            }
2406b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com
2407b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            assert arrayRegisterType.type != null;
2408b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            if (arrayRegisterType.type.getClassType().charAt(0) != '[') {
2409b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with non-array type %s",
2410b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com                        analyzedInstruction.instruction.opcode.name, arrayRegisterType.type.getClassType()));
2411b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            }
2412b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com
2413b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef;
2414b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type;
2415b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com
2416b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            if (arrayClassDef.getArrayDimensions() != 1) {
2417b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with multi-dimensional array type %s",
2418b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com                        analyzedInstruction.instruction.opcode.name, arrayRegisterType.type.getClassType()));
2419b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            }
2420b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com
2421b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            RegisterType arrayBaseType =
2422b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com                    RegisterType.getRegisterTypeForType(arrayClassDef.getBaseElementClass().getClassType());
2423c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            if (!checkArrayFieldAssignment(arrayBaseType.category, instructionCategory)) {
2424b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with array type %s. Incorrect array type " +
2425b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com                        "for the instruction.", analyzedInstruction.instruction.opcode.name,
2426b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com                        arrayRegisterType.type.getClassType()));
2427b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            }
2428b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com        }
2429b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com    }
2430b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com
24317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeAgetWide(AnalyzedInstruction analyzedInstruction) {
2432c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com        ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;
2433c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com
2434c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com        RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
2435c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com        assert arrayRegisterType != null;
2436c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com
2437c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com        if (arrayRegisterType.category != RegisterType.Category.Null) {
2438c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com            assert arrayRegisterType.type != null;
2439c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com            if (arrayRegisterType.type.getClassType().charAt(0) != '[') {
2440c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-wide with non-array type %s",
2441c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com                        arrayRegisterType.type.getClassType()));
2442c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com            }
2443c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com
2444c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com            assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef;
2445c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com            ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type;
2446c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com
2447c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com            char arrayBaseType = arrayClassDef.getBaseElementClass().getClassType().charAt(0);
2448c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com            if (arrayBaseType == 'J') {
244985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
2450c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com                        RegisterType.getRegisterType(RegisterType.Category.LongLo, null));
2451c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com            } else if (arrayBaseType == 'D') {
245285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
2453c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com                        RegisterType.getRegisterType(RegisterType.Category.DoubleLo, null));
2454c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com            } else {
2455c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-wide with array type %s. Incorrect " +
2456c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com                        "array type for the instruction.", arrayRegisterType.type.getClassType()));
2457c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com            }
2458c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com        } else {
245985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
2460c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com                        RegisterType.getRegisterType(RegisterType.Category.LongLo, null));
2461c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com        }
2462c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com    }
2463c308b24b6261ea81497a69e6d4d7ef6319943b10JesusFreke@JesusFreke.com
24647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyAgetWide(AnalyzedInstruction analyzedInstruction) {
2465461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com        ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;
2466461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com
246785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories);
2468461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com
2469461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com        RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
2470461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com        assert arrayRegisterType != null;
2471461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com
2472461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com        if (arrayRegisterType.category != RegisterType.Category.Null) {
2473461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            if (arrayRegisterType.category != RegisterType.Category.Reference) {
24747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-wide with non-array type %s",
2475461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com                        arrayRegisterType.category.toString()));
2476461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            }
2477461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com
2478461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            assert arrayRegisterType.type != null;
2479461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            if (arrayRegisterType.type.getClassType().charAt(0) != '[') {
24807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-wide with non-array type %s",
24817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        arrayRegisterType.type.getClassType()));
24827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            }
24837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
24847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef;
24857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type;
24867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
24877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            if (arrayClassDef.getArrayDimensions() != 1) {
24887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-wide with multi-dimensional array type %s",
24897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        arrayRegisterType.type.getClassType()));
24907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            }
24917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
24927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            char arrayBaseType = arrayClassDef.getBaseElementClass().getClassType().charAt(0);
24937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            if (arrayBaseType != 'J' && arrayBaseType != 'D') {
24947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-wide with array type %s. Incorrect " +
24957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        "array type for the instruction.", arrayRegisterType.type.getClassType()));
24967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            }
24977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
24987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
24997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
25007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeAgetObject(AnalyzedInstruction analyzedInstruction) {
25017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;
25027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
25037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
25047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        assert arrayRegisterType != null;
25057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
25067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        if (arrayRegisterType.category != RegisterType.Category.Null) {
25077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            assert arrayRegisterType.type != null;
25087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            if (arrayRegisterType.type.getClassType().charAt(0) != '[') {
2509461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-object with non-array type %s",
2510461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com                        arrayRegisterType.type.getClassType()));
2511461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            }
2512461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com
2513461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef;
2514461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type;
2515461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com
2516461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            ClassPath.ClassDef elementClassDef = arrayClassDef.getImmediateElementClass();
2517461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            char elementTypePrefix = elementClassDef.getClassType().charAt(0);
2518461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            if (elementTypePrefix != 'L' && elementTypePrefix != '[') {
2519461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-object with array type %s. Incorrect " +
2520461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com                        "array type for the instruction.", arrayRegisterType.type.getClassType()));
2521461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            }
2522461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com
2523461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
2524461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com                    RegisterType.getRegisterType(RegisterType.Category.Reference, elementClassDef));
2525461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com        } else {
2526461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com            setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
2527461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com                    RegisterType.getRegisterType(RegisterType.Category.Null, null));
2528461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com        }
2529461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com    }
2530461a797324f0377db6cf06f680dec894b6f91204JesusFreke@JesusFreke.com
25317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyAgetObject(AnalyzedInstruction analyzedInstruction) {
25327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;
25337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
25347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories);
25357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
25367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
25377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        assert arrayRegisterType != null;
25387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
25397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        if (arrayRegisterType.category != RegisterType.Category.Null) {
25407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            if (arrayRegisterType.category != RegisterType.Category.Reference) {
25417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-object with non-array type %s",
25427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        arrayRegisterType.category.toString()));
25437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            }
25447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
25457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            assert arrayRegisterType.type != null;
25467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            if (arrayRegisterType.type.getClassType().charAt(0) != '[') {
25477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-object with non-array type %s",
25487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        arrayRegisterType.type.getClassType()));
25497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            }
25507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
25517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef;
25527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type;
25537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
25547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            ClassPath.ClassDef elementClassDef = arrayClassDef.getImmediateElementClass();
25557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            char elementTypePrefix = elementClassDef.getClassType().charAt(0);
25567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            if (elementTypePrefix != 'L' && elementTypePrefix != '[') {
25577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-object with array type %s. Incorrect " +
25587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        "array type for the instruction.", arrayRegisterType.type.getClassType()));
25597025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            }
25607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
25617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
25627025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
25637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verify32BitPrimitiveAput(AnalyzedInstruction analyzedInstruction,
2564c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com                                             RegisterType.Category instructionCategory) {
2565c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com        ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;
2566c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com
256785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories);
2568c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com
2569c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com        RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA());
2570c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com        assert sourceRegisterType != null;
2571c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com        RegisterType instructionRegisterType = RegisterType.getRegisterType(instructionCategory, null);
2572c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com        if (!sourceRegisterType.canBeAssignedTo(instructionRegisterType)) {
2573c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use %s with source register type %s.",
2574c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com                    analyzedInstruction.instruction.opcode.name, sourceRegisterType.toString()));
2575c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com        }
2576c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com
2577c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com
2578c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com        RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
2579c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com        assert arrayRegisterType != null;
2580c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com
2581c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com        if (arrayRegisterType.category != RegisterType.Category.Null) {
2582c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            if (arrayRegisterType.category != RegisterType.Category.Reference) {
2583c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with non-array type %s",
2584c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com                        analyzedInstruction.instruction.opcode.name, arrayRegisterType.category.toString()));
2585c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            }
2586c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com
2587c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            assert arrayRegisterType.type != null;
2588c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            if (arrayRegisterType.type.getClassType().charAt(0) != '[') {
2589c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with non-array type %s",
2590c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com                        analyzedInstruction.instruction.opcode.name, arrayRegisterType.type.getClassType()));
2591c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            }
2592c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com
2593c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef;
2594c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type;
2595c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com
2596c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            if (arrayClassDef.getArrayDimensions() != 1) {
2597c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with multi-dimensional array type %s",
2598c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com                        analyzedInstruction.instruction.opcode.name, arrayRegisterType.type.getClassType()));
2599c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            }
2600c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com
2601c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            RegisterType arrayBaseType =
2602c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com                    RegisterType.getRegisterTypeForType(arrayClassDef.getBaseElementClass().getClassType());
2603c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            if (!checkArrayFieldAssignment(arrayBaseType.category, instructionCategory)) {
2604c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with array type %s. Incorrect array type " +
2605c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com                        "for the instruction.", analyzedInstruction.instruction.opcode.name,
2606c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com                        arrayRegisterType.type.getClassType()));
260755d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            }
260855d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com        }
260955d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com    }
261055d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com
26117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyAputWide(AnalyzedInstruction analyzedInstruction) {
261255d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com        ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;
261355d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com
261485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories);
261585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), WideLowCategories);
261655d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com
261755d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com        RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
261855d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com        assert arrayRegisterType != null;
261955d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com
262055d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com        if (arrayRegisterType.category != RegisterType.Category.Null) {
262155d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            if (arrayRegisterType.category != RegisterType.Category.Reference) {
262255d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aput-wide with non-array type %s",
262355d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com                        arrayRegisterType.category.toString()));
262455d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            }
262555d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com
262655d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            assert arrayRegisterType.type != null;
262755d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            if (arrayRegisterType.type.getClassType().charAt(0) != '[') {
262855d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aput-wide with non-array type %s",
262955d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com                        arrayRegisterType.type.getClassType()));
263055d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            }
263155d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com
263255d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef;
263355d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type;
263455d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com
263555d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            if (arrayClassDef.getArrayDimensions() != 1) {
263655d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aput-wide with multi-dimensional array type %s",
263755d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com                        arrayRegisterType.type.getClassType()));
263855d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            }
263955d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com
264055d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            char arrayBaseType = arrayClassDef.getBaseElementClass().getClassType().charAt(0);
264155d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com            if (arrayBaseType != 'J' && arrayBaseType != 'D') {
264255d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aput-wide with array type %s. Incorrect " +
264355d43e36eb862bf86ceaf9c664789ce2c4d92af8JesusFreke@JesusFreke.com                        "array type for the instruction.", arrayRegisterType.type.getClassType()));
2644898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            }
2645898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com        }
2646898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com    }
2647898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com
26487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyAputObject(AnalyzedInstruction analyzedInstruction) {
2649898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com        ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;
2650898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com
265185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), Primitive32BitCategories);
2652898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com
2653898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com        RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA());
2654898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com        assert sourceRegisterType != null;
2655ee7ca05c819845d013d0b15f9c75a92fea6a3b3dJesusFreke@JesusFreke.com
26566d11e9062dfaa27c7fa8719d9d9b4f58b0d5cfa0JesusFreke@JesusFreke.com        //TODO: ensure sourceRegisterType is a Reference type?
2657898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com
2658898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com        RegisterType arrayRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
2659898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com        assert arrayRegisterType != null;
2660898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com
2661898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com        if (arrayRegisterType.category != RegisterType.Category.Null) {
2662898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            //don't check the source type against the array type, just make sure it is an array of reference types
2663898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com
2664898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            if (arrayRegisterType.category != RegisterType.Category.Reference) {
2665898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-object with non-array type %s",
2666898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com                        arrayRegisterType.category.toString()));
2667898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            }
2668898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com
2669898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            assert arrayRegisterType.type != null;
2670898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            if (arrayRegisterType.type.getClassType().charAt(0) != '[') {
2671898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-object with non-array type %s",
2672898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com                        arrayRegisterType.type.getClassType()));
2673898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            }
2674898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com
2675898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            assert arrayRegisterType.type instanceof ClassPath.ArrayClassDef;
2676898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            ClassPath.ArrayClassDef arrayClassDef = (ClassPath.ArrayClassDef)arrayRegisterType.type;
2677898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com
2678898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            ClassPath.ClassDef elementClassDef = arrayClassDef.getImmediateElementClass();
2679898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            char elementTypePrefix = elementClassDef.getClassType().charAt(0);
2680898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com            if (elementTypePrefix != 'L' && elementTypePrefix != '[') {
2681898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use aget-object with array type %s. Incorrect " +
2682898e750048326802a488623d1ebf475df9bca209JesusFreke@JesusFreke.com                        "array type for the instruction.", arrayRegisterType.type.getClassType()));
2683c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com            }
2684c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com        }
2685c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com    }
2686c849236be2031b02d66eac4149617fd8a83572b4JesusFreke@JesusFreke.com
26877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyze32BitPrimitiveIget(AnalyzedInstruction analyzedInstruction,
26887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                                             RegisterType.Category instructionCategory) {
26897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
26907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                RegisterType.getRegisterType(instructionCategory, null));
26917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
26927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
26937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verify32BitPrimitiveIget(AnalyzedInstruction analyzedInstruction,
26944f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com                                             RegisterType.Category instructionCategory) {
26954f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
26964f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com
269785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(),
2698c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                ReferenceOrUninitThisCategories);
26994f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com
27004f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com        //TODO: check access
27014f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
27024f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
27034f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
27044f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com
27054f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com        if (objectRegisterType.category != RegisterType.Category.Null &&
27064f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com            !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) {
27074f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot access field %s through type %s",
27084f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com                    field.getFieldString(), objectRegisterType.type.getClassType()));
27094f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com        }
27104f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com
27114f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
27124f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com
27134f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com        if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) {
27144f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " +
27154f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com                        "for the instruction.", analyzedInstruction.instruction.opcode.name,
27164f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com                        field.getFieldString()));
27174f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com        }
27187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
27194f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com
27207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeIgetWideObject(AnalyzedInstruction analyzedInstruction) {
27217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
27227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
27237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
27247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
27257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
27267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
27277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
27287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, fieldType);
27294f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com    }
27304f84e8f9e9bf4c74cbb2fc083d16ecb4fe0ec501JesusFreke@JesusFreke.com
27317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyIgetWide(AnalyzedInstruction analyzedInstruction) {
27329d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
27339d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com
273485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(),
2735c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                ReferenceOrUninitThisCategories);
27369d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com
27379d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com        //TODO: check access
27389d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
27399d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
27409d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
27419d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com
27429d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com        if (objectRegisterType.category != RegisterType.Category.Null &&
27439d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com            !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) {
27449d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot access field %s through type %s",
27459d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com                    field.getFieldString(), objectRegisterType.type.getClassType()));
27469d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com        }
27479d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com
27489d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
27499d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com
275085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        if (!WideLowCategories.contains(fieldType.category)) {
27519d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " +
275285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                    "for the instruction.", analyzedInstruction.instruction.opcode.name,
275385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                    field.getFieldString()));
27549d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com        }
27557a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com    }
27567a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com
27577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyIgetObject(AnalyzedInstruction analyzedInstruction) {
27587a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
27597a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com
276085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(),
2761c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                ReferenceOrUninitThisCategories);
27627a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com
27637a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com        //TODO: check access
27647a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
27657a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
27667a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
27677a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com
27687a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com        if (objectRegisterType.category != RegisterType.Category.Null &&
27697a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com            !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) {
27707a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot access field %s through type %s",
27717a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com                    field.getFieldString(), objectRegisterType.type.getClassType()));
27727a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com        }
27737a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com
27747a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
27757a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com
27767a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com        if (fieldType.category != RegisterType.Category.Reference) {
27777a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " +
27787a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com                        "for the instruction.", analyzedInstruction.instruction.opcode.name,
27797a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com                        field.getFieldString()));
27807a58f2434a2d906735ce585064d0fa46003c460dJesusFreke@JesusFreke.com        }
27819d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com    }
27829d92fd3748eab8f23502dc11aff06e6e7d29d1f3JesusFreke@JesusFreke.com
27837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verify32BitPrimitiveIput(AnalyzedInstruction analyzedInstruction,
27849971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com                                             RegisterType.Category instructionCategory) {
27859971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
27869971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com
278785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(),
2788c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                ReferenceOrUninitThisCategories);
27899971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com
27909971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA());
27919971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        assert sourceRegisterType != null;
27929971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com
27939971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        //per CodeVerify.c in dalvik:
27949971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        //java generates synthetic functions that write byte values into boolean fields
27959971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        if (sourceRegisterType.category == RegisterType.Category.Byte &&
27969971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com            instructionCategory == RegisterType.Category.Boolean) {
27979971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com
27989971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com            sourceRegisterType = RegisterType.getRegisterType(RegisterType.Category.Boolean, null);
27999971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        }
28009971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com
28019971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        RegisterType instructionRegisterType = RegisterType.getRegisterType(instructionCategory, null);
28029971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        if (!sourceRegisterType.canBeAssignedTo(instructionRegisterType)) {
28039971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use %s with source register type %s.",
28049971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com                    analyzedInstruction.instruction.opcode.name, sourceRegisterType.toString()));
28059971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        }
28069971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com
28079971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com
28089971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        //TODO: check access
28099971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
28109971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
28119971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
28129971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com
28139971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        if (objectRegisterType.category != RegisterType.Category.Null &&
28149971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com            !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) {
28159971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot access field %s through type %s",
28169971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com                    field.getFieldString(), objectRegisterType.type.getClassType()));
28179971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        }
28189971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com
28199971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
28209971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com
28219971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) {
28229971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " +
28239971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com                        "for the instruction.", analyzedInstruction.instruction.opcode.name,
28249971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com                        field.getFieldString()));
28259971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com        }
28269971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com    }
28279971346f4ce431e103c900cfdc14299ea25c685dJesusFreke@JesusFreke.com
28287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyIputWide(AnalyzedInstruction analyzedInstruction) {
282992616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
283092616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com
283185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(),
2832c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                ReferenceOrUninitThisCategories);
283392616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com
283485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), WideLowCategories);
283592616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com
283692616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com        //TODO: check access
283792616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
283892616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
283992616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
284092616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com
284192616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com        if (objectRegisterType.category != RegisterType.Category.Null &&
284292616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com                !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) {
284392616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot access field %s through type %s",
284492616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com                    field.getFieldString(), objectRegisterType.type.getClassType()));
284592616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com        }
284692616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com
284792616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
284892616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com
284992616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com        if (!WideLowCategories.contains(fieldType.category)) {
285092616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " +
285192616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com                    "for the instruction.", analyzedInstruction.instruction.opcode.name,
285292616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com                    field.getFieldString()));
285392616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com        }
285492616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com    }
285592616c9f60a30b5d5ac423675db732cb2428ce79JesusFreke@JesusFreke.com
28567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyIputObject(AnalyzedInstruction analyzedInstruction) {
285750ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
285850ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com
285985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(),
2860c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                ReferenceOrUninitThisCategories);
286150ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com
2862c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com        RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(),
286385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                ReferenceCategories);
286450ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com
286550ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com        //TODO: check access
286650ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
286750ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
286850ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
286950ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com
287050ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com        if (objectRegisterType.category != RegisterType.Category.Null &&
287150ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com            !objectRegisterType.type.extendsClass(ClassPath.getClassDef(field.getContainingClass()))) {
287250ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot access field %s through type %s",
287350ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com                    field.getFieldString(), objectRegisterType.type.getClassType()));
287450ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com        }
287550ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com
287650ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
287750ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com
287850ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com        if (fieldType.category != RegisterType.Category.Reference) {
287950ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " +
288050ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com                        "for the instruction.", analyzedInstruction.instruction.opcode.name,
288150ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com                        field.getFieldString()));
288250ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com        }
288350ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com
288450ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com        if (sourceRegisterType.category != RegisterType.Category.Null &&
288550ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com            !fieldType.type.isInterface() &&
288650ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com            !sourceRegisterType.type.extendsClass(fieldType.type)) {
288750ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com
288850ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot store a value of type %s into a field of type %s",
288950ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com                    sourceRegisterType.type.getClassType(), fieldType.type.getClassType()));
289050ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com        }
289150ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com    }
289250ff6247416eff1a90edd1ebc222ac2cdc5c15cfJesusFreke@JesusFreke.com
28937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyze32BitPrimitiveSget(AnalyzedInstruction analyzedInstruction,
28947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                                             RegisterType.Category instructionCategory) {
28957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
28967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                RegisterType.getRegisterType(instructionCategory, null));
28977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
28987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
28997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verify32BitPrimitiveSget(AnalyzedInstruction analyzedInstruction,
2900052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com                                             RegisterType.Category instructionCategory) {
2901052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com        //TODO: check access
2902052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
2903052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
2904052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
2905052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com
2906052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
2907052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com
2908052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com        if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) {
2909052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " +
2910052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com                        "for the instruction.", analyzedInstruction.instruction.opcode.name,
2911052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com                        field.getFieldString()));
2912052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com        }
29137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
2914052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com
29157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeSgetWideObject(AnalyzedInstruction analyzedInstruction) {
29167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
29177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
29187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
29197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
29207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
29217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction, fieldType);
2922052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com    }
2923052f4890ab954dc8510230b2992904a1a66c5dccJesusFreke@JesusFreke.com
29247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifySgetWide(AnalyzedInstruction analyzedInstruction) {
29252f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com        //TODO: check access
29262f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
29272f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
29282f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
29292f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com
29302f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
29312f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com
29322f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com
29332f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com        if (fieldType.category != RegisterType.Category.LongLo &&
29342f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com            fieldType.category != RegisterType.Category.DoubleLo) {
29352f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com
29362f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " +
29372f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com                    "for the instruction.", analyzedInstruction.instruction.opcode.name,
29382f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com                    field.getFieldString()));
29392f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com        }
29402d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com    }
29412d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com
29427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifySgetObject(AnalyzedInstruction analyzedInstruction) {
29432d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com        //TODO: check access
29442d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
29452d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
29462d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
29472d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com
29482d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
29492d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com
29502d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com        if (fieldType.category != RegisterType.Category.Reference) {
29512d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " +
29522d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com                        "for the instruction.", analyzedInstruction.instruction.opcode.name,
29532d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com                        field.getFieldString()));
29542d6d6eb22c86c79344b85ffe46fdd4268566bd0fJesusFreke@JesusFreke.com        }
29552f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com    }
29562f233fefd9d73af8fab4037a6f874b161b98b259JesusFreke@JesusFreke.com
29577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verify32BitPrimitiveSput(AnalyzedInstruction analyzedInstruction,
29589d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com                                             RegisterType.Category instructionCategory) {
29599d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
29609d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com
29619d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        RegisterType sourceRegisterType = analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA());
29629d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        assert sourceRegisterType != null;
29639d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com
29649d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        //per CodeVerify.c in dalvik:
29659d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        //java generates synthetic functions that write byte values into boolean fields
29669d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        if (sourceRegisterType.category == RegisterType.Category.Byte &&
29679d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com            instructionCategory == RegisterType.Category.Boolean) {
29689d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com
29699d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com            sourceRegisterType = RegisterType.getRegisterType(RegisterType.Category.Boolean, null);
29709d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        }
29719d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com
29729d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        RegisterType instructionRegisterType = RegisterType.getRegisterType(instructionCategory, null);
29739d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        if (!sourceRegisterType.canBeAssignedTo(instructionRegisterType)) {
29749d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use %s with source register type %s.",
29759d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com                    analyzedInstruction.instruction.opcode.name, sourceRegisterType.toString()));
29769d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        }
29779d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com
29789d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        //TODO: check access
29799d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
29809d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
29819d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
29829d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com
29839d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
29849d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com
29859d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        if (!checkArrayFieldAssignment(fieldType.category, instructionCategory)) {
29869d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " +
29879d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com                        "for the instruction.", analyzedInstruction.instruction.opcode.name,
29889d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com                        field.getFieldString()));
29899d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com        }
29909d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com    }
29919d45d563fedaddab6bbdd421b139fe91d2f15fc8JesusFreke@JesusFreke.com
29927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifySputWide(AnalyzedInstruction analyzedInstruction) {
2993f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com        SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
2994f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com
2995f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com
299685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), WideLowCategories);
2997f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com
2998f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com        //TODO: check access
2999f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
3000f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
3001f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
3002f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com
3003f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
3004f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com
3005f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com        if (!WideLowCategories.contains(fieldType.category)) {
3006f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " +
3007f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com                        "for the instruction.", analyzedInstruction.instruction.opcode.name,
3008f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com                        field.getFieldString()));
3009f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com        }
3010f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com    }
3011f08a9e1c2c130a5ed5923999fec0283f91b48a09JesusFreke@JesusFreke.com
30127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifySputObject(AnalyzedInstruction analyzedInstruction) {
301351cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com        SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
301451cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com
301585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(),
301685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                ReferenceCategories);
301751cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com
301851cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com        //TODO: check access
301951cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com        Item referencedItem = ((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem();
302051cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com        assert referencedItem instanceof FieldIdItem;
302151cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com        FieldIdItem field = (FieldIdItem)referencedItem;
302251cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com
302351cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com        RegisterType fieldType = RegisterType.getRegisterTypeForTypeIdItem(field.getFieldType());
302451cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com
302551cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com        if (fieldType.category != RegisterType.Category.Reference) {
302651cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot use %s with field %s. Incorrect field type " +
302751cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com                        "for the instruction.", analyzedInstruction.instruction.opcode.name,
302851cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com                        field.getFieldString()));
302951cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com        }
303051cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com
303151cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com        if (sourceRegisterType.category != RegisterType.Category.Null &&
303251cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com            !fieldType.type.isInterface() &&
303351cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com            !sourceRegisterType.type.extendsClass(fieldType.type)) {
303451cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com
303551cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot store a value of type %s into a field of type %s",
303651cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com                    sourceRegisterType.type.getClassType(), fieldType.type.getClassType()));
303751cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com        }
303851cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com    }
303951cec00885cdc063ee27ee6b67680189be34f8f9JesusFreke@JesusFreke.com
30407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeInvokeDirect(AnalyzedInstruction analyzedInstruction) {
30417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        FiveRegisterInstruction instruction = (FiveRegisterInstruction)analyzedInstruction.instruction;
30427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        analyzeInvokeDirectCommon(analyzedInstruction, new Format35cRegisterIterator(instruction));
30437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
30447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
30457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyInvoke(AnalyzedInstruction analyzedInstruction, int invokeType) {
304689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        FiveRegisterInstruction instruction = (FiveRegisterInstruction)analyzedInstruction.instruction;
30477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        verifyInvokeCommon(analyzedInstruction, false, invokeType, new Format35cRegisterIterator(instruction));
30487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
30497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
30507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeInvokeDirectRange(AnalyzedInstruction analyzedInstruction) {
30517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterRangeInstruction instruction = (RegisterRangeInstruction)analyzedInstruction.instruction;
30527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        analyzeInvokeDirectCommon(analyzedInstruction, new Format3rcRegisterIterator(instruction));
305389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com    }
305489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
30557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyInvokeRange(AnalyzedInstruction analyzedInstruction, int invokeType) {
305689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        RegisterRangeInstruction instruction = (RegisterRangeInstruction)analyzedInstruction.instruction;
30577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        verifyInvokeCommon(analyzedInstruction, true, invokeType, new Format3rcRegisterIterator(instruction));
305889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com    }
305989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
306089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com    private static final int INVOKE_VIRTUAL = 0x01;
306189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com    private static final int INVOKE_SUPER = 0x02;
306289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com    private static final int INVOKE_DIRECT = 0x04;
306389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com    private static final int INVOKE_INTERFACE = 0x08;
306489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com    private static final int INVOKE_STATIC = 0x10;
306589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
30667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeInvokeDirectCommon(AnalyzedInstruction analyzedInstruction, RegisterIterator registers) {
30677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        //the only time that an invoke instruction changes a register type is when using invoke-direct on a
30687025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        //constructor (<init>) method, which changes the uninitialized reference (and any register that the same
30697025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        //uninit reference has been copied to) to an initialized reference
30707025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
30717025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction;
30727025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
30737025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        Item item = instruction.getReferencedItem();
30747025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        assert item.getItemType() == ItemType.TYPE_METHOD_ID_ITEM;
30757025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        MethodIdItem methodIdItem = (MethodIdItem)item;
30767025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
30777025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        if (!methodIdItem.getMethodName().getStringValue().equals("<init>")) {
30787025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            return;
30797025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
30807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
30817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        RegisterType objectRegisterType;
30827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        //the object register is always the first register
30837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        int objectRegister = registers.getRegister();
30847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
30857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        objectRegisterType = analyzedInstruction.getPreInstructionRegisterType(objectRegister);
30867025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        assert objectRegisterType != null;
30877025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
30887025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        if (objectRegisterType.category != RegisterType.Category.UninitRef &&
30897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                objectRegisterType.category != RegisterType.Category.UninitThis) {
30907025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            return;
30917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
30927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
30937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setPostRegisterTypeAndPropagateChanges(analyzedInstruction, objectRegister,
30947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                RegisterType.getRegisterType(RegisterType.Category.Reference, objectRegisterType.type));
30957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
30967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        for (int i=0; i<analyzedInstruction.postRegisterMap.length; i++) {
30977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            RegisterType postInstructionRegisterType = analyzedInstruction.postRegisterMap[i];
30987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            if (postInstructionRegisterType.category == RegisterType.Category.Unknown) {
30997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                RegisterType preInstructionRegisterType =
31007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        analyzedInstruction.getPreInstructionRegisterType(i);
31017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
31027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                if (preInstructionRegisterType.category == RegisterType.Category.UninitRef ||
31037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    preInstructionRegisterType.category == RegisterType.Category.UninitThis) {
31047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
31057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    RegisterType registerType;
31067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    if (preInstructionRegisterType == objectRegisterType) {
31077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        registerType = analyzedInstruction.postRegisterMap[objectRegister];
31087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    } else {
31097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                        registerType = preInstructionRegisterType;
31107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    }
31117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
31127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    setPostRegisterTypeAndPropagateChanges(analyzedInstruction, i, registerType);
31137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                }
31147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            }
31157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
31167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
31177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
31187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyInvokeCommon(AnalyzedInstruction analyzedInstruction, boolean isRange, int invokeType,
311989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                                       RegisterIterator registers) {
312089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        InstructionWithReference instruction = (InstructionWithReference)analyzedInstruction.instruction;
312189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
312289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        //TODO: check access
312389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
312489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        Item item = instruction.getReferencedItem();
312589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        assert item.getItemType() == ItemType.TYPE_METHOD_ID_ITEM;
312689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        MethodIdItem methodIdItem = (MethodIdItem)item;
312789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
312889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        TypeIdItem methodClass = methodIdItem.getContainingClass();
312989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        boolean isInit = false;
313089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
313189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        if (methodIdItem.getMethodName().getStringValue().charAt(0) == '<') {
313289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            if ((invokeType & INVOKE_DIRECT) != 0) {
313389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                isInit = true;
313489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            } else {
313589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot call constructor %s with %s",
313689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                        methodIdItem.getMethodString(), analyzedInstruction.instruction.opcode.name));
313789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            }
313889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        }
313989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
314089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        ClassPath.ClassDef methodClassDef = ClassPath.getClassDef(methodClass);
314189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        if ((invokeType & INVOKE_INTERFACE) != 0) {
314289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            if (!methodClassDef.isInterface()) {
314389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot call method %s with %s. %s is not an interface " +
314489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                        "class.", methodIdItem.getMethodString(), analyzedInstruction.instruction.opcode.name,
314589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                        methodClassDef.getClassType()));
314689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            }
314789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        } else {
314889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            if (methodClassDef.isInterface()) {
314989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot call method %s with %s. %s is an interface class." +
315089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                        " Use invoke-interface or invoke-interface/range instead.", methodIdItem.getMethodString(),
315189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                        analyzedInstruction.instruction.opcode.name, methodClassDef.getClassType()));
315289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            }
315389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        }
315489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
315589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        if ((invokeType & INVOKE_SUPER) != 0) {
3156c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            ClassPath.ClassDef currentMethodClassDef = ClassPath.getClassDef(encodedMethod.method.getContainingClass());
3157c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            if (currentMethodClassDef.getSuperclass() == null) {
315889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot call method %s with %s. %s has no superclass",
315989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                        methodIdItem.getMethodString(), analyzedInstruction.instruction.opcode.name,
316089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                        methodClassDef.getSuperclass().getClassType()));
316189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            }
316289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
3163c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            if (!currentMethodClassDef.getSuperclass().extendsClass(methodClassDef)) {
3164c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot call method %s with %s. %s is not an ancestor " +
3165c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                        "of the current class %s", methodIdItem.getMethodString(),
3166c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                        analyzedInstruction.instruction.opcode.name, methodClass.getTypeDescriptor(),
3167c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                        encodedMethod.method.getContainingClass().getTypeDescriptor()));
3168c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            }
3169c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
3170662e42515071ef596745ffe80c461881541bc447Ben Gruver            if (!currentMethodClassDef.getSuperclass().hasVirtualMethod(methodIdItem.getShortMethodString())) {
317189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot call method %s with %s. The superclass %s has" +
317289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                        "no such method", methodIdItem.getMethodString(),
317389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                        analyzedInstruction.instruction.opcode.name, methodClassDef.getSuperclass().getClassType()));
317489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            }
317589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        }
317689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
317789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        assert isRange || registers.getCount() <= 5;
317889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
317989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        TypeListItem typeListItem = methodIdItem.getPrototype().getParameters();
318089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        int methodParameterRegisterCount;
318189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        if (typeListItem == null) {
318289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            methodParameterRegisterCount = 0;
318389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        } else {
318489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            methodParameterRegisterCount = typeListItem.getRegisterCount();
318589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        }
318689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
318789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        if ((invokeType & INVOKE_STATIC) == 0) {
318889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            methodParameterRegisterCount++;
318989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        }
319089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
319189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        if (methodParameterRegisterCount != registers.getCount()) {
319289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            throw new ValidationException(String.format("The number of registers does not match the number of " +
319389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                    "parameters for method %s. Expecting %d registers, got %d.", methodIdItem.getMethodString(),
319489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                    methodParameterRegisterCount + 1, registers.getCount()));
319589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        }
319689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
319789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        RegisterType objectRegisterType = null;
319889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        int objectRegister = 0;
319989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        if ((invokeType & INVOKE_STATIC) == 0) {
320089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            objectRegister = registers.getRegister();
320189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            registers.moveNext();
320289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
320389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            objectRegisterType = analyzedInstruction.getPreInstructionRegisterType(objectRegister);
320489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            assert objectRegisterType != null;
3205c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            if (objectRegisterType.category == RegisterType.Category.UninitRef ||
3206c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                    objectRegisterType.category == RegisterType.Category.UninitThis) {
3207c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com
320889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                if (!isInit) {
320989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                    throw new ValidationException(String.format("Cannot invoke non-<init> method %s on uninitialized " +
321089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                            "reference type %s", methodIdItem.getMethodString(),
321189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                            objectRegisterType.type.getClassType()));
321289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                }
321389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            } else if (objectRegisterType.category == RegisterType.Category.Reference) {
321489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                if (isInit) {
321589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                    throw new ValidationException(String.format("Cannot invoke %s on initialized reference type %s",
321689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                            methodIdItem.getMethodString(), objectRegisterType.type.getClassType()));
321789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                }
321889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            } else if (objectRegisterType.category == RegisterType.Category.Null) {
321989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                if (isInit) {
322089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                    throw new ValidationException(String.format("Cannot invoke %s on a null reference",
322189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                            methodIdItem.getMethodString()));
322289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                }
322389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            }
322489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            else {
322589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                throw new ValidationException(String.format("Cannot invoke %s on non-reference type %s",
322689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                        methodIdItem.getMethodString(), objectRegisterType.toString()));
322789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            }
322889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
322989e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            if (isInit) {
32307e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                if (objectRegisterType.type.getSuperclass() == methodClassDef) {
32317e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    if (!encodedMethod.method.getMethodName().getStringValue().equals("<init>")) {
323289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                        throw new ValidationException(String.format("Cannot call %s on type %s. The object type must " +
323389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                                "match the method type exactly", methodIdItem.getMethodString(),
323489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                                objectRegisterType.type.getClassType()));
323589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                    }
323689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                }
323789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            }
323889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
3239c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com            if ((invokeType & INVOKE_INTERFACE) == 0 && objectRegisterType.category != RegisterType.Category.Null &&
3240c9be5e13034da9827b5598a6257376164745b827JesusFreke@JesusFreke.com                    !objectRegisterType.type.extendsClass(methodClassDef)) {
324189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
324289e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com               throw new ValidationException(String.format("Cannot call method %s on an object of type %s, which " +
324389e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                       "does not extend %s.", methodIdItem.getMethodString(), objectRegisterType.type.getClassType(),
324489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                        methodClassDef.getClassType()));
324589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com            }
324689e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        }
324789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
32487e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com        if (typeListItem != null) {
32497e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            List<TypeIdItem> parameterTypes = typeListItem.getTypes();
32507e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            int parameterTypeIndex = 0;
32517e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            while (!registers.pastEnd()) {
32527e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                assert parameterTypeIndex < parameterTypes.size();
32537e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                RegisterType parameterType =
32547e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                        RegisterType.getRegisterTypeForTypeIdItem(parameterTypes.get(parameterTypeIndex));
325589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
32567e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                int register = registers.getRegister();
325789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
32587e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                RegisterType parameterRegisterType;
32597e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                if (WideLowCategories.contains(parameterType.category)) {
32607e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    parameterRegisterType = getAndCheckSourceRegister(analyzedInstruction, register, WideLowCategories);
326189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
32627e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    if (!registers.moveNext()) {
32637e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                        throw new ValidationException(String.format("No 2nd register specified for wide register pair v%d",
32647e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                                parameterTypeIndex+1));
32657e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    }
32667e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    int nextRegister = registers.getRegister();
326789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
32687e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    if (nextRegister != register + 1) {
32697e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                        throw new ValidationException(String.format("Invalid wide register pair (v%d, v%d). Registers " +
32707e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                                "must be consecutive.", register, nextRegister));
32717e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    }
32727e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                } else {
32737e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    parameterRegisterType = analyzedInstruction.getPreInstructionRegisterType(register);
327489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com                }
327589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
32767e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                assert parameterRegisterType != null;
327789e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
32787e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                if (!parameterRegisterType.canBeAssignedTo(parameterType)) {
32797e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                    throw new ValidationException(
32807e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                            String.format("Invalid register type %s for parameter %d %s.",
32817e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                                    parameterRegisterType.toString(), parameterTypeIndex+1,
32827e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                                    parameterType.toString()));
32837e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                }
328489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
32857e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                parameterTypeIndex++;
32867e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com                registers.moveNext();
32877e24a9f010eeeff54f7ca0cb589a75cc251fabddJesusFreke@JesusFreke.com            }
328889e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com        }
32897025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
329089e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
32917025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeUnaryOp(AnalyzedInstruction analyzedInstruction, RegisterType.Category destRegisterCategory) {
32927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
32937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                RegisterType.getRegisterType(destRegisterCategory, null));
329489e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com    }
329589e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
32967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyUnaryOp(AnalyzedInstruction analyzedInstruction, EnumSet validSourceCategories) {
32971483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
32981483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com
32991483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validSourceCategories);
33001483cc8e6879d0de625adbcbffd2df42131a90c1JesusFreke@JesusFreke.com    }
330189e1413ef3d2438f7126b2c55f6f57d62361e775JesusFreke@JesusFreke.com
33027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeBinaryOp(AnalyzedInstruction analyzedInstruction, RegisterType.Category destRegisterCategory,
3303195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com                                boolean checkForBoolean) {
33047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        if (checkForBoolean) {
33057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;
3306195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com
33077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            RegisterType source1RegisterType =
33087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
33097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            RegisterType source2RegisterType =
33107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterC());
3311195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com
3312195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            if (BooleanCategories.contains(source1RegisterType.category) &&
3313195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com                BooleanCategories.contains(source2RegisterType.category)) {
3314195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com
3315195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com                destRegisterCategory = RegisterType.Category.Boolean;
3316195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com            }
3317195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com        }
3318195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com
3319195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
3320195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com                RegisterType.getRegisterType(destRegisterCategory, null));
3321195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com    }
3322195e1a1071cce71fe6dd0edd4d6d23090dd0de14JesusFreke@JesusFreke.com
33237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyBinaryOp(AnalyzedInstruction analyzedInstruction, EnumSet validSource1Categories,
33247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                                EnumSet validSource2Categories) {
33257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        ThreeRegisterInstruction instruction = (ThreeRegisterInstruction)analyzedInstruction.instruction;
3326122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com
33277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validSource1Categories);
33287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterC(), validSource2Categories);
33297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
3330122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com
33317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeBinary2AddrOp(AnalyzedInstruction analyzedInstruction,
33327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                                      RegisterType.Category destRegisterCategory, boolean checkForBoolean) {
3333122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com        if (checkForBoolean) {
33347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
33357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
33367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            RegisterType source1RegisterType =
33377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterA());
33387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            RegisterType source2RegisterType =
33397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
33407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
3341122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            if (BooleanCategories.contains(source1RegisterType.category) &&
3342122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com                BooleanCategories.contains(source2RegisterType.category)) {
3343122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com
3344122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com                destRegisterCategory = RegisterType.Category.Boolean;
3345122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com            }
3346122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com        }
3347122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com
3348122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
3349122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com                RegisterType.getRegisterType(destRegisterCategory, null));
3350122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com    }
3351122eba5cecf44f6c819854e204779c83124abdf8JesusFreke@JesusFreke.com
33527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyBinary2AddrOp(AnalyzedInstruction analyzedInstruction, EnumSet validSource1Categories,
33537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                                EnumSet validSource2Categories) {
3354caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
3355caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com
33567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterA(), validSource1Categories);
33577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), validSource2Categories);
33587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
3359caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com
33607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeLiteralBinaryOp(AnalyzedInstruction analyzedInstruction,
33617025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                                        RegisterType.Category destRegisterCategory, boolean checkForBoolean) {
3362caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        if (checkForBoolean) {
33637025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
33647025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
33657025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            RegisterType sourceRegisterType =
33667025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    analyzedInstruction.getPreInstructionRegisterType(instruction.getRegisterB());
33677025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
3368caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            if (BooleanCategories.contains(sourceRegisterType.category)) {
3369caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                long literal = ((LiteralInstruction)analyzedInstruction.instruction).getLiteral();
3370caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                if (literal == 0 || literal == 1) {
3371caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                    destRegisterCategory = RegisterType.Category.Boolean;
3372caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                }
3373caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            }
3374caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        }
3375caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com
3376caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        setDestinationRegisterTypeAndPropagateChanges(analyzedInstruction,
3377caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                RegisterType.getRegisterType(destRegisterCategory, null));
3378caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com    }
3379caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com
33807025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void verifyLiteralBinaryOp(AnalyzedInstruction analyzedInstruction) {
33817025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
33827025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
33837025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(), Primitive32BitCategories);
33847025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
33857025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
3386caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com    private RegisterType.Category getDestTypeForLiteralShiftRight(AnalyzedInstruction analyzedInstruction,
3387caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                                                                  boolean signedShift) {
3388caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
3389caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com
3390caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        RegisterType sourceRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(),
3391caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                Primitive32BitCategories);
3392caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        long literalShift = ((LiteralInstruction)analyzedInstruction.instruction).getLiteral();
3393caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com
3394caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        if (literalShift == 0) {
3395caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            return sourceRegisterType.category;
3396caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        }
3397caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com
3398caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        RegisterType.Category destRegisterCategory;
3399caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        if (!signedShift) {
3400caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            destRegisterCategory = RegisterType.Category.Integer;
3401caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        } else {
3402caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            destRegisterCategory = sourceRegisterType.category;
3403caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        }
3404caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com
3405caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        if (literalShift >= 32) {
3406caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            //TODO: add warning
3407caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            return destRegisterCategory;
3408caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        }
3409caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com
3410caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        switch (sourceRegisterType.category) {
3411caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case Integer:
3412caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case Float:
3413caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                if (!signedShift) {
3414caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                    if (literalShift > 24) {
3415caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                        return RegisterType.Category.PosByte;
3416caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                    }
3417caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                    if (literalShift >= 16) {
3418caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                        return RegisterType.Category.Char;
3419caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                    }
3420caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                } else {
3421caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                    if (literalShift >= 24) {
3422caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                        return RegisterType.Category.Byte;
3423caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                    }
3424caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                    if (literalShift >= 16) {
3425caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                        return RegisterType.Category.Short;
3426caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                    }
3427caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                }
3428caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                break;
3429caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case Short:
3430caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                if (signedShift && literalShift >= 8) {
3431caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                    return RegisterType.Category.Byte;
3432caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                }
3433caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                break;
3434caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case PosShort:
3435caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                if (literalShift >= 8) {
3436caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                    return RegisterType.Category.PosByte;
3437caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                }
3438caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                break;
3439caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case Char:
3440caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                if (literalShift > 8) {
3441caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                    return RegisterType.Category.PosByte;
3442caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                }
3443caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                break;
3444caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case Byte:
3445caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                break;
3446caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case PosByte:
3447caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                return RegisterType.Category.PosByte;
3448caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case Null:
3449caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case One:
3450caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            case Boolean:
3451caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                return RegisterType.Category.Null;
3452caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com            default:
3453caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com                assert false;
3454caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        }
3455caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com
3456caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com        return destRegisterCategory;
3457caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com    }
3458caea37a7d2ad74f884111ee7420e7b37b9417afdJesusFreke@JesusFreke.com
34590c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
34607025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeExecuteInline(AnalyzedInstruction analyzedInstruction) {
34610c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (deodexUtil == null) {
34620c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            throw new ValidationException("Cannot analyze an odexed instruction unless we are deodexing");
34630c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
34640c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3465b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver        Instruction35mi instruction = (Instruction35mi)analyzedInstruction.instruction;
34660c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3467595cdad3d63d79e8d913a704e65f7785ff1bc104JesusFreke@JesusFreke.com        DeodexUtil.InlineMethod inlineMethod = deodexUtil.lookupInlineMethod(analyzedInstruction);
34685967598d012839eb25d50d9fa63952ac802e05ddBen Gruver        MethodIdItem inlineMethodIdItem = inlineMethod.getMethodIdItem(deodexUtil);
34690c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (inlineMethodIdItem == null) {
3470595cdad3d63d79e8d913a704e65f7785ff1bc104JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot load inline method with index %d",
3471b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver                    instruction.getInlineIndex()));
34720c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
34730c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
34740c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        Opcode deodexedOpcode = null;
34750c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        switch (inlineMethod.methodType) {
34760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case DeodexUtil.Direct:
34770c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                deodexedOpcode = Opcode.INVOKE_DIRECT;
34780c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                break;
34790c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case DeodexUtil.Static:
34800c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                deodexedOpcode = Opcode.INVOKE_STATIC;
34810c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                break;
34820c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case DeodexUtil.Virtual:
34830c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                deodexedOpcode = Opcode.INVOKE_VIRTUAL;
34840c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                break;
34850c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            default:
34860c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                assert false;
34870c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
34880c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
34890c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        Instruction35c deodexedInstruction = new Instruction35c(deodexedOpcode, instruction.getRegCount(),
34900c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                instruction.getRegisterD(), instruction.getRegisterE(), instruction.getRegisterF(),
34910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                instruction.getRegisterG(), instruction.getRegisterA(), inlineMethodIdItem);
34920c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
34930c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
34940c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
34950c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        analyzeInstruction(analyzedInstruction);
34960c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com    }
34970c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
34987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeExecuteInlineRange(AnalyzedInstruction analyzedInstruction) {
34990c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (deodexUtil == null) {
35000c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            throw new ValidationException("Cannot analyze an odexed instruction unless we are deodexing");
35010c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
35020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3503b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver        Instruction3rmi instruction = (Instruction3rmi)analyzedInstruction.instruction;
35040c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3505595cdad3d63d79e8d913a704e65f7785ff1bc104JesusFreke@JesusFreke.com        DeodexUtil.InlineMethod inlineMethod = deodexUtil.lookupInlineMethod(analyzedInstruction);
35065967598d012839eb25d50d9fa63952ac802e05ddBen Gruver        MethodIdItem inlineMethodIdItem = inlineMethod.getMethodIdItem(deodexUtil);
35070c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (inlineMethodIdItem == null) {
3508595cdad3d63d79e8d913a704e65f7785ff1bc104JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Cannot load inline method with index %d",
3509b0c62b9781751e4d04d2ddb4458940d545cc8bb2Ben Gruver                    instruction.getInlineIndex()));
35100c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
35110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
35120c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        Opcode deodexedOpcode = null;
35130c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        switch (inlineMethod.methodType) {
35140c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case DeodexUtil.Direct:
351576f566a55b88f0923bdf6fdb8d17ba24dfd79025JesusFreke@JesusFreke.com                deodexedOpcode = Opcode.INVOKE_DIRECT_RANGE;
35160c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                break;
35170c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case DeodexUtil.Static:
351876f566a55b88f0923bdf6fdb8d17ba24dfd79025JesusFreke@JesusFreke.com                deodexedOpcode = Opcode.INVOKE_STATIC_RANGE;
35190c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                break;
35200c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            case DeodexUtil.Virtual:
352176f566a55b88f0923bdf6fdb8d17ba24dfd79025JesusFreke@JesusFreke.com                deodexedOpcode = Opcode.INVOKE_VIRTUAL_RANGE;
35220c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                break;
35230c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            default:
35240c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                assert false;
35250c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
35260c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3527c4db7e2473a77b6dfa58207825efcdb4d51697b7Ben Gruver        Instruction3rc deodexedInstruction = new Instruction3rc(deodexedOpcode, (short)instruction.getRegCount(),
35280c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                instruction.getStartRegister(), inlineMethodIdItem);
35290c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
35300c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
35310c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
35320c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        analyzeInstruction(analyzedInstruction);
35330c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com    }
35340c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
35357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private void analyzeInvokeDirectEmpty(AnalyzedInstruction analyzedInstruction) {
3536ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        analyzeInvokeDirectEmpty(analyzedInstruction, true);
3537ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver    }
3538ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver
3539ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver    private void analyzeInvokeDirectEmpty(AnalyzedInstruction analyzedInstruction, boolean analyzeResult) {
3540c8de336727bfe8e56998332fe97ad5c0e32e50faBen Gruver        Instruction35c instruction = (Instruction35c)analyzedInstruction.instruction;
35410c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
35420c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        Instruction35c deodexedInstruction = new Instruction35c(Opcode.INVOKE_DIRECT, instruction.getRegCount(),
35430c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                instruction.getRegisterD(), instruction.getRegisterE(), instruction.getRegisterF(),
35440c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                instruction.getRegisterG(), instruction.getRegisterA(), instruction.getReferencedItem());
35450c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
35460c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
35470c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3548ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        if (analyzeResult) {
3549ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver            analyzeInstruction(analyzedInstruction);
3550ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        }
35510c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com    }
35520c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3553ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver    private void analyzeInvokeObjectInitRange(AnalyzedInstruction analyzedInstruction) {
3554ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        analyzeInvokeObjectInitRange(analyzedInstruction, true);
3555ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver    }
3556ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver
3557ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver    private void analyzeInvokeObjectInitRange(AnalyzedInstruction analyzedInstruction, boolean analyzeResult) {
3558ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver        Instruction3rc instruction = (Instruction3rc)analyzedInstruction.instruction;
3559ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver
3560ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver        Instruction3rc deodexedInstruction = new Instruction3rc(Opcode.INVOKE_DIRECT_RANGE,
3561ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver                (short)instruction.getRegCount(), instruction.getStartRegister(), instruction.getReferencedItem());
3562ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver
3563ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
3564ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver
3565ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        if (analyzeResult) {
3566ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver            analyzeInstruction(analyzedInstruction);
3567ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        }
3568ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver    }
3569ea7afb02658cc72b5e7156f5dadc51b9c6c212b0Ben Gruver
3570d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com    private boolean analyzeIputIgetQuick(AnalyzedInstruction analyzedInstruction) {
35710c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        Instruction22cs instruction = (Instruction22cs)analyzedInstruction.instruction;
35720c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
35730c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        int fieldOffset = instruction.getFieldOffset();
35740c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, instruction.getRegisterB(),
35750c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                ReferenceOrUninitCategories);
35760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
35770c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (objectRegisterType.category == RegisterType.Category.Null) {
35780c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            return false;
35790c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
35800c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3581ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver        ClassPath.ClassDef accessingClass =
3582ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver                ClassPath.getClassDef(this.encodedMethod.method.getContainingClass(), false);
3583ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver        if (accessingClass == null) {
3584ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver            throw new ExceptionWithContext(String.format("Could not find ClassDef for current class: %s",
3585ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver                    this.encodedMethod.method.getContainingClass()));
3586ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver        }
3587ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver
3588ebd1b0e9c14f46cb55534cbd48084666afbdef21Ben Gruver        FieldIdItem fieldIdItem = deodexUtil.lookupField(accessingClass, objectRegisterType.type, fieldOffset);
35890c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (fieldIdItem == null) {
35900c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Could not resolve the field in class %s at offset %d",
35910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    objectRegisterType.type.getClassType(), fieldOffset));
35920c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
35930c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
35940c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        String fieldType = fieldIdItem.getFieldType().getTypeDescriptor();
35950c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3596d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com        Opcode opcode = OdexedFieldInstructionMapper.getAndCheckDeodexedOpcodeForOdexedOpcode(fieldType, instruction.opcode);
35970c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
35980c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        Instruction22c deodexedInstruction = new Instruction22c(opcode, (byte)instruction.getRegisterA(),
35990c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                (byte)instruction.getRegisterB(), fieldIdItem);
36000c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
36010c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36020c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        analyzeInstruction(analyzedInstruction);
36030c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36040c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        return true;
36050c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com    }
36060c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private boolean analyzeInvokeVirtualQuick(AnalyzedInstruction analyzedInstruction, boolean isSuper,
36087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                                              boolean isRange) {
36090c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        int methodIndex;
36100c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        int objectRegister;
36110c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36120c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36130c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (isRange) {
36140c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            Instruction3rms instruction = (Instruction3rms)analyzedInstruction.instruction;
36153bfd77dff08cfa059ea230017791fca11fa08c53Ben Gruver            methodIndex = instruction.getVtableIndex();
36160c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            objectRegister = instruction.getStartRegister();
36170c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        } else {
36180c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            Instruction35ms instruction = (Instruction35ms)analyzedInstruction.instruction;
36193bfd77dff08cfa059ea230017791fca11fa08c53Ben Gruver            methodIndex = instruction.getVtableIndex();
36200c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            objectRegister = instruction.getRegisterD();
36210c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
36220c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36230c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        RegisterType objectRegisterType = getAndCheckSourceRegister(analyzedInstruction, objectRegister,
36240c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                ReferenceOrUninitCategories);
36250c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36260c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (objectRegisterType.category == RegisterType.Category.Null) {
36270c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            return false;
36280c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
36290c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36300c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        MethodIdItem methodIdItem = null;
3631650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver        ClassPath.ClassDef accessingClass =
3632650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver                ClassPath.getClassDef(this.encodedMethod.method.getContainingClass(), false);
3633650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver        if (accessingClass == null) {
3634650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver            throw new ExceptionWithContext(String.format("Could not find ClassDef for current class: %s",
3635650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver                    this.encodedMethod.method.getContainingClass()));
3636650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver        }
36370c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (isSuper) {
3638650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver            if (accessingClass.getSuperclass() != null) {
3639650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver                methodIdItem = deodexUtil.lookupVirtualMethod(accessingClass, accessingClass.getSuperclass(),
3640650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver                        methodIndex);
36410c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            }
36420c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36430c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            if (methodIdItem == null) {
36440c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                //it's possible that the pre-odexed instruction had used the method from the current class instead
36450c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                //of from the superclass (although the superclass method is still what would actually be called).
36460c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                //And so the MethodIdItem for the superclass method may not be in the dex file. Let's try to get the
36470c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                //MethodIdItem for the method in the current class instead
3648650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver                methodIdItem = deodexUtil.lookupVirtualMethod(accessingClass, accessingClass, methodIndex);
36490c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            }
36500c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        } else{
3651650d426c120993fdee95d982e50faa6a5d70d9afBen Gruver            methodIdItem = deodexUtil.lookupVirtualMethod(accessingClass, objectRegisterType.type, methodIndex);
36520c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
36530c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36540c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (methodIdItem == null) {
36550c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            throw new ValidationException(String.format("Could not resolve the method in class %s at index %d",
36560c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    objectRegisterType.type.getClassType(), methodIndex));
36570c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
36580c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36590c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36600c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        Instruction deodexedInstruction;
36610c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        if (isRange) {
36620c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            Instruction3rms instruction = (Instruction3rms)analyzedInstruction.instruction;
36630c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            Opcode opcode;
36640c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            if (isSuper) {
36650c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                opcode = Opcode.INVOKE_SUPER_RANGE;
36660c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            } else {
36670c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                opcode = Opcode.INVOKE_VIRTUAL_RANGE;
36680c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            }
36690c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3670c4db7e2473a77b6dfa58207825efcdb4d51697b7Ben Gruver            deodexedInstruction = new Instruction3rc(opcode, (short)instruction.getRegCount(),
36710c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    instruction.getStartRegister(), methodIdItem);
36720c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        } else {
36730c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            Instruction35ms instruction = (Instruction35ms)analyzedInstruction.instruction;
36740c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            Opcode opcode;
36750c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            if (isSuper) {
36760c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                opcode = Opcode.INVOKE_SUPER;
36770c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            } else {
36780c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                opcode = Opcode.INVOKE_VIRTUAL;
36790c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            }
36800c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36810c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com            deodexedInstruction = new Instruction35c(opcode, instruction.getRegCount(),
36820c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    instruction.getRegisterD(), instruction.getRegisterE(), instruction.getRegisterF(),
36830c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com                    instruction.getRegisterG(), instruction.getRegisterA(), methodIdItem);
36840c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
36850c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36860c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
36870c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        analyzeInstruction(analyzedInstruction);
36880c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
36890c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        return true;
36900c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com    }
36910c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3692d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com    private boolean analyzePutGetVolatile(AnalyzedInstruction analyzedInstruction) {
3693ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        return analyzePutGetVolatile(analyzedInstruction, true);
3694ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver    }
3695ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver
3696ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver    private boolean analyzePutGetVolatile(AnalyzedInstruction analyzedInstruction, boolean analyzeResult) {
3697d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com        FieldIdItem fieldIdItem =
3698d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com                (FieldIdItem)(((InstructionWithReference)analyzedInstruction.instruction).getReferencedItem());
3699d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com
3700d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com        String fieldType = fieldIdItem.getFieldType().getTypeDescriptor();
3701d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com
3702d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com        Opcode opcode = OdexedFieldInstructionMapper.getAndCheckDeodexedOpcodeForOdexedOpcode(fieldType,
3703d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com                analyzedInstruction.instruction.opcode);
37040c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3705d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com        Instruction deodexedInstruction;
3706d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com
3707d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com        if (analyzedInstruction.instruction.opcode.isOdexedStaticVolatile()) {
3708d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            SingleRegisterInstruction instruction = (SingleRegisterInstruction)analyzedInstruction.instruction;
37099a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            if (analyzedInstruction.instruction.opcode.format == Format.Format21c) {
37109a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                deodexedInstruction = new Instruction21c(opcode, (byte)instruction.getRegisterA(), fieldIdItem);
37119a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            } else {
37129a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                assert(analyzedInstruction.instruction.opcode.format == Format.Format41c);
37139a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                deodexedInstruction = new Instruction41c(opcode, (byte)instruction.getRegisterA(), fieldIdItem);
37149a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            }
3715d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com        } else {
3716d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com            TwoRegisterInstruction instruction = (TwoRegisterInstruction)analyzedInstruction.instruction;
3717d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com
37189a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            if (analyzedInstruction.instruction.opcode.format == Format.Format22c) {
37199a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                deodexedInstruction = new Instruction22c(opcode, (byte)instruction.getRegisterA(),
37209a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                    (byte)instruction.getRegisterB(), fieldIdItem);
37219a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            } else {
37229a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                assert(analyzedInstruction.instruction.opcode.format == Format.Format52c);
37239a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                deodexedInstruction = new Instruction52c(opcode, (byte)instruction.getRegisterA(),
37249a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                    (byte)instruction.getRegisterB(), fieldIdItem);
37259a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver            }
37260c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com        }
37270c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
3728d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
3729d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com
3730ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        if (analyzeResult) {
3731ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver            analyzeInstruction(analyzedInstruction);
3732ed33c426e75376a584c76d919bd48e026cb7a559Ben Gruver        }
3733d4417d7269dad2c6e2f92c67c82a2ada18bb38e3JesusFreke@JesusFreke.com        return true;
37340c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com    }
37350c65e0f4f54ead8fd2832c954d516367b3556ae3JesusFreke@JesusFreke.com
37369a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver    private void analyzeInvokeObjectInitJumbo(AnalyzedInstruction analyzedInstruction) {
37379a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver        Instruction5rc instruction = (Instruction5rc)analyzedInstruction.instruction;
37389a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver
37399a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver        Instruction5rc deodexedInstruction = new Instruction5rc(Opcode.INVOKE_DIRECT_JUMBO,
37409a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver                instruction.getRegCount(), instruction.getStartRegister(), instruction.getReferencedItem());
37419a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver
37429a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver        analyzedInstruction.setDeodexedInstruction(deodexedInstruction);
37439a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver
37449a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver        analyzeInstruction(analyzedInstruction);
37459a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver    }
37469a9a664af23fb4582ef65ec6df4462b94690f0eeBen Gruver
3747b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com    private static boolean checkArrayFieldAssignment(RegisterType.Category arrayFieldCategory,
3748b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com                                                  RegisterType.Category instructionCategory) {
3749b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com        if (arrayFieldCategory == instructionCategory) {
3750b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            return true;
3751b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com        }
3752b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com
3753b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com        if ((arrayFieldCategory == RegisterType.Category.Integer &&
3754b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com             instructionCategory == RegisterType.Category.Float) ||
3755b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            (arrayFieldCategory == RegisterType.Category.Float &&
3756b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com             instructionCategory == RegisterType.Category.Integer)) {
3757b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com            return true;
3758b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com        }
3759b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com        return false;
3760b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com    }
3761b2397452907c28b0743bbbcdf9fa6b2a8208aeabJesusFreke@JesusFreke.com
376285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com    private static RegisterType getAndCheckSourceRegister(AnalyzedInstruction analyzedInstruction, int registerNumber,
376385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com                                            EnumSet validCategories) {
376485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        assert registerNumber >= 0 && registerNumber < analyzedInstruction.postRegisterMap.length;
3765fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
376685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        RegisterType registerType = analyzedInstruction.getPreInstructionRegisterType(registerNumber);
376785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        assert registerType != null;
3768fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
376985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        checkRegister(registerType, registerNumber, validCategories);
3770fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
377185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        if (validCategories == WideLowCategories) {
377285e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            checkRegister(registerType, registerNumber, WideLowCategories);
377385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            checkWidePair(registerNumber, analyzedInstruction);
3774fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
377585e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            RegisterType secondRegisterType = analyzedInstruction.getPreInstructionRegisterType(registerNumber + 1);
377685e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            assert secondRegisterType != null;
377785e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com            checkRegister(secondRegisterType, registerNumber+1, WideHighCategories);
3778fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
3779fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
378085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        return registerType;
378185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com    }
3782fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com
378385e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com    private static void checkRegister(RegisterType registerType, int registerNumber, EnumSet validCategories) {
378485e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        if (!validCategories.contains(registerType.category)) {
3785e9b722eab0b0932be59cb99c8c6f403b00abad6fJesusFreke@JesusFreke.com            throw new ValidationException(String.format("Invalid register type %s for register v%d.",
3786e9b722eab0b0932be59cb99c8c6f403b00abad6fJesusFreke@JesusFreke.com                    registerType.toString(), registerNumber));
3787fffb29fd9d67ba1396bd2999de4f0d9a44b79837JesusFreke@JesusFreke.com        }
378885e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com    }
3789d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com
379085e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com    private static void checkWidePair(int registerNumber, AnalyzedInstruction analyzedInstruction) {
379185e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        if (registerNumber + 1 >= analyzedInstruction.postRegisterMap.length) {
37927025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            throw new ValidationException(String.format("v%d cannot be used as the first register in a wide register" +
37937025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                    "pair because it is the last register.", registerNumber));
37947025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
37957025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
37967025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
37977025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private static interface RegisterIterator {
37987025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        int getRegister();
37997025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        boolean moveNext();
38007025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        int getCount();
38017025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        boolean pastEnd();
38027025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
38037025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
38047025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private static class Format35cRegisterIterator implements RegisterIterator {
38057025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        private final int registerCount;
38067025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        private final int[] registers;
38077025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        private int currentRegister = 0;
38087025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
38097025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        public Format35cRegisterIterator(FiveRegisterInstruction instruction) {
38107025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            registerCount = instruction.getRegCount();
38117025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            registers = new int[]{instruction.getRegisterD(), instruction.getRegisterE(),
38127025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                                  instruction.getRegisterF(), instruction.getRegisterG(),
38137025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com                                  instruction.getRegisterA()};
38147025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
38157025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
38167025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        public int getRegister() {
38177025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            return registers[currentRegister];
38187025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
38197025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
38207025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        public boolean moveNext() {
38217025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            currentRegister++;
38227025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            return !pastEnd();
38237025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
38247025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
38257025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        public int getCount() {
38267025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            return registerCount;
38277025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
38287025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
38297025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        public boolean pastEnd() {
38307025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            return currentRegister >= registerCount;
38317025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
38327025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    }
38337025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
38347025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com    private static class Format3rcRegisterIterator implements RegisterIterator {
38357025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        private final int startRegister;
38367025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        private final int registerCount;
38377025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        private int currentRegister = 0;
38387025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
38397025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        public Format3rcRegisterIterator(RegisterRangeInstruction instruction) {
38407025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            startRegister = instruction.getStartRegister();
38417025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            registerCount = instruction.getRegCount();
38427025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
38437025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
38447025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        public int getRegister() {
38457025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            return startRegister + currentRegister;
38467025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
38477025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
38487025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        public boolean moveNext() {
38497025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            currentRegister++;
38507025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            return !pastEnd();
38517025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
38527025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
38537025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        public int getCount() {
38547025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            return registerCount;
38557025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        }
38567025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com
38577025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com        public boolean pastEnd() {
38587025dfb7535319b39a806ae9124a939d29982cb0JesusFreke@JesusFreke.com            return currentRegister >= registerCount;
385985e17ca30a336e12592911afe666191947ec3697JesusFreke@JesusFreke.com        }
3860d27ca7f7a61cfbe60e1c490bf645257d7d59fd39JesusFreke@JesusFreke.com    }
38616729493700110554c0b98a92a1e41916ee0742d7Ben Gruver}