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