
com.googlecode.jpattern.org.cojen.classfile.CodeAssemblerPrinter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jpattern-cojen Show documentation
Show all versions of jpattern-cojen Show documentation
This is a copy of the good Cojen project from http://cojen.sourceforge.net/ with package name changed
The newest version!
/*
* Copyright 2004-2010 Brian S O'Neill
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.googlecode.jpattern.org.cojen.classfile;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.io.PrintWriter;
/**
* CodeAssembler implementation that prints out instructions using a Java-like
* syntax that matches the methods of CodeAssembler. When used in conjunction
* with a {@link CodeDisassembler}, this class makes it easier to understand
* how to use a CodeAssembler.
*
* @author Brian S O'Neill
*/
public class CodeAssemblerPrinter extends AbstractCodeAssembler implements CodeAssembler {
private final LocalVariable[] mParams;
private final boolean mIsStatic;
private final PrintWriter mWriter;
private final String mLinePrefix;
private final String mLineSuffix;
private final String mBulder;
private boolean mNeedSeparatorLine;
private int mLocalCounter;
private int mLabelCounter;
private int mTypeDescCounter;
// Maps TypeDesc objects to String variable names.
private Map mTypeDescNames;
private int mTypeDescArrayCounter;
// Maps TypeDesc arrays to String variable names.
private Map, String> mTypeDescArrayNames;
public CodeAssemblerPrinter(TypeDesc[] paramTypes, boolean isStatic,
PrintWriter writer)
{
this(paramTypes, isStatic, writer, null, null, null);
}
/**
* @param linePrefix optional prefix for each line
* @param lineSuffix optional suffix for each line
* @param builder when specified, generated method calls are invoked on
* local variable by this name
*/
public CodeAssemblerPrinter(TypeDesc[] paramTypes, boolean isStatic,
PrintWriter writer,
String linePrefix, String lineSuffix,
String builder)
{
mIsStatic = isStatic;
mWriter = writer;
mLinePrefix = linePrefix;
mLineSuffix = lineSuffix;
if (builder == null || builder.length() == 0) {
builder = "";
} else if (!builder.endsWith(".")) {
builder += '.';
}
mBulder = builder;
mTypeDescNames = new HashMap();
mTypeDescArrayNames = new HashMap, String>();
mParams = new LocalVariable[paramTypes.length];
int varNum = (isStatic) ? 0 : 1;
for (int i = 0; i 0) {
buf.append(", ");
}
buf.append(cases[i]);
}
buf.append("}");
buf.append(", ");
buf.append("new Location[] {");
for (int i=0; i 0) {
buf.append(", ");
}
buf.append(getLabelName(locations[i]));
}
buf.append("}");
buf.append(", ");
buf.append(getLabelName(defaultLocation));
buf.append(')');
println(buf.toString());
}
public void jsr(Location location) {
println(mBulder + "jsr(" + getLabelName(location) + ')');
}
public void ret(LocalVariable local) {
println(mBulder + "ret(" + local.getName() + ')');
}
public void math(byte opcode) {
println
(mBulder + "math(Opcode." + Opcode.getMnemonic(opcode).toUpperCase() + ')');
}
public void arrayLength() {
println(mBulder + "arrayLength()");
}
public void throwObject() {
println(mBulder + "throwObject()");
}
public void checkCast(TypeDesc type) {
println(mBulder + "checkCast(" + getTypeDescName(type) + ')');
}
public void instanceOf(TypeDesc type) {
println(mBulder + "instanceOf(" + getTypeDescName(type) + ')');
}
public void integerIncrement(LocalVariable local, int amount) {
println(mBulder + "integerIncrement(" + local.getName() + ", " + amount + ')');
}
public void monitorEnter() {
println(mBulder + "monitorEnter()");
}
public void monitorExit() {
println(mBulder + "monitorExit()");
}
public void nop() {
println(mBulder + "nop()");
}
public void breakpoint() {
println(mBulder + "breakpoint()");
}
private void separatorLine() {
if (mNeedSeparatorLine) {
mWriter.println();
mNeedSeparatorLine = false;
}
}
private void println(String str) {
mNeedSeparatorLine = true;
if (mLinePrefix != null) {
mWriter.print(mLinePrefix);
}
if (mLineSuffix == null) {
mWriter.println(str);
} else {
mWriter.print(str);
mWriter.println(mLineSuffix);
}
}
private String getLabelName(Location location) {
if (location instanceof NamedLabel) {
return ((NamedLabel)location).mName;
} else {
return ((NamedLabel)createLabel()).mName;
}
}
private String getTypeDescName(TypeDesc type) {
if (type == null) {
return "null";
}
String name = mTypeDescNames.get(type);
if (name == null) {
if (type.isPrimitive()) {
name = "TypeDesc.".concat(type.getRootName().toUpperCase());
mTypeDescNames.put(type, name);
return name;
} else if (type == TypeDesc.OBJECT) {
mTypeDescNames.put(type, name = "TypeDesc.OBJECT");
return name;
} else if (type == TypeDesc.STRING) {
mTypeDescNames.put(type, name = "TypeDesc.STRING");
return name;
}
name = "type_" + (++mTypeDescCounter);
mTypeDescNames.put(type, name);
StringBuffer buf = new StringBuffer("TypeDesc ");
buf.append(name);
buf.append(" = ");
TypeDesc componentType = type.getComponentType();
if (componentType != null) {
buf.append(getTypeDescName(componentType));
buf.append(".toArrayType(");
} else {
buf.append("TypeDesc.forClass(");
buf.append('"');
buf.append(type.getRootName());
buf.append('"');
}
buf.append(')');
println(buf.toString());
}
return name;
}
private String getTypeDescArrayName(TypeDesc[] types) {
if (types == null) {
return "null";
}
List key = Arrays.asList(types);
String name = mTypeDescArrayNames.get(key);
if (name == null) {
name = "params_" + (++mTypeDescArrayCounter);
mTypeDescArrayNames.put(key, name);
StringBuffer buf = new StringBuffer("TypeDesc[] ");
buf.append(name);
buf.append(" = new TypeDesc[] {");
for (int i=0; i 0) {
buf.append(", ");
}
buf.append(getTypeDescName(types[i]));
}
buf.append('}');
println(buf.toString());
}
return name;
}
static String escape(String value) {
return escape(value, false);
}
static String escape(String value, boolean forChar) {
int length = value.length();
int i = 0;
for (; i < length; i++) {
char c = value.charAt(i);
if (c < 32 || c > 126 || c == '"' || c == '\\' || (forChar && c == '\'')) {
break;
}
}
if (i >= length) {
return value;
}
StringBuffer buf = new StringBuffer(length + 16);
for (i=0; i= 32 && c <= 126 && c != '"' && c != '\\' && (!forChar || c != '\'')) {
buf.append(c);
continue;
}
switch (c) {
case '\0':
buf.append("\\0");
break;
case '"':
buf.append("\\\"");
break;
case '\'':
buf.append("\\'");
break;
case '\\':
buf.append("\\\\");
break;
case '\b':
buf.append("\\b");
break;
case '\f':
buf.append("\\f");
break;
case '\n':
buf.append("\\n");
break;
case '\r':
buf.append("\\r");
break;
case '\t':
buf.append("\\t");
break;
default:
String u = Integer.toHexString(c).toLowerCase();
buf.append("\\u");
for (int len = u.length(); len < 4; len++) {
buf.append('0');
}
buf.append(u);
break;
}
}
return buf.toString();
}
private class NamedLocal implements LocalVariable {
private final String mName;
private final TypeDesc mType;
private final int mNumber;
public NamedLocal(String name, TypeDesc type, int number) {
mName = name;
mType = type;
mNumber = number;
}
public String getName() {
return mName;
}
public void setName(String name) {
println(mName + ".setName(" + name + ')');
}
public TypeDesc getType() {
return mType;
}
public boolean isDoubleWord() {
return mType.isDoubleWord();
}
public int getNumber() {
return mNumber;
}
public Location getStartLocation() {
return null;
}
public Location getEndLocation() {
return null;
}
public Set getLocationRangeSet() {
return null;
}
}
private class NamedLabel implements Label {
public final String mName;
public NamedLabel(String name) {
mName = name;
}
public Label setLocation() {
println(mName + ".setLocation()");
return this;
}
public int getLocation() {
return -1;
}
public int compareTo(Location obj) {
return 0;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy