jitcraft/Stack.h
author David Anderson <dvander@alliedmods.net>
Mon Jul 09 01:22:03 2012 -0700 (2012-07-09)
changeset 65 7c942b5adebc
parent 62 e04c5be84792
child 68 b40b0e18a918
permissions -rw-r--r--
Added ISPE-oriented API for invoking functions.
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@0
    35
    
dvander@0
    36
union LocalSlot
dvander@0
    37
{
dvander@0
    38
    int i32;
dvander@4
    39
    float f;
dvander@12
    40
    Address address;
dvander@12
    41
    Object *obj;
dvander@12
    42
    Array *array;
dvander@14
    43
    Reference *ref;
dvander@0
    44
};
dvander@0
    45
dvander@0
    46
struct Top
dvander@0
    47
{
dvander@0
    48
    LocalSlot *sp;
dvander@0
    49
    bytecode *pc;
dvander@47
    50
    Frame *fp;
dvander@0
    51
};
dvander@0
    52
dvander@0
    53
class Frame
dvander@0
    54
{
dvander@0
    55
    friend class Stack;
dvander@0
    56
dvander@0
    57
    Frame *prev_;
dvander@0
    58
    bytecode *prevpc_;
dvander@26
    59
    Function *fun_;
dvander@0
    60
    Code *code_;
dvander@12
    61
    Address lifoPosition_;
dvander@0
    62
dvander@0
    63
  public:
dvander@26
    64
    Frame(Frame *prev, bytecode *prevpc, Function *fun, Code *code, Address lifoPosition)
dvander@0
    65
      : prev_(prev),
dvander@0
    66
        prevpc_(prevpc),
dvander@26
    67
        fun_(fun),
dvander@1
    68
        code_(code),
dvander@12
    69
        lifoPosition_(lifoPosition)
dvander@0
    70
    {
dvander@0
    71
    }
dvander@0
    72
dvander@0
    73
    LocalSlot *locals() {
dvander@0
    74
        return reinterpret_cast<LocalSlot *>(this + 1);
dvander@0
    75
    }
dvander@0
    76
    LocalSlot *stackBase() {
dvander@0
    77
        return locals() + code_->nlocals();
dvander@0
    78
    }
dvander@26
    79
    Function *fun() const {
dvander@26
    80
        assert(fun_);
dvander@26
    81
        return fun_;
dvander@26
    82
    }
dvander@26
    83
    Function *maybeFun() const {
dvander@26
    84
        return fun_;
dvander@26
    85
    }
dvander@0
    86
    Code *code() const {
dvander@0
    87
        return code_;
dvander@0
    88
    }
dvander@0
    89
    Frame *prev() const {
dvander@0
    90
        return prev_;
dvander@0
    91
    }
dvander@0
    92
    bytecode *prevpc() const {
dvander@0
    93
        return prevpc_;
dvander@0
    94
    }
dvander@12
    95
    Address lifoPosition() const {
dvander@12
    96
        return lifoPosition_;
dvander@1
    97
    }
dvander@0
    98
    LocalSlot &arg(unsigned slot) {
dvander@26
    99
        assert(slot < fun()->nargs());
dvander@0
   100
        return *(reinterpret_cast<LocalSlot *>(this) - slot - 1);
dvander@0
   101
    }
dvander@47
   102
    void accept(VirtualObjectVisitor *visitor);
dvander@0
   103
};
dvander@0
   104
dvander@65
   105
// RAII object for calling a function from C++.
dvander@65
   106
class InvokeArgs
dvander@65
   107
{
dvander@65
   108
    friend class Stack;
dvander@65
   109
dvander@65
   110
    Stack *stack_;
dvander@65
   111
    LocalSlot *args_;
dvander@65
   112
    unsigned nargs_;
dvander@65
   113
dvander@65
   114
  public:
dvander@65
   115
    InvokeArgs()
dvander@65
   116
      : stack_(NULL),
dvander@65
   117
        args_(NULL),
dvander@65
   118
        nargs_(0)
dvander@65
   119
    {
dvander@65
   120
    }
dvander@65
   121
dvander@65
   122
    ~InvokeArgs();
dvander@65
   123
dvander@65
   124
    LocalSlot &arg(unsigned index) {
dvander@65
   125
        assert(index < nargs_);
dvander@65
   126
        return args_[nargs_ - index - 1];
dvander@65
   127
    }
dvander@65
   128
};
dvander@65
   129
dvander@0
   130
class Stack
dvander@0
   131
{
dvander@65
   132
    friend class InvokeArgs;
dvander@0
   133
dvander@0
   134
  private:
dvander@0
   135
    static const size_t STACK_SIZE = 1024 * 1024;
dvander@0
   136
dvander@0
   137
  public:
dvander@0
   138
    Stack();
dvander@0
   139
    ~Stack();
dvander@0
   140
dvander@0
   141
    bool initialize();
dvander@0
   142
dvander@0
   143
  public:
dvander@65
   144
    Frame *pushInlineFrame(Handle<Function> fun);
dvander@65
   145
    Frame *popInlineFrame();
dvander@65
   146
dvander@65
   147
    bool pushInvokeFrame(Handle<Function> fun, InvokeArgs &args);
dvander@0
   148
dvander@0
   149
    Top *top() {
dvander@65
   150
        return &top_;
dvander@0
   151
    }
dvander@62
   152
    bool isInCallStack(Handle<Module> module);
dvander@47
   153
    void accept(VirtualObjectVisitor *visitor);
dvander@65
   154
dvander@65
   155
  private:
dvander@65
   156
    void popInvokeFrame(InvokeArgs &args);
dvander@65
   157
dvander@65
   158
  private:
dvander@65
   159
    char *buffer_;
dvander@65
   160
    char *end_;
dvander@65
   161
    Top top_;
dvander@0
   162
};
dvander@0
   163
dvander@0
   164
}
dvander@0
   165
dvander@0
   166
#endif // _include_jc_stack_h_