Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/wasm/decoder.h

Issue 1765673002: [wasm] Update {i32,i64}.const to use signed leb128 (Closed) Base URL: http://chromium.googlesource.com/v8/v8.git@master
Patch Set: nits, WASM_I64V fixes Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/wasm/ast-decoder.h ('k') | src/wasm/wasm-macro-gen.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 = static_cast<byte>(0xFF << (8 - kExtraBits));
369 static_cast<byte>((0xFF << (8 - kExtraBits)) & 0xFF); 371 int extra_bits_value;
370 if (*length == kMaxLength && (b & kExtraBitsMask) != 0) { 372 if (is_signed) {
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) {
371 error(base, ptr, "extra bits in varint"); 385 error(base, ptr, "extra bits in varint");
372 return 0; 386 return 0;
373 } 387 }
374 if ((b & 0x80) != 0) { 388 if ((b & 0x80) != 0) {
375 error(base, ptr, msg); 389 error(base, ptr, msg);
376 return 0; 390 return 0;
377 } 391 }
378 } 392 }
379 return result; 393 return result;
380 } 394 }
381 }; 395 };
382 396
383 #undef TRACE 397 #undef TRACE
384 } // namespace wasm 398 } // namespace wasm
385 } // namespace internal 399 } // namespace internal
386 } // namespace v8 400 } // namespace v8
387 401
388 #endif // V8_WASM_DECODER_H_ 402 #endif // V8_WASM_DECODER_H_
OLDNEW
« no previous file with comments | « src/wasm/ast-decoder.h ('k') | src/wasm/wasm-macro-gen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698