# Path: krakatau-lib/src/main/resources/Lib/Krakatau/verifier/verifier_types.py
# T_BYTE = _makeinfo('.byte')
# 
# T_CHAR = _makeinfo('.char')
# 
# T_DOUBLE = _makeinfo('.double')
# 
# T_FLOAT = _makeinfo('.float')
# 
# T_INT = _makeinfo('.int')
# 
# T_LONG = _makeinfo('.long')
# 
# T_SHORT = _makeinfo('.short')
# 
# T_BOOL = _makeinfo('.boolean') #Hotspot doesn't have a bool type, but we can use this elsewhere
# 
# def T_OBJECT(name):
#     return _makeinfo('.obj', extra=name)
# 
# def T_ARRAY(baset, newDimensions=1):
#     assert(0 <= baset.dim <= 255-newDimensions)
#     return _makeinfo(baset.tag, baset.dim+newDimensions, baset.extra)
# 
# Path: krakatau-lib/src/main/resources/Lib/Krakatau/verifier/verifier_types.py
# def _makeinfo(tag, dim=0, extra=None):
# def T_ADDRESS(entry):
# def T_OBJECT(name):
# def T_ARRAY(baset, newDimensions=1):
# def T_UNINIT_OBJECT(origin):
# def objOrArray(fi): #False on uninitialized
# def unSynthesizeType(t):
# def decrementDim(fi):
# def withNoDimension(fi):
# def _decToObjArray(fi):
# def _arrbase(fi):
# def mergeTypes(env, t1, t2, forAssignment=False):
# def isAssignable(env, t1, t2):
# def vt_toStr(self):
# T_INVALID = _makeinfo(None)
# T_INT = _makeinfo('.int')
# T_FLOAT = _makeinfo('.float')
# T_DOUBLE = _makeinfo('.double')
# T_DOUBLE2 = _makeinfo('.double2') #Hotspot only uses these in locals, but we use them on the stack too to simplify things
# T_LONG = _makeinfo('.long')
# T_LONG2 = _makeinfo('.long2')
# T_NULL = _makeinfo('.obj')
# T_UNINIT_THIS = _makeinfo('.init')
# T_BYTE = _makeinfo('.byte')
# T_SHORT = _makeinfo('.short')
# T_CHAR = _makeinfo('.char')
# T_BOOL = _makeinfo('.boolean') #Hotspot doesn't have a bool type, but we can use this elsewhere
# OBJECT_INFO = T_OBJECT('java/lang/Object')
# CLONE_INFO = T_OBJECT('java/lang/Cloneable')
# SERIAL_INFO = T_OBJECT('java/io/Serializable')
# THROWABLE_INFO = T_OBJECT('java/lang/Throwable')


from .verifier_types import T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, T_BOOL, T_OBJECT, T_ARRAY
from .verifier_types import unSynthesizeType, cat2tops
        raise ValueError('Incorrect number of fields in descriptor, expected {} but found {}'.format(cat, len(rval)))
    return rval

#Parse a string to get a Java Method Descriptor
def parseMethodDescriptor(desc_str, unsynthesize=True):
    if not desc_str.startswith('('):
        raise ValueError('Method descriptor does not start with (')

    #we need to split apart the argument list and return value
    #this is greatly complicated by the fact that ) is a legal
    #character that can appear in class names

    lp_pos = desc_str.rfind(')') #this case will work if return type is not an object
    if desc_str.endswith(';'):
        lbound = max(desc_str.rfind(';', 1, -1), 1)
        lp_pos = desc_str.find(')', lbound, -1)
    if lp_pos < 0 or desc_str[lp_pos] != ')':
        raise ValueError('Unable to split method descriptor into arguments and return type')

    arg_str = desc_str[1:lp_pos]
    rval_str = desc_str[lp_pos+1:]

    args = parseFieldDescriptors(arg_str, unsynthesize)
    rval = [] if rval_str == 'V' else parseFieldDescriptor(rval_str, unsynthesize)
    return args, rval

#Adds self argument for nonstatic. Constructors must be handled seperately
def parseUnboundMethodDescriptor(desc_str, target, isstatic):
    args, rval = parseMethodDescriptor(desc_str)
    if not isstatic:

