66
77from __future__ import annotations
88
9+ from typing import TYPE_CHECKING
10+
911from libdestruct .common .field import Field
1012from libdestruct .common .obj import obj
1113
14+ if TYPE_CHECKING :
15+ from libdestruct .backing .resolver import Resolver
16+
1217
1318class ptr (obj ):
1419 """A pointer to an object in memory."""
1520
1621 size : int = 8
1722 """The size of a pointer in bytes."""
1823
19- def __init__ (self : ptr , memory : bytearray , address : int , wrapper : type | None = None ) -> None :
24+ def __init__ (self : ptr , resolver : Resolver , wrapper : type | None = None ) -> None :
2025 """Initialize a pointer.
2126
2227 Args:
23- memory: The backing memory view.
24- address: The address of the pointer in the memory view.
28+ resolver: The backing value resolver.
2529 wrapper: The object this pointer points to.
2630 """
27- super ().__init__ (memory , address )
31+ super ().__init__ (resolver )
2832 self .wrapper = wrapper
2933
3034 def get (self : ptr ) -> int :
3135 """Return the value of the pointer."""
32- return int .from_bytes (self .memory [self .address : self .address + self .size ], self .endianness )
36+ value = self .resolver .resolve (self .size , 0 )
37+ return int .from_bytes (value , self .endianness )
3338
3439 def to_bytes (self : obj ) -> bytes :
3540 """Return the serialized representation of the object."""
3641 if self ._frozen :
3742 return self ._frozen_value .to_bytes (self .size , self .endianness )
3843
39- return self .memory [ self . address : self .address + self . size ]
44+ return self .resolver . resolve ( self .size , 0 )
4045
4146 def _set (self : ptr , value : int ) -> None :
4247 """Set the value of the pointer to the given value."""
43- self .memory [ self . address : self .address + self . size ] = value .to_bytes (self .size , self .endianness )
48+ self .resolver . modify ( self .size , 0 , value .to_bytes (self .size , self .endianness ) )
4449
4550 def unwrap (self : ptr , length : int | None = None ) -> obj :
4651 """Return the object pointed to by the pointer.
@@ -54,12 +59,12 @@ def unwrap(self: ptr, length: int | None = None) -> obj:
5459 if length :
5560 raise ValueError ("Length is not supported when unwrapping a pointer to a wrapper object." )
5661
57- return self .wrapper (self .memory , address )
62+ return self .wrapper (self .resolver . absolute_from_own ( address ) )
5863
5964 if not length :
6065 length = 1
6166
62- return self .memory [ address : address + length ]
67+ return self .resolver . resolve ( length , 0 )
6368
6469 def try_unwrap (self : ptr , length : int | None = None ) -> obj | None :
6570 """Return the object pointed to by the pointer, if it is valid.
@@ -71,7 +76,7 @@ def try_unwrap(self: ptr, length: int | None = None) -> obj | None:
7176
7277 try :
7378 # If the address is invalid, this will raise an IndexError or ValueError.
74- self .memory [ address ]
79+ self .resolver . absolute_from_own ( address ). resolve ( length )
7580 except (IndexError , ValueError ):
7681 return None
7782
@@ -90,7 +95,6 @@ def to_str(self: ptr, indent: int = 0) -> str:
9095
9196 return f"{ ' ' * indent } { name } @0x{ self .get ():x} "
9297
93-
9498 def __str__ (self : ptr ) -> str :
9599 """Return a string representation of the pointer."""
96100 return self .to_str ()
0 commit comments