Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1240)

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: address ahaas' comments Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « 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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 ModuleEnv* m = module_; 150 ModuleEnv* m = module_;
151 if (m && m->module && operand.index < m->module->globals.size()) { 151 if (m && m->module && operand.index < m->module->globals.size()) {
152 operand.machine_type = m->module->globals[operand.index].type; 152 operand.machine_type = m->module->globals[operand.index].type;
153 operand.type = WasmOpcodes::LocalTypeFor(operand.machine_type); 153 operand.type = WasmOpcodes::LocalTypeFor(operand.machine_type);
154 return true; 154 return true;
155 } 155 }
156 error(pc, pc + 1, "invalid global index"); 156 error(pc, pc + 1, "invalid global index");
157 return false; 157 return false;
158 } 158 }
159 159
160 inline bool Complete(const byte* pc, CallFunctionOperand& operand) {
161 ModuleEnv* m = module_;
162 if (m && m->module && operand.index < m->module->functions.size()) {
163 operand.sig = m->module->functions[operand.index].sig;
164 return true;
165 }
166 return false;
167 }
168
160 inline bool Validate(const byte* pc, CallFunctionOperand& operand) { 169 inline bool Validate(const byte* pc, CallFunctionOperand& operand) {
161 ModuleEnv* m = module_; 170 if (Complete(pc, operand)) {
162 if (m && m->module && operand.index < m->module->functions.size()) {
163 operand.sig = m->module->functions[operand.index].sig;
164 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count()); 171 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count());
165 if (operand.arity != expected) { 172 if (operand.arity != expected) {
166 error(pc, pc + 1, 173 error(pc, pc + 1,
167 "arity mismatch in direct function call (expected %u, got %u)", 174 "arity mismatch in direct function call (expected %u, got %u)",
168 expected, operand.arity); 175 expected, operand.arity);
169 return false; 176 return false;
170 } 177 }
171 return true; 178 return true;
172 } 179 }
173 error(pc, pc + 1, "invalid function index"); 180 error(pc, pc + 1, "invalid function index");
174 return false; 181 return false;
175 } 182 }
176 183
184 inline bool Complete(const byte* pc, CallIndirectOperand& operand) {
185 ModuleEnv* m = module_;
186 if (m && m->module && operand.index < m->module->signatures.size()) {
187 operand.sig = m->module->signatures[operand.index];
188 return true;
189 }
190 return false;
191 }
192
177 inline bool Validate(const byte* pc, CallIndirectOperand& operand) { 193 inline bool Validate(const byte* pc, CallIndirectOperand& operand) {
178 ModuleEnv* m = module_; 194 if (Complete(pc, operand)) {
179 if (m && m->module && operand.index < m->module->signatures.size()) {
180 operand.sig = m->module->signatures[operand.index];
181 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count()); 195 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count());
182 if (operand.arity != expected) { 196 if (operand.arity != expected) {
183 error(pc, pc + 1, 197 error(pc, pc + 1,
184 "arity mismatch in indirect function call (expected %u, got %u)", 198 "arity mismatch in indirect function call (expected %u, got %u)",
185 expected, operand.arity); 199 expected, operand.arity);
186 return false; 200 return false;
187 } 201 }
188 return true; 202 return true;
189 } 203 }
190 error(pc, pc + 1, "invalid signature index"); 204 error(pc, pc + 1, "invalid signature index");
191 return false; 205 return false;
192 } 206 }
193 207
208 inline bool Complete(const byte* pc, CallImportOperand& operand) {
209 ModuleEnv* m = module_;
210 if (m && m->module && operand.index < m->module->import_table.size()) {
211 operand.sig = m->module->import_table[operand.index].sig;
212 return true;
213 }
214 return false;
215 }
216
194 inline bool Validate(const byte* pc, CallImportOperand& operand) { 217 inline bool Validate(const byte* pc, CallImportOperand& operand) {
195 ModuleEnv* m = module_; 218 if (Complete(pc, operand)) {
196 if (m && m->module && operand.index < m->module->import_table.size()) {
197 operand.sig = m->module->import_table[operand.index].sig;
198 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count()); 219 uint32_t expected = static_cast<uint32_t>(operand.sig->parameter_count());
199 if (operand.arity != expected) { 220 if (operand.arity != expected) {
200 error(pc, pc + 1, "arity mismatch in import call (expected %u, got %u)", 221 error(pc, pc + 1, "arity mismatch in import call (expected %u, got %u)",
201 expected, operand.arity); 222 expected, operand.arity);
202 return false; 223 return false;
203 } 224 }
204 return true; 225 return true;
205 } 226 }
206 error(pc, pc + 1, "invalid signature index"); 227 error(pc, pc + 1, "invalid signature index");
207 return false; 228 return false;
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 default: 405 default:
385 return 1; 406 return 1;
386 } 407 }
387 } 408 }
388 }; 409 };
389 410
390 // A shift-reduce-parser strategy for decoding Wasm code that uses an explicit 411 // A shift-reduce-parser strategy for decoding Wasm code that uses an explicit
391 // shift-reduce strategy with multiple internal stacks. 412 // shift-reduce strategy with multiple internal stacks.
392 class SR_WasmDecoder : public WasmDecoder { 413 class SR_WasmDecoder : public WasmDecoder {
393 public: 414 public:
394 SR_WasmDecoder(Zone* zone, TFBuilder* builder, FunctionBody& body) 415 SR_WasmDecoder(Zone* zone, TFBuilder* builder, const FunctionBody& body)
395 : WasmDecoder(body.module, body.sig, body.start, body.end), 416 : WasmDecoder(body.module, body.sig, body.start, body.end),
396 zone_(zone), 417 zone_(zone),
397 builder_(builder), 418 builder_(builder),
398 base_(body.base), 419 base_(body.base),
399 local_type_vec_(zone), 420 local_type_vec_(zone),
400 stack_(zone), 421 stack_(zone),
401 control_(zone) { 422 control_(zone) {
402 local_types_ = &local_type_vec_; 423 local_types_ = &local_type_vec_;
403 } 424 }
404 425
(...skipping 1114 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 WasmDecoder decoder(nullptr, nullptr, pc, end); 1540 WasmDecoder decoder(nullptr, nullptr, pc, end);
1520 return decoder.OpcodeLength(pc); 1541 return decoder.OpcodeLength(pc);
1521 } 1542 }
1522 1543
1523 int OpcodeArity(const byte* pc, const byte* end) { 1544 int OpcodeArity(const byte* pc, const byte* end) {
1524 WasmDecoder decoder(nullptr, nullptr, pc, end); 1545 WasmDecoder decoder(nullptr, nullptr, pc, end);
1525 return decoder.OpcodeArity(pc); 1546 return decoder.OpcodeArity(pc);
1526 } 1547 }
1527 1548
1528 void PrintAstForDebugging(const byte* start, const byte* end) { 1549 void PrintAstForDebugging(const byte* start, const byte* end) {
1529 FunctionBody body = {nullptr, nullptr, start, start, end};
1530 base::AccountingAllocator allocator; 1550 base::AccountingAllocator allocator;
1531 PrintAst(&allocator, body); 1551 OFStream os(stdout);
1552 PrintAst(&allocator, FunctionBodyForTesting(start, end), os, nullptr);
1532 } 1553 }
1533 1554
1534 void PrintAst(base::AccountingAllocator* allocator, FunctionBody& body) { 1555 bool PrintAst(base::AccountingAllocator* allocator, const FunctionBody& body,
1556 std::ostream& os,
1557 std::vector<std::tuple<uint32_t, int, int>>* offset_table) {
1535 Zone zone(allocator); 1558 Zone zone(allocator);
1536 SR_WasmDecoder decoder(&zone, nullptr, body); 1559 SR_WasmDecoder decoder(&zone, nullptr, body);
1537 1560 int line_nr = 0;
1538 OFStream os(stdout);
1539 1561
1540 // Print the function signature. 1562 // Print the function signature.
1541 if (body.sig) { 1563 if (body.sig) {
1542 os << "// signature: " << *body.sig << std::endl; 1564 os << "// signature: " << *body.sig << std::endl;
1565 ++line_nr;
1543 } 1566 }
1544 1567
1545 // Print the local declarations. 1568 // Print the local declarations.
1546 AstLocalDecls decls(&zone); 1569 AstLocalDecls decls(&zone);
1547 decoder.DecodeLocalDecls(decls); 1570 decoder.DecodeLocalDecls(decls);
1548 const byte* pc = decoder.pc(); 1571 const byte* pc = decoder.pc();
1549 if (body.start != decoder.pc()) { 1572 if (body.start != decoder.pc()) {
1550 os << "// locals: "; 1573 os << "// locals: ";
1551 for (auto p : decls.local_types) { 1574 for (auto p : decls.local_types) {
1552 LocalType type = p.first; 1575 LocalType type = p.first;
1553 uint32_t count = p.second; 1576 uint32_t count = p.second;
1554 os << " " << count << " " << WasmOpcodes::TypeName(type); 1577 os << " " << count << " " << WasmOpcodes::TypeName(type);
1555 } 1578 }
1556 os << std::endl; 1579 os << std::endl;
1557 1580
1558 for (const byte* locals = body.start; locals < pc; locals++) { 1581 for (const byte* locals = body.start; locals < pc; locals++) {
1559 printf(" 0x%02x,", *locals); 1582 os << (locals == body.start ? "0x" : " 0x") << AsHex(*locals, 2) << ",";
1560 } 1583 }
1561 os << std::endl; 1584 os << std::endl;
1585 ++line_nr;
1562 } 1586 }
1563 1587
1564 os << "// body: \n"; 1588 os << "// body: " << std::endl;
1565 int control_depth = 0; 1589 ++line_nr;
1590 unsigned control_depth = 0;
1566 while (pc < body.end) { 1591 while (pc < body.end) {
1567 size_t length = decoder.OpcodeLength(pc); 1592 size_t length = decoder.OpcodeLength(pc);
1568 1593
1569 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); 1594 WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
1570 if (opcode == kExprElse) control_depth--; 1595 if (opcode == kExprElse) control_depth--;
1571 1596
1572 for (int i = 0; i < control_depth && i < 32; i++) printf(" "); 1597 int num_whitespaces = control_depth < 32 ? 2 * control_depth : 64;
1573 printf("k%s,", WasmOpcodes::OpcodeName(opcode)); 1598 if (offset_table) {
1599 offset_table->push_back(
1600 std::make_tuple(pc - body.start, line_nr, num_whitespaces));
1601 }
1602
1603 // 64 whitespaces
1604 const char* padding =
1605 " ";
1606 os.write(padding, num_whitespaces);
1607 os << "k" << WasmOpcodes::OpcodeName(opcode) << ",";
1574 1608
1575 for (size_t i = 1; i < length; i++) { 1609 for (size_t i = 1; i < length; i++) {
1576 printf(" 0x%02x,", pc[i]); 1610 os << " " << AsHex(pc[i], 2) << ",";
1577 } 1611 }
1578 1612
1579 switch (opcode) { 1613 switch (opcode) {
1580 case kExprIf: 1614 case kExprIf:
1581 case kExprElse: 1615 case kExprElse:
1582 case kExprLoop: 1616 case kExprLoop:
1583 case kExprBlock: 1617 case kExprBlock:
1584 os << " // @" << static_cast<int>(pc - body.start); 1618 os << " // @" << static_cast<int>(pc - body.start);
1585 control_depth++; 1619 control_depth++;
1586 break; 1620 break;
(...skipping 12 matching lines...) Expand all
1599 break; 1633 break;
1600 } 1634 }
1601 case kExprBrTable: { 1635 case kExprBrTable: {
1602 BranchTableOperand operand(&decoder, pc); 1636 BranchTableOperand operand(&decoder, pc);
1603 os << " // arity=" << operand.arity 1637 os << " // arity=" << operand.arity
1604 << " entries=" << operand.table_count; 1638 << " entries=" << operand.table_count;
1605 break; 1639 break;
1606 } 1640 }
1607 case kExprCallIndirect: { 1641 case kExprCallIndirect: {
1608 CallIndirectOperand operand(&decoder, pc); 1642 CallIndirectOperand operand(&decoder, pc);
1609 if (decoder.Validate(pc, operand)) { 1643 if (decoder.Complete(pc, operand)) {
1610 os << " // sig #" << operand.index << ": " << *operand.sig; 1644 os << " // sig #" << operand.index << ": " << *operand.sig;
1611 } else { 1645 } else {
1612 os << " // arity=" << operand.arity << " sig #" << operand.index; 1646 os << " // arity=" << operand.arity << " sig #" << operand.index;
1613 } 1647 }
1614 break; 1648 break;
1615 } 1649 }
1616 case kExprCallImport: { 1650 case kExprCallImport: {
1617 CallImportOperand operand(&decoder, pc); 1651 CallImportOperand operand(&decoder, pc);
1618 if (decoder.Validate(pc, operand)) { 1652 if (decoder.Complete(pc, operand)) {
1619 os << " // import #" << operand.index << ": " << *operand.sig; 1653 os << " // import #" << operand.index << ": " << *operand.sig;
1620 } else { 1654 } else {
1621 os << " // arity=" << operand.arity << " import #" << operand.index; 1655 os << " // arity=" << operand.arity << " import #" << operand.index;
1622 } 1656 }
1623 break; 1657 break;
1624 } 1658 }
1625 case kExprCallFunction: { 1659 case kExprCallFunction: {
1626 CallFunctionOperand operand(&decoder, pc); 1660 CallFunctionOperand operand(&decoder, pc);
1627 if (decoder.Validate(pc, operand)) { 1661 if (decoder.Complete(pc, operand)) {
1628 os << " // function #" << operand.index << ": " << *operand.sig; 1662 os << " // function #" << operand.index << ": " << *operand.sig;
1629 } else { 1663 } else {
1630 os << " // arity=" << operand.arity << " function #" << operand.index; 1664 os << " // arity=" << operand.arity << " function #" << operand.index;
1631 } 1665 }
1632 break; 1666 break;
1633 } 1667 }
1634 case kExprReturn: { 1668 case kExprReturn: {
1635 ReturnArityOperand operand(&decoder, pc); 1669 ReturnArityOperand operand(&decoder, pc);
1636 os << " // arity=" << operand.arity; 1670 os << " // arity=" << operand.arity;
1637 break; 1671 break;
1638 } 1672 }
1639 default: 1673 default:
1640 break; 1674 break;
1641 } 1675 }
1642 1676
1643 pc += length; 1677 pc += length;
1644 os << std::endl; 1678 os << std::endl;
1679 ++line_nr;
1645 } 1680 }
1681
1682 return decoder.ok();
1646 } 1683 }
1647 1684
1648 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, 1685 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
1649 const byte* start, const byte* end) { 1686 const byte* start, const byte* end) {
1650 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; 1687 FunctionBody body = {nullptr, nullptr, nullptr, start, end};
1651 SR_WasmDecoder decoder(zone, nullptr, body); 1688 SR_WasmDecoder decoder(zone, nullptr, body);
1652 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); 1689 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals);
1653 } 1690 }
1654 1691
1655 } // namespace wasm 1692 } // namespace wasm
1656 } // namespace internal 1693 } // namespace internal
1657 } // namespace v8 1694 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/ast-decoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698