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 |