Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

has some problems when run code #39

Open
wzhaha opened this issue Feb 3, 2020 · 3 comments
Open

has some problems when run code #39

wzhaha opened this issue Feb 3, 2020 · 3 comments

Comments

@wzhaha
Copy link

wzhaha commented Feb 3, 2020

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

@WillemJiang
Copy link

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
Copy link

WillemJiang commented Oct 29, 2021

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

@rocky
Copy link

rocky commented Oct 29, 2021

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants