Package org.jnode.vm.classmgr

Source Code of org.jnode.vm.classmgr.VmByteCode

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.vm.classmgr;

import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.jnode.vm.facade.VmUtils;

/**
* @author epr
*/
public final class VmByteCode extends AbstractCode {

    /**
     * The method i'm a part of
     */
    private final VmMethod method;
   
    /**
     * The constant pool where indexes in my bytecode refer to
     */
    private final VmCP cp;
   
    /**
     * Number of local variables for this method
     */
    private char noLocals;
    /**
     * Max. number of slots taken by this method on the stack
     */
    private char maxStack;
   
    /**
     * Bytecode of this method. This is a ByteBuffer or byte[]
     */
    private Object bytecode;
   
    /**
     * Exception handler table
     */
    private VmInterpretedExceptionHandler[] eTable;
   
    /**
     * Line number table
     */
    private VmLineNumberMap lnTable;
   
    /**
     * Local variable table
     */
    private final VmLocalVariableTable lvTable;
   
    /**
     * Data used by the native code compilers
     */
    private transient Object compilerData;

    /**
     * Create a new instance
     *
     * @param method
     * @param bytecode
     * @param noLocals
     * @param maxStack
     * @param eTable
     * @param lnTable
     */
    public VmByteCode(VmMethod method, ByteBuffer bytecode, int noLocals, int maxStack,
                      VmInterpretedExceptionHandler[] eTable, VmLineNumberMap lnTable,
                      VmLocalVariableTable lvTable) {
        this.method = method;
        this.cp = method.getDeclaringClass().getCP();
        if (VmUtils.isWritingImage()) {
            final byte[] buildBytecode = new byte[bytecode.limit()];
            bytecode.get(buildBytecode);
            bytecode.rewind();
            this.bytecode = buildBytecode;
        } else {
            this.bytecode = bytecode;
        }
        this.noLocals = (char) noLocals;
        this.maxStack = (char) maxStack;
        this.eTable = eTable;
        this.lnTable = lnTable;
        this.lvTable = (lvTable != null) ? lvTable : VmLocalVariableTable.EMPTY;
        //this.locked = false;
    }

    /**
     * Gets the actual bytecode.
     * Do not change the contents of the given array!
     *
     * @return the code
     */
    public ByteBuffer getBytecode() {
        final Object bytecode = this.bytecode;
        if (bytecode instanceof ByteBuffer) {
            return ((ByteBuffer) bytecode).duplicate();
        } else {
            final ByteBuffer buf = ByteBuffer.wrap((byte[]) bytecode);
            if (VmUtils.isRunningVm()) {
                this.bytecode = buf;
            }
            return buf.duplicate();
        }
    }

    /**
     * Gets the length of the bytecode
     *
     * @return the length
     */
    public int getLength() {
        final Object bytecode = this.bytecode;
        if (bytecode instanceof ByteBuffer) {
            return ((ByteBuffer) bytecode).limit();
        } else {
            return ((byte[]) bytecode).length;
        }
    }

    /**
     * Gets the maximum stack size
     *
     * @return The maximum stack size
     */
    public int getMaxStack() {
        return maxStack;
    }

    /**
     * Gets the number of local variables
     *
     * @return the number of local variables
     */
    public int getNoLocals() {
        return noLocals;
    }

    /**
     * Get the number of exception handlers
     *
     * @return The number of exception handlers
     */
    public int getNoExceptionHandlers() {
        return (eTable == null) ? 0 : eTable.length;
    }

    /**
     * Get the handler PC of the exception handler at a given index
     *
     * @param index
     * @return The exception handler
     */
    public VmInterpretedExceptionHandler getExceptionHandler(int index) {
        if (eTable != null) {
            return eTable[index];
        } else {
            throw new IndexOutOfBoundsException("eTable is null; index " + index);
        }
    }

    /**
     * Gets all exception handler as unmodifiable list of VmInterpretedExceptionHandler
     * instances.
     *
     * @return The handlers
     */
    public List<VmInterpretedExceptionHandler> getExceptionHandlers() {
        if (eTable == null) {
            return Collections.emptyList();
        } else {
            return Arrays.asList(eTable);
        }
    }

    /**
     * Gets the line number table, or {@code null} if no line number table exists
     * for this bytecode.
     *
     * @return the line number table
     */
    public VmLineNumberMap getLineNrs() {
        return lnTable;
    }

    /**
     * Gets the line number corresponding to a given program counter value.
     *
     * @param pc
     * @return The line number for the given pc, or {@code -1} if no line
     * number can be found.
     */
    public int getLineNr(int pc) {
        final VmLineNumberMap lnTable = this.lnTable;
        if (lnTable != null) {
            return lnTable.findLineNr(pc);
        } else {
            return -1;
        }
    }

    /**
     * Lock this object.
     * This will make future modifications on this object fail.
     */
    final void lock() {
        //this.locked = true;
    }

    /**
     * Gets the constant pool, where indexes in this bytecode refer to
     *
     * @return The constant pool
     */
    public VmCP getCP() {
        return cp;
    }

    /**
     * Gets the method where this bytecode is a part of
     *
     * @return The method
     */
    public VmMethod getMethod() {
        return method;
    }

    /**
     * @return Returns the compilerData.
     */
    public final Object getCompilerData() {
        return this.compilerData;
    }

    /**
     * @param compilerData The compilerData to set.
     */
    public final void setCompilerData(Object compilerData) {
        this.compilerData = compilerData;
    }

    /**
     * Find the local variable at the given program counter (index
     * in bytecode) and the given index.
     *
     * @param pc
     * @param index
     * @return The variable or {@code null} if not found.
     */
    public final VmLocalVariable getVariable(int pc, int index) {
        return lvTable.getVariable(pc, index);
    }

    public final VmLocalVariableTable getLocalVariableTable() {
        return lvTable;
    }
}
TOP

Related Classes of org.jnode.vm.classmgr.VmByteCode

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.