From bd5fddd07ecd388f1cbbab961382976542002c00 Mon Sep 17 00:00:00 2001 From: cw2k <3834079+cw2k@users.noreply.github.com> Date: Sun, 11 Dec 2022 22:03:39 +0100 Subject: [PATCH 1/2] Fix for Unsupported opcode: WITH_EXCEPT_START -> Fixed for Unsupported opcode: [WITH_EXCEPT_START](https://docs.python.org/3/library/dis.html#opcode-WITH_EXCEPT_START) and Unsupported opcode: [RERAISE](https://docs.python.org/3/library/dis.html#opcode-RERAISE) by just adding these into the AST builder but without implementing any handler for it. ( too complicated for me to understand the code and types ) However now it runs. -> added some useful comments on some opcodes -> make the BLOCK_DEBUG to also show Opcodes --- ASTree.cpp | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 115 insertions(+), 4 deletions(-) diff --git a/ASTree.cpp b/ASTree.cpp index 4e327ffdb..5e86abbf3 100644 --- a/ASTree.cpp +++ b/ASTree.cpp @@ -92,21 +92,28 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) bool variable_annotations = false; while (!source.atEof()) { + + curpos = pos; + bc_next(source, mod, opcode, operand, pos); + #if defined(BLOCK_DEBUG) || defined(STACK_DEBUG) - fprintf(stderr, "%-7d", pos); + // DEBUG Positon in source file + fprintf(stderr, "%-7d %-3d %-16s_%-2d", pos, opcode, Pyc::OpcodeName(opcode & 0xFF), operand); #ifdef STACK_DEBUG fprintf(stderr, "%-5d", (unsigned int)stack_hist.size() + 1); #endif #ifdef BLOCK_DEBUG + // DEBUG Indept for (unsigned int i = 0; i < blocks.size(); i++) fprintf(stderr, " "); + + // DEBUG Type String & Length fprintf(stderr, "%s (%d)", curblock->type_str(), curblock->end()); #endif fprintf(stderr, "\n"); #endif - curpos = pos; - bc_next(source, mod, opcode, operand, pos); + if (need_try && opcode != Pyc::SETUP_EXCEPT_A) { need_try = false; @@ -1759,8 +1766,110 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) } break; case Pyc::POP_EXCEPT: - /* Do nothing. */ + /* Do nothing. + Pops a value from the stack, which is used to restore the exception state. + + Changed in version 3.11: Exception representation on the stack now consist of one, not three, items. + */ break; + + case Pyc::WITH_EXCEPT_START: + /* + Calls the function in position 4 on the stack with arguments (type, val, tb) representing the exception at the top of the stack. Used to implement the call context_manager.__exit__(*exc_info()) when an exception has occurred in a with statement. + New in version 3.9. + + The __exit__ function is in position 4 of the stack rather than 7. Exception representation on the stack now consist of one, not three, items. + Changed in version 3.11: + */ + { + //curblock = ASTBlock::BLK_EXCEPT; + PycRef msg = new PycString(); + msg->setValue ( + "# Decompile 'WITH_EXCEPT_START' is not implemented yet.\n" + ); + //fputs( msg->strValue, pyc_output); + case Pyc::POP_EXCEPT: + /* Do nothing. + Pops a value from the stack, which is used to restore the exception state. + + Changed in version 3.11: Exception representation on the stack now consist of one, not three, items. + */ + break; + + case Pyc::WITH_EXCEPT_START: + /* + Calls the function in position 4 on the stack with arguments (type, val, tb) representing the exception at the top of the stack. Used to implement the call context_manager.__exit__(*exc_info()) when an exception has occurred in a with statement. + New in version 3.9. + + The __exit__ function is in position 4 of the stack rather than 7. Exception representation on the stack now consist of one, not three, items. + Changed in version 3.11: + */ + { + //curblock = ASTBlock::BLK_EXCEPT; + PycRef msg = new PycString(); + msg->setValue( + "# Decompile 'WITH_EXCEPT_START' is not implemented yet.\n" + ); + //fputs( msg->strValue, pyc_output); + OutputString(msg); + /* + // TODO: Get that message into the AST (Abtract Syntax Tree) to be shown at the right spot + // However that f*** Types in CPP gimme a crisis + // + // ... and again I know why I prefer Python when coding. + + PycRef name = new ASTName( msg ); + curblock->append( + name.cast() + ); + */ + } + break; + + case Pyc::RERAISE: + // Re-raises the exception currently on top of the stack. + // If oparg is non-zero, pops an additional value from the stack which is used to + // set f_lasti of the current frame. + // New in version 3.9. + // Changed in version 3.11: Exception representation on the stack now consist of one, not three, items. + //https://docs.python.org/3/library/dis.html#opcode-RERAISE + + { + const char* msg = "# Decompile 'RERAISE' is not implemented yet.\n"; + fputs(msg, pyc_output); + } + break; + + case Pyc::POP_TOP: + OutputString( msg); + /* +// TODO: Get that message into the AST (Abtract Syntax Tree) to be shown at the right spot +// However that f*** Types in CPP gimme a crisis +// +// ... and again I know why I prefer Python when coding. + + PycRef name = new ASTName( msg ); + curblock->append( + name.cast() + ); +*/ + } + break; + + case Pyc::RERAISE: + // Re-raises the exception currently on top of the stack. + // If oparg is non-zero, pops an additional value from the stack which is used to + // set f_lasti of the current frame. + // New in version 3.9. + // Changed in version 3.11: Exception representation on the stack now consist of one, not three, items. + //https://docs.python.org/3/library/dis.html#opcode-RERAISE + + { + const char* msg = "# Decompile 'RERAISE' is not implemented yet.\n"; + fputs(msg, pyc_output); + } + break; + case Pyc::POP_TOP: { PycRef value = stack.top(); @@ -1799,6 +1908,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) PycRef printNode; if (curblock->size() > 0 && curblock->nodes().back().type() == ASTNode::NODE_PRINT) printNode = curblock->nodes().back().try_cast(); + if (printNode && printNode->stream() == nullptr && !printNode->eol()) printNode->add(stack.top()); else @@ -1979,6 +2089,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) } } break; + case Pyc::SETUP_EXCEPT_A: { if (curblock->blktype() == ASTBlock::BLK_CONTAINER) { From 9d8adb8cdd162cd0672486aad7bead6ad8cfa91f Mon Sep 17 00:00:00 2001 From: cw2k <3834079+cw2k@users.noreply.github.com> Date: Sun, 11 Dec 2022 23:08:57 +0100 Subject: [PATCH 2/2] fix last commit --- ASTree.cpp | 55 ++---------------------------------------------------- 1 file changed, 2 insertions(+), 53 deletions(-) diff --git a/ASTree.cpp b/ASTree.cpp index 5e86abbf3..ad4674401 100644 --- a/ASTree.cpp +++ b/ASTree.cpp @@ -1765,6 +1765,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) } } break; + case Pyc::POP_EXCEPT: /* Do nothing. Pops a value from the stack, which is used to restore the exception state. @@ -1773,29 +1774,6 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) */ break; - case Pyc::WITH_EXCEPT_START: - /* - Calls the function in position 4 on the stack with arguments (type, val, tb) representing the exception at the top of the stack. Used to implement the call context_manager.__exit__(*exc_info()) when an exception has occurred in a with statement. - New in version 3.9. - - The __exit__ function is in position 4 of the stack rather than 7. Exception representation on the stack now consist of one, not three, items. - Changed in version 3.11: - */ - { - //curblock = ASTBlock::BLK_EXCEPT; - PycRef msg = new PycString(); - msg->setValue ( - "# Decompile 'WITH_EXCEPT_START' is not implemented yet.\n" - ); - //fputs( msg->strValue, pyc_output); - case Pyc::POP_EXCEPT: - /* Do nothing. - Pops a value from the stack, which is used to restore the exception state. - - Changed in version 3.11: Exception representation on the stack now consist of one, not three, items. - */ - break; - case Pyc::WITH_EXCEPT_START: /* Calls the function in position 4 on the stack with arguments (type, val, tb) representing the exception at the top of the stack. Used to implement the call context_manager.__exit__(*exc_info()) when an exception has occurred in a with statement. @@ -1825,36 +1803,6 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) */ } break; - - case Pyc::RERAISE: - // Re-raises the exception currently on top of the stack. - // If oparg is non-zero, pops an additional value from the stack which is used to - // set f_lasti of the current frame. - // New in version 3.9. - // Changed in version 3.11: Exception representation on the stack now consist of one, not three, items. - //https://docs.python.org/3/library/dis.html#opcode-RERAISE - - { - const char* msg = "# Decompile 'RERAISE' is not implemented yet.\n"; - fputs(msg, pyc_output); - } - break; - - case Pyc::POP_TOP: - OutputString( msg); - /* -// TODO: Get that message into the AST (Abtract Syntax Tree) to be shown at the right spot -// However that f*** Types in CPP gimme a crisis -// -// ... and again I know why I prefer Python when coding. - - PycRef name = new ASTName( msg ); - curblock->append( - name.cast() - ); -*/ - } - break; case Pyc::RERAISE: // Re-raises the exception currently on top of the stack. @@ -2283,6 +2231,7 @@ PycRef BuildFromCode(PycRef code, PycModule* mod) else name = new ASTName(code->getVarName(operand)); + if (name.cast()->name()->value()[0] == '_' && name.cast()->name()->value()[1] == '[') { /* Don't show stores of list comp append objects. */