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_