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

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

Issue 2052623003: [wasm] improve handling of malformed input (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 4 years, 5 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') | src/wasm/decoder.h » ('j') | 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 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 for (uint32_t i = 0; i < operand.table_count + 1; ++i) { 252 for (uint32_t i = 0; i < operand.table_count + 1; ++i) {
253 uint32_t target = operand.read_entry(this, i); 253 uint32_t target = operand.read_entry(this, i);
254 if (target >= block_depth) { 254 if (target >= block_depth) {
255 error(operand.table + i * 2, "improper branch in br_table"); 255 error(operand.table + i * 2, "improper branch in br_table");
256 return false; 256 return false;
257 } 257 }
258 } 258 }
259 return true; 259 return true;
260 } 260 }
261 261
262 int OpcodeArity(const byte* pc) { 262 unsigned OpcodeArity(const byte* pc) {
263 #define DECLARE_ARITY(name, ...) \ 263 #define DECLARE_ARITY(name, ...) \
264 static const LocalType kTypes_##name[] = {__VA_ARGS__}; \ 264 static const LocalType kTypes_##name[] = {__VA_ARGS__}; \
265 static const int kArity_##name = \ 265 static const int kArity_##name = \
266 static_cast<int>(arraysize(kTypes_##name) - 1); 266 static_cast<int>(arraysize(kTypes_##name) - 1);
267 267
268 FOREACH_SIGNATURE(DECLARE_ARITY); 268 FOREACH_SIGNATURE(DECLARE_ARITY);
269 #undef DECLARE_ARITY 269 #undef DECLARE_ARITY
270 270
271 switch (static_cast<WasmOpcode>(*pc)) { 271 switch (static_cast<WasmOpcode>(*pc)) {
272 case kExprI8Const: 272 case kExprI8Const:
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 FOREACH_SIMPLE_OPCODE(DECLARE_OPCODE_CASE) 333 FOREACH_SIMPLE_OPCODE(DECLARE_OPCODE_CASE)
334 FOREACH_ASMJS_COMPAT_OPCODE(DECLARE_OPCODE_CASE) 334 FOREACH_ASMJS_COMPAT_OPCODE(DECLARE_OPCODE_CASE)
335 FOREACH_SIMD_OPCODE(DECLARE_OPCODE_CASE) 335 FOREACH_SIMD_OPCODE(DECLARE_OPCODE_CASE)
336 #undef DECLARE_OPCODE_CASE 336 #undef DECLARE_OPCODE_CASE
337 default: 337 default:
338 UNREACHABLE(); 338 UNREACHABLE();
339 return 0; 339 return 0;
340 } 340 }
341 } 341 }
342 342
343 int OpcodeLength(const byte* pc) { 343 unsigned OpcodeLength(const byte* pc) {
344 switch (static_cast<WasmOpcode>(*pc)) { 344 switch (static_cast<WasmOpcode>(*pc)) {
345 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: 345 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name:
346 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE) 346 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE)
347 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE) 347 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE)
348 #undef DECLARE_OPCODE_CASE 348 #undef DECLARE_OPCODE_CASE
349 { 349 {
350 MemoryAccessOperand operand(this, pc); 350 MemoryAccessOperand operand(this, pc);
351 return 1 + operand.length; 351 return 1 + operand.length;
352 } 352 }
353 case kExprBr: 353 case kExprBr:
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 // Decodes the body of a function. 614 // Decodes the body of a function.
615 void DecodeFunctionBody() { 615 void DecodeFunctionBody() {
616 TRACE("wasm-decode %p...%p (module+%d, %d bytes) %s\n", 616 TRACE("wasm-decode %p...%p (module+%d, %d bytes) %s\n",
617 reinterpret_cast<const void*>(start_), 617 reinterpret_cast<const void*>(start_),
618 reinterpret_cast<const void*>(limit_), baserel(pc_), 618 reinterpret_cast<const void*>(limit_), baserel(pc_),
619 static_cast<int>(limit_ - start_), builder_ ? "graph building" : ""); 619 static_cast<int>(limit_ - start_), builder_ ? "graph building" : "");
620 620
621 if (pc_ >= limit_) return; // Nothing to do. 621 if (pc_ >= limit_) return; // Nothing to do.
622 622
623 while (true) { // decoding loop. 623 while (true) { // decoding loop.
624 int len = 1; 624 unsigned len = 1;
625 WasmOpcode opcode = static_cast<WasmOpcode>(*pc_); 625 WasmOpcode opcode = static_cast<WasmOpcode>(*pc_);
626 TRACE(" @%-6d #%02x:%-20s|", startrel(pc_), opcode, 626 TRACE(" @%-6d #%02x:%-20s|", startrel(pc_), opcode,
627 WasmOpcodes::ShortOpcodeName(opcode)); 627 WasmOpcodes::ShortOpcodeName(opcode));
628 628
629 FunctionSig* sig = WasmOpcodes::Signature(opcode); 629 FunctionSig* sig = WasmOpcodes::Signature(opcode);
630 if (sig) { 630 if (sig) {
631 // Fast case of a simple operator. 631 // Fast case of a simple operator.
632 TFNode* node; 632 TFNode* node;
633 switch (sig->parameter_count()) { 633 switch (sig->parameter_count()) {
634 case 1: { 634 case 1: {
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after
1448 TRACE(" !%s\n", error_msg_.get()); 1448 TRACE(" !%s\n", error_msg_.get());
1449 } 1449 }
1450 BitVector* AnalyzeLoopAssignment(const byte* pc) { 1450 BitVector* AnalyzeLoopAssignment(const byte* pc) {
1451 if (pc >= limit_) return nullptr; 1451 if (pc >= limit_) return nullptr;
1452 if (*pc != kExprLoop) return nullptr; 1452 if (*pc != kExprLoop) return nullptr;
1453 1453
1454 BitVector* assigned = 1454 BitVector* assigned =
1455 new (zone_) BitVector(static_cast<int>(local_type_vec_.size()), zone_); 1455 new (zone_) BitVector(static_cast<int>(local_type_vec_.size()), zone_);
1456 int depth = 0; 1456 int depth = 0;
1457 // Iteratively process all AST nodes nested inside the loop. 1457 // Iteratively process all AST nodes nested inside the loop.
1458 while (pc < limit_) { 1458 while (pc < limit_ && ok()) {
1459 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); 1459 WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
1460 int length = 1; 1460 unsigned length = 1;
1461 switch (opcode) { 1461 switch (opcode) {
1462 case kExprLoop: 1462 case kExprLoop:
1463 case kExprIf: 1463 case kExprIf:
1464 case kExprBlock: 1464 case kExprBlock:
1465 depth++; 1465 depth++;
1466 DCHECK_EQ(1, OpcodeLength(pc)); 1466 DCHECK_EQ(1, OpcodeLength(pc));
1467 break; 1467 break;
1468 case kExprSetLocal: { 1468 case kExprSetLocal: {
1469 LocalIndexOperand operand(this, pc); 1469 LocalIndexOperand operand(this, pc);
1470 if (assigned->length() > 0 && 1470 if (assigned->length() > 0 &&
1471 static_cast<int>(operand.index) < assigned->length()) { 1471 static_cast<int>(operand.index) < assigned->length()) {
1472 // Unverified code might have an out-of-bounds index. 1472 // Unverified code might have an out-of-bounds index.
1473 assigned->Add(operand.index); 1473 assigned->Add(operand.index);
1474 } 1474 }
1475 length = 1 + operand.length; 1475 length = 1 + operand.length;
1476 break; 1476 break;
1477 } 1477 }
1478 case kExprEnd: 1478 case kExprEnd:
1479 depth--; 1479 depth--;
1480 break; 1480 break;
1481 default: 1481 default:
1482 length = OpcodeLength(pc); 1482 length = OpcodeLength(pc);
1483 break; 1483 break;
1484 } 1484 }
1485 if (depth <= 0) break; 1485 if (depth <= 0) break;
1486 pc += length; 1486 pc += length;
1487 } 1487 }
1488 return assigned; 1488 return ok() ? assigned : nullptr;
1489 } 1489 }
1490 1490
1491 inline wasm::WasmCodePosition position() { 1491 inline wasm::WasmCodePosition position() {
1492 int offset = static_cast<int>(pc_ - start_); 1492 int offset = static_cast<int>(pc_ - start_);
1493 DCHECK_EQ(pc_ - start_, offset); // overflows cannot happen 1493 DCHECK_EQ(pc_ - start_, offset); // overflows cannot happen
1494 return offset; 1494 return offset;
1495 } 1495 }
1496 }; 1496 };
1497 1497
1498 bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start, 1498 bool DecodeLocalDecls(AstLocalDecls& decls, const byte* start,
(...skipping 29 matching lines...) Expand all
1528 PrintF("%s", WasmOpcodes::OpcodeName(tree.opcode())); 1528 PrintF("%s", WasmOpcodes::OpcodeName(tree.opcode()));
1529 if (tree.count > 0) os << "("; 1529 if (tree.count > 0) os << "(";
1530 for (uint32_t i = 0; i < tree.count; ++i) { 1530 for (uint32_t i = 0; i < tree.count; ++i) {
1531 if (i > 0) os << ", "; 1531 if (i > 0) os << ", ";
1532 os << *tree.children[i]; 1532 os << *tree.children[i];
1533 } 1533 }
1534 if (tree.count > 0) os << ")"; 1534 if (tree.count > 0) os << ")";
1535 return os; 1535 return os;
1536 } 1536 }
1537 1537
1538 int OpcodeLength(const byte* pc, const byte* end) { 1538 unsigned OpcodeLength(const byte* pc, const byte* end) {
1539 WasmDecoder decoder(nullptr, nullptr, pc, end); 1539 WasmDecoder decoder(nullptr, nullptr, pc, end);
1540 return decoder.OpcodeLength(pc); 1540 return decoder.OpcodeLength(pc);
1541 } 1541 }
1542 1542
1543 int OpcodeArity(const byte* pc, const byte* end) { 1543 unsigned OpcodeArity(const byte* pc, const byte* end) {
1544 WasmDecoder decoder(nullptr, nullptr, pc, end); 1544 WasmDecoder decoder(nullptr, nullptr, pc, end);
1545 return decoder.OpcodeArity(pc); 1545 return decoder.OpcodeArity(pc);
1546 } 1546 }
1547 1547
1548 void PrintAstForDebugging(const byte* start, const byte* end) { 1548 void PrintAstForDebugging(const byte* start, const byte* end) {
1549 base::AccountingAllocator allocator; 1549 base::AccountingAllocator allocator;
1550 OFStream os(stdout); 1550 OFStream os(stdout);
1551 PrintAst(&allocator, FunctionBodyForTesting(start, end), os, nullptr); 1551 PrintAst(&allocator, FunctionBodyForTesting(start, end), os, nullptr);
1552 } 1552 }
1553 1553
(...skipping 27 matching lines...) Expand all
1581 os << (locals == body.start ? "0x" : " 0x") << AsHex(*locals, 2) << ","; 1581 os << (locals == body.start ? "0x" : " 0x") << AsHex(*locals, 2) << ",";
1582 } 1582 }
1583 os << std::endl; 1583 os << std::endl;
1584 ++line_nr; 1584 ++line_nr;
1585 } 1585 }
1586 1586
1587 os << "// body: " << std::endl; 1587 os << "// body: " << std::endl;
1588 ++line_nr; 1588 ++line_nr;
1589 unsigned control_depth = 0; 1589 unsigned control_depth = 0;
1590 while (pc < body.end) { 1590 while (pc < body.end) {
1591 size_t length = decoder.OpcodeLength(pc); 1591 unsigned length = decoder.OpcodeLength(pc);
1592 1592
1593 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); 1593 WasmOpcode opcode = static_cast<WasmOpcode>(*pc);
1594 if (opcode == kExprElse) control_depth--; 1594 if (opcode == kExprElse) control_depth--;
1595 1595
1596 int num_whitespaces = control_depth < 32 ? 2 * control_depth : 64; 1596 int num_whitespaces = control_depth < 32 ? 2 * control_depth : 64;
1597 if (offset_table) { 1597 if (offset_table) {
1598 offset_table->push_back( 1598 offset_table->push_back(
1599 std::make_tuple(pc - body.start, line_nr, num_whitespaces)); 1599 std::make_tuple(pc - body.start, line_nr, num_whitespaces));
1600 } 1600 }
1601 1601
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1684 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, 1684 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals,
1685 const byte* start, const byte* end) { 1685 const byte* start, const byte* end) {
1686 FunctionBody body = {nullptr, nullptr, nullptr, start, end}; 1686 FunctionBody body = {nullptr, nullptr, nullptr, start, end};
1687 SR_WasmDecoder decoder(zone, nullptr, body); 1687 SR_WasmDecoder decoder(zone, nullptr, body);
1688 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals); 1688 return decoder.AnalyzeLoopAssignmentForTesting(start, num_locals);
1689 } 1689 }
1690 1690
1691 } // namespace wasm 1691 } // namespace wasm
1692 } // namespace internal 1692 } // namespace internal
1693 } // namespace v8 1693 } // namespace v8
OLDNEW
« no previous file with comments | « src/wasm/ast-decoder.h ('k') | src/wasm/decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698