Package org.jnode.vm

Source Code of org.jnode.vm.VmStackFrameEnumerator

/*
* $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;

import org.jnode.annotation.MagicPermission;
import org.jnode.vm.classmgr.VmCompiledCode;
import org.jnode.vm.classmgr.VmMethod;
import org.vmmagic.unboxed.Address;

@MagicPermission
final class VmStackFrameEnumerator {

    /**
     * Stack frame reader
     */
    private final VmStackReader reader;
    /**
     * Address of current stack frame
     */
    private Address framePtr;
    /**
     * Index in address map of current stack frame method (deals with inlined methods)
     */
    private int codeIndex;
    /**
     * Compiled code for the current frame
     */
    private VmCompiledCode cc;

    /**
     * Initialize this instance.
     *
     * @param reader
     * @param framePtr
     * @param instrPtr
     */
    public VmStackFrameEnumerator(VmStackReader reader, Address framePtr, Address instrPtr) {
        this.reader = reader;
        reset(framePtr, instrPtr);
    }

    /**
     * Initialize this instance.
     * Set the enumerator to enumerate the stack of the current thread.
     *
     * @param reader
     */
    public VmStackFrameEnumerator(VmStackReader reader) {
        this.reader = reader;
        final Address curFrame = VmMagic.getCurrentFrame();
        reset(reader.getPrevious(curFrame), reader.getReturnAddress(curFrame));
    }

    /**
     * Reset the enumerator to the given pointers.
     *
     * @param framePtr
     * @param instrPtr
     */
    public final void reset(Address framePtr, Address instrPtr) {
        this.framePtr = framePtr;
        initializeCodeIndex(instrPtr);
    }

    /**
     * Is the current frameptr valid.
     *
     * @return
     */
    public final boolean isValid() {
        return reader.isValid(framePtr);
    }

    /**
     * Move to the next stack position.
     */
    public final void next() {
        if (reader.isValid(framePtr)) {
            if (cc != null) {
                final int newIndex = cc.getAddressMap().getCallSiteIndex(codeIndex);
                if (newIndex >= 0) {
                    codeIndex = newIndex;
                    return;
                }
            }
            final Address nextIP = reader.getReturnAddress(framePtr).add(-1);
            this.framePtr = reader.getPrevious(framePtr);
            initializeCodeIndex(nextIP);
        }
    }

    /**
     * Gets the method at the current stack position.
     *
     * @return
     */
    public final VmMethod getMethod() {
        VmMethod m = null;
        if (cc != null) {
            m = cc.getAddressMap().getMethodAtIndex(codeIndex);
        }
        if (m == null) {
            m = cc.getMethod();
        }
        if (m == null) {
            m = reader.getMethod(framePtr);
        }
        return m;
    }

    /**
     * Gets the method at the current stack position.
     *
     * @return
     */
    public final int getProgramCounter() {
        if (cc != null) {
            return cc.getAddressMap().getProgramCounterAtIndex(codeIndex);
        } else {
            return -1;
        }
    }

    /**
     * Gets the line number at the current stack position.
     *
     * @return
     */
    public final int getLineNumber() {
        return getMethod().getBytecode().getLineNr(getProgramCounter());
    }

    private void initializeCodeIndex(Address instrPtr) {
        cc = reader.getCompiledCode(framePtr);
        if (cc != null) {
            codeIndex = cc.getAddressMapIndex(instrPtr);
        } else {
            codeIndex = -1;
        }
    }
}
TOP

Related Classes of org.jnode.vm.VmStackFrameEnumerator

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.