1
// ---------------------------------------------------------------------------
3
// - standard object library - object stack class implementation -
4
// ---------------------------------------------------------------------------
5
// - This program is free software; you can redistribute it and/or modify -
6
// - it provided that this copyright notice is kept intact. -
8
// - This program is distributed in the hope that it will be useful, but -
9
// - without any warranty; without even the implied warranty of -
10
// - merchantability or fitness for a particular purpose. In no event shall -
11
// - the copyright holder be liable for any direct, indirect, incidental or -
12
// - special damages arising in any way out of the use of this software. -
13
// ---------------------------------------------------------------------------
14
// - copyright (c) 1999-2007 amaury darsch -
15
// ---------------------------------------------------------------------------
18
#include "Integer.hpp"
19
#include "Exception.hpp"
24
// -------------------------------------------------------------------------
26
// -------------------------------------------------------------------------
28
// create a default stack
31
d_size = 8 * c_pagesize ();
32
p_base = (Object**) c_mmap (d_size * sizeof (Object*));
33
p_top = p_base + d_size - 1;
40
Stack::~Stack (void) {
42
c_munmap (p_base, d_size * sizeof (Object*));
45
// return the class name
47
String Stack::repr (void) const {
51
// make this stack a shared object
53
void Stack::mksho (void) {
54
if (p_shared != nilp) return;
57
while (ptr != p_base) {
59
if (obj != nilp) obj->mksho ();
63
// push an object on top of the stack
65
void Stack::push (Object* object) {
68
// check for stack overflow
69
if (p_sp >= p_top) resize (d_size * 2);
71
if ((p_shared != nilp) && (object != nilp)) object->mksho ();
73
*p_sp++ = Object::iref (object);
81
// pop an object from the stack
83
Object* Stack::pop (void) {
87
throw Exception ("stack-error","out of bound stack pop");
89
Object* result = *--p_sp;
90
if (p_fp > p_sp) p_fp = p_sp;
91
Object::tref (result);
100
// return true if the stack is empty
102
bool Stack::empty (void) const {
104
bool result = (p_sp == p_base);
109
// return the current stack pointer
111
Object** Stack::getsp (void) const {
113
Object** result = p_sp;
118
// return the current frame pointer
120
Object** Stack::getfp (void) const {
122
Object** result = p_fp;
127
// set the current frame pointer
129
void Stack::setfp (Object** fp) {
132
if ((p_sp < p_base) || (fp > p_sp)) {
133
throw Exception ("stack-error", "out of bound frame pointer");
143
// unwind the stack to it base pointer
145
void Stack::unwind (void) {
148
while (p_sp != p_base) Object::cref (pop ());
157
// unwind the stack by matching the fp
159
void Stack::unwind (Object** sp, Object** fp) {
162
while (p_sp != sp) Object::cref (pop ());
171
// return an argument by index in reference to the frame pointer
173
Object* Stack::get (const long index) const {
176
Object** ptr = p_fp + index;
178
throw Exception ("stack-exception", "out of bound stack access");
180
Object* result = *ptr;
189
// set a stack value by index
191
void Stack::set (const long index, Object* object) {
194
Object** ptr = p_fp + index;
196
throw Exception ("stack-exception", "out of bound stack access");
198
Object::iref (object);
208
// resize the stack by a certain amount
210
void Stack::resize (const long size) {
213
long spoff = (long) (p_sp - p_base);
214
long fpoff = (long) (p_fp - p_base);
215
p_base = (Object**) c_mremap (p_base, d_size * sizeof (Object*),
216
size * sizeof (Object*));
217
p_top = p_base + size - 1;
219
p_sp = p_base + spoff;
220
p_fp = p_base + fpoff;