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

com.googlecode.jpattern.org.cojen.classfile.AbstractCodeAssembler Maven / Gradle / Ivy

Go to download

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