Skip to content

Commit

Permalink
list -> bytearray
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Grosse committed Jan 29, 2016
1 parent 0f528df commit 97b1d3f
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 42 deletions.
12 changes: 3 additions & 9 deletions enjarify/byteio.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,10 @@ def readCStr(self):

class Writer:
def __init__(self):
self.strings = []
self.len = 0
self.buf = bytearray()

def write(self, s):
if isinstance(s, Writer):
self.strings.extend(s.strings)
self.len += s.len
else:
self.strings.append(s)
self.len += len(s)
self.buf += s

def _pack(self, fmt, arg):
return self.write(struct.pack(fmt, arg))
Expand All @@ -83,4 +77,4 @@ def u32(self, x): return self._pack('>I', x)
def u64(self, x): return self._pack('>Q', x)

def toBytes(self):
return b''.join(self.strings)
return bytes(self.buf)
36 changes: 18 additions & 18 deletions enjarify/jvm/constants/calc.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,17 @@ def _calcFloat(x):

ex_combine_op = FDIV if exponent < 0 else FMUL
exponent = abs(exponent)
exponent_parts = []
exponent_parts = bytearray()
while exponent >= 63: # max 2 iterations since -149 <= exp <= 104
exponent_parts.append(bytes([LCONST_1, ICONST_M1, LSHL, L2F, ex_combine_op]))
exponent_parts.extend([LCONST_1, ICONST_M1, LSHL, L2F, ex_combine_op])
mantissa = -mantissa
exponent -= 63

if exponent > 0:
exponent_parts.append(bytes([LCONST_1]))
exponent_parts.append(_calcInt(exponent))
exponent_parts.append(bytes([LSHL, L2F, ex_combine_op]))
return _calcInt(mantissa) + bytes([I2F]) + b''.join(exponent_parts)
exponent_parts.append(LCONST_1)
exponent_parts.extend(_calcInt(exponent))
exponent_parts.extend([LSHL, L2F, ex_combine_op])
return _calcInt(mantissa) + bytes([I2F]) + exponent_parts

def _calcDouble(x):
assert(x == normalizeDouble(x))
Expand All @@ -117,44 +117,44 @@ def _calcDouble(x):
mantissa = -mantissa

abs_exponent = abs(exponent)
exponent_parts = []
exponent_parts = bytearray()

part63 = abs_exponent // 63
if part63: #create *63 part of exponent by repeated squaring
# use 2^-x instead of calculating 2^x and dividing to avoid overflow in
# case we need 2^-1071
if exponent < 0: # -2^-63
exponent_parts.append(bytes([DCONST_1, LCONST_1, ICONST_M1, LSHL, L2D, DDIV]))
exponent_parts.extend([DCONST_1, LCONST_1, ICONST_M1, LSHL, L2D, DDIV])
else: # -2^63
exponent_parts.append(bytes([LCONST_1, ICONST_M1, LSHL, L2D]))
exponent_parts.extend([LCONST_1, ICONST_M1, LSHL, L2D])
# adjust sign of mantissa for odd powers since we're actually using -2^63 rather than positive
if part63 & 1:
mantissa = -mantissa

last_needed = part63 & 1
stack = [1] # Not actually required to compute the results - it's just used for a sanity check
for bi in range(1, part63.bit_length()):
exponent_parts.append(bytes([DUP2]))
exponent_parts.append(DUP2)
stack.append(stack[-1])
if last_needed:
exponent_parts.append(bytes([DUP2]))
exponent_parts.append(DUP2)
stack.append(stack[-1])
exponent_parts.append(bytes([DMUL]))
exponent_parts.append(DMUL)
stack.append(stack.pop() + stack.pop())
last_needed = part63 & (1<<bi)

assert(sum(stack) == part63 and len(stack) == bin(part63).count('1'))
exponent_parts.append(bytes([DMUL] * bin(part63).count('1')))
exponent_parts.extend([DMUL] * bin(part63).count('1'))

