hammer util: avoid running concurrent cleanups
[dragonfly.git] / sys / boot / ficl / stack.c
blobe2204e6fd7c3fb3c78d08459686f1a7c79cad089
1 /*******************************************************************
2 ** s t a c k . c
3 ** Forth Inspired Command Language
4 ** Author: John Sadler (john_sadler@alum.mit.edu)
5 ** Created: 16 Oct 1997
6 ** $Id: stack.c,v 1.10 2001/12/05 07:21:34 jsadler Exp $
7 *******************************************************************/
8 /*
9 ** Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
10 ** All rights reserved.
12 ** Get the latest Ficl release at http://ficl.sourceforge.net
14 ** I am interested in hearing from anyone who uses ficl. If you have
15 ** a problem, a success story, a defect, an enhancement request, or
16 ** if you would like to contribute to the ficl release, please
17 ** contact me by email at the address above.
19 ** L I C E N S E and D I S C L A I M E R
20 **
21 ** Redistribution and use in source and binary forms, with or without
22 ** modification, are permitted provided that the following conditions
23 ** are met:
24 ** 1. Redistributions of source code must retain the above copyright
25 ** notice, this list of conditions and the following disclaimer.
26 ** 2. Redistributions in binary form must reproduce the above copyright
27 ** notice, this list of conditions and the following disclaimer in the
28 ** documentation and/or other materials provided with the distribution.
30 ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
31 ** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
32 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 ** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
34 ** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
35 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
36 ** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 ** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
38 ** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
39 ** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
40 ** SUCH DAMAGE.
44 * $FreeBSD: src/sys/boot/ficl/stack.c,v 1.5 2002/04/09 17:45:11 dcs Exp $
45 * $DragonFly: src/sys/boot/ficl/stack.c,v 1.3 2003/11/10 06:08:33 dillon Exp $
48 #ifdef TESTMAIN
49 #include <stdlib.h>
50 #else
51 #include <stand.h>
52 #endif
53 #include "ficl.h"
55 #define STKDEPTH(s) ((s)->sp - (s)->base)
58 ** N O T E: Stack convention:
60 ** sp points to the first available cell
61 ** push: store value at sp, increment sp
62 ** pop: decrement sp, fetch value at sp
63 ** Stack grows from low to high memory
66 /*******************************************************************
67 v m C h e c k S t a c k
68 ** Check the parameter stack for underflow or overflow.
69 ** nCells controls the type of check: if nCells is zero,
70 ** the function checks the stack state for underflow and overflow.
71 ** If nCells > 0, checks to see that the stack has room to push
72 ** that many cells. If less than zero, checks to see that the
73 ** stack has room to pop that many cells. If any test fails,
74 ** the function throws (via vmThrow) a VM_ERREXIT exception.
75 *******************************************************************/
76 void vmCheckStack(FICL_VM *pVM, int popCells, int pushCells)
78 FICL_STACK *pStack = pVM->pStack;
79 int nFree = pStack->base + pStack->nCells - pStack->sp;
81 if (popCells > STKDEPTH(pStack))
83 vmThrowErr(pVM, "Error: stack underflow");
86 if (nFree < pushCells - popCells)
88 vmThrowErr(pVM, "Error: stack overflow");
91 return;
94 #if FICL_WANT_FLOAT
95 void vmCheckFStack(FICL_VM *pVM, int popCells, int pushCells)
97 FICL_STACK *fStack = pVM->fStack;
98 int nFree = fStack->base + fStack->nCells - fStack->sp;
100 if (popCells > STKDEPTH(fStack))
102 vmThrowErr(pVM, "Error: float stack underflow");
105 if (nFree < pushCells - popCells)
107 vmThrowErr(pVM, "Error: float stack overflow");
110 #endif
112 /*******************************************************************
113 s t a c k C r e a t e
115 *******************************************************************/
117 FICL_STACK *stackCreate(unsigned nCells)
119 size_t size = sizeof (FICL_STACK) + nCells * sizeof (CELL);
120 FICL_STACK *pStack = ficlMalloc(size);
122 #if FICL_ROBUST
123 assert (nCells != 0);
124 assert (pStack != NULL);
125 #endif
127 pStack->nCells = nCells;
128 pStack->sp = pStack->base;
129 pStack->pFrame = NULL;
130 return pStack;
134 /*******************************************************************
135 s t a c k D e l e t e
137 *******************************************************************/
139 void stackDelete(FICL_STACK *pStack)
141 if (pStack)
142 ficlFree(pStack);
143 return;
147 /*******************************************************************
148 s t a c k D e p t h
150 *******************************************************************/
152 int stackDepth(FICL_STACK *pStack)
154 return STKDEPTH(pStack);
157 /*******************************************************************
158 s t a c k D r o p
160 *******************************************************************/
162 void stackDrop(FICL_STACK *pStack, int n)
164 #if FICL_ROBUST
165 assert(n > 0);
166 #endif
167 pStack->sp -= n;
168 return;
172 /*******************************************************************
173 s t a c k F e t c h
175 *******************************************************************/
177 CELL stackFetch(FICL_STACK *pStack, int n)
179 return pStack->sp[-n-1];
182 void stackStore(FICL_STACK *pStack, int n, CELL c)
184 pStack->sp[-n-1] = c;
185 return;
189 /*******************************************************************
190 s t a c k G e t T o p
192 *******************************************************************/
194 CELL stackGetTop(FICL_STACK *pStack)
196 return pStack->sp[-1];
200 /*******************************************************************
201 s t a c k L i n k
202 ** Link a frame using the stack's frame pointer. Allot space for
203 ** nCells cells in the frame
204 ** 1) Push pFrame
205 ** 2) pFrame = sp
206 ** 3) sp += nCells
207 *******************************************************************/
209 void stackLink(FICL_STACK *pStack, int nCells)
211 stackPushPtr(pStack, pStack->pFrame);
212 pStack->pFrame = pStack->sp;
213 pStack->sp += nCells;
214 return;
218 /*******************************************************************
219 s t a c k U n l i n k
220 ** Unink a stack frame previously created by stackLink
221 ** 1) sp = pFrame
222 ** 2) pFrame = pop()
223 *******************************************************************/
225 void stackUnlink(FICL_STACK *pStack)
227 pStack->sp = pStack->pFrame;
228 pStack->pFrame = stackPopPtr(pStack);
229 return;
233 /*******************************************************************
234 s t a c k P i c k
236 *******************************************************************/
238 void stackPick(FICL_STACK *pStack, int n)
240 stackPush(pStack, stackFetch(pStack, n));
241 return;
245 /*******************************************************************
246 s t a c k P o p
248 *******************************************************************/
250 CELL stackPop(FICL_STACK *pStack)
252 return *--pStack->sp;
255 void *stackPopPtr(FICL_STACK *pStack)
257 return (*--pStack->sp).p;
260 FICL_UNS stackPopUNS(FICL_STACK *pStack)
262 return (*--pStack->sp).u;
265 FICL_INT stackPopINT(FICL_STACK *pStack)
267 return (*--pStack->sp).i;
270 #if (FICL_WANT_FLOAT)
271 float stackPopFloat(FICL_STACK *pStack)
273 return (*(--pStack->sp)).f;
275 #endif
277 /*******************************************************************
278 s t a c k P u s h
280 *******************************************************************/
282 void stackPush(FICL_STACK *pStack, CELL c)
284 *pStack->sp++ = c;
287 void stackPushPtr(FICL_STACK *pStack, void *ptr)
289 *pStack->sp++ = LVALUEtoCELL(ptr);
292 void stackPushUNS(FICL_STACK *pStack, FICL_UNS u)
294 *pStack->sp++ = LVALUEtoCELL(u);
297 void stackPushINT(FICL_STACK *pStack, FICL_INT i)
299 *pStack->sp++ = LVALUEtoCELL(i);
302 #if (FICL_WANT_FLOAT)
303 void stackPushFloat(FICL_STACK *pStack, FICL_FLOAT f)
305 *pStack->sp++ = LVALUEtoCELL(f);
307 #endif
309 /*******************************************************************
310 s t a c k R e s e t
312 *******************************************************************/
314 void stackReset(FICL_STACK *pStack)
316 pStack->sp = pStack->base;
317 return;
321 /*******************************************************************
322 s t a c k R o l l
323 ** Roll nth stack entry to the top (counting from zero), if n is
324 ** >= 0. Drop other entries as needed to fill the hole.
325 ** If n < 0, roll top-of-stack to nth entry, pushing others
326 ** upward as needed to fill the hole.
327 *******************************************************************/
329 void stackRoll(FICL_STACK *pStack, int n)
331 CELL c;
332 CELL *pCell;
334 if (n == 0)
335 return;
336 else if (n > 0)
338 pCell = pStack->sp - n - 1;
339 c = *pCell;
341 for (;n > 0; --n, pCell++)
343 *pCell = pCell[1];
346 *pCell = c;
348 else
350 pCell = pStack->sp - 1;
351 c = *pCell;
353 for (; n < 0; ++n, pCell--)
355 *pCell = pCell[-1];
358 *pCell = c;
360 return;
364 /*******************************************************************
365 s t a c k S e t T o p
367 *******************************************************************/
369 void stackSetTop(FICL_STACK *pStack, CELL c)
371 pStack->sp[-1] = c;
372 return;