Skip to content

Commit

Permalink
Merge commit 'c4c35fc5318b904d5141a7f3c4a70d80576c30da'
Browse files Browse the repository at this point in the history
  • Loading branch information
zrax committed Jun 5, 2023
2 parents 72c5f87 + c4c35fc commit 482c32d
Show file tree
Hide file tree
Showing 10 changed files with 488 additions and 460 deletions.
526 changes: 263 additions & 263 deletions ASTree.cpp

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions ASTree.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
#include "ASTNode.h"

PycRef<ASTNode> BuildFromCode(PycRef<PycCode> code, PycModule* mod);
void print_src(PycRef<ASTNode> node, PycModule* mod);
void print_src(PycRef<ASTNode> node, PycModule* mod, std::ostream& pyc_output);

void decompyle(PycRef<PycCode> code, PycModule* mod);
void decompyle(PycRef<PycCode> code, PycModule* mod, std::ostream& pyc_output);

#endif
148 changes: 74 additions & 74 deletions bytecode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,10 @@ bool Pyc::IsCompareArg(int opcode)
return (opcode == Pyc::COMPARE_OP_A);
}

void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_string_quote)
void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_string_quote, std::ostream& pyc_output)
{
if (obj == NULL) {
fputs("<NULL>", pyc_output);
pyc_output << "<NULL>";
return;
}

Expand All @@ -190,112 +190,112 @@ void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_str
case PycObject::TYPE_TUPLE:
case PycObject::TYPE_SMALL_TUPLE:
{
fputs("(", pyc_output);
pyc_output << "(";
PycTuple::value_t values = obj.cast<PycTuple>()->values();
auto it = values.cbegin();
if (it != values.cend()) {
print_const(*it, mod);
print_const(*it, mod, nullptr, pyc_output);
while (++it != values.cend()) {
fputs(", ", pyc_output);
print_const(*it, mod);
pyc_output << ", ";
print_const(*it, mod, nullptr, pyc_output);
}
}
if (values.size() == 1)
fputs(",)", pyc_output);
pyc_output << ",)";
else
fputs(")", pyc_output);
pyc_output << ")";
}
break;
case PycObject::TYPE_LIST:
{
fputs("[", pyc_output);
pyc_output << "[";
PycList::value_t values = obj.cast<PycList>()->values();
auto it = values.cbegin();
if (it != values.cend()) {
print_const(*it, mod);
print_const(*it, mod, nullptr, pyc_output);
while (++it != values.cend()) {
fputs(", ", pyc_output);
print_const(*it, mod);
pyc_output << ", ";
print_const(*it, mod, nullptr, pyc_output);
}
}
fputs("]", pyc_output);
pyc_output << "]";
}
break;
case PycObject::TYPE_DICT:
{
fputs("{", pyc_output);
pyc_output << "{";
PycDict::key_t keys = obj.cast<PycDict>()->keys();
PycDict::value_t values = obj.cast<PycDict>()->values();
auto ki = keys.cbegin();
auto vi = values.cbegin();
if (ki != keys.cend()) {
print_const(*ki, mod);
fputs(": ", pyc_output);
print_const(*vi, mod);
print_const(*ki, mod, nullptr, pyc_output);
pyc_output << ": ";
print_const(*vi, mod, nullptr, pyc_output);
while (++ki != keys.cend()) {
++vi;
fputs(", ", pyc_output);
print_const(*ki, mod);
fputs(": ", pyc_output);
print_const(*vi, mod);
pyc_output << ", ";
print_const(*ki, mod, nullptr, pyc_output);
pyc_output << ": ";
print_const(*vi, mod, nullptr, pyc_output);
}
}
fputs("}", pyc_output);
pyc_output << "}";
}
break;
case PycObject::TYPE_SET:
{
fputs("{", pyc_output);
pyc_output << "{";
PycSet::value_t values = obj.cast<PycSet>()->values();
auto it = values.cbegin();
if (it != values.cend()) {
print_const(*it, mod);
print_const(*it, mod, nullptr, pyc_output);
while (++it != values.cend()) {
fputs(", ", pyc_output);
print_const(*it, mod);
pyc_output << ", ";
print_const(*it, mod, nullptr, pyc_output);
}
}
fputs("}", pyc_output);
pyc_output << "}";
}
break;
case PycObject::TYPE_FROZENSET:
{
fputs("frozenset({", pyc_output);
pyc_output << "frozenset({";
PycSet::value_t values = obj.cast<PycSet>()->values();
auto it = values.cbegin();
if (it != values.cend()) {
print_const(*it, mod);
print_const(*it, mod, nullptr, pyc_output);
while (++it != values.cend()) {
fputs(", ", pyc_output);
print_const(*it, mod);
pyc_output << ", ";
print_const(*it, mod, nullptr, pyc_output);
}
}
fputs("})", pyc_output);
pyc_output << "})";
}
break;
case PycObject::TYPE_NONE:
fputs("None", pyc_output);
pyc_output << "None";
break;
case PycObject::TYPE_TRUE:
fputs("True", pyc_output);
pyc_output << "True";
break;
case PycObject::TYPE_FALSE:
fputs("False", pyc_output);
pyc_output << "False";
break;
case PycObject::TYPE_ELLIPSIS:
fputs("...", pyc_output);
pyc_output << "...";
break;
case PycObject::TYPE_INT:
fprintf(pyc_output, "%d", obj.cast<PycInt>()->value());
formatted_print(pyc_output, "%d", obj.cast<PycInt>()->value());
break;
case PycObject::TYPE_LONG:
fprintf(pyc_output, "%s", obj.cast<PycLong>()->repr().c_str());
formatted_print(pyc_output, "%s", obj.cast<PycLong>()->repr().c_str());
break;
case PycObject::TYPE_FLOAT:
fprintf(pyc_output, "%s", obj.cast<PycFloat>()->value());
formatted_print(pyc_output, "%s", obj.cast<PycFloat>()->value());
break;
case PycObject::TYPE_COMPLEX:
fprintf(pyc_output, "(%s+%sj)", obj.cast<PycComplex>()->value(),
formatted_print(pyc_output, "(%s+%sj)", obj.cast<PycComplex>()->value(),
obj.cast<PycComplex>()->imag());
break;
case PycObject::TYPE_BINARY_FLOAT:
Expand All @@ -305,31 +305,31 @@ void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_str
bool is_negative = std::signbit(value);
if (std::isnan(value)) {
if (is_negative) {
fprintf(pyc_output, "float('-nan')");
pyc_output << "float('-nan')";
} else {
fprintf(pyc_output, "float('nan')");
pyc_output << "float('nan')";
}
} else if (std::isinf(value)) {
if (is_negative) {
fprintf(pyc_output, "float('-inf')");
pyc_output << "float('-inf')";
} else {
fprintf(pyc_output, "float('inf')");
pyc_output << "float('inf')";
}
} else {
fprintf(pyc_output, "%g", value);
formatted_print(pyc_output, "%g", value);
}
}
break;
case PycObject::TYPE_BINARY_COMPLEX:
fprintf(pyc_output, "(%g+%gj)", obj.cast<PycCComplex>()->value(),
formatted_print(pyc_output, "(%g+%gj)", obj.cast<PycCComplex>()->value(),
obj.cast<PycCComplex>()->imag());
break;
case PycObject::TYPE_CODE:
case PycObject::TYPE_CODE2:
fprintf(pyc_output, "<CODE> %s", obj.cast<PycCode>()->name()->value());
formatted_print(pyc_output, "<CODE> %s", obj.cast<PycCode>()->name()->value());
break;
default:
fprintf(pyc_output, "<TYPE: %d>\n", obj->type());
formatted_print(pyc_output, "<TYPE: %d>\n", obj->type());
}
}

Expand Down Expand Up @@ -363,7 +363,7 @@ void bc_next(PycBuffer& source, PycModule* mod, int& opcode, int& operand, int&
}
}

void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags)
void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags, std::ostream &pyc_output)
{
static const char *cmp_strings[] = {
"<", "<=", "==", "!=", ">", ">=", "in", "not in", "is", "is not",
Expand All @@ -388,78 +388,78 @@ void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags)
continue;

for (int i=0; i<indent; i++)
fputs(" ", pyc_output);
fprintf(pyc_output, "%-7d %-30s", start_pos, Pyc::OpcodeName(opcode));
pyc_output << " ";
formatted_print(pyc_output, "%-7d %-30s", start_pos, Pyc::OpcodeName(opcode));

if (opcode >= Pyc::PYC_HAVE_ARG) {
if (Pyc::IsConstArg(opcode)) {
try {
auto constParam = code->getConst(operand);
fprintf(pyc_output, "%d: ", operand);
print_const(constParam, mod);
formatted_print(pyc_output, "%d: ", operand);
print_const(constParam, mod, nullptr, pyc_output);
} catch (const std::out_of_range &) {
fprintf(pyc_output, "%d <INVALID>", operand);
formatted_print(pyc_output, "%d <INVALID>", 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());
formatted_print(pyc_output, "%d: NULL + %s", operand, code->getName(operand >> 1)->value());
else
fprintf(pyc_output, "%d: %s", operand, code->getName(operand >> 1)->value());
formatted_print(pyc_output, "%d: %s", operand, code->getName(operand >> 1)->value());
} catch (const std::out_of_range &) {
fprintf(pyc_output, "%d <INVALID>", operand);
formatted_print(pyc_output, "%d <INVALID>", operand);
}
} else if (Pyc::IsNameArg(opcode)) {
try {
fprintf(pyc_output, "%d: %s", operand, code->getName(operand)->value());
formatted_print(pyc_output, "%d: %s", operand, code->getName(operand)->value());
} catch (const std::out_of_range &) {
fprintf(pyc_output, "%d <INVALID>", operand);
formatted_print(pyc_output, "%d <INVALID>", operand);
}
} else if (Pyc::IsVarNameArg(opcode)) {
try {
fprintf(pyc_output, "%d: %s", operand, code->getLocal(operand)->value());
formatted_print(pyc_output, "%d: %s", operand, code->getLocal(operand)->value());
} catch (const std::out_of_range &) {
fprintf(pyc_output, "%d <INVALID>", operand);
formatted_print(pyc_output, "%d <INVALID>", operand);
}
} else if (Pyc::IsCellArg(opcode)) {
try {
fprintf(pyc_output, "%d: %s", operand, code->getCellVar(mod, operand)->value());
formatted_print(pyc_output, "%d: %s", operand, code->getCellVar(mod, operand)->value());
} catch (const std::out_of_range &) {
fprintf(pyc_output, "%d <INVALID>", operand);
formatted_print(pyc_output, "%d <INVALID>", operand);
}
} else if (Pyc::IsJumpOffsetArg(opcode)) {
int offs = operand;
if (mod->verCompare(3, 10) >= 0)
offs *= sizeof(uint16_t); // BPO-27129
fprintf(pyc_output, "%d (to %d)", operand, pos+offs);
formatted_print(pyc_output, "%d (to %d)", operand, pos+offs);
} else if (Pyc::IsJumpArg(opcode)) {
if (mod->verCompare(3, 10) >= 0) // BPO-27129
fprintf(pyc_output, "%d (to %d)", operand, int(operand * sizeof(uint16_t)));
formatted_print(pyc_output, "%d (to %d)", operand, int(operand * sizeof(uint16_t)));
else
fprintf(pyc_output, "%d", operand);
formatted_print(pyc_output, "%d", operand);
} else if (Pyc::IsCompareArg(opcode)) {
if (static_cast<size_t>(operand) < cmp_strings_len)
fprintf(pyc_output, "%d (%s)", operand, cmp_strings[operand]);
formatted_print(pyc_output, "%d (%s)", operand, cmp_strings[operand]);
else
fprintf(pyc_output, "%d (UNKNOWN)", operand);
formatted_print(pyc_output, "%d (UNKNOWN)", operand);
} else if (opcode == Pyc::BINARY_OP_A) {
if (static_cast<size_t>(operand) < binop_strings_len)
fprintf(pyc_output, "%d (%s)", operand, binop_strings[operand]);
formatted_print(pyc_output, "%d (%s)", operand, binop_strings[operand]);
else
fprintf(pyc_output, "%d (UNKNOWN)", operand);
formatted_print(pyc_output, "%d (UNKNOWN)", operand);
} else if (opcode == Pyc::IS_OP_A) {
fprintf(pyc_output, "%d (%s)", operand, (operand == 0) ? "is"
formatted_print(pyc_output, "%d (%s)", operand, (operand == 0) ? "is"
: (operand == 1) ? "is not"
: "UNKNOWN");
} else if (opcode == Pyc::CONTAINS_OP_A) {
fprintf(pyc_output, "%d (%s)", operand, (operand == 0) ? "in"
formatted_print(pyc_output, "%d (%s)", operand, (operand == 0) ? "in"
: (operand == 1) ? "not in"
: "UNKNOWN");
} else {
fprintf(pyc_output, "%d", operand);
formatted_print(pyc_output, "%d", operand);
}
}
fputs("\n", pyc_output);
pyc_output << "\n";
}
}
4 changes: 2 additions & 2 deletions bytecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ bool IsCompareArg(int opcode);

}