# Path: krakatau-lib/src/main/resources/Lib/Krakatau/verifier/verifier_types.py
# T_BYTE = _makeinfo('.byte')
# 
# T_CHAR = _makeinfo('.char')
# 
# T_DOUBLE = _makeinfo('.double')
# 
# T_FLOAT = _makeinfo('.float')
# 
# T_INT = _makeinfo('.int')
# 
# T_LONG = _makeinfo('.long')
# 
# T_SHORT = _makeinfo('.short')
# 
# T_BOOL = _makeinfo('.boolean') #Hotspot doesn't have a bool type, but we can use this elsewhere
# 
# def T_OBJECT(name):
#     return _makeinfo('.obj', extra=name)
# 
# def T_ARRAY(baset, newDimensions=1):
#     assert(0 <= baset.dim <= 255-newDimensions)
#     return _makeinfo(baset.tag, baset.dim+newDimensions, baset.extra)
# 
# Path: krakatau-lib/src/main/resources/Lib/Krakatau/verifier/verifier_types.py
# def _makeinfo(tag, dim=0, extra=None):
# def T_ADDRESS(entry):
# def T_OBJECT(name):
# def T_ARRAY(baset, newDimensions=1):
# def T_UNINIT_OBJECT(origin):
# def objOrArray(fi): #False on uninitialized
# def unSynthesizeType(t):
# def decrementDim(fi):
# def withNoDimension(fi):
# def _decToObjArray(fi):
# def _arrbase(fi):
# def mergeTypes(env, t1, t2, forAssignment=False):
# def isAssignable(env, t1, t2):
# def vt_toStr(self):
# T_INVALID = _makeinfo(None)
# T_INT = _makeinfo('.int')
# T_FLOAT = _makeinfo('.float')
# T_DOUBLE = _makeinfo('.double')
# T_DOUBLE2 = _makeinfo('.double2') #Hotspot only uses these in locals, but we use them on the stack too to simplify things
# T_LONG = _makeinfo('.long')
# T_LONG2 = _makeinfo('.long2')
# T_NULL = _makeinfo('.obj')
# T_UNINIT_THIS = _makeinfo('.init')
# T_BYTE = _makeinfo('.byte')
# T_SHORT = _makeinfo('.short')
# T_CHAR = _makeinfo('.char')
# T_BOOL = _makeinfo('.boolean') #Hotspot doesn't have a bool type, but we can use this elsewhere
# OBJECT_INFO = T_OBJECT('java/lang/Object')
# CLONE_INFO = T_OBJECT('java/lang/Cloneable')
# SERIAL_INFO = T_OBJECT('java/io/Serializable')
# THROWABLE_INFO = T_OBJECT('java/lang/Throwable')


# Path: krakatau-lib/src/main/resources/Lib/Krakatau/verifier/descriptors.py
from .verifier_types import T_BYTE, T_CHAR, T_DOUBLE, T_FLOAT, T_INT, T_LONG, T_SHORT, T_BOOL, T_OBJECT, T_ARRAY
from .verifier_types import unSynthesizeType, cat2tops

        raise ValueError('Incorrect number of fields in descriptor, expected {} but found {}'.format(cat, len(rval)))
    return rval

#Parse a string to get a Java Method Descriptor
def parseMethodDescriptor(desc_str, unsynthesize=True):
    if not desc_str.startswith('('):
        raise ValueError('Method descriptor does not start with (')

    #we need to split apart the argument list and return value
    #this is greatly complicated by the fact that ) is a legal
    #character that can appear in class names

    lp_pos = desc_str.rfind(')') #this case will work if return type is not an object
    if desc_str.endswith(';'):
        lbound = max(desc_str.rfind(';', 1, -1), 1)
        lp_pos = desc_str.find(')', lbound, -1)
    if lp_pos < 0 or desc_str[lp_pos] != ')':
        raise ValueError('Unable to split method descriptor into arguments and return type')

    arg_str = desc_str[1:lp_pos]
    rval_str = desc_str[lp_pos+1:]

    args = parseFieldDescriptors(arg_str, unsynthesize)
    rval = [] if rval_str == 'V' else parseFieldDescriptor(rval_str, unsynthesize)
    return args, rval

#Adds self argument for nonstatic. Constructors must be handled seperately
def parseUnboundMethodDescriptor(desc_str, target, isstatic):
    args, rval = parseMethodDescriptor(desc_str)
    if not isstatic:

        args = [T_OBJECT(target)] + args