All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.fife.rsta.ac.java.classreader.Frame Maven / Gradle / Ivy

/*
 * 03/21/2010
 *
 * Copyright (C) 2010 Robert Futrell
 * robert_futrell at users.sourceforge.net
 * http://fifesoft.com/rsyntaxtextarea
 *
 * This library is distributed under a modified BSD license.  See the included
 * RSTALanguageSupport.License.txt file for details.
 */
package org.fife.rsta.ac.java.classreader;

import java.util.*;

import org.fife.rsta.ac.java.classreader.attributes.Code;


/**
 * A Frame contains information on a method being decompiled,
 * similar to a Frame as defined in 3.6 of the JVM spec.
 *
 * @author Robert Futrell
 * @version 1.0
 */
public class Frame {

	private Stack operandStack;
	private LocalVarInfo[] localVars;


	/**
	 * Constructor.
	 *
	 * @param code The {@link Code} attribute being decompiled.
	 */
	public Frame(Code code) {

		operandStack = new Stack();

		localVars = new LocalVarInfo[code.getMaxLocals()];
		int i = 0;
		MethodInfo mi = code.getMethodInfo();

		// Instance methods have an implicit first parameter of "this".
		if (!mi.isStatic()) {
			localVars[i++] = new LocalVarInfo("this", true);
		}

		// Name the passed-in local vars by their types. longs and doubles
		// take up two slots.
		String[] paramTypes = mi.getParameterTypes();
		for (int param_i=0; param_i-1) { // Class types.
				type = type.substring(type.lastIndexOf('.')+1);
			}
			String name = "localVar_" + type + "_" + param_i;
			localVars[i] = new LocalVarInfo(name, true);
			i++;
			if ("long".equals(type) || "double".equals(type)) {
				i++; // longs and doubles take up two slots.
			}
		}

		// NOTE: Other local vars will still be "null" here!  We need to
		// infer their types from their usage during disassembly/decompilation.
		System.out.println("NOTE: " + (localVars.length-i) + " unknown localVars slots");

	}


	public LocalVarInfo getLocalVar(int index, String defaultType) {
		LocalVarInfo var = localVars[index];
		if (var==null) {
			String name = "localVar_" + defaultType + "_" + index;
			var = new LocalVarInfo(name, false);
			localVars[index] = var;
		}
		else {
			var.alreadyDeclared = true; // May be redundant
		}
		return var;
	}


	public String pop() {
		return (String)operandStack.pop();
	}


	public void push(String value) {
		operandStack.push(value);
	}


	public static class LocalVarInfo {

		private String value;
		private boolean alreadyDeclared;

		public LocalVarInfo(String value, boolean alreadyDeclared) {
			this.value = value;
			this.alreadyDeclared = alreadyDeclared;
		}

		public String getValue() {
			return value;
		}

		public boolean isAlreadyDeclared() {
			return alreadyDeclared;
		}

	}


}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy