static int merge(int current,int incoming,ConstantPool pool){
  int currentTag=getTag(current);
  int incomingTag=getTag(incoming);
  boolean currentIsObject=currentTag == TypeInfo.OBJECT_TAG;
  boolean incomingIsObject=incomingTag == TypeInfo.OBJECT_TAG;
  if (current == incoming || (currentIsObject && incoming == NULL)) {
    return current;
  }
 else   if (currentTag == TypeInfo.TOP || incomingTag == TypeInfo.TOP) {
    return TypeInfo.TOP;
  }
 else   if (current == NULL && incomingIsObject) {
    return incoming;
  }
 else   if (currentIsObject && incomingIsObject) {
    String currentName=getPayloadAsType(current,pool);
    String incomingName=getPayloadAsType(incoming,pool);
    String currentlyGeneratedName=(String)pool.getConstantData(2);
    String currentlyGeneratedSuperName=(String)pool.getConstantData(4);
    if (currentName.equals(currentlyGeneratedName)) {
      currentName=currentlyGeneratedSuperName;
    }
    if (incomingName.equals(currentlyGeneratedName)) {
      incomingName=currentlyGeneratedSuperName;
    }
    Class<?> currentClass=getClassFromInternalName(currentName);
    Class<?> incomingClass=getClassFromInternalName(incomingName);
    if (currentClass.isAssignableFrom(incomingClass)) {
      return current;
    }
 else     if (incomingClass.isAssignableFrom(currentClass)) {
      return incoming;
    }
 else     if (incomingClass.isInterface() || currentClass.isInterface()) {
      return OBJECT("java/lang/Object",pool);
    }
 else {
      Class<?> commonClass=incomingClass.getSuperclass();
      while (commonClass != null) {
        if (commonClass.isAssignableFrom(currentClass)) {
          String name=commonClass.getName();
          name=ClassFileWriter.getSlashedForm(name);
          return OBJECT(name,pool);
        }
        commonClass=commonClass.getSuperclass();
      }
    }
  }
  throw new IllegalArgumentException("bad merge attempt between " + toString(current,pool) + " and "+ toString(incoming,pool));
}

static int merge ( int current , int incoming , ConstantPool pool ) { int currentTag = getTag ( current ) ; int incomingTag = getTag ( incoming ) ; boolean currentIsObject = currentTag == TypeInfo . OBJECT_TAG ; boolean incomingIsObject = incomingTag == TypeInfo . OBJECT_TAG ; if ( current == incoming || ( currentIsObject && incoming == NULL ) ) { return current ; } else if ( currentTag == TypeInfo . TOP || incomingTag == TypeInfo . TOP ) { return TypeInfo . TOP ; } else if ( current == NULL && incomingIsObject ) { return incoming ; } else if ( currentIsObject && incomingIsObject ) { String currentName = getPayloadAsType ( current , pool ) ; String incomingName = getPayloadAsType ( incoming , pool ) ; String currentlyGeneratedName = ( String ) pool . getConstantData ( 2 ) ; String currentlyGeneratedSuperName = ( String ) pool . getConstantData ( 4 ) ; if ( currentName . equals ( currentlyGeneratedName ) ) { currentName = currentlyGeneratedSuperName ; } if ( incomingName . equals ( currentlyGeneratedName ) ) { incomingName = currentlyGeneratedSuperName ; } Class < ? > currentClass = getClassFromInternalName ( currentName ) ; Class < ? > incomingClass = getClassFromInternalName ( incomingName ) ; if ( currentClass . isAssignableFrom ( incomingClass ) ) { return current ; } else if ( incomingClass . isAssignableFrom ( currentClass ) ) { return incoming ; } else if ( incomingClass . isInterface ( ) || currentClass . isInterface ( ) ) { return OBJECT ( "java/lang/Object" , pool ) ; } else { Class < ? > commonClass = incomingClass . getSuperclass ( ) ; while ( commonClass != null ) { if ( commonClass . isAssignableFrom ( currentClass ) ) { String name = commonClass . getName ( ) ; name = ClassFileWriter . getSlashedForm ( name ) ; return OBJECT ( name , pool ) ; } commonClass = commonClass . getSuperclass ( ) ; } } } throw new IllegalArgumentException ( "bad merge attempt between " + toString ( current , pool ) + " and " + toString ( incoming , pool ) ) ; }
merge two verification types . in most cases , the verification types must be the same . for example , integer and double cannot be merged and an exception will be thrown . the basic rules are : - if the types are equal , simply return one . - if either type is top , return top . - if either type is null , return the other type . - if both types are objects , find the lowest common ancestor in the class hierarchy . this method uses reflection to traverse the class hierarchy . therefore , it is assumed that the current class being generated is never the target of a full object - object merge , which would need to load the current class reflectively .
