Module refinery.lib.java
Parsing of the Java Class file format as per the official specification.
Expand source code Browse git
"""
Parsing of the Java Class file format as per
[the official specification](https://docs.oracle.com/javase/specs/jvms/se14/html/jvms-4.html).
"""
from __future__ import annotations
from enum import IntEnum
from typing import Any, Generic, TypeVar
from refinery.lib.structures import (
AttrType,
PerInstanceAttribute,
StreamDetour,
Struct,
StructReader,
)
from refinery.lib.types import buf
__all__ = (
'opc',
'JvAccessFlags',
'JvAttribute',
'JvBaseType',
'JvClassFile',
'JvClassMember',
'JvClassProperty',
'JvCode',
'JvConstType',
'JvDynamic',
'JvException',
'JvMethodHandle',
'JvMethodHandleRefKind',
'JvNameAndType',
'JvOpCode',
'JvString',
)
class Index(PerInstanceAttribute[AttrType]):
def __init__(self, jtype: type[AttrType]):
super().__init__()
self.jtype = jtype
def resolve(self, parent: Any, value: int) -> AttrType:
if not value:
return None
try:
cpool = parent.pool
except AttributeError as AE:
raise AttributeError from AE
try:
result = cpool[value - 1]
except IndexError as IE:
raise AttributeError from IE
if not isinstance(result, self.jtype):
raise TypeError
return result
class JvConstType(IntEnum):
Utf8 = 0x01 # noqa
Int = 0x03 # noqa
Float = 0x04 # noqa
Long = 0x05 # noqa
Double = 0x06 # noqa
Class = 0x07 # noqa
String = 0x08 # noqa
Field = 0x09 # noqa
Method = 0x0A # noqa
InterfaceMethod = 0x0B # noqa
NameAndType = 0x0C # noqa
MethodHandle = 0x0F # noqa
MethodType = 0x10 # noqa
Dynamic = 0x11 # noqa
InvokeDynamic = 0x12 # noqa
Module = 0x13 # noqa
Package = 0x14 # noqa
class JvMethodHandleRefKind(IntEnum):
GetField = 1 # noqa
GetStatic = 2 # noqa
PutField = 3 # noqa
PutStatic = 4 # noqa
InvokeVirtual = 5 # noqa
InvokeStatic = 6 # noqa
InvokeSpecial = 7 # noqa
InvokeSpecialNew = 8 # noqa
InvokeInterface = 9 # noqa
class _HasPoolAndTag(Struct):
def __init__(self, _: StructReader, pool: list, tag: JvConstType):
self.pool = pool
self.tag = tag
class JvStructWithName(_HasPoolAndTag):
name: str = Index(str)
def __repr__(self):
return self.name
class JvNameAndType(JvStructWithName):
descriptor: str = Index(str)
def __init__(self, reader: StructReader, **kwargs):
super().__init__(reader, **kwargs)
self.name = reader.u16()
self.descriptor = reader.u16()
class JvString(_HasPoolAndTag):
value: str = Index(str)
def __init__(self, reader: StructReader, **kwargs):
super().__init__(reader, **kwargs)
self.value = reader.u16()
def __repr__(self):
return repr(self.value)
def __str__(self):
return self.value
class JvClassProperty(_HasPoolAndTag):
name: JvString = Index(JvString)
info: JvNameAndType = Index(JvNameAndType)
def __init__(self, reader: StructReader, **kwargs):
super().__init__(reader, **kwargs)
self.name = reader.u16()
self.info = reader.u16()
def __repr__(self):
name: str = str(self.name)
name = '.'.join(name.split('/'))
return F'{name}::{self.info}'
class JvMethodHandle(_HasPoolAndTag):
reference: JvClassProperty = Index(JvClassProperty)
def __init__(self, reader: StructReader, **kwargs):
super().__init__(reader, **kwargs)
self.kind = JvMethodHandleRefKind(reader.read_byte())
self.reference = reader.u16()
class JvDynamic(_HasPoolAndTag):
def __init__(self, reader: StructReader, **kwargs):
super().__init__(reader, **kwargs)
self.bootstrap_method_attr_index = reader.u16()
self.info = reader.u16()
class JvAccessFlags(Struct):
def __init__(self, reader: StructReader):
(
self.MODULE, # 0x8000
self.ENUM, # 0x4000
self.ANNOTATION, # 0x2000
self.SYNTHETIC, # 0x1000
_, # ...
self.ABSTRACT, # 0x0400
self.INTERFACE, # 0x0200
_, _, _, # ...
self.SUPER, # 0x0020
self.FINAL, # 0x0010
_, _, _, # ...
self.PUBLIC, # 0x0001
) = reader.read_flags(16)
ParserType = TypeVar('ParserType', bound=Struct)
class JvAttribute(JvStructWithName, Generic[ParserType]):
def __init__(self, reader: StructReader, pool: list):
self.pool = pool
self.name = reader.u16()
self.data = reader.read(reader.u32())
def parse(self, parser: type[ParserType]) -> ParserType:
return parser.Parse(self.data, pool=self.pool)
class JvClassMember(JvStructWithName):
descriptor: str = Index(str)
def __init__(self, reader: StructReader, pool: list):
self.pool = pool
self.access = JvAccessFlags(reader)
self.name = reader.u16()
self.descriptor = reader.u16()
self.attributes = [JvAttribute(reader, pool=pool) for _ in range(reader.u16())]
class opc(IntEnum):
nop = 0x00 # noqa
aconst_null = 0x01 # noqa
iconst_m1 = 0x02 # noqa
iconst_0 = 0x03 # noqa
iconst_1 = 0x04 # noqa
iconst_2 = 0x05 # noqa
iconst_3 = 0x06 # noqa
iconst_4 = 0x07 # noqa
iconst_5 = 0x08 # noqa
lconst_0 = 0x09 # noqa
lconst_1 = 0x0a # noqa
fconst_0 = 0x0b # noqa
fconst_1 = 0x0c # noqa
fconst_2 = 0x0d # noqa
dconst_0 = 0x0e # noqa
dconst_1 = 0x0f # noqa
bipush = 0x10 # noqa
sipush = 0x11 # noqa
ldc = 0x12 # noqa
ldc_w = 0x13 # noqa
ldc2_w = 0x14 # noqa
iload = 0x15 # noqa
lload = 0x16 # noqa
fload = 0x17 # noqa
dload = 0x18 # noqa
aload = 0x19 # noqa
iload_0 = 0x1a # noqa
iload_1 = 0x1b # noqa
iload_2 = 0x1c # noqa
iload_3 = 0x1d # noqa
lload_0 = 0x1e # noqa
lload_1 = 0x1f # noqa
lload_2 = 0x20 # noqa
lload_3 = 0x21 # noqa
fload_0 = 0x22 # noqa
fload_1 = 0x23 # noqa
fload_2 = 0x24 # noqa
fload_3 = 0x25 # noqa
dload_0 = 0x26 # noqa
dload_1 = 0x27 # noqa
dload_2 = 0x28 # noqa
dload_3 = 0x29 # noqa
aload_0 = 0x2a # noqa
aload_1 = 0x2b # noqa
aload_2 = 0x2c # noqa
aload_3 = 0x2d # noqa
iaload = 0x2e # noqa
laload = 0x2f # noqa
faload = 0x30 # noqa
daload = 0x31 # noqa
aaload = 0x32 # noqa
baload = 0x33 # noqa
caload = 0x34 # noqa
saload = 0x35 # noqa
istore = 0x36 # noqa
lstore = 0x37 # noqa
fstore = 0x38 # noqa
dstore = 0x39 # noqa
astore = 0x3a # noqa
istore_0 = 0x3b # noqa
istore_1 = 0x3c # noqa
istore_2 = 0x3d # noqa
istore_3 = 0x3e # noqa
lstore_0 = 0x3f # noqa
lstore_1 = 0x40 # noqa
lstore_2 = 0x41 # noqa
lstore_3 = 0x42 # noqa
fstore_0 = 0x43 # noqa
fstore_1 = 0x44 # noqa
fstore_2 = 0x45 # noqa
fstore_3 = 0x46 # noqa
dstore_0 = 0x47 # noqa
dstore_1 = 0x48 # noqa
dstore_2 = 0x49 # noqa
dstore_3 = 0x4a # noqa
astore_0 = 0x4b # noqa
astore_1 = 0x4c # noqa
astore_2 = 0x4d # noqa
astore_3 = 0x4e # noqa
iastore = 0x4f # noqa
lastore = 0x50 # noqa
fastore = 0x51 # noqa
dastore = 0x52 # noqa
aastore = 0x53 # noqa
bastore = 0x54 # noqa
castore = 0x55 # noqa
sastore = 0x56 # noqa
pop = 0x57 # noqa
pop2 = 0x58 # noqa
dup = 0x59 # noqa
dup_x1 = 0x5a # noqa
dup_x2 = 0x5b # noqa
dup2 = 0x5c # noqa
dup2_x1 = 0x5d # noqa
dup2_x2 = 0x5e # noqa
swap = 0x5f # noqa
iadd = 0x60 # noqa
ladd = 0x61 # noqa
fadd = 0x62 # noqa
dadd = 0x63 # noqa
isub = 0x64 # noqa
lsub = 0x65 # noqa
fsub = 0x66 # noqa
dsub = 0x67 # noqa
imul = 0x68 # noqa
lmul = 0x69 # noqa
fmul = 0x6a # noqa
dmul = 0x6b # noqa
idiv = 0x6c # noqa
ldiv = 0x6d # noqa
fdiv = 0x6e # noqa
ddiv = 0x6f # noqa
irem = 0x70 # noqa
lrem = 0x71 # noqa
frem = 0x72 # noqa
drem = 0x73 # noqa
ineg = 0x74 # noqa
lneg = 0x75 # noqa
fneg = 0x76 # noqa
dneg = 0x77 # noqa
ishl = 0x78 # noqa
lshl = 0x79 # noqa
ishr = 0x7a # noqa
lshr = 0x7b # noqa
iushr = 0x7c # noqa
lushr = 0x7d # noqa
iand = 0x7e # noqa
land = 0x7f # noqa
ior = 0x80 # noqa
lor = 0x81 # noqa
ixor = 0x82 # noqa
lxor = 0x83 # noqa
iinc = 0x84 # noqa
i2l = 0x85 # noqa
i2f = 0x86 # noqa
i2d = 0x87 # noqa
l2i = 0x88 # noqa
l2f = 0x89 # noqa
l2d = 0x8a # noqa
f2i = 0x8b # noqa
f2l = 0x8c # noqa
f2d = 0x8d # noqa
d2i = 0x8e # noqa
d2l = 0x8f # noqa
d2f = 0x90 # noqa
i2b = 0x91 # noqa
i2c = 0x92 # noqa
i2s = 0x93 # noqa
lcmp = 0x94 # noqa
fcmpl = 0x95 # noqa
fcmpg = 0x96 # noqa
dcmpl = 0x97 # noqa
dcmpg = 0x98 # noqa
ifeq = 0x99 # noqa
ifne = 0x9a # noqa
iflt = 0x9b # noqa
ifge = 0x9c # noqa
ifgt = 0x9d # noqa
ifle = 0x9e # noqa
if_icmpeq = 0x9f # noqa
if_icmpne = 0xa0 # noqa
if_icmplt = 0xa1 # noqa
if_icmpge = 0xa2 # noqa
if_icmpgt = 0xa3 # noqa
if_icmple = 0xa4 # noqa
if_acmpeq = 0xa5 # noqa
if_acmpne = 0xa6 # noqa
goto = 0xa7 # noqa
jsr = 0xa8 # noqa
ret = 0xa9 # noqa
tableswitch = 0xaa # noqa
lookupswitch = 0xab # noqa
ireturn = 0xac # noqa
lreturn = 0xad # noqa
freturn = 0xae # noqa
dreturn = 0xaf # noqa
areturn = 0xb0 # noqa
vreturn = 0xb1 # noqa
getstatic = 0xb2 # noqa
putstatic = 0xb3 # noqa
getfield = 0xb4 # noqa
putfield = 0xb5 # noqa
invokevirtual = 0xb6 # noqa
invokespecial = 0xb7 # noqa
invokestatic = 0xb8 # noqa
invokeinterface = 0xb9 # noqa
invokedynamic = 0xba # noqa
new = 0xbb # noqa
newarray = 0xbc # noqa
anewarray = 0xbd # noqa
arraylength = 0xbe # noqa
athrow = 0xbf # noqa
checkcast = 0xc0 # noqa
instanceof = 0xc1 # noqa
monitorenter = 0xc2 # noqa
monitorexit = 0xc3 # noqa
wide = 0xc4 # noqa
multianewarray = 0xc5 # noqa
ifnull = 0xc6 # noqa
ifnonnull = 0xc7 # noqa
goto_w = 0xc8 # noqa
jsr_w = 0xc9 # noqa
dbgbreak = 0xca # noqa
impdep1 = 0xfe # noqa
impdep2 = 0xff # noqa
def __repr__(self) -> str:
return self.name
class JvBaseType(IntEnum):
BOOLEAN = 0x4 # noqa
CHAR = 0x5 # noqa
FLOAT = 0x6 # noqa
DOUBLE = 0x7 # noqa
BYTE = 0x8 # noqa
SHORT = 0x9 # noqa
INT = 0xA # noqa
LONG = 0xB # noqa
def __repr__(self) -> str:
return self.name
class JvTypePath:
def __init__(self, object_path):
self._path = '.'.join(str(object_path).split('/'))
def __repr__(self):
return self._path
class JvOpCode(Struct):
OPC_ARGMAP = {
opc.bipush : 'b',
opc.sipush : 'h',
opc.ldc : 'B',
opc.ldc_w : 'H',
opc.ldc2_w : 'H',
opc.iload : 'B',
opc.lload : 'B',
opc.fload : 'B',
opc.dload : 'B',
opc.aload : 'B',
opc.istore : 'B',
opc.lstore : 'B',
opc.fstore : 'B',
opc.dstore : 'B',
opc.astore : 'B',
opc.iinc : 'Bb',
opc.ifeq : 'H',
opc.ifne : 'H',
opc.iflt : 'H',
opc.ifge : 'H',
opc.ifgt : 'H',
opc.ifle : 'H',
opc.if_icmpeq : 'H',
opc.if_icmpne : 'H',
opc.if_icmplt : 'H',
opc.if_icmpge : 'H',
opc.if_icmpgt : 'H',
opc.if_icmple : 'H',
opc.if_acmpeq : 'H',
opc.if_acmpne : 'H',
opc.goto : 'H',
opc.jsr : 'H',
opc.ret : 'B',
opc.getstatic : 'H',
opc.putstatic : 'H',
opc.getfield : 'H',
opc.putfield : 'H',
opc.invokevirtual : 'H',
opc.invokespecial : 'H',
opc.invokestatic : 'H',
opc.invokeinterface : 'HBx',
opc.invokedynamic : 'Hxx',
opc.new : 'H',
opc.anewarray : 'H',
opc.checkcast : 'H',
opc.instanceof : 'H',
opc.multianewarray : 'HB',
opc.ifnull : 'H',
opc.ifnonnull : 'H',
opc.goto_w : 'L',
opc.jsr_w : 'L',
}
OPC_CONSTPOOL = {
opc.ldc,
opc.ldc_w,
opc.ldc2_w,
opc.getstatic,
opc.putstatic,
opc.getfield,
opc.putfield,
opc.invokevirtual,
opc.invokespecial,
opc.invokestatic,
opc.new,
opc.anewarray,
opc.checkcast,
opc.instanceof,
opc.multianewarray,
}
def __getitem__(self, k):
return self.arguments[k]
def __init__(self, reader: StructReader, pool: list):
with StreamDetour(reader):
self.code = opc(reader.read_byte())
self.table: dict[int, int] | None = None
try:
fmt = self.OPC_ARGMAP[self.code]
except KeyError:
self.arguments = []
else:
self.arguments = list(reader.read_struct(fmt))
if self.code == opc.newarray:
self.arguments = [JvBaseType(reader.read_byte())]
elif self.code in self.OPC_CONSTPOOL:
try:
self.arguments[0] = pool[self.arguments[0] - 1]
except (AttributeError, IndexError):
pass
if self.code == opc.new:
self.arguments[0] = JvTypePath(self.arguments[0])
elif self.code == opc.lookupswitch:
reader.byte_align(blocksize=4)
default, npairs = reader.read_struct('LL')
pairs = reader.read_struct(F'{npairs * 2}L')
self.table = dict(zip(*([iter(pairs)] * 2)))
self.table[None] = default
elif self.code == opc.tableswitch:
reader.byte_align(blocksize=4)
default, low, high = reader.read_struct('LLL')
assert low <= high
offsets = reader.read_struct(F'{high - low + 1}L')
self.table = {k + low: offset for k, offset in enumerate(offsets)}
self.table[None] = default
elif self.code == opc.wide:
argop = opc(reader.u8())
self.arguments = (argop, reader.u16())
if argop == opc.iinc:
self.arguments += reader.i16(),
else:
assert argop in (
opc.iload, opc.istore,
opc.fload, opc.fstore,
opc.aload, opc.astore,
opc.lload, opc.lstore,
opc.dload, opc.dstore,
opc.ret)
offset = reader.tell()
self.raw = bytes(reader.read(offset - reader.tell()))
def __bytes__(self):
return self.raw
class JvException(Struct):
def __init__(self, reader: StructReader):
self.start = reader.u16()
self.end = reader.u16()
self.handler = reader.u16()
self.catch = reader.u16()
class JvCode(Struct):
def __init__(self, reader: StructReader, pool: list):
reader.bigendian = True
self.max_stack = reader.u16()
self.max_locals = reader.u16()
self.disassembly: list[JvOpCode] = []
with StructReader(reader.read(reader.u32())) as code:
code.bigendian = True
while not code.eof:
self.disassembly.append(JvOpCode.Parse(code, pool=pool))
self.exceptions = [JvException(reader ) for _ in range(reader.u16())] # noqa
self.attributes = [JvAttribute(reader, pool) for _ in range(reader.u16())] # noqa
class JvClassFile(Struct):
TYPEHANDLER: dict[JvConstType, type[Struct]] = {
JvConstType.Class : JvString,
JvConstType.String : JvString,
JvConstType.Field : JvClassProperty,
JvConstType.Method : JvClassProperty,
JvConstType.InterfaceMethod : JvClassProperty,
JvConstType.NameAndType : JvNameAndType,
JvConstType.MethodHandle : JvMethodHandle,
JvConstType.MethodType : JvString,
JvConstType.Dynamic : JvDynamic,
JvConstType.InvokeDynamic : JvDynamic,
JvConstType.Module : JvString,
JvConstType.Package : JvString,
}
this: JvString = Index(JvString)
parent: JvString = Index(JvString)
def __init__(self, reader: StructReader):
reader.bigendian = True
if reader.read(4).hex() != 'cafebabe':
raise ValueError('class file magic missing.')
minor = reader.u16()
major = reader.u16()
self.version = (major, minor)
self.pool: list[Struct | int | float | str] = []
self._read_pool(reader)
self.strings: list[str] = {
s.value for s in self.pool if isinstance(s, Struct) and s.tag == JvConstType.String}
self.access = JvAccessFlags(reader)
self.this = reader.u16()
self.parent = reader.u16()
try:
self.interfaces = [self.pool[reader.u16()]
for _ in range(reader.u16())]
except IndexError:
raise ValueError('Failed parsing Interfaces.')
try:
self.fields = [JvClassMember(reader, pool=self.pool)
for _ in range(reader.u16())]
except IndexError:
raise ValueError('Failed parsing Fields.')
try:
self.methods = [JvClassMember(reader, pool=self.pool)
for _ in range(reader.u16())]
except IndexError:
raise ValueError('Failed parsing Methods.')
try:
self.attributes = [JvAttribute(reader, pool=self.pool)
for _ in range(reader.u16())]
except IndexError:
raise ValueError('Failed parsing Attributes.')
@staticmethod
def decode_utf8m(string: buf) -> str:
"""
Based on the following code:
https://gist.github.com/BarelyAliveMau5/000e7e453b6d4ebd0cb06f39bc2e7aec
Given in answer to the following SO question:
https://stackoverflow.com/a/48037020
"""
new_string = bytearray()
length = len(string)
i = 0
while i < length:
byte1 = string[i]
if (byte1 & 0x80) == 0:
new_string.append(byte1)
elif (byte1 & 0xE0) == 0xC0:
i += 1
byte2 = string[i]
if byte1 != 0xC0 or byte2 != 0x80:
new_string.append(byte1)
new_string.append(byte2)
else:
new_string.append(0)
elif (byte1 & 0xF0) == 0xE0:
i += 1
byte2 = string[i]
i += 1
byte3 = string[i]
if i + 3 < length and byte1 == 0xED and (byte2 & 0xF0) == 0xA0:
byte4 = string[i + 1]
byte5 = string[i + 2]
byte6 = string[i + 3]
if byte4 == 0xED and (byte5 & 0xF0) == 0xB0:
i += 3
u21 = ((byte2 & 0x0F) + 1) << 16
u21 += (byte3 & 0x3F) << 10
u21 += (byte5 & 0x0F) << 6
u21 += (byte6 & 0x3F)
new_string.append(0xF0 + ((u21 >> 18) & 0x07))
new_string.append(0x80 + ((u21 >> 12) & 0x3F))
new_string.append(0x80 + ((u21 >> 6) & 0x3F))
new_string.append(0x80 + (u21 & 0x3F))
continue
new_string.append(byte1)
new_string.append(byte2)
new_string.append(byte3)
i += 1
return new_string.decode('utf8')
def _read_pool(self, reader: StructReader):
assert not self.pool, 'pool can only be read once.'
size = reader.u16() - 1
reserved_slot = False
for _ in range(size):
if reserved_slot:
self.pool.append(NotImplemented)
reserved_slot = False
continue
tid = reader.read_byte()
try:
tag = JvConstType(tid)
except KeyError:
raise ValueError(F'Encountered invalid type specifier {tid:02X}.')
if tag == JvConstType.Utf8:
size = reader.u16()
data = reader.read(size)
data = self.decode_utf8m(data)
self.pool.append(data)
continue
try:
tf, reserved_slot = {
JvConstType.Long : ('Q', True),
JvConstType.Double : ('d', True),
JvConstType.Int : ('I', False),
JvConstType.Float : ('f', False),
}[tag]
except KeyError:
JvType = self.TYPEHANDLER[tag]
self.pool.append(JvType(reader, pool=self.pool, tag=tag))
else:
self.pool.append(reader.read_struct(tf))
continue
Classes
class opc (*args, **kwds)-
Enum where members are also (and must be) ints
Expand source code Browse git
class opc(IntEnum): nop = 0x00 # noqa aconst_null = 0x01 # noqa iconst_m1 = 0x02 # noqa iconst_0 = 0x03 # noqa iconst_1 = 0x04 # noqa iconst_2 = 0x05 # noqa iconst_3 = 0x06 # noqa iconst_4 = 0x07 # noqa iconst_5 = 0x08 # noqa lconst_0 = 0x09 # noqa lconst_1 = 0x0a # noqa fconst_0 = 0x0b # noqa fconst_1 = 0x0c # noqa fconst_2 = 0x0d # noqa dconst_0 = 0x0e # noqa dconst_1 = 0x0f # noqa bipush = 0x10 # noqa sipush = 0x11 # noqa ldc = 0x12 # noqa ldc_w = 0x13 # noqa ldc2_w = 0x14 # noqa iload = 0x15 # noqa lload = 0x16 # noqa fload = 0x17 # noqa dload = 0x18 # noqa aload = 0x19 # noqa iload_0 = 0x1a # noqa iload_1 = 0x1b # noqa iload_2 = 0x1c # noqa iload_3 = 0x1d # noqa lload_0 = 0x1e # noqa lload_1 = 0x1f # noqa lload_2 = 0x20 # noqa lload_3 = 0x21 # noqa fload_0 = 0x22 # noqa fload_1 = 0x23 # noqa fload_2 = 0x24 # noqa fload_3 = 0x25 # noqa dload_0 = 0x26 # noqa dload_1 = 0x27 # noqa dload_2 = 0x28 # noqa dload_3 = 0x29 # noqa aload_0 = 0x2a # noqa aload_1 = 0x2b # noqa aload_2 = 0x2c # noqa aload_3 = 0x2d # noqa iaload = 0x2e # noqa laload = 0x2f # noqa faload = 0x30 # noqa daload = 0x31 # noqa aaload = 0x32 # noqa baload = 0x33 # noqa caload = 0x34 # noqa saload = 0x35 # noqa istore = 0x36 # noqa lstore = 0x37 # noqa fstore = 0x38 # noqa dstore = 0x39 # noqa astore = 0x3a # noqa istore_0 = 0x3b # noqa istore_1 = 0x3c # noqa istore_2 = 0x3d # noqa istore_3 = 0x3e # noqa lstore_0 = 0x3f # noqa lstore_1 = 0x40 # noqa lstore_2 = 0x41 # noqa lstore_3 = 0x42 # noqa fstore_0 = 0x43 # noqa fstore_1 = 0x44 # noqa fstore_2 = 0x45 # noqa fstore_3 = 0x46 # noqa dstore_0 = 0x47 # noqa dstore_1 = 0x48 # noqa dstore_2 = 0x49 # noqa dstore_3 = 0x4a # noqa astore_0 = 0x4b # noqa astore_1 = 0x4c # noqa astore_2 = 0x4d # noqa astore_3 = 0x4e # noqa iastore = 0x4f # noqa lastore = 0x50 # noqa fastore = 0x51 # noqa dastore = 0x52 # noqa aastore = 0x53 # noqa bastore = 0x54 # noqa castore = 0x55 # noqa sastore = 0x56 # noqa pop = 0x57 # noqa pop2 = 0x58 # noqa dup = 0x59 # noqa dup_x1 = 0x5a # noqa dup_x2 = 0x5b # noqa dup2 = 0x5c # noqa dup2_x1 = 0x5d # noqa dup2_x2 = 0x5e # noqa swap = 0x5f # noqa iadd = 0x60 # noqa ladd = 0x61 # noqa fadd = 0x62 # noqa dadd = 0x63 # noqa isub = 0x64 # noqa lsub = 0x65 # noqa fsub = 0x66 # noqa dsub = 0x67 # noqa imul = 0x68 # noqa lmul = 0x69 # noqa fmul = 0x6a # noqa dmul = 0x6b # noqa idiv = 0x6c # noqa ldiv = 0x6d # noqa fdiv = 0x6e # noqa ddiv = 0x6f # noqa irem = 0x70 # noqa lrem = 0x71 # noqa frem = 0x72 # noqa drem = 0x73 # noqa ineg = 0x74 # noqa lneg = 0x75 # noqa fneg = 0x76 # noqa dneg = 0x77 # noqa ishl = 0x78 # noqa lshl = 0x79 # noqa ishr = 0x7a # noqa lshr = 0x7b # noqa iushr = 0x7c # noqa lushr = 0x7d # noqa iand = 0x7e # noqa land = 0x7f # noqa ior = 0x80 # noqa lor = 0x81 # noqa ixor = 0x82 # noqa lxor = 0x83 # noqa iinc = 0x84 # noqa i2l = 0x85 # noqa i2f = 0x86 # noqa i2d = 0x87 # noqa l2i = 0x88 # noqa l2f = 0x89 # noqa l2d = 0x8a # noqa f2i = 0x8b # noqa f2l = 0x8c # noqa f2d = 0x8d # noqa d2i = 0x8e # noqa d2l = 0x8f # noqa d2f = 0x90 # noqa i2b = 0x91 # noqa i2c = 0x92 # noqa i2s = 0x93 # noqa lcmp = 0x94 # noqa fcmpl = 0x95 # noqa fcmpg = 0x96 # noqa dcmpl = 0x97 # noqa dcmpg = 0x98 # noqa ifeq = 0x99 # noqa ifne = 0x9a # noqa iflt = 0x9b # noqa ifge = 0x9c # noqa ifgt = 0x9d # noqa ifle = 0x9e # noqa if_icmpeq = 0x9f # noqa if_icmpne = 0xa0 # noqa if_icmplt = 0xa1 # noqa if_icmpge = 0xa2 # noqa if_icmpgt = 0xa3 # noqa if_icmple = 0xa4 # noqa if_acmpeq = 0xa5 # noqa if_acmpne = 0xa6 # noqa goto = 0xa7 # noqa jsr = 0xa8 # noqa ret = 0xa9 # noqa tableswitch = 0xaa # noqa lookupswitch = 0xab # noqa ireturn = 0xac # noqa lreturn = 0xad # noqa freturn = 0xae # noqa dreturn = 0xaf # noqa areturn = 0xb0 # noqa vreturn = 0xb1 # noqa getstatic = 0xb2 # noqa putstatic = 0xb3 # noqa getfield = 0xb4 # noqa putfield = 0xb5 # noqa invokevirtual = 0xb6 # noqa invokespecial = 0xb7 # noqa invokestatic = 0xb8 # noqa invokeinterface = 0xb9 # noqa invokedynamic = 0xba # noqa new = 0xbb # noqa newarray = 0xbc # noqa anewarray = 0xbd # noqa arraylength = 0xbe # noqa athrow = 0xbf # noqa checkcast = 0xc0 # noqa instanceof = 0xc1 # noqa monitorenter = 0xc2 # noqa monitorexit = 0xc3 # noqa wide = 0xc4 # noqa multianewarray = 0xc5 # noqa ifnull = 0xc6 # noqa ifnonnull = 0xc7 # noqa goto_w = 0xc8 # noqa jsr_w = 0xc9 # noqa dbgbreak = 0xca # noqa impdep1 = 0xfe # noqa impdep2 = 0xff # noqa def __repr__(self) -> str: return self.nameAncestors
- enum.IntEnum
- builtins.int
- enum.ReprEnum
- enum.Enum
Class variables
var nop-
The type of the None singleton.
var aconst_null-
The type of the None singleton.
var iconst_m1-
The type of the None singleton.
var iconst_0-
The type of the None singleton.
var iconst_1-
The type of the None singleton.
var iconst_2-
The type of the None singleton.
var iconst_3-
The type of the None singleton.
var iconst_4-
The type of the None singleton.
var iconst_5-
The type of the None singleton.
var lconst_0-
The type of the None singleton.
var lconst_1-
The type of the None singleton.
var fconst_0-
The type of the None singleton.
var fconst_1-
The type of the None singleton.
var fconst_2-
The type of the None singleton.
var dconst_0-
The type of the None singleton.
var dconst_1-
The type of the None singleton.
var bipush-
The type of the None singleton.
var sipush-
The type of the None singleton.
var ldc-
The type of the None singleton.
var ldc_w-
The type of the None singleton.
var ldc2_w-
The type of the None singleton.
var iload-
The type of the None singleton.
var lload-
The type of the None singleton.
var fload-
The type of the None singleton.
var dload-
The type of the None singleton.
var aload-
The type of the None singleton.
var iload_0-
The type of the None singleton.
var iload_1-
The type of the None singleton.
var iload_2-
The type of the None singleton.
var iload_3-
The type of the None singleton.
var lload_0-
The type of the None singleton.
var lload_1-
The type of the None singleton.
var lload_2-
The type of the None singleton.
var lload_3-
The type of the None singleton.
var fload_0-
The type of the None singleton.
var fload_1-
The type of the None singleton.
var fload_2-
The type of the None singleton.
var fload_3-
The type of the None singleton.
var dload_0-
The type of the None singleton.
var dload_1-
The type of the None singleton.
var dload_2-
The type of the None singleton.
var dload_3-
The type of the None singleton.
var aload_0-
The type of the None singleton.
var aload_1-
The type of the None singleton.
var aload_2-
The type of the None singleton.
var aload_3-
The type of the None singleton.
var iaload-
The type of the None singleton.
var laload-
The type of the None singleton.
var faload-
The type of the None singleton.
var daload-
The type of the None singleton.
var aaload-
The type of the None singleton.
var baload-
The type of the None singleton.
var caload-
The type of the None singleton.
var saload-
The type of the None singleton.
var istore-
The type of the None singleton.
var lstore-
The type of the None singleton.
var fstore-
The type of the None singleton.
var dstore-
The type of the None singleton.
var astore-
The type of the None singleton.
var istore_0-
The type of the None singleton.
var istore_1-
The type of the None singleton.
var istore_2-
The type of the None singleton.
var istore_3-
The type of the None singleton.
var lstore_0-
The type of the None singleton.
var lstore_1-
The type of the None singleton.
var lstore_2-
The type of the None singleton.
var lstore_3-
The type of the None singleton.
var fstore_0-
The type of the None singleton.
var fstore_1-
The type of the None singleton.
var fstore_2-
The type of the None singleton.
var fstore_3-
The type of the None singleton.
var dstore_0-
The type of the None singleton.
var dstore_1-
The type of the None singleton.
var dstore_2-
The type of the None singleton.
var dstore_3-
The type of the None singleton.
var astore_0-
The type of the None singleton.
var astore_1-
The type of the None singleton.
var astore_2-
The type of the None singleton.
var astore_3-
The type of the None singleton.
var iastore-
The type of the None singleton.
var lastore-
The type of the None singleton.
var fastore-
The type of the None singleton.
var dastore-
The type of the None singleton.
var aastore-
The type of the None singleton.
var bastore-
The type of the None singleton.
var castore-
The type of the None singleton.
var sastore-
The type of the None singleton.
var pop-
The type of the None singleton.
var pop2-
The type of the None singleton.
var dup-
The type of the None singleton.
var dup_x1-
The type of the None singleton.
var dup_x2-
The type of the None singleton.
var dup2-
The type of the None singleton.
var dup2_x1-
The type of the None singleton.
var dup2_x2-
The type of the None singleton.
var swap-
The type of the None singleton.
var iadd-
The type of the None singleton.
var ladd-
The type of the None singleton.
var fadd-
The type of the None singleton.
var dadd-
The type of the None singleton.
var isub-
The type of the None singleton.
var lsub-
The type of the None singleton.
var fsub-
The type of the None singleton.
var dsub-
The type of the None singleton.
var imul-
The type of the None singleton.
var lmul-
The type of the None singleton.
var fmul-
The type of the None singleton.
var dmul-
The type of the None singleton.
var idiv-
The type of the None singleton.
var ldiv-
The type of the None singleton.
var fdiv-
The type of the None singleton.
var ddiv-
The type of the None singleton.
var irem-
The type of the None singleton.
var lrem-
The type of the None singleton.
var frem-
The type of the None singleton.
var drem-
The type of the None singleton.
var ineg-
The type of the None singleton.
var lneg-
The type of the None singleton.
var fneg-
The type of the None singleton.
var dneg-
The type of the None singleton.
var ishl-
The type of the None singleton.
var lshl-
The type of the None singleton.
var ishr-
The type of the None singleton.
var lshr-
The type of the None singleton.
var iushr-
The type of the None singleton.
var lushr-
The type of the None singleton.
var iand-
The type of the None singleton.
var land-
The type of the None singleton.
var ior-
The type of the None singleton.
var lor-
The type of the None singleton.
var ixor-
The type of the None singleton.
var lxor-
The type of the None singleton.
var iinc-
The type of the None singleton.
var i2l-
The type of the None singleton.
var i2f-
The type of the None singleton.
var i2d-
The type of the None singleton.
var l2i-
The type of the None singleton.
var l2f-
The type of the None singleton.
var l2d-
The type of the None singleton.
var f2i-
The type of the None singleton.
var f2l-
The type of the None singleton.
var f2d-
The type of the None singleton.
var d2i-
The type of the None singleton.
var d2l-
The type of the None singleton.
var d2f-
The type of the None singleton.
var i2b-
The type of the None singleton.
var i2c-
The type of the None singleton.
var i2s-
The type of the None singleton.
var lcmp-
The type of the None singleton.
var fcmpl-
The type of the None singleton.
var fcmpg-
The type of the None singleton.
var dcmpl-
The type of the None singleton.
var dcmpg-
The type of the None singleton.
var ifeq-
The type of the None singleton.
var ifne-
The type of the None singleton.
var iflt-
The type of the None singleton.
var ifge-
The type of the None singleton.
var ifgt-
The type of the None singleton.
var ifle-
The type of the None singleton.
var if_icmpeq-
The type of the None singleton.
var if_icmpne-
The type of the None singleton.
var if_icmplt-
The type of the None singleton.
var if_icmpge-
The type of the None singleton.
var if_icmpgt-
The type of the None singleton.
var if_icmple-
The type of the None singleton.
var if_acmpeq-
The type of the None singleton.
var if_acmpne-
The type of the None singleton.
var goto-
The type of the None singleton.
var jsr-
The type of the None singleton.
var ret-
The type of the None singleton.
var tableswitch-
The type of the None singleton.
var lookupswitch-
The type of the None singleton.
var ireturn-
The type of the None singleton.
var lreturn-
The type of the None singleton.
var freturn-
The type of the None singleton.
var dreturn-
The type of the None singleton.
var areturn-
The type of the None singleton.
var vreturn-
The type of the None singleton.
var getstatic-
The type of the None singleton.
var putstatic-
The type of the None singleton.
var getfield-
The type of the None singleton.
var putfield-
The type of the None singleton.
var invokevirtual-
The type of the None singleton.
var invokespecial-
The type of the None singleton.
var invokestatic-
The type of the None singleton.
var invokeinterface-
The type of the None singleton.
var invokedynamic-
The type of the None singleton.
var new-
The type of the None singleton.
var newarray-
The type of the None singleton.
var anewarray-
The type of the None singleton.
var arraylength-
The type of the None singleton.
var athrow-
The type of the None singleton.
var checkcast-
The type of the None singleton.
var instanceof-
The type of the None singleton.
var monitorenter-
The type of the None singleton.
var monitorexit-
The type of the None singleton.
var wide-
The type of the None singleton.
var multianewarray-
The type of the None singleton.
var ifnull-
The type of the None singleton.
var ifnonnull-
The type of the None singleton.
var goto_w-
The type of the None singleton.
var jsr_w-
The type of the None singleton.
var dbgbreak-
The type of the None singleton.
var impdep1-
The type of the None singleton.
var impdep2-
The type of the None singleton.
class JvAccessFlags (reader)-
A class to parse structured data. A
Structclass can be instantiated as follows:foo = Struct(data, bar=29)The initialization routine of the structure will be called with a single argument
reader. If the objectdatais already aStructReader, then it will be passed asreader. Otherwise, the argument will be wrapped in aStructReader. Additional arguments to the struct are passed through.Expand source code Browse git
class JvAccessFlags(Struct): def __init__(self, reader: StructReader): ( self.MODULE, # 0x8000 self.ENUM, # 0x4000 self.ANNOTATION, # 0x2000 self.SYNTHETIC, # 0x1000 _, # ... self.ABSTRACT, # 0x0400 self.INTERFACE, # 0x0200 _, _, _, # ... self.SUPER, # 0x0020 self.FINAL, # 0x0010 _, _, _, # ... self.PUBLIC, # 0x0001 ) = reader.read_flags(16)Ancestors
- Struct
- typing.Generic
Static methods
def Parse(reader, *args, **kwargs)
class JvAttribute (reader, pool)-
A class to parse structured data. A
Structclass can be instantiated as follows:foo = Struct(data, bar=29)The initialization routine of the structure will be called with a single argument
reader. If the objectdatais already aStructReader, then it will be passed asreader. Otherwise, the argument will be wrapped in aStructReader. Additional arguments to the struct are passed through.Expand source code Browse git
class JvAttribute(JvStructWithName, Generic[ParserType]): def __init__(self, reader: StructReader, pool: list): self.pool = pool self.name = reader.u16() self.data = reader.read(reader.u32()) def parse(self, parser: type[ParserType]) -> ParserType: return parser.Parse(self.data, pool=self.pool)Ancestors
- refinery.lib.java.JvStructWithName
- refinery.lib.java._HasPoolAndTag
- Struct
- typing.Generic
Static methods
def Parse(reader, *args, **kwargs)
Instance variables
var name-
Expand source code Browse git
def __get__(self, parent, tp=None) -> AttrType: pid = id(parent) if pid not in self.__get: try: seed = self.__set[pid] except KeyError as K: raise AttributeError from K self.__get[pid] = self.resolve(parent, seed) return self.__get[pid]
Methods
def parse(self, parser)-
Expand source code Browse git
def parse(self, parser: type[ParserType]) -> ParserType: return parser.Parse(self.data, pool=self.pool)
class JvBaseType (*args, **kwds)-
Enum where members are also (and must be) ints
Expand source code Browse git
class JvBaseType(IntEnum): BOOLEAN = 0x4 # noqa CHAR = 0x5 # noqa FLOAT = 0x6 # noqa DOUBLE = 0x7 # noqa BYTE = 0x8 # noqa SHORT = 0x9 # noqa INT = 0xA # noqa LONG = 0xB # noqa def __repr__(self) -> str: return self.nameAncestors
- enum.IntEnum
- builtins.int
- enum.ReprEnum
- enum.Enum
Class variables
var BOOLEAN-
The type of the None singleton.
var CHAR-
The type of the None singleton.
var FLOAT-
The type of the None singleton.
var DOUBLE-
The type of the None singleton.
var BYTE-
The type of the None singleton.
var SHORT-
The type of the None singleton.
var INT-
The type of the None singleton.
var LONG-
The type of the None singleton.
class JvClassFile (reader)-
A class to parse structured data. A
Structclass can be instantiated as follows:foo = Struct(data, bar=29)The initialization routine of the structure will be called with a single argument
reader. If the objectdatais already aStructReader, then it will be passed asreader. Otherwise, the argument will be wrapped in aStructReader. Additional arguments to the struct are passed through.Expand source code Browse git
class JvClassFile(Struct): TYPEHANDLER: dict[JvConstType, type[Struct]] = { JvConstType.Class : JvString, JvConstType.String : JvString, JvConstType.Field : JvClassProperty, JvConstType.Method : JvClassProperty, JvConstType.InterfaceMethod : JvClassProperty, JvConstType.NameAndType : JvNameAndType, JvConstType.MethodHandle : JvMethodHandle, JvConstType.MethodType : JvString, JvConstType.Dynamic : JvDynamic, JvConstType.InvokeDynamic : JvDynamic, JvConstType.Module : JvString, JvConstType.Package : JvString, } this: JvString = Index(JvString) parent: JvString = Index(JvString) def __init__(self, reader: StructReader): reader.bigendian = True if reader.read(4).hex() != 'cafebabe': raise ValueError('class file magic missing.') minor = reader.u16() major = reader.u16() self.version = (major, minor) self.pool: list[Struct | int | float | str] = [] self._read_pool(reader) self.strings: list[str] = { s.value for s in self.pool if isinstance(s, Struct) and s.tag == JvConstType.String} self.access = JvAccessFlags(reader) self.this = reader.u16() self.parent = reader.u16() try: self.interfaces = [self.pool[reader.u16()] for _ in range(reader.u16())] except IndexError: raise ValueError('Failed parsing Interfaces.') try: self.fields = [JvClassMember(reader, pool=self.pool) for _ in range(reader.u16())] except IndexError: raise ValueError('Failed parsing Fields.') try: self.methods = [JvClassMember(reader, pool=self.pool) for _ in range(reader.u16())] except IndexError: raise ValueError('Failed parsing Methods.') try: self.attributes = [JvAttribute(reader, pool=self.pool) for _ in range(reader.u16())] except IndexError: raise ValueError('Failed parsing Attributes.') @staticmethod def decode_utf8m(string: buf) -> str: """ Based on the following code: https://gist.github.com/BarelyAliveMau5/000e7e453b6d4ebd0cb06f39bc2e7aec Given in answer to the following SO question: https://stackoverflow.com/a/48037020 """ new_string = bytearray() length = len(string) i = 0 while i < length: byte1 = string[i] if (byte1 & 0x80) == 0: new_string.append(byte1) elif (byte1 & 0xE0) == 0xC0: i += 1 byte2 = string[i] if byte1 != 0xC0 or byte2 != 0x80: new_string.append(byte1) new_string.append(byte2) else: new_string.append(0) elif (byte1 & 0xF0) == 0xE0: i += 1 byte2 = string[i] i += 1 byte3 = string[i] if i + 3 < length and byte1 == 0xED and (byte2 & 0xF0) == 0xA0: byte4 = string[i + 1] byte5 = string[i + 2] byte6 = string[i + 3] if byte4 == 0xED and (byte5 & 0xF0) == 0xB0: i += 3 u21 = ((byte2 & 0x0F) + 1) << 16 u21 += (byte3 & 0x3F) << 10 u21 += (byte5 & 0x0F) << 6 u21 += (byte6 & 0x3F) new_string.append(0xF0 + ((u21 >> 18) & 0x07)) new_string.append(0x80 + ((u21 >> 12) & 0x3F)) new_string.append(0x80 + ((u21 >> 6) & 0x3F)) new_string.append(0x80 + (u21 & 0x3F)) continue new_string.append(byte1) new_string.append(byte2) new_string.append(byte3) i += 1 return new_string.decode('utf8') def _read_pool(self, reader: StructReader): assert not self.pool, 'pool can only be read once.' size = reader.u16() - 1 reserved_slot = False for _ in range(size): if reserved_slot: self.pool.append(NotImplemented) reserved_slot = False continue tid = reader.read_byte() try: tag = JvConstType(tid) except KeyError: raise ValueError(F'Encountered invalid type specifier {tid:02X}.') if tag == JvConstType.Utf8: size = reader.u16() data = reader.read(size) data = self.decode_utf8m(data) self.pool.append(data) continue try: tf, reserved_slot = { JvConstType.Long : ('Q', True), JvConstType.Double : ('d', True), JvConstType.Int : ('I', False), JvConstType.Float : ('f', False), }[tag] except KeyError: JvType = self.TYPEHANDLER[tag] self.pool.append(JvType(reader, pool=self.pool, tag=tag)) else: self.pool.append(reader.read_struct(tf)) continueAncestors
- Struct
- typing.Generic
Class variables
var TYPEHANDLER-
The type of the None singleton.
Static methods
def decode_utf8m(string)-
Based on the following code: https://gist.github.com/BarelyAliveMau5/000e7e453b6d4ebd0cb06f39bc2e7aec Given in answer to the following SO question: https://stackoverflow.com/a/48037020
Expand source code Browse git
@staticmethod def decode_utf8m(string: buf) -> str: """ Based on the following code: https://gist.github.com/BarelyAliveMau5/000e7e453b6d4ebd0cb06f39bc2e7aec Given in answer to the following SO question: https://stackoverflow.com/a/48037020 """ new_string = bytearray() length = len(string) i = 0 while i < length: byte1 = string[i] if (byte1 & 0x80) == 0: new_string.append(byte1) elif (byte1 & 0xE0) == 0xC0: i += 1 byte2 = string[i] if byte1 != 0xC0 or byte2 != 0x80: new_string.append(byte1) new_string.append(byte2) else: new_string.append(0) elif (byte1 & 0xF0) == 0xE0: i += 1 byte2 = string[i] i += 1 byte3 = string[i] if i + 3 < length and byte1 == 0xED and (byte2 & 0xF0) == 0xA0: byte4 = string[i + 1] byte5 = string[i + 2] byte6 = string[i + 3] if byte4 == 0xED and (byte5 & 0xF0) == 0xB0: i += 3 u21 = ((byte2 & 0x0F) + 1) << 16 u21 += (byte3 & 0x3F) << 10 u21 += (byte5 & 0x0F) << 6 u21 += (byte6 & 0x3F) new_string.append(0xF0 + ((u21 >> 18) & 0x07)) new_string.append(0x80 + ((u21 >> 12) & 0x3F)) new_string.append(0x80 + ((u21 >> 6) & 0x3F)) new_string.append(0x80 + (u21 & 0x3F)) continue new_string.append(byte1) new_string.append(byte2) new_string.append(byte3) i += 1 return new_string.decode('utf8') def Parse(reader, *args, **kwargs)
Instance variables
var this-
Expand source code Browse git
def __get__(self, parent, tp=None) -> AttrType: pid = id(parent) if pid not in self.__get: try: seed = self.__set[pid] except KeyError as K: raise AttributeError from K self.__get[pid] = self.resolve(parent, seed) return self.__get[pid] var parent-
Expand source code Browse git
def __get__(self, parent, tp=None) -> AttrType: pid = id(parent) if pid not in self.__get: try: seed = self.__set[pid] except KeyError as K: raise AttributeError from K self.__get[pid] = self.resolve(parent, seed) return self.__get[pid]
class JvClassMember (reader, pool)-
A class to parse structured data. A
Structclass can be instantiated as follows:foo = Struct(data, bar=29)The initialization routine of the structure will be called with a single argument
reader. If the objectdatais already aStructReader, then it will be passed asreader. Otherwise, the argument will be wrapped in aStructReader. Additional arguments to the struct are passed through.Expand source code Browse git
class JvClassMember(JvStructWithName): descriptor: str = Index(str) def __init__(self, reader: StructReader, pool: list): self.pool = pool self.access = JvAccessFlags(reader) self.name = reader.u16() self.descriptor = reader.u16() self.attributes = [JvAttribute(reader, pool=pool) for _ in range(reader.u16())]Ancestors
- refinery.lib.java.JvStructWithName
- refinery.lib.java._HasPoolAndTag
- Struct
- typing.Generic
Static methods
def Parse(reader, *args, **kwargs)
Instance variables
var descriptor-
Expand source code Browse git
def __get__(self, parent, tp=None) -> AttrType: pid = id(parent) if pid not in self.__get: try: seed = self.__set[pid] except KeyError as K: raise AttributeError from K self.__get[pid] = self.resolve(parent, seed) return self.__get[pid]
class JvClassProperty (reader, **kwargs)-
A class to parse structured data. A
Structclass can be instantiated as follows:foo = Struct(data, bar=29)The initialization routine of the structure will be called with a single argument
reader. If the objectdatais already aStructReader, then it will be passed asreader. Otherwise, the argument will be wrapped in aStructReader. Additional arguments to the struct are passed through.Expand source code Browse git
class JvClassProperty(_HasPoolAndTag): name: JvString = Index(JvString) info: JvNameAndType = Index(JvNameAndType) def __init__(self, reader: StructReader, **kwargs): super().__init__(reader, **kwargs) self.name = reader.u16() self.info = reader.u16() def __repr__(self): name: str = str(self.name) name = '.'.join(name.split('/')) return F'{name}::{self.info}'Ancestors
- refinery.lib.java._HasPoolAndTag
- Struct
- typing.Generic
Static methods
def Parse(reader, *args, **kwargs)
Instance variables
var name-
Expand source code Browse git
def __get__(self, parent, tp=None) -> AttrType: pid = id(parent) if pid not in self.__get: try: seed = self.__set[pid] except KeyError as K: raise AttributeError from K self.__get[pid] = self.resolve(parent, seed) return self.__get[pid] var info-
Expand source code Browse git
def __get__(self, parent, tp=None) -> AttrType: pid = id(parent) if pid not in self.__get: try: seed = self.__set[pid] except KeyError as K: raise AttributeError from K self.__get[pid] = self.resolve(parent, seed) return self.__get[pid]
class JvCode (reader, pool)-
A class to parse structured data. A
Structclass can be instantiated as follows:foo = Struct(data, bar=29)The initialization routine of the structure will be called with a single argument
reader. If the objectdatais already aStructReader, then it will be passed asreader. Otherwise, the argument will be wrapped in aStructReader. Additional arguments to the struct are passed through.Expand source code Browse git
class JvCode(Struct): def __init__(self, reader: StructReader, pool: list): reader.bigendian = True self.max_stack = reader.u16() self.max_locals = reader.u16() self.disassembly: list[JvOpCode] = [] with StructReader(reader.read(reader.u32())) as code: code.bigendian = True while not code.eof: self.disassembly.append(JvOpCode.Parse(code, pool=pool)) self.exceptions = [JvException(reader ) for _ in range(reader.u16())] # noqa self.attributes = [JvAttribute(reader, pool) for _ in range(reader.u16())] # noqaAncestors
- Struct
- typing.Generic
Static methods
def Parse(reader, *args, **kwargs)
class JvConstType (*args, **kwds)-
Enum where members are also (and must be) ints
Expand source code Browse git
class JvConstType(IntEnum): Utf8 = 0x01 # noqa Int = 0x03 # noqa Float = 0x04 # noqa Long = 0x05 # noqa Double = 0x06 # noqa Class = 0x07 # noqa String = 0x08 # noqa Field = 0x09 # noqa Method = 0x0A # noqa InterfaceMethod = 0x0B # noqa NameAndType = 0x0C # noqa MethodHandle = 0x0F # noqa MethodType = 0x10 # noqa Dynamic = 0x11 # noqa InvokeDynamic = 0x12 # noqa Module = 0x13 # noqa Package = 0x14 # noqaAncestors
- enum.IntEnum
- builtins.int
- enum.ReprEnum
- enum.Enum
Class variables
var Utf8-
The type of the None singleton.
var Int-
The type of the None singleton.
var Float-
The type of the None singleton.
var Long-
The type of the None singleton.
var Double-
The type of the None singleton.
var Class-
The type of the None singleton.
var String-
The type of the None singleton.
var Field-
The type of the None singleton.
var Method-
The type of the None singleton.
var InterfaceMethod-
The type of the None singleton.
var NameAndType-
The type of the None singleton.
var MethodHandle-
The type of the None singleton.
var MethodType-
The type of the None singleton.
var Dynamic-
The type of the None singleton.
var InvokeDynamic-
The type of the None singleton.
var Module-
The type of the None singleton.
var Package-
The type of the None singleton.
class JvDynamic (reader, **kwargs)-
A class to parse structured data. A
Structclass can be instantiated as follows:foo = Struct(data, bar=29)The initialization routine of the structure will be called with a single argument
reader. If the objectdatais already aStructReader, then it will be passed asreader. Otherwise, the argument will be wrapped in aStructReader. Additional arguments to the struct are passed through.Expand source code Browse git
class JvDynamic(_HasPoolAndTag): def __init__(self, reader: StructReader, **kwargs): super().__init__(reader, **kwargs) self.bootstrap_method_attr_index = reader.u16() self.info = reader.u16()Ancestors
- refinery.lib.java._HasPoolAndTag
- Struct
- typing.Generic
Static methods
def Parse(reader, *args, **kwargs)
class JvException (reader)-
A class to parse structured data. A
Structclass can be instantiated as follows:foo = Struct(data, bar=29)The initialization routine of the structure will be called with a single argument
reader. If the objectdatais already aStructReader, then it will be passed asreader. Otherwise, the argument will be wrapped in aStructReader. Additional arguments to the struct are passed through.Expand source code Browse git
class JvException(Struct): def __init__(self, reader: StructReader): self.start = reader.u16() self.end = reader.u16() self.handler = reader.u16() self.catch = reader.u16()Ancestors
- Struct
- typing.Generic
Static methods
def Parse(reader, *args, **kwargs)
class JvMethodHandle (reader, **kwargs)-
A class to parse structured data. A
Structclass can be instantiated as follows:foo = Struct(data, bar=29)The initialization routine of the structure will be called with a single argument
reader. If the objectdatais already aStructReader, then it will be passed asreader. Otherwise, the argument will be wrapped in aStructReader. Additional arguments to the struct are passed through.Expand source code Browse git
class JvMethodHandle(_HasPoolAndTag): reference: JvClassProperty = Index(JvClassProperty) def __init__(self, reader: StructReader, **kwargs): super().__init__(reader, **kwargs) self.kind = JvMethodHandleRefKind(reader.read_byte()) self.reference = reader.u16()Ancestors
- refinery.lib.java._HasPoolAndTag
- Struct
- typing.Generic
Static methods
def Parse(reader, *args, **kwargs)
Instance variables
var reference-
Expand source code Browse git
def __get__(self, parent, tp=None) -> AttrType: pid = id(parent) if pid not in self.__get: try: seed = self.__set[pid] except KeyError as K: raise AttributeError from K self.__get[pid] = self.resolve(parent, seed) return self.__get[pid]
class JvMethodHandleRefKind (*args, **kwds)-
Enum where members are also (and must be) ints
Expand source code Browse git
class JvMethodHandleRefKind(IntEnum): GetField = 1 # noqa GetStatic = 2 # noqa PutField = 3 # noqa PutStatic = 4 # noqa InvokeVirtual = 5 # noqa InvokeStatic = 6 # noqa InvokeSpecial = 7 # noqa InvokeSpecialNew = 8 # noqa InvokeInterface = 9 # noqaAncestors
- enum.IntEnum
- builtins.int
- enum.ReprEnum
- enum.Enum
Class variables
var GetField-
The type of the None singleton.
var GetStatic-
The type of the None singleton.
var PutField-
The type of the None singleton.
var PutStatic-
The type of the None singleton.
var InvokeVirtual-
The type of the None singleton.
var InvokeStatic-
The type of the None singleton.
var InvokeSpecial-
The type of the None singleton.
var InvokeSpecialNew-
The type of the None singleton.
var InvokeInterface-
The type of the None singleton.
class JvNameAndType (reader, **kwargs)-
A class to parse structured data. A
Structclass can be instantiated as follows:foo = Struct(data, bar=29)The initialization routine of the structure will be called with a single argument
reader. If the objectdatais already aStructReader, then it will be passed asreader. Otherwise, the argument will be wrapped in aStructReader. Additional arguments to the struct are passed through.Expand source code Browse git
class JvNameAndType(JvStructWithName): descriptor: str = Index(str) def __init__(self, reader: StructReader, **kwargs): super().__init__(reader, **kwargs) self.name = reader.u16() self.descriptor = reader.u16()Ancestors
- refinery.lib.java.JvStructWithName
- refinery.lib.java._HasPoolAndTag
- Struct
- typing.Generic
Static methods
def Parse(reader, *args, **kwargs)
Instance variables
var descriptor-
Expand source code Browse git
def __get__(self, parent, tp=None) -> AttrType: pid = id(parent) if pid not in self.__get: try: seed = self.__set[pid] except KeyError as K: raise AttributeError from K self.__get[pid] = self.resolve(parent, seed) return self.__get[pid]
class JvOpCode (reader, pool)-
A class to parse structured data. A
Structclass can be instantiated as follows:foo = Struct(data, bar=29)The initialization routine of the structure will be called with a single argument
reader. If the objectdatais already aStructReader, then it will be passed asreader. Otherwise, the argument will be wrapped in aStructReader. Additional arguments to the struct are passed through.Expand source code Browse git
class JvOpCode(Struct): OPC_ARGMAP = { opc.bipush : 'b', opc.sipush : 'h', opc.ldc : 'B', opc.ldc_w : 'H', opc.ldc2_w : 'H', opc.iload : 'B', opc.lload : 'B', opc.fload : 'B', opc.dload : 'B', opc.aload : 'B', opc.istore : 'B', opc.lstore : 'B', opc.fstore : 'B', opc.dstore : 'B', opc.astore : 'B', opc.iinc : 'Bb', opc.ifeq : 'H', opc.ifne : 'H', opc.iflt : 'H', opc.ifge : 'H', opc.ifgt : 'H', opc.ifle : 'H', opc.if_icmpeq : 'H', opc.if_icmpne : 'H', opc.if_icmplt : 'H', opc.if_icmpge : 'H', opc.if_icmpgt : 'H', opc.if_icmple : 'H', opc.if_acmpeq : 'H', opc.if_acmpne : 'H', opc.goto : 'H', opc.jsr : 'H', opc.ret : 'B', opc.getstatic : 'H', opc.putstatic : 'H', opc.getfield : 'H', opc.putfield : 'H', opc.invokevirtual : 'H', opc.invokespecial : 'H', opc.invokestatic : 'H', opc.invokeinterface : 'HBx', opc.invokedynamic : 'Hxx', opc.new : 'H', opc.anewarray : 'H', opc.checkcast : 'H', opc.instanceof : 'H', opc.multianewarray : 'HB', opc.ifnull : 'H', opc.ifnonnull : 'H', opc.goto_w : 'L', opc.jsr_w : 'L', } OPC_CONSTPOOL = { opc.ldc, opc.ldc_w, opc.ldc2_w, opc.getstatic, opc.putstatic, opc.getfield, opc.putfield, opc.invokevirtual, opc.invokespecial, opc.invokestatic, opc.new, opc.anewarray, opc.checkcast, opc.instanceof, opc.multianewarray, } def __getitem__(self, k): return self.arguments[k] def __init__(self, reader: StructReader, pool: list): with StreamDetour(reader): self.code = opc(reader.read_byte()) self.table: dict[int, int] | None = None try: fmt = self.OPC_ARGMAP[self.code] except KeyError: self.arguments = [] else: self.arguments = list(reader.read_struct(fmt)) if self.code == opc.newarray: self.arguments = [JvBaseType(reader.read_byte())] elif self.code in self.OPC_CONSTPOOL: try: self.arguments[0] = pool[self.arguments[0] - 1] except (AttributeError, IndexError): pass if self.code == opc.new: self.arguments[0] = JvTypePath(self.arguments[0]) elif self.code == opc.lookupswitch: reader.byte_align(blocksize=4) default, npairs = reader.read_struct('LL') pairs = reader.read_struct(F'{npairs * 2}L') self.table = dict(zip(*([iter(pairs)] * 2))) self.table[None] = default elif self.code == opc.tableswitch: reader.byte_align(blocksize=4) default, low, high = reader.read_struct('LLL') assert low <= high offsets = reader.read_struct(F'{high - low + 1}L') self.table = {k + low: offset for k, offset in enumerate(offsets)} self.table[None] = default elif self.code == opc.wide: argop = opc(reader.u8()) self.arguments = (argop, reader.u16()) if argop == opc.iinc: self.arguments += reader.i16(), else: assert argop in ( opc.iload, opc.istore, opc.fload, opc.fstore, opc.aload, opc.astore, opc.lload, opc.lstore, opc.dload, opc.dstore, opc.ret) offset = reader.tell() self.raw = bytes(reader.read(offset - reader.tell())) def __bytes__(self): return self.rawAncestors
- Struct
- typing.Generic
Class variables
var OPC_ARGMAP-
The type of the None singleton.
var OPC_CONSTPOOL-
The type of the None singleton.
Static methods
def Parse(reader, *args, **kwargs)
class JvString (reader, **kwargs)-
A class to parse structured data. A
Structclass can be instantiated as follows:foo = Struct(data, bar=29)The initialization routine of the structure will be called with a single argument
reader. If the objectdatais already aStructReader, then it will be passed asreader. Otherwise, the argument will be wrapped in aStructReader. Additional arguments to the struct are passed through.Expand source code Browse git
class JvString(_HasPoolAndTag): value: str = Index(str) def __init__(self, reader: StructReader, **kwargs): super().__init__(reader, **kwargs) self.value = reader.u16() def __repr__(self): return repr(self.value) def __str__(self): return self.valueAncestors
- refinery.lib.java._HasPoolAndTag
- Struct
- typing.Generic
Static methods
def Parse(reader, *args, **kwargs)
Instance variables
var value-
Expand source code Browse git
def __get__(self, parent, tp=None) -> AttrType: pid = id(parent) if pid not in self.__get: try: seed = self.__set[pid] except KeyError as K: raise AttributeError from K self.__get[pid] = self.resolve(parent, seed) return self.__get[pid]