Skip to content

Commit

Permalink
Refactor fieldRef to be compliant with the Liskov Substitution Principle
Browse files Browse the repository at this point in the history
  • Loading branch information
N3rdL0rd committed Nov 29, 2024
1 parent addd459 commit db48e0a
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 7 deletions.
15 changes: 11 additions & 4 deletions crashlink/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,17 @@ class fieldRef(ResolvableVarInt):
"""
Abstract class to represent a field index.
"""

def resolve(self, code: "Bytecode", obj: "Obj") -> "Field":
fields = obj.resolve_fields(code)
return fields[self.value]

obj: Optional["Obj"] = None

def resolve(self, code: "Bytecode") -> "Field":
if self.obj:
return self.obj.resolve_fields(code)[self.value]
raise ValueError("Cannot resolve field without context. Try setting `field.obj` to an instance of `Obj`, or use `field.resolve_obj(code, obj)` instead.")

def resolve_obj(self, code: "Bytecode", obj: "Obj") -> "Field":
self.obj = obj
return obj.resolve_fields(code)[self.value]


class Reg(ResolvableVarInt):
Expand Down
6 changes: 3 additions & 3 deletions crashlink/disasm.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def pseudo_from_op(
this = reg.resolve(code)
break
if this:
return f"reg{op.definition['dst']} = this.{op.definition['field'].resolve(code, this.definition).name.resolve(code)}"
return f"reg{op.definition['dst']} = this.{op.definition['field'].resolve_obj(code, this.definition).name.resolve(code)}"
return f"reg{op.definition['dst']} = this.f@{op.definition['field'].value} (this not found!)"
elif op.op == "Label":
return "label"
Expand Down Expand Up @@ -209,14 +209,14 @@ def pseudo_from_op(
elif op.op == "Field":
field = (
op.definition["field"]
.resolve(code, regs[op.definition["obj"].value].resolve(code).definition)
.resolve_obj(code, regs[op.definition["obj"].value].resolve(code).definition)
.name.resolve(code)
)
return f"reg{op.definition['dst']} = reg{op.definition['obj']}.{field}"
elif op.op == "SetField":
field = (
op.definition["field"]
.resolve(code, regs[op.definition["obj"].value].resolve(code).definition)
.resolve_obj(code, regs[op.definition["obj"].value].resolve(code).definition)
.name.resolve(code)
)
return f"reg{op.definition['obj']}.{field} = reg{op.definition['src']}"
Expand Down

0 comments on commit db48e0a

Please sign in to comment.