Parse exception table
This commit is contained in:
15
bytecode.cpp
15
bytecode.cpp
@@ -600,3 +600,18 @@ void bc_disasm(std::ostream& pyc_output, PycRef<PycCode> code, PycModule* mod,
|
|||||||
pyc_output << "\n";
|
pyc_output << "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bc_exceptiontable(std::ostream& pyc_output, PycRef<PycCode> code,
|
||||||
|
int indent)
|
||||||
|
{
|
||||||
|
for (auto tuple: code->exceptTableEntries()) {
|
||||||
|
|
||||||
|
for (int i=0; i<indent; i++)
|
||||||
|
pyc_output << " ";
|
||||||
|
|
||||||
|
pyc_output << std::get<0>(tuple) << " to " << std::get<1>(tuple);
|
||||||
|
pyc_output << " -> " << std::get<2>(tuple) << " ";
|
||||||
|
pyc_output << "[" << std::get<3>(tuple) << "] " << (std::get<4>(tuple) ? "lasti": "");
|
||||||
|
pyc_output << "\n";
|
||||||
|
}
|
||||||
|
}
|
@@ -32,3 +32,5 @@ void print_const(std::ostream& pyc_output, PycRef<PycObject> obj, PycModule* mod
|
|||||||
void bc_next(PycBuffer& source, PycModule* mod, int& opcode, int& operand, int& pos);
|
void bc_next(PycBuffer& source, PycModule* mod, int& opcode, int& operand, int& pos);
|
||||||
void bc_disasm(std::ostream& pyc_output, PycRef<PycCode> code, PycModule* mod,
|
void bc_disasm(std::ostream& pyc_output, PycRef<PycCode> code, PycModule* mod,
|
||||||
int indent, unsigned flags);
|
int indent, unsigned flags);
|
||||||
|
void bc_exceptiontable(std::ostream& pyc_output, PycRef<PycCode> code,
|
||||||
|
int indent);
|
||||||
|
41
pyc_code.cpp
41
pyc_code.cpp
@@ -128,3 +128,44 @@ PycRef<PycString> PycCode::getCellVar(PycModule* mod, int idx) const
|
|||||||
? m_freeVars->get(idx - m_cellVars->size()).cast<PycString>()
|
? m_freeVars->get(idx - m_cellVars->size()).cast<PycString>()
|
||||||
: m_cellVars->get(idx).cast<PycString>();
|
: m_cellVars->get(idx).cast<PycString>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int _parse_varint(PycBuffer& data, int& pos) {
|
||||||
|
int b = data.getByte();
|
||||||
|
pos += 1;
|
||||||
|
|
||||||
|
int val = b & 63;
|
||||||
|
while (b & 64) {
|
||||||
|
val <<= 6;
|
||||||
|
|
||||||
|
b = data.getByte();
|
||||||
|
pos += 1;
|
||||||
|
|
||||||
|
val |= (b & 63);
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<PycCode::exception_table_entry_t> PycCode::exceptTableEntries() const
|
||||||
|
{
|
||||||
|
PycBuffer data(m_exceptTable->value(), m_exceptTable->length());
|
||||||
|
|
||||||
|
std::vector<exception_table_entry_t> entries;
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
while (!data.atEof()) {
|
||||||
|
|
||||||
|
int start = _parse_varint(data, pos) * 2;
|
||||||
|
int length = _parse_varint(data, pos) * 2;
|
||||||
|
int end = start + length;
|
||||||
|
|
||||||
|
int target = _parse_varint(data, pos) * 2;
|
||||||
|
int dl = _parse_varint(data, pos);
|
||||||
|
|
||||||
|
int depth = dl >> 1;
|
||||||
|
bool lasti = bool(dl & 1);
|
||||||
|
|
||||||
|
entries.emplace_back(start, end, target, depth, lasti);
|
||||||
|
}
|
||||||
|
|
||||||
|
return entries;
|
||||||
|
}
|
@@ -87,6 +87,10 @@ public:
|
|||||||
m_globalsUsed.emplace_back(std::move(varname));
|
m_globalsUsed.emplace_back(std::move(varname));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef std::tuple<int, int, int, int, bool> exception_table_entry_t;
|
||||||
|
|
||||||
|
std::vector<exception_table_entry_t> exceptTableEntries() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int m_argCount, m_posOnlyArgCount, m_kwOnlyArgCount, m_numLocals;
|
int m_argCount, m_posOnlyArgCount, m_kwOnlyArgCount, m_numLocals;
|
||||||
int m_stackSize, m_flags;
|
int m_stackSize, m_flags;
|
||||||
|
10
pycdas.cpp
10
pycdas.cpp
@@ -145,16 +145,16 @@ void output_object(PycRef<PycObject> obj, PycModule* mod, int indent,
|
|||||||
iputs(pyc_output, indent + 1, "[Disassembly]\n");
|
iputs(pyc_output, indent + 1, "[Disassembly]\n");
|
||||||
bc_disasm(pyc_output, codeObj, mod, indent + 2, flags);
|
bc_disasm(pyc_output, codeObj, mod, indent + 2, flags);
|
||||||
|
|
||||||
|
if (mod->verCompare(3, 11) >= 0) {
|
||||||
|
iputs(pyc_output, indent + 1, "[Exception Table]\n");
|
||||||
|
bc_exceptiontable(pyc_output, codeObj, indent+2);
|
||||||
|
}
|
||||||
|
|
||||||
if (mod->verCompare(1, 5) >= 0 && (flags & Pyc::DISASM_PYCODE_VERBOSE) != 0) {
|
if (mod->verCompare(1, 5) >= 0 && (flags & Pyc::DISASM_PYCODE_VERBOSE) != 0) {
|
||||||
iprintf(pyc_output, indent + 1, "First Line: %d\n", codeObj->firstLine());
|
iprintf(pyc_output, indent + 1, "First Line: %d\n", codeObj->firstLine());
|
||||||
iputs(pyc_output, indent + 1, "[Line Number Table]\n");
|
iputs(pyc_output, indent + 1, "[Line Number Table]\n");
|
||||||
output_object(codeObj->lnTable().cast<PycObject>(), mod, indent + 2, flags, pyc_output);
|
output_object(codeObj->lnTable().cast<PycObject>(), mod, indent + 2, flags, pyc_output);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mod->verCompare(3, 11) >= 0 && (flags & Pyc::DISASM_PYCODE_VERBOSE) != 0) {
|
|
||||||
iputs(pyc_output, indent + 1, "[Exception Table]\n");
|
|
||||||
output_object(codeObj->exceptTable().cast<PycObject>(), mod, indent + 2, flags, pyc_output);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PycObject::TYPE_STRING:
|
case PycObject::TYPE_STRING:
|
||||||
|
Reference in New Issue
Block a user