OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef RUNTIME_VM_KERNEL_BINARY_H_ | 5 #ifndef RUNTIME_VM_KERNEL_BINARY_H_ |
6 #define RUNTIME_VM_KERNEL_BINARY_H_ | 6 #define RUNTIME_VM_KERNEL_BINARY_H_ |
7 | 7 |
8 #if !defined(DART_PRECOMPILED_RUNTIME) | 8 #if !defined(DART_PRECOMPILED_RUNTIME) |
9 | 9 |
10 #include <map> | 10 #include <map> |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 kSpecializedVariableGet = 128, | 130 kSpecializedVariableGet = 128, |
131 kSpecializedVariableSet = 136, | 131 kSpecializedVariableSet = 136, |
132 kSpecialIntLiteral = 144, | 132 kSpecialIntLiteral = 144, |
133 }; | 133 }; |
134 | 134 |
135 static const int SpecializedIntLiteralBias = 3; | 135 static const int SpecializedIntLiteralBias = 3; |
136 | 136 |
137 class Reader { | 137 class Reader { |
138 public: | 138 public: |
139 Reader(const uint8_t* buffer, intptr_t size) | 139 Reader(const uint8_t* buffer, intptr_t size) |
140 : buffer_(buffer), size_(size), offset_(0) {} | 140 : raw_buffer_(buffer), typed_data_(NULL), size_(size), offset_(0) {} |
| 141 |
| 142 explicit Reader(const TypedData& typed_data) |
| 143 : raw_buffer_(NULL), |
| 144 typed_data_(&typed_data), |
| 145 size_(typed_data.IsNull() ? 0 : typed_data.Length()), |
| 146 offset_(0) {} |
141 | 147 |
142 uint32_t ReadUInt32() { | 148 uint32_t ReadUInt32() { |
143 ASSERT(offset_ + 4 <= size_); | 149 ASSERT(offset_ + 4 <= size_); |
144 | 150 |
145 uint32_t value = (buffer_[offset_ + 0] << 24) | | 151 const uint8_t* buffer = this->buffer(); |
146 (buffer_[offset_ + 1] << 16) | | 152 uint32_t value = (buffer[offset_ + 0] << 24) | (buffer[offset_ + 1] << 16) | |
147 (buffer_[offset_ + 2] << 8) | (buffer_[offset_ + 3] << 0); | 153 (buffer[offset_ + 2] << 8) | (buffer[offset_ + 3] << 0); |
148 offset_ += 4; | 154 offset_ += 4; |
149 return value; | 155 return value; |
150 } | 156 } |
151 | 157 |
152 uint32_t ReadUInt() { | 158 uint32_t ReadUInt() { |
153 ASSERT(offset_ + 1 <= size_); | 159 ASSERT(offset_ + 1 <= size_); |
154 uint8_t byte0 = buffer_[offset_]; | 160 |
| 161 const uint8_t* buffer = this->buffer(); |
| 162 uint8_t byte0 = buffer[offset_]; |
155 if ((byte0 & 0x80) == 0) { | 163 if ((byte0 & 0x80) == 0) { |
156 // 0... | 164 // 0... |
157 offset_++; | 165 offset_++; |
158 return byte0; | 166 return byte0; |
159 } else if ((byte0 & 0xc0) == 0x80) { | 167 } else if ((byte0 & 0xc0) == 0x80) { |
160 // 10... | 168 // 10... |
161 ASSERT(offset_ + 2 <= size_); | 169 ASSERT(offset_ + 2 <= size_); |
162 uint32_t value = ((byte0 & ~0x80) << 8) | (buffer_[offset_ + 1]); | 170 uint32_t value = ((byte0 & ~0x80) << 8) | (buffer[offset_ + 1]); |
163 offset_ += 2; | 171 offset_ += 2; |
164 return value; | 172 return value; |
165 } else { | 173 } else { |
166 // 11... | 174 // 11... |
167 ASSERT(offset_ + 4 <= size_); | 175 ASSERT(offset_ + 4 <= size_); |
168 uint32_t value = ((byte0 & ~0xc0) << 24) | (buffer_[offset_ + 1] << 16) | | 176 uint32_t value = ((byte0 & ~0xc0) << 24) | (buffer[offset_ + 1] << 16) | |
169 (buffer_[offset_ + 2] << 8) | | 177 (buffer[offset_ + 2] << 8) | (buffer[offset_ + 3] << 0); |
170 (buffer_[offset_ + 3] << 0); | |
171 offset_ += 4; | 178 offset_ += 4; |
172 return value; | 179 return value; |
173 } | 180 } |
174 } | 181 } |
175 | 182 |
176 /** | 183 /** |
177 * Read and return a TokenPosition from this reader. | 184 * Read and return a TokenPosition from this reader. |
178 * @param record specifies whether or not the read position is saved as a | |
179 * valid token position in the current script. | |
180 * If not be sure to record it later by calling record_token_position (after | |
181 * setting the correct current_script_id). | |
182 */ | 185 */ |
183 TokenPosition ReadPosition() { | 186 TokenPosition ReadPosition() { |
184 // Position is saved as unsigned, | 187 // Position is saved as unsigned, |
185 // but actually ranges from -1 and up (thus the -1) | 188 // but actually ranges from -1 and up (thus the -1) |
186 intptr_t value = ReadUInt() - 1; | 189 intptr_t value = ReadUInt() - 1; |
187 TokenPosition result = TokenPosition(value); | 190 TokenPosition result = TokenPosition(value); |
188 max_position_ = Utils::Maximum(max_position_, result); | 191 max_position_ = Utils::Maximum(max_position_, result); |
189 if (min_position_.IsNoSource()) { | 192 if (min_position_.IsNoSource()) { |
190 min_position_ = result; | 193 min_position_ = result; |
191 } else if (result.IsReal()) { | 194 } else if (result.IsReal()) { |
192 min_position_ = Utils::Minimum(min_position_, result); | 195 min_position_ = Utils::Minimum(min_position_, result); |
193 } | 196 } |
194 | 197 |
195 return result; | 198 return result; |
196 } | 199 } |
197 | 200 |
198 intptr_t ReadListLength() { return ReadUInt(); } | 201 intptr_t ReadListLength() { return ReadUInt(); } |
199 | 202 |
200 uint8_t ReadByte() { return buffer_[offset_++]; } | 203 uint8_t ReadByte() { return buffer()[offset_++]; } |
201 | 204 |
202 uint8_t PeekByte() { return buffer_[offset_]; } | 205 uint8_t PeekByte() { return buffer()[offset_]; } |
203 | 206 |
204 bool ReadBool() { return (ReadByte() & 1) == 1; } | 207 bool ReadBool() { return (ReadByte() & 1) == 1; } |
205 | 208 |
206 word ReadFlags() { return ReadByte(); } | 209 word ReadFlags() { return ReadByte(); } |
207 | 210 |
208 Tag ReadTag(uint8_t* payload = NULL) { | 211 Tag ReadTag(uint8_t* payload = NULL) { |
209 uint8_t byte = ReadByte(); | 212 uint8_t byte = ReadByte(); |
210 bool has_payload = (byte & kSpecializedTagHighBit) != 0; | 213 bool has_payload = (byte & kSpecializedTagHighBit) != 0; |
211 if (has_payload) { | 214 if (has_payload) { |
212 if (payload != NULL) { | 215 if (payload != NULL) { |
(...skipping 11 matching lines...) Expand all Loading... |
224 if (has_payload) { | 227 if (has_payload) { |
225 if (payload != NULL) { | 228 if (payload != NULL) { |
226 *payload = byte & kSpecializedPayloadMask; | 229 *payload = byte & kSpecializedPayloadMask; |
227 } | 230 } |
228 return static_cast<Tag>(byte & kSpecializedTagMask); | 231 return static_cast<Tag>(byte & kSpecializedTagMask); |
229 } else { | 232 } else { |
230 return static_cast<Tag>(byte); | 233 return static_cast<Tag>(byte); |
231 } | 234 } |
232 } | 235 } |
233 | 236 |
234 const uint8_t* Consume(int count) { | |
235 ASSERT(offset_ + count <= size_); | |
236 const uint8_t* old = buffer_ + offset_; | |
237 offset_ += count; | |
238 return old; | |
239 } | |
240 | |
241 void EnsureEnd() { | 237 void EnsureEnd() { |
242 if (offset_ != size_) { | 238 if (offset_ != size_) { |
243 FATAL2( | 239 FATAL2( |
244 "Reading Kernel file: Expected to be at EOF " | 240 "Reading Kernel file: Expected to be at EOF " |
245 "(offset: %" Pd ", size: %" Pd ")", | 241 "(offset: %" Pd ", size: %" Pd ")", |
246 offset_, size_); | 242 offset_, size_); |
247 } | 243 } |
248 } | 244 } |
249 | 245 |
250 // The largest position read yet (since last reset). | 246 // The largest position read yet (since last reset). |
251 // This is automatically updated when calling ReadPosition, | 247 // This is automatically updated when calling ReadPosition, |
252 // but can be overwritten (e.g. via the PositionScope class). | 248 // but can be overwritten (e.g. via the PositionScope class). |
253 TokenPosition max_position() { return max_position_; } | 249 TokenPosition max_position() { return max_position_; } |
254 // The smallest position read yet (since last reset). | 250 // The smallest position read yet (since last reset). |
255 // This is automatically updated when calling ReadPosition, | 251 // This is automatically updated when calling ReadPosition, |
256 // but can be overwritten (e.g. via the PositionScope class). | 252 // but can be overwritten (e.g. via the PositionScope class). |
257 TokenPosition min_position() { return min_position_; } | 253 TokenPosition min_position() { return min_position_; } |
258 | 254 |
259 template <typename T, typename RT> | |
260 T* ReadOptional() { | |
261 Tag tag = ReadTag(); | |
262 if (tag == kNothing) { | |
263 return NULL; | |
264 } | |
265 ASSERT(tag == kSomething); | |
266 return RT::ReadFrom(this); | |
267 } | |
268 | |
269 template <typename T> | |
270 T* ReadOptional() { | |
271 return ReadOptional<T, T>(); | |
272 } | |
273 | |
274 // A canonical name reference of -1 indicates none (for optional names), not | 255 // A canonical name reference of -1 indicates none (for optional names), not |
275 // the root name as in the canonical name table. | 256 // the root name as in the canonical name table. |
276 NameIndex ReadCanonicalNameReference() { return NameIndex(ReadUInt() - 1); } | 257 NameIndex ReadCanonicalNameReference() { return NameIndex(ReadUInt() - 1); } |
277 | 258 |
278 intptr_t offset() { return offset_; } | 259 intptr_t offset() { return offset_; } |
279 void set_offset(intptr_t offset) { offset_ = offset; } | 260 void set_offset(intptr_t offset) { offset_ = offset; } |
| 261 |
280 intptr_t size() { return size_; } | 262 intptr_t size() { return size_; } |
| 263 void set_size(intptr_t size) { size_ = size; } |
281 | 264 |
282 const uint8_t* buffer() { return buffer_; } | 265 const TypedData* typed_data() { return typed_data_; } |
| 266 void set_typed_data(const TypedData* typed_data) { typed_data_ = typed_data; } |
| 267 |
| 268 const uint8_t* raw_buffer() { return raw_buffer_; } |
| 269 void set_raw_buffer(const uint8_t* raw_buffer) { raw_buffer_ = raw_buffer; } |
| 270 |
| 271 TypedData& CopyDataToVMHeap(Zone* zone, |
| 272 intptr_t from_byte, |
| 273 intptr_t to_byte) { |
| 274 intptr_t size = to_byte - from_byte; |
| 275 TypedData& data = TypedData::Handle( |
| 276 zone, TypedData::New(kTypedDataUint8ArrayCid, size, Heap::kOld)); |
| 277 { |
| 278 NoSafepointScope no_safepoint; |
| 279 memmove(data.DataAddr(0), buffer() + from_byte, size); |
| 280 } |
| 281 return data; |
| 282 } |
| 283 |
| 284 uint8_t* CopyDataIntoZone(Zone* zone, intptr_t offset, intptr_t length) { |
| 285 uint8_t* buffer_ = zone->Alloc<uint8_t>(length); |
| 286 { |
| 287 NoSafepointScope no_safepoint; |
| 288 memmove(buffer_, buffer() + offset, length); |
| 289 } |
| 290 return buffer_; |
| 291 } |
283 | 292 |
284 private: | 293 private: |
285 const uint8_t* buffer_; | 294 const uint8_t* buffer() { |
| 295 if (raw_buffer_ != NULL) { |
| 296 return raw_buffer_; |
| 297 } |
| 298 NoSafepointScope no_safepoint; |
| 299 return reinterpret_cast<uint8_t*>(typed_data_->DataAddr(0)); |
| 300 } |
| 301 |
| 302 const uint8_t* raw_buffer_; |
| 303 const TypedData* typed_data_; |
286 intptr_t size_; | 304 intptr_t size_; |
287 intptr_t offset_; | 305 intptr_t offset_; |
288 TokenPosition max_position_; | 306 TokenPosition max_position_; |
289 TokenPosition min_position_; | 307 TokenPosition min_position_; |
290 intptr_t current_script_id_; | 308 intptr_t current_script_id_; |
291 | 309 |
292 friend class PositionScope; | 310 friend class PositionScope; |
293 friend class Program; | 311 friend class Program; |
294 }; | 312 }; |
295 | 313 |
(...skipping 24 matching lines...) Expand all Loading... |
320 Reader* reader_; | 338 Reader* reader_; |
321 TokenPosition min_; | 339 TokenPosition min_; |
322 TokenPosition max_; | 340 TokenPosition max_; |
323 }; | 341 }; |
324 | 342 |
325 } // namespace kernel | 343 } // namespace kernel |
326 } // namespace dart | 344 } // namespace dart |
327 | 345 |
328 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 346 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
329 #endif // RUNTIME_VM_KERNEL_BINARY_H_ | 347 #endif // RUNTIME_VM_KERNEL_BINARY_H_ |
OLD | NEW |