src/Stack.h
changeset 86 32ad0523b309
parent 85 06a0015b6a5c
child 230 fb3cd08bc7fb
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/Stack.h	Tue Jul 24 23:53:34 2012 -0700
     1.3 @@ -0,0 +1,233 @@
     1.4 +/* vim: set ts=4 sw=4 tw=99 et:
     1.5 + *
     1.6 + * Copyright (C) 2012 David Anderson
     1.7 + *
     1.8 + * This file is part of JITCraft.
     1.9 + *
    1.10 + * JITCraft is free software: you can redistribute it and/or modify it under
    1.11 + * the terms of the GNU General Public License as published by the Free
    1.12 + * Software Foundation, either version 3 of the License, or (at your option)
    1.13 + * any later version.
    1.14 + * 
    1.15 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    1.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    1.18 + *
    1.19 + * You should have received a copy of the GNU General Public License along with
    1.20 + * JITCraft. If not, see http://www.gnu.org/licenses/.
    1.21 + */
    1.22 +#ifndef _include_jc_stack_h_
    1.23 +#define _include_jc_stack_h_
    1.24 +
    1.25 +#include <stddef.h>
    1.26 +#include "Utility.h"
    1.27 +#include "Code.h"
    1.28 +#include "Functions.h"
    1.29 +#include "VirtualObjectVisitor.h"
    1.30 +
    1.31 +namespace ke {
    1.32 +
    1.33 +class Object;
    1.34 +class Array;
    1.35 +class Reference;
    1.36 +class Frame;
    1.37 +class Stack;
    1.38 +class Zone;
    1.39 +class Module;
    1.40 +    
    1.41 +union LocalSlot
    1.42 +{
    1.43 +    int i32;
    1.44 +    float f;
    1.45 +    Address address;
    1.46 +    Object *obj;
    1.47 +    Array *array;
    1.48 +    Reference *ref;
    1.49 +    Function *fun;
    1.50 +    Module *module;
    1.51 +};
    1.52 +
    1.53 +struct Top
    1.54 +{
    1.55 +    LocalSlot *sp;
    1.56 +    bytecode *pc;
    1.57 +    Frame *fp;
    1.58 +};
    1.59 +
    1.60 +class Frame
    1.61 +{
    1.62 +    friend class Stack;
    1.63 +
    1.64 +    Frame *prev_;
    1.65 +    bytecode *prevpc_;
    1.66 +    union {
    1.67 +        Function *fun_;
    1.68 +        Native *native_;
    1.69 +        Object *callee_;
    1.70 +    };
    1.71 +    Code *code_;
    1.72 +    Address lifoPosition_;
    1.73 +
    1.74 +  public:
    1.75 +    Frame(Frame *prev, bytecode *prevpc, Function *fun, Code *code, Address lifoPosition)
    1.76 +      : prev_(prev),
    1.77 +        prevpc_(prevpc),
    1.78 +        fun_(fun),
    1.79 +        code_(code),
    1.80 +        lifoPosition_(lifoPosition)
    1.81 +    {
    1.82 +    }
    1.83 +
    1.84 +    Frame(Frame *prev, bytecode *prevpc, Native *native, Address lifoPosition)
    1.85 +      : prev_(prev),
    1.86 +        prevpc_(prevpc),
    1.87 +        native_(native),
    1.88 +        code_(NULL),
    1.89 +        lifoPosition_(lifoPosition)
    1.90 +    {
    1.91 +    }
    1.92 +
    1.93 +    LocalSlot *locals() {
    1.94 +        return reinterpret_cast<LocalSlot *>(this + 1);
    1.95 +    }
    1.96 +    LocalSlot *stackBase() {
    1.97 +        return locals() + code_->nlocals();
    1.98 +    }
    1.99 +    Function *fun() const {
   1.100 +        assert(fun_ && callee_->is(MapKind_Function));
   1.101 +        return fun_;
   1.102 +    }
   1.103 +    Function *maybeFun() const {
   1.104 +        return (fun_ && callee_->is(MapKind_Function)) ? fun_ : NULL;
   1.105 +    }
   1.106 +    bool isNative() const {
   1.107 +        return callee_ && callee_->is(MapKind_Native);
   1.108 +    }
   1.109 +    Native *native() const {
   1.110 +        assert(isNative());
   1.111 +        return native_;
   1.112 +    }
   1.113 +    Code *code() const {
   1.114 +        assert(code_);
   1.115 +        return code_;
   1.116 +    }
   1.117 +    Frame *prev() const {
   1.118 +        return prev_;
   1.119 +    }
   1.120 +    bytecode *prevpc() const {
   1.121 +        return prevpc_;
   1.122 +    }
   1.123 +    Address lifoPosition() const {
   1.124 +        return lifoPosition_;
   1.125 +    }
   1.126 +    LocalSlot &arg(unsigned slot) {
   1.127 +        assert(slot < fun()->nargs());
   1.128 +        return *(reinterpret_cast<LocalSlot *>(this) - slot - 1);
   1.129 +    }
   1.130 +    void accept(VirtualObjectVisitor *visitor);
   1.131 +};
   1.132 +
   1.133 +// RAII object for calling a function from C++.
   1.134 +class InvokeArgs
   1.135 +{
   1.136 +    friend class Stack;
   1.137 +
   1.138 +    Stack *stack_;
   1.139 +    LocalSlot *args_;
   1.140 +    unsigned nargs_;
   1.141 +
   1.142 +  public:
   1.143 +    InvokeArgs()
   1.144 +      : stack_(NULL),
   1.145 +        args_(NULL),
   1.146 +        nargs_(0)
   1.147 +    {
   1.148 +    }
   1.149 +
   1.150 +    ~InvokeArgs();
   1.151 +
   1.152 +    LocalSlot &arg(unsigned index) {
   1.153 +        assert(index < nargs_);
   1.154 +        return args_[nargs_ - index - 1];
   1.155 +    }
   1.156 +};
   1.157 +
   1.158 +// RAII object for calling a native from C++.
   1.159 +class NativeArgs
   1.160 +{
   1.161 +    friend class Stack;
   1.162 +
   1.163 +    Stack *stack_;
   1.164 +    LocalSlot *argsBase_;
   1.165 +
   1.166 +  public:
   1.167 +    NativeArgs()
   1.168 +      : stack_(NULL),
   1.169 +        argsBase_(NULL)
   1.170 +    {
   1.171 +    }
   1.172 +
   1.173 +    ~NativeArgs();
   1.174 +
   1.175 +    intptr_t *args() {
   1.176 +        return reinterpret_cast<intptr_t *>(argsBase_);
   1.177 +    }
   1.178 +};
   1.179 +
   1.180 +class Stack
   1.181 +{
   1.182 +    friend class InvokeArgs;
   1.183 +    friend class NativeArgs;
   1.184 +
   1.185 +  private:
   1.186 +    static const size_t STACK_SIZE = 1024 * 1024;
   1.187 +
   1.188 +  public:
   1.189 +    Stack(Zone *zone);
   1.190 +    ~Stack();
   1.191 +
   1.192 +    bool initialize();
   1.193 +
   1.194 +  public:
   1.195 +    Frame *pushInlineFrame(Handle<Function> fun);
   1.196 +    Frame *popInlineFrame();
   1.197 +
   1.198 +    bool pushInvokeFrame(Handle<Function> fun, InvokeArgs &args);
   1.199 +    bool pushModuleFrame(Handle<Module> module, InvokeArgs &args);
   1.200 +    bool pushNativeFrame(Handle<Native> native, NativeArgs &args, unsigned argc);
   1.201 +
   1.202 +    Top *top() {
   1.203 +        return &top_;
   1.204 +    }
   1.205 +    bool isInCallStack(Handle<Module> module);
   1.206 +    void accept(VirtualObjectVisitor *visitor);
   1.207 +
   1.208 +  private:
   1.209 +    void popInvokeFrame(InvokeArgs &args);
   1.210 +    void popNativeFrame(NativeArgs &args);
   1.211 +
   1.212 +  private:
   1.213 +    Zone *zone_;
   1.214 +    char *buffer_;
   1.215 +    char *end_;
   1.216 +    Top top_;
   1.217 +};
   1.218 +
   1.219 +class StackIter
   1.220 +{
   1.221 +    bytecode *pc_;
   1.222 +    Frame *fp_;
   1.223 +
   1.224 +  public:
   1.225 +    StackIter(Zone *zone);
   1.226 +
   1.227 +    bool done() const;
   1.228 +    const char *function() const;
   1.229 +    unsigned lineNumber() const;
   1.230 +    const char *source() const;
   1.231 +    void prev();
   1.232 +};
   1.233 +
   1.234 +}
   1.235 +
   1.236 +#endif // _include_jc_stack_h_