diff --git a/ASTree.cpp b/ASTree.cpp index b22f034..7cc746d 100644 --- a/ASTree.cpp +++ b/ASTree.cpp @@ -1606,7 +1606,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) } break; case Pyc::LOAD_DEREF_A: - stack.push(new ASTName(code->getCellVar(operand))); + stack.push(new ASTName(code->getCellVar(mod, operand))); break; case Pyc::LOAD_FAST_A: if (mod->verCompare(1, 3) < 0) @@ -2100,7 +2100,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) case Pyc::STORE_DEREF_A: { if (unpack) { - PycRef name = new ASTName(code->getCellVar(operand)); + PycRef name = new ASTName(code->getCellVar(mod, operand)); PycRef tup = stack.top(); if (tup.type() == ASTNode::NODE_TUPLE) @@ -2122,7 +2122,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) } else { PycRef value = stack.top(); stack.pop(); - PycRef name = new ASTName(code->getCellVar(operand)); + PycRef name = new ASTName(code->getCellVar(mod, operand)); if (value.type() == ASTNode::NODE_CHAINSTORE) { append_to_chain_store(value, name, stack, curblock); diff --git a/bytecode.cpp b/bytecode.cpp index 789bcbd..c00fe05 100644 --- a/bytecode.cpp +++ b/bytecode.cpp @@ -363,7 +363,7 @@ void bc_disasm(PycRef code, PycModule* mod, int indent) fprintf(pyc_output, "%-7d ", pos); // Current bytecode position bc_next(source, mod, opcode, operand, pos); - fprintf(pyc_output, "%-24s", Pyc::OpcodeName(opcode)); + fprintf(pyc_output, "%-30s", Pyc::OpcodeName(opcode)); if (opcode >= Pyc::PYC_HAVE_ARG) { if (Pyc::IsConstArg(opcode)) { @@ -374,6 +374,16 @@ void bc_disasm(PycRef code, PycModule* mod, int indent) } catch (const std::out_of_range &) { fprintf(pyc_output, "%d ", operand); } + } else if (opcode == Pyc::LOAD_GLOBAL_A) { + // Special case for Python 3.11+ + try { + if (operand & 1) + fprintf(pyc_output, "%d: NULL + %s", operand, code->getName(operand >> 1)->value()); + else + fprintf(pyc_output, "%d: %s", operand, code->getName(operand >> 1)->value()); + } catch (const std::out_of_range &) { + fprintf(pyc_output, "%d ", operand); + } } else if (Pyc::IsNameArg(opcode)) { try { fprintf(pyc_output, "%d: %s", operand, code->getName(operand)->value()); @@ -388,7 +398,7 @@ void bc_disasm(PycRef code, PycModule* mod, int indent) } } else if (Pyc::IsCellArg(opcode)) { try { - fprintf(pyc_output, "%d: %s", operand, code->getCellVar(operand)->value()); + fprintf(pyc_output, "%d: %s", operand, code->getCellVar(mod, operand)->value()); } catch (const std::out_of_range &) { fprintf(pyc_output, "%d ", operand); } diff --git a/pyc_code.cpp b/pyc_code.cpp index 2693aa5..acc2eb8 100644 --- a/pyc_code.cpp +++ b/pyc_code.cpp @@ -87,3 +87,13 @@ void PycCode::load(PycData* stream, PycModule* mod) else m_exceptTable = new PycString; } + +PycRef PycCode::getCellVar(PycModule* mod, int idx) const +{ + if (mod->verCompare(3, 11) >= 0) + return getLocal(idx); + + return (idx >= m_cellVars->size()) + ? m_freeVars->get(idx - m_cellVars->size()).cast() + : m_cellVars->get(idx).cast(); +} diff --git a/pyc_code.h b/pyc_code.h index c3fdc9f..4d6e47c 100644 --- a/pyc_code.h +++ b/pyc_code.h @@ -5,6 +5,9 @@ #include "pyc_string.h" #include +class PycData; +class PycModule; + class PycCode : public PycObject { public: typedef std::vector> globals_t; @@ -32,7 +35,7 @@ public: : PycObject(type), m_argCount(), m_posOnlyArgCount(), m_kwOnlyArgCount(), m_numLocals(), m_stackSize(), m_flags(), m_firstLine() { } - void load(class PycData* stream, class PycModule* mod) override; + void load(PycData* stream, PycModule* mod) override; int argCount() const { return m_argCount; } int posOnlyArgCount() const { return m_posOnlyArgCount; } @@ -69,12 +72,7 @@ public: return m_localNames->get(idx).cast(); } - PycRef getCellVar(int idx) const - { - return (idx >= m_cellVars->size()) - ? m_freeVars->get(idx - m_cellVars->size()).cast() - : m_cellVars->get(idx).cast(); - } + PycRef getCellVar(PycModule* mod, int idx) const; const globals_t& getGlobals() const { return m_globalsUsed; }