This also removes the InternalPassAsPointer experiment. This also fixes that u8 values were stores as 32 bits in structs and tuples (but not dynamic arrays since that is special cased as bytes). Also, fixes allocation issue wi th dynamic arrays, it would allocate quadratic amount of memory.
63 lines
2.0 KiB
Python
63 lines
2.0 KiB
Python
from . import prelude
|
|
from .stdlib.types import TYPE_INFO_CONSTRUCTED, TYPE_INFO_MAP
|
|
from .type3.routers import NoRouteForTypeException, TypeApplicationRouter
|
|
from .type3.types import IntType3, Type3
|
|
|
|
|
|
def calculate_alloc_size_static_array(is_member: bool, args: tuple[Type3, IntType3]) -> int:
|
|
if is_member:
|
|
return TYPE_INFO_CONSTRUCTED.alloc_size
|
|
|
|
sa_type, sa_len = args
|
|
|
|
return sa_len.value * calculate_alloc_size(sa_type, is_member=True)
|
|
|
|
def calculate_alloc_size_tuple(is_member: bool, args: tuple[Type3, ...]) -> int:
|
|
if is_member:
|
|
return TYPE_INFO_CONSTRUCTED.alloc_size
|
|
|
|
return sum(
|
|
calculate_alloc_size(x, is_member=True)
|
|
for x in args
|
|
)
|
|
|
|
def calculate_alloc_size_struct(is_member: bool, args: tuple[tuple[str, Type3], ...]) -> int:
|
|
if is_member:
|
|
return TYPE_INFO_CONSTRUCTED.alloc_size
|
|
|
|
return sum(
|
|
calculate_alloc_size(x, is_member=True)
|
|
for _, x in args
|
|
)
|
|
|
|
ALLOC_SIZE_ROUTER = TypeApplicationRouter[bool, int]()
|
|
ALLOC_SIZE_ROUTER.add(prelude.static_array, calculate_alloc_size_static_array)
|
|
ALLOC_SIZE_ROUTER.add(prelude.struct, calculate_alloc_size_struct)
|
|
ALLOC_SIZE_ROUTER.add(prelude.tuple_, calculate_alloc_size_tuple)
|
|
|
|
def calculate_alloc_size(typ: Type3, is_member: bool = False) -> int:
|
|
typ_info = TYPE_INFO_MAP.get(typ.name)
|
|
if typ_info is not None:
|
|
return typ_info.alloc_size
|
|
|
|
try:
|
|
return ALLOC_SIZE_ROUTER(is_member, typ)
|
|
except NoRouteForTypeException:
|
|
if is_member:
|
|
# By default, 'boxed' or 'constructed' types are
|
|
# stored as pointers when a member of a struct or tuple
|
|
return TYPE_INFO_CONSTRUCTED.alloc_size
|
|
|
|
raise NotImplementedError(typ)
|
|
|
|
def calculate_member_offset(st_name: str, st_args: tuple[tuple[str, Type3], ...], needle: str) -> int:
|
|
result = 0
|
|
|
|
for memnam, memtyp in st_args:
|
|
if needle == memnam:
|
|
return result
|
|
|
|
result += calculate_alloc_size(memtyp, is_member=True)
|
|
|
|
raise Exception(f'{needle} not in {st_name}')
|