Java Code Examples for org.objectweb.asm.Opcodes#INVOKEINTERFACE

The following examples show how to use org.objectweb.asm.Opcodes#INVOKEINTERFACE . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: GuiNewChatTransformer.java    From SkyblockAddons with MIT License 6 votes vote down vote up
@Override
public void transform(ClassNode classNode, String name) {
    for (MethodNode methodNode : classNode.methods) {
        if (TransformerMethod.printChatMessageWithOptionalDeletion.matches(methodNode)) {

            // Objective:
            // Find: chatComponent.getUnformattedText();
            // Replace With: GuiNewChatHook.getUnformattedText(chatComponent);

            Iterator<AbstractInsnNode> iterator = methodNode.instructions.iterator();
            while (iterator.hasNext()) {
                AbstractInsnNode abstractNode = iterator.next();
                if (abstractNode instanceof MethodInsnNode && abstractNode.getOpcode() == Opcodes.INVOKEINTERFACE) {
                    MethodInsnNode methodInsnNode = (MethodInsnNode) abstractNode;
                    if (methodInsnNode.owner.equals(TransformerClass.IChatComponent.getNameRaw()) && TransformerMethod.getUnformattedText.matches(methodInsnNode)) {
                        methodNode.instructions.insertBefore(abstractNode, new MethodInsnNode(Opcodes.INVOKESTATIC, "codes/biscuit/skyblockaddons/asm/hooks/GuiNewChatHook",
                                "getUnformattedText", "("+TransformerClass.IChatComponent.getName()+")Ljava/lang/String;", false)); // GuiNewChatHook.getUnformattedText(chatComponent);

                        iterator.remove(); // Remove the old line.
                        break;
                    }
                }
            }
        }
    }
}
 