void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_string_quote = nullptr);
void print_const(PycRef<PycObject> obj, PycModule* mod, const char* parent_f_string_quote, std::ostream& pyc_output);
void bc_next(PycBuffer& source, PycModule* mod, int& opcode, int& operand, int& pos);
void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags);
void bc_disasm(PycRef<PycCode> code, PycModule* mod, int indent, unsigned flags, std::ostream& pyc_output);
22 changes: 20 additions & 2 deletions data.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "data.h"
#include <cstring>

FILE* pyc_output = stdout;
#include <ostream>
#include <vector>

/* PycData */
int PycData::get16()
Expand Down Expand Up @@ -82,3 +82,21 @@ int PycBuffer::getBuffer(int bytes, void* buffer)
memcpy(buffer, (m_buffer + m_pos), bytes);
return bytes;
}



#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wvarargs"
int formatted_print(std::ostream& stream, const std::string& format, ...) {
va_list args;
va_start(args, format);
size_t len = std::vsnprintf(NULL, 0, format.c_str(), args);
va_end(args);
std::vector<char> vec(len + 1);
va_start(args, format);
std::vsnprintf(&vec[0], len + 1, format.c_str(), args);
va_end(args);
stream << &vec[0];
return 0;
}
#pragma clang diagnostic pop
3 changes: 2 additions & 1 deletion data.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define _PYC_FILE_H

#include <cstdio>
#include <ostream>

#ifdef WIN32
typedef __int64 Pyc_INT64;
Expand Down Expand Up @@ -56,6 +57,6 @@ class PycBuffer : public PycData {
int m_size, m_pos;
};

extern FILE* pyc_output;
int formatted_print(std::ostream& stream, const std::string& format, ...);

#endif
Loading

0 comments on commit 482c32d

Please sign in to comment.