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

kilim.analysis.AsmDetector Maven / Gradle / Ivy

Go to download

Coroutines, continuations, fibers, actors and message passing for the JVM

There is a newer version: 2.0.2-jdk7
Show newest version
// Copyright 2006 by sriram - offered under the terms of the MIT License

package kilim.analysis;

import java.util.LinkedList;
import java.io.IOException;
import java.util.HashMap;

import kilim.mirrors.Detector;

import org.objectweb.asm.ClassReader;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;

/**
 * This class is called by Detector to parse signatures of classes
 * that may have verification errors. It uses asm to open the file instead
 * of trying to classload it.
 */
public class AsmDetector {
    static HashMap classCacheMap= new HashMap();
    public static int getPausableStatus(String className, String methodName,
            String desc, Detector detector) 
    {
        try {
            ClassCache classCache = classCacheMap.get(className);
            if (classCache == null) {
                ClassReader cr = new ClassReader(className);
                ClassNode cn = new ClassNode();
                cr.accept(cn, /*flags*/ 0);
                classCache = cache(className, cn);
            }
            int status = classCache.getPausableStatus(methodName, desc);
            if (status == Detector.METHOD_NOT_FOUND_OR_PAUSABLE) {
                // check super classes
                for (String superName: classCache.superClasses) {
                    status = detector.getPausableStatus(superName, methodName, desc);
                    if (status != Detector.METHOD_NOT_FOUND_OR_PAUSABLE) 
                        break;
                }
            }
            return status;
        } catch (IOException ioe) {
            System.err.println("***Error reading " + className + ": " + ioe.getMessage());
            return Detector.METHOD_NOT_FOUND_OR_PAUSABLE;
        }
    }
    private static ClassCache cache(String className, ClassNode cn) {
        ClassCache classCache = new ClassCache();
        classCache.className = className;
        classCacheMap.put(className, classCache);
        LOOP:
        for (Object m: cn.methods) {
            MethodNode mn = (MethodNode)m;
            for (Object exception: mn.exceptions) {
                if ("kilim/Pausable".equals(exception)) {
                    classCache.pausableMethods.add(mn.name + mn.desc);
                    continue LOOP;
                }
            }
            classCache.otherMethods.add(mn.name + mn.desc);
        }
        classCache.addSuper(cn.superName);
        for (Object interfaceName: cn.interfaces) {
            classCache.addSuper((String)interfaceName);
        }
//        System.out.println(classCache);
        return classCache;
    }
    public static void main(String[] args) {
        AsmDetector.getPausableStatus(
                "com/sleepycat/je/Database",
                "putInternal",
                "Lcom/sleepycat/je/Transaction;Lcom/sleepycat/je/DatabaseEntry;Lcom/sleepycat/je/DatabaseEntry;Lcom/sleepycat/je/dbi/PutMode;Lkilim/Fiber;)Lcom/sleepycat/je/OperationStatus;)V",
                KilimContext.DEFAULT.detector);
    }
    
    static class ClassCache {
        String className;
        LinkedList pausableMethods = new LinkedList();
        LinkedList otherMethods = new LinkedList();
        LinkedList superClasses = new LinkedList();
        public void addSuper(String superName) {
            if (superName.equals("java/lang/Object")) return;
            if (!superClasses.contains(superName)) {superClasses.add(superName);}
        }
        public int getPausableStatus(String methodName, String desc) {
            String md = methodName + desc;
            if (pausableMethods.contains(md)) {
                return Detector.PAUSABLE_METHOD_FOUND; 
            } else if (otherMethods.contains(md)) {
                return Detector.METHOD_NOT_PAUSABLE;
            } else { 
                return Detector.METHOD_NOT_FOUND_OR_PAUSABLE;
            }
        }
        @Override
        public String toString() {
            return className + "\nPausable Methods: " + pausableMethods + "\nOthers:" + otherMethods;
        }
    }
}






© 2015 - 2024 Weber Informatics LLC | Privacy Policy