src/Stack.h
author David Anderson <dvander@alliedmods.net>
Sun Nov 18 15:00:08 2012 -0800 (2012-11-18)
changeset 214 e1a6deaa6ebe
parent 86 32ad0523b309
child 230 fb3cd08bc7fb
permissions -rw-r--r--
Fix timeout handling in the test harness.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of JITCraft.
     6  *
     7  * JITCraft is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * JITCraft. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #ifndef _include_jc_stack_h_
    20 #define _include_jc_stack_h_
    21 
    22 #include <stddef.h>
    23 #include "Utility.h"
    24 #include "Code.h"
    25 #include "Functions.h"
    26 #include "VirtualObjectVisitor.h"
    27 
    28 namespace ke {
    29 
    30 class Object;
    31 class Array;
    32 class Reference;
    33 class Frame;
    34 class Stack;
    35 class Zone;
    36 class Module;
    37     
    38 union LocalSlot
    39 {
    40     int i32;
    41     float f;
    42     Address address;
    43     Object *obj;
    44     Array *array;
    45     Reference *ref;
    46     Function *fun;
    47     Module *module;
    48 };
    49 
    50 struct Top
    51 {
    52     LocalSlot *sp;
    53     bytecode *pc;
    54     Frame *fp;
    55 };
    56 
    57 class Frame
    58 {
    59     friend class Stack;
    60 
    61     Frame *prev_;
    62     bytecode *prevpc_;
    63     union {
    64         Function *fun_;
    65         Native *native_;
    66         Object *callee_;
    67     };
    68     Code *code_;
    69     Address lifoPosition_;
    70 
    71   public:
    72     Frame(Frame *prev, bytecode *prevpc, Function *fun, Code *code, Address lifoPosition)
    73       : prev_(prev),
    74         prevpc_(prevpc),
    75         fun_(fun),
    76         code_(code),
    77         lifoPosition_(lifoPosition)
    78     {
    79     }
    80 
    81     Frame(Frame *prev, bytecode *prevpc, Native *native, Address lifoPosition)
    82       : prev_(prev),
    83         prevpc_(prevpc),
    84         native_(native),
    85         code_(NULL),
    86         lifoPosition_(lifoPosition)
    87     {
    88     }
    89 
    90     LocalSlot *locals() {
    91         return reinterpret_cast<LocalSlot *>(this + 1);
    92     }
    93     LocalSlot *stackBase() {
    94         return locals() + code_->nlocals();
    95     }
    96     Function *fun() const {
    97         assert(fun_ && callee_->is(MapKind_Function));
    98         return fun_;
    99     }
   100     Function *maybeFun() const {
   101         return (fun_ && callee_->is(MapKind_Function)) ? fun_ : NULL;
   102     }
   103     bool isNative() const {
   104         return callee_ && callee_->is(MapKind_Native);
   105     }
   106     Native *native() const {
   107         assert(isNative());
   108         return native_;
   109     }
   110     Code *code() const {
   111         assert(code_);
   112         return code_;
   113     }
   114     Frame *prev() const {
   115         return prev_;
   116     }
   117     bytecode *prevpc() const {
   118         return prevpc_;
   119     }
   120     Address lifoPosition() const {
   121         return lifoPosition_;
   122     }
   123     LocalSlot &arg(unsigned slot) {
   124         assert(slot < fun()->nargs());
   125         return *(reinterpret_cast<LocalSlot *>(this) - slot - 1);
   126     }
   127     void accept(VirtualObjectVisitor *visitor);
   128 };
   129 
   130 // RAII object for calling a function from C++.
   131 class InvokeArgs
   132 {
   133     friend class Stack;
   134 
   135     Stack *stack_;
   136     LocalSlot *args_;
   137     unsigned nargs_;
   138 
   139   public:
   140     InvokeArgs()
   141       : stack_(NULL),
   142         args_(NULL),
   143         nargs_(0)
   144     {
   145     }
   146 
   147     ~InvokeArgs();
   148 
   149     LocalSlot &arg(unsigned index) {
   150         assert(index < nargs_);
   151         return args_[nargs_ - index - 1];
   152     }
   153 };
   154 
   155 // RAII object for calling a native from C++.
   156 class NativeArgs
   157 {
   158     friend class Stack;
   159 
   160     Stack *stack_;
   161     LocalSlot *argsBase_;
   162 
   163   public:
   164     NativeArgs()
   165       : stack_(NULL),
   166         argsBase_(NULL)
   167     {
   168     }
   169 
   170     ~NativeArgs();
   171 
   172     intptr_t *args() {
   173         return reinterpret_cast<intptr_t *>(argsBase_);
   174     }
   175 };
   176 
   177 class Stack
   178 {
   179     friend class InvokeArgs;
   180     friend class NativeArgs;
   181 
   182   private:
   183     static const size_t STACK_SIZE = 1024 * 1024;
   184 
   185   public:
   186     Stack(Zone *zone);
   187     ~Stack();
   188 
   189     bool initialize();
   190 
   191   public:
   192     Frame *pushInlineFrame(Handle<Function> fun);
   193     Frame *popInlineFrame();
   194 
   195     bool pushInvokeFrame(Handle<Function> fun, InvokeArgs &args);
   196     bool pushModuleFrame(Handle<Module> module, InvokeArgs &args);
   197     bool pushNativeFrame(Handle<Native> native, NativeArgs &args, unsigned argc);
   198 
   199     Top *top() {
   200         return &top_;
   201     }
   202     bool isInCallStack(Handle<Module> module);
   203     void accept(VirtualObjectVisitor *visitor);
   204 
   205   private:
   206     void popInvokeFrame(InvokeArgs &args);
   207     void popNativeFrame(NativeArgs &args);
   208 
   209   private:
   210     Zone *zone_;
   211     char *buffer_;
   212     char *end_;
   213     Top top_;
   214 };
   215 
   216 class StackIter
   217 {
   218     bytecode *pc_;
   219     Frame *fp_;
   220 
   221   public:
   222     StackIter(Zone *zone);
   223 
   224     bool done() const;
   225     const char *function() const;
   226     unsigned lineNumber() const;
   227     const char *source() const;
   228     void prev();
   229 };
   230 
   231 }
   232 
   233 #endif // _include_jc_stack_h_