Website Summary Files Commits Branches @commit @diff @stats
path: root / spasm / src / frames.cpp
diff options
context:
space:
mode:
Commitc3252e63c296d1133254f4973fe7e3bf52cc6c1a (patch)
Author
 Dimitar Trendafilov <dimitar@coherent-labs.com>
2018-11-05 23:34:00 +0200
Committer
 Dimitar Trendafilov <dimitar@coherent-labs.com>
2018-11-05 23:34:00 +0200
Files67c6bfc067696562aded70f66d25899f3f70a1c8 /spasm/src/frames.cpp
IPL-c3252e63c296d1133254f4973fe7e3bf52cc6c1a.tar
IPL-c3252e63c296d1133254f4973fe7e3bf52cc6c1a.tar.gz
IPL-c3252e63c296d1133254f4973fe7e3bf52cc6c1a.zip
Parentc9912fdb174e1580629e00cacab6bc4ed480e643 (diff)
Parent6e19bb560d474736d45f5be011ff0830c7019991 (diff)
Merge commit '6e19bb560d474736d45f5be011ff0830c7019991' as 'spasm'
1 files changed, 130 insertions, 0 deletions
-rw-r--r--spasm/src/frames.cpp130
diff --git a/spasm/src/frames.cpp b/spasm/src/frames.cpp
new file mode 100644
index 0000000..8b7c891
--- /dev/null
+++ b/spasm/src/frames.cpp
@@ -0,0 +1,130 @@
+#include <algorithm>
+
+#include "types.hpp"
+
+#include "frames.hpp"
+
+namespace SpasmImpl
+{
+FrameStack::FrameStack() : base_ptr(NULL), frame_ptr(NULL), g_size(0), c_size(0)
+{
+}
+
+FrameStack::FrameStack(const FrameStack& fs)
+ : g_size(fs.g_size), c_size(fs.c_size), fstack(fs.fstack)
+{
+ copy_fstack(fs);
+}
+
+FrameStack::~FrameStack()
+{
+ delete_fstack();
+}
+
+FrameStack& FrameStack::operator=(const FrameStack& fs)
+{
+ if (this != &fs)
+ {
+ delete_fstack();
+ copy_fstack(fs);
+ g_size = fs.g_size;
+ c_size = fs.c_size;
+ fstack = fs.fstack;
+ }
+ return *this;
+}
+
+/*!
+** Deletes the frame stack
+*/
+void FrameStack::delete_fstack()
+{
+ if (base_ptr)
+ delete[] base_ptr;
+}
+
+/*!
+** Copies the frame stack fs
+**
+** \param fs - the frame stack to be copied
+*/
+void FrameStack::copy_fstack(const FrameStack& fs)
+{
+ base_ptr = new data_t[fs.g_size];
+ std::copy(fs.base_ptr, fs.frame_ptr + fs.c_size, base_ptr);
+ frame_ptr = base_ptr + (fs.frame_ptr - fs.base_ptr);
+}
+
+/*!
+** Returns a data_t object from the current frame
+**
+** \param index - index of the data_t object
+** \return const reference to the object
+*/
+const data_t& FrameStack::operator[](size_t index) const
+{
+ return frame_ptr[index];
+}
+
+/*!
+** Returns a data_t object from the current frame
+**
+** \param index - index of the data_t object
+** \return reference to the object
+*/
+data_t& FrameStack::operator[](size_t index)
+{
+ return frame_ptr[index];
+}
+
+/*!
+** Removes the current frame from the stack.
+** It is called when a function does return.
+*/
+void FrameStack::pop_frame()
+{
+ if (fstack.empty())
+ {
+ frame_ptr = base_ptr;
+ c_size = 0;
+ }
+ else
+ {
+ data_t* new_frame_ptr = base_ptr + fstack.top();
+ fstack.pop();
+ c_size = frame_ptr - new_frame_ptr;
+ frame_ptr = new_frame_ptr;
+ }
+}
+
+/*!
+** Creates (pushes on the stack) new frame of fsize data_t objects
+**
+** \param fsize - size in data_t objects of the new frame
+*/
+void FrameStack::new_frame(size_t fsize)
+{
+ if (frame_ptr + c_size + fsize > base_ptr + g_size)
+ {
+ size_t new_size = g_size + std::max(g_size, c_size + fsize);
+ data_t* new_base = new data_t[new_size];
+ if (base_ptr)
+ {
+ std::copy(base_ptr, frame_ptr + c_size, new_base);
+ delete[] base_ptr;
+ }
+ frame_ptr = new_base + (frame_ptr - base_ptr);
+ base_ptr = new_base;
+ }
+ fstack.push(frame_ptr - base_ptr);
+ c_size = fsize;
+}
+
+/*!
+** \return true if the stack is empty
+*/
+bool FrameStack::empty() const
+{
+ return frame_ptr == base_ptr && c_size == 0;
+}
+} // namespace SpasmImpl