[pypy-commit] pypy py3.6-wordcode: switch encoding of bytecodes in the astcompiler to that of cpython 3.6
cfbolz
pypy.commits at gmail.com
Mon May 14 08:55:45 EDT 2018
Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: py3.6-wordcode
Changeset: r94574:61471dc3b236
Date: 2018-05-14 13:33 +0200
http://bitbucket.org/pypy/pypy/changeset/61471dc3b236/
Log: switch encoding of bytecodes in the astcompiler to that of cpython
3.6
diff --git a/pypy/interpreter/astcompiler/assemble.py b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -21,6 +21,8 @@
def __init__(self, opcode, arg=0):
self.opcode = opcode
self.arg = arg
+ if opcode < ops.HAVE_ARGUMENT:
+ assert arg == 0
self.lineno = 0
self.has_jump = False
@@ -28,9 +30,33 @@
"""Return the size of bytes of this instruction when it is
encoded.
"""
- if self.opcode >= ops.HAVE_ARGUMENT:
- return (6 if self.arg > 0xFFFF else 3)
- return 1
+ if self.arg <= 0xff:
+ return 2
+ if self.arg <= 0xffff:
+ return 4
+ if self.arg <= 0xffffff:
+ return 6
+ return 8
+
+ def encode(self, code):
+ opcode = self.opcode
+
+ arg = self.arg
+ size = self.size()
+ if size == 8:
+ code.append(chr(ops.EXTENDED_ARG))
+ code.append(chr((arg >> 24) & 0xff))
+ assert ((arg >> 24) & 0xff) == (arg >> 24)
+ if size >= 6:
+ code.append(chr(ops.EXTENDED_ARG))
+ code.append(chr((arg >> 16) & 0xff))
+ if size >= 4:
+ code.append(chr(ops.EXTENDED_ARG))
+ code.append(chr((arg >> 8) & 0xff))
+ if size >= 2:
+ code.append(chr(opcode))
+ code.append(chr(arg & 0xff))
+
def jump_to(self, target, absolute=False):
"""Indicate the target this jump instruction.
@@ -121,20 +147,7 @@
"""Encode the instructions in this block into bytecode."""
code = []
for instr in self.instructions:
- opcode = instr.opcode
- if opcode >= ops.HAVE_ARGUMENT:
- arg = instr.arg
- if instr.arg > 0xFFFF:
- ext = arg >> 16
- code.append(chr(ops.EXTENDED_ARG))
- code.append(chr(ext & 0xFF))
- code.append(chr(ext >> 8))
- arg &= 0xFFFF
- code.append(chr(opcode))
- code.append(chr(arg & 0xFF))
- code.append(chr(arg >> 8))
- else:
- code.append(chr(opcode))
+ instr.encode(code)
return ''.join(code)
diff --git a/pypy/interpreter/astcompiler/test/test_misc.py b/pypy/interpreter/astcompiler/test/test_misc.py
--- a/pypy/interpreter/astcompiler/test/test_misc.py
+++ b/pypy/interpreter/astcompiler/test/test_misc.py
@@ -1,4 +1,5 @@
from pypy.interpreter.astcompiler.misc import mangle
+from pypy.interpreter.astcompiler.assemble import Instruction, ops
def test_mangle():
assert mangle("foo", "Bar") == "foo"
@@ -13,6 +14,34 @@
assert mangle("__foo", "___") == "__foo"
assert mangle("___foo", "__Bar") == "_Bar___foo"
+def test_instruction_size():
+ assert Instruction(ops.POP_TOP).size() == 2
+ assert Instruction(ops.LOAD_FAST, 23).size() == 2
+ assert Instruction(ops.LOAD_FAST, 0xfff0).size() == 4
+ assert Instruction(ops.LOAD_FAST, 0x10000).size() == 6
+ assert Instruction(ops.LOAD_FAST, 0x1000000).size() == 8
+
+def test_instruction_encode():
+ c = []
+ Instruction(ops.POP_TOP).encode(c)
+ assert c == [chr(ops.POP_TOP), '\x00']
+
+ c = []
+ Instruction(ops.LOAD_FAST, 1).encode(c)
+ assert c == [chr(ops.LOAD_FAST), '\x01']
+
+ c = []
+ Instruction(ops.LOAD_FAST, 0x201).encode(c)
+ assert c == [chr(ops.EXTENDED_ARG), '\x02', chr(ops.LOAD_FAST), '\x01']
+
+ c = []
+ Instruction(ops.LOAD_FAST, 0x30201).encode(c)
+ assert c == [chr(ops.EXTENDED_ARG), '\x03', chr(ops.EXTENDED_ARG), '\x02', chr(ops.LOAD_FAST), '\x01']
+
+ c = []
+ Instruction(ops.LOAD_FAST, 0x5030201).encode(c)
+ assert c == [chr(ops.EXTENDED_ARG), '\x05', chr(ops.EXTENDED_ARG), '\x03', chr(ops.EXTENDED_ARG), '\x02', chr(ops.LOAD_FAST), '\x01']
+
def app_test_warning_to_error_translation():
import warnings
More information about the pypy-commit
mailing list