Chromium Code Reviews| Index: src/wasm/ast-decoder.cc |
| diff --git a/src/wasm/ast-decoder.cc b/src/wasm/ast-decoder.cc |
| index 1f361b9998dd63c8243f660226f18624065861d5..1432e152b084ceb9d1c6b1017dac97fadb9ec57f 100644 |
| --- a/src/wasm/ast-decoder.cc |
| +++ b/src/wasm/ast-decoder.cc |
| @@ -1524,6 +1524,12 @@ int OpcodeArity(const byte* pc, const byte* end) { |
| 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) { |
| Zone zone(allocator); |
| SR_WasmDecoder decoder(&zone, nullptr, body); |
| @@ -1540,7 +1546,7 @@ void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) { |
| decoder.DecodeLocalDecls(decls); |
| const byte* pc = decoder.pc(); |
| if (body.start != decoder.pc()) { |
| - printf("// locals:"); |
| + os << "// locals: "; |
| for (auto p : decls.local_types) { |
| LocalType type = p.first; |
| 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++) { |
| printf(" 0x%02x,", *locals); |
| } |
| - printf("\n"); |
| + os << std::endl; |
| } |
| - printf("// body: \n"); |
| - std::vector<int> arity_stack; |
| + os << "// body: \n"; |
| + int control_depth = 0; |
| while (pc < body.end) { |
| - int arity = decoder.OpcodeArity(pc); |
| size_t length = decoder.OpcodeLength(pc); |
| - for (auto arity : arity_stack) { |
| - printf(" "); |
| - USE(arity); |
| - } |
| - |
| 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)); |
| for (size_t i = 1; i < length; i++) { |
| printf(" 0x%02x,", pc[i]); |
| } |
| - if (body.module) { |
| - switch (opcode) { |
| - case kExprCallIndirect: { |
| - CallIndirectOperand operand(&decoder, pc); |
| - if (decoder.Validate(pc, operand)) { |
| - os << " // sig #" << operand.index << ": " << *operand.sig; |
| - } |
| - break; |
| + switch (opcode) { |
| + case kExprIf: |
| + case kExprElse: |
| + case kExprLoop: |
| + case kExprBlock: |
| + os << " // @" << static_cast<int>(pc - body.start); |
| + control_depth++; |
| + break; |
| + case kExprEnd: |
| + os << " // @" << static_cast<int>(pc - body.start); |
| + control_depth--; |
| + break; |
| + case kExprBr: { |
| + BreakDepthOperand operand(&decoder, pc); |
| + os << " // arity=" << operand.arity << " depth=" << operand.depth; |
|
Clemens Hammacher
2016/05/06 14:11:05
I don't see why you output the arity and depth her
titzer
2016/05/06 16:00:57
Yeah, they are encoded as varint operand following
|
| + break; |
| + } |
| + case kExprBrIf: { |
| + BreakDepthOperand operand(&decoder, pc); |
| + os << " // arity=" << operand.arity << " depth" << operand.depth; |
| + break; |
| + } |
| + case kExprBrTable: { |
| + BranchTableOperand operand(&decoder, pc); |
| + 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; |
| } |
| - case kExprCallImport: { |
| - CallImportOperand operand(&decoder, pc); |
| - if (decoder.Validate(pc, operand)) { |
| - os << " // import #" << operand.index << ": " << *operand.sig; |
| - } |
| - break; |
| + 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; |
| } |
| - case kExprCallFunction: { |
| - CallFunctionOperand operand(&decoder, pc); |
| - if (decoder.Validate(pc, operand)) { |
| - os << " // function #" << operand.index << ": " << *operand.sig; |
| - } |
| - break; |
| + 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; |
| } |
| - default: |
| - break; |
| + break; |
| + } |
| + case kExprReturn: { |
| + ReturnArityOperand operand(&decoder, pc); |
| + os << " // arity=" << operand.arity; |
| + break; |
| + } |
| + default: |
| + break; |
| } |
| - } |
| pc += length; |
| - printf("\n"); |
| - |
| - arity_stack.push_back(arity); |
| - while (arity_stack.back() == 0) { |
| - arity_stack.pop_back(); |
| - if (arity_stack.empty()) break; |
| - arity_stack.back()--; |
| - } |
| + os << std::endl; |
| } |
| } |