1.1 --- a/src/Stack.h Mon Jun 10 00:46:29 2013 +0100
1.2 +++ b/src/Stack.h Mon Jun 10 01:04:43 2013 +0100
1.3 @@ -1,246 +1,246 @@
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 -
1.73 - // Position of the LIFO stack at function entry.
1.74 - Address lifoPosition_;
1.75 -
1.76 - // Loop nesting level, for LIFO stack balancing. LIFO stack balancing
1.77 - // is not strictly required, but it helps to avoid unnecessary waste,
1.78 - // since once the LIFO stack is depleted, we must use the heap instead.
1.79 - unsigned loopDepth_;
1.80 -
1.81 - public:
1.82 - Frame(Frame *prev, bytecode *prevpc, Function *fun, Code *code, Address lifoPosition)
1.83 - : prev_(prev),
1.84 - prevpc_(prevpc),
1.85 - fun_(fun),
1.86 - code_(code),
1.87 - lifoPosition_(lifoPosition),
1.88 - loopDepth_(0)
1.89 - {
1.90 - }
1.91 -
1.92 - Frame(Frame *prev, bytecode *prevpc, Native *native, Address lifoPosition)
1.93 - : prev_(prev),
1.94 - prevpc_(prevpc),
1.95 - native_(native),
1.96 - code_(NULL),
1.97 - lifoPosition_(lifoPosition)
1.98 - {
1.99 - }
1.100 -
1.101 - Address *loopStack() {
1.102 - return reinterpret_cast<Address *>(this + 1);
1.103 - }
1.104 - LocalSlot *locals() {
1.105 - return reinterpret_cast<LocalSlot *>(loopStack() + code_->maxLoopDepth());
1.106 - }
1.107 - LocalSlot *stackBase() {
1.108 - return locals() + code_->nlocals();
1.109 - }
1.110 - Function *fun() const {
1.111 - assert(fun_ && callee_->is(MapKind_Function));
1.112 - return fun_;
1.113 - }
1.114 - Function *maybeFun() const {
1.115 - return (fun_ && callee_->is(MapKind_Function)) ? fun_ : NULL;
1.116 - }
1.117 - bool isNative() const {
1.118 - return callee_ && callee_->is(MapKind_Native);
1.119 - }
1.120 - Native *native() const {
1.121 - assert(isNative());
1.122 - return native_;
1.123 - }
1.124 - Code *code() const {
1.125 - assert(code_);
1.126 - return code_;
1.127 - }
1.128 - Frame *prev() const {
1.129 - return prev_;
1.130 - }
1.131 - bytecode *prevpc() const {
1.132 - return prevpc_;
1.133 - }
1.134 - Address lifoPosition() const {
1.135 - return lifoPosition_;
1.136 - }
1.137 - LocalSlot &arg(unsigned slot) {
1.138 - assert(slot < fun()->nargs());
1.139 - return *(reinterpret_cast<LocalSlot *>(this) - slot - 1);
1.140 - }
1.141 - void enterLoop(Zone *zone);
1.142 - void leaveLoop(Zone *zone);
1.143 - void accept(VirtualObjectVisitor *visitor);
1.144 -};
1.145 -
1.146 -// RAII object for calling a function from C++.
1.147 -class InvokeArgs
1.148 -{
1.149 - friend class Stack;
1.150 -
1.151 - Stack *stack_;
1.152 - LocalSlot *args_;
1.153 - unsigned nargs_;
1.154 -
1.155 - public:
1.156 - InvokeArgs()
1.157 - : stack_(NULL),
1.158 - args_(NULL),
1.159 - nargs_(0)
1.160 - {
1.161 - }
1.162 -
1.163 - ~InvokeArgs();
1.164 -
1.165 - LocalSlot &arg(unsigned index) {
1.166 - assert(index < nargs_);
1.167 - return args_[nargs_ - index - 1];
1.168 - }
1.169 -};
1.170 -
1.171 -// RAII object for calling a native from C++.
1.172 -class NativeArgs
1.173 -{
1.174 - friend class Stack;
1.175 -
1.176 - Stack *stack_;
1.177 - LocalSlot *argsBase_;
1.178 -
1.179 - public:
1.180 - NativeArgs()
1.181 - : stack_(NULL),
1.182 - argsBase_(NULL)
1.183 - {
1.184 - }
1.185 -
1.186 - ~NativeArgs();
1.187 -
1.188 - intptr_t *args() {
1.189 - return reinterpret_cast<intptr_t *>(argsBase_);
1.190 - }
1.191 -};
1.192 -
1.193 -class Stack
1.194 -{
1.195 - friend class InvokeArgs;
1.196 - friend class NativeArgs;
1.197 -
1.198 - private:
1.199 - static const size_t STACK_SIZE = 1024 * 1024;
1.200 -
1.201 - public:
1.202 - Stack(Zone *zone);
1.203 - ~Stack();
1.204 -
1.205 - bool initialize();
1.206 -
1.207 - public:
1.208 - Frame *pushInlineFrame(Handle<Function> fun);
1.209 - Frame *popInlineFrame();
1.210 -
1.211 - bool pushInvokeFrame(Handle<Function> fun, InvokeArgs &args);
1.212 - bool pushModuleFrame(Handle<Module> module, InvokeArgs &args);
1.213 - bool pushNativeFrame(Handle<Native> native, NativeArgs &args, unsigned argc);
1.214 -
1.215 - Top *top() {
1.216 - return &top_;
1.217 - }
1.218 - bool isInCallStack(Handle<Module> module);
1.219 - void accept(VirtualObjectVisitor *visitor);
1.220 -
1.221 - private:
1.222 - void popInvokeFrame(InvokeArgs &args);
1.223 - void popNativeFrame(NativeArgs &args);
1.224 -
1.225 - private:
1.226 - Zone *zone_;
1.227 - char *buffer_;
1.228 - char *end_;
1.229 - Top top_;
1.230 -};
1.231 -
1.232 -class StackIter
1.233 -{
1.234 - bytecode *pc_;
1.235 - Frame *fp_;
1.236 -
1.237 - public:
1.238 - StackIter(Zone *zone);
1.239 -
1.240 - bool done() const;
1.241 - const char *function() const;
1.242 - unsigned lineNumber() const;
1.243 - const char *source() const;
1.244 - void prev();
1.245 -};
1.246 -
1.247 -}
1.248 -
1.249 -#endif // _include_jc_stack_h_
1.250 +/* vim: set ts=4 sw=4 tw=99 et:
1.251 + *
1.252 + * Copyright (C) 2012 David Anderson
1.253 + *
1.254 + * This file is part of JITCraft.
1.255 + *
1.256 + * JITCraft is free software: you can redistribute it and/or modify it under
1.257 + * the terms of the GNU General Public License as published by the Free
1.258 + * Software Foundation, either version 3 of the License, or (at your option)
1.259 + * any later version.
1.260 + *
1.261 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
1.262 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.263 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.264 + *
1.265 + * You should have received a copy of the GNU General Public License along with
1.266 + * JITCraft. If not, see http://www.gnu.org/licenses/.
1.267 + */
1.268 +#ifndef _include_jc_stack_h_
1.269 +#define _include_jc_stack_h_
1.270 +
1.271 +#include <stddef.h>
1.272 +#include "Utility.h"
1.273 +#include "Code.h"
1.274 +#include "Functions.h"
1.275 +#include "VirtualObjectVisitor.h"
1.276 +
1.277 +namespace ke {
1.278 +
1.279 +class Object;
1.280 +class Array;
1.281 +class Reference;
1.282 +class Frame;
1.283 +class Stack;
1.284 +class Zone;
1.285 +class Module;
1.286 +
1.287 +union LocalSlot
1.288 +{
1.289 + int i32;
1.290 + float f;
1.291 + Address address;
1.292 + Object *obj;
1.293 + Array *array;
1.294 + Reference *ref;
1.295 + Function *fun;
1.296 + Module *module;
1.297 +};
1.298 +
1.299 +struct Top
1.300 +{
1.301 + LocalSlot *sp;
1.302 + bytecode *pc;
1.303 + Frame *fp;
1.304 +};
1.305 +
1.306 +class Frame
1.307 +{
1.308 + friend class Stack;
1.309 +
1.310 + Frame *prev_;
1.311 + bytecode *prevpc_;
1.312 + union {
1.313 + Function *fun_;
1.314 + Native *native_;
1.315 + Object *callee_;
1.316 + };
1.317 + Code *code_;
1.318 +
1.319 + // Position of the LIFO stack at function entry.
1.320 + Address lifoPosition_;
1.321 +
1.322 + // Loop nesting level, for LIFO stack balancing. LIFO stack balancing
1.323 + // is not strictly required, but it helps to avoid unnecessary waste,
1.324 + // since once the LIFO stack is depleted, we must use the heap instead.
1.325 + unsigned loopDepth_;
1.326 +
1.327 + public:
1.328 + Frame(Frame *prev, bytecode *prevpc, Function *fun, Code *code, Address lifoPosition)
1.329 + : prev_(prev),
1.330 + prevpc_(prevpc),
1.331 + fun_(fun),
1.332 + code_(code),
1.333 + lifoPosition_(lifoPosition),
1.334 + loopDepth_(0)
1.335 + {
1.336 + }
1.337 +
1.338 + Frame(Frame *prev, bytecode *prevpc, Native *native, Address lifoPosition)
1.339 + : prev_(prev),
1.340 + prevpc_(prevpc),
1.341 + native_(native),
1.342 + code_(NULL),
1.343 + lifoPosition_(lifoPosition)
1.344 + {
1.345 + }
1.346 +
1.347 + Address *loopStack() {
1.348 + return reinterpret_cast<Address *>(this + 1);
1.349 + }
1.350 + LocalSlot *locals() {
1.351 + return reinterpret_cast<LocalSlot *>(loopStack() + code_->maxLoopDepth());
1.352 + }
1.353 + LocalSlot *stackBase() {
1.354 + return locals() + code_->nlocals();
1.355 + }
1.356 + Function *fun() const {
1.357 + assert(fun_ && callee_->is(MapKind_Function));
1.358 + return fun_;
1.359 + }
1.360 + Function *maybeFun() const {
1.361 + return (fun_ && callee_->is(MapKind_Function)) ? fun_ : NULL;
1.362 + }
1.363 + bool isNative() const {
1.364 + return callee_ && callee_->is(MapKind_Native);
1.365 + }
1.366 + Native *native() const {
1.367 + assert(isNative());
1.368 + return native_;
1.369 + }
1.370 + Code *code() const {
1.371 + assert(code_);
1.372 + return code_;
1.373 + }
1.374 + Frame *prev() const {
1.375 + return prev_;
1.376 + }
1.377 + bytecode *prevpc() const {
1.378 + return prevpc_;
1.379 + }
1.380 + Address lifoPosition() const {
1.381 + return lifoPosition_;
1.382 + }
1.383 + LocalSlot &arg(unsigned slot) {
1.384 + assert(slot < fun()->nargs());
1.385 + return *(reinterpret_cast<LocalSlot *>(this) - slot - 1);
1.386 + }
1.387 + void enterLoop(Zone *zone);
1.388 + void leaveLoop(Zone *zone);
1.389 + void accept(VirtualObjectVisitor *visitor);
1.390 +};
1.391 +
1.392 +// RAII object for calling a function from C++.
1.393 +class InvokeArgs
1.394 +{
1.395 + friend class Stack;
1.396 +
1.397 + Stack *stack_;
1.398 + LocalSlot *args_;
1.399 + unsigned nargs_;
1.400 +
1.401 + public:
1.402 + InvokeArgs()
1.403 + : stack_(NULL),
1.404 + args_(NULL),
1.405 + nargs_(0)
1.406 + {
1.407 + }
1.408 +
1.409 + ~InvokeArgs();
1.410 +
1.411 + LocalSlot &arg(unsigned index) {
1.412 + assert(index < nargs_);
1.413 + return args_[nargs_ - index - 1];
1.414 + }
1.415 +};
1.416 +
1.417 +// RAII object for calling a native from C++.
1.418 +class NativeArgs
1.419 +{
1.420 + friend class Stack;
1.421 +
1.422 + Stack *stack_;
1.423 + LocalSlot *argsBase_;
1.424 +
1.425 + public:
1.426 + NativeArgs()
1.427 + : stack_(NULL),
1.428 + argsBase_(NULL)
1.429 + {
1.430 + }
1.431 +
1.432 + ~NativeArgs();
1.433 +
1.434 + intptr_t *args() {
1.435 + return reinterpret_cast<intptr_t *>(argsBase_);
1.436 + }
1.437 +};
1.438 +
1.439 +class Stack
1.440 +{
1.441 + friend class InvokeArgs;
1.442 + friend class NativeArgs;
1.443 +
1.444 + private:
1.445 + static const size_t STACK_SIZE = 1024 * 1024;
1.446 +
1.447 + public:
1.448 + Stack(Zone *zone);
1.449 + ~Stack();
1.450 +
1.451 + bool initialize();
1.452 +
1.453 + public:
1.454 + Frame *pushInlineFrame(Handle<Function> fun);
1.455 + Frame *popInlineFrame();
1.456 +
1.457 + bool pushInvokeFrame(Handle<Function> fun, InvokeArgs &args);
1.458 + bool pushModuleFrame(Handle<Module> module, InvokeArgs &args);
1.459 + bool pushNativeFrame(Handle<Native> native, NativeArgs &args, unsigned argc);
1.460 +
1.461 + Top *top() {
1.462 + return &top_;
1.463 + }
1.464 + bool isInCallStack(Handle<Module> module);
1.465 + void accept(VirtualObjectVisitor *visitor);
1.466 +
1.467 + private:
1.468 + void popInvokeFrame(InvokeArgs &args);
1.469 + void popNativeFrame(NativeArgs &args);
1.470 +
1.471 + private:
1.472 + Zone *zone_;
1.473 + char *buffer_;
1.474 + char *end_;
1.475 + Top top_;
1.476 +};
1.477 +
1.478 +class StackIter
1.479 +{
1.480 + bytecode *pc_;
1.481 + Frame *fp_;
1.482 +
1.483 + public:
1.484 + StackIter(Zone *zone);
1.485 +
1.486 + bool done() const;
1.487 + const char *function() const;
1.488 + unsigned lineNumber() const;
1.489 + const char *source() const;
1.490 + void prev();
1.491 +};
1.492 +
1.493 +}
1.494 +
1.495 +#endif // _include_jc_stack_h_