parent
5346b0127e
commit
6fbd197e57
@ -1,13 +1,64 @@
|
|||||||
#include <state.h>
|
#include <state.h>
|
||||||
#include "dev.h"
|
#include "dev.h"
|
||||||
|
|
||||||
void _sm_pop_stack(sm_state* state)
|
/// A generator that just returns `nullptr` (end). Used for yielding without calling in to another generator.
|
||||||
|
///
|
||||||
|
/// NOTE: To avoid uselessly creating a stack frame for calls to this generator, its address is (TODO) directly compared to when switching into a deeper generator, and then skipped entirely.
|
||||||
|
sm_yield _sm_noop(sm_state*)
|
||||||
{
|
{
|
||||||
TODO("Free the current stack frame in `state` and replace it with the previous one");
|
return (sm_yield)nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
sm_yield _sm_noop(sm_state*)
|
sm_state* sm_new()
|
||||||
{
|
{
|
||||||
return (sm_yield)nullptr;
|
auto state = box<sm_state>();
|
||||||
|
state->current = box<_sm_frame, true>();
|
||||||
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline static void sm_free_user(_sm_user* data)
|
||||||
|
{
|
||||||
|
if (data->free) {
|
||||||
|
free(data->_ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void _sm_free_page(_sm_user_page* page)
|
||||||
|
{
|
||||||
|
for (int i=0;i<_SM_STACK_SIZE;i++) sm_free_user(&page->data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static void _sm_free_all_pages(_sm_user_page* page)
|
||||||
|
{
|
||||||
|
while(page)
|
||||||
|
{
|
||||||
|
_sm_free_page(page);
|
||||||
|
auto old = page;
|
||||||
|
page = page->next;
|
||||||
|
free(old);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sm_free(sm_state* state)
|
||||||
|
{
|
||||||
|
_sm_frame* frame = unbox(state).current;
|
||||||
|
|
||||||
|
while(frame)
|
||||||
|
{
|
||||||
|
_sm_free_all_pages(frame->user.next);
|
||||||
|
_sm_free_page(&frame->user);
|
||||||
|
|
||||||
|
frame = unbox(frame).prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _sm_pop_stack(sm_state* state)
|
||||||
|
{
|
||||||
|
if(!state->current) return;
|
||||||
|
|
||||||
|
auto last = unbox(state->current);
|
||||||
|
state->current = last.prev;
|
||||||
|
|
||||||
|
_sm_free_all_pages(last.user.next);
|
||||||
|
_sm_free_page(&last.user);
|
||||||
|
}
|
||||||
|
Loading…
Reference in new issue