Add PUSH_NULL, PRECALL_A, CALL_A support (#324)

* Add `PUSH_NULL`, `PRECALL_A`, `CALL_A` support

* feat: @zrax

Co-authored-by: Michael Hansen <zrax0111@gmail.com>

* Good suggested change to make the code shorter

* Add `PUSH_NULL`, `PRECALL`, `CALL` test tokenized

* Add `PUSH_NULL`, `PRECALL`, `CALL` test

* Add `PUSH_NULL`, `PRECALL`, `CALL` test compiled

* Delete push_null-precall-call.3.11.pyc

* Delete push_null-precall-call.py

* Delete push_null-precall-call.txt

* Update README.markdown

Blank commit to re-run the tests.

* Join all no-ops/"fake"-ops together

* Update ASTree.cpp

https://github.com/zrax/pycdc/pull/324#issuecomment-1449049283

* Add compiled test for #324

---------

Co-authored-by: Michael Hansen <zrax0111@gmail.com>
This commit is contained in:
TheHellTower
2023-03-01 00:48:33 +01:00
committed by GitHub
parent f4db6a7cf6
commit 4d81a16638
2 changed files with 15 additions and 9 deletions

View File

@@ -474,6 +474,7 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
stack.push(new ASTTuple(values));
}
break;
case Pyc::CALL_A:
case Pyc::CALL_FUNCTION_A:
{
int kwparams = (operand & 0xFF00) >> 8;
@@ -540,12 +541,16 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
pparamList.push_front(decor_name);
}
} else {
}
else {
pparamList.push_front(param);
}
}
PycRef<ASTNode> func = stack.top();
stack.pop();
if (opcode == Pyc::CALL_A && stack.top() == nullptr)
stack.pop();
stack.push(new ASTCall(func, pparamList, kwparamList));
}
break;
@@ -1032,12 +1037,6 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
stack.push(new ASTAwaitable(object));
}
break;
case Pyc::GET_ITER:
/* We just entirely ignore this */
break;
case Pyc::GET_YIELD_FROM_ITER:
/* We just entirely ignore this */
break;
case Pyc::IMPORT_NAME_A:
if (mod->majorVer() == 1) {
stack.push(new ASTImport(new ASTName(code->getName(operand)), NULL));
@@ -2547,14 +2546,21 @@ PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod)
case Pyc::SETUP_ANNOTATIONS:
variable_annotations = true;
break;
case Pyc::GET_ITER:
case Pyc::GET_YIELD_FROM_ITER:
break;
case Pyc::PRECALL_A:
case Pyc::RESUME_A:
/* We just entirely ignore this / no-op */
break;
case Pyc::CACHE:
/* These "fake" opcodes are used as placeholders for optimizing
certain opcodes in Python 3.11+. Since we have no need for
that during disassembly/decompilation, we can just treat these
as no-ops. */
break;
case Pyc::RESUME_A:
/* Treated as no-op for decompyle purposes */
case Pyc::PUSH_NULL:
stack.push(nullptr);
break;
default:
fprintf(stderr, "Unsupported opcode: %s\n", Pyc::OpcodeName(opcode & 0xFF));

Binary file not shown.