# now handle the rest
rest = abs_exponent % 63
if rest:
exponent_parts.append(bytes([LCONST_1]))
exponent_parts.append(_calcInt(rest))
exponent_parts.append(bytes([LSHL, L2D]))
exponent_parts.append(bytes([DDIV if exponent < 0 else DMUL]))
exponent_parts.append(LCONST_1)
exponent_parts.extend(_calcInt(rest))
exponent_parts.extend([LSHL, L2D])
exponent_parts.append(DDIV if exponent < 0 else DMUL)

return _calcLong(mantissa) + bytes([L2D]) + b''.join(exponent_parts)
return _calcLong(mantissa) + bytes([L2D]) + exponent_parts

def calcInt(x): return _calcInt(s32(x))
def calcLong(x): return _calcLong(s64(x))
Expand Down
16 changes: 8 additions & 8 deletions enjarify/jvm/ir.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,20 +195,20 @@ def calcBytecode(self, posd, labels):
offset = posd[labels[self.default]] - pos
pad = (-pos-1) % 4

parts = []
bytecode = bytearray()
if self.istable:
parts.append(bytes([TABLESWITCH] + [0]*pad))
parts.append(struct.pack('>iii', offset, self.low, self.high))
bytecode += bytes([TABLESWITCH] + [0]*pad)
bytecode += struct.pack('>iii', offset, self.low, self.high)
for k in range(self.low, self.high + 1):
target = self.jumps.get(k, self.default)
parts.append(struct.pack('>i', posd[labels[target]] - pos))
bytecode += struct.pack('>i', posd[labels[target]] - pos)
else:
parts.append(bytes([LOOKUPSWITCH] + [0]*pad))
parts.append(struct.pack('>iI', offset, len(self.jumps)))
bytecode += bytes([LOOKUPSWITCH] + [0]*pad)
bytecode += struct.pack('>iI', offset, len(self.jumps))
for k, target in sorted(self.jumps.items()):
offset = posd[labels[target]] - pos
parts.append(struct.pack('>ii', k, offset))
self.bytecode = b''.join(parts)
bytecode += struct.pack('>ii', k, offset)
self.bytecode = bytes(bytecode)

_return_or_throw_bytecodes = {bytes([op]) for op in range(IRETURN, RETURN+1) }
_return_or_throw_bytecodes.add(bytes([ATHROW]))
Expand Down
8 changes: 3 additions & 5 deletions enjarify/jvm/optimization/jumps.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,11 @@ def createBytecode(irdata):
instrs = irdata.flat_instructions
posd, end_pos = _calcMinimumPositions(instrs)

parts = []
bytecode = bytearray()
for ins in instrs:
if isinstance(ins, (ir.LazyJumpBase, ir.Switch)):
ins.calcBytecode(posd, irdata.labels)
parts.append(ins.bytecode)

bytecode = b''.join(parts)
bytecode += ins.bytecode
assert(len(bytecode) == end_pos)

prev_instr_map = dict(zip(instrs[1:], instrs))
Expand All @@ -88,4 +86,4 @@ def createBytecode(irdata):
print('Skipping zero width exception!')
assert(0)

return bytecode, packed_excepts
return bytes(bytecode), packed_excepts
5 changes: 3 additions & 2 deletions enjarify/jvm/writeclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,10 @@ def writeMethod(pool, stream, method, code_attr_data):
stream.u16(pool.utf8(method.id.desc))

if code_attr_data is not None:
code_attr_data = code_attr_data.toBytes()
stream.u16(1)
stream.u16(pool.utf8(b"Code"))
stream.u32(code_attr_data.len)
stream.u32(len(code_attr_data))
stream.write(code_attr_data)
else:
stream.u16(0) # no attributes
Expand Down Expand Up @@ -115,5 +116,5 @@ def toClassFile(cls, opts):
# write constant pool
pool.write(stream)
# write rest of file
stream.write(rest_stream)
stream.write(rest_stream.toBytes())
return stream.toBytes()

0 comments on commit 97b1d3f

Please sign in to comment.