diff --git a/include/frame.h b/include/frame.h index 038ac0f..f7124a4 100644 --- a/include/frame.h +++ b/include/frame.h @@ -3,11 +3,15 @@ #include "box.h" #include -#define _SM_STACK_SIZE 256 +#define _SM_STACK_SIZE 15 + +#define _SM_KEY_SIZE (UINT64_MAX >> 2) struct _sm_user { - bool set ;//: 1; No need for these to be bitfield packed, there's an alignment hole here anyway. - bool free ;//: 1; + uint64_t set : 1; + uint64_t free : 1; + + uint64_t key : 62; union { uint8_t _8; diff --git a/include/state.h b/include/state.h index 7225b86..c398c1a 100644 --- a/include/state.h +++ b/include/state.h @@ -4,23 +4,51 @@ typedef void* (*sm_yield)(sm_state* state); //NOTE: This `void*` is a stand-in for this function returning itself. +inline uint64_t _sm_confine_key(uint64_t ui) +{ + return ui & _SM_KEY_SIZE; +} + +inline uint64_t _sm_compute_key(uint64_t name) +{ + return _sm_confine_key(name); +} + template -inline T* _sm_var(sm_state* state, U name, T init) +inline T* _sm_var(_sm_user_page* user, U name, T init) { - auto val = &state->current->user.data[name]; - bool set = val->set; + auto skey = name % _SM_STACK_SIZE; - val->set = true; - + auto val = &user->data[skey]; - return ( ! set ) ? - (val->free = false, _sm_init(val, init)) : - _sm_get(val); + auto key = _sm_compute_key( (uint64_t)name ); + + bool set = val->set; + + if(!set) { + val->set = true; + val->free = false; + val->key = key; + return _sm_init(val, init); + } + else if(key == val->key) { + //TODO: Check equality of value somehow + return _sm_get(val); + } else { + // Move to next page + if(!user->next) user->next = box<_sm_user_page, true>(); + return _sm_var(user->next, name, init); + } +} +template +inline T* _sm_var(sm_state* state, U name, T init) +{ + return _sm_var(&state->current->user, name, init); } template inline T* _sm_var(sm_state* state, T init) { - static_assert(name < _SM_STACK_SIZE, "Line pseudo-hashmap not yet implemented"); + //static_assert(name < _SM_STACK_SIZE, "Line pseudo-hashmap not yet implemented"); return _sm_var(state, name, init); }