77#define PY_SSIZE_T_CLEAN
88#include < Python.h>
99
10+ // Python 3.13+ stack chunk minimum size (16KB)
11+ // This is the minimum size of a stack chunk from Python's implementation
12+ // https://github.com/python/cpython/blob/f6536d48cd294f3dea6a4ecfd8148aa505dbb581/Python/pystate.c#L1417
13+ #define _PY_DATA_STACK_CHUNK_SIZE (16 * 1024 )
14+
1015#include < exception>
1116#include < memory>
17+ #include < vector>
1218
1319#include < echion/vm.h>
1420
@@ -27,21 +33,19 @@ class StackChunkError : public std::exception
2733class StackChunk
2834{
2935public:
30- StackChunk () {}
36+ StackChunk ()
37+ {
38+ // Initialize with Python's minimum stack chunk size
39+ data_capacity = _PY_DATA_STACK_CHUNK_SIZE;
40+ data.resize (data_capacity);
41+ }
3142
3243 inline void update (_PyStackChunk* chunk_addr);
3344 inline void * resolve (void * frame_addr);
3445
3546private:
3647 void * origin = NULL ;
37- struct FreeDeleter
38- {
39- void operator ()(void * ptr) const
40- {
41- free (ptr);
42- }
43- };
44- std::unique_ptr<char [], FreeDeleter> data = nullptr ;
48+ std::vector<char > data;
4549 size_t data_capacity = 0 ;
4650 std::unique_ptr<StackChunk> previous = nullptr ;
4751};
@@ -58,18 +62,13 @@ void StackChunk::update(_PyStackChunk* chunk_addr)
5862 // if data_size is not enough, reallocate
5963 if (chunk.size > data_capacity)
6064 {
61- data_capacity = chunk.size ;
62- char * new_data = (char *)realloc (data.get (), data_capacity);
63- if (!new_data)
64- {
65- throw StackChunkError ();
66- }
67- data.release (); // Release the old pointer before resetting
68- data.reset (new_data);
65+ data_capacity =
66+ std::max (chunk.size , data_capacity); // Use max to maintain minimum capacity
67+ data.resize (data_capacity);
6968 }
7069
7170 // Copy the data up until the size of the chunk
72- if (copy_generic (chunk_addr, data.get (), chunk.size ))
71+ if (copy_generic (chunk_addr, data.data (), chunk.size ))
7372 throw StackChunkError ();
7473
7574 if (chunk.previous != NULL )
@@ -90,7 +89,7 @@ void StackChunk::update(_PyStackChunk* chunk_addr)
9089// ----------------------------------------------------------------------------
9190void * StackChunk::resolve (void * address)
9291{
93- _PyStackChunk* chunk = (_PyStackChunk*)data.get ();
92+ _PyStackChunk* chunk = (_PyStackChunk*)data.data ();
9493
9594 // Check if this chunk contains the address
9695 if (address >= origin && address < (char *)origin + chunk->size )
0 commit comments