/* * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.max.vm.bytecode; import static com.sun.max.vm.classfile.ErrorContext.*; import com.sun.cri.bytecode.*; import com.sun.max.annotate.*; /** * An abstract class that can be extended and paired with a {@link BytecodeScanner} to process * the instructions decoded from a JVM instruction stream. */ public abstract class BytecodeVisitor { private BytecodeScanner bytecodeScanner; void setBytecodeScanner(BytecodeScanner bytecodeScanner) { this.bytecodeScanner = bytecodeScanner; } @INLINE public final BytecodeScanner bytecodeScanner() { return bytecodeScanner; } @INLINE public final int currentBCI() { return bytecodeScanner.currentBCI(); } @INLINE public final int currentOpcode() { return bytecodeScanner.currentOpcode(); } /** * Determines if the instruction currently being visited has a {@linkplain Bytecodes#WIDE wide} prefix. */ @INLINE public final boolean isCurrentOpcodeWidened() { return bytecodeScanner.isCurrentOpcodeWidened(); } @INLINE public final int currentOpcodeBCI() { return bytecodeScanner.currentOpcodeBCI(); } @INLINE protected final byte[] code() { return bytecodeScanner.bytecodeBlock().code(); } /** * Gives the byte code visitor an opportunity to do something in the presence of its byte code scanner before the * first byte gets scanned. */ protected void prologue() { } /** * Subclasses override this method if they need to do any processing after the * {@linkplain #bytecodeScanner() scanner} has decoded the {@linkplain #currentOpcode() opcode} of an instruction * but before it dispatches to the relevant bytecode specific method in this visitor. * <p> * The default implementation does nothing. */ protected void opcodeDecoded() { } /** * Subclasses override this method if they need to do any processing after the * {@linkplain #bytecodeScanner() scanner} has decoded a complete instruction. * <p> * The default implementation does nothing. */ protected void instructionDecoded() { } protected abstract void nop(); protected abstract void aconst_null(); protected abstract void iconst_m1(); protected abstract void iconst_0(); protected abstract void iconst_1(); protected abstract void iconst_2(); protected abstract void iconst_3(); protected abstract void iconst_4(); protected abstract void iconst_5(); protected abstract void lconst_0(); protected abstract void lconst_1(); protected abstract void fconst_0(); protected abstract void fconst_1(); protected abstract void fconst_2(); protected abstract void dconst_0(); protected abstract void dconst_1(); protected abstract void bipush(int operand); protected abstract void sipush(int operand); protected abstract void ldc(int index); protected abstract void ldc_w(int index); protected abstract void ldc2_w(int index); protected abstract void iload(int index); protected abstract void lload(int index); protected abstract void fload(int index); protected abstract void dload(int index); protected abstract void aload(int index); protected abstract void iload_0(); protected abstract void iload_1(); protected abstract void iload_2(); protected abstract void iload_3(); protected abstract void lload_0(); protected abstract void lload_1(); protected abstract void lload_2(); protected abstract void lload_3(); protected abstract void fload_0(); protected abstract void fload_1(); protected abstract void fload_2(); protected abstract void fload_3(); protected abstract void dload_0(); protected abstract void dload_1(); protected abstract void dload_2(); protected abstract void dload_3(); protected abstract void aload_0(); protected abstract void aload_1(); protected abstract void aload_2(); protected abstract void aload_3(); protected abstract void iaload(); protected abstract void laload(); protected abstract void faload(); protected abstract void daload(); protected abstract void aaload(); protected abstract void baload(); protected abstract void caload(); protected abstract void saload(); protected abstract void istore(int index); protected abstract void lstore(int index); protected abstract void fstore(int index); protected abstract void dstore(int index); protected abstract void astore(int index); protected abstract void istore_0(); protected abstract void istore_1(); protected abstract void istore_2(); protected abstract void istore_3(); protected abstract void lstore_0(); protected abstract void lstore_1(); protected abstract void lstore_2(); protected abstract void lstore_3(); protected abstract void fstore_0(); protected abstract void fstore_1(); protected abstract void fstore_2(); protected abstract void fstore_3(); protected abstract void dstore_0(); protected abstract void dstore_1(); protected abstract void dstore_2(); protected abstract void dstore_3(); protected abstract void astore_0(); protected abstract void astore_1(); protected abstract void astore_2(); protected abstract void astore_3(); protected abstract void iastore(); protected abstract void lastore(); protected abstract void fastore(); protected abstract void dastore(); protected abstract void aastore(); protected abstract void bastore(); protected abstract void castore(); protected abstract void sastore(); protected abstract void pop(); protected abstract void pop2(); protected abstract void dup(); protected abstract void dup_x1(); protected abstract void dup_x2(); protected abstract void dup2(); protected abstract void dup2_x1(); protected abstract void dup2_x2(); protected abstract void swap(); protected abstract void iadd(); protected abstract void ladd(); protected abstract void fadd(); protected abstract void dadd(); protected abstract void isub(); protected abstract void lsub(); protected abstract void fsub(); protected abstract void dsub(); protected abstract void imul(); protected abstract void lmul(); protected abstract void fmul(); protected abstract void dmul(); protected abstract void idiv(); protected abstract void ldiv(); protected abstract void fdiv(); protected abstract void ddiv(); protected abstract void irem(); protected abstract void lrem(); protected abstract void frem(); protected abstract void drem(); protected abstract void ineg(); protected abstract void lneg(); protected abstract void fneg(); protected abstract void dneg(); protected abstract void ishl(); protected abstract void lshl(); protected abstract void ishr(); protected abstract void lshr(); protected abstract void iushr(); protected abstract void lushr(); protected abstract void iand(); protected abstract void land(); protected abstract void ior(); protected abstract void lor(); protected abstract void ixor(); protected abstract void lxor(); protected abstract void iinc(int index, int addend); protected abstract void i2l(); protected abstract void i2f(); protected abstract void i2d(); protected abstract void l2i(); protected abstract void l2f(); protected abstract void l2d(); protected abstract void f2i(); protected abstract void f2l(); protected abstract void f2d(); protected abstract void d2i(); protected abstract void d2l(); protected abstract void d2f(); protected abstract void i2b(); protected abstract void i2c(); protected abstract void i2s(); protected abstract void lcmp(); protected abstract void fcmpl(); protected abstract void fcmpg(); protected abstract void dcmpl(); protected abstract void dcmpg(); protected abstract void ifeq(int offset); protected abstract void ifne(int offset); protected abstract void iflt(int offset); protected abstract void ifge(int offset); protected abstract void ifgt(int offset); protected abstract void ifle(int offset); protected abstract void if_icmpeq(int offset); protected abstract void if_icmpne(int offset); protected abstract void if_icmplt(int offset); protected abstract void if_icmpge(int offset); protected abstract void if_icmpgt(int offset); protected abstract void if_icmple(int offset); protected abstract void if_acmpeq(int offset); protected abstract void if_acmpne(int offset); protected abstract void goto_(int offset); protected abstract void jsr(int offset); protected abstract void ret(int index); protected abstract void tableswitch(int defaultOffset, int lowMatch, int highMatch, int numberOfCases); protected abstract void lookupswitch(int defaultOffset, int numberOfCases); protected abstract void ireturn(); protected abstract void lreturn(); protected abstract void freturn(); protected abstract void dreturn(); protected abstract void areturn(); protected abstract void vreturn(); protected abstract void getstatic(int index); protected abstract void putstatic(int index); protected abstract void getfield(int index); protected abstract void putfield(int index); protected abstract void invokevirtual(int index); protected abstract void invokespecial(int index); protected abstract void invokestatic(int index); protected abstract void invokeinterface(int index, int count); protected abstract void new_(int index); protected abstract void newarray(int tag); protected abstract void anewarray(int index); protected abstract void arraylength(); protected abstract void athrow(); protected abstract void checkcast(int index); protected abstract void instanceof_(int index); protected abstract void monitorenter(); protected abstract void monitorexit(); protected abstract void wide(); protected abstract void multianewarray(int index, int nDimensions); protected abstract void ifnull(int offset); protected abstract void ifnonnull(int offset); protected abstract void goto_w(int offset); protected abstract void jsr_w(int offset); protected abstract void breakpoint(); /** * @see Bytecodes#JNICALL */ protected abstract void jnicall(int nativeFunctionDescriptorIndex); /** * Parses an {@linkplain Bytecodes#isStandard(int) extended} bytecode instruction. * * @param opcode the opcode of the extended bytecode instruction * @param isWide specifies if the WIDE prefix was parsed before the opcode * @return {@code true} if this method ensures that the complete instruction has been parsed from the stream; * otherwise the caller is responsible for skipping any unparsed bytes of the instruction. */ protected boolean extension(int opcode, boolean isWide) { int length = Bytecodes.lengthOf(opcode); assert length != 0; bytecodeScanner.skipBytes(length - 1); return true; } protected void unknown(int opcode) { throw verifyError("Unsupported bytecode: " + opcode); } }