byterun icon indicating copy to clipboard operation
byterun copied to clipboard

has some problems when run code

Open wzhaha opened this issue 5 years ago • 3 comments

intArg = byteint(arg[0]) + (byteint(arg[1]) << 8) if byteCode in dis.hasconst: arg = f.f_code.co_consts[intArg]

this is the code of function 'parse_byte_and_args', in this part, intArg is index out of range, i dont know why, can u help me, thanks

wzhaha avatar Feb 03 '20 01:02 wzhaha

It is caused by Python changed the byte code format.

"After version 3.6, Python uses 2 bytes for each instruction. One byte is for the code of that instruction which is called an opcode, and one byte is reserved for its argument which is called the oparg. "

You can find more information here.

WillemJiang avatar Oct 29 '21 01:10 WillemJiang

I managed to fix the bytecode issue by apply following patch. But there are some test failed due to the new add the operation codes since python 3.9

diff --git a/interpreter/code/byterun/pyvm2.py b/interpreter/code/byterun/pyvm2.py
index 954d82c3..94099a8c 100644
--- a/interpreter/code/byterun/pyvm2.py
+++ b/interpreter/code/byterun/pyvm2.py
@@ -168,15 +168,19 @@ class VirtualMachine(object):
         # return val # for testing

     def parse_byte_and_args(self):
+        """ After version 3.6, Python uses 2 bytes for each instruction.
+        One byte is for the code of that instruction which is called an opcode,
+        and one byte is reserved for its argument which is called the oparg. """
         f = self.frame
+        extended_arg = 0
         opoffset = f.last_instruction
         byteCode = f.code_obj.co_code[opoffset]
-        f.last_instruction += 1
+        f.last_instruction += 2
         byte_name = dis.opname[byteCode]
         if byteCode >= dis.HAVE_ARGUMENT:
-            arg = f.code_obj.co_code[f.last_instruction:f.last_instruction+2]  # index into the bytecode
-            f.last_instruction += 2   # advance the instruction pointer
-            arg_val = arg[0] + (arg[1] << 8)
+            arg = f.code_obj.co_code[f.last_instruction-1]  # index into the bytecode
+            arg_val = arg | extended_arg
+            extended_arg = (arg_val << 8) if byteCode == dis.EXTENDED_ARG else 0
             if byteCode in dis.hasconst:   # Look up a constant
                 arg = f.code_obj.co_consts[arg_val]
             elif byteCode in dis.hasname:  # Look up a name

WillemJiang avatar Oct 29 '21 01:10 WillemJiang

xpython has

  • the 3.9 opcodes, and via xdis,
  • allows the interpreter to interpret different bytecode from the bytecode that Python is running the interpreter, and
  • Has a debugger that can single-step bytecode instructions

That said, it will be undergoing major upheaval soon in order to be able to interpret 3.10 opcodes.

And it has many of the other problems that this codebase has too.

It just gets you closer.

rocky avatar Oct 29 '21 09:10 rocky