[wasm] Improve output of PrintAstForDebugging.

R=clemensh@chromium.org
BUG=

Review-Url: https://codereview.chromium.org/1956703002
Cr-Commit-Position: refs/heads/master@{#36086}
This commit is contained in:
titzer 2016-05-06 09:27:22 -07:00 committed by Commit bot
parent dae0fecfd2
commit 3181c87e04
2 changed files with 79 additions and 44 deletions

View File

@ -1524,6 +1524,12 @@ int OpcodeArity(const byte* pc, const byte* end) {
return decoder.OpcodeArity(pc); return decoder.OpcodeArity(pc);
} }
void PrintAstForDebugging(const byte* start, const byte* end) {
FunctionBody body = {nullptr, nullptr, start, start, end};
base::AccountingAllocator allocator;
PrintAst(&allocator, body);
}
void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) { void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) {
Zone zone(allocator); Zone zone(allocator);
SR_WasmDecoder decoder(&zone, nullptr, body); SR_WasmDecoder decoder(&zone, nullptr, body);
@ -1540,7 +1546,7 @@ void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) {
decoder.DecodeLocalDecls(decls); decoder.DecodeLocalDecls(decls);
const byte* pc = decoder.pc(); const byte* pc = decoder.pc();
if (body.start != decoder.pc()) { if (body.start != decoder.pc()) {
printf("// locals:"); os << "// locals: ";
for (auto p : decls.local_types) { for (auto p : decls.local_types) {
LocalType type = p.first; LocalType type = p.first;
uint32_t count = p.second; uint32_t count = p.second;
@ -1551,64 +1557,90 @@ void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) {
for (const byte* locals = body.start; locals < pc; locals++) { for (const byte* locals = body.start; locals < pc; locals++) {
printf(" 0x%02x,", *locals); printf(" 0x%02x,", *locals);
} }
printf("\n"); os << std::endl;
} }
printf("// body: \n"); os << "// body: \n";
std::vector<int> arity_stack; int control_depth = 0;
while (pc < body.end) { while (pc < body.end) {
int arity = decoder.OpcodeArity(pc);
size_t length = decoder.OpcodeLength(pc); size_t length = decoder.OpcodeLength(pc);
for (auto arity : arity_stack) {
printf(" ");
USE(arity);
}
WasmOpcode opcode = static_cast<WasmOpcode>(*pc); WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
if (opcode == kExprElse) control_depth--;
for (int i = 0; i < control_depth && i < 32; i++) printf(" ");
printf("k%s,", WasmOpcodes::OpcodeName(opcode)); printf("k%s,", WasmOpcodes::OpcodeName(opcode));
for (size_t i = 1; i < length; i++) { for (size_t i = 1; i < length; i++) {
printf(" 0x%02x,", pc[i]); printf(" 0x%02x,", pc[i]);
} }
if (body.module) { switch (opcode) {
switch (opcode) { case kExprIf:
case kExprCallIndirect: { case kExprElse:
CallIndirectOperand operand(&decoder, pc); case kExprLoop:
if (decoder.Validate(pc, operand)) { case kExprBlock:
os << " // sig #" << operand.index << ": " << *operand.sig; os << " // @" << static_cast<int>(pc - body.start);
} control_depth++;
break; break;
} case kExprEnd:
case kExprCallImport: { os << " // @" << static_cast<int>(pc - body.start);
CallImportOperand operand(&decoder, pc); control_depth--;
if (decoder.Validate(pc, operand)) { break;
os << " // import #" << operand.index << ": " << *operand.sig; case kExprBr: {
} BreakDepthOperand operand(&decoder, pc);
break; os << " // arity=" << operand.arity << " depth=" << operand.depth;
} break;
case kExprCallFunction: { }
CallFunctionOperand operand(&decoder, pc); case kExprBrIf: {
if (decoder.Validate(pc, operand)) { BreakDepthOperand operand(&decoder, pc);
os << " // function #" << operand.index << ": " << *operand.sig; os << " // arity=" << operand.arity << " depth" << operand.depth;
} break;
break; }
} case kExprBrTable: {
default: BranchTableOperand operand(&decoder, pc);
break; os << " // arity=" << operand.arity
<< " entries=" << operand.table_count;
break;
}
case kExprCallIndirect: {
CallIndirectOperand operand(&decoder, pc);
if (decoder.Validate(pc, operand)) {
os << " // sig #" << operand.index << ": " << *operand.sig;
} else {
os << " // arity=" << operand.arity << " sig #" << operand.index;
}
break;
}
case kExprCallImport: {
CallImportOperand operand(&decoder, pc);
if (decoder.Validate(pc, operand)) {
os << " // import #" << operand.index << ": " << *operand.sig;
} else {
os << " // arity=" << operand.arity << " import #" << operand.index;
}
break;
}
case kExprCallFunction: {
CallFunctionOperand operand(&decoder, pc);
if (decoder.Validate(pc, operand)) {
os << " // function #" << operand.index << ": " << *operand.sig;
} else {
os << " // arity=" << operand.arity << " function #" << operand.index;
}
break;
}
case kExprReturn: {
ReturnArityOperand operand(&decoder, pc);
os << " // arity=" << operand.arity;
break;
}
default:
break;
} }
}
pc += length; pc += length;
printf("\n"); os << std::endl;
arity_stack.push_back(arity);
while (arity_stack.back() == 0) {
arity_stack.pop_back();
if (arity_stack.empty()) break;
arity_stack.back()--;
}
} }
} }

View File

@ -224,6 +224,9 @@ TreeResult BuildTFGraph(base::AccountingAllocator* allocator,
TFBuilder* builder, FunctionBody& body); TFBuilder* builder, FunctionBody& body);
void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body); void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body);
// A simplified form of AST printing, e.g. from a debugger.
void PrintAstForDebugging(const byte* start, const byte* end);
inline TreeResult VerifyWasmCode(base::AccountingAllocator* allocator, inline TreeResult VerifyWasmCode(base::AccountingAllocator* allocator,
ModuleEnv* module, FunctionSig* sig, ModuleEnv* module, FunctionSig* sig,
const byte* start, const byte* end) { const byte* start, const byte* end) {