| 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 |