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/smart-pointers.h" | 8 #include "src/base/smart-pointers.h" |
9 #include "src/flags.h" | 9 #include "src/flags.h" |
10 #include "src/signature.h" | 10 #include "src/signature.h" |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 | 73 |
74 // Reads 64-bit word, reporting an error if out of bounds. | 74 // Reads 64-bit word, reporting an error if out of bounds. |
75 inline uint64_t checked_read_u64(const byte* base, int offset, | 75 inline uint64_t checked_read_u64(const byte* base, int offset, |
76 const char* msg = "expected 8 bytes") { | 76 const char* msg = "expected 8 bytes") { |
77 return check(base, offset, 8, msg) ? read_u64(base + offset) : 0; | 77 return check(base, offset, 8, msg) ? read_u64(base + offset) : 0; |
78 } | 78 } |
79 | 79 |
80 // Reads a variable-length unsigned integer (little endian). | 80 // Reads a variable-length unsigned integer (little endian). |
81 uint32_t checked_read_u32v(const byte* base, int offset, int* length, | 81 uint32_t checked_read_u32v(const byte* base, int offset, int* length, |
82 const char* msg = "expected LEB32") { | 82 const char* msg = "expected LEB32") { |
83 return checked_read_leb<uint32_t>(base, offset, length, msg); | 83 return checked_read_leb<uint32_t, false>(base, offset, length, msg); |
84 } | 84 } |
85 | 85 |
86 // Reads a variable-length signed integer (little endian). | 86 // Reads a variable-length signed integer (little endian). |
87 int32_t checked_read_i32v(const byte* base, int offset, int* length, | 87 int32_t checked_read_i32v(const byte* base, int offset, int* length, |
88 const char* msg = "expected SLEB32") { | 88 const char* msg = "expected SLEB32") { |
89 uint32_t result = checked_read_u32v(base, offset, length, msg); | 89 uint32_t result = |
| 90 checked_read_leb<uint32_t, true>(base, offset, length, msg); |
90 if (*length == 5) return bit_cast<int32_t>(result); | 91 if (*length == 5) return bit_cast<int32_t>(result); |
91 if (*length > 0) { | 92 if (*length > 0) { |
92 int shift = 32 - 7 * *length; | 93 int shift = 32 - 7 * *length; |
93 // Perform sign extension. | 94 // Perform sign extension. |
94 return bit_cast<int32_t>(result << shift) >> shift; | 95 return bit_cast<int32_t>(result << shift) >> shift; |
95 } | 96 } |
96 return 0; | 97 return 0; |
97 } | 98 } |
98 | 99 |
99 // Reads a variable-length unsigned integer (little endian). | 100 // Reads a variable-length unsigned integer (little endian). |
100 uint64_t checked_read_u64v(const byte* base, int offset, int* length, | 101 uint64_t checked_read_u64v(const byte* base, int offset, int* length, |
101 const char* msg = "expected LEB64") { | 102 const char* msg = "expected LEB64") { |
102 return checked_read_leb<uint64_t>(base, offset, length, msg); | 103 return checked_read_leb<uint64_t, false>(base, offset, length, msg); |
103 } | 104 } |
104 | 105 |
105 // Reads a variable-length signed integer (little endian). | 106 // Reads a variable-length signed integer (little endian). |
106 int64_t checked_read_i64v(const byte* base, int offset, int* length, | 107 int64_t checked_read_i64v(const byte* base, int offset, int* length, |
107 const char* msg = "expected SLEB64") { | 108 const char* msg = "expected SLEB64") { |
108 uint64_t result = checked_read_u64v(base, offset, length, msg); | 109 uint64_t result = |
| 110 checked_read_leb<uint64_t, true>(base, offset, length, msg); |
109 if (*length == 10) return bit_cast<int64_t>(result); | 111 if (*length == 10) return bit_cast<int64_t>(result); |
110 if (*length > 0) { | 112 if (*length > 0) { |
111 int shift = 64 - 7 * *length; | 113 int shift = 64 - 7 * *length; |
112 // Perform sign extension. | 114 // Perform sign extension. |
113 return bit_cast<int64_t>(result << shift) >> shift; | 115 return bit_cast<int64_t>(result << shift) >> shift; |
114 } | 116 } |
115 return 0; | 117 return 0; |
116 } | 118 } |
117 | 119 |
118 // Reads a single 16-bit unsigned integer (little endian). | 120 // Reads a single 16-bit unsigned integer (little endian). |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
332 protected: | 334 protected: |
333 const byte* start_; | 335 const byte* start_; |
334 const byte* pc_; | 336 const byte* pc_; |
335 const byte* limit_; | 337 const byte* limit_; |
336 const byte* end_; | 338 const byte* end_; |
337 const byte* error_pc_; | 339 const byte* error_pc_; |
338 const byte* error_pt_; | 340 const byte* error_pt_; |
339 base::SmartArrayPointer<char> error_msg_; | 341 base::SmartArrayPointer<char> error_msg_; |
340 | 342 |
341 private: | 343 private: |
342 template <typename IntType> | 344 template <typename IntType, bool is_signed> |
343 IntType checked_read_leb(const byte* base, int offset, int* length, | 345 IntType checked_read_leb(const byte* base, int offset, int* length, |
344 const char* msg) { | 346 const char* msg) { |
345 if (!check(base, offset, 1, msg)) { | 347 if (!check(base, offset, 1, msg)) { |
346 *length = 0; | 348 *length = 0; |
347 return 0; | 349 return 0; |
348 } | 350 } |
349 | 351 |
350 const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7; | 352 const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7; |
351 const byte* ptr = base + offset; | 353 const byte* ptr = base + offset; |
352 const byte* end = ptr + kMaxLength; | 354 const byte* end = ptr + kMaxLength; |
353 if (end > limit_) end = limit_; | 355 if (end > limit_) end = limit_; |
354 int shift = 0; | 356 int shift = 0; |
355 byte b = 0; | 357 byte b = 0; |
356 IntType result = 0; | 358 IntType result = 0; |
357 while (ptr < end) { | 359 while (ptr < end) { |
358 b = *ptr++; | 360 b = *ptr++; |
359 result = result | (static_cast<IntType>(b & 0x7F) << shift); | 361 result = result | (static_cast<IntType>(b & 0x7F) << shift); |
360 if ((b & 0x80) == 0) break; | 362 if ((b & 0x80) == 0) break; |
361 shift += 7; | 363 shift += 7; |
362 } | 364 } |
363 DCHECK_LE(ptr - (base + offset), kMaxLength); | 365 DCHECK_LE(ptr - (base + offset), kMaxLength); |
364 *length = static_cast<int>(ptr - (base + offset)); | 366 *length = static_cast<int>(ptr - (base + offset)); |
365 if (ptr == end) { | 367 if (ptr == end) { |
366 // Check there are no bits set beyond the bitwidth of {IntType}. | 368 // Check there are no bits set beyond the bitwidth of {IntType}. |
367 const int kExtraBits = (1 + kMaxLength * 7) - (sizeof(IntType) * 8); | 369 const int kExtraBits = (1 + kMaxLength * 7) - (sizeof(IntType) * 8); |
368 const byte kExtraBitsMask = | 370 const byte kExtraBitsMask = |
369 static_cast<byte>((0xFF << (8 - kExtraBits)) & 0xFF); | 371 static_cast<byte>((0xFF << (8 - kExtraBits)) & 0xFF); |
370 if (*length == kMaxLength && (b & kExtraBitsMask) != 0) { | 372 int extra_bits_value; |
| 373 if (is_signed) { |
| 374 // A signed-LEB128 must sign-extend the final byte, excluding its |
| 375 // most-signifcant bit. e.g. for a 32-bit LEB128: |
| 376 // kExtraBits = 4 |
| 377 // kExtraBitsMask = 0xf0 |
| 378 // If b is 0x0f, the value is negative, so extra_bits_value is 0x70. |
| 379 // If b is 0x03, the value is positive, so extra_bits_value is 0x00. |
| 380 extra_bits_value = (static_cast<int8_t>(b << kExtraBits) >> 8) & |
| 381 kExtraBitsMask & ~0x80; |
| 382 } else { |
| 383 extra_bits_value = 0; |
| 384 } |
| 385 if (*length == kMaxLength && (b & kExtraBitsMask) != extra_bits_value) { |
371 error(base, ptr, "extra bits in varint"); | 386 error(base, ptr, "extra bits in varint"); |
372 return 0; | 387 return 0; |
373 } | 388 } |
374 if ((b & 0x80) != 0) { | 389 if ((b & 0x80) != 0) { |
375 error(base, ptr, msg); | 390 error(base, ptr, msg); |
376 return 0; | 391 return 0; |
377 } | 392 } |
378 } | 393 } |
379 return result; | 394 return result; |
380 } | 395 } |
381 }; | 396 }; |
382 | 397 |
383 #undef TRACE | 398 #undef TRACE |
384 } // namespace wasm | 399 } // namespace wasm |
385 } // namespace internal | 400 } // namespace internal |
386 } // namespace v8 | 401 } // namespace v8 |
387 | 402 |
388 #endif // V8_WASM_DECODER_H_ | 403 #endif // V8_WASM_DECODER_H_ |
OLD | NEW |