init
This commit is contained in:
commit
38355d2442
9083 changed files with 1225834 additions and 0 deletions
75
.venv/lib/python3.8/site-packages/mypyc/irbuild/vtable.py
Normal file
75
.venv/lib/python3.8/site-packages/mypyc/irbuild/vtable.py
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
"""Compute vtables of native (extension) classes."""
|
||||
|
||||
import itertools
|
||||
|
||||
from mypyc.ir.class_ir import ClassIR, VTableEntries, VTableMethod
|
||||
from mypyc.sametype import is_same_method_signature
|
||||
|
||||
|
||||
def compute_vtable(cls: ClassIR) -> None:
|
||||
"""Compute the vtable structure for a class."""
|
||||
if cls.vtable is not None:
|
||||
return
|
||||
|
||||
if not cls.is_generated:
|
||||
cls.has_dict = any(x.inherits_python for x in cls.mro)
|
||||
|
||||
for t in cls.mro[1:]:
|
||||
# Make sure all ancestors are processed first
|
||||
compute_vtable(t)
|
||||
# Merge attributes from traits into the class
|
||||
if not t.is_trait:
|
||||
continue
|
||||
for name, typ in t.attributes.items():
|
||||
if not cls.is_trait and not any(name in b.attributes for b in cls.base_mro):
|
||||
cls.attributes[name] = typ
|
||||
|
||||
cls.vtable = {}
|
||||
if cls.base:
|
||||
assert cls.base.vtable is not None
|
||||
cls.vtable.update(cls.base.vtable)
|
||||
cls.vtable_entries = specialize_parent_vtable(cls, cls.base)
|
||||
|
||||
# Include the vtable from the parent classes, but handle method overrides.
|
||||
entries = cls.vtable_entries
|
||||
|
||||
all_traits = [t for t in cls.mro if t.is_trait]
|
||||
|
||||
for t in [cls] + cls.traits:
|
||||
for fn in itertools.chain(t.methods.values()):
|
||||
# TODO: don't generate a new entry when we overload without changing the type
|
||||
if fn == cls.get_method(fn.name):
|
||||
cls.vtable[fn.name] = len(entries)
|
||||
# If the class contains a glue method referring to itself, that is a
|
||||
# shadow glue method to support interpreted subclasses.
|
||||
shadow = cls.glue_methods.get((cls, fn.name))
|
||||
entries.append(VTableMethod(t, fn.name, fn, shadow))
|
||||
|
||||
# Compute vtables for all of the traits that the class implements
|
||||
if not cls.is_trait:
|
||||
for trait in all_traits:
|
||||
compute_vtable(trait)
|
||||
cls.trait_vtables[trait] = specialize_parent_vtable(cls, trait)
|
||||
|
||||
|
||||
def specialize_parent_vtable(cls: ClassIR, parent: ClassIR) -> VTableEntries:
|
||||
"""Generate the part of a vtable corresponding to a parent class or trait"""
|
||||
updated = []
|
||||
for entry in parent.vtable_entries:
|
||||
# Find the original method corresponding to this vtable entry.
|
||||
# (This may not be the method in the entry, if it was overridden.)
|
||||
orig_parent_method = entry.cls.get_method(entry.name)
|
||||
assert orig_parent_method
|
||||
method_cls = cls.get_method_and_class(entry.name)
|
||||
if method_cls:
|
||||
child_method, defining_cls = method_cls
|
||||
# TODO: emit a wrapper for __init__ that raises or something
|
||||
if (is_same_method_signature(orig_parent_method.sig, child_method.sig)
|
||||
or orig_parent_method.name == '__init__'):
|
||||
entry = VTableMethod(entry.cls, entry.name, child_method, entry.shadow_method)
|
||||
else:
|
||||
entry = VTableMethod(entry.cls, entry.name,
|
||||
defining_cls.glue_methods[(entry.cls, entry.name)],
|
||||
entry.shadow_method)
|
||||
updated.append(entry)
|
||||
return updated
|
||||
Loading…
Add table
Add a link
Reference in a new issue