diff --git a/crashlink/core.py b/crashlink/core.py index 4129e3a..a844db6 100644 --- a/crashlink/core.py +++ b/crashlink/core.py @@ -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): diff --git a/crashlink/disasm.py b/crashlink/disasm.py index a805c76..e6ad1b7 100644 --- a/crashlink/disasm.py +++ b/crashlink/disasm.py @@ -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" @@ -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']}"