| 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 offset, unsigned 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 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 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 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 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 offset, |
| 85 unsigned* 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 offset, unsigned* length, |
| 90 const char* msg = "expected SLEB32") { | 92 const char* msg = "expected SLEB32") { |
| 91 uint32_t result = | 93 uint32_t result = |
| 92 checked_read_leb<uint32_t, true>(base, offset, length, msg); | 94 checked_read_leb<uint32_t, true>(base, offset, length, msg); |
| 93 if (*length == 5) return bit_cast<int32_t>(result); | 95 if (*length == 5) return bit_cast<int32_t>(result); |
| 94 if (*length > 0) { | 96 if (*length > 0) { |
| 95 int shift = 32 - 7 * *length; | 97 int shift = 32 - 7 * *length; |
| 96 // Perform sign extension. | 98 // Perform sign extension. |
| 97 return bit_cast<int32_t>(result << shift) >> shift; | 99 return bit_cast<int32_t>(result << shift) >> shift; |
| 98 } | 100 } |
| 99 return 0; | 101 return 0; |
| 100 } | 102 } |
| 101 | 103 |
| 102 // Reads a variable-length unsigned integer (little endian). | 104 // Reads a variable-length unsigned integer (little endian). |
| 103 uint64_t checked_read_u64v(const byte* base, int offset, int* length, | 105 uint64_t checked_read_u64v(const byte* base, unsigned offset, |
| 106 unsigned* length, |
| 104 const char* msg = "expected LEB64") { | 107 const char* msg = "expected LEB64") { |
| 105 return checked_read_leb<uint64_t, false>(base, offset, length, msg); | 108 return checked_read_leb<uint64_t, false>(base, offset, length, msg); |
| 106 } | 109 } |
| 107 | 110 |
| 108 // Reads a variable-length signed integer (little endian). | 111 // Reads a variable-length signed integer (little endian). |
| 109 int64_t checked_read_i64v(const byte* base, int offset, int* length, | 112 int64_t checked_read_i64v(const byte* base, unsigned offset, unsigned* length, |
| 110 const char* msg = "expected SLEB64") { | 113 const char* msg = "expected SLEB64") { |
| 111 uint64_t result = | 114 uint64_t result = |
| 112 checked_read_leb<uint64_t, true>(base, offset, length, msg); | 115 checked_read_leb<uint64_t, true>(base, offset, length, msg); |
| 113 if (*length == 10) return bit_cast<int64_t>(result); | 116 if (*length == 10) return bit_cast<int64_t>(result); |
| 114 if (*length > 0) { | 117 if (*length > 0) { |
| 115 int shift = 64 - 7 * *length; | 118 int shift = 64 - 7 * *length; |
| 116 // Perform sign extension. | 119 // Perform sign extension. |
| 117 return bit_cast<int64_t>(result << shift) >> shift; | 120 return bit_cast<int64_t>(result << shift) >> shift; |
| 118 } | 121 } |
| 119 return 0; | 122 return 0; |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 const byte* start_; | 345 const byte* start_; |
| 343 const byte* pc_; | 346 const byte* pc_; |
| 344 const byte* limit_; | 347 const byte* limit_; |
| 345 const byte* end_; | 348 const byte* end_; |
| 346 const byte* error_pc_; | 349 const byte* error_pc_; |
| 347 const byte* error_pt_; | 350 const byte* error_pt_; |
| 348 base::SmartArrayPointer<char> error_msg_; | 351 base::SmartArrayPointer<char> error_msg_; |
| 349 | 352 |
| 350 private: | 353 private: |
| 351 template <typename IntType, bool is_signed> | 354 template <typename IntType, bool is_signed> |
| 352 IntType checked_read_leb(const byte* base, int offset, int* length, | 355 IntType checked_read_leb(const byte* base, unsigned offset, unsigned* length, |
| 353 const char* msg) { | 356 const char* msg) { |
| 354 if (!check(base, offset, 1, msg)) { | 357 if (!check(base, offset, 1, msg)) { |
| 355 *length = 0; | 358 *length = 0; |
| 356 return 0; | 359 return 0; |
| 357 } | 360 } |
| 358 | 361 |
| 359 const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7; | 362 const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7; |
| 360 const byte* ptr = base + offset; | 363 const byte* ptr = base + offset; |
| 361 const byte* end = ptr + kMaxLength; | 364 const byte* end = ptr + kMaxLength; |
| 362 if (end > limit_) end = limit_; | 365 if (end > limit_) end = limit_; |
| 363 int shift = 0; | 366 int shift = 0; |
| 364 byte b = 0; | 367 byte b = 0; |
| 365 IntType result = 0; | 368 IntType result = 0; |
| 366 while (ptr < end) { | 369 while (ptr < end) { |
| 367 b = *ptr++; | 370 b = *ptr++; |
| 368 result = result | (static_cast<IntType>(b & 0x7F) << shift); | 371 result = result | (static_cast<IntType>(b & 0x7F) << shift); |
| 369 if ((b & 0x80) == 0) break; | 372 if ((b & 0x80) == 0) break; |
| 370 shift += 7; | 373 shift += 7; |
| 371 } | 374 } |
| 372 DCHECK_LE(ptr - (base + offset), kMaxLength); | 375 DCHECK_LE(ptr - (base + offset), kMaxLength); |
| 373 *length = static_cast<int>(ptr - (base + offset)); | 376 *length = static_cast<unsigned>(ptr - (base + offset)); |
| 374 if (ptr == end) { | 377 if (ptr == end) { |
| 375 // Check there are no bits set beyond the bitwidth of {IntType}. | 378 // Check there are no bits set beyond the bitwidth of {IntType}. |
| 376 const int kExtraBits = (1 + kMaxLength * 7) - (sizeof(IntType) * 8); | 379 const int kExtraBits = (1 + kMaxLength * 7) - (sizeof(IntType) * 8); |
| 377 const byte kExtraBitsMask = | 380 const byte kExtraBitsMask = |
| 378 static_cast<byte>((0xFF << (8 - kExtraBits)) & 0xFF); | 381 static_cast<byte>((0xFF << (8 - kExtraBits)) & 0xFF); |
| 379 int extra_bits_value; | 382 int extra_bits_value; |
| 380 if (is_signed) { | 383 if (is_signed) { |
| 381 // A signed-LEB128 must sign-extend the final byte, excluding its | 384 // A signed-LEB128 must sign-extend the final byte, excluding its |
| 382 // most-signifcant bit. e.g. for a 32-bit LEB128: | 385 // most-signifcant bit. e.g. for a 32-bit LEB128: |
| 383 // kExtraBits = 4 | 386 // kExtraBits = 4 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 401 return result; | 404 return result; |
| 402 } | 405 } |
| 403 }; | 406 }; |
| 404 | 407 |
| 405 #undef TRACE | 408 #undef TRACE |
| 406 } // namespace wasm | 409 } // namespace wasm |
| 407 } // namespace internal | 410 } // namespace internal |
| 408 } // namespace v8 | 411 } // namespace v8 |
| 409 | 412 |
| 410 #endif // V8_WASM_DECODER_H_ | 413 #endif // V8_WASM_DECODER_H_ |
| OLD | NEW |