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