~ubuntu-branches/ubuntu/wily/afnix/wily

« back to all changes in this revision

Viewing changes to src/lib/std/shl/obj/Stack.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2011-03-16 21:31:18 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20110316213118-gk4k3ez3e5d2huna
Tags: 2.0.0-1
* QA upload.
* New upstream release
* Debian source format is 3.0 (quilt)
* Fix debhelper-but-no-misc-depends
* Fix ancient-standards-version
* Fix package-contains-linda-override
* debhelper compatibility is 7
* Fix dh-clean-k-is-deprecated

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// ---------------------------------------------------------------------------
2
 
// - Stack.cpp                                                               -
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.                  -
7
 
// -                                                                         -
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
 
// ---------------------------------------------------------------------------
16
 
 
17
 
#include "Stack.hpp"
18
 
#include "Integer.hpp"
19
 
#include "Exception.hpp"
20
 
#include "cmem.hpp"
21
 
 
22
 
namespace afnix {
23
 
  
24
 
  // -------------------------------------------------------------------------
25
 
  // - class section                                                         -
26
 
  // -------------------------------------------------------------------------
27
 
 
28
 
  // create a default stack
29
 
  
30
 
  Stack::Stack (void) {
31
 
    d_size = 8 * c_pagesize ();
32
 
    p_base = (Object**) c_mmap (d_size * sizeof (Object*));
33
 
    p_top  = p_base + d_size - 1;
34
 
    p_sp   = p_base;
35
 
    p_fp   = p_base;
36
 
  }
37
 
  
38
 
  // destroy this stack
39
 
 
40
 
  Stack::~Stack (void) {
41
 
    unwind ();
42
 
    c_munmap (p_base, d_size * sizeof (Object*));
43
 
  }
44
 
 
45
 
  // return the class name
46
 
 
47
 
  String Stack::repr (void) const {
48
 
    return "Stack";
49
 
  }
50
 
 
51
 
  // make this stack a shared object
52
 
  
53
 
  void Stack::mksho (void) {
54
 
     if (p_shared != nilp) return;
55
 
    Object::mksho ();
56
 
    Object** ptr= p_sp;
57
 
    while (ptr != p_base) {
58
 
      Object* obj = *--ptr;
59
 
      if (obj != nilp) obj->mksho ();
60
 
    }
61
 
  }
62
 
 
63
 
  // push an object on top of the stack
64
 
 
65
 
  void Stack::push (Object* object) {
66
 
    wrlock ();
67
 
    try {
68
 
      // check for stack overflow
69
 
      if (p_sp >= p_top) resize (d_size * 2);
70
 
      // check for shared
71
 
      if ((p_shared != nilp) && (object != nilp)) object->mksho ();
72
 
      // push the object
73
 
      *p_sp++ = Object::iref (object);
74
 
      unlock ();
75
 
    } catch (...) {
76
 
      unlock ();
77
 
      throw;
78
 
    }
79
 
  }
80
 
 
81
 
  // pop an object from the stack
82
 
 
83
 
  Object* Stack::pop (void) {
84
 
    wrlock ();
85
 
    try {
86
 
      if (p_sp == p_base) {
87
 
        throw Exception ("stack-error","out of bound stack pop");
88
 
      }
89
 
      Object* result = *--p_sp;
90
 
      if (p_fp > p_sp) p_fp = p_sp;
91
 
      Object::tref (result);
92
 
      unlock ();
93
 
      return result;
94
 
    } catch (...) {
95
 
      unlock ();
96
 
      throw;
97
 
    }
98
 
  }
99
 
 
100
 
  // return true if the stack is empty
101
 
 
102
 
  bool Stack::empty (void) const {
103
 
    rdlock ();
104
 
    bool result = (p_sp == p_base);
105
 
    unlock ();
106
 
    return result;
107
 
  }
108
 
 
109
 
  // return the current stack pointer
110
 
 
111
 
  Object** Stack::getsp (void) const {
112
 
    rdlock ();
113
 
    Object** result = p_sp;
114
 
    unlock ();
115
 
    return result;
116
 
  }
117
 
  
118
 
  // return the current frame pointer
119
 
 
120
 
  Object** Stack::getfp (void) const {
121
 
    rdlock ();
122
 
    Object** result = p_fp;
123
 
    unlock ();
124
 
    return result;
125
 
  }
126
 
  
127
 
  // set the current frame pointer
128
 
 
129
 
  void Stack::setfp (Object** fp) {
130
 
    wrlock ();
131
 
    try {
132
 
      if ((p_sp < p_base) || (fp > p_sp)) {
133
 
        throw Exception ("stack-error", "out of bound frame pointer");
134
 
      }
135
 
      p_fp = fp;
136
 
      unlock ();
137
 
    } catch (...) {
138
 
      unlock ();
139
 
      throw;
140
 
    }
141
 
  }
142
 
 
143
 
  // unwind the stack to it base pointer
144
 
 
145
 
  void Stack::unwind (void) {
146
 
    wrlock ();
147
 
    try {
148
 
      while (p_sp != p_base) Object::cref (pop ());
149
 
      p_fp = p_base;
150
 
      unlock ();
151
 
    } catch (...) {
152
 
      unlock ();
153
 
      throw;
154
 
    }
155
 
  }
156
 
 
157
 
  // unwind the stack by matching the fp
158
 
  
159
 
  void Stack::unwind (Object** sp, Object** fp) {
160
 
    wrlock ();
161
 
    try {
162
 
      while (p_sp != sp) Object::cref (pop ());
163
 
      p_fp = fp;
164
 
      unlock ();
165
 
    } catch (...) {
166
 
      unlock ();
167
 
      throw;
168
 
    }
169
 
  }
170
 
 
171
 
  // return an argument by index in reference to the frame pointer
172
 
 
173
 
  Object* Stack::get (const long index) const {
174
 
    rdlock ();
175
 
    try {
176
 
      Object** ptr = p_fp + index;
177
 
      if (ptr >= p_sp) {
178
 
        throw Exception ("stack-exception", "out of bound stack access");
179
 
      }
180
 
      Object* result = *ptr;
181
 
      unlock ();
182
 
      return result;
183
 
    } catch (...) {
184
 
      unlock ();
185
 
      throw;
186
 
    } 
187
 
  }
188
 
 
189
 
  // set a stack value by index
190
 
  
191
 
  void Stack::set (const long index, Object* object) {
192
 
    wrlock ();
193
 
    try {
194
 
      Object** ptr = p_fp + index;
195
 
      if (ptr >= p_sp) {
196
 
        throw Exception ("stack-exception", "out of bound stack access");
197
 
      }
198
 
      Object::iref (object);
199
 
      Object::dref (*ptr);
200
 
      *ptr = object;
201
 
      unlock ();
202
 
    } catch (...) {
203
 
      unlock ();
204
 
      throw;
205
 
    }
206
 
  }
207
 
 
208
 
  // resize the stack by a certain amount
209
 
 
210
 
  void Stack::resize (const long size) {
211
 
    wrlock ();
212
 
    try {
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;
218
 
      d_size = size;
219
 
      p_sp   = p_base + spoff;
220
 
      p_fp   = p_base + fpoff;
221
 
      unlock ();
222
 
    } catch (...) {
223
 
      unlock ();
224
 
      throw;
225
 
    }
226
 
  }
227
 
}