| File: | out/../deps/v8/src/torque/instance-type-generator.cc |
| Warning: | line 240, column 5 Value stored to 'own_type_pending' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | // Copyright 2019 the V8 project authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "src/torque/implementation-visitor.h" |
| 6 | |
| 7 | namespace v8 { |
| 8 | namespace internal { |
| 9 | namespace torque { |
| 10 | |
| 11 | namespace { |
| 12 | |
| 13 | // Contains all necessary state for a single class type during the process of |
| 14 | // assigning instance types, and provides a convenient way to access the list of |
| 15 | // types that inherit from this one. |
| 16 | struct InstanceTypeTree { |
| 17 | explicit InstanceTypeTree(const ClassType* type) |
| 18 | : type(type), |
| 19 | start(INT_MAX2147483647), |
| 20 | end(INT_MIN(-2147483647 -1)), |
| 21 | value(-1), |
| 22 | num_values(0), |
| 23 | num_own_values(0) {} |
| 24 | const ClassType* type; |
| 25 | std::vector<std::unique_ptr<InstanceTypeTree>> children; |
| 26 | int start; // Start of range for this and subclasses, or INT_MAX. |
| 27 | int end; // End of range for this and subclasses, or INT_MIN. |
| 28 | int value; // Assigned value for this class itself, or -1 when unassigned. |
| 29 | int num_values; // Number of values assigned for this and subclasses. |
| 30 | int num_own_values; // How many values this needs (not including subclasses). |
| 31 | }; |
| 32 | |
| 33 | // Assembles all class types into a tree, but doesn't yet attempt to assign |
| 34 | // instance types for them. |
| 35 | std::unique_ptr<InstanceTypeTree> BuildInstanceTypeTree() { |
| 36 | // First, build InstanceTypeTree instances for every class but don't try to |
| 37 | // attach them to their subclasses yet. |
| 38 | std::unordered_map<const ClassType*, InstanceTypeTree*> map_by_type; |
| 39 | std::vector<std::unique_ptr<InstanceTypeTree>> unparented_types; |
| 40 | for (auto& p : GlobalContext::AllDeclarables()) { |
| 41 | if (const TypeAlias* alias = TypeAlias::DynamicCast(p.get())) { |
| 42 | const Type* type = alias->type(); |
| 43 | const ClassType* class_type = ClassType::DynamicCast(type); |
| 44 | if (class_type == nullptr) { |
| 45 | continue; |
| 46 | } |
| 47 | auto& map_slot = map_by_type[class_type]; |
| 48 | if (map_slot != nullptr) { |
| 49 | continue; // We already encountered this type. |
| 50 | } |
| 51 | std::unique_ptr<InstanceTypeTree> type_tree = |
| 52 | std::make_unique<InstanceTypeTree>(class_type); |
| 53 | map_slot = type_tree.get(); |
| 54 | unparented_types.push_back(std::move(type_tree)); |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | // Second, assemble them all into a tree following the inheritance hierarchy. |
| 59 | std::unique_ptr<InstanceTypeTree> root; |
| 60 | for (auto& type_tree : unparented_types) { |
| 61 | const ClassType* parent = type_tree->type->GetSuperClass(); |
| 62 | if (parent == nullptr) { |
| 63 | if (root != nullptr) |
| 64 | Error("Expected only one root class type. Found: ", root->type->name(), |
| 65 | " and ", type_tree->type->name()) |
| 66 | .Position(type_tree->type->GetPosition()); |
| 67 | root = std::move(type_tree); |
| 68 | } else { |
| 69 | map_by_type[parent]->children.push_back(std::move(type_tree)); |
| 70 | } |
| 71 | } |
| 72 | return root; |
| 73 | } |
| 74 | |
| 75 | // Propagates constraints about instance types from children to their parents. |
| 76 | void PropagateInstanceTypeConstraints(InstanceTypeTree* root) { |
| 77 | for (auto& child : root->children) { |
| 78 | PropagateInstanceTypeConstraints(child.get()); |
| 79 | if (child->start < root->start) root->start = child->start; |
| 80 | if (child->end > root->end) root->end = child->end; |
| 81 | root->num_values += child->num_values; |
| 82 | } |
| 83 | const InstanceTypeConstraints& constraints = |
| 84 | root->type->GetInstanceTypeConstraints(); |
| 85 | if (!root->type->IsAbstract() && !root->type->HasSameInstanceTypeAsParent()) { |
| 86 | root->num_own_values = 1; |
| 87 | } |
| 88 | root->num_values += root->num_own_values; |
| 89 | if (constraints.num_flags_bits != -1) { |
| 90 | // Children won't get any types assigned; must be done manually in C++. |
| 91 | root->children.clear(); |
| 92 | root->num_values = 1 << constraints.num_flags_bits; |
| 93 | root->num_own_values = root->num_values; |
| 94 | root->start = 0; |
| 95 | root->end = root->num_values - 1; |
| 96 | } |
| 97 | if (constraints.value != -1) { |
| 98 | if (root->num_own_values != 1) { |
| 99 | Error("Instance type value requested for abstract class ", |
| 100 | root->type->name()) |
| 101 | .Position(root->type->GetPosition()); |
| 102 | } |
| 103 | root->value = constraints.value; |
| 104 | if (constraints.value < root->start) root->start = constraints.value; |
| 105 | if (constraints.value > root->end) root->end = constraints.value; |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | // Assigns values for the type itself, not including any children. Returns the |
| 110 | // next available value. |
| 111 | int SelectOwnValues(InstanceTypeTree* root, int start_value) { |
| 112 | if (root->value == -1) { |
| 113 | root->value = start_value; |
| 114 | } else if (root->value < start_value) { |
| 115 | Error("Failed to assign instance type ", root->value, " to ", |
| 116 | root->type->name()) |
| 117 | .Position(root->type->GetPosition()); |
| 118 | } |
| 119 | return root->value + root->num_own_values; |
| 120 | } |
| 121 | |
| 122 | // Sorting function for types that don't have specific values they must include. |
| 123 | // Prioritizes bigger type ranges (those with more subtypes) first, and |
| 124 | // then sorts alphabetically within each size category. |
| 125 | struct CompareUnconstrainedTypes { |
| 126 | constexpr bool operator()(const InstanceTypeTree* a, |
| 127 | const InstanceTypeTree* b) const { |
| 128 | return (a->num_values > b->num_values) |
| 129 | ? true |
| 130 | : (a->num_values < b->num_values) |
| 131 | ? false |
| 132 | : std::less<std::string>()(a->type->name(), |
| 133 | b->type->name()); |
| 134 | } |
| 135 | }; |
| 136 | |
| 137 | // Assigns concrete values for every instance type range, and sorts the children |
| 138 | // at each layer of the tree into increasing order. Appends the newly-assigned |
| 139 | // tree to the destination vector. Returns the first unassigned value after |
| 140 | // those that have been used. |
| 141 | int SolveInstanceTypeConstraints( |
| 142 | std::unique_ptr<InstanceTypeTree> root, int start_value, |
| 143 | std::vector<std::unique_ptr<InstanceTypeTree>>* destination) { |
| 144 | if (root->start < start_value) { |
| 145 | Error("Failed to assign instance type ", root->start, " to ", |
| 146 | root->type->name()) |
| 147 | .Position(root->type->GetPosition()); |
| 148 | } |
| 149 | |
| 150 | // First, separate the children into four groups: |
| 151 | // - The one child that must go first, if it exists; |
| 152 | // - Children with specific value requirements ("constrained"); |
| 153 | // - Children without specific value requirements ("unconstrained"); |
| 154 | // - The one child that must go last, if it exists. |
| 155 | std::unique_ptr<InstanceTypeTree> lowest_child; |
| 156 | std::unique_ptr<InstanceTypeTree> highest_child; |
| 157 | std::multimap<int, std::unique_ptr<InstanceTypeTree>> |
| 158 | constrained_children_by_start; |
| 159 | // Using std::map because you can't std::move out of a std::set until C++17. |
| 160 | std::map<InstanceTypeTree*, std::unique_ptr<InstanceTypeTree>, |
| 161 | CompareUnconstrainedTypes> |
| 162 | unconstrained_children_by_size; |
| 163 | for (auto& child : root->children) { |
| 164 | if (child->type->IsHighestInstanceTypeWithinParent()) { |
| 165 | if (highest_child) { |
| 166 | Error("Two classes requested to be the highest instance type: ", |
| 167 | highest_child->type->name(), " and ", child->type->name(), |
| 168 | " within range for parent class ", root->type->name()) |
| 169 | .Position(child->type->GetPosition()); |
| 170 | } |
| 171 | if (child->type->IsLowestInstanceTypeWithinParent()) { |
| 172 | Error( |
| 173 | "Class requested to be both highest and lowest instance type " |
| 174 | "within its parent range: ", |
| 175 | child->type->name()) |
| 176 | .Position(child->type->GetPosition()); |
| 177 | } |
| 178 | highest_child = std::move(child); |
| 179 | } else if (child->type->IsLowestInstanceTypeWithinParent()) { |
| 180 | if (lowest_child) { |
| 181 | Error("Two classes requested to be the lowest instance type: ", |
| 182 | lowest_child->type->name(), " and ", child->type->name(), |
| 183 | " within range for parent class ", root->type->name()) |
| 184 | .Position(child->type->GetPosition()); |
| 185 | } |
| 186 | lowest_child = std::move(child); |
| 187 | } else if (child->start > child->end) { |
| 188 | unconstrained_children_by_size.insert( |
| 189 | std::make_pair(child.get(), std::move(child))); |
| 190 | } else { |
| 191 | constrained_children_by_start.insert( |
| 192 | std::make_pair(child->start, std::move(child))); |
| 193 | } |
| 194 | } |
| 195 | root->children.clear(); |
| 196 | |
| 197 | bool own_type_pending = root->num_own_values > 0; |
| 198 | |
| 199 | // Second, iterate and place the children in ascending order. |
| 200 | if (lowest_child != nullptr) { |
| 201 | start_value = SolveInstanceTypeConstraints(std::move(lowest_child), |
| 202 | start_value, &root->children); |
| 203 | } |
| 204 | for (auto& constrained_child_pair : constrained_children_by_start) { |
| 205 | // Select the next constrained child type in ascending order. |
| 206 | std::unique_ptr<InstanceTypeTree> constrained_child = |
| 207 | std::move(constrained_child_pair.second); |
| 208 | |
| 209 | // Try to place the root type before the constrained child type if it fits. |
| 210 | if (own_type_pending) { |
| 211 | if ((root->value != -1 && root->value < constrained_child->start) || |
| 212 | (root->value == -1 && |
| 213 | start_value + root->num_own_values <= constrained_child->start)) { |
| 214 | start_value = SelectOwnValues(root.get(), start_value); |
| 215 | own_type_pending = false; |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | // Try to find any unconstrained children that fit before the constrained |
| 220 | // one. This simple greedy algorithm just puts the biggest unconstrained |
| 221 | // children in first, which might not fill the space as efficiently as |
| 222 | // possible but is good enough for our needs. |
| 223 | for (auto it = unconstrained_children_by_size.begin(); |
| 224 | it != unconstrained_children_by_size.end();) { |
| 225 | if (it->second->num_values + start_value <= constrained_child->start) { |
| 226 | start_value = SolveInstanceTypeConstraints( |
| 227 | std::move(it->second), start_value, &root->children); |
| 228 | it = unconstrained_children_by_size.erase(it); |
| 229 | } else { |
| 230 | ++it; |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | // Place the constrained child type. |
| 235 | start_value = SolveInstanceTypeConstraints(std::move(constrained_child), |
| 236 | start_value, &root->children); |
| 237 | } |
| 238 | if (own_type_pending) { |
| 239 | start_value = SelectOwnValues(root.get(), start_value); |
| 240 | own_type_pending = false; |
Value stored to 'own_type_pending' is never read | |
| 241 | } |
| 242 | for (auto& child_pair : unconstrained_children_by_size) { |
| 243 | start_value = SolveInstanceTypeConstraints(std::move(child_pair.second), |
| 244 | start_value, &root->children); |
| 245 | } |
| 246 | if (highest_child != nullptr) { |
| 247 | start_value = SolveInstanceTypeConstraints(std::move(highest_child), |
| 248 | start_value, &root->children); |
| 249 | } |
| 250 | |
| 251 | // Finally, set the range for this class to include all placed subclasses. |
| 252 | root->end = start_value - 1; |
| 253 | root->start = |
| 254 | root->children.empty() ? start_value : root->children.front()->start; |
| 255 | if (root->value != -1 && root->value < root->start) { |
| 256 | root->start = root->value; |
| 257 | } |
| 258 | root->num_values = root->end - root->start + 1; |
| 259 | root->type->InitializeInstanceTypes( |
| 260 | root->value == -1 ? base::Optional<int>{} : root->value, |
| 261 | std::make_pair(root->start, root->end)); |
| 262 | |
| 263 | if (root->num_values > 0) { |
| 264 | destination->push_back(std::move(root)); |
| 265 | } |
| 266 | return start_value; |
| 267 | } |
| 268 | |
| 269 | std::unique_ptr<InstanceTypeTree> SolveInstanceTypeConstraints( |
| 270 | std::unique_ptr<InstanceTypeTree> root) { |
| 271 | std::vector<std::unique_ptr<InstanceTypeTree>> destination; |
| 272 | SolveInstanceTypeConstraints(std::move(root), 0, &destination); |
| 273 | return destination.empty() ? nullptr : std::move(destination.front()); |
| 274 | } |
| 275 | |
| 276 | std::unique_ptr<InstanceTypeTree> AssignInstanceTypes() { |
| 277 | std::unique_ptr<InstanceTypeTree> root = BuildInstanceTypeTree(); |
| 278 | if (root != nullptr) { |
| 279 | PropagateInstanceTypeConstraints(root.get()); |
| 280 | root = SolveInstanceTypeConstraints(std::move(root)); |
| 281 | } |
| 282 | return root; |
| 283 | } |
| 284 | |
| 285 | // Prints items in macro lists for the given type and its descendants. |
| 286 | // - definitions: This list is pairs of instance type name and assigned value, |
| 287 | // such as V(ODDBALL_TYPE, 67). It includes FIRST_* and LAST_* items for each |
| 288 | // type that has more than one associated InstanceType. Items within those |
| 289 | // ranges are indented for readability. |
| 290 | // - values: This list is just instance type names, like V(ODDBALL_TYPE). It |
| 291 | // does not include any FIRST_* and LAST_* range markers. |
| 292 | // - fully_defined_single_instance_types: This list is pairs of class name and |
| 293 | // instance type, for classes which have defined layouts and a single |
| 294 | // corresponding instance type. |
| 295 | // - fully_defined_multiple_instance_types: This list is pairs of class name and |
| 296 | // instance type, for classes which have defined layouts and subclasses. |
| 297 | // - only_declared_single_instance_types: This list is pairs of class name and |
| 298 | // instance type, for classes which have a single corresponding instance type |
| 299 | // and do not have layout definitions in Torque. |
| 300 | // - only_declared_multiple_instance_types: This list is pairs of class name and |
| 301 | // instance type, for classes which have subclasses but also have a single |
| 302 | // corresponding instance type, and do not have layout definitions in Torque. |
| 303 | // - fully_defined_range_instance_types: This list is triples of class name, |
| 304 | // first instance type, and last instance type, for classes which have defined |
| 305 | // layouts and multiple corresponding instance types. |
| 306 | // - only_declared_range_instance_types: This list is triples of class name, |
| 307 | // first instance type, and last instance type, for classes which have |
| 308 | // multiple corresponding instance types and do not have layout definitions in |
| 309 | // Torque. |
| 310 | void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions, |
| 311 | std::ostream& values, |
| 312 | std::ostream& fully_defined_single_instance_types, |
| 313 | std::ostream& fully_defined_multiple_instance_types, |
| 314 | std::ostream& only_declared_single_instance_types, |
| 315 | std::ostream& only_declared_multiple_instance_types, |
| 316 | std::ostream& fully_defined_range_instance_types, |
| 317 | std::ostream& only_declared_range_instance_types, |
| 318 | const std::string& indent) { |
| 319 | std::string type_name = |
| 320 | CapifyStringWithUnderscores(root->type->name()) + "_TYPE"; |
| 321 | std::string inner_indent = indent; |
| 322 | |
| 323 | if (root->num_values > 1) { |
| 324 | definitions << indent << "V(FIRST_" << type_name << ", " << root->start |
| 325 | << ") \\\n"; |
| 326 | inner_indent += " "; |
| 327 | } |
| 328 | if (root->num_own_values == 1) { |
| 329 | definitions << inner_indent << "V(" << type_name << ", " << root->value |
| 330 | << ") /* " << root->type->GetPosition() << " */\\\n"; |
| 331 | values << " V(" << type_name << ") /* " << root->type->GetPosition() |
| 332 | << " */\\\n"; |
| 333 | std::ostream& type_checker_list = |
| 334 | root->type->HasUndefinedLayout() |
| 335 | ? (root->num_values == 1 ? only_declared_single_instance_types |
| 336 | : only_declared_multiple_instance_types) |
| 337 | : (root->num_values == 1 ? fully_defined_single_instance_types |
| 338 | : fully_defined_multiple_instance_types); |
| 339 | type_checker_list << " V(" << root->type->name() << ", " << type_name |
| 340 | << ") /* " << root->type->GetPosition() << " */ \\\n"; |
| 341 | } |
| 342 | for (auto& child : root->children) { |
| 343 | PrintInstanceTypes(child.get(), definitions, values, |
| 344 | fully_defined_single_instance_types, |
| 345 | fully_defined_multiple_instance_types, |
| 346 | only_declared_single_instance_types, |
| 347 | only_declared_multiple_instance_types, |
| 348 | fully_defined_range_instance_types, |
| 349 | only_declared_range_instance_types, inner_indent); |
| 350 | } |
| 351 | if (root->num_values > 1) { |
| 352 | // We can't emit LAST_STRING_TYPE because it's not a valid flags |
| 353 | // combination. So if the class type has multiple own values, which only |
| 354 | // happens when using ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE, then omit |
| 355 | // the end marker. |
| 356 | if (root->num_own_values <= 1) { |
| 357 | definitions << indent << "V(LAST_" << type_name << ", " << root->end |
| 358 | << ") \\\n"; |
| 359 | } |
| 360 | |
| 361 | // Only output the instance type range for things other than the root type. |
| 362 | if (root->type->GetSuperClass() != nullptr) { |
| 363 | std::ostream& range_instance_types = |
| 364 | root->type->HasUndefinedLayout() ? only_declared_range_instance_types |
| 365 | : fully_defined_range_instance_types; |
| 366 | range_instance_types << " V(" << root->type->name() << ", FIRST_" |
| 367 | << type_name << ", LAST_" << type_name << ") \\\n"; |
| 368 | } |
| 369 | } |
| 370 | } |
| 371 | |
| 372 | } // namespace |
| 373 | |
| 374 | void ImplementationVisitor::GenerateInstanceTypes( |
| 375 | const std::string& output_directory) { |
| 376 | std::stringstream header; |
| 377 | std::string file_name = "instance-types.h"; |
| 378 | { |
| 379 | IncludeGuardScope guard(header, file_name); |
| 380 | |
| 381 | header << "// Instance types for all classes except for those that use " |
| 382 | "InstanceType as flags.\n"; |
| 383 | header << "#define TORQUE_ASSIGNED_INSTANCE_TYPES(V) \\\n"; |
| 384 | std::unique_ptr<InstanceTypeTree> instance_types = AssignInstanceTypes(); |
| 385 | std::stringstream values_list; |
| 386 | std::stringstream fully_defined_single_instance_types; |
| 387 | std::stringstream fully_defined_multiple_instance_types; |
| 388 | std::stringstream only_declared_single_instance_types; |
| 389 | std::stringstream only_declared_multiple_instance_types; |
| 390 | std::stringstream fully_defined_range_instance_types; |
| 391 | std::stringstream only_declared_range_instance_types; |
| 392 | if (instance_types != nullptr) { |
| 393 | PrintInstanceTypes(instance_types.get(), header, values_list, |
| 394 | fully_defined_single_instance_types, |
| 395 | fully_defined_multiple_instance_types, |
| 396 | only_declared_single_instance_types, |
| 397 | only_declared_multiple_instance_types, |
| 398 | fully_defined_range_instance_types, |
| 399 | only_declared_range_instance_types, " "); |
| 400 | } |
| 401 | header << "\n"; |
| 402 | |
| 403 | header << "// Instance types for all classes except for those that use\n"; |
| 404 | header << "// InstanceType as flags.\n"; |
| 405 | header << "#define TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(V) \\\n"; |
| 406 | header << values_list.str(); |
| 407 | header << "\n"; |
| 408 | |
| 409 | header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that have\n"; |
| 410 | header << "// full Torque definitions.\n"; |
| 411 | header << "#define TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(V) \\\n"; |
| 412 | header << fully_defined_single_instance_types.str(); |
| 413 | header << "\n"; |
| 414 | |
| 415 | header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that have\n"; |
| 416 | header << "// full Torque definitions and subclasses.\n"; |
| 417 | header << "#define TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(V) \\\n"; |
| 418 | header << fully_defined_multiple_instance_types.str(); |
| 419 | header << "\n"; |
| 420 | |
| 421 | header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that are\n"; |
| 422 | header << "// declared but not defined in Torque. These classes may\n"; |
| 423 | header << "// correspond with actual C++ classes, but they are not\n"; |
| 424 | header << "// guaranteed to.\n"; |
| 425 | header << "#define TORQUE_INSTANCE_CHECKERS_SINGLE_ONLY_DECLARED(V) \\\n"; |
| 426 | header << only_declared_single_instance_types.str(); |
| 427 | header << "\n"; |
| 428 | |
| 429 | header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that are\n"; |
| 430 | header << "// declared but not defined in Torque, and have subclasses.\n"; |
| 431 | header << "// These classes may correspond with actual C++ classes, but\n"; |
| 432 | header << "// they are not guaranteed to.\n"; |
| 433 | header << "#define TORQUE_INSTANCE_CHECKERS_MULTIPLE_ONLY_DECLARED(V) \\\n"; |
| 434 | header << only_declared_multiple_instance_types.str(); |
| 435 | header << "\n"; |
| 436 | |
| 437 | header << "// Triples of (ClassName, FIRST_TYPE, LAST_TYPE) for classes\n"; |
| 438 | header << "// that have full Torque definitions.\n"; |
| 439 | header << "#define TORQUE_INSTANCE_CHECKERS_RANGE_FULLY_DEFINED(V) \\\n"; |
| 440 | header << fully_defined_range_instance_types.str(); |
| 441 | header << "\n"; |
| 442 | |
| 443 | header << "// Triples of (ClassName, FIRST_TYPE, LAST_TYPE) for classes\n"; |
| 444 | header << "// that are declared but not defined in Torque. These classes\n"; |
| 445 | header << "// may correspond with actual C++ classes, but they are not\n"; |
| 446 | header << "// guaranteed to.\n"; |
| 447 | header << "#define TORQUE_INSTANCE_CHECKERS_RANGE_ONLY_DECLARED(V) \\\n"; |
| 448 | header << only_declared_range_instance_types.str(); |
| 449 | header << "\n"; |
| 450 | |
| 451 | std::stringstream torque_defined_class_list; |
| 452 | std::stringstream torque_defined_varsize_instance_type_list; |
| 453 | std::stringstream torque_defined_fixed_instance_type_list; |
| 454 | std::stringstream torque_defined_map_csa_list; |
| 455 | std::stringstream torque_defined_map_root_list; |
| 456 | |
| 457 | for (const ClassType* type : TypeOracle::GetClasses()) { |
| 458 | std::string upper_case_name = type->name(); |
| 459 | std::string lower_case_name = SnakeifyString(type->name()); |
| 460 | std::string instance_type_name = |
| 461 | CapifyStringWithUnderscores(type->name()) + "_TYPE"; |
| 462 | |
| 463 | if (!type->IsExtern()) { |
| 464 | torque_defined_class_list << " V(" << upper_case_name << ") \\\n"; |
| 465 | } |
| 466 | |
| 467 | if (type->ShouldGenerateUniqueMap()) { |
| 468 | torque_defined_map_csa_list << " V(_, " << upper_case_name << "Map, " |
| 469 | << lower_case_name << "_map, " |
| 470 | << upper_case_name << ") \\\n"; |
| 471 | torque_defined_map_root_list << " V(Map, " << lower_case_name |
| 472 | << "_map, " << upper_case_name |
| 473 | << "Map) \\\n"; |
| 474 | std::stringstream& list = |
| 475 | type->HasStaticSize() ? torque_defined_fixed_instance_type_list |
| 476 | : torque_defined_varsize_instance_type_list; |
| 477 | list << " V(" << instance_type_name << ", " << upper_case_name << ", " |
| 478 | << lower_case_name << ") \\\n"; |
| 479 | } |
| 480 | } |
| 481 | |
| 482 | header << "// Fully Torque-defined classes (both internal and exported).\n"; |
| 483 | header << "#define TORQUE_DEFINED_CLASS_LIST(V) \\\n"; |
| 484 | header << torque_defined_class_list.str(); |
| 485 | header << "\n"; |
| 486 | header << "#define TORQUE_DEFINED_VARSIZE_INSTANCE_TYPE_LIST(V) \\\n"; |
| 487 | header << torque_defined_varsize_instance_type_list.str(); |
| 488 | header << "\n"; |
| 489 | header << "#define TORQUE_DEFINED_FIXED_INSTANCE_TYPE_LIST(V) \\\n"; |
| 490 | header << torque_defined_fixed_instance_type_list.str(); |
| 491 | header << "\n"; |
| 492 | header << "#define TORQUE_DEFINED_INSTANCE_TYPE_LIST(V) \\\n"; |
| 493 | header << " TORQUE_DEFINED_VARSIZE_INSTANCE_TYPE_LIST(V) \\\n"; |
| 494 | header << " TORQUE_DEFINED_FIXED_INSTANCE_TYPE_LIST(V) \\\n"; |
| 495 | header << "\n"; |
| 496 | header << "#define TORQUE_DEFINED_MAP_CSA_LIST_GENERATOR(V, _) \\\n"; |
| 497 | header << torque_defined_map_csa_list.str(); |
| 498 | header << "\n"; |
| 499 | header << "#define TORQUE_DEFINED_MAP_ROOT_LIST(V) \\\n"; |
| 500 | header << torque_defined_map_root_list.str(); |
| 501 | header << "\n"; |
| 502 | } |
| 503 | std::string output_header_path = output_directory + "/" + file_name; |
| 504 | WriteFile(output_header_path, header.str()); |
| 505 | |
| 506 | GlobalContext::SetInstanceTypesInitialized(); |
| 507 | } |
| 508 | |
| 509 | } // namespace torque |
| 510 | } // namespace internal |
| 511 | } // namespace v8 |