Skip to content

Commit e8e10f1

Browse files
committed
Parse exception table
1 parent a267bfb commit e8e10f1

File tree

5 files changed

+67
-5
lines changed

5 files changed

+67
-5
lines changed

bytecode.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -600,3 +600,18 @@ void bc_disasm(std::ostream& pyc_output, PycRef<PycCode> code, PycModule* mod,
600600
pyc_output << "\n";
601601
}
602602
}
603+
604+
void bc_exceptiontable(std::ostream& pyc_output, PycRef<PycCode> code,
605+
int indent)
606+
{
607+
for (auto tuple: code->exceptTableEntries()) {
608+
609+
for (int i=0; i<indent; i++)
610+
pyc_output << " ";
611+
612+
pyc_output << std::get<0>(tuple) << " to " << std::get<1>(tuple);
613+
pyc_output << " -> " << std::get<2>(tuple) << " ";
614+
pyc_output << "[" << std::get<3>(tuple) << "] " << (std::get<4>(tuple) ? "lasti": "");
615+
pyc_output << "\n";
616+
}
617+
}

bytecode.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ void print_const(std::ostream& pyc_output, PycRef<PycObject> obj, PycModule* mod
3232
void bc_next(PycBuffer& source, PycModule* mod, int& opcode, int& operand, int& pos);
3333
void bc_disasm(std::ostream& pyc_output, PycRef<PycCode> code, PycModule* mod,
3434
int indent, unsigned flags);
35+
void bc_exceptiontable(std::ostream& pyc_output, PycRef<PycCode> code,
36+
int indent);

pyc_code.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,3 +128,44 @@ PycRef<PycString> PycCode::getCellVar(PycModule* mod, int idx) const
128128
? m_freeVars->get(idx - m_cellVars->size()).cast<PycString>()
129129
: m_cellVars->get(idx).cast<PycString>();
130130
}
131+
132+
int _parse_varint(PycBuffer& data, int& pos) {
133+
int b = data.getByte();
134+
pos += 1;
135+
136+
int val = b & 63;
137+
while (b & 64) {
138+
val <<= 6;
139+
140+
b = data.getByte();
141+
pos += 1;
142+
143+
val |= (b & 63);
144+
}
145+
return val;
146+
}
147+
148+
std::vector<PycCode::exception_table_entry_t> PycCode::exceptTableEntries() const
149+
{
150+
PycBuffer data(m_exceptTable->value(), m_exceptTable->length());
151+
152+
std::vector<exception_table_entry_t> entries;
153+
154+
int pos = 0;
155+
while (!data.atEof()) {
156+
157+
int start = _parse_varint(data, pos) * 2;
158+
int length = _parse_varint(data, pos) * 2;
159+
int end = start + length;
160+
161+
int target = _parse_varint(data, pos) * 2;
162+
int dl = _parse_varint(data, pos);
163+
164+
int depth = dl >> 1;
165+
bool lasti = bool(dl & 1);
166+
167+
entries.emplace_back(start, end, target, depth, lasti);
168+
}
169+
170+
return entries;
171+
}

pyc_code.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ class PycCode : public PycObject {
8787
m_globalsUsed.emplace_back(std::move(varname));
8888
}
8989

90+
typedef std::tuple<int, int, int, int, bool> exception_table_entry_t;
91+
92+
std::vector<exception_table_entry_t> exceptTableEntries() const;
93+
9094
private:
9195
int m_argCount, m_posOnlyArgCount, m_kwOnlyArgCount, m_numLocals;
9296
int m_stackSize, m_flags;

pycdas.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,16 +145,16 @@ void output_object(PycRef<PycObject> obj, PycModule* mod, int indent,
145145
iputs(pyc_output, indent + 1, "[Disassembly]\n");
146146
bc_disasm(pyc_output, codeObj, mod, indent + 2, flags);
147147

148+
if (mod->verCompare(3, 11) >= 0) {
149+
iputs(pyc_output, indent + 1, "[Exception Table]\n");
150+
bc_exceptiontable(pyc_output, codeObj, indent+2);
151+
}
152+
148153
if (mod->verCompare(1, 5) >= 0 && (flags & Pyc::DISASM_PYCODE_VERBOSE) != 0) {
149154
iprintf(pyc_output, indent + 1, "First Line: %d\n", codeObj->firstLine());
150155
iputs(pyc_output, indent + 1, "[Line Number Table]\n");
151156
output_object(codeObj->lnTable().cast<PycObject>(), mod, indent + 2, flags, pyc_output);
152157
}
153-
154-
if (mod->verCompare(3, 11) >= 0 && (flags & Pyc::DISASM_PYCODE_VERBOSE) != 0) {
155-
iputs(pyc_output, indent + 1, "[Exception Table]\n");
156-
output_object(codeObj->exceptTable().cast<PycObject>(), mod, indent + 2, flags, pyc_output);
157-
}
158158
}
159159
break;
160160
case PycObject::TYPE_STRING:

0 commit comments

Comments
 (0)