jitcraft/Stack.h
author David Anderson <dvander@alliedmods.net>
Tue Jul 10 02:11:13 2012 -0700 (2012-07-10)
changeset 68 b40b0e18a918
parent 65 7c942b5adebc
child 69 dfce0539a77d
permissions -rw-r--r--
Added support for ISourcePawnEngine natives.
     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     
    36 union LocalSlot
    37 {
    38     int i32;
    39     float f;
    40     Address address;
    41     Object *obj;
    42     Array *array;
    43     Reference *ref;
    44 };
    45 
    46 struct Top
    47 {
    48     LocalSlot *sp;
    49     bytecode *pc;
    50     Frame *fp;
    51 };
    52 
    53 class Frame
    54 {
    55     friend class Stack;
    56 
    57     Frame *prev_;
    58     bytecode *prevpc_;
    59     union {
    60         Function *fun_;
    61         Native *native_;
    62         Object *callee_;
    63     };
    64     Code *code_;
    65     Address lifoPosition_;
    66 
    67   public:
    68     Frame(Frame *prev, bytecode *prevpc, Function *fun, Code *code, Address lifoPosition)
    69       : prev_(prev),
    70         prevpc_(prevpc),
    71         fun_(fun),
    72         code_(code),
    73         lifoPosition_(lifoPosition)
    74     {
    75     }
    76 
    77     Frame(Frame *prev, bytecode *prevpc, Native *native, Address lifoPosition)
    78       : prev_(prev),
    79         prevpc_(prevpc),
    80         native_(native),
    81         code_(NULL),
    82         lifoPosition_(lifoPosition)
    83     {
    84     }
    85 
    86     LocalSlot *locals() {
    87         return reinterpret_cast<LocalSlot *>(this + 1);
    88     }
    89     LocalSlot *stackBase() {
    90         return locals() + code_->nlocals();
    91     }
    92     Function *fun() const {
    93         assert(fun_ && callee_->is(MapKind_Function));
    94         return fun_;
    95     }
    96     Function *maybeFun() const {
    97         return (fun_ && callee_->is(MapKind_Function)) ? fun_ : NULL;
    98     }
    99     bool isNative() const {
   100         return callee_ && callee_->is(MapKind_Native);
   101     }
   102     Code *code() const {
   103         assert(code_);
   104         return code_;
   105     }
   106     Frame *prev() const {
   107         return prev_;
   108     }
   109     bytecode *prevpc() const {
   110         return prevpc_;
   111     }
   112     Address lifoPosition() const {
   113         return lifoPosition_;
   114     }
   115     LocalSlot &arg(unsigned slot) {
   116         assert(slot < fun()->nargs());
   117         return *(reinterpret_cast<LocalSlot *>(this) - slot - 1);
   118     }
   119     void accept(VirtualObjectVisitor *visitor);
   120 };
   121 
   122 // RAII object for calling a function from C++.
   123 class InvokeArgs
   124 {
   125     friend class Stack;
   126 
   127     Stack *stack_;
   128     LocalSlot *args_;
   129     unsigned nargs_;
   130 
   131   public:
   132     InvokeArgs()
   133       : stack_(NULL),
   134         args_(NULL),
   135         nargs_(0)
   136     {
   137     }
   138 
   139     ~InvokeArgs();
   140 
   141     LocalSlot &arg(unsigned index) {
   142         assert(index < nargs_);
   143         return args_[nargs_ - index - 1];
   144     }
   145 };
   146 
   147 // RAII object for calling a native from C++.
   148 class NativeArgs
   149 {
   150     friend class Stack;
   151 
   152     Stack *stack_;
   153     LocalSlot *argsBase_;
   154 
   155   public:
   156     NativeArgs()
   157       : stack_(NULL),
   158         argsBase_(NULL)
   159     {
   160     }
   161 
   162     ~NativeArgs();
   163 
   164     intptr_t *args() {
   165         return reinterpret_cast<int *>(argsBase_);
   166     }
   167 };
   168 
   169 class Stack
   170 {
   171     friend class InvokeArgs;
   172     friend class NativeArgs;
   173 
   174   private:
   175     static const size_t STACK_SIZE = 1024 * 1024;
   176 
   177   public:
   178     Stack();
   179     ~Stack();
   180 
   181     bool initialize();
   182 
   183   public:
   184     Frame *pushInlineFrame(Handle<Function> fun);
   185     Frame *popInlineFrame();
   186 
   187     bool pushInvokeFrame(Handle<Function> fun, InvokeArgs &args);
   188     bool pushNativeFrame(Handle<Native> native, NativeArgs &args, unsigned argc);
   189 
   190     Top *top() {
   191         return &top_;
   192     }
   193     bool isInCallStack(Handle<Module> module);
   194     void accept(VirtualObjectVisitor *visitor);
   195 
   196   private:
   197     void popInvokeFrame(InvokeArgs &args);
   198     void popNativeFrame(NativeArgs &args);
   199 
   200   private:
   201     char *buffer_;
   202     char *end_;
   203     Top top_;
   204 };
   205 
   206 }
   207 
   208 #endif // _include_jc_stack_h_