Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
jadex.bdiv3.ASMBDIClassGenerator Maven / Gradle / Ivy
package jadex.bdiv3;
import java.io.InputStream;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;
import org.objectweb.asm.util.ASMifier;
import org.objectweb.asm.util.TraceClassVisitor;
import jadex.bdiv3.exceptions.JadexBDIGenerationException;
import jadex.bdiv3.model.BDIModel;
import jadex.bdiv3.model.MBelief;
import jadex.bdiv3.model.MGoal;
import jadex.bridge.IInternalAccess;
import jadex.commons.SReflect;
import jadex.commons.SUtil;
import jadex.commons.Tuple2;
import jadex.micro.MicroClassReader.DummyClassLoader;
/**
*
*/
public class ASMBDIClassGenerator extends AbstractAsmBdiClassGenerator
{
protected static Method methoddc1;
protected static Method methoddc2;
static
{
try
{
AccessController.doPrivileged(new PrivilegedExceptionAction()
{
public Object run() throws Exception
{
Class> cl = Class.forName("java.lang.ClassLoader");
methoddc1 = cl.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class});
methoddc2 = cl.getDeclaredMethod("defineClass", new Class[]{String.class, byte[].class, int.class, int.class, ProtectionDomain.class});
return null;
}
});
}
catch(PrivilegedActionException e)
{
throw new RuntimeException(e);
}
}
/**
* Generate class.
*/
public List> generateBDIClass(String clname, BDIModel model, ClassLoader dummycl) throws JadexBDIGenerationException
{
return generateBDIClass(clname, model, dummycl, new HashMap());
}
/**
* Generate class.
*/
public List> generateBDIClass(final String clname, final BDIModel model,
ClassLoader dummycl, final Map done) throws JadexBDIGenerationException //final boolean isstatic
{
List> ret = new ArrayList>();
final ClassLoader cl = ((DummyClassLoader)dummycl).getOriginal();
// System.out.println("Generating with cl: "+cl+" "+clname);
final List todo = new ArrayList();
// final Set statics = new HashSet();
try
{
// String clname = cma.getName()+BDIModelLoader.FILE_EXTENSION_BDIV3_FIRST;
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
final ClassNode cn = new ClassNode();
done.put(clname, cn);
// TraceClassVisitor tcv = new TraceClassVisitor(cw, new PrintWriter(System.out))
// TraceClassVisitor tcv = new TraceClassVisitor(cw, new ASMifier(), new PrintWriter(System.out));
// CheckClassAdapter cc = new CheckClassAdapter(cw);
final String iclname = clname.replace(".", "/");
ClassVisitor cv = new ClassVisitor(Opcodes.ASM4, cn)
{
boolean isagentorcapa = false;
boolean isgoal = false;
// boolean iamstaticc = false;
// boolean isplan = false;
// Set fields = new HashSet();
public void visit(int version, int access, String name,
String signature, String superName, String[] interfaces)
{
// Make class non-abstract if agent implements IBDIAgent interface
boolean implbdiagent = false;
if(interfaces!=null)
{
for(String iface: interfaces)
{
if(iface.indexOf(Type.getInternalName(IBDIAgent.class))!=-1)
{
implbdiagent = true;
break;
}
}
}
if(implbdiagent && name.endsWith(BDIModelLoader.FILE_EXTENSION_BDIV3_FIRST))
{
// erase abstract modifier
// access = ~Opcodes.ACC_ABSTRACT & access;
access = access-Opcodes.ACC_ABSTRACT;
}
// iamstaticc = (access&Opcodes.ACC_STATIC)!=0;
super.visit(version, access, name, null, superName, interfaces);
}
// public FieldVisitor visitField(int access, String name,
// String desc, String signature, Object value)
// {
// fields.add(name);
// return super.visitField(access, name, desc, signature, value);
// }
public AnnotationVisitor visitAnnotation(String desc, boolean visible)
{
if(visible)
{
if(isAgentOrCapa(desc))
{
isagentorcapa = true;
}
else if(isGoal(desc))
{
isgoal = true;
}
// else if(isPlan(desc))
// {
// isplan = true;
// }
}
// return super.visitAnnotation(desc, visible);
// System.out.println("visA: "+desc);
//
return new AnnotationVisitor(api, super.visitAnnotation(desc, visible))
{
public AnnotationVisitor visitAnnotation(String name, String desc)
{
// System.out.println("visit: "+name+" "+desc);
return !desc.equals("Ljadex/bdiv3/annotation/Goal;")? this: new AnnotationVisitor(Opcodes.ASM4, super.visitAnnotation(name, desc))
{
public void visit(String name, Object value)
{
// if("clazz".equals(name))
// {
// String cln = ((Type)value).getClassName();
//
// if(!done.containsKey(cln))
// todo.add(cln);
// }
super.visit(name, value);
}
};
}
public AnnotationVisitor visitArray(String name)
{
return new AnnotationVisitor(api, super.visitArray(iclname))
{
public AnnotationVisitor visitAnnotation(String name, String desc)
{
// System.out.println("visit: "+name+" "+desc);
return !desc.equals("Ljadex/bdiv3/annotation/Goal;")? this: new AnnotationVisitor(Opcodes.ASM4, super.visitAnnotation(name, desc))
{
public void visit(String name, Object value)
{
if("clazz".equals(name))
{
String cln = ((Type)value).getClassName();
if(!done.containsKey(cln))
todo.add(cln);
}
super.visit(name, value);
}
};
}
};
}
};
}
public MethodVisitor visitMethod(int access, final String methodname, String desc, String signature, String[] exceptions)
{
// if(clname.indexOf("PlanPrecondition")!=-1)
// System.out.println(desc+" "+methodname);
return new MethodVisitor(api, super.visitMethod(access, methodname, desc, signature, exceptions))
{
public void visitFieldInsn(int opcode, String owner, String name, String desc)
{
boolean enh = false;
if(ophelper.isPutField(opcode))
{
// if is a putfield and is belief and not is in init (__agent field is not available)
// either is itself agent/capa or is not field of non-agent
if(model.getCapability().hasBelief(name)
&& model.getCapability().getBelief(name).isFieldBelief()
&& (isagentorcapa || !owner.equals(iclname)))
{
// possibly transform basic value
if(SReflect.isBasicType(SReflect.findClass0(Type.getType(desc).getClassName(), null, cl)))
visitMethodInsn(Opcodes.INVOKESTATIC, "jadex/commons/SReflect", "wrapValue", "("+desc+")Ljava/lang/Object;");
visitInsn(Opcodes.SWAP);
// fetch bdi agent value from field
// this pop aload is necessary in inner classes!
if(isagentorcapa)
{
visitInsn(Opcodes.POP);
visitVarInsn(Opcodes.ALOAD, 0);
super.visitFieldInsn(Opcodes.GETFIELD, iclname, AGENT_FIELD_NAME, Type.getDescriptor(IInternalAccess.class));
}
else
{
visitInsn(Opcodes.POP);
visitInsn(Opcodes.ACONST_NULL);
}
// add field name
visitLdcInsn(name);
visitInsn(Opcodes.SWAP);
// add this
visitVarInsn(Opcodes.ALOAD, 0);
visitInsn(Opcodes.SWAP);
visitMethodInsn(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "writeField", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;Ljadex/bridge/IInternalAccess;)V");
enh = true;
}
else if(isgoal)
{
MGoal mgoal = model.getCapability().getGoal(clname);
if(mgoal!=null && mgoal.hasParameter(name))
{
// possibly transform basic value
if(SReflect.isBasicType(SReflect.findClass0(Type.getType(desc).getClassName(), null, cl)))
visitMethodInsn(Opcodes.INVOKESTATIC, "jadex/commons/SReflect", "wrapValue", "("+desc+")Ljava/lang/Object;");
visitInsn(Opcodes.SWAP);
// fetch bdi agent value from field
visitInsn(Opcodes.POP);
visitInsn(Opcodes.ACONST_NULL);
// add field name
visitLdcInsn(name);
visitInsn(Opcodes.SWAP);
// add this
visitVarInsn(Opcodes.ALOAD, 0);
visitInsn(Opcodes.SWAP);
visitMethodInsn(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "writeParameterField", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;Ljadex/bridge/IInternalAccess;)V");
enh = true;
}
}
// else if(isplan)
// {
// // todo? currently have no parameter support
// }
}
if(!enh)
super.visitFieldInsn(opcode, owner, name, desc);
}
// public void visitInsn(int opcode)
// {
// if(Opcodes.AASTORE==opcode)
// {
// // on stack: arrayref, index, value
// visitVarInsn(Opcodes.ALOAD, 0);
// super.visitFieldInsn(Opcodes.GETFIELD, iclname, AGENT_FIELD_NAME, Type.getDescriptor(BDIAgent.class));
//
// // invoke method
// visitMethodInsn(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "writeArrayField", "(Ljava/lang/Object;ILjava/lang/Object;Ljadex/bridge/IInternalAccess;)V");
// }
// else
// {
// super.visitInsn(opcode);
// }
//// super.visitInsn(opcode);
// }
};
}
public void visitInnerClass(String name, String outerName, String innerName, int access)
{
String icln = name.replace("/", ".");
// if((access&Opcodes.ACC_STATIC)!=0)
// statics.add(icln);
// Exclude non-relevant inner classes (that do not belong to the application code)
if(iclname!=null && (outerName!=null && iclname.startsWith(outerName))
|| (outerName==null && innerName==null)) // case in anonymous inner classes
{
// System.out.println("vic: "+name+" "+outerName+" "+innerName+" "+access);
if(!done.containsKey(icln))
todo.add(icln);
}
// else
// {
// System.out.println("skipping class enhancement of: "+innerName);
// }
super.visitInnerClass(name, outerName, innerName, access);//Opcodes.ACC_PUBLIC); does not work
}
public void visitEnd()
{
if(isagentorcapa || (isgoal))// && (isstatic || iamstaticc)))
visitField(Opcodes.ACC_PUBLIC, AGENT_FIELD_NAME, Type.getDescriptor(IInternalAccess.class), null, null);
visitField(Opcodes.ACC_PUBLIC, GLOBALNAME_FIELD_NAME, Type.getDescriptor(String.class), null, null);
super.visitEnd();
}
};
InputStream is = null;
try
{
String fname = clname.replace('.', '/') + ".class";
is = SUtil.getResource(fname, cl);
ClassReader cr = new ClassReader(is);
// TraceClassVisitor tcv2 = new TraceClassVisitor(cv, new PrintWriter(System.out));
// TraceClassVisitor tcv3 = new TraceClassVisitor(null, new PrintWriter(System.out));
// cr.accept(tcv2, 0);
cr.accept(cv, 0);
transformClassNode(cn, iclname, model, dummycl, done);
cn.accept(cw);
byte[] data = cw.toByteArray();
// CheckClassAdapter.verify(new ClassReader(data), true, new PrintWriter(System.out));
// Find correct cloader for injecting the class.
// Probes to load class without loading class.
List pas = new LinkedList();
ClassLoader tmp = cl;
while(tmp!=null)
{
pas.add(0, tmp);
tmp = tmp.getParent();
}
ClassLoader found = null;
for(ClassLoader tmpcl: pas)
{
if(tmpcl.getResource(fname)!=null)
{
found = tmpcl;
break;
}
}
// System.out.println("toClass: "+clname+" "+found);
Class> loadedclass = toClass(clname, data, found, null);
if(loadedclass != null)
{
// if it's null, we were not allowed to generate this class
// e.g. java.util.Map.Entry "subclasses" (in bdiv3.tutorial.c1.TranslationBDI)
ret.add(loadedclass);
}
// if(ret.getName().indexOf("$")!=-1)
// {
// try
// {
// Method m = ret.getMethod("__getLineNumber", new Class[0]);
// Object o = m.invoke(null, new Object[0]);
// System.out.println("Line is: "+ret.getName()+" "+o);
// }
// catch(Exception e)
// {
// }
// }
}
catch(Exception e)
{
throw new JadexBDIGenerationException("Could not generate BDI Class: " + clname,e);
}
finally
{
try
{
if(is!=null)
is.close();
}
catch(Exception e)
{
}
}
for(String icl: todo)
{
List> classes = generateBDIClass(icl, model, dummycl, done);//, statics.contains(icl));
ret.addAll(classes);
}
}
catch(Throwable e)
{
throw new JadexBDIGenerationException("Error generating BDI class:" + clname, e);
}
return ret;
}
/**
*
*/
protected void replaceNativeGetter(String iclname, MethodNode mn, String belname)
{
Type ret = Type.getReturnType(mn.desc);
mn.access = mn.access - Opcodes.ACC_NATIVE;
InsnList nl = new InsnList();
nl.add(new VarInsnNode(Opcodes.ALOAD, 0));
nl.add(new FieldInsnNode(Opcodes.GETFIELD, iclname, AGENT_FIELD_NAME, "Ljadex/bridge/IInternalAccess;"));
nl.add(new VarInsnNode(Opcodes.ALOAD, 0));
nl.add(new FieldInsnNode(Opcodes.GETFIELD, iclname, GLOBALNAME_FIELD_NAME, "Ljava/lang/String;"));
nl.add(new LdcInsnNode(belname));
if(ret.getClassName().equals("byte"))
{
nl.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;"));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "getAbstractBeliefValue", "(Ljadex/bridge/IInternalAccess;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"));
nl.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Number"));
nl.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Number", "intValue", "()I"));
nl.add(new InsnNode(Opcodes.I2B));
nl.add(new InsnNode(Opcodes.IRETURN));
}
else if(ret.getClassName().equals("short"))
{
nl.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;"));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "getAbstractBeliefValue", "(Ljadex/bridge/IInternalAccess;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"));
nl.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Number"));
nl.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Number", "intValue", "()I"));
nl.add(new InsnNode(Opcodes.I2S));
nl.add(new InsnNode(Opcodes.IRETURN));
}
else if(ret.getClassName().equals("int"))
{
nl.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "getAbstractBeliefValue", "(Ljadex/bridge/IInternalAccess;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"));
nl.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Number"));
nl.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Number", "intValue", "()I"));
nl.add(new InsnNode(Opcodes.IRETURN));
}
else if(ret.getClassName().equals("char"))
{
nl.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;"));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "getAbstractBeliefValue", "(Ljadex/bridge/IInternalAccess;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"));
nl.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Character"));
nl.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Character", "charValue", "()C"));
nl.add(new InsnNode(Opcodes.IRETURN));
}
else if(ret.getClassName().equals("boolean"))
{
nl.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;"));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "getAbstractBeliefValue", "(Ljadex/bridge/IInternalAccess;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"));
nl.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Boolean"));
nl.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"));
nl.add(new InsnNode(Opcodes.IRETURN));
}
else if(ret.getClassName().equals("long"))
{
nl.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;"));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "getAbstractBeliefValue", "(Ljadex/bridge/IInternalAccess;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"));
nl.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Number"));
nl.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Number", "longValue", "()J"));
nl.add(new InsnNode(Opcodes.LRETURN));
}
else if(ret.getClassName().equals("float"))
{
nl.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;"));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "getAbstractBeliefValue", "(Ljadex/bridge/IInternalAccess;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"));
nl.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Number"));
nl.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Number", "floatValue", "()F"));
nl.add(new InsnNode(Opcodes.FRETURN));
}
else if(ret.getClassName().equals("double"))
{
nl.add(new FieldInsnNode(Opcodes.GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;"));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "getAbstractBeliefValue", "(Ljadex/bridge/IInternalAccess;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"));
nl.add(new TypeInsnNode(Opcodes.CHECKCAST, "java/lang/Number"));
nl.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/Number", "doubleValue", "()D"));
nl.add(new InsnNode(Opcodes.DRETURN));
}
else // Object
{
nl.add(new LdcInsnNode(ret));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "getAbstractBeliefValue", "(Ljadex/bridge/IInternalAccess;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;"));
nl.add(new TypeInsnNode(Opcodes.CHECKCAST, ret.getInternalName()));
nl.add(new InsnNode(Opcodes.ARETURN));
}
mn.instructions = nl;
}
/**
*
*/
protected void makeObject(InsnList nl, Type arg)
{
if(arg.getClassName().equals("byte"))
{
nl.add(new VarInsnNode(Opcodes.ILOAD, 1));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;"));
}
else if(arg.getClassName().equals("short"))
{
nl.add(new VarInsnNode(Opcodes.ILOAD, 1));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;"));
}
else if(arg.getClassName().equals("int"))
{
nl.add(new VarInsnNode(Opcodes.ILOAD, 1));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;"));
}
else if(arg.getClassName().equals("char"))
{
nl.add(new VarInsnNode(Opcodes.ILOAD, 1));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;"));
}
else if(arg.getClassName().equals("boolean"))
{
nl.add(new VarInsnNode(Opcodes.ILOAD, 1));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;"));
}
else if(arg.getClassName().equals("long"))
{
nl.add(new VarInsnNode(Opcodes.LLOAD, 1));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;"));
}
else if(arg.getClassName().equals("float"))
{
nl.add(new VarInsnNode(Opcodes.FLOAD, 1));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;"));
}
else if(arg.getClassName().equals("double"))
{
nl.add(new VarInsnNode(Opcodes.DLOAD, 1));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;"));
}
else // Object
{
nl.add(new VarInsnNode(Opcodes.ALOAD, 1));
}
}
/**
*
*/
protected void replaceNativeSetter(String iclname, MethodNode mn, String belname)
{
Type arg = Type.getArgumentTypes(mn.desc)[0];
mn.access = mn.access - Opcodes.ACC_NATIVE;
InsnList nl = new InsnList();
nl.add(new VarInsnNode(Opcodes.ALOAD, 0));
nl.add(new FieldInsnNode(Opcodes.GETFIELD, iclname, AGENT_FIELD_NAME, "Ljadex/bridge/IInternalAccess;"));
nl.add(new VarInsnNode(Opcodes.ALOAD, 0));
nl.add(new FieldInsnNode(Opcodes.GETFIELD, iclname, GLOBALNAME_FIELD_NAME, "Ljava/lang/String;"));
nl.add(new LdcInsnNode(belname));
makeObject(nl, arg);
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "setAbstractBeliefValue", "(Ljadex/bridge/IInternalAccess;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Object;)V"));
nl.add(new InsnNode(Opcodes.RETURN));
mn.instructions = nl;
}
/**
*
*/
protected void enhanceSetter(String iclname, MethodNode mn, String belname)
{
// System.out.println("method acc: "+mn.getName()+" "+mn.getAccess());
Type[] args = Type.getArgumentTypes(mn.desc);
InsnList l = mn.instructions;
// System.out.println("icl: "+iclname);
InsnList nl = new InsnList();
nl.add(new VarInsnNode(Opcodes.ALOAD, 0)); // loads the object
nl.add(new FieldInsnNode(Opcodes.GETFIELD, iclname, AGENT_FIELD_NAME, Type.getDescriptor(IInternalAccess.class)));
nl.add(new LdcInsnNode(belname));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "unobserveValue",
// "(Ljava/lang/String;)V"));
"(Ljadex/bridge/IInternalAccess;Ljava/lang/String;)V"));
l.insertBefore(l.getFirst(), nl);
nl = new InsnList();
// nl.add(new VarInsnNode(Opcodes.ALOAD, 1)); // loads the argument (=parameter0) does not work for other types than object
if(args.length>0)
{
makeObject(nl, args[0]);
}
else
{
nl.add(new InsnNode(Opcodes.ACONST_NULL));
}
nl.add(new InsnNode(Opcodes.ACONST_NULL)); // oldvalue ?
nl.add(new InsnNode(Opcodes.ACONST_NULL)); // no index/key
nl.add(new VarInsnNode(Opcodes.ALOAD, 0)); // loads the agent object
nl.add(new FieldInsnNode(Opcodes.GETFIELD, iclname, AGENT_FIELD_NAME, Type.getDescriptor(IInternalAccess.class)));
nl.add(new LdcInsnNode(belname));
// nl.add(new LdcInsnNode(mbel));
nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bdiv3/features/impl/BDIAgentFeature", "createChangeEvent",
// "(Ljava/lang/Object;Ljadex/bridge/IInternalAccess;Ljava/lang/String;)V"));
"(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljadex/bridge/IInternalAccess;Ljava/lang/String;)V"));
// nl.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "jadex/bridge/IInternalAccess", "createEvent",
// "()V"));
// Find return and insert call before that
AbstractInsnNode n;
for(n = l.getLast(); n.getOpcode()!=Opcodes.RETURN; n = n.getPrevious())
{
}
l.insertBefore(n, nl);
}
/**
*
*/
protected void transformConstructor(ClassNode cn, MethodNode mn, BDIModel model, List tododyn, Map others)
{
InsnList l = mn.instructions;
LabelNode begin = null;
int foundcon = -1;
for(int i=0; i evs = new ArrayList();
while(!start.equals(begin))
{
// find method name via last constant load
if(name==null && start instanceof LdcInsnNode)
name = (String)((LdcInsnNode)start).cst;
if(start.getOpcode()==Opcodes.GETFIELD)
{
String bn = ((FieldInsnNode)start).name;
if(model.getCapability().hasBelief(bn))
{
evs.add(bn);
}
}
start = start.getPrevious();
}
// todo: use findBeliefs?!
// Set bels = findBeliefs(cn, mn, model, others);
// Create new update method for dynamic belief
if(tododyn.remove(name))
{
MBelief mbel = model.getCapability().getBelief(name);
Set bevs = new LinkedHashSet(mbel.getBeliefEvents());
bevs.addAll(evs);
mbel.setBeliefEvents(bevs);
MethodNode mnode = new MethodNode(Opcodes.ACC_PUBLIC, IBDIClassGenerator.DYNAMIC_BELIEF_UPDATEMETHOD_PREFIX
+SUtil.firstToUpperCase(name), Type.getMethodDescriptor(Type.VOID_TYPE), null, null);
// First labels are cloned
AbstractInsnNode cur = start;
Map labels = new HashMap();
while(!cur.equals(min))
{
if(cur instanceof LabelNode)
labels.put((LabelNode)cur, new LabelNode(new Label()));
cur = cur.getNext();
}
// Then code is cloned and uses cloned labels
cur = start;
while(!cur.equals(min))
{
AbstractInsnNode clone = cur.clone(labels);
mnode.instructions.add(clone);
cur = cur.getNext();
}
mnode.instructions.add(cur.clone(labels));
mnode.visitInsn(Opcodes.RETURN);
cn.methods.add(mnode);
}
begin = null;
}
}
// Move init code to separate method for being called after injections.
if(foundcon!=-1 && foundcon+1foundcon+1)
{
AbstractInsnNode node = l.get(foundcon+1);
if(ophelper.isReturn(node.getOpcode()))
{
break;
}
l.remove(node);
wrappedMNode.instructions.add(node);
}
mnode.visitInsn(Opcodes.RETURN);
// Add code to store arguments in field.
Type[] args = Type.getArgumentTypes(mn.desc);
InsnList init = new InsnList();
// obj param
init.add(new VarInsnNode(Opcodes.ALOAD, 0));
// clazz param
init.add(new LdcInsnNode(Type.getType("L"+iclname+";")));
// argtypes param
init.add(new LdcInsnNode(args.length));
init.add(new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Class"));
for(int i=0; i belnames = new ArrayList();
List paramnames = new ArrayList();
MGoal mgoal = model.getCapability().getGoal(iclname.replaceAll("/", "."));
for(int i=0; inull
, if the class is not valid, such as Map.entry "inner Classes".
*/
public Class> toClass(String name, byte[] data, ClassLoader loader, ProtectionDomain domain)
{
Class> ret = null;
try
{
Method method;
Object[] args;
if(domain == null)
{
method = methoddc1;
args = new Object[]{name, data, Integer.valueOf(0), Integer.valueOf(data.length)};
}
else
{
method = methoddc2;
args = new Object[]{name, data, Integer.valueOf(0), Integer.valueOf(data.length), domain};
}
method.setAccessible(true);
try
{
ret = (Class>)method.invoke(loader, args);
}
catch(InvocationTargetException e)
{
if(e.getTargetException() instanceof LinkageError)
{
// e.printStackTrace();
// when same class was already loaded via other filename wrong cache miss:-(
// ret = SReflect.findClass(name, null, loader);
ret = Class.forName(name, true, loader);
}
else
{
throw e.getTargetException();
}
}
finally
{
method.setAccessible(false);
}
}
catch(Throwable e)
{
if(e instanceof Error)
{
throw (Error)e;
}
else if(e instanceof RuntimeException)
{
throw (RuntimeException)e;
}
else
{
throw new RuntimeException(e);
}
}
return ret;
}
/**
* Find beliefs accessed in methods.
*/
protected Set findBeliefs(ClassNode cn, MethodNode mn, BDIModel model, Map others)
{
Set ret = new HashSet();
InsnList l = mn.instructions;
String refob = null;
for(int i=0; i fns = cn.fields;
for(FieldNode fn: fns)
{
if(fn.name.equals(refob))
{
Type t = Type.getType(fn.desc);
// search the class (node) this$ refers to
ClassNode ocl = others.get(t.getClassName());
if(ocl!=null)
{
// search the access$ method on that class
List mnodes = ocl.methods;
for(MethodNode mnode: mnodes)
{
// add dependencies of that access$ method
if(mnode.name.equals(((MethodInsnNode)node).name))
{
ret.addAll(findBeliefs(ocl, mnode, model, others));
break;
}
}
}
break;
}
}
}
}
// System.out.println("Found belief accesses: "+cn.name+" "+ret+" in "+mn.name);
return ret;
}
/**
* Find parameters accessed in methods.
*/
protected Set findParameters(ClassNode cn, MethodNode mn, BDIModel model, Map others, MGoal mgoal)
{
Set ret = new HashSet();
InsnList l = mn.instructions;
String refob = null;
for(int i=0; i fns = cn.fields;
for(FieldNode fn: fns)
{
if(fn.name.equals(refob))
{
Type t = Type.getType(fn.desc);
// search the class (node) this$ refers to
ClassNode ocl = others.get(t.getClassName());
if(ocl!=null)
{
// search the access$ method on that class
List mnodes = ocl.methods;
for(MethodNode mnode: mnodes)
{
// add dependencies of that access$ method
if(mnode.name.equals(((MethodInsnNode)node).name))
{
ret.addAll(findParameters(ocl, mnode, model, others, mgoal));
break;
}
}
}
break;
}
}
}
}
// System.out.println("Found belief accesses: "+cn.name+" "+ret+" in "+mn.name);
return ret;
}
// /**
// * Find parameters accessed in methods.
// */
// protected Map> findParameters(ClassNode cn, MethodNode mn, BDIModel model, Map others)
// {
// Map> ret = new HashMap>();
//
// InsnList l = mn.instructions;
// String refob = null;
//
// for(int i=0; i fns = cn.fields;
// for(FieldNode fn: fns)
// {
// if(fn.name.equals(refob))
// {
// Type t = Type.getType(fn.desc);
//
// // search the class (node) this$ refers to
// ClassNode ocl = others.get(t.getClassName());
// if(ocl!=null)
// {
// // search the access$ method on that class
// List mnodes = ocl.methods;
// for(MethodNode mnode: mnodes)
// {
// // add dependencies of that access$ method
// if(mnode.name.equals(((MethodInsnNode)node).name))
// {
// ret.putAll(findParameters(ocl, mnode, model, others));
// break;
// }
// }
// }
// break;
// }
// }
// }
// }
//
//// System.out.println("Found belief accesses: "+cn.name+" "+ret+" in "+mn.name);
//
// return ret;
// }
// /**
// *
// * @param model
// */
// protected void addParameters(BDIModel model, String name, Map> res)
// {
// List mgoals = model.getCapability().getGoals();
//
// if(mgoals!=null)
// {
// for(MGoal mgoal: mgoals)
// {
// String param = mgoal.hasParameterIgnoreCase(name);
// if(param!=null)
// {
// Set params = res.get(mgoal);
// if(params==null)
// {
// params = new HashSet();
// res.put(mgoal, params);
// }
// params.add(param);
// }
// }
// }
// }
/**
*
*/
public static void main(String[] args) throws Exception
{
// System.out.println(int.class.getName());
// Method m = SReflect.getMethods(BDIAgent.class, "writeArrayField")[0];
// Method[] ms = SReflect.getMethods(SReflect.class, "wrapValue");
// for(Method m: ms)
// {
// System.out.println(m.toString()+" "+Type.getMethodDescriptor(m));
// }
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES);
// TraceClassVisitor tcv = new TraceClassVisitor(cw, new PrintWriter(System.out));
TraceClassVisitor tcv = new TraceClassVisitor(cw, new ASMifier(), new PrintWriter(System.out));
// CheckClassAdapter cc = new CheckClassAdapter(tcv);
// final String classname = "lars/Lars";
// final String supername = "jadex/bdiv3/MyTestClass";
// final ASMifier asm = new ASMifier();
ClassVisitor cv = new ClassVisitor(Opcodes.ASM4, tcv)
{
// public void visit(int version, int access, String name,
// String signature, String superName, String[] interfaces)
// {
// super.visit(version, access, classname, null, superName, interfaces);
// }
public MethodVisitor visitMethod(int access, final String methodname, String desc, String signature, String[] exceptions)
{
return new MethodVisitor(api, super.visitMethod(access, methodname, desc, signature, exceptions))
{
// public void visitFieldInsn(int opcode, String owner, String name, String desc)
// {
// super.visitFieldInsn(opcode, owner, methodname, desc);
// }
public void visitInsn(int opcode)
{
super.visitInsn(opcode);
}
};
// return super.visitMethod(access, methodname, desc, signature, exceptions);
//
// System.out.println("visit method: "+methodname);
// if("".equals(methodname))
// {
// return new TraceMethodVisitor(super.visitMethod(access, methodname, desc, signature, exceptions), asm);
// }
// else
// {
// return super.visitMethod(access, methodname, desc, signature, exceptions);
// }
}
};
ClassReader cr = new ClassReader("jadex.bdiv3.MyTestClass");
cr.accept(cv, 0);
// ClassNode cn = new ClassNode();
// cr.accept(cn, 0);
//
// String prefix = "__update";
// Set todo = new HashSet();
// todo.add("testfield");
// todo.add("testfield2");
// todo.add("testfield3");
//
// MethodNode[] mths = cn.methods.toArray(new MethodNode[0]);
// for(MethodNode mn: mths)
// {
// System.out.println(mn.name);
// if(mn.name.equals(""))
// {
// InsnList l = cn.methods.get(0).instructions;
// for(int i=0; i labels = new HashMap();
// while(!start.equals(fn))
// {
// AbstractInsnNode clone;
// if(start instanceof LabelNode)
// {
// clone = new LabelNode(new Label());
// labels.put((LabelNode)start, (LabelNode)clone);
// }
// else
// {
// clone = start.clone(labels);
// }
// mnode.instructions.add(clone);
// start = start.getNext();
// }
// mnode.instructions.add(start.clone(labels));
// mnode.visitInsn(Opcodes.RETURN);
//
// cn.methods.add(mnode);
// }
// }
// else
// {
// System.out.println(n);
// }
// }
// }
// }
// cn.name = classname;
// System.out.println("cn: "+cn);
// System.out.println(asm.getText());
// ClassWriter cw = new ClassWriter(0);
// cw.accept(tcv);
// byte[] data = cw.toByteArray();
// ByteClassLoader bcl = new ByteClassLoader(ASMBDIClassGenerator.class.getClassLoader());
// Class> cl = toClass("jadex.bdiv3.MyTestClass", data, new URLClassLoader(new URL[0], ASMBDIClassGenerator.class.getClassLoader()), null);
//// Class> cl = bcl.loadClass("lars.Lars", cw.toByteArray(), true);
// Object o = cl.newInstance();
//// System.out.println("o: "+o);
//// Object v = cl.getMethod("getVal", new Class[0]).invoke(o, new Object[0]);
// String mn = prefix+SUtil.firstToUpperCase("testfield");
// Object v = cl.getMethod(mn, new Class[0]).invoke(o, new Object[0]);
// cl.getMethod(mn, new Class[0]).invoke(o, new Object[0]);
// cl.getMethod(mn, new Class[0]).invoke(o, new Object[0]);
// System.out.println("res: "+cl.getDeclaredField("testfield").get(o));
// System.out.println(SUtil.arrayToString(cl.getDeclaredMethods()));
// System.out.println(cl);
// Constructor> c = cl.getConstructor(new Class[0]);
// c.setAccessible(true);
// c.newInstance(new Object[0]);
// Method m = cl.getMethod("main", new Class[]{String[].class});
// m.setAccessible(true);
// m.invoke(null, new Object[]{new String[0]});
}
}