Example 2
Source File: InstructionAdapter.java    From JByteMod-Beta with GNU General Public License v2.0 6 votes vote down vote up
private void doVisitMethodInsn(
    final int opcode,
    final String owner,
    final String name,
    final String descriptor,
    final boolean isInterface) {
  switch (opcode) {
    case Opcodes.INVOKESPECIAL:
      invokespecial(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKEVIRTUAL:
      invokevirtual(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKESTATIC:
      invokestatic(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKEINTERFACE:
      invokeinterface(owner, name, descriptor);
      break;
    default:
      throw new IllegalArgumentException();
  }
}
 
Example 3
Source File: InstructionAdapter.java    From JReFrameworker with MIT License 6 votes vote down vote up
private void doVisitMethodInsn(
    final int opcode,
    final String owner,
    final String name,
    final String descriptor,
    final boolean isInterface) {
  switch (opcode) {
    case Opcodes.INVOKESPECIAL:
      invokespecial(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKEVIRTUAL:
      invokevirtual(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKESTATIC:
      invokestatic(owner, name, descriptor, isInterface);
      break;
    case Opcodes.INVOKEINTERFACE:
      invokeinterface(owner, name, descriptor);
      break;
    default:
      throw new IllegalArgumentException();
  }
}
 
Example 4
Source File: InterfaceDesugaring.java    From bazel with Apache License 2.0 6 votes vote down vote up
static String normalizeInterfaceMethodName(String name, boolean isLambda, int opcode) {
  if (isLambda) {
    // Rename lambda method to reflect the new owner.  Not doing so confuses LambdaDesugaring
    // if it's run over this class again. LambdaDesugaring has already renamed the method from
    // its original name to include the interface name at this point.
    return name + DependencyCollector.INTERFACE_COMPANION_SUFFIX;
  }

  switch (opcode) {
    case Opcodes.INVOKESPECIAL:
      // Rename static methods holding default method implementations since their descriptor
      // differs from the original method (due to explicit receiver parameter). This avoids
      // possible clashes with static interface methods or generated stubs for default methods
      // that could otherwise have the same name and descriptor by coincidence.
      return name + DEFAULT_COMPANION_METHOD_SUFFIX;
    case Opcodes.INVOKESTATIC: // moved but with same name
      return name + "$$STATIC$$"; // TODO(b/117453106): Stop renaming static interface methods
    case Opcodes.INVOKEINTERFACE: // not moved
    case Opcodes.INVOKEVIRTUAL: // tolerate being called for non-interface methods
      return name;
    default:
      throw new IllegalArgumentException("Unexpected opcode calling " + name + ": " + opcode);
  }
}
 
Example 5
Source File: CheckMethodAdapter.java    From JReFrameworker with MIT License 5 votes vote down vote up
private void doVisitMethodInsn(
    final int opcode,
    final String owner,
    final String name,
    final String descriptor,
    final boolean isInterface) {
  checkVisitCodeCalled();
  checkVisitMaxsNotCalled();
  checkOpcodeMethod(opcode, Method.VISIT_METHOD_INSN);
  if (opcode != Opcodes.INVOKESPECIAL || !"<init>".equals(name)) {
    checkMethodIdentifier(version, name, "name");
  }
  checkInternalName(version, owner, "owner");
  checkMethodDescriptor(version, descriptor);
  if (opcode == Opcodes.INVOKEVIRTUAL && isInterface) {
    throw new IllegalArgumentException("INVOKEVIRTUAL can't be used with interfaces");
  }
  if (opcode == Opcodes.INVOKEINTERFACE && !isInterface) {
    throw new IllegalArgumentException("INVOKEINTERFACE can't be used with classes");
  }
  if (opcode == Opcodes.INVOKESPECIAL && isInterface && (version & 0xFFFF) < Opcodes.V1_8) {
    throw new IllegalArgumentException(
        "INVOKESPECIAL can't be used with interfaces prior to Java 8");
  }

  // Calling super.visitMethodInsn requires to call the correct version depending on this.api
  // (otherwise infinite loops can occur). To simplify and to make it easier to automatically
  // remove the backward compatibility code, we inline the code of the overridden method here.
  if (mv != null) {
    mv.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
  }
  ++insnCount;
}
 
Example 6
Source File: BytecodeInstanceMethodInvokeEmitter.java    From Despector with MIT License 5 votes vote down vote up
public int getOpcode(InstanceMethodInvoke.Type type) {
    switch (type) {
    case INTERFACE:
        return Opcodes.INVOKEINTERFACE;
    case SPECIAL:
        return Opcodes.INVOKESPECIAL;
    case VIRTUAL:
    default:
        return Opcodes.INVOKEVIRTUAL;
    }
}
 
Example 7
Source File: CustomInvoke.java    From CodenameOne with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void addDependencies(List<String> dependencyList) {
    String t = owner.replace('.', '_').replace('/', '_').replace('$', '_');
    t = unarray(t);
    if(t != null && !dependencyList.contains(t)) {
        dependencyList.add(t);
    }

    StringBuilder bld = new StringBuilder();
    if(origOpcode != Opcodes.INVOKEINTERFACE && origOpcode != Opcodes.INVOKEVIRTUAL) {
        return;
    }         
    bld.append(owner.replace('/', '_').replace('$', '_'));
    bld.append("_");
    if(name.equals("<init>")) {
        bld.append("__INIT__");
    } else {
        if(name.equals("<clinit>")) {
            bld.append("__CLINIT__");
        } else {
            bld.append(name);
        }
    }
    bld.append("__");
    ArrayList<String> args = new ArrayList<String>();
    String returnVal = BytecodeMethod.appendMethodSignatureSuffixFromDesc(desc, bld, args);        
    String str = bld.toString();
    BytecodeMethod.addVirtualMethodsInvoked(str);
}
 
Example 8
Source File: MethodsMirror.java    From CodenameOne with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Returns true if the mirror contains a method that mirrors
 * <code>methodName</code>. The mirror method should be static, have the
 * same name, and have the exact same arguments excepting an argument of
 * type
 */
public boolean hasMethod(final String owner, final String methodName, final String methodDescriptor, final int opcode) {
	Type[] types = Type.getArgumentTypes(methodDescriptor);

	if (opcode == Opcodes.INVOKEVIRTUAL || opcode == Opcodes.INVOKEINTERFACE) {
		Type[] newTypes = new Type[types.length + 1];
		newTypes[0] = Type.getType("L" + owner + ";");
		System.arraycopy(types, 0, newTypes, 1, types.length);
		types = newTypes;
	}

outer_loop:
	for (Method m : class_.getDeclaredMethods()) {
		final Type[] methodTypes = Type.getArgumentTypes(m);
		if (!m.getName().equals(methodName)
				|| methodTypes.length != types.length) {
			continue;
		}

		for (int i = 0; i < types.length; ++i) {
			if (!types[i].equals(methodTypes[i])) {
				continue outer_loop;
			}
		}

		return true;
	}

	return false;
}
 
Example 9
Source File: MethodConstantsCollector.java    From CodenameOne with GNU General Public License v2.0 5 votes vote down vote up
public void visitMethodInsn(
    final int opcode,
    final String owner,
    final String name,
    final String desc)
{
    boolean itf = opcode == Opcodes.INVOKEINTERFACE;
    cp.newMethod(owner, name, desc, itf);
    mv.visitMethodInsn(opcode, owner, name, desc);
}
 
Example 10
Source File: Invoke.java    From CodenameOne with GNU General Public License v2.0 5 votes vote down vote up
@Override
public void addDependencies(List<String> dependencyList) {
    String t = owner.replace('.', '_').replace('/', '_').replace('$', '_');
    t = unarray(t);
    if(t != null && !dependencyList.contains(t)) {
        dependencyList.add(t);
    }

    StringBuilder bld = new StringBuilder();
    if(opcode != Opcodes.INVOKEINTERFACE && opcode != Opcodes.INVOKEVIRTUAL) {
        return;
    }         
    bld.append(owner.replace('/', '_').replace('$', '_'));
    bld.append("_");
    if(name.equals("<init>")) {
        bld.append("__INIT__");
    } else {
        if(name.equals("<clinit>")) {
            bld.append("__CLINIT__");
        } else {
            bld.append(name);
        }
    }
    bld.append("__");
    ArrayList<String> args = new ArrayList<String>();
    String returnVal = BytecodeMethod.appendMethodSignatureSuffixFromDesc(desc, bld, args);        
    String str = bld.toString();
    BytecodeMethod.addVirtualMethodsInvoked(str);
}
 
Example 11
Source File: MethodAssignableValue.java    From yql-plus with Apache License 2.0 5 votes vote down vote up
public MethodAssignableValue(TypeWidget type, Class ownerClass, String name, BytecodeExpression target) {
    this.type = type;
    this.target = target;
    this.ownerName = Type.getInternalName(ownerClass);
    this.name = name;
    this.op = ownerClass.isInterface() ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL;
    this.desc = Type.getMethodDescriptor(type.getJVMType());
}
 
Example 12
Source File: VirtualInvocationExpr.java    From maple-ir with GNU General Public License v3.0 5 votes vote down vote up
public static CallType resolveCallType(int asmOpcode) {
	switch (asmOpcode) {
	case Opcodes.INVOKEVIRTUAL:
		return CallType.VIRTUAL;
	case Opcodes.INVOKESPECIAL:
		return CallType.SPECIAL;
	case Opcodes.INVOKEINTERFACE:
		return CallType.INTERFACE;
	default:
		throw new IllegalArgumentException(String.valueOf(asmOpcode));
	}
}
 
Example 13
Source File: VirtualInvocationExpr.java    From maple-ir with GNU General Public License v3.0 5 votes vote down vote up
private static int resolveASMOpcode(CallType t) {
	switch (t) {
	case SPECIAL:
		return Opcodes.INVOKESPECIAL;
	case VIRTUAL:
		return Opcodes.INVOKEVIRTUAL;
	case INTERFACE:
		return Opcodes.INVOKEINTERFACE;
	default:
		throw new IllegalArgumentException(t.toString());
	}
}
 
Example 14
Source File: StringBuffHelper.java    From Concurnas with MIT License 5 votes vote down vote up
public static void start(BytecodeGennerator bv, Type toAdd) {
	String vo = toAdd.getBytecodeType();
	if(!vo.equals("Ljava/lang/String;"))
	{
		if(toAdd.hasArrayLevels())
		{
			append(bv, toAdd);
			bv.bcoutputter.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "valueOf", "(Ljava/lang/String;)Ljava/lang/String;");
		}
		else if(toAdd instanceof PrimativeType)
		{
			bv.bcoutputter.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "valueOf", "("+vo+")Ljava/lang/String;");
		}
		else if(toAdd instanceof NamedType && TypeCheckUtils.isTypedActor(bv.errorRaisableSupressionFromSatc, (NamedType)toAdd)){
			
			String callOn = toAdd.getCheckCastType();
			int opcode = Opcodes.INVOKEVIRTUAL;
			if(callOn.equals("com/concurnas/lang/Actor") || callOn.equals("com/concurnas/lang/TypedActor")){
				callOn = "x" + ((NamedType)toAdd).getGenTypes().get(0).getCheckCastType() + "$$ActorIterface";
				opcode=Opcodes.INVOKEINTERFACE;
			}
			
			bv.bcoutputter.visitMethodInsn(opcode, callOn, "toString$ActorCall", "()Ljava/lang/String;");
		}
		else
		{
			//bv.mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;");
			//below is better
			bv.bcoutputter.visitMethodInsn(Opcodes.INVOKESTATIC, "com/concurnas/bootstrap/lang/Stringifier", "stringify", "(Ljava/lang/Object;)Ljava/lang/String;");
		}
	}
	bv.bcoutputter.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V");
}
 
Example 15
Source File: ContinuableMethodNode.java    From tascalate-javaflow with Apache License 2.0 5 votes vote down vote up
private boolean needsFrameGuard(int opcode, String owner, String name, String desc) {
    if (owner.startsWith("java/") || owner.startsWith("javax/")) {
        //System.out.println("SKIP:: " + owner + "." + name + desc);
        return false;
    }

    // Always create save-point before Continuation methods (like suspend)
    if (CONTINUATION_CLASS_INTERNAL_NAME.equals(owner)) {
        return CONTINUATION_CLASS_CONTINUABLE_METHODS.contains(name);
    }

    // No need to create save-point before constructors -- it's forbidden to suspend in constructors anyway
    if (opcode == Opcodes.INVOKESPECIAL && "<init>".equals(name)) {
        return false;
    }

    if (opcode == Opcodes.INVOKEINTERFACE ||
        opcode == Opcodes.INVOKESPECIAL   ||
        opcode == Opcodes.INVOKESTATIC    ||
        opcode == Opcodes.INVOKEVIRTUAL) {
        ContinuableClassInfo classInfo;
        try {
            classInfo = cciResolver.resolve(owner);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
        return null != classInfo && classInfo.isContinuableMethod(opcode, name, desc, desc);
    }
    return false;
}
 
Example 16
Source File: BytecodeTypeInference.java    From bazel with Apache License 2.0 5 votes vote down vote up
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
  if (opcode == Opcodes.INVOKESPECIAL && "<init>".equals(name)) {
    int argumentSize = (Type.getArgumentsAndReturnSizes(desc) >> 2);
    InferredType receiverType = getTypeOfOperandFromTop(argumentSize - 1);
    if (receiverType.isUninitialized()) {
      InferredType realType = InferredType.create('L' + owner + ';');
      replaceUninitializedTypeInStack(receiverType, realType);
    }
  }
  switch (opcode) {
    case Opcodes.INVOKESPECIAL:
    case Opcodes.INVOKEVIRTUAL:
    case Opcodes.INVOKESTATIC:
    case Opcodes.INVOKEINTERFACE:
      popDescriptor(desc);
      if (opcode != Opcodes.INVOKESTATIC) {
        pop(); // Pop receiver.
      }
      pushDescriptor(desc);
      break;
    default:
      throw new RuntimeException(
          String.format(
              "Unhandled opcode %s, owner=%s, name=%s, desc=%s, itf=%s",
              opcode, owner, name, desc, itf));
  }
  super.visitMethodInsn(opcode, owner, name, desc, itf);
}
 
Example 17
Source File: AsmUtils.java    From grappa with Apache License 2.0 5 votes vote down vote up
public static boolean isCallOnContextAware(final AbstractInsnNode insn)
{
    Objects.requireNonNull(insn, "insn");
    if (insn.getOpcode() != Opcodes.INVOKEVIRTUAL
        && insn.getOpcode() != Opcodes.INVOKEINTERFACE)
        return false;
    final MethodInsnNode mi = (MethodInsnNode) insn;
    return isAssignableTo(mi.owner, ContextAware.class);
}
 
Example 18
Source File: InterfaceDesugaring.java    From bazel with Apache License 2.0 4 votes vote down vote up
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
  // Assume that any static interface methods on the classpath are moved
  if ((itf || owner.equals(interfaceName)) && !bootclasspath.isKnown(owner)) {
    if (name.startsWith("lambda$")) {
      // Redirect lambda invocations to completely remove all lambda methods from interfaces.
      checkArgument(
          !owner.endsWith(DependencyCollector.INTERFACE_COMPANION_SUFFIX),
          "shouldn't consider %s an interface",
          owner);
      if (opcode == Opcodes.INVOKEINTERFACE) {
        opcode = Opcodes.INVOKESTATIC;
        desc = companionDefaultMethodDescriptor(owner, desc);
      } else {
        checkArgument(
            opcode == Opcodes.INVOKESTATIC,
            "Unexpected opcode %s to invoke %s.%s",
            opcode,
            owner,
            name);
      }
      // Reflect that InterfaceDesugaring moves and renames the lambda body method
      name = normalizeInterfaceMethodName(name, /*isLambda=*/ true, opcode);
      owner += DependencyCollector.INTERFACE_COMPANION_SUFFIX;
      itf = false;
      // Record dependency on companion class
      depsCollector.assumeCompanionClass(declaringClass, owner);

      String expectedLambdaMethodName = LambdaDesugaring.uniqueInPackage(owner, name);
      checkState(
          name.equals(expectedLambdaMethodName),
          "Unexpected lambda body method name for %s: real=%s, expected=%s",
          owner,
          name,
          expectedLambdaMethodName);
    } else if ((opcode == Opcodes.INVOKESTATIC || opcode == Opcodes.INVOKESPECIAL)) {
      checkArgument(
          !owner.endsWith(DependencyCollector.INTERFACE_COMPANION_SUFFIX),
          "shouldn't consider %s an interface",
          owner);
      if (opcode == Opcodes.INVOKESPECIAL) {
        // Turn Interface.super.m() into DefiningInterface$$CC.m(receiver). Note that owner
        // always refers to the current type's immediate super-interface, but the default method
        // may be inherited by that interface, so we have to figure out where the method is
        // defined and invoke it in the corresponding companion class (b/73355452).  Note that
        // we're always dealing with interfaces here, and all interface methods are public,
        // so using Class.getMethods should suffice to find inherited methods.  Also note this
        // can only be a default method invocation, no abstract method invocation.
        owner =
            findDefaultMethod(owner, name, desc)
                .getDeclaringClass()
                .getName()
                .replace('.', '/');
        desc = companionDefaultMethodDescriptor(owner, desc);
      }
      name = normalizeInterfaceMethodName(name, /*isLambda=*/ false, opcode);
      owner += DependencyCollector.INTERFACE_COMPANION_SUFFIX;
      opcode = Opcodes.INVOKESTATIC;
      itf = false;
      // Record dependency on companion class
      depsCollector.assumeCompanionClass(declaringClass, owner);
    } // else non-lambda INVOKEINTERFACE, which needs no rewriting
  }
  super.visitMethodInsn(opcode, owner, name, desc, itf);
}
 
Example 19
Source File: StringBuffHelper.java    From Concurnas with MIT License 4 votes vote down vote up
public static void append(BytecodeGennerator bv, Type tryingToPassType, boolean supressSB){
	//supressSB is a hack lol
	boolean callToString = false;
	if(!tryingToPassType.hasArrayLevels() && tryingToPassType instanceof NamedType){
		NamedType asNamed = (NamedType)tryingToPassType;
		if(!TypeCheckUtils.objectNT.equals(asNamed)){
			if(null == TypeCheckUtils.checkSubType(bv.errorRaisableSupressionFromSatc, ScopeAndTypeChecker.map_object, asNamed, 42, 42, 42, 42) && 
					null == TypeCheckUtils.checkSubType(bv.errorRaisableSupressionFromSatc, ScopeAndTypeChecker.list_object, asNamed, 42, 42, 42, 42) &&
					null == TypeCheckUtils.checkSubType(bv.errorRaisableSupressionFromSatc, ScopeAndTypeChecker.set_object, asNamed, 42, 42, 42, 42))
			{//if not map and not list
				callToString=true;
			}
		}
	}
	
	String bcType;
	if(tryingToPassType instanceof PrimativeType && tryingToPassType.hasArrayLevels()){
		bcType="Ljava/lang/Object;";
	}
	else{
		bcType= (tryingToPassType instanceof GenericType || tryingToPassType instanceof NamedType || tryingToPassType instanceof FuncType || (tryingToPassType instanceof PrimativeType)&& ((PrimativeType)tryingToPassType).type == PrimativeTypeEnum.LAMBDA )?"Ljava/lang/Object;":tryingToPassType.getBytecodeType();
	}
	
	if(bcType.equals("S")){
		bcType = "I";//short cast to int
	}
	
	if(callToString || TypeCheckUtils.isNonArrayStringOrPrimative(tryingToPassType)){//JPT: imperfectly unit tested, anything which has no functional impact is here... :(
		//primative with no array or a String - no need to call stringifier
		if(tryingToPassType instanceof NamedType && TypeCheckUtils.isTypedActor(bv.errorRaisableSupressionFromSatc, (NamedType)tryingToPassType)){
			String callOn = tryingToPassType.getCheckCastType();
			int opcode = Opcodes.INVOKEVIRTUAL;
			if(callOn.equals("com/concurnas/lang/Actor") || callOn.equals("com/concurnas/lang/TypedActor")){
				callOn = "x" + ((NamedType)tryingToPassType).getGenTypes().get(0).getCheckCastType() + "$$ActorIterface";
				opcode=Opcodes.INVOKEINTERFACE;
			}
			bv.bcoutputter.visitMethodInsn(opcode, callOn, "toString$ActorCall", "()Ljava/lang/String;");
		}
		if(!supressSB){
			doAppend(bv, bcType);
		}
	}
	else{//uh oh, something tricky, call stringifier
		bv.bcoutputter.visitMethodInsn(Opcodes.INVOKESTATIC, "com/concurnas/bootstrap/lang/Stringifier", "stringify", String.format("(%s)Ljava/lang/String;",bcType)) ;
		bcType = "Ljava/lang/String;";
		if(!supressSB){
			doAppend(bv, bcType);
		}
	}
}
 
Example 20
Source File: Printer.java    From JByteMod-Beta with GNU General Public License v2.0 3 votes vote down vote up
/**
 * Method instruction. See
 * {@link org.objectweb.asm.MethodVisitor#visitMethodInsn}.
 *
 * @param opcode
 *          the opcode of the type instruction to be visited. This opcode is
 *          either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or
 *          INVOKEINTERFACE.
 * @param owner
 *          the internal name of the method's owner class (see
 *          {@link org.objectweb.asm.Type#getInternalName() getInternalName}).
 * @param name
 *          the method's name.
 * @param desc
 *          the method's descriptor (see {@link org.objectweb.asm.Type Type}).
 * @param itf
 *          if the method's owner class is an interface.
 */
public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) {
  if (api < Opcodes.ASM5) {
    if (itf != (opcode == Opcodes.INVOKEINTERFACE)) {
      throw new IllegalArgumentException("INVOKESPECIAL/STATIC on interfaces require ASM 5");
    }
    visitMethodInsn(opcode, owner, name, desc);
    return;
  }
  throw new RuntimeException("Must be overriden");
}