| 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 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 131 | 131 |
| 132 kSpecializedVariableGet = 128, | 132 kSpecializedVariableGet = 128, |
| 133 kSpecializedVariableSet = 136, | 133 kSpecializedVariableSet = 136, |
| 134 kSpecialIntLiteral = 144, | 134 kSpecialIntLiteral = 144, |
| 135 }; | 135 }; |
| 136 | 136 |
| 137 | 137 |
| 138 static const int SpecializedIntLiteralBias = 3; | 138 static const int SpecializedIntLiteralBias = 3; |
| 139 | 139 |
| 140 | 140 |
| 141 template <typename T> | |
| 142 class BlockStack { | |
| 143 public: | |
| 144 BlockStack() : current_count_(0) {} | |
| 145 | |
| 146 void EnterScope() { | |
| 147 variable_count_.Add(current_count_); | |
| 148 current_count_ = 0; | |
| 149 } | |
| 150 | |
| 151 void LeaveScope() { | |
| 152 variables_.TruncateTo(variables_.length() - current_count_); | |
| 153 current_count_ = variable_count_[variable_count_.length() - 1]; | |
| 154 variable_count_.RemoveLast(); | |
| 155 } | |
| 156 | |
| 157 T* Lookup(int index) { | |
| 158 ASSERT(index < variables_.length()); | |
| 159 return variables_[index]; | |
| 160 } | |
| 161 | |
| 162 void Push(T* v) { | |
| 163 variables_.Add(v); | |
| 164 current_count_++; | |
| 165 } | |
| 166 | |
| 167 void Push(List<T>* decl) { | |
| 168 for (intptr_t i = 0; i < decl->length(); i++) { | |
| 169 variables_.Add(decl[i]); | |
| 170 current_count_++; | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 void Pop(T* decl) { | |
| 175 variables_.RemoveLast(); | |
| 176 current_count_--; | |
| 177 } | |
| 178 | |
| 179 void Pop(List<T>* decl) { | |
| 180 variables_.TruncateTo(variables_.length() - decl->length()); | |
| 181 current_count_ -= decl->length(); | |
| 182 } | |
| 183 | |
| 184 private: | |
| 185 int current_count_; | |
| 186 MallocGrowableArray<T*> variables_; | |
| 187 MallocGrowableArray<int> variable_count_; | |
| 188 }; | |
| 189 | |
| 190 | |
| 191 template <typename T> | |
| 192 class BlockMap { | |
| 193 public: | |
| 194 BlockMap() : current_count_(0), stack_height_(0) {} | |
| 195 | |
| 196 void EnterScope() { | |
| 197 variable_count_.Add(current_count_); | |
| 198 current_count_ = 0; | |
| 199 } | |
| 200 | |
| 201 void LeaveScope() { | |
| 202 stack_height_ -= current_count_; | |
| 203 current_count_ = variable_count_[variable_count_.length() - 1]; | |
| 204 variable_count_.RemoveLast(); | |
| 205 } | |
| 206 | |
| 207 int Lookup(T* object) { | |
| 208 typename MallocMap<T, int>::Pair* result = variables_.LookupPair(object); | |
| 209 ASSERT(result != NULL); | |
| 210 if (result == NULL) FATAL("lookup failure"); | |
| 211 return RawPointerKeyValueTrait<T, int>::ValueOf(*result); | |
| 212 } | |
| 213 | |
| 214 void Push(T* v) { | |
| 215 ASSERT(variables_.LookupPair(v) == NULL); | |
| 216 int index = stack_height_++; | |
| 217 variables_.Insert(v, index); | |
| 218 current_count_++; | |
| 219 } | |
| 220 | |
| 221 void Set(T* v, int index) { | |
| 222 typename MallocMap<T, int>::Pair* entry = variables_.LookupPair(v); | |
| 223 ASSERT(entry != NULL); | |
| 224 entry->value = index; | |
| 225 } | |
| 226 | |
| 227 void Push(List<T>* decl) { | |
| 228 for (intptr_t i = 0; i < decl->length(); i++) { | |
| 229 Push(decl[i]); | |
| 230 } | |
| 231 } | |
| 232 | |
| 233 void Pop(T* v) { | |
| 234 current_count_--; | |
| 235 stack_height_--; | |
| 236 } | |
| 237 | |
| 238 private: | |
| 239 int current_count_; | |
| 240 int stack_height_; | |
| 241 MallocMap<T, int> variables_; | |
| 242 MallocGrowableArray<int> variable_count_; | |
| 243 }; | |
| 244 | |
| 245 | |
| 246 template <typename T> | |
| 247 class VariableScope { | |
| 248 public: | |
| 249 explicit VariableScope(T* builder) : builder_(builder) { | |
| 250 builder_->variables().EnterScope(); | |
| 251 } | |
| 252 ~VariableScope() { builder_->variables().LeaveScope(); } | |
| 253 | |
| 254 private: | |
| 255 T* builder_; | |
| 256 }; | |
| 257 | |
| 258 | |
| 259 template <typename T> | |
| 260 class TypeParameterScope { | |
| 261 public: | |
| 262 explicit TypeParameterScope(T* builder) : builder_(builder) { | |
| 263 builder_->type_parameters().EnterScope(); | |
| 264 } | |
| 265 ~TypeParameterScope() { builder_->type_parameters().LeaveScope(); } | |
| 266 | |
| 267 private: | |
| 268 T* builder_; | |
| 269 }; | |
| 270 | |
| 271 | |
| 272 // Unlike other scopes, labels from enclosing functions are not visible in | |
| 273 // nested functions. The LabelScope class is used to hide outer labels. | |
| 274 template <typename Builder, typename Block> | |
| 275 class LabelScope { | |
| 276 public: | |
| 277 explicit LabelScope(Builder* builder) : builder_(builder) { | |
| 278 outer_block_ = builder_->labels(); | |
| 279 builder_->set_labels(&block_); | |
| 280 } | |
| 281 ~LabelScope() { builder_->set_labels(outer_block_); } | |
| 282 | |
| 283 private: | |
| 284 Builder* builder_; | |
| 285 Block block_; | |
| 286 Block* outer_block_; | |
| 287 }; | |
| 288 | |
| 289 | |
| 290 class ReaderHelper { | |
| 291 public: | |
| 292 ReaderHelper() : program_(NULL), labels_(NULL) {} | |
| 293 | |
| 294 Program* program() { return program_; } | |
| 295 void set_program(Program* program) { program_ = program; } | |
| 296 | |
| 297 BlockStack<VariableDeclaration>& variables() { return scope_; } | |
| 298 BlockStack<TypeParameter>& type_parameters() { return type_parameters_; } | |
| 299 | |
| 300 BlockStack<LabeledStatement>* labels() { return labels_; } | |
| 301 void set_labels(BlockStack<LabeledStatement>* labels) { labels_ = labels; } | |
| 302 | |
| 303 private: | |
| 304 Program* program_; | |
| 305 BlockStack<VariableDeclaration> scope_; | |
| 306 BlockStack<TypeParameter> type_parameters_; | |
| 307 BlockStack<LabeledStatement>* labels_; | |
| 308 }; | |
| 309 | |
| 310 | |
| 311 class Reader { | 141 class Reader { |
| 312 public: | 142 public: |
| 313 Reader(const uint8_t* buffer, intptr_t size) | 143 Reader(const uint8_t* buffer, intptr_t size) |
| 314 : buffer_(buffer), | 144 : buffer_(buffer), size_(size), offset_(0) {} |
| 315 size_(size), | |
| 316 offset_(0), | |
| 317 string_data_offset_(-1), | |
| 318 string_offsets_(NULL), | |
| 319 canonical_name_parents_(NULL), | |
| 320 canonical_name_strings_(NULL) {} | |
| 321 | |
| 322 ~Reader(); | |
| 323 | 145 |
| 324 uint32_t ReadUInt32() { | 146 uint32_t ReadUInt32() { |
| 325 ASSERT(offset_ + 4 <= size_); | 147 ASSERT(offset_ + 4 <= size_); |
| 326 | 148 |
| 327 uint32_t value = (buffer_[offset_ + 0] << 24) | | 149 uint32_t value = (buffer_[offset_ + 0] << 24) | |
| 328 (buffer_[offset_ + 1] << 16) | | 150 (buffer_[offset_ + 1] << 16) | |
| 329 (buffer_[offset_ + 2] << 8) | (buffer_[offset_ + 3] << 0); | 151 (buffer_[offset_ + 2] << 8) | (buffer_[offset_ + 3] << 0); |
| 330 offset_ += 4; | 152 offset_ += 4; |
| 331 return value; | 153 return value; |
| 332 } | 154 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 348 // 11... | 170 // 11... |
| 349 ASSERT(offset_ + 4 <= size_); | 171 ASSERT(offset_ + 4 <= size_); |
| 350 uint32_t value = ((byte0 & ~0xc0) << 24) | (buffer_[offset_ + 1] << 16) | | 172 uint32_t value = ((byte0 & ~0xc0) << 24) | (buffer_[offset_ + 1] << 16) | |
| 351 (buffer_[offset_ + 2] << 8) | | 173 (buffer_[offset_ + 2] << 8) | |
| 352 (buffer_[offset_ + 3] << 0); | 174 (buffer_[offset_ + 3] << 0); |
| 353 offset_ += 4; | 175 offset_ += 4; |
| 354 return value; | 176 return value; |
| 355 } | 177 } |
| 356 } | 178 } |
| 357 | 179 |
| 358 void add_token_position( | |
| 359 MallocGrowableArray<MallocGrowableArray<intptr_t>*>* list, | |
| 360 TokenPosition position) { | |
| 361 intptr_t size = list->length(); | |
| 362 while (size <= current_script_id_) { | |
| 363 MallocGrowableArray<intptr_t>* tmp = new MallocGrowableArray<intptr_t>(); | |
| 364 list->Add(tmp); | |
| 365 size = list->length(); | |
| 366 } | |
| 367 list->At(current_script_id_)->Add(position.value()); | |
| 368 } | |
| 369 | |
| 370 void record_token_position(TokenPosition position) { | |
| 371 if (position.IsReal() && helper()->program() != NULL) { | |
| 372 add_token_position(&helper()->program()->valid_token_positions, position); | |
| 373 } | |
| 374 } | |
| 375 | |
| 376 void record_yield_token_position(TokenPosition position) { | |
| 377 if (helper()->program() != NULL) { | |
| 378 add_token_position(&helper()->program()->yield_token_positions, position); | |
| 379 } | |
| 380 } | |
| 381 | |
| 382 /** | 180 /** |
| 383 * Read and return a TokenPosition from this reader. | 181 * Read and return a TokenPosition from this reader. |
| 384 * @param record specifies whether or not the read position is saved as a | 182 * @param record specifies whether or not the read position is saved as a |
| 385 * valid token position in the current script. | 183 * valid token position in the current script. |
| 386 * If not be sure to record it later by calling record_token_position (after | 184 * If not be sure to record it later by calling record_token_position (after |
| 387 * setting the correct current_script_id). | 185 * setting the correct current_script_id). |
| 388 */ | 186 */ |
| 389 TokenPosition ReadPosition(bool record = true) { | 187 TokenPosition ReadPosition() { |
| 390 // Position is saved as unsigned, | 188 // Position is saved as unsigned, |
| 391 // but actually ranges from -1 and up (thus the -1) | 189 // but actually ranges from -1 and up (thus the -1) |
| 392 intptr_t value = ReadUInt() - 1; | 190 intptr_t value = ReadUInt() - 1; |
| 393 TokenPosition result = TokenPosition(value); | 191 TokenPosition result = TokenPosition(value); |
| 394 max_position_ = Utils::Maximum(max_position_, result); | 192 max_position_ = Utils::Maximum(max_position_, result); |
| 395 if (min_position_.IsNoSource()) { | 193 if (min_position_.IsNoSource()) { |
| 396 min_position_ = result; | 194 min_position_ = result; |
| 397 } else if (result.IsReal()) { | 195 } else if (result.IsReal()) { |
| 398 min_position_ = Utils::Minimum(min_position_, result); | 196 min_position_ = Utils::Minimum(min_position_, result); |
| 399 } | 197 } |
| 400 | 198 |
| 401 if (record) { | |
| 402 record_token_position(result); | |
| 403 } | |
| 404 return result; | 199 return result; |
| 405 } | 200 } |
| 406 | 201 |
| 407 intptr_t ReadListLength() { return ReadUInt(); } | 202 intptr_t ReadListLength() { return ReadUInt(); } |
| 408 | 203 |
| 409 uint8_t ReadByte() { return buffer_[offset_++]; } | 204 uint8_t ReadByte() { return buffer_[offset_++]; } |
| 410 | 205 |
| 411 uint8_t PeekByte() { return buffer_[offset_]; } | 206 uint8_t PeekByte() { return buffer_[offset_]; } |
| 412 | 207 |
| 413 bool ReadBool() { return (ReadByte() & 1) == 1; } | 208 bool ReadBool() { return (ReadByte() & 1) == 1; } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 449 | 244 |
| 450 void EnsureEnd() { | 245 void EnsureEnd() { |
| 451 if (offset_ != size_) { | 246 if (offset_ != size_) { |
| 452 FATAL2( | 247 FATAL2( |
| 453 "Reading Kernel file: Expected to be at EOF " | 248 "Reading Kernel file: Expected to be at EOF " |
| 454 "(offset: %" Pd ", size: %" Pd ")", | 249 "(offset: %" Pd ", size: %" Pd ")", |
| 455 offset_, size_); | 250 offset_, size_); |
| 456 } | 251 } |
| 457 } | 252 } |
| 458 | 253 |
| 459 void DumpOffset(const char* str) { | |
| 460 OS::PrintErr("@%" Pd " %s\n", offset_, str); | |
| 461 } | |
| 462 | |
| 463 // The largest position read yet (since last reset). | 254 // The largest position read yet (since last reset). |
| 464 // This is automatically updated when calling ReadPosition, | 255 // This is automatically updated when calling ReadPosition, |
| 465 // but can be overwritten (e.g. via the PositionScope class). | 256 // but can be overwritten (e.g. via the PositionScope class). |
| 466 TokenPosition max_position() { return max_position_; } | 257 TokenPosition max_position() { return max_position_; } |
| 467 // The smallest position read yet (since last reset). | 258 // The smallest position read yet (since last reset). |
| 468 // This is automatically updated when calling ReadPosition, | 259 // This is automatically updated when calling ReadPosition, |
| 469 // but can be overwritten (e.g. via the PositionScope class). | 260 // but can be overwritten (e.g. via the PositionScope class). |
| 470 TokenPosition min_position() { return min_position_; } | 261 TokenPosition min_position() { return min_position_; } |
| 471 // The current script id for what we are currently processing. | |
| 472 // Note though that this is only a convenience helper and has to be set | |
| 473 // manually. | |
| 474 intptr_t current_script_id() { return current_script_id_; } | |
| 475 void set_current_script_id(intptr_t script_id) { | |
| 476 current_script_id_ = script_id; | |
| 477 } | |
| 478 | 262 |
| 479 template <typename T, typename RT> | 263 template <typename T, typename RT> |
| 480 T* ReadOptional() { | 264 T* ReadOptional() { |
| 481 Tag tag = ReadTag(); | 265 Tag tag = ReadTag(); |
| 482 if (tag == kNothing) { | 266 if (tag == kNothing) { |
| 483 return NULL; | 267 return NULL; |
| 484 } | 268 } |
| 485 ASSERT(tag == kSomething); | 269 ASSERT(tag == kSomething); |
| 486 return RT::ReadFrom(this); | 270 return RT::ReadFrom(this); |
| 487 } | 271 } |
| 488 | 272 |
| 489 template <typename T> | 273 template <typename T> |
| 490 T* ReadOptional() { | 274 T* ReadOptional() { |
| 491 return ReadOptional<T, T>(); | 275 return ReadOptional<T, T>(); |
| 492 } | 276 } |
| 493 | 277 |
| 494 ReaderHelper* helper() { return &builder_; } | |
| 495 | |
| 496 // A canonical name reference of -1 indicates none (for optional names), not | 278 // A canonical name reference of -1 indicates none (for optional names), not |
| 497 // the root name as in the canonical name table. | 279 // the root name as in the canonical name table. |
| 498 NameIndex ReadCanonicalNameReference() { return NameIndex(ReadUInt() - 1); } | 280 NameIndex ReadCanonicalNameReference() { return NameIndex(ReadUInt() - 1); } |
| 499 | 281 |
| 500 intptr_t offset() { return offset_; } | 282 intptr_t offset() { return offset_; } |
| 501 void set_offset(intptr_t offset) { offset_ = offset; } | 283 void set_offset(intptr_t offset) { offset_ = offset; } |
| 502 intptr_t size() { return size_; } | 284 intptr_t size() { return size_; } |
| 503 | 285 |
| 504 const uint8_t* buffer() { return buffer_; } | 286 const uint8_t* buffer() { return buffer_; } |
| 505 | 287 |
| 506 intptr_t string_data_offset() { return string_data_offset_; } | |
| 507 void MarkStringDataOffset() { | |
| 508 ASSERT(string_data_offset_ == -1); | |
| 509 string_data_offset_ = offset_; | |
| 510 } | |
| 511 | |
| 512 intptr_t StringLength(StringIndex index) { | |
| 513 return string_offsets_[index + 1] - string_offsets_[index]; | |
| 514 } | |
| 515 | |
| 516 uint8_t CharacterAt(StringIndex string_index, intptr_t index) { | |
| 517 ASSERT(index < StringLength(string_index)); | |
| 518 return buffer_[string_data_offset_ + string_offsets_[string_index] + index]; | |
| 519 } | |
| 520 | |
| 521 // The canonical name index of a canonical name's parent (-1 indicates that | |
| 522 // the parent is the root name). | |
| 523 NameIndex CanonicalNameParent(NameIndex index) { | |
| 524 return canonical_name_parents_[index]; | |
| 525 } | |
| 526 | |
| 527 // The string index of a canonical name's name string. | |
| 528 StringIndex CanonicalNameString(NameIndex index) { | |
| 529 return canonical_name_strings_[index]; | |
| 530 } | |
| 531 | |
| 532 private: | 288 private: |
| 533 const uint8_t* buffer_; | 289 const uint8_t* buffer_; |
| 534 intptr_t size_; | 290 intptr_t size_; |
| 535 intptr_t offset_; | 291 intptr_t offset_; |
| 536 ReaderHelper builder_; | |
| 537 TokenPosition max_position_; | 292 TokenPosition max_position_; |
| 538 TokenPosition min_position_; | 293 TokenPosition min_position_; |
| 539 intptr_t current_script_id_; | 294 intptr_t current_script_id_; |
| 540 | 295 |
| 541 // The offset of the start of the string data is recorded to allow access to | |
| 542 // the strings during deserialization. | |
| 543 intptr_t string_data_offset_; | |
| 544 | |
| 545 // The string offsets are decoded to support efficient access to string UTF-8 | |
| 546 // encodings. | |
| 547 intptr_t* string_offsets_; | |
| 548 | |
| 549 // The canonical names are decoded. | |
| 550 NameIndex* canonical_name_parents_; | |
| 551 StringIndex* canonical_name_strings_; | |
| 552 | |
| 553 friend class PositionScope; | 296 friend class PositionScope; |
| 554 friend class Program; | 297 friend class Program; |
| 555 }; | 298 }; |
| 556 | 299 |
| 557 | 300 |
| 558 // A helper class that resets the readers min and max positions both upon | 301 // A helper class that resets the readers min and max positions both upon |
| 559 // initialization and upon destruction, i.e. when created the min an max | 302 // initialization and upon destruction, i.e. when created the min an max |
| 560 // positions will be reset to "noSource", when destructing the min and max will | 303 // positions will be reset to "noSource", when destructing the min and max will |
| 561 // be reset to have they value they would have had, if they hadn't been reset in | 304 // be reset to have they value they would have had, if they hadn't been reset in |
| 562 // the first place. | 305 // the first place. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 582 Reader* reader_; | 325 Reader* reader_; |
| 583 TokenPosition min_; | 326 TokenPosition min_; |
| 584 TokenPosition max_; | 327 TokenPosition max_; |
| 585 }; | 328 }; |
| 586 | 329 |
| 587 } // namespace kernel | 330 } // namespace kernel |
| 588 } // namespace dart | 331 } // namespace dart |
| 589 | 332 |
| 590 #endif // !defined(DART_PRECOMPILED_RUNTIME) | 333 #endif // !defined(DART_PRECOMPILED_RUNTIME) |
| 591 #endif // RUNTIME_VM_KERNEL_BINARY_H_ | 334 #endif // RUNTIME_VM_KERNEL_BINARY_H_ |
| OLD | NEW |