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

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

Issue 1746063003: [wasm] Add support for 64-bit LEB encodings. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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
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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 const char* msg = "expected 4 bytes") { 70 const char* msg = "expected 4 bytes") {
71 return check(base, offset, 4, msg) ? read_u32(base + offset) : 0; 71 return check(base, offset, 4, msg) ? read_u32(base + offset) : 0;
72 } 72 }
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 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,
81 const char* msg = "expected LEB128") { 82 const char* msg = "expected LEB32") {
82 if (!check(base, offset, 1, msg)) { 83 return checked_read_leb<uint32_t>(base, offset, length, msg);
83 *length = 0;
84 return 0;
85 }
86
87 const ptrdiff_t kMaxDiff = 5; // maximum 5 bytes.
88 const byte* ptr = base + offset;
89 const byte* end = ptr + kMaxDiff;
90 if (end > limit_) end = limit_;
91 int shift = 0;
92 byte b = 0;
93 uint32_t result = 0;
94 while (ptr < end) {
95 b = *ptr++;
96 result = result | ((b & 0x7F) << shift);
97 if ((b & 0x80) == 0) break;
98 shift += 7;
99 }
100 DCHECK_LE(ptr - (base + offset), kMaxDiff);
101 *length = static_cast<int>(ptr - (base + offset));
102 if (ptr == end) {
103 if (*length == kMaxDiff && (b & 0xF0) != 0) {
104 error(base, ptr, "extra bits in LEB128");
105 return 0;
106 }
107 if ((b & 0x80) != 0) {
108 error(base, ptr, msg);
109 return 0;
110 }
111 }
112 return result;
113 } 84 }
114 85
115 // Reads a variable-length signed integer (little endian). 86 // Reads a variable-length signed integer (little endian).
116 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,
117 const char* msg = "expected SLEB128") { 88 const char* msg = "expected SLEB32") {
118 uint32_t result = checked_read_u32v(base, offset, length, msg); 89 uint32_t result = checked_read_u32v(base, offset, length, msg);
119 if (*length == 5) return bit_cast<int32_t>(result); 90 if (*length == 5) return bit_cast<int32_t>(result);
120 if (*length > 0) { 91 if (*length > 0) {
121 int shift = 32 - 7 * *length; 92 int shift = 32 - 7 * *length;
122 return bit_cast<int32_t>(result << shift) >> shift; 93 return bit_cast<int32_t>(result << shift) >> shift;
123 } 94 }
124 return 0; 95 return 0;
125 } 96 }
126 97
98 // Reads a variable-length unsigned integer (little endian).
99 uint64_t checked_read_u64v(const byte* base, int offset, int* length,
100 const char* msg = "expected LEB64") {
101 return checked_read_leb<uint64_t>(base, offset, length, msg);
102 }
103
104 // Reads a variable-length signed integer (little endian).
105 int64_t checked_read_i64v(const byte* base, int offset, int* length,
106 const char* msg = "expected SLEB64") {
107 uint64_t result = checked_read_u64v(base, offset, length, msg);
108 if (*length == 10) return bit_cast<int64_t>(result);
109 if (*length > 0) {
110 int shift = 64 - 7 * *length;
111 return bit_cast<int64_t>(result << shift) >> shift;
ahaas 2016/03/01 08:22:58 Could you add a comment to explain this line? Some
titzer 2016/03/01 18:49:12 Done.
112 }
113 return 0;
114 }
115
127 // Reads a single 16-bit unsigned integer (little endian). 116 // Reads a single 16-bit unsigned integer (little endian).
128 inline uint16_t read_u16(const byte* ptr) { 117 inline uint16_t read_u16(const byte* ptr) {
129 DCHECK(ptr >= start_ && (ptr + 2) <= end_); 118 DCHECK(ptr >= start_ && (ptr + 2) <= end_);
130 #if V8_TARGET_LITTLE_ENDIAN && UNALIGNED_ACCESS_OK 119 #if V8_TARGET_LITTLE_ENDIAN && UNALIGNED_ACCESS_OK
131 return *reinterpret_cast<const uint16_t*>(ptr); 120 return *reinterpret_cast<const uint16_t*>(ptr);
132 #else 121 #else
133 uint16_t b0 = ptr[0]; 122 uint16_t b0 = ptr[0];
134 uint16_t b1 = ptr[1]; 123 uint16_t b1 = ptr[1];
135 return (b1 << 8) | b0; 124 return (b1 << 8) | b0;
136 #endif 125 #endif
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
326 const byte* pc() { return pc_; } 315 const byte* pc() { return pc_; }
327 316
328 protected: 317 protected:
329 const byte* start_; 318 const byte* start_;
330 const byte* pc_; 319 const byte* pc_;
331 const byte* limit_; 320 const byte* limit_;
332 const byte* end_; 321 const byte* end_;
333 const byte* error_pc_; 322 const byte* error_pc_;
334 const byte* error_pt_; 323 const byte* error_pt_;
335 base::SmartArrayPointer<char> error_msg_; 324 base::SmartArrayPointer<char> error_msg_;
325
326 private:
327 template <typename IntType>
328 IntType checked_read_leb(const byte* base, int offset, int* length,
329 const char* msg) {
330 if (!check(base, offset, 1, msg)) {
331 *length = 0;
332 return 0;
333 }
334
335 const int kMaxDiff = (sizeof(IntType) * 8 + 6) / 7;
ahaas 2016/03/01 08:22:58 Should this be "kMaxLength"? It is the maximum val
titzer 2016/03/01 18:49:12 Done.
336 const byte* ptr = base + offset;
337 const byte* end = ptr + kMaxDiff;
binji 2016/03/01 18:49:40 I don't think this is right if we allow non-minima
titzer 2016/03/01 19:09:19 I don't think we should support arbitrary-length L
338 if (end > limit_) end = limit_;
339 int shift = 0;
340 byte b = 0;
341 IntType result = 0;
342 while (ptr < end) {
343 b = *ptr++;
344 result = result | (static_cast<IntType>(b & 0x7F) << shift);
345 if ((b & 0x80) == 0) break;
346 shift += 7;
347 }
348 DCHECK_LE(ptr - (base + offset), kMaxDiff);
349 *length = static_cast<int>(ptr - (base + offset));
350 if (ptr == end) {
351 const int kExtraBits = (1 + kMaxDiff * 7) - (sizeof(IntType) * 8);
ahaas 2016/03/01 08:22:58 Could you add a comment here, to hint what this ex
titzer 2016/03/01 18:49:12 Done.
binji 2016/03/01 18:49:40 Yeah, it took me walking through it to understand
352 const byte kExtraBitsMask = static_cast<byte>(0xFF << (8 - kExtraBits));
353 if (*length == kMaxDiff && (b & kExtraBitsMask) != 0) {
354 error(base, ptr, "extra bits in varint");
355 return 0;
356 }
357 if ((b & 0x80) != 0) {
358 error(base, ptr, msg);
359 return 0;
360 }
361 }
362 return result;
363 }
336 }; 364 };
337 365
338 #undef TRACE 366 #undef TRACE
339 } // namespace wasm 367 } // namespace wasm
340 } // namespace internal 368 } // namespace internal
341 } // namespace v8 369 } // namespace v8
342 370
343 #endif // V8_WASM_DECODER_H_ 371 #endif // V8_WASM_DECODER_H_
OLDNEW
« no previous file with comments | « no previous file | test/unittests/wasm/decoder-unittest.cc » ('j') | test/unittests/wasm/decoder-unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698