1// Copyright 2012 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_SNAPSHOT_SOURCE_SINK_H_
6#define V8_SNAPSHOT_SOURCE_SINK_H_
7
8#include "src/base/logging.h"
9#include "src/utils.h"
10
11namespace v8 {
12namespace internal {
13
14
15/**
16 * Source to read snapshot and builtins files from.
17 *
18 * Note: Memory ownership remains with callee.
19 */
20class SnapshotByteSource FINAL {
21 public:
22  SnapshotByteSource(const byte* array, int length);
23  ~SnapshotByteSource();
24
25  bool HasMore() { return position_ < length_; }
26
27  int Get() {
28    DCHECK(position_ < length_);
29    return data_[position_++];
30  }
31
32  int32_t GetUnalignedInt();
33
34  void Advance(int by) { position_ += by; }
35
36  void CopyRaw(byte* to, int number_of_bytes);
37
38  inline int GetInt() {
39    // This way of variable-length encoding integers does not suffer from branch
40    // mispredictions.
41    uint32_t answer = GetUnalignedInt();
42    int bytes = answer & 3;
43    Advance(bytes);
44    uint32_t mask = 0xffffffffu;
45    mask >>= 32 - (bytes << 3);
46    answer &= mask;
47    answer >>= 2;
48    return answer;
49  }
50
51  bool GetBlob(const byte** data, int* number_of_bytes);
52
53  bool AtEOF();
54
55  int position() { return position_; }
56
57 private:
58  const byte* data_;
59  int length_;
60  int position_;
61
62  DISALLOW_COPY_AND_ASSIGN(SnapshotByteSource);
63};
64
65
66/**
67 * Sink to write snapshot files to.
68 *
69 * Subclasses must implement actual storage or i/o.
70 */
71class SnapshotByteSink {
72 public:
73  virtual ~SnapshotByteSink() { }
74  virtual void Put(byte b, const char* description) = 0;
75  virtual void PutSection(int b, const char* description) {
76    DCHECK_LE(b, kMaxUInt8);
77    Put(static_cast<byte>(b), description);
78  }
79  void PutInt(uintptr_t integer, const char* description);
80  void PutRaw(byte* data, int number_of_bytes, const char* description);
81  void PutBlob(byte* data, int number_of_bytes, const char* description);
82  virtual int Position() = 0;
83};
84
85
86class DummySnapshotSink : public SnapshotByteSink {
87 public:
88  DummySnapshotSink() : length_(0) {}
89  virtual ~DummySnapshotSink() {}
90  virtual void Put(byte b, const char* description) { length_++; }
91  virtual int Position() { return length_; }
92
93 private:
94  int length_;
95};
96
97
98// Wrap a SnapshotByteSink into a DebugSnapshotSink to get debugging output.
99class DebugSnapshotSink : public SnapshotByteSink {
100 public:
101  explicit DebugSnapshotSink(SnapshotByteSink* chained) : sink_(chained) {}
102  virtual void Put(byte b, const char* description) OVERRIDE;
103  virtual int Position() OVERRIDE { return sink_->Position(); }
104
105 private:
106  SnapshotByteSink* sink_;
107};
108
109
110class ListSnapshotSink : public i::SnapshotByteSink {
111 public:
112  explicit ListSnapshotSink(i::List<byte>* data) : data_(data) {}
113  virtual void Put(byte b, const char* description) OVERRIDE {
114    data_->Add(b);
115  }
116  virtual int Position() OVERRIDE { return data_->length(); }
117
118 private:
119  i::List<byte>* data_;
120};
121
122}  // namespace v8::internal
123}  // namespace v8
124
125#endif  // V8_SNAPSHOT_SOURCE_SINK_H_
126