
com.googlecode.jpattern.org.cojen.classfile.AbstractCodeAssembler 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.io.InputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.MissingResourceException;
/**
*
*
* @author Brian S O'Neill
*/
public abstract class AbstractCodeAssembler implements CodeAssembler {
protected AbstractCodeAssembler() {
}
public void ifComparisonBranch(Location location, String choice, TypeDesc type) {
boolean trueBranch = false;
int length = choice.length();
if (choice.charAt(length - 1) == 't') {
trueBranch = true;
choice = choice.substring(0, length - 1);
}
choice = choice.intern();
switch (type.getTypeCode()) {
default:
if (choice == "==") {
ifEqualBranch(location, true);
} else if (choice == "!=") {
ifEqualBranch(location, false);
} else {
throw new IllegalArgumentException
("Comparison not allowed on object types: " + choice);
}
return;
case TypeDesc.BOOLEAN_CODE:
case TypeDesc.CHAR_CODE:
case TypeDesc.BYTE_CODE:
case TypeDesc.SHORT_CODE:
case TypeDesc.INT_CODE:
ifComparisonBranch(location, choice);
return;
case TypeDesc.LONG_CODE:
math(Opcode.LCMP);
break;
case TypeDesc.FLOAT_CODE:
math((choice == (trueBranch ? "<=" : ">") || choice == (trueBranch ? "<" : ">="))
? Opcode.FCMPG : Opcode.FCMPL);
break;
case TypeDesc.DOUBLE_CODE:
math((choice == (trueBranch ? "<=" : ">") || choice == (trueBranch ? "<" : ">="))
? Opcode.DCMPG : Opcode.DCMPL);
break;
}
ifZeroComparisonBranch(location, choice);
}
public void inline(Object code) {
// First load the class for the inlined code.
Class codeClass = code.getClass();
String className = codeClass.getName().replace('.', '/') + ".class";
ClassLoader loader = codeClass.getClassLoader();
InputStream in;
if (loader == null) {
in = ClassLoader.getSystemResourceAsStream(className);
} else {
in = loader.getResourceAsStream(className);
}
if (in == null) {
throw new MissingResourceException("Unable to find class file", className, null);
}
ClassFile cf;
try {
cf = ClassFile.readFrom(in);
} catch (IOException e) {
MissingResourceException e2 = new MissingResourceException
("Error loading class file: " + e.getMessage(), className, null);
try {
e2.initCause(e);
} catch (NoSuchMethodError e3) {
}
throw e2;
}
// Now find the single "define" method.
MethodInfo defineMethod = null;
MethodInfo[] methods = cf.getMethods();
for (int i=0; i=0; ) {
LocalVariable paramVar = createLocalVariable(null, paramTypes[i]);
storeLocal(paramVar);
paramVars[i] = paramVar;
}
Label returnLocation = createLabel();
CodeDisassembler cd = new CodeDisassembler(defineMethod);
cd.disassemble(this, paramVars, returnLocation);
returnLocation.setLocation();
}
public void invoke(Method method) {
TypeDesc ret = TypeDesc.forClass(method.getReturnType());
Class[] paramClasses = method.getParameterTypes();
TypeDesc[] params = new TypeDesc[paramClasses.length];
for (int i=0; i
© 2015 - 2025 Weber Informatics LLC | Privacy Policy