Lib.Krakatau.classfile.py Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of krakatau-lib Show documentation
Show all versions of krakatau-lib Show documentation
Assembler, disassebmler, decompiler and compiler tools library for Java.
from . import constant_pool, method, field
from .attributes_raw import get_attributes_raw, fixAttributeNames
cp_structFmts = {3: '>i',
4: '>i', #floats and doubles internally represented as integers with same bit pattern
5: '>q',
6: '>q',
7: '>H',
8: '>H',
9: '>HH',
10: '>HH',
11: '>HH',
12: '>HH',
15: '>BH',
16: '>H',
18: '>HH'}
def get_cp_raw(bytestream):
const_count = bytestream.get('>H')
assert(const_count > 1)
placeholder = None,None
pool = [placeholder]
while len(pool) < const_count:
tag = bytestream.get('B')
if tag == 1: #utf8
length = bytestream.get('>H')
data = bytestream.getRaw(length)
val = tag, (data,)
else:
val = tag,bytestream.get(cp_structFmts[tag], True)
pool.append(val)
#Longs and Doubles take up two spaces in the pool
if tag == 5 or tag == 6:
pool.append(placeholder)
assert(len(pool) == const_count)
return pool
def get_field_raw(bytestream):
flags, name, desc = bytestream.get('>HHH')
attributes = get_attributes_raw(bytestream)
return flags, name, desc, attributes
def get_fields_raw(bytestream):
count = bytestream.get('>H')
return [get_field_raw(bytestream) for _ in range(count)]
#fields and methods have same raw format
get_method_raw = get_field_raw
get_methods_raw = get_fields_raw
class ClassFile(object):
flagVals = {'PUBLIC':0x0001,
'FINAL':0x0010,
'SUPER':0x0020,
'INTERFACE':0x0200,
'ABSTRACT':0x0400,
'SYNTHETIC':0x1000,
'ANNOTATION':0x2000,
'ENUM':0x4000,
# These flags are only used for InnerClasses attributes
'PRIVATE':0x0002,
'PROTECTED':0x0004,
'STATIC':0x0008,
}
def __init__(self, bytestream):
magic, minor, major = bytestream.get('>LHH')
assert(magic == 0xCAFEBABE)
self.version = major,minor
const_pool_raw = get_cp_raw(bytestream)
flags, self.this, self.super = bytestream.get('>HHH')
interface_count = bytestream.get('>H')
self.interfaces_raw = [bytestream.get('>H') for _ in range(interface_count)]
self.fields_raw = get_fields_raw(bytestream)
self.methods_raw = get_methods_raw(bytestream)
ic_indices = [i for i,x in enumerate(const_pool_raw) if x == (1, ("InnerClasses",))]
self.attributes_raw = get_attributes_raw(bytestream, ic_indices)
assert(bytestream.size() == 0)
self.flags = set(name for name,mask in ClassFile.flagVals.items() if (mask & flags))
self.cpool = constant_pool.ConstPool(const_pool_raw)
self.name = self.cpool.getArgsCheck('Class', self.this)
self.elementsLoaded = False
def loadSupers(self, env, name, subclasses):
self.env = env
assert(self.name == name)
if self.super:
self.supername = self.cpool.getArgsCheck('Class', self.super)
# if superclass is cached, we can assume it is free from circular inheritance
# since it must have been loaded successfully on a previous run
if not self.env.isCached(self.supername):
self.env.getClass(self.supername, subclasses + (name,), partial=True)
self.hierarchy = self.env.getSupers(self.supername) + (self.name,)
else:
assert(name == 'java/lang/Object')
self.supername = None
self.hierarchy = (self.name,)
def loadElements(self, keepRaw=False):
if self.elementsLoaded:
return
self.fields = [field.Field(m, self, keepRaw) for m in self.fields_raw]
self.methods = [method.Method(m, self, keepRaw) for m in self.methods_raw]
self.attributes = fixAttributeNames(self.attributes_raw, self.cpool)
del self.fields_raw
del self.methods_raw
if not keepRaw:
del self.attributes_raw
self.elementsLoaded = True
def getSuperclassHierarchy(self):
return self.hierarchy
© 2015 - 2025 Weber Informatics LLC | Privacy Policy