private void build_boilerplate(ClassWriter cw) { String classname = "SVDBPersistenceDelegate"; String full_classname = transform_cls(fTargetPkg) + "/" + classname; cw.visit( Opcodes.V1_5, ACC_PROTECTED + ACC_PUBLIC + ACC_SUPER, full_classname, null, fBaseClass, null); cw.visitSource(classname + ".java", null); MethodVisitor mv; // Constructor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, fBaseClass, "<init>", "()V"); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); buildItemDispatchMethods(cw); buildObjectDispatchMethods(cw); }
public void startScript(StaticScope scope) { classWriter = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); // Create the class with the appropriate class name and source file classWriter.visit( javaVersion == null ? RubyInstanceConfig.JAVA_VERSION : javaVersion, ACC_PUBLIC + ACC_SUPER, getClassname(), null, p(AbstractScript.class), null); // add setPosition impl, which stores filename as constant to speed updates SkinnyMethodAdapter method = new SkinnyMethodAdapter( getClassVisitor(), ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, "setPosition", sig(Void.TYPE, params(ThreadContext.class, int.class)), null, null); method.start(); method.aload(0); // thread context method.ldc(sourcename); method.iload(1); // line number method.invokevirtual( p(ThreadContext.class), "setFileAndLine", sig(void.class, String.class, int.class)); method.voidreturn(); method.end(); topLevelScope = scope; beginInit(); cacheCompiler = OptoFactory.newCacheCompiler(this); // This code was originally used to provide debugging info using JSR-45 // "SMAP" format. However, it breaks using normal Java traces to // generate Ruby traces, since the original path is lost. Reverting // to full path for now. // String sourceNoPath; // if (sourcename.indexOf("/") >= 0) { // String[] pathElements = sourcename.split("/"); // sourceNoPath = pathElements[pathElements.length - 1]; // } else if (sourcename.indexOf("\\") >= 0) { // String[] pathElements = sourcename.split("\\\\"); // sourceNoPath = pathElements[pathElements.length - 1]; // } else { // sourceNoPath = sourcename; // } final File sourceFile = new File(getSourcename()); // Revert to using original sourcename here, so that jitted traces match // interpreted traces. classWriter.visitSource(sourcename, sourceFile.getAbsolutePath()); }
public Class<?> createWrapper(Method callback) { ClassWriter cw = new ClassWriter(0); MethodVisitor mv; String name = getUniqueName(callback); String desc = name.replace('.', '/'); String instType = Type.getInternalName(callback.getDeclaringClass()); String eventType = Type.getInternalName(callback.getParameterTypes()[0]); /* System.out.println("Name: " + name); System.out.println("Desc: " + desc); System.out.println("InstType: " + instType); System.out.println("Callback: " + callback.getName() + Type.getMethodDescriptor(callback)); System.out.println("Event: " + eventType); */ cw.visit( V1_6, ACC_PUBLIC | ACC_SUPER, desc, null, "java/lang/Object", new String[] {HANDLER_DESC}); cw.visitSource(".dynamic", null); { cw.visitField(ACC_PUBLIC, "instance", "Ljava/lang/Object;", null, null).visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/Object;)V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, desc, "instance", "Ljava/lang/Object;"); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC, "invoke", HANDLER_FUNC_DESC, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, desc, "instance", "Ljava/lang/Object;"); mv.visitTypeInsn(CHECKCAST, instType); mv.visitVarInsn(ALOAD, 1); mv.visitTypeInsn(CHECKCAST, eventType); mv.visitMethodInsn( INVOKEVIRTUAL, instType, callback.getName(), Type.getMethodDescriptor(callback)); mv.visitInsn(RETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } cw.visitEnd(); return LOADER.define(name, cw.toByteArray()); }
protected static ClassWriter createClassWriter(String internalName, AccessorType accessorType) { ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); classWriter.visit( V1_6, ACC_PUBLIC + ACC_SUPER, internalName, null, "java/lang/Object", new String[] {getInternalName(accessorType.getAccessorType().getName())}); classWriter.visitSource(getExternalName(internalName), null); return classWriter; }
public static byte[] dump() throws Exception { ClassWriter cw = new ClassWriter(0); MethodVisitor mv; cw.visit(52, ACC_PUBLIC + ACC_SUPER, "DummyBundleClass", null, "java/lang/Object", null); cw.visitSource("DummyBundleClass.java", null); { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitLineNumber(1, l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitInsn(RETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", "LDummyBundleClass;", null, l0, l1, 0); mv.visitMaxs(1, 1); mv.visitEnd(); } { mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitLineNumber(4, l0); mv.visitInsn(RETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("args", "[Ljava/lang/String;", null, l0, l1, 0); mv.visitMaxs(0, 1); mv.visitEnd(); } cw.visitEnd(); return cw.toByteArray(); }
private static byte[] compileBytes( Rule rule, Class helperClass, String helperName, String compiledHelperName, boolean compileToBytecode) throws Exception { ClassWriter cw = new ClassWriter(0); FieldVisitor fv; MethodVisitor mv; AnnotationVisitor av0; // create the class as a subclass of the rule helper class, appending Compiled to the front // of the class name and a unique number to the end of the class helperName // also ensure it implements the HelperAdapter interface // // public class foo.bar.Compiled_<helper>_<NNN> extends foo.bar.<helper> implements // HelperAdapter cw.visit( V1_5, ACC_PUBLIC + ACC_SUPER, compiledHelperName, null, helperName, new String[] {"org/jboss/byteman/rule/helper/HelperAdapter"}); // we need to install the source file name { String fullFileName = rule.getFile(); int idx = fullFileName.lastIndexOf(java.io.File.separatorChar); String basicFileName = (idx < 0 ? fullFileName : fullFileName.substring(idx + 1)); String debug = "// compiled from: " + fullFileName + "\n// generated by Byteman\n"; cw.visitSource(basicFileName, debug); } { // we need a Hashmap field to hold the bindings // // private HashMap<String, Object> bindingMap; fv = cw.visitField( ACC_PRIVATE, "bindingMap", "Ljava/util/HashMap;", "Ljava/util/HashMap<Ljava/lang/String;Ljava/lang/Object;>;", null); fv.visitEnd(); } { // and a rule field to hold the rule // // private Rule rule; fv = cw.visitField( ACC_PRIVATE, "rule", "Lorg/jboss/byteman/rule/Rule;", "Lorg/jboss/byteman/rule/Rule;", null); fv.visitEnd(); } { // we need a constructor which takes a Rule as argument // if the helper implements a constructor which takes a Rule as argument then we invoke it // otherwise we invoke the empty helper constructor Constructor superConstructor = null; try { superConstructor = helperClass.getDeclaredConstructor(Rule.class); } catch (NoSuchMethodException e) { // hmm, ok see if there is an empty constructor } catch (SecurityException e) { throw new CompileException( "Compiler.compileBytes : unable to access constructor for helper class " + helperClass.getCanonicalName()); } boolean superWantsRule = (superConstructor != null); if (!superWantsRule) { try { superConstructor = helperClass.getDeclaredConstructor(); } catch (NoSuchMethodException e) { throw new CompileException( "Compiler.compileBytes : no valid constructor found for helper class " + helperClass.getCanonicalName()); } catch (SecurityException e) { throw new CompileException( "Compiler.compileBytes : unable to access constructor for helper class " + helperClass.getCanonicalName()); } } // // public Compiled<helper>_<NNN>()Rule rule) mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Lorg/jboss/byteman/rule/Rule;)V", null, null); mv.visitCode(); // super(); // // or // // super(Rule); if (superWantsRule) { mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn(INVOKESPECIAL, helperName, "<init>", "(Lorg/jboss/byteman/rule/Rule;)V"); } else { mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, helperName, "<init>", "()V"); } // bindingMap = new HashMap<String, Object); mv.visitVarInsn(ALOAD, 0); mv.visitTypeInsn(NEW, "java/util/HashMap"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/util/HashMap", "<init>", "()V"); mv.visitFieldInsn(PUTFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); // this.rule = rule mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); // return; mv.visitInsn(RETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } { // create the execute method // // public void execute(Bindings bindings, Object recipient, Object[] args) throws // ExecuteException mv = cw.visitMethod( ACC_PUBLIC, "execute", "(Ljava/lang/Object;[Ljava/lang/Object;)V", null, new String[] {"org/jboss/byteman/rule/exception/ExecuteException"}); mv.visitCode(); // if (Transformer.isVerbose()) mv.visitMethodInsn(INVOKESTATIC, "org/jboss/byteman/agent/Transformer", "isVerbose", "()Z"); Label l0 = new Label(); mv.visitJumpInsn(IFEQ, l0); // then // System.out.println(rule.getName() + " execute"); mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"); mv.visitTypeInsn(NEW, "java/lang/StringBuilder"); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V"); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getName", "()Ljava/lang/String;"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); mv.visitLdcInsn(" execute()"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;"); mv.visitMethodInsn( INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V"); // end if mv.visitLabel(l0); Bindings bindings = rule.getBindings(); Iterator<Binding> iterator = bindings.iterator(); while (iterator.hasNext()) { Binding binding = iterator.next(); String name = binding.getName(); if (binding.isAlias()) { // lookups and updates will use the aliased name continue; } if (binding.isHelper()) { // bindingMap.put(name, this); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); mv.visitLdcInsn(name); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); } else if (binding.isRecipient()) { // bindingMap.put(name, recipient); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); mv.visitLdcInsn(name); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); // } else if (binding.isParam() || binding.isLocalVar() || binding.isReturn() || // binding.isThrowable() || binding.isParamCount() || binding.isParamArray()) // { } else if (!binding.isBindVar()) { // bindingMap.put(name, args[binding.getCallArrayIndex()]); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); mv.visitLdcInsn(name); mv.visitVarInsn(ALOAD, 2); mv.visitLdcInsn(binding.getCallArrayIndex()); mv.visitInsn(AALOAD); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); } } // execute0() mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, compiledHelperName, "execute0", "()V"); // now restore update bindings iterator = bindings.iterator(); while (iterator.hasNext()) { Binding binding = iterator.next(); if (binding.isAlias()) { continue; } String name = binding.getName(); if (binding.isUpdated()) { // if (binding.isParam() || binding.isLocalVar() || binding.isReturn()) { if (!binding.isBindVar()) { int idx = binding.getCallArrayIndex(); // Object value = bindingMap.get(name); // args[idx] = value; mv.visitVarInsn(ALOAD, 2); // args mv.visitLdcInsn(idx); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); mv.visitLdcInsn(name); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/HashMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(AASTORE); } } } // return mv.visitInsn(RETURN); mv.visitMaxs(4, 3); mv.visitEnd(); } { // create the setBinding method // // public void setBinding(String name, Object value) mv = cw.visitMethod( ACC_PUBLIC, "setBinding", "(Ljava/lang/String;Ljava/lang/Object;)V", null, null); mv.visitCode(); // bindingMap.put(name, value); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/HashMap", "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(POP); // return mv.visitInsn(RETURN); mv.visitMaxs(3, 3); mv.visitEnd(); } { // create the getBinding method // // public Object getBinding(String name) mv = cw.visitMethod( ACC_PUBLIC, "getBinding", "(Ljava/lang/String;)Ljava/lang/Object;", null, null); mv.visitCode(); // {TOS} <== bindingMap.get(name); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "bindingMap", "Ljava/util/HashMap;"); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKEVIRTUAL, "java/util/HashMap", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); // return {TOS} mv.visitInsn(ARETURN); mv.visitMaxs(2, 2); mv.visitEnd(); } { // create the getName method // // public String getName() mv = cw.visitMethod(ACC_PUBLIC, "getName", "()Ljava/lang/String;", null, null); mv.visitCode(); // {TOS} <== rule.getName() mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getName", "()Ljava/lang/String;"); // return {TOS} mv.visitInsn(ARETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } // create the getAccessibleField method // // public Object getAccessibleField(Object owner, int fieldIndex) { mv = cw.visitMethod( ACC_PUBLIC, "getAccessibleField", "(Ljava/lang/Object;I)Ljava/lang/Object;", null, null); mv.visitCode(); // {TOS} <== rule.getAccessibleField(owner, fieldIndex); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ILOAD, 2); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getAccessibleField", "(Ljava/lang/Object;I)Ljava/lang/Object;"); // return {TOS} mv.visitInsn(ARETURN); mv.visitMaxs(3, 3); mv.visitEnd(); } // create the setAccessibleField method // // public void setAccessibleField(Object owner, Object value, int fieldIndex) // rule.setAccessibleField(owner, value, fieldIndex); { mv = cw.visitMethod( ACC_PUBLIC, "setAccessibleField", "(Ljava/lang/Object;Ljava/lang/Object;I)V", null, null); mv.visitCode(); // rule.setAccessibleField(owner, value, fieldIndex); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "setAccessibleField", "(Ljava/lang/Object;Ljava/lang/Object;I)V"); // return mv.visitInsn(RETURN); mv.visitMaxs(4, 4); mv.visitEnd(); } // create the invokeAccessibleMethod method // // public Object invokeAccessibleMethod(Object target, Object[] args, int methodIndex) // {TOS} <== rule.invokeAccessibleMethod(target, args, methodIndex); { mv = cw.visitMethod( ACC_PUBLIC, "invokeAccessibleMethod", "(Ljava/lang/Object;[Ljava/lang/Object;I)Ljava/lang/Object;", null, null); mv.visitCode(); // rule.invokeAccessibleMethod(target, args, fieldIndex); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "invokeAccessibleMethod", "(Ljava/lang/Object;[Ljava/lang/Object;I)Ljava/lang/Object;"); // return {TOS} mv.visitInsn(ARETURN); mv.visitMaxs(4, 4); mv.visitEnd(); } if (compileToBytecode) { // we generate a single execute0 method if we want to run compiled and get // the event, condiiton and action to insert the relevant bytecode to implement // bind(), test() and fire() { // create the execute0() method // // private void execute0() mv = cw.visitMethod( ACC_PRIVATE, "execute0", "()V", null, new String[] {"org/jboss/byteman/rule/exception/ExecuteException"}); mv.visitCode(); CompileContext compileContext = new CompileContext(mv); // make sure we set the first line number before generating any code compileContext.notifySourceLine(rule.getLine()); compileContext.addLocalCount(3); // for this and 2 object args // bind(); rule.getEvent().compile(mv, compileContext); // if (test()) rule.getCondition().compile(mv, compileContext); Label l0 = new Label(); mv.visitJumpInsn(IFEQ, l0); compileContext.addStackCount(-1); // then rule.getAction().compile(mv, compileContext); // fire(); // end if mv.visitLabel(l0); // this will match the ENDRULE line compileContext.notifySourceEnd(); // return mv.visitInsn(RETURN); // need to specify correct Maxs values mv.visitMaxs(compileContext.getStackMax(), compileContext.getLocalMax()); mv.visitEnd(); } } else { // we generate the following methods if we want to run interpreted { // create the execute0() method // // private void execute0() mv = cw.visitMethod( ACC_PRIVATE, "execute0", "()V", null, new String[] {"org/jboss/byteman/rule/exception/ExecuteException"}); mv.visitCode(); // bind(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, compiledHelperName, "bind", "()V"); // if (test()) mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, compiledHelperName, "test", "()Z"); Label l0 = new Label(); mv.visitJumpInsn(IFEQ, l0); // then // fire(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, compiledHelperName, "fire", "()V"); // end if mv.visitLabel(l0); // return mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } { // create the bind method // // private void bind() mv = cw.visitMethod( ACC_PRIVATE, "bind", "()V", null, new String[] {"org/jboss/byteman/rule/exception/ExecuteException"}); mv.visitCode(); // rule.getEvent().interpret(this); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getEvent", "()Lorg/jboss/byteman/rule/Event;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Event", "interpret", "(Lorg/jboss/byteman/rule/helper/HelperAdapter;)Ljava/lang/Object;"); mv.visitInsn(RETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } { // create the test method // // private boolean test() mv = cw.visitMethod( ACC_PRIVATE, "test", "()Z", null, new String[] {"org/jboss/byteman/rule/exception/ExecuteException"}); mv.visitCode(); // {TOS} <== rule.getCondition().interpret(this); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getCondition", "()Lorg/jboss/byteman/rule/Condition;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Condition", "interpret", "(Lorg/jboss/byteman/rule/helper/HelperAdapter;)Ljava/lang/Object;"); mv.visitTypeInsn(Opcodes.CHECKCAST, "java/lang/Boolean"); // unbox the returned Boolean mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z"); // return {TOS} mv.visitInsn(IRETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } { // create the fire method // // private void fire() mv = cw.visitMethod( ACC_PRIVATE, "fire", "()V", null, new String[] {"org/jboss/byteman/rule/exception/ExecuteException"}); mv.visitCode(); // rule.getAction().interpret(this); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, compiledHelperName, "rule", "Lorg/jboss/byteman/rule/Rule;"); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Rule", "getAction", "()Lorg/jboss/byteman/rule/Action;"); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEVIRTUAL, "org/jboss/byteman/rule/Action", "interpret", "(Lorg/jboss/byteman/rule/helper/HelperAdapter;)Ljava/lang/Object;"); // return mv.visitInsn(RETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } } cw.visitEnd(); return cw.toByteArray(); }
@Override public Object visitProgram(Program program, Object arg) throws Exception { className = program.JVMName; classDescriptor = 'L' + className + ';'; cw.visit( 52, // version ACC_PUBLIC + ACC_SUPER, // access codes className, // fully qualified classname null, // signature "java/lang/Object", // superclass new String[] {"cop5555sp15/Codelet"} // implemented interfaces ); cw.visitSource(null, null); // maybe replace first argument with source // file name // create init method { MethodVisitor mv; mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitLineNumber(3, l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitInsn(RETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitLocalVariable("this", classDescriptor, null, l0, l1, 0); mv.visitMaxs(1, 1); mv.visitEnd(); } // generate the execute method MethodVisitor mv = cw.visitMethod( ACC_PUBLIC, "execute", // name of top // level // method "()V", // descriptor: this method is parameterless with no // return value null, // signature. This is null for us, it has to do with generic types null // array of strings containing exceptions ); mv.visitCode(); Label lbeg = new Label(); mv.visitLabel(lbeg); mv.visitLineNumber(program.firstToken.lineNumber, lbeg); program.block.visit(this, new InheritedAttributes(mv)); mv.visitInsn(RETURN); Label lend = new Label(); mv.visitLabel(lend); mv.visitLocalVariable("this", classDescriptor, null, lbeg, lend, 0); mv.visitMaxs(0, 0); // this is required just before the end of a method. // It causes asm to calculate information about the // stack usage of this method. mv.visitEnd(); cw.visitEnd(); return cw.toByteArray(); }