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

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

Issue 2613193002: [wasm] Decoder had 2 representations for "end". (Closed)
Patch Set: Created 3 years, 11 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 | « no previous file | src/wasm/function-body-decoder.cc » ('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 <memory> 8 #include <memory>
9 9
10 #include "src/base/compiler-specific.h" 10 #include "src/base/compiler-specific.h"
(...skipping 16 matching lines...) Expand all
27 #define TRACE(...) 27 #define TRACE(...)
28 #endif 28 #endif
29 29
30 // A helper utility to decode bytes, integers, fields, varints, etc, from 30 // A helper utility to decode bytes, integers, fields, varints, etc, from
31 // a buffer of bytes. 31 // a buffer of bytes.
32 class Decoder { 32 class Decoder {
33 public: 33 public:
34 Decoder(const byte* start, const byte* end) 34 Decoder(const byte* start, const byte* end)
35 : start_(start), 35 : start_(start),
36 pc_(start), 36 pc_(start),
37 limit_(end),
38 end_(end), 37 end_(end),
39 error_pc_(nullptr), 38 error_pc_(nullptr),
40 error_pt_(nullptr) {} 39 error_pt_(nullptr) {}
41 40
42 virtual ~Decoder() {} 41 virtual ~Decoder() {}
43 42
44 inline bool check(const byte* base, unsigned offset, unsigned length, 43 inline bool check(const byte* base, unsigned offset, unsigned length,
45 const char* msg) { 44 const char* msg) {
46 DCHECK_GE(base, start_); 45 DCHECK_GE(base, start_);
47 if ((base + offset + length) > limit_) { 46 if ((base + offset + length) > end_) {
48 error(base, base + offset, "%s", msg); 47 error(base, base + offset, "%s", msg);
49 return false; 48 return false;
50 } 49 }
51 return true; 50 return true;
52 } 51 }
53 52
54 // Reads a single 8-bit byte, reporting an error if out of bounds. 53 // Reads a single 8-bit byte, reporting an error if out of bounds.
55 inline uint8_t checked_read_u8(const byte* base, unsigned offset, 54 inline uint8_t checked_read_u8(const byte* base, unsigned offset,
56 const char* msg = "expected 1 byte") { 55 const char* msg = "expected 1 byte") {
57 return check(base, offset, 1, msg) ? base[offset] : 0; 56 return check(base, offset, 1, msg) ? base[offset] : 0;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 return consume_leb<int32_t, true>(name); 182 return consume_leb<int32_t, true>(name);
184 } 183 }
185 184
186 // Consume {size} bytes and send them to the bit bucket, advancing {pc_}. 185 // Consume {size} bytes and send them to the bit bucket, advancing {pc_}.
187 void consume_bytes(uint32_t size, const char* name = "skip") { 186 void consume_bytes(uint32_t size, const char* name = "skip") {
188 TRACE(" +%d %-20s: %d bytes\n", static_cast<int>(pc_ - start_), name, 187 TRACE(" +%d %-20s: %d bytes\n", static_cast<int>(pc_ - start_), name,
189 size); 188 size);
190 if (checkAvailable(size)) { 189 if (checkAvailable(size)) {
191 pc_ += size; 190 pc_ += size;
192 } else { 191 } else {
193 pc_ = limit_; 192 pc_ = end_;
194 } 193 }
195 } 194 }
196 195
197 // Check that at least {size} bytes exist between {pc_} and {limit_}. 196 // Check that at least {size} bytes exist between {pc_} and {end_}.
198 bool checkAvailable(int size) { 197 bool checkAvailable(int size) {
199 intptr_t pc_overflow_value = std::numeric_limits<intptr_t>::max() - size; 198 intptr_t pc_overflow_value = std::numeric_limits<intptr_t>::max() - size;
200 if (size < 0 || (intptr_t)pc_ > pc_overflow_value) { 199 if (size < 0 || (intptr_t)pc_ > pc_overflow_value) {
201 error(pc_, nullptr, "reading %d bytes would underflow/overflow", size); 200 error(pc_, nullptr, "reading %d bytes would underflow/overflow", size);
202 return false; 201 return false;
203 } else if (pc_ < start_ || limit_ < (pc_ + size)) { 202 } else if (pc_ < start_ || end_ < (pc_ + size)) {
204 error(pc_, nullptr, "expected %d bytes, fell off end", size); 203 error(pc_, nullptr, "expected %d bytes, fell off end", size);
205 return false; 204 return false;
206 } else { 205 } else {
207 return true; 206 return true;
208 } 207 }
209 } 208 }
210 209
211 void error(const char* msg) { error(pc_, nullptr, "%s", msg); } 210 void error(const char* msg) { error(pc_, nullptr, "%s", msg); }
212 211
213 void error(const byte* pc, const char* msg) { error(pc, nullptr, "%s", msg); } 212 void error(const byte* pc, const char* msg) { error(pc, nullptr, "%s", msg); }
(...skipping 20 matching lines...) Expand all
234 } 233 }
235 } 234 }
236 235
237 // Behavior triggered on first error, overridden in subclasses. 236 // Behavior triggered on first error, overridden in subclasses.
238 virtual void onFirstError() {} 237 virtual void onFirstError() {}
239 238
240 // Debugging helper to print bytes up to the end. 239 // Debugging helper to print bytes up to the end.
241 template <typename T> 240 template <typename T>
242 T traceOffEnd() { 241 T traceOffEnd() {
243 T t = 0; 242 T t = 0;
244 for (const byte* ptr = pc_; ptr < limit_; ptr++) { 243 for (const byte* ptr = pc_; ptr < end_; ptr++) {
245 TRACE("%02x ", *ptr); 244 TRACE("%02x ", *ptr);
246 } 245 }
247 TRACE("<end>\n"); 246 TRACE("<end>\n");
248 pc_ = limit_; 247 pc_ = end_;
249 return t; 248 return t;
250 } 249 }
251 250
252 // Converts the given value to a {Result}, copying the error if necessary. 251 // Converts the given value to a {Result}, copying the error if necessary.
253 template <typename T> 252 template <typename T>
254 Result<T> toResult(T val) { 253 Result<T> toResult(T val) {
255 Result<T> result; 254 Result<T> result;
256 if (failed()) { 255 if (failed()) {
257 TRACE("Result error: %s\n", error_msg_.get()); 256 TRACE("Result error: %s\n", error_msg_.get());
258 result.error_code = kError; 257 result.error_code = kError;
259 result.start = start_; 258 result.start = start_;
260 result.error_pc = error_pc_; 259 result.error_pc = error_pc_;
261 result.error_pt = error_pt_; 260 result.error_pt = error_pt_;
262 // transfer ownership of the error to the result. 261 // transfer ownership of the error to the result.
263 result.error_msg.reset(error_msg_.release()); 262 result.error_msg.reset(error_msg_.release());
264 } else { 263 } else {
265 result.error_code = kSuccess; 264 result.error_code = kSuccess;
266 } 265 }
267 result.val = std::move(val); 266 result.val = std::move(val);
268 return result; 267 return result;
269 } 268 }
270 269
271 // Resets the boundaries of this decoder. 270 // Resets the boundaries of this decoder.
272 void Reset(const byte* start, const byte* end) { 271 void Reset(const byte* start, const byte* end) {
273 start_ = start; 272 start_ = start;
274 pc_ = start; 273 pc_ = start;
275 limit_ = end;
276 end_ = end; 274 end_ = end;
277 error_pc_ = nullptr; 275 error_pc_ = nullptr;
278 error_pt_ = nullptr; 276 error_pt_ = nullptr;
279 error_msg_.reset(); 277 error_msg_.reset();
280 } 278 }
281 279
282 bool ok() const { return error_msg_ == nullptr; } 280 bool ok() const { return error_msg_ == nullptr; }
283 bool failed() const { return !ok(); } 281 bool failed() const { return !ok(); }
284 bool more() const { return pc_ < limit_; } 282 bool more() const { return pc_ < end_; }
285 283
286 const byte* start() { return start_; } 284 const byte* start() { return start_; }
287 const byte* pc() { return pc_; } 285 const byte* pc() { return pc_; }
288 uint32_t pc_offset() { return static_cast<uint32_t>(pc_ - start_); } 286 uint32_t pc_offset() { return static_cast<uint32_t>(pc_ - start_); }
289 287
290 protected: 288 protected:
291 const byte* start_; 289 const byte* start_;
292 const byte* pc_; 290 const byte* pc_;
293 const byte* limit_;
294 const byte* end_; 291 const byte* end_;
295 const byte* error_pc_; 292 const byte* error_pc_;
296 const byte* error_pt_; 293 const byte* error_pt_;
297 std::unique_ptr<char[]> error_msg_; 294 std::unique_ptr<char[]> error_msg_;
298 295
299 private: 296 private:
300 template <typename IntType, bool is_signed> 297 template <typename IntType, bool is_signed>
301 IntType checked_read_leb(const byte* base, unsigned offset, unsigned* length, 298 IntType checked_read_leb(const byte* base, unsigned offset, unsigned* length,
302 const char* msg) { 299 const char* msg) {
303 if (!check(base, offset, 1, msg)) { 300 if (!check(base, offset, 1, msg)) {
304 *length = 0; 301 *length = 0;
305 return 0; 302 return 0;
306 } 303 }
307 304
308 const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7; 305 const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7;
309 const byte* ptr = base + offset; 306 const byte* ptr = base + offset;
310 const byte* end = ptr + kMaxLength; 307 const byte* end = ptr + kMaxLength;
311 if (end > limit_) end = limit_; 308 if (end > end_) end = end_;
312 int shift = 0; 309 int shift = 0;
313 byte b = 0; 310 byte b = 0;
314 IntType result = 0; 311 IntType result = 0;
315 while (ptr < end) { 312 while (ptr < end) {
316 b = *ptr++; 313 b = *ptr++;
317 result = result | (static_cast<IntType>(b & 0x7F) << shift); 314 result = result | (static_cast<IntType>(b & 0x7F) << shift);
318 if ((b & 0x80) == 0) break; 315 if ((b & 0x80) == 0) break;
319 shift += 7; 316 shift += 7;
320 } 317 }
321 DCHECK_LE(ptr - (base + offset), kMaxLength); 318 DCHECK_LE(ptr - (base + offset), kMaxLength);
(...skipping 29 matching lines...) Expand all
351 } 348 }
352 349
353 template <typename IntType, bool is_signed> 350 template <typename IntType, bool is_signed>
354 IntType consume_leb(const char* name = nullptr) { 351 IntType consume_leb(const char* name = nullptr) {
355 TRACE(" +%d %-20s: ", static_cast<int>(pc_ - start_), 352 TRACE(" +%d %-20s: ", static_cast<int>(pc_ - start_),
356 name ? name : "varint"); 353 name ? name : "varint");
357 if (checkAvailable(1)) { 354 if (checkAvailable(1)) {
358 const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7; 355 const int kMaxLength = (sizeof(IntType) * 8 + 6) / 7;
359 const byte* pos = pc_; 356 const byte* pos = pc_;
360 const byte* end = pc_ + kMaxLength; 357 const byte* end = pc_ + kMaxLength;
361 if (end > limit_) end = limit_; 358 if (end > end_) end = end_;
362 359
363 IntType result = 0; 360 IntType result = 0;
364 int shift = 0; 361 int shift = 0;
365 byte b = 0; 362 byte b = 0;
366 while (pc_ < end) { 363 while (pc_ < end) {
367 b = *pc_++; 364 b = *pc_++;
368 TRACE("%02x ", b); 365 TRACE("%02x ", b);
369 result = result | (static_cast<IntType>(b & 0x7F) << shift); 366 result = result | (static_cast<IntType>(b & 0x7F) << shift);
370 shift += 7; 367 shift += 7;
371 if ((b & 0x80) == 0) break; 368 if ((b & 0x80) == 0) break;
(...skipping 19 matching lines...) Expand all
391 return traceOffEnd<uint32_t>(); 388 return traceOffEnd<uint32_t>();
392 } 389 }
393 }; 390 };
394 391
395 #undef TRACE 392 #undef TRACE
396 } // namespace wasm 393 } // namespace wasm
397 } // namespace internal 394 } // namespace internal
398 } // namespace v8 395 } // namespace v8
399 396
400 #endif // V8_WASM_DECODER_H_ 397 #endif // V8_WASM_DECODER_H_
OLDNEW
« no previous file with comments | « no previous file | src/wasm/function-body-decoder.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698