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