summaryrefslogtreecommitdiff
path: root/tools/libdol2asm/data/reference_array.py
diff options
context:
space:
mode:
authorJulgodis <>2021-03-28 22:49:05 +0200
committerJulgodis <>2021-03-28 22:49:05 +0200
commitd244b7cb0d961cb42f76cb30b57ab35820c3c48e (patch)
tree2bb9acf55c1e941d6ba6bfd8d751b19d569d7b6d /tools/libdol2asm/data/reference_array.py
parent88eb837a9cd134322324157d00d302e637a2a81c (diff)
dol2asm OK
Diffstat (limited to 'tools/libdol2asm/data/reference_array.py')
-rw-r--r--tools/libdol2asm/data/reference_array.py79
1 files changed, 79 insertions, 0 deletions
diff --git a/tools/libdol2asm/data/reference_array.py b/tools/libdol2asm/data/reference_array.py
new file mode 100644
index 0000000000..9fe9be37d0
--- /dev/null
+++ b/tools/libdol2asm/data/reference_array.py
@@ -0,0 +1,79 @@
+import struct
+
+from dataclasses import dataclass, field
+from typing import List, Tuple
+
+from ..builder import AsyncBuilder
+from ..globals import *
+from .. import util
+from .base import *
+from .identifier import *
+from .literal import *
+
+@dataclass(eq=False)
+class ReferenceArray(ArbitraryData):
+ @property
+ def element_size(self):
+ return 4
+
+ def array_type(self):
+ size = self.size // self.element_size
+ padding = self.padding // self.element_size
+
+ if size == 1 and padding == 0:
+ return self.element_type()
+ else:
+ return PaddingArrayType.create(
+ self.element_type(),
+ self.size // self.element_size,
+ self.padding // self.element_size)
+
+ def valid_reference(self, addr):
+ return addr % 4 == 0
+
+ def values(self):
+ return Integer.u32_from(self.data)
+ def gather_references(self, context, valid_range):
+ self.references = [ addr for addr in self.values() if addr in valid_range ]
+
+ def export_reference_value(self, symbol_table, index, addr) -> str:
+ symbol = symbol_table[-1, addr]
+ if symbol:
+ return symbol.cpp_reference(self, addr)
+ elif addr == 0:
+ return "NULL"
+ else:
+ return f"0x{addr:08X}"
+
+ async def export_declaration_body(self, exporter, builder: AsyncBuilder):
+ values = self.values()
+
+ if self.total_element_count == 1:
+ await builder.write(f" = (void*){self.export_reference_value(exporter.gst, 0, values[0])};")
+ else:
+ await builder.write(f" = {{")
+ for index, addr in enumerate(values):
+ value = self.export_reference_value(exporter.gst, index, addr)
+ await builder.write(f"\t(void*){value},")
+
+ if self.padding > 0:
+ await builder.write("\t/* padding */")
+ for i in range(self.padding // self.element_size):
+ await builder.write("\tNULL,")
+ await builder.write("};")
+
+
+ @staticmethod
+ def create(identifier: Identifier, addr: int, data: bytearray, padding_data: bytearray) -> "ReferenceArray":
+ assert sum(padding_data) == 0
+ assert len(data) % 4 == 0
+ assert len(padding_data) % 4 == 0
+ return ReferenceArray(
+ identifier=identifier,
+ data_type=PointerType(VOID),
+ addr=addr,
+ data = data,
+ size=len(data),
+ padding_data = padding_data,
+ padding = len(padding_data),
+ ) \ No newline at end of file