github.com/ronhuafeng/gofrontend@v0.0.0-20220715151246-ff23266b8bc5/go/export.cc (about) 1 // export.cc -- Export declarations in Go frontend. 2 3 // Copyright 2009 The Go Authors. All rights reserved. 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file. 6 7 #include "go-system.h" 8 9 #include "go-c.h" 10 #include "go-diagnostics.h" 11 #include "go-sha1.h" 12 #include "gogo.h" 13 #include "types.h" 14 #include "expressions.h" 15 #include "statements.h" 16 #include "export.h" 17 #include "go-linemap.h" 18 #include "backend.h" 19 20 // This file handles exporting global declarations. 21 22 // Class Export. 23 24 const int Export::magic_len; 25 26 // Current version magic string. 27 const char Export::cur_magic[Export::magic_len] = 28 { 29 'v', '3', ';', '\n' 30 }; 31 32 // Magic strings for previous versions (still supported). 33 const char Export::v1_magic[Export::magic_len] = 34 { 35 'v', '1', ';', '\n' 36 }; 37 const char Export::v2_magic[Export::magic_len] = 38 { 39 'v', '2', ';', '\n' 40 }; 41 42 const int Export::checksum_len; 43 44 // Type hash table operations, treating aliases as distinct. 45 46 class Type_hash_alias_identical 47 { 48 public: 49 unsigned int 50 operator()(const Type* type) const 51 { 52 return type->hash_for_method(NULL, 53 (Type::COMPARE_ERRORS 54 | Type::COMPARE_TAGS 55 | Type::COMPARE_EMBEDDED_INTERFACES 56 | Type::COMPARE_ALIASES)); 57 } 58 }; 59 60 class Type_alias_identical 61 { 62 public: 63 bool 64 operator()(const Type* t1, const Type* t2) const 65 { 66 return Type::are_identical(t1, t2, 67 (Type::COMPARE_ERRORS 68 | Type::COMPARE_TAGS 69 | Type::COMPARE_EMBEDDED_INTERFACES 70 | Type::COMPARE_ALIASES), 71 NULL); 72 } 73 }; 74 75 // Mapping from Type objects to a constant index. 76 typedef Unordered_map_hash(const Type*, int, Type_hash_alias_identical, 77 Type_alias_identical) Type_refs; 78 79 // Implementation object for class Export. Hidden implementation avoids 80 // having to #include types.h in export.h, or use a static map. 81 82 struct Export_impl { 83 Type_refs type_refs; 84 }; 85 86 // Constructor. 87 88 Export::Export(Stream* stream) 89 : stream_(stream), type_index_(1), packages_(), impl_(new Export_impl) 90 { 91 go_assert(Export::checksum_len == Go_sha1_helper::checksum_len); 92 } 93 94 // Destructor. 95 96 Export::~Export() 97 { 98 delete this->impl_; 99 } 100 101 // A traversal class to collect functions and global variables 102 // referenced by inlined functions, and also to gather up 103 // referenced types that need to be included in the exports. 104 105 class Collect_export_references : public Traverse 106 { 107 public: 108 Collect_export_references(Export* exp, 109 const std::map<std::string, Package*>& packages, 110 Unordered_set(Named_object*)* exports, 111 Unordered_set(const Package*)* imports) 112 : Traverse(traverse_expressions 113 | traverse_types), 114 exp_(exp), packages_(packages), exports_(exports), imports_(imports), 115 inline_fcn_worklist_(NULL), exports_finalized_(false) 116 { } 117 118 // Initial entry point; performs a walk to expand the exports set. 119 void 120 expand_exports(std::vector<Named_object*>* inlinable_functions); 121 122 // Second entry point (called after the method above), to find 123 // all types referenced by exports. 124 void 125 prepare_types(const std::vector<Named_object*>& sorted_exports); 126 127 // Third entry point (called after the method above), to find 128 // all types in expressions referenced by exports. 129 void 130 prepare_expressions(const std::vector<Named_object*>& sorted_exports); 131 132 protected: 133 // Override of parent class method. 134 int 135 expression(Expression**); 136 137 // Override of parent class method. 138 int 139 type(Type* type); 140 141 // Traverse the components of a function type. 142 void 143 traverse_function_type(Function_type*); 144 145 // Traverse the methods of a named type, and register its package. 146 void 147 traverse_named_type(Named_type*); 148 149 private: 150 151 // Add a named object to the exports set (during expand_exports()). 152 // Returns TRUE if a new object was added to the exports set, 153 // FALSE otherwise. 154 bool 155 add_to_exports(Named_object*); 156 157 // The exporter. 158 Export* exp_; 159 // The list of packages known to this compilation. 160 const std::map<std::string, Package*>& packages_; 161 // The set of named objects to export. 162 Unordered_set(Named_object*)* exports_; 163 // Set containing all directly and indirectly imported packages. 164 Unordered_set(const Package*)* imports_; 165 // Functions we've already traversed and don't need to visit again. 166 Unordered_set(Named_object*) checked_functions_; 167 // Worklist of functions we are exporting with inline bodies that need 168 // to be checked. 169 std::vector<Named_object*>* inline_fcn_worklist_; 170 // Set to true if expand_exports() has been called and is complete. 171 bool exports_finalized_; 172 }; 173 174 void 175 Collect_export_references::expand_exports(std::vector<Named_object*>* fcns) 176 { 177 this->inline_fcn_worklist_ = fcns; 178 while (!this->inline_fcn_worklist_->empty()) 179 { 180 Named_object* no = this->inline_fcn_worklist_->back(); 181 this->inline_fcn_worklist_->pop_back(); 182 std::pair<Unordered_set(Named_object*)::iterator, bool> ins = 183 this->checked_functions_.insert(no); 184 if (ins.second) 185 { 186 // This traversal may add new objects to this->exports_ and new 187 // functions to this->inline_fcn_worklist_. 188 no->func_value()->block()->traverse(this); 189 } 190 } 191 this->inline_fcn_worklist_ = NULL; 192 this->exports_finalized_ = true; 193 } 194 195 bool 196 Collect_export_references::add_to_exports(Named_object* no) 197 { 198 std::pair<Unordered_set(Named_object*)::iterator, bool> ins = 199 this->exports_->insert(no); 200 // If the export list has been finalized, then we should not be 201 // adding anything new to the exports set. 202 go_assert(!this->exports_finalized_ || !ins.second); 203 return ins.second; 204 } 205 206 int 207 Collect_export_references::expression(Expression** pexpr) 208 { 209 const Expression* expr = *pexpr; 210 211 const Var_expression* ve = expr->var_expression(); 212 if (ve != NULL) 213 { 214 Named_object* no = ve->named_object(); 215 if (no->is_variable() && no->var_value()->is_global()) 216 { 217 const Package* var_package = no->package(); 218 if (var_package != NULL) 219 this->imports_->insert(var_package); 220 221 this->add_to_exports(no); 222 no->var_value()->set_is_referenced_by_inline(); 223 } 224 return TRAVERSE_CONTINUE; 225 } 226 227 const Func_expression* fe = expr->func_expression(); 228 if (fe != NULL) 229 { 230 Named_object* no = fe->named_object(); 231 232 const Package* func_package = fe->named_object()->package(); 233 if (func_package != NULL) 234 this->imports_->insert(func_package); 235 236 if (no->is_function_declaration() 237 && no->func_declaration_value()->type()->is_builtin()) 238 return TRAVERSE_CONTINUE; 239 240 if (this->inline_fcn_worklist_ != NULL) 241 { 242 bool added = this->add_to_exports(no); 243 244 if (no->is_function()) 245 no->func_value()->set_is_referenced_by_inline(); 246 247 // If 'added' is false then this object was already in 248 // exports_, in which case it was already added to 249 // check_inline_refs_ the first time we added it to exports_, so 250 // we don't need to add it again. 251 if (added 252 && no->is_function() 253 && no->func_value()->export_for_inlining()) 254 this->inline_fcn_worklist_->push_back(no); 255 } 256 257 return TRAVERSE_CONTINUE; 258 } 259 260 const Named_object* nco = expr->named_constant(); 261 if (nco != 0) 262 { 263 const Named_constant *nc = nco->const_value(); 264 Type::traverse(nc->type(), this); 265 return TRAVERSE_CONTINUE; 266 } 267 268 const Call_expression* call = expr->call_expression(); 269 if (call != NULL) 270 { 271 const Builtin_call_expression* bce = call->builtin_call_expression(); 272 if (bce != NULL 273 && (bce->code() == Builtin_call_expression::BUILTIN_ADD 274 || bce->code() == Builtin_call_expression::BUILTIN_SLICE)) 275 { 276 // This is a reference to unsafe.Add or unsafe.Slice. Make 277 // sure we list the "unsafe" package in the imports and give 278 // it a package index. 279 const std::map<std::string, Package*>::const_iterator p = 280 this->packages_.find("unsafe"); 281 go_assert(p != this->packages_.end()); 282 this->imports_->insert(p->second); 283 } 284 } 285 286 return TRAVERSE_CONTINUE; 287 } 288 289 // Collect up the set of types mentioned in expressions of things we're exporting, 290 // and collect all the packages encountered during type traversal, to make sure 291 // we can declare things referered to indirectly (for example, in the body of an 292 // exported inline function from another package). 293 294 void 295 Collect_export_references::prepare_expressions(const std::vector<Named_object*>& sorted_exports) 296 { 297 for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin(); 298 p != sorted_exports.end(); 299 ++p) 300 { 301 Named_object* no = *p; 302 if (no->classification() == Named_object::NAMED_OBJECT_CONST) 303 { 304 Expression* e = no->const_value()->expr(); 305 if (e != NULL) 306 Expression::traverse(&e, this); 307 } 308 } 309 } 310 311 // Collect up the set of types mentioned in things we're exporting, and collect 312 // all the packages encountered during type traversal, to make sure we can 313 // declare things referered to indirectly (for example, in the body of an 314 // exported inline function from another package). 315 316 void 317 Collect_export_references::prepare_types(const std::vector<Named_object*>& sorted_exports) 318 { 319 // Iterate through the exported objects and traverse any types encountered. 320 for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin(); 321 p != sorted_exports.end(); 322 ++p) 323 { 324 Named_object* no = *p; 325 switch (no->classification()) 326 { 327 case Named_object::NAMED_OBJECT_CONST: 328 { 329 Type* t = no->const_value()->type(); 330 if (t != NULL && !t->is_abstract()) 331 Type::traverse(t, this); 332 } 333 break; 334 335 case Named_object::NAMED_OBJECT_TYPE: 336 Type::traverse(no->type_value()->real_type(), this); 337 this->traverse_named_type(no->type_value()); 338 break; 339 340 case Named_object::NAMED_OBJECT_VAR: 341 Type::traverse(no->var_value()->type(), this); 342 break; 343 344 case Named_object::NAMED_OBJECT_FUNC: 345 { 346 Function* fn = no->func_value(); 347 this->traverse_function_type(fn->type()); 348 if (fn->export_for_inlining()) 349 fn->block()->traverse(this); 350 } 351 break; 352 353 case Named_object::NAMED_OBJECT_FUNC_DECLARATION: 354 this->traverse_function_type(no->func_declaration_value()->type()); 355 break; 356 357 default: 358 // We shouldn't see anything else. If we do we'll give an 359 // error later when we try to actually export it. 360 break; 361 } 362 } 363 } 364 365 // Record referenced type, record package imports, and make sure we traverse 366 // methods of named types. 367 368 int 369 Collect_export_references::type(Type* type) 370 { 371 // Skip forwarders; don't try to give them a type index. 372 if (type->forward_declaration_type() != NULL) 373 return TRAVERSE_CONTINUE; 374 375 // Skip the void type, which we'll see when exporting 376 // unsafe.Pointer. The void type is not itself exported, because 377 // Pointer_type::do_export checks for it. 378 if (type->is_void_type()) 379 return TRAVERSE_SKIP_COMPONENTS; 380 381 // Skip the nil type, turns up in function bodies. 382 if (type->is_nil_type()) 383 return TRAVERSE_SKIP_COMPONENTS; 384 385 // Skip abstract types. We should never see these in real code, 386 // only in things like const declarations. 387 if (type->is_abstract()) 388 return TRAVERSE_SKIP_COMPONENTS; 389 390 if (!this->exp_->record_type(type)) 391 { 392 // We've already seen this type. 393 return TRAVERSE_SKIP_COMPONENTS; 394 } 395 396 // At this stage of compilation traversing interface types traverses 397 // the final list of methods, but we export the locally defined 398 // methods. If there is an embedded interface type we need to make 399 // sure to export that. Check classification, rather than calling 400 // the interface_type method, because we want to handle named types 401 // below. 402 if (type->classification() == Type::TYPE_INTERFACE) 403 { 404 Interface_type* it = type->interface_type(); 405 const Typed_identifier_list* methods = it->local_methods(); 406 if (methods != NULL) 407 { 408 for (Typed_identifier_list::const_iterator p = methods->begin(); 409 p != methods->end(); 410 ++p) 411 { 412 if (p->name().empty()) 413 Type::traverse(p->type(), this); 414 else 415 this->traverse_function_type(p->type()->function_type()); 416 } 417 } 418 return TRAVERSE_SKIP_COMPONENTS; 419 } 420 421 Named_type* nt = type->named_type(); 422 if (nt != NULL) 423 this->traverse_named_type(nt); 424 425 return TRAVERSE_CONTINUE; 426 } 427 428 void 429 Collect_export_references::traverse_named_type(Named_type* nt) 430 { 431 const Package* package = nt->named_object()->package(); 432 if (package != NULL) 433 this->imports_->insert(package); 434 435 // We have to traverse the methods of named types, because we are 436 // going to export them. This is not done by ordinary type 437 // traversal. 438 const Bindings* methods = nt->local_methods(); 439 if (methods != NULL) 440 { 441 for (Bindings::const_definitions_iterator pm = 442 methods->begin_definitions(); 443 pm != methods->end_definitions(); 444 ++pm) 445 { 446 Function* fn = (*pm)->func_value(); 447 this->traverse_function_type(fn->type()); 448 if (fn->export_for_inlining()) 449 fn->block()->traverse(this); 450 } 451 452 for (Bindings::const_declarations_iterator pm = 453 methods->begin_declarations(); 454 pm != methods->end_declarations(); 455 ++pm) 456 { 457 Named_object* mno = pm->second; 458 if (mno->is_function_declaration()) 459 this->traverse_function_type(mno->func_declaration_value()->type()); 460 } 461 } 462 } 463 464 // Traverse the types in a function type. We don't need the function 465 // type itself, just the receiver, parameter, and result types. 466 467 void 468 Collect_export_references::traverse_function_type(Function_type* type) 469 { 470 go_assert(type != NULL); 471 if (this->remember_type(type)) 472 return; 473 const Typed_identifier* receiver = type->receiver(); 474 if (receiver != NULL) 475 Type::traverse(receiver->type(), this); 476 const Typed_identifier_list* parameters = type->parameters(); 477 if (parameters != NULL) 478 parameters->traverse(this); 479 const Typed_identifier_list* results = type->results(); 480 if (results != NULL) 481 results->traverse(this); 482 } 483 484 // Return true if we should export NO. 485 486 static bool 487 should_export(Named_object* no) 488 { 489 // We only export objects which are locally defined. 490 if (no->package() != NULL) 491 return false; 492 493 // We don't export packages. 494 if (no->is_package()) 495 return false; 496 497 // We don't export hidden names. 498 if (Gogo::is_hidden_name(no->name())) 499 return false; 500 501 // We don't export various special functions. 502 if (Gogo::special_name_pos(no->name()) != std::string::npos) 503 return false; 504 505 // Methods are exported with the type, not here. 506 if (no->is_function() 507 && no->func_value()->type()->is_method()) 508 return false; 509 if (no->is_function_declaration() 510 && no->func_declaration_value()->type()->is_method()) 511 return false; 512 513 // Don't export dummy global variables created for initializers when 514 // used with sinks. 515 if (no->is_variable() && no->name()[0] == '_' && no->name()[1] == '.') 516 return false; 517 518 return true; 519 } 520 521 // Compare Typed_identifier_list's. 522 523 static int 524 compare_til(const Typed_identifier_list*, const Typed_identifier_list*); 525 526 // A functor to sort Named_object pointers by name. 527 528 struct Sort_bindings 529 { 530 bool 531 operator()(const Named_object* n1, const Named_object* n2) const 532 { 533 if (n1 == n2) 534 return false; 535 536 if (n1->package() != n2->package()) 537 { 538 if (n1->package() == NULL) 539 return true; 540 if (n2->package() == NULL) 541 return false; 542 543 // Make sure we don't see the same pkgpath twice. 544 const std::string& p1(n1->package()->pkgpath()); 545 const std::string& p2(n2->package()->pkgpath()); 546 go_assert(p1 != p2); 547 548 return p1 < p2; 549 } 550 551 if (n1->name() != n2->name()) 552 return n1->name() < n2->name(); 553 554 // We shouldn't see the same name twice, but it can happen for 555 // nested type names. 556 557 go_assert(n1->is_type() && n2->is_type()); 558 559 unsigned int ind1; 560 const Named_object* g1 = n1->type_value()->in_function(&ind1); 561 unsigned int ind2; 562 const Named_object* g2 = n2->type_value()->in_function(&ind2); 563 564 if (g1 == NULL) 565 { 566 go_assert(g2 != NULL); 567 return true; 568 } 569 else if (g2 == NULL) 570 return false; 571 else if (g1 == g2) 572 { 573 go_assert(ind1 != ind2); 574 return ind1 < ind2; 575 } 576 else if ((g1->package() != g2->package()) || (g1->name() != g2->name())) 577 return Sort_bindings()(g1, g2); 578 else 579 { 580 // This case can happen if g1 or g2 is a method. 581 if (g1 != NULL && g1->func_value()->is_method()) 582 { 583 const Typed_identifier* r = g1->func_value()->type()->receiver(); 584 g1 = r->type()->named_type()->named_object(); 585 } 586 if (g2 != NULL && g2->func_value()->is_method()) 587 { 588 const Typed_identifier* r = g2->func_value()->type()->receiver(); 589 g2 = r->type()->named_type()->named_object(); 590 } 591 return Sort_bindings()(g1, g2); 592 } 593 } 594 }; 595 596 // A functor to sort types for export. 597 598 struct Sort_types 599 { 600 bool 601 operator()(const Type* t1, const Type* t2) const 602 { 603 t1 = t1->forwarded(); 604 t2 = t2->forwarded(); 605 606 const Named_type* nt1 = t1->named_type(); 607 const Named_type* nt2 = t2->named_type(); 608 if (nt1 != NULL) 609 { 610 if (nt2 != NULL) 611 { 612 Sort_bindings sb; 613 return sb(nt1->named_object(), nt2->named_object()); 614 } 615 else 616 return true; 617 } 618 else if (nt2 != NULL) 619 return false; 620 if (t1->classification() != t2->classification()) 621 return t1->classification() < t2->classification(); 622 Gogo* gogo = go_get_gogo(); 623 Backend_name b1; 624 gogo->type_descriptor_backend_name(t1, NULL, &b1); 625 Backend_name b2; 626 gogo->type_descriptor_backend_name(t2, NULL, &b2); 627 628 std::string n1 = b1.name(); 629 std::string n2 = b2.name(); 630 if (n1 != n2) 631 return n1 < n2; 632 633 // We should never see equal types here. If we do, we may not 634 // generate an identical output file for identical input. But the 635 // backend names can be equal because we want to treat aliases 636 // differently while type_descriptor_backend_name does not. In 637 // that case we need to traverse the type elements. 638 639 // t1 == t2 in case std::sort compares elements to themselves. 640 if (t1 == t2) 641 return false; 642 643 Sort_types sort; 644 Type_alias_identical identical; 645 go_assert(!identical(t1, t2)); 646 647 switch (t1->classification()) 648 { 649 case Type::TYPE_ERROR: 650 return false; 651 652 case Type::TYPE_VOID: 653 case Type::TYPE_BOOLEAN: 654 case Type::TYPE_INTEGER: 655 case Type::TYPE_FLOAT: 656 case Type::TYPE_COMPLEX: 657 case Type::TYPE_STRING: 658 case Type::TYPE_SINK: 659 case Type::TYPE_NIL: 660 case Type::TYPE_CALL_MULTIPLE_RESULT: 661 case Type::TYPE_NAMED: 662 case Type::TYPE_FORWARD: 663 default: 664 go_unreachable(); 665 666 case Type::TYPE_FUNCTION: 667 { 668 const Function_type* ft1 = t1->function_type(); 669 const Function_type* ft2 = t2->function_type(); 670 const Typed_identifier* r1 = ft1->receiver(); 671 const Typed_identifier* r2 = ft2->receiver(); 672 if (r1 == NULL) 673 go_assert(r2 == NULL); 674 else 675 { 676 go_assert(r2 != NULL); 677 const Type* rt1 = r1->type()->forwarded(); 678 const Type* rt2 = r2->type()->forwarded(); 679 if (!identical(rt1, rt2)) 680 return sort(rt1, rt2); 681 } 682 683 const Typed_identifier_list* p1 = ft1->parameters(); 684 const Typed_identifier_list* p2 = ft2->parameters(); 685 if (p1 == NULL || p1->empty()) 686 go_assert(p2 == NULL || p2->empty()); 687 else 688 { 689 go_assert(p2 != NULL && !p2->empty()); 690 int i = compare_til(p1, p2); 691 if (i < 0) 692 return false; 693 else if (i > 0) 694 return true; 695 } 696 697 p1 = ft1->results(); 698 p2 = ft2->results(); 699 if (p1 == NULL || p1->empty()) 700 go_assert(p2 == NULL || p2->empty()); 701 else 702 { 703 go_assert(p2 != NULL && !p2->empty()); 704 int i = compare_til(p1, p2); 705 if (i < 0) 706 return false; 707 else if (i > 0) 708 return true; 709 } 710 711 go_unreachable(); 712 } 713 714 case Type::TYPE_POINTER: 715 { 716 const Type* p1 = t1->points_to()->forwarded(); 717 const Type* p2 = t2->points_to()->forwarded(); 718 go_assert(!identical(p1, p2)); 719 return sort(p1, p2); 720 } 721 722 case Type::TYPE_STRUCT: 723 { 724 const Struct_type* s1 = t1->struct_type(); 725 const Struct_type* s2 = t2->struct_type(); 726 const Struct_field_list* f1 = s1->fields(); 727 const Struct_field_list* f2 = s2->fields(); 728 go_assert(f1 != NULL && f2 != NULL); 729 Struct_field_list::const_iterator p1 = f1->begin(); 730 Struct_field_list::const_iterator p2 = f2->begin(); 731 for (; p2 != f2->end(); ++p1, ++p2) 732 { 733 go_assert(p1 != f1->end()); 734 go_assert(p1->field_name() == p2->field_name()); 735 go_assert(p1->is_anonymous() == p2->is_anonymous()); 736 const Type* ft1 = p1->type()->forwarded(); 737 const Type* ft2 = p2->type()->forwarded(); 738 if (!identical(ft1, ft2)) 739 return sort(ft1, ft2); 740 } 741 go_assert(p1 == f1->end()); 742 go_unreachable(); 743 } 744 745 case Type::TYPE_ARRAY: 746 { 747 const Type* e1 = t1->array_type()->element_type()->forwarded(); 748 const Type* e2 = t2->array_type()->element_type()->forwarded(); 749 go_assert(!identical(e1, e2)); 750 return sort(e1, e2); 751 } 752 753 case Type::TYPE_MAP: 754 { 755 const Map_type* m1 = t1->map_type(); 756 const Map_type* m2 = t2->map_type(); 757 const Type* k1 = m1->key_type()->forwarded(); 758 const Type* k2 = m2->key_type()->forwarded(); 759 if (!identical(k1, k2)) 760 return sort(k1, k2); 761 const Type* v1 = m1->val_type()->forwarded(); 762 const Type* v2 = m2->val_type()->forwarded(); 763 go_assert(!identical(v1, v2)); 764 return sort(v1, v2); 765 } 766 767 case Type::TYPE_CHANNEL: 768 { 769 const Type* e1 = t1->channel_type()->element_type()->forwarded(); 770 const Type* e2 = t2->channel_type()->element_type()->forwarded(); 771 go_assert(!identical(e1, e2)); 772 return sort(e1, e2); 773 } 774 775 case Type::TYPE_INTERFACE: 776 { 777 const Interface_type* it1 = t1->interface_type(); 778 const Interface_type* it2 = t2->interface_type(); 779 const Typed_identifier_list* m1 = it1->local_methods(); 780 const Typed_identifier_list* m2 = it2->local_methods(); 781 782 // We know the full method lists are the same, because the 783 // mangled type names were the same, but here we are looking 784 // at the local method lists, which include embedded 785 // interfaces, and we can have an embedded empty interface. 786 if (m1 == NULL || m1->empty()) 787 { 788 go_assert(m2 != NULL && !m2->empty()); 789 return true; 790 } 791 else if (m2 == NULL || m2->empty()) 792 { 793 go_assert(m1 != NULL && !m1->empty()); 794 return false; 795 } 796 797 int i = compare_til(m1, m2); 798 if (i < 0) 799 return false; 800 else if (i > 0) 801 return true; 802 else 803 go_unreachable(); 804 } 805 } 806 } 807 }; 808 809 // Compare Typed_identifier_list's with Sort_types, returning -1, 0, +1. 810 811 static int 812 compare_til( 813 const Typed_identifier_list* til1, 814 const Typed_identifier_list* til2) 815 { 816 Type_alias_identical identical; 817 Sort_types sort; 818 Typed_identifier_list::const_iterator p1 = til1->begin(); 819 Typed_identifier_list::const_iterator p2 = til2->begin(); 820 for (; p2 != til2->end(); ++p1, ++p2) 821 { 822 if (p1 == til1->end()) 823 return -1; 824 const Type* t1 = p1->type()->forwarded(); 825 const Type* t2 = p2->type()->forwarded(); 826 if (!identical(t1, t2)) 827 { 828 if (sort(t1, t2)) 829 return -1; 830 else 831 return +1; 832 } 833 } 834 if (p1 != til1->end()) 835 return +1; 836 return 0; 837 } 838 839 // Export those identifiers marked for exporting. 840 841 void 842 Export::export_globals(const std::string& package_name, 843 const std::string& prefix, 844 const std::string& pkgpath, 845 const std::map<std::string, Package*>& packages, 846 const std::map<std::string, Package*>& imports, 847 const std::string& import_init_fn, 848 const Import_init_set& imported_init_fns, 849 const Bindings* bindings, 850 Unordered_set(Named_object*)* functions_marked_inline) 851 { 852 // If there have been any errors so far, don't try to export 853 // anything. That way the export code doesn't have to worry about 854 // mismatched types or other confusions. 855 if (saw_errors()) 856 return; 857 858 // EXPORTS is the set of objects to export. CHECK_INLINE_REFS is a 859 // list of exported function with inline bodies that need to be 860 // checked for references to other objects. Every function on 861 // CHECK_INLINE_REFS is also on EXPORTS. 862 Unordered_set(Named_object*) exports; 863 std::vector<Named_object*> check_inline_refs; 864 check_inline_refs.reserve(functions_marked_inline->size()); 865 866 // Add all functions/methods from the "marked inlined" set to the 867 // CHECK_INLINE_REFS worklist. 868 for (Unordered_set(Named_object*)::const_iterator p = functions_marked_inline->begin(); 869 p != functions_marked_inline->end(); 870 ++p) 871 check_inline_refs.push_back(*p); 872 873 for (Bindings::const_definitions_iterator p = bindings->begin_definitions(); 874 p != bindings->end_definitions(); 875 ++p) 876 { 877 if (should_export(*p)) 878 exports.insert(*p); 879 } 880 881 for (Bindings::const_declarations_iterator p = 882 bindings->begin_declarations(); 883 p != bindings->end_declarations(); 884 ++p) 885 { 886 // We export a function declaration as it may be implemented in 887 // supporting C code. We do not export type declarations. 888 if (p->second->is_function_declaration() 889 && should_export(p->second)) 890 exports.insert(p->second); 891 } 892 893 // Track all imported packages mentioned in export data. 894 Unordered_set(const Package*) all_imports; 895 896 Collect_export_references collect(this, packages, &exports, &all_imports); 897 898 // Walk the set of inlinable routine bodies collected above. This 899 // can potentially expand the exports set. 900 collect.expand_exports(&check_inline_refs); 901 902 // Export the symbols in sorted order. That will reduce cases where 903 // irrelevant changes to the source code affect the exported 904 // interface. 905 std::vector<Named_object*> sorted_exports; 906 sorted_exports.reserve(exports.size()); 907 908 for (Unordered_set(Named_object*)::const_iterator p = exports.begin(); 909 p != exports.end(); 910 ++p) 911 { 912 sorted_exports.push_back(*p); 913 914 const Package* pkg = (*p)->package(); 915 if (pkg != NULL) 916 all_imports.insert(pkg); 917 } 918 919 std::sort(sorted_exports.begin(), sorted_exports.end(), Sort_bindings()); 920 921 // Collect up the set of types mentioned in things we're exporting, 922 // and any packages that may be referred to indirectly. 923 collect.prepare_types(sorted_exports); 924 collect.prepare_expressions(sorted_exports); 925 926 // Assign indexes to all exported types and types referenced by 927 // things we're exporting. Return value is index of first non-exported 928 // type. 929 int unexported_type_index = this->assign_type_indices(sorted_exports); 930 931 // Although the export data is readable, at least this version is, 932 // it is conceptually a binary format. Start with a four byte 933 // version number. 934 this->write_bytes(Export::cur_magic, Export::magic_len); 935 936 // The package name. 937 this->write_c_string("package "); 938 this->write_string(package_name); 939 this->write_c_string("\n"); 940 941 // The prefix or package path, used for all global symbols. 942 if (prefix.empty()) 943 { 944 go_assert(!pkgpath.empty()); 945 this->write_c_string("pkgpath "); 946 this->write_string(pkgpath); 947 } 948 else 949 { 950 this->write_c_string("prefix "); 951 this->write_string(prefix); 952 } 953 this->write_c_string("\n"); 954 955 this->write_packages(packages); 956 957 this->write_imports(imports, all_imports); 958 959 this->write_imported_init_fns(package_name, import_init_fn, 960 imported_init_fns); 961 962 // FIXME: It might be clever to add something about the processor 963 // and ABI being used, although ideally any problems in that area 964 // would be caught by the linker. 965 966 // Write out all the types, both exported and not. 967 this->write_types(unexported_type_index); 968 969 // Write out the non-type export data. 970 for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin(); 971 p != sorted_exports.end(); 972 ++p) 973 { 974 if (!(*p)->is_type()) 975 (*p)->export_named_object(this); 976 } 977 978 std::string checksum = this->stream_->checksum(); 979 std::string s = "checksum "; 980 for (std::string::const_iterator p = checksum.begin(); 981 p != checksum.end(); 982 ++p) 983 { 984 unsigned char c = *p; 985 unsigned int dig = c >> 4; 986 s += dig < 10 ? '0' + dig : 'A' + dig - 10; 987 dig = c & 0xf; 988 s += dig < 10 ? '0' + dig : 'A' + dig - 10; 989 } 990 s += "\n"; 991 this->stream_->write_checksum(s); 992 } 993 994 // Record a type in the "to be indexed" set. Return true if the type 995 // was not already in the set, false otherwise. 996 997 bool 998 Export::record_type(Type* type) 999 { 1000 type = type->forwarded(); 1001 std::pair<Type_refs::iterator, bool> ins = 1002 this->impl_->type_refs.insert(std::make_pair(type, 0)); 1003 return ins.second; 1004 } 1005 1006 // Assign the specified type an index. 1007 1008 void 1009 Export::set_type_index(const Type* type) 1010 { 1011 type = type->forwarded(); 1012 Type_refs::iterator p = this->impl_->type_refs.find(type); 1013 go_assert(p != this->impl_->type_refs.end()); 1014 int index = this->type_index_; 1015 ++this->type_index_; 1016 go_assert(p->second == 0); 1017 p->second = index; 1018 } 1019 1020 // This helper assigns type indices to all types mentioned directly or 1021 // indirectly in the things we're exporting. Actual exported types are given 1022 // indices according to where the appear on the sorted exports list; all other 1023 // types appear afterwards. Return value is the total number of exported types 1024 // plus 1, e.g. the index of the 1st non-exported type. 1025 1026 int 1027 Export::assign_type_indices(const std::vector<Named_object*>& sorted_exports) 1028 { 1029 // Assign indexes to all the exported types. 1030 for (std::vector<Named_object*>::const_iterator p = sorted_exports.begin(); 1031 p != sorted_exports.end(); 1032 ++p) 1033 { 1034 if (!(*p)->is_type()) 1035 continue; 1036 this->record_type((*p)->type_value()); 1037 this->set_type_index((*p)->type_value()); 1038 } 1039 int ret = this->type_index_; 1040 1041 // Collect export-referenced, non-builtin types. 1042 std::vector<const Type*> types; 1043 types.reserve(this->impl_->type_refs.size()); 1044 for (Type_refs::const_iterator p = this->impl_->type_refs.begin(); 1045 p != this->impl_->type_refs.end(); 1046 ++p) 1047 { 1048 const Type* t = p->first; 1049 if (p->second != 0) 1050 continue; 1051 types.push_back(t); 1052 } 1053 1054 // Sort the types. 1055 std::sort(types.begin(), types.end(), Sort_types()); 1056 1057 // Assign numbers to the sorted list. 1058 for (std::vector<const Type *>::const_iterator p = types.begin(); 1059 p != types.end(); 1060 ++p) 1061 this->set_type_index((*p)); 1062 1063 return ret; 1064 } 1065 1066 // Sort packages. 1067 1068 static bool 1069 packages_compare(const Package* a, const Package* b) 1070 { 1071 if (a->package_name() < b->package_name()) 1072 return true; 1073 else if (a->package_name() > b->package_name()) 1074 return false; 1075 1076 if (a->pkgpath() < b->pkgpath()) 1077 return true; 1078 else if (a->pkgpath() > b->pkgpath()) 1079 return false; 1080 1081 // In principle if we get here then a == b. Try to do something sensible 1082 // even if the import information is inconsistent. 1083 if (a->pkgpath_symbol() < b->pkgpath_symbol()) 1084 return true; 1085 else if (a->pkgpath_symbol() > b->pkgpath_symbol()) 1086 return false; 1087 1088 return a < b; 1089 } 1090 1091 // Write out all the known packages whose pkgpath symbol is not a 1092 // simple transformation of the pkgpath, so that the importing code 1093 // can reliably know it. 1094 1095 void 1096 Export::write_packages(const std::map<std::string, Package*>& packages) 1097 { 1098 // Sort for consistent output. 1099 std::vector<Package*> out; 1100 for (std::map<std::string, Package*>::const_iterator p = packages.begin(); 1101 p != packages.end(); 1102 ++p) 1103 { 1104 if (p->second->pkgpath_symbol() 1105 != Gogo::pkgpath_for_symbol(p->second->pkgpath())) 1106 out.push_back(p->second); 1107 } 1108 1109 std::sort(out.begin(), out.end(), packages_compare); 1110 1111 for (std::vector<Package*>::const_iterator p = out.begin(); 1112 p != out.end(); 1113 ++p) 1114 { 1115 this->write_c_string("package "); 1116 this->write_string((*p)->package_name()); 1117 this->write_c_string(" "); 1118 this->write_string((*p)->pkgpath()); 1119 this->write_c_string(" "); 1120 this->write_string((*p)->pkgpath_symbol()); 1121 this->write_c_string("\n"); 1122 } 1123 } 1124 1125 // Sort imported packages. 1126 1127 static bool 1128 import_compare(const std::pair<std::string, Package*>& a, 1129 const std::pair<std::string, Package*>& b) 1130 { 1131 return a.first < b.first; 1132 } 1133 1134 // Write out the imported packages. 1135 1136 void 1137 Export::write_imports(const std::map<std::string, Package*>& imports, 1138 const Unordered_set(const Package*)& all_imports) 1139 { 1140 // Sort the imports for more consistent output. 1141 Unordered_set(const Package*) seen; 1142 std::vector<std::pair<std::string, Package*> > sorted_imports; 1143 for (std::map<std::string, Package*>::const_iterator p = imports.begin(); 1144 p != imports.end(); 1145 ++p) 1146 { 1147 sorted_imports.push_back(std::make_pair(p->first, p->second)); 1148 seen.insert(p->second); 1149 } 1150 1151 std::sort(sorted_imports.begin(), sorted_imports.end(), import_compare); 1152 1153 int package_index = 1; 1154 for (std::vector<std::pair<std::string, Package*> >::const_iterator p = 1155 sorted_imports.begin(); 1156 p != sorted_imports.end(); 1157 ++p) 1158 { 1159 this->write_c_string("import "); 1160 this->write_string(p->second->package_name()); 1161 this->write_c_string(" "); 1162 this->write_string(p->second->pkgpath()); 1163 this->write_c_string(" \""); 1164 this->write_string(p->first); 1165 this->write_c_string("\"\n"); 1166 1167 this->packages_[p->second] = package_index; 1168 package_index++; 1169 } 1170 1171 // Write out a separate list of indirectly imported packages. 1172 std::vector<const Package*> indirect_imports; 1173 for (Unordered_set(const Package*)::const_iterator p = 1174 all_imports.begin(); 1175 p != all_imports.end(); 1176 ++p) 1177 { 1178 if (seen.find(*p) == seen.end()) 1179 indirect_imports.push_back(*p); 1180 } 1181 1182 std::sort(indirect_imports.begin(), indirect_imports.end(), 1183 packages_compare); 1184 1185 for (std::vector<const Package*>::const_iterator p = 1186 indirect_imports.begin(); 1187 p != indirect_imports.end(); 1188 ++p) 1189 { 1190 this->write_c_string("indirectimport "); 1191 this->write_string((*p)->package_name()); 1192 this->write_c_string(" "); 1193 this->write_string((*p)->pkgpath()); 1194 this->write_c_string("\n"); 1195 1196 this->packages_[*p] = package_index; 1197 package_index++; 1198 } 1199 } 1200 1201 void 1202 Export::add_init_graph_edge(Init_graph* init_graph, unsigned src, unsigned sink) 1203 { 1204 Init_graph::iterator it = init_graph->find(src); 1205 if (it != init_graph->end()) 1206 it->second.insert(sink); 1207 else 1208 { 1209 std::set<unsigned> succs; 1210 succs.insert(sink); 1211 (*init_graph)[src] = succs; 1212 } 1213 } 1214 1215 // Constructs the imported portion of the init graph, e.g. those 1216 // edges that we read from imported packages. 1217 1218 void 1219 Export::populate_init_graph(Init_graph* init_graph, 1220 const Import_init_set& imported_init_fns, 1221 const std::map<std::string, unsigned>& init_idx) 1222 { 1223 for (Import_init_set::const_iterator p = imported_init_fns.begin(); 1224 p != imported_init_fns.end(); 1225 ++p) 1226 { 1227 const Import_init* ii = *p; 1228 if (ii->is_dummy()) 1229 continue; 1230 std::map<std::string, unsigned>::const_iterator srcit = 1231 init_idx.find(ii->init_name()); 1232 go_assert(srcit != init_idx.end()); 1233 unsigned src = srcit->second; 1234 for (std::set<std::string>::const_iterator pci = ii->precursors().begin(); 1235 pci != ii->precursors().end(); 1236 ++pci) 1237 { 1238 std::map<std::string, unsigned>::const_iterator it = 1239 init_idx.find(*pci); 1240 go_assert(it != init_idx.end()); 1241 unsigned sink = it->second; 1242 add_init_graph_edge(init_graph, src, sink); 1243 } 1244 } 1245 } 1246 1247 // Write out the initialization functions which need to run for this 1248 // package. 1249 1250 void 1251 Export::write_imported_init_fns(const std::string& package_name, 1252 const std::string& import_init_fn, 1253 const Import_init_set& imported_init_fns) 1254 { 1255 if (import_init_fn.empty() && imported_init_fns.empty()) return; 1256 1257 // Maps a given init function to the its index in the exported "init" clause. 1258 std::map<std::string, unsigned> init_idx; 1259 1260 this->write_c_string("init"); 1261 1262 if (!import_init_fn.empty()) 1263 { 1264 this->write_c_string(" "); 1265 this->write_string(package_name); 1266 this->write_c_string(" "); 1267 this->write_string(import_init_fn); 1268 init_idx[import_init_fn] = 0; 1269 } 1270 1271 if (imported_init_fns.empty()) 1272 { 1273 this->write_c_string("\n"); 1274 return; 1275 } 1276 1277 typedef std::map<int, std::vector<std::string> > level_map; 1278 Init_graph init_graph; 1279 level_map inits_at_level; 1280 1281 // Walk through the set of import inits (already sorted by 1282 // init fcn name) and write them out to the exports. 1283 for (Import_init_set::const_iterator p = imported_init_fns.begin(); 1284 p != imported_init_fns.end(); 1285 ++p) 1286 { 1287 const Import_init* ii = *p; 1288 1289 if (ii->init_name() == import_init_fn) 1290 continue; 1291 1292 this->write_c_string(" "); 1293 this->write_string(ii->package_name()); 1294 this->write_c_string(" "); 1295 this->write_string(ii->init_name()); 1296 1297 // Populate init_idx. 1298 go_assert(init_idx.find(ii->init_name()) == init_idx.end()); 1299 unsigned idx = init_idx.size(); 1300 init_idx[ii->init_name()] = idx; 1301 1302 // If the init function has a non-negative priority value, this 1303 // is an indication that it was referred to in an older version 1304 // export data section (e.g. we read a legacy object 1305 // file). Record such init fcns so that we can fix up the graph 1306 // for them (handled later in this function). 1307 if (ii->priority() > 0) 1308 { 1309 level_map::iterator it = inits_at_level.find(ii->priority()); 1310 if (it == inits_at_level.end()) 1311 { 1312 std::vector<std::string> l; 1313 l.push_back(ii->init_name()); 1314 inits_at_level[ii->priority()] = l; 1315 } 1316 else 1317 it->second.push_back(ii->init_name()); 1318 } 1319 } 1320 this->write_c_string("\n"); 1321 1322 // Create the init graph. Start by populating the graph with 1323 // all the edges we inherited from imported packages. 1324 populate_init_graph(&init_graph, imported_init_fns, init_idx); 1325 1326 // Now add edges from the local init function to each of the 1327 // imported fcns. 1328 if (!import_init_fn.empty() && import_init_fn[0] != '~') 1329 { 1330 unsigned src = 0; 1331 go_assert(init_idx[import_init_fn] == 0); 1332 for (Import_init_set::const_iterator p = imported_init_fns.begin(); 1333 p != imported_init_fns.end(); 1334 ++p) 1335 { 1336 const Import_init* ii = *p; 1337 if (ii->is_dummy()) 1338 continue; 1339 unsigned sink = init_idx[ii->init_name()]; 1340 add_init_graph_edge(&init_graph, src, sink); 1341 } 1342 } 1343 1344 // In the scenario where one or more of the packages we imported 1345 // was written with the legacy export data format, add dummy edges 1346 // to capture the priority relationships. Here is a package import 1347 // graph as an example: 1348 // 1349 // *A 1350 // /| 1351 // / | 1352 // B *C 1353 // /| 1354 // / | 1355 // *D *E 1356 // | /| 1357 // |/ | 1358 // *F *G 1359 // 1360 // Let's suppose that the object for package "C" is from an old 1361 // gccgo, e.g. it has the old export data format. All other 1362 // packages are compiled with the new compiler and have the new 1363 // format. Packages with *'s have init functions. The scenario is 1364 // that we're compiling a package "A"; during this process we'll 1365 // read the export data for "C". It should look something like 1366 // 1367 // init F F..import 1 G G..import 1 D D..import 2 E E..import 2; 1368 // 1369 // To capture this information and convey it to the consumers of 1370 // "A", the code below adds edges to the graph from each priority K 1371 // function to every priority K-1 function for appropriate values 1372 // of K. This will potentially add more edges than we need (for 1373 // example, an edge from D to G), but given that we don't expect 1374 // to see large numbers of old objects, this will hopefully be OK. 1375 1376 if (inits_at_level.size() > 0) 1377 { 1378 for (level_map::reverse_iterator it = inits_at_level.rbegin(); 1379 it != inits_at_level.rend(); ++it) 1380 { 1381 int level = it->first; 1382 if (level < 2) break; 1383 const std::vector<std::string>& fcns_at_level = it->second; 1384 for (std::vector<std::string>::const_iterator sit = 1385 fcns_at_level.begin(); 1386 sit != fcns_at_level.end(); ++sit) 1387 { 1388 unsigned src = init_idx[*sit]; 1389 level_map::iterator it2 = inits_at_level.find(level - 1); 1390 if (it2 != inits_at_level.end()) 1391 { 1392 const std::vector<std::string> fcns_at_lm1 = it2->second; 1393 for (std::vector<std::string>::const_iterator mit = 1394 fcns_at_lm1.begin(); 1395 mit != fcns_at_lm1.end(); ++mit) 1396 { 1397 unsigned sink = init_idx[*mit]; 1398 add_init_graph_edge(&init_graph, src, sink); 1399 } 1400 } 1401 } 1402 } 1403 } 1404 1405 // Write out the resulting graph. 1406 this->write_c_string("init_graph"); 1407 for (Init_graph::const_iterator ki = init_graph.begin(); 1408 ki != init_graph.end(); ++ki) 1409 { 1410 unsigned src = ki->first; 1411 const std::set<unsigned>& successors = ki->second; 1412 for (std::set<unsigned>::const_iterator vi = successors.begin(); 1413 vi != successors.end(); ++vi) 1414 { 1415 this->write_c_string(" "); 1416 this->write_unsigned(src); 1417 unsigned sink = (*vi); 1418 this->write_c_string(" "); 1419 this->write_unsigned(sink); 1420 } 1421 } 1422 this->write_c_string("\n"); 1423 } 1424 1425 // Write the types to the export stream. 1426 1427 void 1428 Export::write_types(int unexported_type_index) 1429 { 1430 // Map from type index to type. 1431 std::vector<const Type*> types(static_cast<size_t>(this->type_index_)); 1432 for (Type_refs::const_iterator p = this->impl_->type_refs.begin(); 1433 p != this->impl_->type_refs.end(); 1434 ++p) 1435 { 1436 if (p->second >= 0) 1437 types.at(p->second) = p->first; 1438 } 1439 1440 // Write the type information to a buffer. 1441 Stream_to_string type_data; 1442 Export::Stream* orig_stream = this->stream_; 1443 this->stream_ = &type_data; 1444 1445 std::vector<size_t> type_sizes(static_cast<size_t>(this->type_index_)); 1446 type_sizes[0] = 0; 1447 1448 // Start at 1 because type index 0 is not used. 1449 size_t start_size = 0; 1450 for (int i = 1; i < this->type_index_; ++i) 1451 { 1452 this->write_type_definition(types[i], i); 1453 1454 size_t cur_size = type_data.string().size(); 1455 type_sizes[i] = cur_size - start_size; 1456 start_size = cur_size; 1457 } 1458 1459 // Back to original stream. 1460 this->stream_ = orig_stream; 1461 1462 // The line "types MAXP1 EXPORTEDP1 SIZES..." appears before the 1463 // types. MAXP1 is one more than the maximum type index used; that 1464 // is, it is the size of the array we need to allocate to hold all 1465 // the values. Indexes 1 up to but not including EXPORTEDP1 are the 1466 // exported types. The other types are not exported. SIZES... is a 1467 // list of MAXP1-1 entries listing the size of the type definition 1468 // for each type, starting at index 1. 1469 char buf[100]; 1470 snprintf(buf, sizeof buf, "types %d %d", this->type_index_, 1471 unexported_type_index); 1472 this->write_c_string(buf); 1473 1474 // Start at 1 because type index 0 is not used. 1475 for (int i = 1; i < this->type_index_; ++i) 1476 { 1477 snprintf(buf, sizeof buf, " %lu", 1478 static_cast<unsigned long>(type_sizes[i])); 1479 this->write_c_string(buf); 1480 } 1481 this->write_c_string("\n"); 1482 this->write_string(type_data.string()); 1483 } 1484 1485 // Write a single type to the export stream. 1486 1487 void 1488 Export::write_type_definition(const Type* type, int index) 1489 { 1490 this->write_c_string("type "); 1491 1492 char buf[30]; 1493 snprintf(buf, sizeof buf, "%d ", index); 1494 this->write_c_string(buf); 1495 1496 const Named_type* nt = type->named_type(); 1497 if (nt != NULL) 1498 { 1499 const Named_object* no = nt->named_object(); 1500 const Package* package = no->package(); 1501 1502 this->write_c_string("\""); 1503 if (package != NULL && !Gogo::is_hidden_name(no->name())) 1504 { 1505 this->write_string(package->pkgpath()); 1506 this->write_c_string("."); 1507 } 1508 this->write_string(nt->named_object()->name()); 1509 this->write_c_string("\" "); 1510 1511 if (!nt->in_heap()) 1512 this->write_c_string("notinheap "); 1513 1514 if (nt->is_alias()) 1515 this->write_c_string("= "); 1516 } 1517 1518 type->export_type(this); 1519 1520 // Type::export_type will print a newline for a named type, but not 1521 // otherwise. 1522 if (nt == NULL) 1523 this->write_c_string("\n"); 1524 } 1525 1526 // Write a name to the export stream. 1527 1528 void 1529 Export::write_name(const std::string& name) 1530 { 1531 if (name.empty()) 1532 this->write_c_string("?"); 1533 else 1534 this->write_string(Gogo::unpack_hidden_name(name)); 1535 } 1536 1537 // Write an integer value to the export stream. 1538 1539 void 1540 Export::write_int(int value) 1541 { 1542 char buf[100]; 1543 snprintf(buf, sizeof buf, "%d", value); 1544 this->write_c_string(buf); 1545 } 1546 1547 // Write an integer value to the export stream. 1548 1549 void 1550 Export::write_unsigned(unsigned value) 1551 { 1552 char buf[100]; 1553 snprintf(buf, sizeof buf, "%u", value); 1554 this->write_c_string(buf); 1555 } 1556 1557 // Return the index of a package. 1558 1559 int 1560 Export::package_index(const Package* pkg) const 1561 { 1562 Unordered_map(const Package *, int)::const_iterator p = 1563 this->packages_.find(pkg); 1564 go_assert(p != this->packages_.end()); 1565 int index = p->second; 1566 go_assert(index != 0); 1567 return index; 1568 } 1569 1570 // Return the index of the "unsafe" package. 1571 1572 int 1573 Export::unsafe_package_index() const 1574 { 1575 for (Unordered_map(const Package*, int)::const_iterator p = 1576 this->packages_.begin(); 1577 p != this->packages_.end(); 1578 ++p) 1579 { 1580 if (p->first->pkgpath() == "unsafe") 1581 { 1582 go_assert(p->second != 0); 1583 return p->second; 1584 } 1585 } 1586 go_unreachable(); 1587 } 1588 1589 // Return the index of a type. 1590 1591 int 1592 Export::type_index(const Type* type) 1593 { 1594 type = type->forwarded(); 1595 Type_refs::const_iterator p = this->impl_->type_refs.find(type); 1596 go_assert(p != this->impl_->type_refs.end()); 1597 int index = p->second; 1598 go_assert(index != 0); 1599 return index; 1600 } 1601 1602 // Export a type. 1603 1604 void 1605 Export::write_type(const Type* type) 1606 { 1607 int index = this->type_index(type); 1608 char buf[30]; 1609 snprintf(buf, sizeof buf, "<type %d>", index); 1610 this->write_c_string(buf); 1611 } 1612 1613 // Export a type to a function body. 1614 1615 void 1616 Export::write_type_to(const Type* type, Export_function_body* efb) 1617 { 1618 int index = this->type_index(type); 1619 char buf[30]; 1620 snprintf(buf, sizeof buf, "<type %d>", index); 1621 efb->write_c_string(buf); 1622 } 1623 1624 // Export escape note. 1625 1626 void 1627 Export::write_escape(std::string* note) 1628 { 1629 if (note != NULL && *note != "esc:0x0") 1630 { 1631 this->write_c_string(" "); 1632 char buf[50]; 1633 go_assert(note->find("esc:") != std::string::npos); 1634 snprintf(buf, sizeof buf, "<%s>", note->c_str()); 1635 this->write_c_string(buf); 1636 } 1637 } 1638 1639 // Add the builtin types to the export table. 1640 1641 void 1642 Export::register_builtin_types(Gogo* gogo) 1643 { 1644 this->register_builtin_type(gogo, "int8", BUILTIN_INT8); 1645 this->register_builtin_type(gogo, "int16", BUILTIN_INT16); 1646 this->register_builtin_type(gogo, "int32", BUILTIN_INT32); 1647 this->register_builtin_type(gogo, "int64", BUILTIN_INT64); 1648 this->register_builtin_type(gogo, "uint8", BUILTIN_UINT8); 1649 this->register_builtin_type(gogo, "uint16", BUILTIN_UINT16); 1650 this->register_builtin_type(gogo, "uint32", BUILTIN_UINT32); 1651 this->register_builtin_type(gogo, "uint64", BUILTIN_UINT64); 1652 this->register_builtin_type(gogo, "float32", BUILTIN_FLOAT32); 1653 this->register_builtin_type(gogo, "float64", BUILTIN_FLOAT64); 1654 this->register_builtin_type(gogo, "complex64", BUILTIN_COMPLEX64); 1655 this->register_builtin_type(gogo, "complex128", BUILTIN_COMPLEX128); 1656 this->register_builtin_type(gogo, "int", BUILTIN_INT); 1657 this->register_builtin_type(gogo, "uint", BUILTIN_UINT); 1658 this->register_builtin_type(gogo, "uintptr", BUILTIN_UINTPTR); 1659 this->register_builtin_type(gogo, "bool", BUILTIN_BOOL); 1660 this->register_builtin_type(gogo, "string", BUILTIN_STRING); 1661 this->register_builtin_type(gogo, "error", BUILTIN_ERROR); 1662 this->register_builtin_type(gogo, "byte", BUILTIN_BYTE); 1663 this->register_builtin_type(gogo, "rune", BUILTIN_RUNE); 1664 } 1665 1666 // Register one builtin type in the export table. 1667 1668 void 1669 Export::register_builtin_type(Gogo* gogo, const char* name, Builtin_code code) 1670 { 1671 Named_object* named_object = gogo->lookup_global(name); 1672 go_assert(named_object != NULL && named_object->is_type()); 1673 std::pair<Type_refs::iterator, bool> ins = 1674 this->impl_->type_refs.insert(std::make_pair(named_object->type_value(), code)); 1675 go_assert(ins.second); 1676 1677 // We also insert the underlying type. We can see the underlying 1678 // type at least for string and bool. It's OK if this insert 1679 // fails--we expect duplications here, and it doesn't matter when 1680 // they occur. 1681 Type* real_type = named_object->type_value()->real_type(); 1682 this->impl_->type_refs.insert(std::make_pair(real_type, code)); 1683 } 1684 1685 // Class Export::Stream. 1686 1687 Export::Stream::Stream() 1688 { 1689 this->sha1_helper_ = go_create_sha1_helper(); 1690 go_assert(this->sha1_helper_ != NULL); 1691 } 1692 1693 Export::Stream::~Stream() 1694 { 1695 } 1696 1697 // Write bytes to the stream. This keeps a checksum of bytes as they 1698 // go by. 1699 1700 void 1701 Export::Stream::write_and_sum_bytes(const char* bytes, size_t length) 1702 { 1703 this->sha1_helper_->process_bytes(bytes, length); 1704 this->do_write(bytes, length); 1705 } 1706 1707 // Get the checksum. 1708 1709 std::string 1710 Export::Stream::checksum() 1711 { 1712 std::string rval = this->sha1_helper_->finish(); 1713 delete this->sha1_helper_; 1714 return rval; 1715 } 1716 1717 // Write the checksum string to the export data. 1718 1719 void 1720 Export::Stream::write_checksum(const std::string& s) 1721 { 1722 this->do_write(s.data(), s.length()); 1723 } 1724 1725 // Class Stream_to_section. 1726 1727 Stream_to_section::Stream_to_section(Backend* backend) 1728 : backend_(backend) 1729 { 1730 } 1731 1732 // Write data to a section. 1733 1734 void 1735 Stream_to_section::do_write(const char* bytes, size_t length) 1736 { 1737 this->backend_->write_export_data (bytes, length); 1738 } 1739 1740 // Class Export_function_body. 1741 1742 // Record a temporary statement. 1743 1744 unsigned int 1745 Export_function_body::record_temporary(const Temporary_statement* temp) 1746 { 1747 unsigned int ret = this->next_temporary_index_; 1748 if (ret > 0x7fffffff) 1749 go_error_at(temp->location(), 1750 "too many temporary statements in export data"); 1751 ++this->next_temporary_index_; 1752 std::pair<const Temporary_statement*, unsigned int> val(temp, ret); 1753 std::pair<Unordered_map(const Temporary_statement*, unsigned int)::iterator, 1754 bool> ins = this->temporary_indexes_.insert(val); 1755 go_assert(ins.second); 1756 return ret; 1757 } 1758 1759 // Return the index of a temporary statement. 1760 1761 unsigned int 1762 Export_function_body::temporary_index(const Temporary_statement* temp) 1763 { 1764 Unordered_map(const Temporary_statement*, unsigned int)::const_iterator p = 1765 this->temporary_indexes_.find(temp); 1766 go_assert(p != this->temporary_indexes_.end()); 1767 return p->second; 1768 } 1769 1770 // Return the index of an unnamed label. If it doesn't already have 1771 // an index, give it one. 1772 1773 unsigned int 1774 Export_function_body::unnamed_label_index(const Unnamed_label* label) 1775 { 1776 unsigned int next = this->next_label_index_; 1777 std::pair<const Unnamed_label*, unsigned int> val(label, next); 1778 std::pair<Unordered_map(const Unnamed_label*, unsigned int)::iterator, 1779 bool> ins = 1780 this->label_indexes_.insert(val); 1781 if (!ins.second) 1782 return ins.first->second; 1783 else 1784 { 1785 if (next > 0x7fffffff) 1786 go_error_at(label->location(), 1787 "too many unnamed labels in export data"); 1788 ++this->next_label_index_; 1789 return next; 1790 } 1791 }