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 Sigalpackage javassist.convert;
1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CannotCompileException;
1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.ClassPool;
1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtClass;
2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.NotFoundException;
2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CodeConverter.ArrayAccessReplacementMethodNames;
2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.BadBytecode;
2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.CodeIterator;
2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.ConstPool;
2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.Descriptor;
2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.MethodInfo;
2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.analysis.Analyzer;
2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.analysis.Frame;
2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/**
3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A transformer which replaces array access with static method invocations.
3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal *
3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @author Jason T. Greene
3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @version $Revision: 1.8 $
3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */
3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic final class TransformAccessArrayField extends Transformer {
3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private final String methodClassname;
3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private final ArrayAccessReplacementMethodNames names;
4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Frame[] frames;
4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int offset;
4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public TransformAccessArrayField(Transformer next, String methodClassname,
4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ArrayAccessReplacementMethodNames names) throws NotFoundException {
4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        super(next);
4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this.methodClassname = methodClassname;
4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        this.names = names;
4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void initialize(ConstPool cp, CtClass clazz, MethodInfo minfo) throws CannotCompileException {
5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        /*
5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         * This transformer must be isolated from other transformers, since some
5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         * of them affect the local variable and stack maximums without updating
5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         * the code attribute to reflect the changes. This screws up the
5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         * data-flow analyzer, since it relies on consistent code state. Even
5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         * if the attribute values were updated correctly, we would have to
5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         * detect it, and redo analysis, which is not cheap. Instead, we are
5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         * better off doing all changes in initialize() before everyone else has
6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         * a chance to muck things up.
6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal         */
6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CodeIterator iterator = minfo.getCodeAttribute().iterator();
6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        while (iterator.hasNext()) {
6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            try {
6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int pos = iterator.next();
6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int c = iterator.byteAt(pos);
6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (c == AALOAD)
6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    initFrames(clazz, minfo);
7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (c == AALOAD || c == BALOAD || c == CALOAD || c == DALOAD
7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        || c == FALOAD || c == IALOAD || c == LALOAD
7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        || c == SALOAD) {
7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    pos = replace(cp, iterator, pos, c, getLoadReplacementSignature(c));
7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                } else if (c == AASTORE || c == BASTORE || c == CASTORE
7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        || c == DASTORE || c == FASTORE || c == IASTORE
7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                        || c == LASTORE || c == SASTORE) {
7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    pos = replace(cp, iterator, pos, c, getStoreReplacementSignature(c));
7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                }
8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            } catch (Exception e) {
8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                throw new CannotCompileException(e);
8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public void clean() {
8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        frames = null;
8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        offset = -1;
9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    public int transform(CtClass tclazz, int pos, CodeIterator iterator,
9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            ConstPool cp) throws BadBytecode {
9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        // Do nothing, see above comment
9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return pos;
9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private Frame getFrame(int pos) throws BadBytecode {
9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return frames[pos - offset]; // Adjust pos
10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private void initFrames(CtClass clazz, MethodInfo minfo) throws BadBytecode {
10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (frames == null) {
10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            frames = ((new Analyzer())).analyze(clazz, minfo);
10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            offset = 0; // start tracking changes
10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int updatePos(int pos, int increment) {
11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (offset > -1)
11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            offset += increment;
11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return pos + increment;
11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private String getTopType(int pos) throws BadBytecode {
11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        Frame frame = getFrame(pos);
11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (frame == null)
11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return null;
12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        CtClass clazz = frame.peek().getCtClass();
12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return clazz != null ? Descriptor.toJvmName(clazz) : null;
12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private int replace(ConstPool cp, CodeIterator iterator, int pos,
12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int opcode, String signature) throws BadBytecode {
12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String castType = null;
12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String methodName = getMethodName(opcode);
12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (methodName != null) {
13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // See if the object must be cast
13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (opcode == AALOAD) {
13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                castType = getTopType(iterator.lookAhead());
13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                // Do not replace an AALOAD instruction that we do not have a type for
13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                // This happens when the state is guaranteed to be null (Type.UNINIT)
13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                // So we don't really care about this case.
13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if (castType == null)
13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    return pos;
13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                if ("java/lang/Object".equals(castType))
13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                    castType = null;
14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // The gap may include extra padding
14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            // Write a nop in case the padding pushes the instruction forward
14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            iterator.writeByte(NOP, pos);
14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            CodeIterator.Gap gap
14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                = iterator.insertGapAt(pos, castType != null ? 5 : 2, false);
14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            pos = gap.position;
14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int mi = cp.addClassInfo(methodClassname);
14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            int methodref = cp.addMethodrefInfo(mi, methodName, signature);
15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            iterator.writeByte(INVOKESTATIC, pos);
15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            iterator.write16bit(methodref, pos + 1);
15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            if (castType != null) {
15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                int index = cp.addClassInfo(castType);
15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                iterator.writeByte(CHECKCAST, pos + 3);
15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal                iterator.write16bit(index, pos + 4);
15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            }
15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            pos = updatePos(pos, gap.length);
16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return pos;
16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private String getMethodName(int opcode) {
16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        String methodName = null;
16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (opcode) {
16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case AALOAD:
16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.objectRead();
17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case BALOAD:
17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.byteOrBooleanRead();
17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case CALOAD:
17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.charRead();
17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case DALOAD:
17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.doubleRead();
17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case FALOAD:
18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.floatRead();
18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case IALOAD:
18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.intRead();
18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case SALOAD:
18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.shortRead();
18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case LALOAD:
19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.longRead();
19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case AASTORE:
19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.objectWrite();
19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case BASTORE:
19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.byteOrBooleanWrite();
19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case CASTORE:
19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.charWrite();
20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case DASTORE:
20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.doubleWrite();
20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case FASTORE:
20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.floatWrite();
20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case IASTORE:
20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.intWrite();
20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case SASTORE:
21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.shortWrite();
21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case LASTORE:
21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = names.longWrite();
21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            break;
21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        if (methodName.equals(""))
21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            methodName = null;
22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        return methodName;
22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private String getLoadReplacementSignature(int opcode) throws BadBytecode {
22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (opcode) {
22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case AALOAD:
22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;I)Ljava/lang/Object;";
22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case BALOAD:
22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;I)B";
23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case CALOAD:
23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;I)C";
23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case DALOAD:
23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;I)D";
23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case FALOAD:
23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;I)F";
23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case IALOAD:
23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;I)I";
23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case SALOAD:
23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;I)S";
24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case LALOAD:
24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;I)J";
24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throw new BadBytecode(opcode);
24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    private String getStoreReplacementSignature(int opcode) throws BadBytecode {
24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        switch (opcode) {
24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case AASTORE:
25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;ILjava/lang/Object;)V";
25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case BASTORE:
25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;IB)V";
25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case CASTORE:
25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;IC)V";
25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case DASTORE:
25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;ID)V";
25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case FASTORE:
25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;IF)V";
25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case IASTORE:
26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;II)V";
26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case SASTORE:
26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;IS)V";
26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        case LASTORE:
26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal            return "(Ljava/lang/Object;IJ)V";
26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        }
26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal
26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal        throw new BadBytecode(opcode);
26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal    }
26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal}
270