MCPcopy Index your code
hub / github.com/python/mypy / generate_vtables

Function generate_vtables

mypyc/codegen/emitclass.py:471–554  ·  view source on GitHub ↗

Emit the vtables and vtable setup functions for a class. This includes both the primary vtable and any trait implementation vtables. The trait vtables go before the main vtable, and have the following layout: { CPyType_T1, // pointer to type object C_

(
    base: ClassIR, vtable_setup_name: str, vtable_name: str, emitter: Emitter, shadow: bool
)

Source from the content-addressed store, hash-verified

469
470
471def generate_vtables(
472 base: ClassIR, vtable_setup_name: str, vtable_name: str, emitter: Emitter, shadow: bool
473) -> str:
474 """Emit the vtables and vtable setup functions for a class.
475
476 This includes both the primary vtable and any trait implementation vtables.
477 The trait vtables go before the main vtable, and have the following layout:
478 {
479 CPyType_T1, // pointer to type object
480 C_T1_trait_vtable, // pointer to array of method pointers
481 C_T1_offset_table, // pointer to array of attribute offsets
482 CPyType_T2,
483 C_T2_trait_vtable,
484 C_T2_offset_table,
485 ...
486 }
487 The method implementations are calculated at the end of IR pass, attribute
488 offsets are {offsetof(native__C, _x1), offsetof(native__C, _y1), ...}.
489
490 To account for both dynamic loading and dynamic class creation,
491 vtables are populated dynamically at class creation time, so we
492 emit empty array definitions to store the vtables and a function to
493 populate them.
494
495 If shadow is True, generate "shadow vtables" that point to the
496 shadow glue methods (which should dispatch via the Python C-API).
497
498 Returns the expression to use to refer to the vtable, which might be
499 different than the name, if there are trait vtables.
500 """
501
502 def trait_vtable_name(trait: ClassIR) -> str:
503 return "{}_{}_trait_vtable{}".format(
504 base.name_prefix(emitter.names),
505 trait.name_prefix(emitter.names),
506 "_shadow" if shadow else "",
507 )
508
509 def trait_offset_table_name(trait: ClassIR) -> str:
510 return "{}_{}_offset_table".format(
511 base.name_prefix(emitter.names), trait.name_prefix(emitter.names)
512 )
513
514 # Emit array definitions with enough space for all the entries
515 emitter.emit_line(
516 "static CPyVTableItem {}[{}];".format(
517 vtable_name, max(1, len(base.vtable_entries) + 3 * len(base.trait_vtables))
518 )
519 )
520
521 for trait, vtable in base.trait_vtables.items():
522 # Trait methods entry (vtable index -> method implementation).
523 emitter.emit_line(
524 f"static CPyVTableItem {trait_vtable_name(trait)}[{max(1, len(vtable))}];"
525 )
526 # Trait attributes entry (attribute number in trait -> offset in actual struct).
527 emitter.emit_line(
528 "static size_t {}[{}];".format(

Callers 1

generate_classFunction · 0.85

Calls 10

maxFunction · 0.85
lenFunction · 0.85
trait_vtable_nameFunction · 0.85
trait_offset_table_nameFunction · 0.85
generate_vtableFunction · 0.85
generate_offset_tableFunction · 0.85
appendMethod · 0.80
emit_lineMethod · 0.45
formatMethod · 0.45
itemsMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…