1#ifndef GREENLET_STACK_STATE_CPP
2#define GREENLET_STACK_STATE_CPP
4#include "TGreenlet.hpp"
8#ifdef GREENLET_USE_STDIO
13std::ostream& operator<<(std::ostream& os,
const StackState& s)
15 os <<
"StackState(stack_start=" << (
void*)s._stack_start
16 <<
", stack_stop=" << (
void*)s.stack_stop
17 <<
", stack_copy=" << (
void*)s.stack_copy
18 <<
", stack_saved=" << s._stack_saved
19 <<
", stack_prev=" << s.stack_prev
27 : _stack_start(nullptr),
28 stack_stop((char*)mark),
32 stack_prev(current._stack_start
39 : _stack_start(nullptr),
50 : _stack_start(nullptr),
56 this->operator=(other);
59StackState& StackState::operator=(
const StackState& other)
64 if (other._stack_saved) {
65 throw std::runtime_error(
"Refusing to steal memory.");
69 this->free_stack_copy();
71 this->_stack_start = other._stack_start;
72 this->stack_stop = other.stack_stop;
73 this->stack_copy = other.stack_copy;
74 this->_stack_saved = other._stack_saved;
75 this->stack_prev = other.stack_prev;
79inline void StackState::free_stack_copy() noexcept
81 PyMem_Free(this->stack_copy);
82 this->stack_copy =
nullptr;
83 this->_stack_saved = 0;
86inline void StackState::copy_heap_to_stack(
const StackState& current)
noexcept
90 if (this->_stack_saved != 0) {
91 memcpy(this->_stack_start, this->stack_copy, this->_stack_saved);
92 this->free_stack_copy();
94 StackState* owner =
const_cast<StackState*
>(¤t);
95 if (!owner->_stack_start) {
96 owner = owner->stack_prev;
98 while (owner && owner->stack_stop <= this->stack_stop) {
100 owner = owner->stack_prev;
102 this->stack_prev = owner;
106inline int StackState::copy_stack_to_heap_up_to(
const char*
const stop)
noexcept
118 intptr_t sz1 = this->_stack_saved;
119 intptr_t sz2 = stop - this->_stack_start;
120 assert(this->_stack_start);
122 char* c = (
char*)PyMem_Realloc(this->stack_copy, sz2);
127 memcpy(c + sz1, this->_stack_start + sz1, sz2 - sz1);
128 this->stack_copy = c;
129 this->_stack_saved = sz2;
134inline int StackState::copy_stack_to_heap(
char*
const stackref,
135 const StackState& current)
noexcept
138 const char*
const target_stop = this->stack_stop;
140 StackState* owner =
const_cast<StackState*
>(¤t);
141 assert(owner->_stack_saved == 0);
142 if (!owner->_stack_start) {
143 owner = owner->stack_prev;
146 owner->_stack_start = stackref;
149 while (owner->stack_stop < target_stop) {
151 if (owner->copy_stack_to_heap_up_to(owner->stack_stop)) {
154 owner = owner->stack_prev;
157 if (owner->copy_stack_to_heap_up_to(target_stop)) {
164inline bool StackState::started() const noexcept
166 return this->stack_stop !=
nullptr;
169inline bool StackState::main() const noexcept
171 return this->stack_stop == (
char*)-1;
174inline bool StackState::active() const noexcept
176 return this->_stack_start !=
nullptr;
179inline void StackState::set_active() noexcept
181 assert(this->_stack_start ==
nullptr);
182 this->_stack_start = (
char*)1;
185inline void StackState::set_inactive() noexcept
187 this->_stack_start =
nullptr;
198 if (this->_stack_saved) {
199 this->free_stack_copy();
203inline intptr_t StackState::stack_saved() const noexcept
205 return this->_stack_saved;
208inline char* StackState::stack_start() const noexcept
210 return this->_stack_start;
214inline StackState StackState::make_main() noexcept
217 s._stack_start = (
char*)1;
218 s.stack_stop = (
char*)-1;
222StackState::~StackState()
224 if (this->_stack_saved != 0) {
225 this->free_stack_copy();
229void StackState::copy_from_stack(
void* vdest,
const void* vsrc,
size_t n)
const
231 char* dest =
static_cast<char*
>(vdest);
232 const char* src =
static_cast<const char*
>(vsrc);
233 if (src + n <= this->_stack_start
234 || src >= this->_stack_start + this->_stack_saved
235 || this->_stack_saved == 0) {
237 memcpy(dest, src, n);
241 if (src < this->_stack_start) {
244 const size_t nbefore = this->_stack_start - src;
245 memcpy(dest, src, nbefore);
252 size_t nspilled = std::min<size_t>(n, this->_stack_start + this->_stack_saved - src);
253 memcpy(dest, this->stack_copy + (src - this->_stack_start), nspilled);
259 memcpy(dest, src, n);
Definition TGreenlet.hpp:185
StackState()
Definition TStackState.cpp:38