Chromium Code Reviews

Side by Side Diff: src/wasm/ast-decoder.cc

Issue 2050213002: [wasm] Implement AST printing into an ostream (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@refactor-function-names-table
Patch Set: see if adding <functional> include fixes this Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
« src/wasm/ast-decoder.h ('K') | « src/wasm/ast-decoder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/signature.h" 5 #include "src/signature.h"
6 6
7 #include "src/bit-vector.h" 7 #include "src/bit-vector.h"
8 #include "src/flags.h" 8 #include "src/flags.h"
9 #include "src/handles.h" 9 #include "src/handles.h"
10 #include "src/zone-containers.h" 10 #include "src/zone-containers.h"
(...skipping 130 matching lines...)
141 operand.type = kAstStmt; 141 operand.type = kAstStmt;
142 } 142 }
143 return true; 143 return true;
144 } 144 }
145 error(pc, pc + 1, "invalid local index"); 145 error(pc, pc + 1, "invalid local index");
146 return false; 146 return false;
147 } 147 }
148 148
149 inline bool Validate(const byte* pc, GlobalIndexOperand& operand) { 149 inline bool Validate(const byte* pc, GlobalIndexOperand& operand) {
150 ModuleEnv* m = module_; 150 ModuleEnv* m = module_;
151 if (m && m->module && operand.index < m->module->globals.size()) { 151 if (!m || !m->module) return false;
titzer 2016/06/10 10:57:40 This change means that there will not be an error
Clemens Hammacher 2016/06/13 09:45:17 I changed it to have a Complete() and a Validate()
152 if (operand.index < m->module->globals.size()) {
152 operand.machine_type = m->module->globals[operand.index].type; 153 operand.machine_type = m->module->globals[operand.index].type;
153 operand.type = WasmOpcodes::LocalTypeFor(operand.machine_type); 154 operand.type = WasmOpcodes::LocalTypeFor(operand.machine_type);
154 return true; 155 return true;
155 } 156 }
156 error(pc, pc + 1, "invalid global index"); 157 error(pc, pc + 1, "invalid global index");
157 return false; 158 return false;
158 } 159 }
159 160
160 inline bool Validate(const byte* pc, CallFunctionOperand& operand) { 161 inline bool Validate(const byte* pc, CallFunctionOperand& operand) {
161 ModuleEnv* m = module_; 162 ModuleEnv* m = module_;
162 if (m && m->module && operand.index < m->module->functions.size()) { 163 if (!m || !m->module) return false;
164 if (operand.index < m->module->functions.size()) {
163 operand.sig = m->module->functions[operand.index].sig; 165 operand.sig = m->module->functions[operand.index].sig;
164 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count()); 166 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count());
165 if (operand.arity != expected) { 167 if (operand.arity != expected) {
166 error(pc, pc + 1, 168 error(pc, pc + 1,
167 "arity mismatch in direct function call (expected %u, got %u)", 169 "arity mismatch in direct function call (expected %u, got %u)",
168 expected, operand.arity); 170 expected, operand.arity);
169 return false; 171 return false;
170 } 172 }
171 return true; 173 return true;
172 } 174 }
173 error(pc, pc + 1, "invalid function index"); 175 error(pc, pc + 1, "invalid function index");
174 return false; 176 return false;
175 } 177 }
176 178
177 inline bool Validate(const byte* pc, CallIndirectOperand& operand) { 179 inline bool Validate(const byte* pc, CallIndirectOperand& operand) {
178 ModuleEnv* m = module_; 180 ModuleEnv* m = module_;
179 if (m && m->module && operand.index < m->module->signatures.size()) { 181 if (!m || !m->module) return false;
182 if (operand.index < m->module->signatures.size()) {
180 operand.sig = m->module->signatures[operand.index]; 183 operand.sig = m->module->signatures[operand.index];
181 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count()); 184 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count());
182 if (operand.arity != expected) { 185 if (operand.arity != expected) {
183 error(pc, pc + 1, 186 error(pc, pc + 1,
184 "arity mismatch in indirect function call (expected %u, got %u)", 187 "arity mismatch in indirect function call (expected %u, got %u)",
185 expected, operand.arity); 188 expected, operand.arity);
186 return false; 189 return false;
187 } 190 }
188 return true; 191 return true;
189 } 192 }
190 error(pc, pc + 1, "invalid signature index"); 193 error(pc, pc + 1, "invalid signature index");
191 return false; 194 return false;
192 } 195 }
193 196
194 inline bool Validate(const byte* pc, CallImportOperand& operand) { 197 inline bool Validate(const byte* pc, CallImportOperand& operand) {
195 ModuleEnv* m = module_; 198 ModuleEnv* m = module_;
196 if (m && m->module && operand.index < m->module->import_table.size()) { 199 if (!m || !m->module) return false;
200 if (operand.index < m->module->import_table.size()) {
197 operand.sig = m->module->import_table[operand.index].sig; 201 operand.sig = m->module->import_table[operand.index].sig;
198 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count()); 202 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count());
199 if (operand.arity != expected) { 203 if (operand.arity != expected) {
200 error(pc, pc + 1, "arity mismatch in import call (expected %u, got %u)", 204 error(pc, pc + 1, "arity mismatch in import call (expected %u, got %u)",
201 expected, operand.arity); 205 expected, operand.arity);
202 return false; 206 return false;
203 } 207 }
204 return true; 208 return true;
205 } 209 }
206 error(pc, pc + 1, "invalid signature index"); 210 error(pc, pc + 1, "invalid signature index");
(...skipping 177 matching lines...)
384 default: 388 default:
385 return 1; 389 return 1;
386 } 390 }
387 } 391 }
388 }; 392 };
389 393
390 // A shift-reduce-parser strategy for decoding Wasm code that uses an explicit 394 // A shift-reduce-parser strategy for decoding Wasm code that uses an explicit
391 // shift-reduce strategy with multiple internal stacks. 395 // shift-reduce strategy with multiple internal stacks.
392 class SR_WasmDecoder : public WasmDecoder { 396 class SR_WasmDecoder : public WasmDecoder {
393 public: 397 public:
394 SR_WasmDecoder(Zone* zone, TFBuilder* builder, FunctionBody& body) 398 SR_WasmDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body)
395 : WasmDecoder(body.module, body.sig, body.start, body.end), 399 : WasmDecoder(body.module, body.sig, body.start, body.end),
396 zone_(zone), 400 zone_(zone),
397 builder_(builder), 401 builder_(builder),
398 base_(body.base), 402 base_(body.base),
399 local_type_vec_(zone), 403 local_type_vec_(zone),
400 stack_(zone), 404 stack_(zone),
401 control_(zone) { 405 control_(zone) {
402 local_types_ = &local_type_vec_; 406 local_types_ = &local_type_vec_;
403 } 407 }
404 408
(...skipping 1114 matching lines...)
1519 WasmDecoder decoder(nullptr, nullptr, pc, end); 1523 WasmDecoder decoder(nullptr, nullptr, pc, end);
1520 return decoder.OpcodeLength(pc); 1524 return decoder.OpcodeLength(pc);
1521 } 1525 }
1522 1526
1523 int OpcodeArity(const byte* pc, const byte* end) { 1527 int OpcodeArity(const byte* pc, const byte* end) {
1524 WasmDecoder decoder(nullptr, nullptr, pc, end); 1528 WasmDecoder decoder(nullptr, nullptr, pc, end);
1525 return decoder.OpcodeArity(pc); 1529 return decoder.OpcodeArity(pc);
1526 } 1530 }
1527 1531
1528 void PrintAstForDebugging(const byte* start, const byte* end) { 1532 void PrintAstForDebugging(const byte* start, const byte* end) {
1529 FunctionBody body = {nullptr, nullptr, start, start, end};
1530 base::AccountingAllocator allocator; 1533 base::AccountingAllocator allocator;
1531 PrintAst(&allocator, body); 1534 OFStream os(stdout);
1535 PrintAst(&allocator, FunctionBody::ForTesting(start, end), os);
1532 } 1536 }
1533 1537
1534 void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) { 1538 bool PrintAst(base::AccountingAllocator* allocator, const FunctionBody& body,
1539 std::ostream& os,
1540 std::function<void(uint32_t)> instruction_callback) {
1535 Zone zone(allocator); 1541 Zone zone(allocator);
1536 SR_WasmDecoder decoder(&zone, nullptr, body); 1542 SR_WasmDecoder decoder(&zone, nullptr, body);
1537 1543
1538 OFStream os(stdout);
1539
1540 // Print the function signature. 1544 // Print the function signature.
1541 if (body.sig) { 1545 if (body.sig) {
1542 os << "// signature: " << *body.sig << std::endl; 1546 os << "// signature: " << *body.sig << std::endl;
1543 } 1547 }
1544 1548
1545 // Print the local declarations. 1549 // Print the local declarations.
1546 AstLocalDecls decls(&zone); 1550 AstLocalDecls decls(&zone);
1547 decoder.DecodeLocalDecls(decls); 1551 decoder.DecodeLocalDecls(decls);
1548 const byte* pc = decoder.pc(); 1552 const byte* pc = decoder.pc();
1549 if (body.start != decoder.pc()) { 1553 if (body.start != decoder.pc()) {
1550 os << "// locals: "; 1554 os << "// locals: ";
1551 for (auto p : decls.local_types) { 1555 for (auto p : decls.local_types) {
1552 LocalType type = p.first; 1556 LocalType type = p.first;
1553 uint32_t count = p.second; 1557 uint32_t count = p.second;
1554 os << " " << count << " " << WasmOpcodes::TypeName(type); 1558 os << " " << count << " " << WasmOpcodes::TypeName(type);
1555 } 1559 }
1556 os << std::endl; 1560 os << std::endl;
1557 1561
1558 for (const byte* locals = body.start; locals < pc; locals++) { 1562 for (const byte* locals = body.start; locals < pc; locals++) {
1559 printf(" 0x%02x,", *locals); 1563 os << (locals == body.start ? "0x" : " 0x") << AsHex(*locals, 2) << ",";
1560 } 1564 }
1561 os << std::endl; 1565 os << std::endl;
1562 } 1566 }
1563 1567
1564 os << "// body: \n"; 1568 os << "// body: \n";
1565 int control_depth = 0; 1569 unsigned control_depth = 0;
1566 while (pc < body.end) { 1570 while (pc < body.end) {
1567 size_t length = decoder.OpcodeLength(pc); 1571 size_t length = decoder.OpcodeLength(pc);
1568 1572
1569 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); 1573 WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
1570 if (opcode == kExprElse) control_depth--; 1574 if (opcode == kExprElse) control_depth--;
1571 1575
1572 for (int i = 0; i < control_depth && i < 32; i++) printf(" "); 1576 // 32 whitespaces
1573 printf("k%s,", WasmOpcodes::OpcodeName(opcode)); 1577 const char* padding = " ";
1578 os.write(padding, control_depth < 32 ? control_depth : 32);
1579 if (instruction_callback) {
1580 instruction_callback(static_cast<int>(pc - body.start));
1581 }
1582 os << "k" << WasmOpcodes::OpcodeName(opcode) << ",";
1574 1583
1575 for (size_t i = 1; i < length; i++) { 1584 for (size_t i = 1; i < length; i++) {
1576 printf(" 0x%02x,", pc[i]); 1585 os << " " << AsHex(pc[i], 2) << ",";
1577 } 1586 }
1578 1587
1579 switch (opcode) { 1588 switch (opcode) {
1580 case kExprIf: 1589 case kExprIf:
1581 case kExprElse: 1590 case kExprElse:
1582 case kExprLoop: 1591 case kExprLoop:
1583 case kExprBlock: 1592 case kExprBlock:
1584 os << " // @" << static_cast<int>(pc - body.start); 1593 os << " // @" << static_cast<int>(pc - body.start);
1585 control_depth++; 1594 control_depth++;
1586 break; 1595 break;
(...skipping 49 matching lines...)
1636 os << " // arity=" << operand.arity; 1645 os << " // arity=" << operand.arity;
1637 break; 1646 break;
1638 } 1647 }
1639 default: 1648 default:
1640 break; 1649 break;
1641 } 1650 }
1642 1651
1643 pc += length; 1652 pc += length;
1644 os << std::endl; 1653 os << std::endl;
1645 } 1654 }
1655
1656 return decoder.ok();
1646 } 1657 }
1647 1658
1648 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, 1659 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
1649 const byte* start, const byte* end) { 1660 const byte* start, const byte* end) {
1650 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; 1661 FunctionBody body = {nullptr, nullptr, nullptr, start, end};
1651 SR_WasmDecoder decoder(zone, nullptr, body); 1662 SR_WasmDecoder decoder(zone, nullptr, body);
1652 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); 1663 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals);
1653 } 1664 }
1654 1665
1655 } // namespace wasm 1666 } // namespace wasm
1656 } // namespace internal 1667 } // namespace internal
1657 } // namespace v8 1668 } // namespace v8
OLDNEW
« src/wasm/ast-decoder.h ('K') | « src/wasm/ast-decoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine