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 26 matching lines...) Expand all Loading... |
37 Decoder(const byte* start, const byte* end) | 37 Decoder(const byte* start, const byte* end) |
38 : start_(start), | 38 : start_(start), |
39 pc_(start), | 39 pc_(start), |
40 limit_(end), | 40 limit_(end), |
41 end_(end), | 41 end_(end), |
42 error_pc_(nullptr), | 42 error_pc_(nullptr), |
43 error_pt_(nullptr) {} | 43 error_pt_(nullptr) {} |
44 | 44 |
45 virtual ~Decoder() {} | 45 virtual ~Decoder() {} |
46 | 46 |
| 47 inline bool check(const byte* base, int offset, int length, const char* msg) { |
| 48 DCHECK_GE(base, start_); |
| 49 if ((base + offset + length) > limit_) { |
| 50 error(base, base + offset, msg); |
| 51 return false; |
| 52 } |
| 53 return true; |
| 54 } |
| 55 |
| 56 // Reads a single 8-bit byte, reporting an error if out of bounds. |
| 57 inline uint8_t checked_read_u8(const byte* base, int offset, |
| 58 const char* msg = "expected 1 byte") { |
| 59 return check(base, offset, 1, msg) ? base[offset] : 0; |
| 60 } |
| 61 |
| 62 // Reads 16-bit word, reporting an error if out of bounds. |
| 63 inline uint16_t checked_read_u16(const byte* base, int offset, |
| 64 const char* msg = "expected 2 bytes") { |
| 65 return check(base, offset, 2, msg) ? read_u16(base + offset) : 0; |
| 66 } |
| 67 |
| 68 // Reads 32-bit word, reporting an error if out of bounds. |
| 69 inline uint32_t checked_read_u32(const byte* base, int offset, |
| 70 const char* msg = "expected 4 bytes") { |
| 71 return check(base, offset, 4, msg) ? read_u32(base + offset) : 0; |
| 72 } |
| 73 |
| 74 // Reads 64-bit word, reporting an error if out of bounds. |
| 75 inline uint64_t checked_read_u64(const byte* base, int offset, |
| 76 const char* msg = "expected 8 bytes") { |
| 77 return check(base, offset, 8, msg) ? read_u64(base + offset) : 0; |
| 78 } |
| 79 |
| 80 uint32_t checked_read_u32v(const byte* base, int offset, int* length, |
| 81 const char* msg = "expected LEB128") { |
| 82 if (!check(base, offset, 1, 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 && (b & 0x80)) { |
| 103 error(base, ptr, msg); |
| 104 return 0; |
| 105 } |
| 106 return result; |
| 107 } |
| 108 |
47 // Reads a single 16-bit unsigned integer (little endian). | 109 // Reads a single 16-bit unsigned integer (little endian). |
48 inline uint16_t read_u16(const byte* ptr) { | 110 inline uint16_t read_u16(const byte* ptr) { |
49 DCHECK(ptr >= start_ && (ptr + 2) <= end_); | 111 DCHECK(ptr >= start_ && (ptr + 2) <= end_); |
50 #if V8_TARGET_LITTLE_ENDIAN && UNALIGNED_ACCESS_OK | 112 #if V8_TARGET_LITTLE_ENDIAN && UNALIGNED_ACCESS_OK |
51 return *reinterpret_cast<const uint16_t*>(ptr); | 113 return *reinterpret_cast<const uint16_t*>(ptr); |
52 #else | 114 #else |
53 uint16_t b0 = ptr[0]; | 115 uint16_t b0 = ptr[0]; |
54 uint16_t b1 = ptr[1]; | 116 uint16_t b1 = ptr[1]; |
55 return (b1 << 8) | b0; | 117 return (b1 << 8) | b0; |
56 #endif | 118 #endif |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 // Check that at least {size} bytes exist between {pc_} and {limit_}. | 225 // Check that at least {size} bytes exist between {pc_} and {limit_}. |
164 bool checkAvailable(int size) { | 226 bool checkAvailable(int size) { |
165 if (pc_ < start_ || (pc_ + size) > limit_) { | 227 if (pc_ < start_ || (pc_ + size) > limit_) { |
166 error(pc_, nullptr, "expected %d bytes, fell off end", size); | 228 error(pc_, nullptr, "expected %d bytes, fell off end", size); |
167 return false; | 229 return false; |
168 } else { | 230 } else { |
169 return true; | 231 return true; |
170 } | 232 } |
171 } | 233 } |
172 | 234 |
| 235 bool RangeOk(const byte* pc, int length) { |
| 236 if (pc < start_ || pc_ >= limit_) return false; |
| 237 if ((pc + length) >= limit_) return false; |
| 238 return true; |
| 239 } |
| 240 |
173 void error(const char* msg) { error(pc_, nullptr, msg); } | 241 void error(const char* msg) { error(pc_, nullptr, msg); } |
174 | 242 |
175 void error(const byte* pc, const char* msg) { error(pc, nullptr, msg); } | 243 void error(const byte* pc, const char* msg) { error(pc, nullptr, msg); } |
176 | 244 |
177 // Sets internal error state. | 245 // Sets internal error state. |
178 void error(const byte* pc, const byte* pt, const char* format, ...) { | 246 void error(const byte* pc, const byte* pt, const char* format, ...) { |
179 if (ok()) { | 247 if (ok()) { |
180 #if DEBUG | 248 #if DEBUG |
181 if (FLAG_wasm_break_on_decoder_error) { | 249 if (FLAG_wasm_break_on_decoder_error) { |
182 base::OS::DebugBreak(); | 250 base::OS::DebugBreak(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 const byte* error_pt_; | 319 const byte* error_pt_; |
252 base::SmartArrayPointer<char> error_msg_; | 320 base::SmartArrayPointer<char> error_msg_; |
253 }; | 321 }; |
254 | 322 |
255 #undef TRACE | 323 #undef TRACE |
256 } // namespace wasm | 324 } // namespace wasm |
257 } // namespace internal | 325 } // namespace internal |
258 } // namespace v8 | 326 } // namespace v8 |
259 | 327 |
260 #endif // V8_WASM_DECODER_H_ | 328 #endif // V8_WASM_DECODER_H_ |
OLD | NEW |