Cleanup: DataBlock as part of the constants

As they can refer to other constants which are stored in
memory.
This commit is contained in:
Johan B.W. de Vries 2023-11-10 15:02:07 +01:00
parent 1536ea0bbb
commit de92504394
3 changed files with 47 additions and 38 deletions

View File

@ -251,37 +251,46 @@ def expression(wgn: WasmGenerator, inp: ourlang.Expression) -> None:
if isinstance(inp.variable, ourlang.ModuleConstantDef): if isinstance(inp.variable, ourlang.ModuleConstantDef):
assert isinstance(inp.type3, type3types.Type3), type3types.TYPE3_ASSERTION_ERROR assert isinstance(inp.type3, type3types.Type3), type3types.TYPE3_ASSERTION_ERROR
if isinstance(inp.type3, type3types.PrimitiveType3):
expression(wgn, inp.variable.constant)
return
if inp.type3 is type3types.bytes: if inp.type3 is type3types.bytes:
assert inp.variable.data_block is not None, 'Bytes must be memory stored' assert isinstance(inp.variable.constant, ourlang.ConstantBytes)
assert inp.variable.data_block.address is not None, 'Value not allocated'
wgn.i32.const(inp.variable.data_block.address) address = inp.variable.constant.data_block.address
assert address is not None, 'Value not allocated'
wgn.i32.const(address)
return return
if isinstance(inp.type3, type3types.StructType3): if isinstance(inp.type3, type3types.StructType3):
assert inp.variable.data_block is not None, 'Structs must be memory stored' assert isinstance(inp.variable.constant, ourlang.ConstantStruct)
assert inp.variable.data_block.address is not None, 'Value not allocated'
wgn.i32.const(inp.variable.data_block.address) address = inp.variable.constant.data_block.address
assert address is not None, 'Value not allocated'
wgn.i32.const(address)
return return
if isinstance(inp.type3, type3types.AppliedType3): if isinstance(inp.type3, type3types.AppliedType3):
if inp.type3.base == type3types.static_array: if inp.type3.base == type3types.static_array:
assert inp.variable.data_block is not None, 'Static arrays must be memory stored' assert isinstance(inp.variable.constant, ourlang.ConstantTuple)
assert inp.variable.data_block.address is not None, 'Value not allocated'
wgn.i32.const(inp.variable.data_block.address) address = inp.variable.constant.data_block.address
assert address is not None, 'Value not allocated'
wgn.i32.const(address)
return return
if inp.type3.base == type3types.tuple: if inp.type3.base == type3types.tuple:
assert inp.variable.data_block is not None, 'Tuples must be memory stored' assert isinstance(inp.variable.constant, ourlang.ConstantTuple)
assert inp.variable.data_block.address is not None, 'Value not allocated'
wgn.i32.const(inp.variable.data_block.address) address = inp.variable.constant.data_block.address
assert address is not None, 'Value not allocated'
wgn.i32.const(address)
return return
raise NotImplementedError(expression, inp.variable, inp.type3.base) raise NotImplementedError(expression, inp.variable, inp.type3.base)
assert inp.variable.data_block is None, 'Primitives are not memory stored' raise NotImplementedError(expression, inp)
expression(wgn, inp.variable.constant)
return
raise NotImplementedError(expression, inp.variable) raise NotImplementedError(expression, inp.variable)

View File

