Skip to content

Commit

Permalink
Fix ability to use long b'' literals
Browse files Browse the repository at this point in the history
The BIPUSH opcode treats values as 8-bit signed, and sign-extends when
storing.  Using BIPUSH to set the length of a byte array limits the
length to 127 bytes.

Use ICONST_val instead of BIPUSH to select the appropriate instruction
for setting the length of a byte array.  Also, only pass values in the
8-bit signed range to BIPUSH.
  • Loading branch information
whydoubt committed Aug 17, 2019
1 parent a407c03 commit a00dfee
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 4 deletions.
8 changes: 8 additions & 0 deletions tests/datatypes/test_bytes.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,14 @@ def test_too_many_arguments(self):
print(err)
""")

def test_long_literal(self):
self.assertCodeExecution("""
b = b'''00000000001111111111222222222233333333334444444444
55555555556666666666777777777888888888899999999990000000000
11111111112222222222'''
print(b)
""")


class UnaryBytesOperationTests(UnaryOperationTestCase, TranspileTestCase):
data_type = 'bytes'
Expand Down
4 changes: 2 additions & 2 deletions voc/java/opcodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -463,11 +463,11 @@ def __arg_repr__(self):

@classmethod
def read_extra(cls, reader, dump=None):
const = reader.read_u1()
const = reader.read_s1()
return cls(const)

def write_extra(self, writer):
writer.write_u1(self.const)
writer.write_s1(self.const)

@property
def produce_count(self):
Expand Down
5 changes: 3 additions & 2 deletions voc/python/ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -2260,15 +2260,16 @@ def visit_Bytes(self, node):
self.context.add_opcodes(
java.New('org/python/types/Bytes'),

JavaOpcodes.BIPUSH(len(node.s)),
ICONST_val(len(node.s)),
JavaOpcodes.NEWARRAY(JavaOpcodes.NEWARRAY.T_BYTE),
)

for i, b in enumerate(node.s):
self.context.add_opcodes(
JavaOpcodes.DUP(),
ICONST_val(i),
JavaOpcodes.BIPUSH(node.s[i]),
# 'bytes' values are unsigned, but BIPUSH needs signed values
JavaOpcodes.BIPUSH(b if b <= 127 else b - 256),
JavaOpcodes.BASTORE(),
)

Expand Down
2 changes: 2 additions & 0 deletions voc/python/types/primitives.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ def ICONST_val(value):
return JavaOpcodes.ICONST_5()
elif value == -1:
return JavaOpcodes.ICONST_M1()
elif -128 <= value <= 127:
return JavaOpcodes.BIPUSH(value)
elif -32768 <= value <= 32767:
return JavaOpcodes.SIPUSH(value)
elif -2147483648 <= value <= 2147483647:
Expand Down

0 comments on commit a00dfee

Please sign in to comment.