169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/*
269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit.
369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved.
469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version
669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with
769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License.  Alternatively, the contents of this file may be used under
869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later.
969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis,
1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the
1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License.
1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.bytecode.stackmap;
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.ClassPool;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtClass;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.NotFoundException;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.ConstPool;
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.StackMapTable;
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.BadBytecode;
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport java.util.ArrayList;
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic abstract class TypeData {
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /* Memo:
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * array type is a subtype of Cloneable and Serializable
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected TypeData() {}
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public abstract void merge(TypeData neighbor);
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Sets the type name of this object type.  If the given type name is
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * a subclass of the current type name, then the given name becomes
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * the name of this object type.
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     *
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * @param className     dot-separated name unless the type is an array type.
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    static void setType(TypeData td, String className, ClassPool cp) throws BadBytecode {
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (td == TypeTag.TOP)
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("unset variable");
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        else
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            td.setType(className, cp);
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public abstract boolean equals(Object obj);
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public abstract int getTypeTag();
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public abstract int getTypeData(ConstPool cp);
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /*
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * See UninitData.getSelf().
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public TypeData getSelf() { return this; }
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /* An operand value is copied when it is stored in a
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * local variable.
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public abstract TypeData copy();
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public abstract boolean isObjectType();
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public boolean is2WordType() { return false; }
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public boolean isNullType() { return false; }
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public abstract String getName() throws BadBytecode;
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected abstract void setType(String s, ClassPool cp) throws BadBytecode;
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public abstract void evalExpectedType(ClassPool cp) throws BadBytecode;
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public abstract String getExpected() throws BadBytecode;
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Primitive types.
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected static class BasicType extends TypeData {
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        private String name;
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        private int typeTag;
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public BasicType(String type, int tag) {
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            name = type;
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            typeTag = tag;
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public void merge(TypeData neighbor) {}
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public boolean equals(Object obj) {
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return this == obj;
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public int getTypeTag() { return typeTag; }
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public int getTypeData(ConstPool cp) { return 0; }
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public boolean isObjectType() { return false; }
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public boolean is2WordType() {
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return typeTag == StackMapTable.LONG
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    || typeTag == StackMapTable.DOUBLE;
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public TypeData copy() {
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return this;
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public void evalExpectedType(ClassPool cp) throws BadBytecode {}
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public String getExpected() throws BadBytecode {
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return name;
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public String getName() {
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return name;
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        protected void setType(String s, ClassPool cp) throws BadBytecode {
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("conflict: " + name + " and " + s);
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public String toString() { return name; }
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    protected static abstract class TypeName extends TypeData {
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        protected ArrayList equivalences;
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        protected String expectedName;
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        private CtClass cache;
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        private boolean evalDone;
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        protected TypeName() {
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            equivalences = new ArrayList();
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            equivalences.add(this);
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            expectedName = null;
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            cache = null;
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            evalDone = false;
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public void merge(TypeData neighbor) {
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (this == neighbor)
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return;
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (!(neighbor instanceof TypeName))
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return;     // neighbor might be UninitData
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            TypeName neighbor2 = (TypeName)neighbor;
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ArrayList list = equivalences;
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ArrayList list2 = neighbor2.equivalences;
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (list == list2)
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return;
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int n = list2.size();
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            for (int i = 0; i < n; i++) {
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                TypeName tn = (TypeName)list2.get(i);
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                add(list, tn);
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                tn.equivalences = list;
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        private static void add(ArrayList list, TypeData td) {
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int n = list.size();
16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            for (int i = 0; i < n; i++)
16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (list.get(i) == td)
16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return;
16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            list.add(td);
16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        /* NullType overrides this method.
16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         */
16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public int getTypeTag() { return StackMapTable.OBJECT; }
17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public int getTypeData(ConstPool cp) {
17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            String type;
17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            try {
17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                type = getExpected();
17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            } catch (BadBytecode e) {
17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new RuntimeException("fatal error: ", e);
17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return getTypeData2(cp, type);
18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        /* NullType overrides this method.
18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         */
18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        protected int getTypeData2(ConstPool cp, String type) {
18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return cp.addClassInfo(type);
18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public boolean equals(Object obj) {
18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (obj instanceof TypeName) {
19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                try {
19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    TypeName tn = (TypeName)obj;
19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return getExpected().equals(tn.getExpected());
19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                catch (BadBytecode e) {}
19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return false;
19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public boolean isObjectType() { return true; }
20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        protected void setType(String typeName, ClassPool cp) throws BadBytecode {
20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (update(cp, expectedName, typeName))
20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                expectedName = typeName;
20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public void evalExpectedType(ClassPool cp) throws BadBytecode {
20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (this.evalDone)
20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return;
21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ArrayList equiv = this.equivalences;
21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int n = equiv.size();
21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            String name = evalExpectedType2(equiv, n);
21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (name == null) {
21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                name = this.expectedName;
21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                for (int i = 0; i < n; i++) {
21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    TypeData td = (TypeData)equiv.get(i);
21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    if (td instanceof TypeName) {
21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        TypeName tn = (TypeName)td;
22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        if (update(cp, name, tn.expectedName))
22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                            name = tn.expectedName;
22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    }
22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            for (int i = 0; i < n; i++) {
22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                TypeData td = (TypeData)equiv.get(i);
22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (td instanceof TypeName) {
22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    TypeName tn = (TypeName)td;
23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    tn.expectedName = name;
23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    tn.cache = null;
23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    tn.evalDone = true;
23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        private String evalExpectedType2(ArrayList equiv, int n) throws BadBytecode {
23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            String origName = null;
23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            for (int i = 0; i < n; i++) {
24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                TypeData td = (TypeData)equiv.get(i);
24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (!td.isNullType())
24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    if (origName == null)
24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        origName = td.getName();
24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    else if (!origName.equals(td.getName()))
24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        return null;
24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return origName;
24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        protected boolean isTypeName() { return true; }
25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        private boolean update(ClassPool cp, String oldName, String typeName) throws BadBytecode {
25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (typeName == null)
25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return false;
25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else if (oldName == null)
25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return true;
25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else if (oldName.equals(typeName))
25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return false;
26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else if (typeName.charAt(0) == '['
26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                     && oldName.equals("[Ljava.lang.Object;")) {
26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                /* this rule is not correct but Tracer class sets the type
26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                   of the operand of arraylength to java.lang.Object[].
26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                   Thus, int[] etc. must be a subtype of java.lang.Object[].
26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                 */
26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return true;
26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            try {
27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (cache == null)
27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    cache = cp.get(oldName);
27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                CtClass cache2 = cp.get(typeName);
27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (cache2.subtypeOf(cache)) {
27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    cache = cache2;
27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return true;
27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                else
27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return false;
28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            catch (NotFoundException e) {
28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new BadBytecode("cannot find " + e.getMessage());
28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        /* See also NullType.getExpected().
28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         */
28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public String getExpected() throws BadBytecode {
28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ArrayList equiv = equivalences;
29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (equiv.size() == 1)
29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return getName();
29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else {
29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                String en = expectedName;
29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (en == null)
29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return "java.lang.Object";
29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                else
29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return en;
29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public String toString() {
30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            try {
30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                String en = expectedName;
30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (en != null)
30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return en;
30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                String name = getName();
30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (equivalences.size() == 1)
30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return name;
31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                else
31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return name + "?";
31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            catch (BadBytecode e) {
31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "<" + e.getMessage() + ">";
31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Type data for OBJECT.
32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static class ClassName extends TypeName {
32369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        private String name;    // dot separated.  null if this object is a copy of another.
32469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
32569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public ClassName(String n) {
32669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            name = n;
32769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
32869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
32969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public TypeData copy() {
33069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return new ClassName(name);
33169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
33269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
33369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public String getName() {   // never returns null.
33469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return name;
33569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
33669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
33769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
33869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
33969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Type data for NULL or OBJECT.
34069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * The types represented by the instances of this class are
34169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * initially NULL but will be OBJECT.
34269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
34369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static class NullType extends ClassName {
34469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public NullType() {
34569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            super("null");      // type name
34669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
34769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
34869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public TypeData copy() {
34969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return new NullType();
35069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
35169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
35269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public boolean isNullType() { return true; }
35369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
35469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public int getTypeTag() {
35569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            try {
35669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if ("null".equals(getExpected()))
35769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return StackMapTable.NULL;
35869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                else
35969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return super.getTypeTag();
36069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
36169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            catch (BadBytecode e) {
36269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new RuntimeException("fatal error: ", e);
36369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
36469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
36569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
36669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        protected int getTypeData2(ConstPool cp, String type) {
36769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if ("null".equals(type))
36869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return 0;
36969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
37069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return super.getTypeData2(cp, type);
37169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
37269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
37369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public String getExpected() throws BadBytecode {
37469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            String en = expectedName;
37569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (en == null) {
37669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal              // ArrayList equiv = equivalences;
37769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal              // if (equiv.size() == 1)
37869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal              //    return getName();
37969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal              // else
38069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return "java.lang.Object";
38169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
38269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
38369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return en;
38469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
38569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
38669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
38769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
38869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Type data for OBJECT if the type is an object type and is
38969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * derived as an element type from an array type by AALOAD.
39069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
39169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static class ArrayElement extends TypeName {
39269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        TypeData array;
39369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
39469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public ArrayElement(TypeData a) {   // a is never null
39569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            array = a;
39669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
39769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
39869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public TypeData copy() {
39969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return new ArrayElement(array);
40069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
40169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
40269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        protected void setType(String typeName, ClassPool cp) throws BadBytecode {
40369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            super.setType(typeName, cp);
40469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            array.setType(getArrayType(typeName), cp);
40569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
40669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
40769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public String getName() throws BadBytecode {
40869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            String name = array.getName();
40969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (name.length() > 1 && name.charAt(0) == '[') {
41069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                char c = name.charAt(1);
41169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (c == 'L')
41269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return name.substring(2, name.length() - 1).replace('/', '.');
41369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                else if (c == '[')
41469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return name.substring(1);
41569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
41669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
41769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            throw new BadBytecode("bad array type for AALOAD: "
41869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                                  + name);
41969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
42069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
42169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public static String getArrayType(String elementType) {
42269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (elementType.charAt(0) == '[')
42369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "[" + elementType;
42469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
42569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return "[L" + elementType.replace('.', '/') + ";";
42669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
42769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
42869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public static String getElementType(String arrayType) {
42969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            char c = arrayType.charAt(1);
43069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (c == 'L')
43169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return arrayType.substring(2, arrayType.length() - 1).replace('/', '.');
43269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else if (c == '[')
43369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return arrayType.substring(1);
43469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
43569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return arrayType;
43669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
43769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
43869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
43969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    /**
44069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     * Type data for UNINIT.
44169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal     */
44269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static class UninitData extends TypeData {
44369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String className;
44469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        int offset;
44569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        boolean initialized;
44669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
44769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        UninitData(int offset, String className) {
44869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            this.className = className;
44969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            this.offset = offset;
45069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            this.initialized = false;
45169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
45269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
45369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public void merge(TypeData neighbor) {}
45469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
45569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public int getTypeTag() { return StackMapTable.UNINIT; }
45669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public int getTypeData(ConstPool cp) { return offset; }
45769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
45869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public boolean equals(Object obj) {
45969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (obj instanceof UninitData) {
46069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                UninitData ud = (UninitData)obj;
46169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return offset == ud.offset && className.equals(ud.className);
46269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
46369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
46469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return false;
46569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
46669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
46769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public TypeData getSelf() {
46869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (initialized)
46969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return copy();
47069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            else
47169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                return this;
47269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
47369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
47469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public TypeData copy() {
47569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return new ClassName(className);
47669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
47769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
47869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public boolean isObjectType() { return true; }
47969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
48069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        protected void setType(String typeName, ClassPool cp) throws BadBytecode {
48169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            initialized = true;
48269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
48369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
48469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public void evalExpectedType(ClassPool cp) throws BadBytecode {}
48569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
48669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public String getName() {
48769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return className;
48869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
48969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
49069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public String getExpected() { return className; }
49169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
49269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public String toString() { return "uninit:" + className + "@" + offset; }
49369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
49469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
49569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public static class UninitThis extends UninitData {
49669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        UninitThis(String className) {
49769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            super(-1, className);
49869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
49969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
50069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public int getTypeTag() { return StackMapTable.THIS; }
50169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public int getTypeData(ConstPool cp) { return 0; }
50269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
50369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public boolean equals(Object obj) {
50469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return obj instanceof UninitThis;
50569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
50669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
50769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        public String toString() { return "uninit:this"; }
50869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
50969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
510