/** * ensure last marked parameter on the stack is a primitive boolean if mark==stack size, we assume * an empty expression or statement. was used and we will use the value given in emptyDefault as * boolean if mark==stack.size()-1 the top element will be cast to boolean using Groovy truth. In * other cases we throw a GroovyBugError */ public void castToBool(int mark, boolean emptyDefault) { int size = stack.size(); MethodVisitor mv = controller.getMethodVisitor(); if (mark == size) { // no element, so use emptyDefault if (emptyDefault) { mv.visitIntInsn(BIPUSH, 1); } else { mv.visitIntInsn(BIPUSH, 0); } stack.add(null); } else if (mark == stack.size() - 1) { ClassNode last = stack.get(size - 1); // nothing to do in that case if (last == ClassHelper.boolean_TYPE) return; // not a primitive type, so call booleanUnbox if (!ClassHelper.isPrimitiveType(last)) { controller.getInvocationWriter().castNonPrimitiveToBool(last); } else { primitive2b(mv, last); } } else { throw new GroovyBugError( "operand stack contains " + stack.size() + " elements, but we expected only " + mark); } stack.set(mark, ClassHelper.boolean_TYPE); }
public static void pushConstant(MethodVisitor mv, int value) { switch (value) { case 0: mv.visitInsn(ICONST_0); break; case 1: mv.visitInsn(ICONST_1); break; case 2: mv.visitInsn(ICONST_2); break; case 3: mv.visitInsn(ICONST_3); break; case 4: mv.visitInsn(ICONST_4); break; case 5: mv.visitInsn(ICONST_5); break; default: if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { mv.visitIntInsn(BIPUSH, value); } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) { mv.visitIntInsn(SIPUSH, value); } else { mv.visitLdcInsn(Integer.valueOf(value)); } } }
private void initializeDelegateObject(final MethodVisitor mv, int argStart) { int idx = argStart + 1; mv.visitIntInsn(ALOAD, 0); // this mv.visitIntInsn(ALOAD, idx); // constructor arg n is the closure map mv.visitFieldInsn( PUTFIELD, proxyName, DELEGATE_OBJECT_FIELD, BytecodeHelper.getTypeDescription(delegateClass)); }
/** Generate a call to the delegate object. */ protected MethodVisitor makeDelegateCall( final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags) { MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions); mv.visitVarInsn(ALOAD, 0); // load this mv.visitFieldInsn( GETFIELD, proxyName, DELEGATE_OBJECT_FIELD, BytecodeHelper.getTypeDescription(delegateClass)); // load delegate // using InvokerHelper to allow potential intercepted calls int size; mv.visitLdcInsn(name); // method name Type[] args = Type.getArgumentTypes(desc); BytecodeHelper.pushConstant(mv, args.length); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); size = 3; int idx = 1; for (int i = 0; i < args.length; i++) { Type arg = args[i]; mv.visitInsn(DUP); BytecodeHelper.pushConstant(mv, i); // primitive types must be boxed if (isPrimitive(arg)) { mv.visitIntInsn(getLoadInsn(arg), idx); String wrappedType = getWrappedClassDescriptor(arg); mv.visitMethodInsn( INVOKESTATIC, wrappedType, "valueOf", "(" + arg.getDescriptor() + ")L" + wrappedType + ";"); } else { mv.visitVarInsn(ALOAD, idx); // load argument i } size = Math.max(6, 5 + registerLen(arg)); idx += registerLen(arg); mv.visitInsn(AASTORE); // store value into array } mv.visitMethodInsn( INVOKESTATIC, "org/codehaus/groovy/runtime/InvokerHelper", "invokeMethod", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;"); unwrapResult(mv, desc); mv.visitMaxs(size, registerLen(args) + 1); return EMPTY_VISITOR; }
/** Generates the bytecode that pushes the given value onto the stack */ public void pushInt(int aValue) { switch (aValue) { case -1: itsVisitor.visitInsn(Opcodes.ICONST_M1); return; case 0: itsVisitor.visitInsn(Opcodes.ICONST_0); return; case 1: itsVisitor.visitInsn(Opcodes.ICONST_1); return; case 2: itsVisitor.visitInsn(Opcodes.ICONST_2); return; case 3: itsVisitor.visitInsn(Opcodes.ICONST_3); return; case 4: itsVisitor.visitInsn(Opcodes.ICONST_4); return; case 5: itsVisitor.visitInsn(Opcodes.ICONST_5); return; } if (aValue >= Byte.MIN_VALUE && aValue <= Byte.MAX_VALUE) itsVisitor.visitIntInsn(Opcodes.BIPUSH, aValue); else if (aValue >= Short.MIN_VALUE && aValue <= Short.MAX_VALUE) itsVisitor.visitIntInsn(Opcodes.SIPUSH, aValue); else itsVisitor.visitLdcInsn(new Integer(aValue)); }
private MethodVisitor createConstructor( final int access, final String name, final String desc, final String signature, final String[] exceptions) { Type[] args = Type.getArgumentTypes(desc); StringBuilder newDesc = new StringBuilder("("); for (Type arg : args) { newDesc.append(arg.getDescriptor()); } newDesc.append("Ljava/util/Map;"); // the closure map if (generateDelegateField) { newDesc.append(BytecodeHelper.getTypeDescription(delegateClass)); } newDesc.append(")V"); MethodVisitor mv = super.visitMethod(access, name, newDesc.toString(), signature, exceptions); mv.visitCode(); initializeDelegateClosure(mv, args.length); if (generateDelegateField) { initializeDelegateObject(mv, args.length + 1); } mv.visitVarInsn(ALOAD, 0); int idx = 1; for (Type arg : args) { if (isPrimitive(arg)) { mv.visitIntInsn(getLoadInsn(arg), idx); } else { mv.visitVarInsn(ALOAD, idx); // load argument i } idx += registerLen(arg); } mv.visitMethodInsn( INVOKESPECIAL, BytecodeHelper.getClassInternalName(superClass), "<init>", desc); mv.visitInsn(RETURN); int max = idx + 1 + (generateDelegateField ? 1 : 0); mv.visitMaxs(max, max); mv.visitEnd(); return EMPTY_VISITOR; }
@Override public void visitIntInsn(final int opcode, final int operand) { checkStartCode(); checkEndCode(); checkOpcode(opcode, 1); switch (opcode) { case Opcodes.BIPUSH: checkSignedByte(operand, "Invalid operand"); break; case Opcodes.SIPUSH: checkSignedShort(operand, "Invalid operand"); break; // case Constants.NEWARRAY: default: if (operand < Opcodes.T_BOOLEAN || operand > Opcodes.T_LONG) { throw new IllegalArgumentException( "Invalid operand (must be an array type code T_...): " + operand); } } super.visitIntInsn(opcode, operand); ++insnCount; }
private void initializeDelegateClosure(final MethodVisitor mv, int argStart) { int idx = argStart + 1; mv.visitIntInsn(ALOAD, 0); // this mv.visitIntInsn(ALOAD, idx); // constructor arg n is the closure map mv.visitFieldInsn(PUTFIELD, proxyName, CLOSURES_MAP_FIELD, "Ljava/util/Map;"); }
/** * When an object doesn't implement the GroovyObject interface, we generate bytecode for the * {@link GroovyObject} interface methods. Otherwise, the superclass is expected to implement * them. */ private void createGroovyObjectSupport() { visitField(ACC_PRIVATE + ACC_TRANSIENT, "metaClass", "Lgroovy/lang/MetaClass;", null, null); // getMetaClass MethodVisitor mv; { mv = super.visitMethod(ACC_PUBLIC, "getMetaClass", "()Lgroovy/lang/MetaClass;", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, proxyName, "metaClass", "Lgroovy/lang/MetaClass;"); Label l1 = new Label(); mv.visitJumpInsn(IFNONNULL, l1); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;"); mv.visitMethodInsn( INVOKESTATIC, "org/codehaus/groovy/runtime/InvokerHelper", "getMetaClass", "(Ljava/lang/Class;)Lgroovy/lang/MetaClass;"); mv.visitFieldInsn(PUTFIELD, proxyName, "metaClass", "Lgroovy/lang/MetaClass;"); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, proxyName, "metaClass", "Lgroovy/lang/MetaClass;"); mv.visitInsn(ARETURN); mv.visitMaxs(2, 1); mv.visitEnd(); } // getProperty { mv = super.visitMethod( ACC_PUBLIC, "getProperty", "(Ljava/lang/String;)Ljava/lang/Object;", null, null); mv.visitCode(); mv.visitIntInsn(ALOAD, 0); mv.visitMethodInsn( INVOKEINTERFACE, "groovy/lang/GroovyObject", "getMetaClass", "()Lgroovy/lang/MetaClass;"); mv.visitIntInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKEINTERFACE, "groovy/lang/MetaClass", "getProperty", "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;"); mv.visitInsn(ARETURN); mv.visitMaxs(3, 2); mv.visitEnd(); } // setProperty { mv = super.visitMethod( ACC_PUBLIC, "setProperty", "(Ljava/lang/String;Ljava/lang/Object;)V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, proxyName, "getMetaClass", "()Lgroovy/lang/MetaClass;"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn( INVOKEINTERFACE, "groovy/lang/MetaClass", "setProperty", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V"); Label l1 = new Label(); mv.visitLabel(l1); mv.visitInsn(RETURN); Label l2 = new Label(); mv.visitLabel(l2); mv.visitMaxs(4, 3); mv.visitEnd(); } // invokeMethod { mv = super.visitMethod( ACC_PUBLIC, "invokeMethod", "(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;", null, null); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKEVIRTUAL, proxyName, "getMetaClass", "()Lgroovy/lang/MetaClass;"); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn( INVOKEINTERFACE, "groovy/lang/MetaClass", "invokeMethod", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitInsn(ARETURN); Label l1 = new Label(); mv.visitLabel(l1); mv.visitMaxs(4, 3); mv.visitEnd(); } // setMetaClass { mv = super.visitMethod(ACC_PUBLIC, "setMetaClass", "(Lgroovy/lang/MetaClass;)V", null, null); mv.visitCode(); Label l0 = new Label(); mv.visitLabel(l0); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); mv.visitFieldInsn(PUTFIELD, proxyName, "metaClass", "Lgroovy/lang/MetaClass;"); Label l1 = new Label(); mv.visitLabel(l1); mv.visitInsn(RETURN); Label l2 = new Label(); mv.visitLabel(l2); mv.visitMaxs(2, 2); mv.visitEnd(); } }
public void visitIntInsn(int i, int i1) { System.out.println("visitIntInsn(" + opcodeAsString(i) + ", " + i1 + ")"); methodVisitor.visitIntInsn(i, i1); }
@Override public void compile(Type type, MethodVisitor mv, AsmDeserializerContext context) { mv.visitCode(); // if (flag == Types.NULL) { // return null; // } mv.visitVarInsn(ILOAD, 3); mv.visitInsn(ICONST_1); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l1); mv.visitInsn(ACONST_NULL); mv.visitInsn(ARETURN); mv.visitLabel(l1); mv.visitVarInsn(ILOAD, 3); mv.visitMethodInsn(INVOKESTATIC, "transfer/def/TransferConfig", "getType", "(B)B", false); mv.visitVarInsn(ISTORE, 5); mv.visitVarInsn(ILOAD, 5); mv.visitIntInsn(BIPUSH, Types.ENUM); Label l2 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l2); mv.visitTypeInsn(NEW, "transfer/exceptions/IllegalTypeException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 5); mv.visitIntInsn(BIPUSH, Types.ENUM); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn( INVOKESPECIAL, "transfer/exceptions/IllegalTypeException", "<init>", "(Ltransfer/core/DeserialContext;BBLjava/lang/reflect/Type;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(l2); Class<?> rawClass = TypeUtils.getRawClass(type); if (type == null || type == Object.class || type == Enum.class || rawClass.isInterface() || Modifier.isAbstract(rawClass.getModifiers()) && !rawClass.isArray()) { mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKESTATIC, "transfer/utils/BitUtils", "getInt", "(Ltransfer/Inputable;)I", false); mv.visitVarInsn(ISTORE, 6); mv.visitVarInsn(ILOAD, 6); mv.visitMethodInsn( INVOKESTATIC, "transfer/def/TransferConfig", "getClass", "(I)Ljava/lang/Class;", false); mv.visitVarInsn(ASTORE, 7); mv.visitVarInsn(ALOAD, 7); Label l12 = new Label(); mv.visitJumpInsn(IFNONNULL, l12); mv.visitTypeInsn(NEW, "transfer/exceptions/UnsupportDeserializerTypeException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn( INVOKESPECIAL, "transfer/exceptions/UnsupportDeserializerTypeException", "<init>", "(Ljava/lang/reflect/Type;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(l12); mv.visitVarInsn(ALOAD, 7); mv.visitMethodInsn( INVOKESTATIC, "transfer/def/TransferConfig", "getOrCreateClassInfo", "(Ljava/lang/Class;)Ltransfer/core/ClassInfo;", false); mv.visitTypeInsn(CHECKCAST, "transfer/core/EnumInfo"); mv.visitVarInsn(ASTORE, 8); mv.visitVarInsn(ALOAD, 8); Label l15 = new Label(); mv.visitJumpInsn(IFNONNULL, l15); mv.visitTypeInsn(NEW, "transfer/exceptions/UnsupportDeserializerTypeException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 7); mv.visitMethodInsn( INVOKESPECIAL, "transfer/exceptions/UnsupportDeserializerTypeException", "<init>", "(Ljava/lang/reflect/Type;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(l15); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ALOAD, 8); mv.visitMethodInsn(INVOKEVIRTUAL, "transfer/core/EnumInfo", "getClassId", "()I", false); Label l17 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l17); mv.visitTypeInsn(NEW, "transfer/exceptions/IllegalClassTypeException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn( INVOKESPECIAL, "transfer/exceptions/IllegalClassTypeException", "<init>", "(Ltransfer/core/DeserialContext;ILjava/lang/reflect/Type;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(l17); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKESTATIC, "transfer/utils/BitUtils", "getInt", "(Ltransfer/Inputable;)I", false); mv.visitVarInsn(ISTORE, 9); mv.visitVarInsn(ALOAD, 8); mv.visitVarInsn(ILOAD, 9); mv.visitMethodInsn( INVOKEVIRTUAL, "transfer/core/EnumInfo", "toEnum", "(I)Ljava/lang/Enum;", false); mv.visitInsn(ARETURN); mv.visitMaxs(5, 10); mv.visitEnd(); } else { mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKESTATIC, "transfer/utils/BitUtils", "getInt", "(Ltransfer/Inputable;)I", false); mv.visitVarInsn(ISTORE, 6); mv.visitLdcInsn( org.objectweb.asm.Type.getType("L" + AsmUtils.toAsmCls(rawClass.getName()) + ";")); mv.visitMethodInsn( INVOKESTATIC, "transfer/def/TransferConfig", "getOrCreateClassInfo", "(Ljava/lang/Class;)Ltransfer/core/ClassInfo;", false); mv.visitTypeInsn(CHECKCAST, "transfer/core/EnumInfo"); mv.visitVarInsn(ASTORE, 7); mv.visitVarInsn(ALOAD, 7); Label l15 = new Label(); mv.visitJumpInsn(IFNONNULL, l15); mv.visitTypeInsn(NEW, "transfer/exceptions/UnsupportDeserializerTypeException"); mv.visitInsn(DUP); mv.visitLdcInsn( org.objectweb.asm.Type.getType("L" + AsmUtils.toAsmCls(rawClass.getName()) + ";")); mv.visitMethodInsn( INVOKESPECIAL, "transfer/exceptions/UnsupportDeserializerTypeException", "<init>", "(Ljava/lang/reflect/Type;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(l15); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ALOAD, 7); mv.visitMethodInsn(INVOKEVIRTUAL, "transfer/core/EnumInfo", "getClassId", "()I", false); Label l17 = new Label(); mv.visitJumpInsn(IF_ICMPEQ, l17); mv.visitTypeInsn(NEW, "transfer/exceptions/IllegalClassTypeException"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 4); mv.visitVarInsn(ILOAD, 6); mv.visitVarInsn(ALOAD, 2); mv.visitMethodInsn( INVOKESPECIAL, "transfer/exceptions/IllegalClassTypeException", "<init>", "(Ltransfer/core/DeserialContext;ILjava/lang/reflect/Type;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(l17); mv.visitVarInsn(ALOAD, 1); mv.visitMethodInsn( INVOKESTATIC, "transfer/utils/BitUtils", "getInt", "(Ltransfer/Inputable;)I", false); mv.visitVarInsn(ISTORE, 8); mv.visitVarInsn(ALOAD, 7); mv.visitVarInsn(ILOAD, 8); mv.visitMethodInsn( INVOKEVIRTUAL, "transfer/core/EnumInfo", "toEnum", "(I)Ljava/lang/Enum;", false); mv.visitInsn(ARETURN); mv.visitMaxs(5, 10); mv.visitEnd(); } }
@Override public void visitIntInsn(int opcode, int operand) { mtd.addVariableOperation(opcode, operand); super.visitIntInsn(opcode, operand); }
@Override public void visitIntInsn(int opcode, int operand) { _touchBranch(); super.visitIntInsn(opcode, operand); }
private void pushPrimitiveConstant( final MethodVisitor mv, final Object value, final ClassNode type) { boolean isInt = ClassHelper.int_TYPE.equals(type); boolean isShort = ClassHelper.short_TYPE.equals(type); boolean isByte = ClassHelper.byte_TYPE.equals(type); if (isInt || isShort || isByte) { int val = isInt ? (Integer) value : isShort ? (Short) value : (Byte) value; switch (val) { case 0: mv.visitInsn(ICONST_0); break; case 1: mv.visitInsn(ICONST_1); break; case 2: mv.visitInsn(ICONST_2); break; case 3: mv.visitInsn(ICONST_3); break; case 4: mv.visitInsn(ICONST_4); break; case 5: mv.visitInsn(ICONST_5); break; default: if (val >= Byte.MIN_VALUE && val <= Byte.MAX_VALUE) { mv.visitIntInsn(BIPUSH, val); } else if (val >= Short.MIN_VALUE && val <= Short.MAX_VALUE) { mv.visitIntInsn(SIPUSH, val); } else { mv.visitLdcInsn(value); } } } else if (ClassHelper.long_TYPE.equals(type)) { if ((Long) value == 0L) { mv.visitInsn(LCONST_0); } else if ((Long) value == 1L) { mv.visitInsn(LCONST_1); } else { mv.visitLdcInsn(value); } } else if (ClassHelper.float_TYPE.equals(type)) { if ((Float) value == 0f) { mv.visitInsn(FCONST_0); } else if ((Float) value == 1f) { mv.visitInsn(FCONST_1); } else if ((Float) value == 2f) { mv.visitInsn(FCONST_2); } else { mv.visitLdcInsn(value); } } else if (ClassHelper.double_TYPE.equals(type)) { if ((Double) value == 0d) { mv.visitInsn(DCONST_0); } else if ((Double) value == 1d) { mv.visitInsn(DCONST_1); } else { mv.visitLdcInsn(value); } } else if (ClassHelper.boolean_TYPE.equals(type)) { boolean b = (Boolean) value; if (b) { mv.visitInsn(ICONST_1); } else { mv.visitInsn(ICONST_0); } } else { mv.visitLdcInsn(value); } }
public static byte[] generate(EventClassModel model) { ClassWriter cwriter = new ClassWriter(ClassWriter.COMPUTE_MAXS); ClassVisitor cw; if (TRACE) { cw = new TraceClassVisitor(cwriter, new ASMifier(), new PrintWriter(System.out)); cw = new CheckClassAdapter(cw); } else { cw = cwriter; } FieldVisitor fv; MethodVisitor mv; String concreteClassName = model.getRootPackageInternalPrefix() + "event/" + model.technicalNameCapitalized + "Event"; String className = model.isCustomized ? model.getRootPackageInternalPrefix() + "event/Abstract" + model.technicalNameCapitalized + "Event" : concreteClassName; cw.visit( V1_7, ACC_PUBLIC + ACC_SUPER + (model.isCustomized ? ACC_ABSTRACT : 0), className, null, "org/instantlogic/interaction/flow/impl/SimpleFlowEvent", null); // public static final HomeEvent { fv = cw.visitField( ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "INSTANCE", "L" + concreteClassName + ";", null, null); fv.visitEnd(); } { mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null); mv.visitCode(); // INSTANCE = new HomeEvent(); mv.visitTypeInsn(NEW, concreteClassName); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, concreteClassName, "<init>", "()V"); mv.visitFieldInsn(PUTSTATIC, className, "INSTANCE", "L" + concreteClassName + ";"); mv.visitInsn(RETURN); mv.visitMaxs(9, 99); mv.visitEnd(); } // Default synthetic constructor { mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitLdcInsn(model.name); mv.visitIntInsn(BIPUSH, model.parameters.size()); mv.visitTypeInsn(ANEWARRAY, "org/instantlogic/fabric/model/Entity"); int i = 0; for (String parameter : model.parameters) { mv.visitInsn(DUP); mv.visitIntInsn(BIPUSH, i); mv.visitFieldInsn( GETSTATIC, model.getRootPackageInternalPrefix() + "entity/" + parameter + "Entity", "INSTANCE", "L" + model.getRootPackageInternalPrefix() + "entity/" + parameter + "Entity;"); mv.visitInsn(AASTORE); i++; } mv.visitMethodInsn( INVOKESPECIAL, "org/instantlogic/interaction/flow/impl/SimpleFlowEvent", "<init>", "(Ljava/lang/String;[Lorg/instantlogic/fabric/model/Entity;)V"); mv.visitInsn(RETURN); mv.visitMaxs(9, 99); mv.visitEnd(); } cw.visitEnd(); return cwriter.toByteArray(); }
protected MethodVisitor makeDelegateToClosureCall( final String name, final String desc, final String signature, final String[] exceptions, final int accessFlags) { MethodVisitor mv = super.visitMethod(accessFlags, name, desc, signature, exceptions); // TraceMethodVisitor tmv = new TraceMethodVisitor(mv); // mv = tmv; mv.visitCode(); int stackSize = 0; // method body should be: // this.$delegate$closure$methodName.call(new Object[] { method arguments }) Type[] args = Type.getArgumentTypes(desc); int arrayStore = args.length + 1; BytecodeHelper.pushConstant(mv, args.length); mv.visitTypeInsn(ANEWARRAY, "java/lang/Object"); // stack size = 1 stackSize = 1; int idx = 1; for (int i = 0; i < args.length; i++) { Type arg = args[i]; mv.visitInsn(DUP); // stack size = 2 BytecodeHelper.pushConstant(mv, i); // array index, stack size = 3 stackSize = 3; // primitive types must be boxed if (isPrimitive(arg)) { mv.visitIntInsn(getLoadInsn(arg), idx); String wrappedType = getWrappedClassDescriptor(arg); mv.visitMethodInsn( INVOKESTATIC, wrappedType, "valueOf", "(" + arg.getDescriptor() + ")L" + wrappedType + ";"); } else { mv.visitVarInsn(ALOAD, idx); // load argument i } idx += registerLen(arg); stackSize = Math.max(4, 3 + registerLen(arg)); mv.visitInsn(AASTORE); // store value into array } mv.visitVarInsn(ASTORE, arrayStore); // store array int arrayIndex = arrayStore; mv.visitVarInsn(ALOAD, 0); // load this mv.visitFieldInsn( GETFIELD, proxyName, CLOSURES_MAP_FIELD, "Ljava/util/Map;"); // load closure map mv.visitLdcInsn(name); // load method name mv.visitMethodInsn( INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); arrayStore++; mv.visitVarInsn(ASTORE, arrayStore); // if null, test if wildcard exists Label notNull = new Label(); mv.visitIntInsn(ALOAD, arrayStore); mv.visitJumpInsn(IFNONNULL, notNull); mv.visitVarInsn(ALOAD, 0); // load this mv.visitFieldInsn( GETFIELD, proxyName, CLOSURES_MAP_FIELD, "Ljava/util/Map;"); // load closure map mv.visitLdcInsn("*"); // load wildcard mv.visitMethodInsn( INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;"); mv.visitVarInsn(ASTORE, arrayStore); mv.visitLabel(notNull); mv.visitVarInsn(ALOAD, arrayStore); mv.visitMethodInsn( INVOKESTATIC, BytecodeHelper.getClassInternalName(this.getClass()), "ensureClosure", "(Ljava/lang/Object;)Lgroovy/lang/Closure;"); mv.visitVarInsn(ALOAD, arrayIndex); // load argument array stackSize++; mv.visitMethodInsn( INVOKEVIRTUAL, "groovy/lang/Closure", "call", "([Ljava/lang/Object;)Ljava/lang/Object;"); // call closure unwrapResult(mv, desc); mv.visitMaxs(stackSize, arrayStore + 1); mv.visitEnd(); // System.out.println("tmv.getText() = " + tmv.getText()); return EMPTY_VISITOR; }
public void visitIntInsn(int opcode, int operand) { visitor.visitIntInsn(opcode, operand); }
@Override public DataType visitAtom(@NotNull PythonParser.AtomContext ctx) { // System.out.println("Zz" + ctx.NAME() + ctx.STRING()); if (ctx.test() != null) { // 1 return visitTest(ctx.test()); } else if (ctx.STRING().size() > 0) { // 7,8,9 String ss = ""; for (TerminalNode s : ctx.STRING()) { ss += s.getText(); } mv.visitLdcInsn(ss.length()); mv.visitIntInsn(NEWARRAY, T_CHAR); int tempIndex = 0; for (int i = 0; i < ss.length(); i++) { if (!("\"".equals(ss.substring(i, i + 1))) && !("\'".equals(ss.substring(i, i + 1)))) { mv.visitInsn(DUP); mv.visitLdcInsn(tempIndex); mv.visitLdcInsn(ss.charAt(i)); mv.visitInsn(CASTORE); tempIndex++; } } if (ctx.LBRACK() != null) { if (Integer.parseInt(ctx.INT().getText()) > tempIndex - 1) { throw new CompileException( String.format( "Index out of bounds exception for string %s with index %s", ss, Integer.parseInt(ctx.INT().getText()))); } mv.visitLdcInsn(Integer.parseInt(ctx.INT().getText())); mv.visitInsn(CALOAD); mv.visitMethodInsn( INVOKESTATIC, Type.getType(String.class).getInternalName(), "valueOf", "(C)Ljava/lang/String;", false); return new StringType(1); } else { mv.visitMethodInsn( INVOKESTATIC, Type.getType(String.class).getInternalName(), "valueOf", "([C)Ljava/lang/String;", false); return new StringType(ss.length()); } } else if (!ctx.NAME().isEmpty()) { // 3,4,5 DataType type = null; // System.out.println("GG" + ctx.getText() + "GG"); String varName = ctx.NAME().get(0).getText(); if (scope.isLocalVariable(varName)) { if (ctx.LBRACK() != null) { // 4,5 type = scope.getLocalVariableType(varName); if (!(type instanceof StringType)) { throw new CompileException(String.format("Trying to take index not from string!!")); } mv.visitVarInsn(type.isPrimitive() ? ILOAD : ALOAD, scope.getLocalVariableIndex(varName)); if (ctx.INT() != null) { mv.visitMethodInsn( INVOKEVIRTUAL, Type.getType(String.class).getInternalName(), "toCharArray", "()[C", false); if (Integer.parseInt(ctx.INT().getText()) > type.getSize()) { throw new CompileException(String.format("Index out of bounds exception!")); } mv.visitLdcInsn(Integer.parseInt(ctx.INT().getText())); mv.visitInsn(CALOAD); mv.visitMethodInsn( INVOKESTATIC, Type.getType(String.class).getInternalName(), "valueOf", "(C)Ljava/lang/String;", false); return new StringType(1); } else if (ctx.NAME(1) != null) { varName = ctx.NAME(1).getText(); type = scope.getLocalVariableType(ctx.NAME(1).getText()); if (!type.isInteger()) { throw new CompileException( String.format("Trying to take index from string not with int!")); } else { Label okLabel = new Label(); mv.visitMethodInsn( INVOKEVIRTUAL, Type.getType(String.class).getInternalName(), "toCharArray", "()[C", false); mv.visitVarInsn(ILOAD, scope.getLocalVariableIndex(ctx.NAME(1).getText())); mv.visitInsn(DUP); mv.visitLdcInsn(type.getSize()); mv.visitInsn(SWAP); mv.visitJumpInsn(IF_ICMPGT, okLabel); mv.visitLabel(okLabel); mv.visitInsn(CALOAD); mv.visitMethodInsn( INVOKESTATIC, Type.getType(String.class).getInternalName(), "valueOf", "(C)Ljava/lang/String;", false); // TODO out of bounds a[b] // mv.visitLdcInsn("Out of bounds!"); // mv.visitMethodInsn(INVOKESPECIAL, // "java/lang/CompilerException", "<init>", // "(Ljava/lang/String;)V", false); return new StringType(1); } } else { throw new CompileException(String.format("Unidentified operation")); } } else { // 3 type = scope.getLocalVariableType(varName); mv.visitVarInsn(type.isPrimitive() ? ILOAD : ALOAD, scope.getLocalVariableIndex(varName)); } } else if (scope.isGlobalVariable(varName)) { if (ctx.LBRACK() != null) { // 4,5 type = scope.getGlobalVariableType(varName); if (!(type instanceof StringType)) { throw new CompileException(String.format("Trying to take index not from string!!")); } mv.visitFieldInsn( GETSTATIC, scope.getClassName(), varName, type.getType().getDescriptor()); if (ctx.INT() != null) { mv.visitMethodInsn( INVOKEVIRTUAL, Type.getType(String.class).getInternalName(), "toCharArray", "()[C", false); if (Integer.parseInt(ctx.INT().getText()) > type.getSize()) { throw new CompileException(String.format("Index out of bounds exception!")); } mv.visitLdcInsn(Integer.parseInt(ctx.INT().getText())); mv.visitInsn(CALOAD); mv.visitMethodInsn( INVOKESTATIC, Type.getType(String.class).getInternalName(), "valueOf", "(C)Ljava/lang/String;", false); return new StringType(1); } else if (ctx.NAME(1) != null) { varName = ctx.NAME(1).getText(); type = scope.getLocalVariableType(ctx.NAME(1).getText()); if (!type.isInteger()) { throw new CompileException( String.format("Trying to take index from string not with int!")); } else { Label okLabel = new Label(); mv.visitMethodInsn( INVOKEVIRTUAL, Type.getType(String.class).getInternalName(), "toCharArray", "()[C", false); mv.visitVarInsn(ILOAD, scope.getLocalVariableIndex(ctx.NAME(1).getText())); mv.visitInsn(DUP); mv.visitLdcInsn(type.getSize()); mv.visitInsn(SWAP); mv.visitJumpInsn(IF_ICMPGT, okLabel); mv.visitLabel(okLabel); mv.visitInsn(CALOAD); mv.visitMethodInsn( INVOKESTATIC, Type.getType(String.class).getInternalName(), "valueOf", "(C)Ljava/lang/String;", false); // TODO out of bounds a[b] // mv.visitLdcInsn("Out of bounds!"); // mv.visitMethodInsn(INVOKESPECIAL, // "java/lang/CompilerException", "<init>", // "(Ljava/lang/String;)V", false); return new StringType(1); } } else { throw new CompileException(String.format("Unidentified operation")); } } else { // 3 type = scope.getGlobalVariableType(varName); mv.visitFieldInsn( GETSTATIC, scope.getClassName(), varName, type.getType().getDescriptor()); } } return type; // } else if (scope.isFunction) } else if (ctx.INT() != null) { // 6 mv.visitLdcInsn(Integer.parseInt(ctx.INT().getText())); return PrimitiveType.INTEGER; } else if (ctx.BOOL() != null) { // 2 mv.visitInsn("False".equals(ctx.BOOL().getText()) ? ICONST_0 : ICONST_1); return PrimitiveType.BOOLEAN; } else { throw new CompileException(String.format("Undefined thing to work with! %s", ctx.getText())); } }
/* * (non-Javadoc) * * @see org.objectweb.asm.MethodAdapter#visitLdcInsn(java.lang.Object) */ @Override public void visitLdcInsn(Object cst) { if (cst == null) { this.visitInsn(ACONST_NULL); } else if (cst instanceof Integer) { int value = (Integer) cst; if (value >= -1 && value <= 5) { super.visitInsn(ICONST_0 + value); } else if (value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE) { super.visitIntInsn(BIPUSH, value); } else if (value <= Short.MAX_VALUE && value >= Short.MIN_VALUE) { super.visitIntInsn(SIPUSH, value); } else { super.visitLdcInsn(cst); } } else if (cst instanceof Long) { long value = (Long) cst; if (value == 0L || value == 1L) { super.visitInsn(LCONST_0 + ((int) value)); } else { super.visitLdcInsn(cst); } } else if (cst instanceof Float) { float value = (Float) cst; if (value == 0.0F) { super.visitInsn(FCONST_0); } else if (value == 1.0F) { super.visitInsn(FCONST_1); } else if (value == 2.0F) { super.visitInsn(FCONST_2); } else { super.visitLdcInsn(cst); } } else if (cst instanceof Double) { double value = (Double) cst; if (value == 0.0D) { super.visitInsn(DCONST_0); } else if (value == 1.0D) { super.visitInsn(DCONST_1); } else { super.visitLdcInsn(cst); } } else if (cst instanceof Type) { Type t = (Type) cst; switch (t.getSort()) { case Type.BOOLEAN: super.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;"); break; case Type.BYTE: super.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;"); break; case Type.CHAR: super.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;"); break; case Type.DOUBLE: super.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;"); break; case Type.FLOAT: super.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;"); break; case Type.INT: super.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;"); break; case Type.LONG: super.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;"); break; case Type.SHORT: super.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;"); break; default: super.visitLdcInsn(cst); } } else { super.visitLdcInsn(cst); } }