| OLD | NEW |
| 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 #ifndef V8_WASM_DECODER_H_ | 5 #ifndef V8_WASM_DECODER_H_ |
| 6 #define V8_WASM_DECODER_H_ | 6 #define V8_WASM_DECODER_H_ |
| 7 | 7 |
| 8 #include "src/base/compiler-specific.h" | 8 #include "src/base/compiler-specific.h" |
| 9 #include "src/base/smart-pointers.h" | 9 #include "src/base/smart-pointers.h" |
| 10 #include "src/flags.h" | 10 #include "src/flags.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 Decoder(const byte* start, const byte* end) | 39 Decoder(const byte* start, const byte* end) |
| 40 : start_(start), | 40 : start_(start), |
| 41 pc_(start), | 41 pc_(start), |
| 42 limit_(end), | 42 limit_(end), |
| 43 end_(end), | 43 end_(end), |
| 44 error_pc_(nullptr), | 44 error_pc_(nullptr), |
| 45 error_pt_(nullptr) {} | 45 error_pt_(nullptr) {} |
| 46 | 46 |
| 47 virtual ~Decoder() {} | 47 virtual ~Decoder() {} |
| 48 | 48 |
| 49 inline bool check(const byte* base, int offset, int length, const char* msg) { | 49 inline bool check(const byte* base, unsigned int offset, unsigned int length, |
| 50 const char* msg) { |
| 50 DCHECK_GE(base, start_); | 51 DCHECK_GE(base, start_); |
| 51 if ((base + offset + length) > limit_) { | 52 if ((base + offset + length) > limit_) { |
| 52 error(base, base + offset, "%s", msg); | 53 error(base, base + offset, "%s", msg); |
| 53 return false; | 54 return false; |
| 54 } | 55 } |
| 55 return true; | 56 return true; |
| 56 } | 57 } |
| 57 | 58 |
| 58 // Reads a single 8-bit byte, reporting an error if out of bounds. | 59 // Reads a single 8-bit byte, reporting an error if out of bounds. |
| 59 inline uint8_t checked_read_u8(const byte* base, int offset, | 60 inline uint8_t checked_read_u8(const byte* base, unsigned int offset, |
| 60 const char* msg = "expected 1 byte") { | 61 const char* msg = "expected 1 byte") { |
| 61 return check(base, offset, 1, msg) ? base[offset] : 0; | 62 return check(base, offset, 1, msg) ? base[offset] : 0; |
| 62 } | 63 } |
| 63 | 64 |
| 64 // Reads 16-bit word, reporting an error if out of bounds. | 65 // Reads 16-bit word, reporting an error if out of bounds. |
| 65 inline uint16_t checked_read_u16(const byte* base, int offset, | 66 inline uint16_t checked_read_u16(const byte* base, unsigned int offset, |
| 66 const char* msg = "expected 2 bytes") { | 67 const char* msg = "expected 2 bytes") { |
| 67 return check(base, offset, 2, msg) ? read_u16(base + offset) : 0; | 68 return check(base, offset, 2, msg) ? read_u16(base + offset) : 0; |
| 68 } | 69 } |
| 69 | 70 |
| 70 // Reads 32-bit word, reporting an error if out of bounds. | 71 // Reads 32-bit word, reporting an error if out of bounds. |
| 71 inline uint32_t checked_read_u32(const byte* base, int offset, | 72 inline uint32_t checked_read_u32(const byte* base, unsigned int offset, |
| 72 const char* msg = "expected 4 bytes") { | 73 const char* msg = "expected 4 bytes") { |
| 73 return check(base, offset, 4, msg) ? read_u32(base + offset) : 0; | 74 return check(base, offset, 4, msg) ? read_u32(base + offset) : 0; |
| 74 } | 75 } |
| 75 | 76 |
| 76 // Reads 64-bit word, reporting an error if out of bounds. | 77 // Reads 64-bit word, reporting an error if out of bounds. |
| 77 inline uint64_t checked_read_u64(const byte* base, int offset, | 78 inline uint64_t checked_read_u64(const byte* base, unsigned int offset, |
| 78 const char* msg = "expected 8 bytes") { | 79 const char* msg = "expected 8 bytes") { |
| 79 return check(base, offset, 8, msg) ? read_u64(base + offset) : 0; | 80 return check(base, offset, 8, msg) ? read_u64(base + offset) : 0; |
| 80 } | 81 } |
| 81 | 82 |
| 82 // Reads a variable-length unsigned integer (little endian). | 83 // Reads a variable-length unsigned integer (little endian). |
| 83 uint32_t checked_read_u32v(const byte* base, int offset, int* length, | 84 uint32_t checked_read_u32v(const byte* base, unsigned int offset, |
| 85 unsigned int* length, |
| 84 const char* msg = "expected LEB32") { | 86 const char* msg = "expected LEB32") { |
| 85 return checked_read_leb<uint32_t, false>(base, offset, length, msg); | 87 return checked_read_leb<uint32_t, false>(base, offset, length, msg); |
| 86 } | 88 } |
| 87 | 89 |
| 88 // Reads a variable-length signed integer (little endian). | 90 // Reads a variable-length signed integer (little endian). |
| 89 int32_t checked_read_i32v(const byte* base, int offset, int* length, | 91 int32_t checked_read_i32v(const byte* base, unsigned int offset, |
| 92 unsigned int* length, |
| 90 const char* msg = "expected SLEB32") { | 93 const char* msg = "expected SLEB32") { |
| 91 uint32_t result = | 94 uint32_t result = |
| 92 checked_read_leb<uint32_t, true>(base, offset, length, msg); | 95 checked_read_leb<uint32_t, true>(base, offset, length, msg); |
| 93 if (*length == 5) return bit_cast<int32_t>(result); | 96 if (*length == 5) return bit_cast<int32_t>(result); |
| 94 if (*length > 0) { | 97 if (*length > 0) { |
| 95 int shift = 32 - 7 * *length; | 98 int shift = 32 - 7 * *length; |
| 96 // Perform sign extension. | 99 // Perform sign extension. |
| 97 return bit_cast<int32_t>(result << shift) >> shift; | 100 return bit_cast<int32_t>(result << shift) >> shift; |
| 98 } | 101 } |
| 99 return 0; | 102 return 0; |
| 100 } | 103 } |
| 101 | 104 |
| 102 // Reads a variable-length unsigned integer (little endian). | 105 // Reads a variable-length unsigned integer (little endian). |
| 103 uint64_t checked_read_u64v(const byte* base, int offset, int* length, | 106 uint64_t checked_read_u64v(const byte* base, unsigned int offset, |
| 107 unsigned int* length, |
| 104 const char* msg = "expected LEB64") { | 108 const char* msg = "expected LEB64") { |
| 105 return checked_read_leb<uint64_t, false>(base, offset, length, msg); | 109 return checked_read_leb<uint64_t, false>(base, offset, length, msg); |
| 106 } | 110 } |
| 107 | 111 |
| 108 // Reads a variable-length signed integer (little endian). | 112 // Reads a variable-length signed integer (little endian). |
| 109 int64_t checked_read_i64v(const byte* base, int offset, int* length, | 113 int64_t checked_read_i64v(const byte* base, unsigned int offset, |
| 114 unsigned int* length, |
| 110 const char* msg = "expected SLEB64") { | 115 const char* msg = "expected SLEB64") { |
| 111 uint64_t result = | 116 uint64_t result = |
| 112 checked_read_leb<uint64_t, true>(base, offset, length, msg); | 117 checked_read_leb<uint64_t, true>(base, offset, length, msg); |
| 113 if (*length == 10) return bit_cast<int64_t>(result); | 118 if (*length == 10) return bit_cast<int64_t>(result); |
| 114 if (*length > 0) { | 119 if (*length > 0) { |
| 115 int shift = 64 - 7 * *length; | 120 int shift = 64 - 7 * *length; |
| 116 // Perform sign extension. | 121 // Perform sign extension. |
| 117 return bit_cast<int64_t>(result << shift) >> shift; | 122 return bit_cast<int64_t>(result << shift) >> shift; |
| 118 } | 123 } |
| 119 return 0; | 124 return 0; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 if (checkAvailable(4)) { | 202 if (checkAvailable(4)) { |
| 198 uint32_t val = read_u32(pc_); | 203 uint32_t val = read_u32(pc_); |
| 199 TRACE("%02x %02x %02x %02x = %u\n", pc_[0], pc_[1], pc_[2], pc_[3], val); | 204 TRACE("%02x %02x %02x %02x = %u\n", pc_[0], pc_[1], pc_[2], pc_[3], val); |
| 200 pc_ += 4; | 205 pc_ += 4; |
| 201 return val; | 206 return val; |
| 202 } | 207 } |
| 203 return traceOffEnd<uint32_t>(); | 208 return traceOffEnd<uint32_t>(); |
| 204 } | 209 } |
| 205 | 210 |
| 206 // Reads a LEB128 variable-length 32-bit integer and advances {pc_}. | 211 // Reads a LEB128 variable-length 32-bit integer and advances {pc_}. |
| 207 uint32_t consume_u32v(int* length, const char* name = nullptr) { | 212 uint32_t consume_u32v(unsigned int* length, const char* name = nullptr) { |
| 208 TRACE(" +%d %-20s: ", static_cast<int>(pc_ - start_), | 213 TRACE(" +%d %-20s: ", static_cast<int>(pc_ - start_), |
| 209 name ? name : "varint"); | 214 name ? name : "varint"); |
| 210 | 215 |
| 211 if (checkAvailable(1)) { | 216 if (checkAvailable(1)) { |
| 212 const byte* pos = pc_; | 217 const byte* pos = pc_; |
| 213 const byte* end = pc_ + 5; | 218 const byte* end = pc_ + 5; |
| 214 if (end > limit_) end = limit_; | 219 if (end > limit_) end = limit_; |
| 215 | 220 |
| 216 uint32_t result = 0; | 221 uint32_t result = 0; |
| 217 int shift = 0; | 222 int shift = 0; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 const byte* start_; | 348 const byte* start_; |
| 344 const byte* pc_; | 349 const byte* pc_; |
| 345 const byte* limit_; | 350 const byte* limit_; |
| 346 const byte* end_; | 351 const byte* end_; |
| 347 const byte* error_pc_; | 352 const byte* error_pc_; |
| 348 const byte* error_pt_; | 353 const byte* error_pt_; |
| 349 base::SmartArrayPointer<char> error_msg_; | 354 base::SmartArrayPointer<char> error_msg_; |
| 350 | 355 |
| 351 private: | 356 private: |
| 352 template <typename IntType, bool is_signed> | 357 template <typename IntType, bool is_signed> |
| 353 IntType checked_read_leb(const byte* base, int offset, int* length, | 358 IntType checked_read_leb(const byte* base, unsigned int offset, |
| 354 const char* msg) { | 359 unsigned int* length, const char* msg) { |
| 355 if (!check(base, offset, 1, msg)) { | 360 if (!check(base, offset, 1, msg)) { |
| 356 *length = 0; | 361 *length = 0; |
| 357 return 0; | 362 return 0; |
| 358 } | 363 } |
| 359 | 364 |
| 360 const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7; | 365 const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7; |
| 361 const byte* ptr = base + offset; | 366 const byte* ptr = base + offset; |
| 362 const byte* end = ptr + kMaxLength; | 367 const byte* end = ptr + kMaxLength; |
| 363 if (end > limit_) end = limit_; | 368 if (end > limit_) end = limit_; |
| 364 int shift = 0; | 369 int shift = 0; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 return result; | 407 return result; |
| 403 } | 408 } |
| 404 }; | 409 }; |
| 405 | 410 |
| 406 #undef TRACE | 411 #undef TRACE |
| 407 } // namespace wasm | 412 } // namespace wasm |
| 408 } // namespace internal | 413 } // namespace internal |
| 409 } // namespace v8 | 414 } // namespace v8 |
| 410 | 415 |
| 411 #endif // V8_WASM_DECODER_H_ | 416 #endif // V8_WASM_DECODER_H_ |
| OLD | NEW |