From 6e19bb560d474736d45f5be011ff0830c7019991 Mon Sep 17 00:00:00 2001 From: Dimitar Trendafilov Date: Mon, 5 Nov 2018 23:34:00 +0200 Subject: Squashed 'spasm/' content from commit 08ee95d git-subtree-dir: spasm git-subtree-split: 08ee95d89054ba0d33697d613799a0a013aedf89 --- src/frames.cpp | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 src/frames.cpp (limited to 'src/frames.cpp') diff --git a/src/frames.cpp b/src/frames.cpp new file mode 100644 index 0000000..8b7c891 --- /dev/null +++ b/src/frames.cpp @@ -0,0 +1,130 @@ +#include + +#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 -- cgit v1.3.1-23-gd82d