Skip to content

Commit ef593c7

Browse files
committed
refact: do not emit LBound tables for statically accessed arrays
1 parent d12de69 commit ef593c7

5 files changed

Lines changed: 17 additions & 4 deletions

File tree

src/arch/z80/visitor/function_translator.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,16 @@ def visit_FUNCTION(self, node):
6161
if local_var.class_ == CLASS.array and local_var.scope == SCOPE.local:
6262
lbound_label = local_var.mangled + ".__LBOUND__"
6363
ubound_label = local_var.mangled + ".__UBOUND__"
64+
lbound_needed = not local_var.is_zero_based and local_var.is_dynamically_accessed
6465

65-
bound_ptrs = ["0" if local_var.is_zero_based else lbound_label, "0"]
66+
bound_ptrs = [lbound_label if lbound_needed else "0", "0"]
6667
if local_var.ubound_used:
6768
bound_ptrs[1] = ubound_label
6869

6970
if bound_ptrs != ["0", "0"]:
7071
OPTIONS["__DEFINES"].value["__ZXB_USE_LOCAL_ARRAY_WITH_BOUNDS__"] = ""
7172

72-
if not local_var.is_zero_based:
73+
if lbound_needed:
7374
l = ["%04X" % bound.lower for bound in local_var.bounds]
7475
bound_tables.append(LabelledData(lbound_label, l))
7576

src/arch/z80/visitor/var_translator.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def visit_ARRAYDECL(self, node):
4848
ubound_label = entry.mangled + ".__UBOUND__"
4949
bound_ptrs = ["0", "0"] # NULL by default
5050

51-
if not entry.is_zero_based:
51+
if not entry.is_zero_based and entry.is_dynamically_accessed:
5252
bound_ptrs[0] = lbound_label
5353

5454
if entry.ubound_used or OPTIONS.array_check:

src/lib/arch/zx48k/runtime/bound.asm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,10 @@ __CONT:
7070
ld h, (hl)
7171
ld l, a ; LD HL, (HL) => Origin of L/U Bound table
7272

73+
; for LBound only, HL = 0x0000 (NULL) if the array is all 0-based
74+
or h
75+
ret z ; Should never happen for UBound
76+
7377
add hl, de ; hl += OFFSET __LBOUND._xxxx
7478
ld e, (hl) ; de = (hl)
7579
inc hl

src/symbols/arrayaccess.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class SymbolARRAYACCESS(SymbolCALL):
3535
def __init__(self, entry, arglist: SymbolARGLIST, lineno: int, filename: str):
3636
super().__init__(entry, arglist, lineno, filename)
3737
assert all(gl.BOUND_TYPE == x.type_.type_ for x in arglist), "Invalid type for array index"
38+
self.entry.ref.is_dynamically_accessed = True
3839

3940
@property
4041
def entry(self):
@@ -90,6 +91,12 @@ def offset(self) -> int | None:
9091
offset *= self.type_.size
9192
return offset
9293

94+
@cached_property
95+
def is_constant(self) -> bool:
96+
"""Whether this array access is constant.
97+
e.g. A(1) is constant. A(i) is not."""
98+
return self.offset is None
99+
93100
@classmethod
94101
def make_node(cls, id_: str, arglist: SymbolARGLIST, lineno: int, filename: str) -> Optional["SymbolARRAYACCESS"]:
95102
"""Creates an array access. A(x1, x2, ..., xn)"""

src/symbols/id_/ref/arrayref.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99

1010
class ArrayRef(VarRef):
11-
__slots__ = "lbound_used", "ubound_used"
11+
__slots__ = "is_dynamically_accessed", "lbound_used", "ubound_used"
1212

1313
def __init__(self, parent: SymbolID, bounds: SymbolBOUNDLIST):
1414
super().__init__(parent)
@@ -19,6 +19,7 @@ def __init__(self, parent: SymbolID, bounds: SymbolBOUNDLIST):
1919
self.callable = True
2020
self.offset: str | None = None
2121
self.byref = False # Whether this array is passed by ref to a func
22+
self.is_dynamically_accessed: bool = False # Whether the array is accessed using variables at any moment
2223

2324
@property
2425
def token(self) -> str:

0 commit comments

Comments
 (0)