@ -71,33 +71,43 @@ class ConstantTuple(Constant):
""" """
A Tuple constant value expression within a statement A Tuple constant value expression within a statement
""" """
__slots__ = ('value', ) __slots__ = ('value', 'data_block', )
value: List[Union[ConstantPrimitive, ConstantBytes]] value: List[Union[ConstantPrimitive, ConstantBytes]] # FIXME: Tuple of tuples?
data_block: 'ModuleDataBlock'
def __init__(self, value: List[Union[ConstantPrimitive, ConstantBytes]]) -> None: # FIXME: Tuple of tuples? def __init__(self, value: List[Union[ConstantPrimitive, ConstantBytes]], data_block: 'ModuleDataBlock') -> None:
super().__init__() super().__init__()
self.value = value self.value = value
self.data_block = data_block
def __repr__(self) -> str: def __repr__(self) -> str:
return f'ConstantTuple({repr(self.value)})' # Do not repr the whole ModuleDataBlock
# As this has a reference back to this constant for its data
# which it needs to compile the data into the program
return f'ConstantTuple({repr(self.value)}, @{repr(self.data_block.address)})'
class ConstantStruct(Constant): class ConstantStruct(Constant):
""" """
A Struct constant value expression within a statement A Struct constant value expression within a statement
""" """
__slots__ = ('struct_name', 'value', ) __slots__ = ('struct_name', 'value', 'data_block', )
struct_name: str struct_name: str
value: List[Union[ConstantPrimitive, ConstantBytes]] value: List[Union[ConstantPrimitive, ConstantBytes]] # FIXME: Struct of structs?
data_block: 'ModuleDataBlock'
def __init__(self, struct_name: str, value: List[Union[ConstantPrimitive, ConstantBytes]]) -> None: # FIXME: Struct of structs? def __init__(self, struct_name: str, value: List[Union[ConstantPrimitive, ConstantBytes]], data_block: 'ModuleDataBlock') -> None:
super().__init__() super().__init__()
self.struct_name = struct_name self.struct_name = struct_name
self.value = value self.value = value
self.data_block = data_block
def __repr__(self) -> str: def __repr__(self) -> str:
return f'ConstantStruct({repr(self.struct_name)}, {repr(self.value)})' # Do not repr the whole ModuleDataBlock
# As this has a reference back to this constant for its data
# which it needs to compile the data into the program
return f'ConstantStruct({repr(self.struct_name)}, {repr(self.value)}, @{repr(self.data_block.address)})'
class VariableReference(Expression): class VariableReference(Expression):
""" """
@ -347,20 +357,18 @@ class ModuleConstantDef:
""" """
A constant definition within a module A constant definition within a module
""" """
__slots__ = ('name', 'lineno', 'type3', 'constant', 'data_block', ) __slots__ = ('name', 'lineno', 'type3', 'constant', )
name: str name: str
lineno: int lineno: int
type3: Type3 type3: Type3
constant: Constant constant: Constant
data_block: Optional['ModuleDataBlock']
def __init__(self, name: str, lineno: int, type3: Type3, constant: Constant, data_block: Optional['ModuleDataBlock']) -> None: def __init__(self, name: str, lineno: int, type3: Type3, constant: Constant) -> None:
self.name = name self.name = name
self.lineno = lineno self.lineno = lineno
self.type3 = type3 self.type3 = type3
self.constant = constant self.constant = constant
self.data_block = data_block
class ModuleDataBlock: class ModuleDataBlock:
""" """

View File

@ -211,17 +211,11 @@ class OurVisitor:
value_data = self.visit_Module_Constant(module, node.value) value_data = self.visit_Module_Constant(module, node.value)
if isinstance(value_data, ConstantBytes):
data_block = value_data.data_block
else:
data_block = None
return ModuleConstantDef( return ModuleConstantDef(
node.target.id, node.target.id,
node.lineno, node.lineno,
type3, type3,
value_data, value_data,
data_block,
) )
if isinstance(node.value, ast.Tuple): if isinstance(node.value, ast.Tuple):
@ -242,8 +236,7 @@ class OurVisitor:
node.target.id, node.target.id,
node.lineno, node.lineno,
self.visit_type(module, node.annotation), self.visit_type(module, node.annotation),
ConstantTuple(tuple_data), ConstantTuple(tuple_data, data_block),
data_block,
) )
if isinstance(node.value, ast.Call): if isinstance(node.value, ast.Call):
@ -281,8 +274,7 @@ class OurVisitor:
node.target.id, node.target.id,
node.lineno, node.lineno,
self.visit_type(module, node.annotation), self.visit_type(module, node.annotation),
ConstantStruct(node.value.func.id, struct_data), ConstantStruct(node.value.func.id, struct_data, data_block),
data_block,
) )
raise NotImplementedError(f'{node} on Module AnnAssign') raise NotImplementedError(f'{node} on Module AnnAssign')