u3: refactors road stack api, limiting overflow checks

This commit is contained in:
Joe Bryan 2020-09-11 13:38:04 -07:00
parent 2af18a6659
commit b719a738f4
4 changed files with 128 additions and 78 deletions

View File

@ -168,6 +168,13 @@
u3a_flag_sand = 0x1, // bump allocation (XX not impl)
};
/* u3_pile: stack control, abstracted over road direction.
*/
typedef struct _u3a_pile {
u3_post top_p;
c3_ws mov_ws;
c3_ws off_ws;
} u3a_pile;
/** Macros. Should be better commented.
**/
@ -302,6 +309,35 @@
# define u3_Loom ((c3_w *)(void *)U3_OS_LoomBase)
/** inline functions.
**/
/** road stack.
**/
/* u3a_peek(): examine the top of the road stack
*/
inline void*
u3a_peek(u3a_pile* pil_u)
{
return u3to(void, (u3R->cap_p + pil_u->off_ws));
}
/* u3a_pop(): deallocate space on the road stack
*/
inline void
u3a_pop(u3a_pile* pil_u)
{
u3R->cap_p -= pil_u->mov_ws;
}
/* u3a_push(): allocate space on the road stack
*/
inline void*
u3a_push(u3a_pile* pil_u)
{
u3R->cap_p += pil_u->mov_ws;
return u3a_peek(pil_u);
}
/** Functions.
**/
/** Allocation.
@ -328,20 +364,20 @@
void*
u3a_wealloc(void* lag_v, c3_w len_w);
/* u3a_push(): allocate space on the road stack
*/
void*
u3a_push(c3_w len_w);
/* u3a_pop(): deallocate space on the road stack
/* u3a_pile_prep(): initialize stack control.
*/
void
u3a_pop(c3_w len_w);
u3a_pile_prep(u3a_pile* pil_u, c3_w len_w);
/* u3a_peek(): examine the top of the road stack
/* u3a_pile_sane(): bail on invalid road stack state.
*/
void*
u3a_peek(c3_w len_w);
void
u3a_pile_sane(u3a_pile* pil_u);
/* u3a_pile_done(): assert valid upon completion.
*/
void
u3a_pile_done(u3a_pile* pil_u);
/* C-style aligned allocation - *not* compatible with above.

View File

@ -10,28 +10,39 @@
u3_noun b)
{
u3_noun pro = u3k(u3x_at(u3x_sam_3, b));
if ( u3_nul != a ) {
u3a_pile pil_u;
u3j_site sit_u;
u3_noun* top;
u3_noun i, t = a;
u3_noun* top;
u3_noun i, t = a;
c3_w len_w = 0;
// push list onto road stack
u3a_pile_prep(&pil_u, sizeof(u3_noun));
// push list onto road stack
//
do {
u3x_cell(t, &i, &t);
top = (c3_w*) u3a_push(sizeof(u3_noun));
top = u3a_push(&pil_u);
*top = i;
++len_w;
} while ( u3_nul != t );
u3a_pile_sane(&pil_u);
u3j_gate_prep(&sit_u, u3k(b));
while ( len_w-- > 0 ) {
top = u3a_peek(sizeof(u3_noun));
u3a_pop(sizeof(u3_noun));
top = u3a_peek(&pil_u);
u3a_pop(&pil_u);
pro = u3j_gate_slam(&sit_u, u3nc(u3k(*top), pro));
}
u3j_gate_lose(&sit_u);
u3a_pile_done(&pil_u);
}
return pro;
}
u3_noun

View File

@ -930,9 +930,12 @@
// top: stack pointer
// len_w: number of result pairs on the stack
//
u3_noun p_wag, puq_wag, quq_wag;
u3_noun* top;
c3_w len_w = 0;
u3_noun p_wag, puq_wag, quq_wag;
u3_noun* top;
u3a_pile pil_u;
c3_w len_w = 0;
u3a_pile_prep(&pil_u, sizeof(u3_noun));
// push incremental, successful [fel] parse results onto road stack
//
@ -949,10 +952,10 @@
while ( u3_nul != q_vex ) {
u3x_trel(q_vex, 0, &puq_vex, &quq_vex);
top = u3a_push(sizeof(u3_noun));
top = u3a_push(&pil_u);
*top = u3k(puq_vex);
top = u3a_push(sizeof(u3_noun));
top = u3a_push(&pil_u);
*top = u3k(p_vex);
++len_w;
@ -972,6 +975,10 @@
u3j_gate_lose(&fel_u);
}
// check for stack overflow
//
u3a_pile_sane(&pil_u);
// unwind the stack, folding parse results into [wag] by way of [raq]
//
if ( len_w ) {
@ -980,13 +987,13 @@
u3j_gate_prep(&raq_u, u3k(raq));
while ( len_w-- > 0 ) {
top = u3a_peek(sizeof(u3_noun));
top = u3a_peek(&pil_u);
p_vex = *top;
u3a_pop(sizeof(u3_noun));
u3a_pop(&pil_u);
top = u3a_peek(sizeof(u3_noun));
top = u3a_peek(&pil_u);
puq_vex = *top;
u3a_pop(sizeof(u3_noun));
u3a_pop(&pil_u);
p_wag = _last_k(p_vex, p_wag);
puq_wag = u3j_gate_slam(&raq_u, u3nc(puq_vex, puq_wag));
@ -995,6 +1002,8 @@
u3j_gate_lose(&raq_u);
}
u3a_pile_done(&pil_u);
return u3nq(p_wag, u3_nul, puq_wag, quq_wag);
}

View File

@ -3,6 +3,15 @@
*/
#include "all.h"
// declarations of inline functions
//
void*
u3a_peek(u3a_pile* pil_u);
void
u3a_pop(u3a_pile* pil_u);
void*
u3a_push(u3a_pile* pil_u);
/* _box_count(): adjust memory count.
*/
#ifdef U3_CPU_DEBUG
@ -589,67 +598,52 @@ u3a_wealloc(void* lag_v, c3_w len_w)
}
}
}
/* u3a_push(): allocate space on the road stack
*/
void*
u3a_push(c3_w len_w)
{
void *cur, *top = u3to(void, u3R->cap_p);
if ( c3y == u3a_is_north(u3R) ) {
top -= len_w;
cur = top;
u3p(void) cap_p = u3R->cap_p = u3of(void, top);
if( !( cap_p < u3R->mat_p &&
cap_p > u3R->hat_p ) )
{
u3m_bail(c3__meme);
}
return cur;
}
else {
cur = top;
top += len_w;
u3R->cap_p = u3of(void, top);
u3p(void) cap_p = u3R->cap_p = u3of(void, top);
if( !( cap_p > u3R->mat_p &&
cap_p < u3R->hat_p ) )
{
u3m_bail(c3__meme);
}
return cur;
}
}
/* u3a_pop(): deallocate space on the road stack
/* u3a_pile_prep(): initialize stack control.
*/
void
u3a_pop(c3_w len_w)
u3a_pile_prep(u3a_pile* pil_u, c3_w len_w)
{
void* top = u3to(void, u3R->cap_p);
if ( c3y == u3a_is_north(u3R) ) {
top += len_w;
u3p(void) cap_p = u3R->cap_p = u3of(void, top);
c3_assert(cap_p <= u3R->mat_p);
c3_assert(cap_p > u3R->hat_p);
}
else {
top -= len_w;
u3p(void) cap_p = u3R->cap_p = u3of(void, top);
c3_assert(cap_p >= u3R->mat_p);
c3_assert(cap_p < u3R->hat_p);
}
// frame size, in words
//
c3_w wor_w = (len_w + 3) >> 2;
c3_o nor_o = u3a_is_north(u3R);
pil_u->top_p = u3R->cap_p;
pil_u->mov_ws = (c3y == nor_o) ? -wor_w : wor_w;
pil_u->off_ws = (c3y == nor_o) ? 0 : -wor_w;
}
/* u3a_peek(): examine the top of the road stack
/* u3a_pile_sane(): bail on invalid road stack state.
*/
void*
u3a_peek(c3_w len_w)
void
u3a_pile_sane(u3a_pile* pil_u)
{
return u3to(void, u3R->cap_p) - (c3y == u3a_is_north(u3R) ? 0 : len_w);
// !off means we're on a north road
//
if ( !pil_u->off_ws ) {
if( !(u3R->cap_p > u3R->hat_p) ) {
u3m_bail(c3__meme);
}
c3_assert( pil_u->top_p >= u3R->cap_p );
}
else {
if( !(u3R->cap_p < u3R->hat_p) ) {
u3m_bail(c3__meme);
}
c3_assert( pil_u->top_p <= u3R->cap_p );
}
// XX also stash road pointer in [pil_u] and assert same road?
//
}
/* u3a_pile_done(): assert valid upon completion.
*/
void
u3a_pile_done(u3a_pile* pil_u)
{
c3_assert( pil_u->top_p == u3R->cap_p );
}
/* u3a_wfree(): free storage.