jitcraft/Stack.cpp
author David Anderson <dvander@alliedmods.net>
Mon Jun 25 02:57:28 2012 -0700 (2012-06-25)
changeset 0 c455ebb9a5dc
child 1 27f12e2fc369
permissions -rw-r--r--
Initial import of prototype.
     1 /*
     2  * Copyright (C) 2012 David Anderson
     3  *
     4  * This file is part of JITCraft.
     5  *
     6  * JITCraft is free software: you can redistribute it and/or modify it under
     7  * the terms of the GNU General Public License as published by the Free
     8  * Software Foundation, either version 3 of the License, or (at your option)
     9  * any later version.
    10  * 
    11  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License along with
    16  * JITCraft. If not, see http://www.gnu.org/licenses/.
    17  */
    18 #include <new>
    19 #include <stdlib.h>
    20 #include "Stack.h"
    21 
    22 using namespace jc;
    23 
    24 Stack::Stack()
    25   : buffer_(NULL),
    26     top_(NULL),
    27     end_(NULL)
    28 {
    29 }
    30 
    31 Stack::~Stack()
    32 {
    33     free(buffer_);
    34 }
    35 
    36 bool
    37 Stack::initialize()
    38 {
    39     buffer_ = (char *)malloc(STACK_SIZE);
    40     if (!buffer_)
    41         return false;
    42 
    43     top_ = NULL;
    44     end_ = buffer_ + STACK_SIZE;
    45     return true;
    46 }
    47 
    48 static inline size_t
    49 SizeForCodeFrame(Code *code)
    50 {
    51     return sizeof(Frame) + sizeof(LocalSlot) * (code->nlocals() + code->maxStackDepth());
    52 }
    53 
    54 Frame *
    55 Stack::pushFrame(Frame *prev, Code *code)
    56 {
    57     size_t nbytes = SizeForCodeFrame(code);
    58     if (reinterpret_cast<char *>(top_->sp) + nbytes >= end_)
    59         return NULL;
    60 
    61     Frame *frame = reinterpret_cast<Frame *>(top_->sp);
    62     new (frame) Frame(prev, top_->pc, code);
    63     memset(frame->locals(), 0, sizeof(LocalSlot) * code->nlocals());
    64 
    65     top_->pc = frame->code()->start();
    66     top_->sp = frame->stackBase();
    67 
    68     return frame;
    69 }
    70 
    71 
    72 Frame *
    73 Stack::popFrame(Frame *frame)
    74 {
    75     Frame *prev = frame->prev();
    76     Code *code = frame->code();
    77     size_t nbytes = sizeof(LocalSlot) * code->nlocals() +
    78                     sizeof(Frame) +
    79                     sizeof(LocalSlot) * code->nargs();
    80     top_->pc = frame->prevpc();
    81     top_->sp = reinterpret_cast<LocalSlot *>(reinterpret_cast<char *>(top_->sp) - nbytes);
    82     return prev;
    83 }
    84 
    85 UnsafeStack::UnsafeStack()
    86   : buffer_(NULL),
    87     pos_(NULL),
    88     end_(NULL)
    89 {
    90 }
    91 
    92 UnsafeStack::~UnsafeStack()
    93 {
    94     free(buffer_);
    95 }
    96 
    97 bool
    98 UnsafeStack::initialize()
    99 {
   100     buffer_ = (char *)malloc(STACK_SIZE);
   101     if (!buffer_)
   102         return false;
   103 
   104     pos_ = NULL;
   105     end_ = buffer_ + STACK_SIZE;
   106     return true;
   107 }