diff -r c4b1341297e5 -r ba85a47ee414 src/Stack.h --- a/src/Stack.h Mon Jun 10 00:46:29 2013 +0100 +++ b/src/Stack.h Mon Jun 10 01:04:43 2013 +0100 @@ -1,246 +1,246 @@ -/* vim: set ts=4 sw=4 tw=99 et: - * - * Copyright (C) 2012 David Anderson - * - * This file is part of JITCraft. - * - * JITCraft is free software: you can redistribute it and/or modify it under - * the terms of the GNU General Public License as published by the Free - * Software Foundation, either version 3 of the License, or (at your option) - * any later version. - * - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along with - * JITCraft. If not, see http://www.gnu.org/licenses/. - */ -#ifndef _include_jc_stack_h_ -#define _include_jc_stack_h_ - -#include -#include "Utility.h" -#include "Code.h" -#include "Functions.h" -#include "VirtualObjectVisitor.h" - -namespace ke { - -class Object; -class Array; -class Reference; -class Frame; -class Stack; -class Zone; -class Module; - -union LocalSlot -{ - int i32; - float f; - Address address; - Object *obj; - Array *array; - Reference *ref; - Function *fun; - Module *module; -}; - -struct Top -{ - LocalSlot *sp; - bytecode *pc; - Frame *fp; -}; - -class Frame -{ - friend class Stack; - - Frame *prev_; - bytecode *prevpc_; - union { - Function *fun_; - Native *native_; - Object *callee_; - }; - Code *code_; - - // Position of the LIFO stack at function entry. - Address lifoPosition_; - - // Loop nesting level, for LIFO stack balancing. LIFO stack balancing - // is not strictly required, but it helps to avoid unnecessary waste, - // since once the LIFO stack is depleted, we must use the heap instead. - unsigned loopDepth_; - - public: - Frame(Frame *prev, bytecode *prevpc, Function *fun, Code *code, Address lifoPosition) - : prev_(prev), - prevpc_(prevpc), - fun_(fun), - code_(code), - lifoPosition_(lifoPosition), - loopDepth_(0) - { - } - - Frame(Frame *prev, bytecode *prevpc, Native *native, Address lifoPosition) - : prev_(prev), - prevpc_(prevpc), - native_(native), - code_(NULL), - lifoPosition_(lifoPosition) - { - } - - Address *loopStack() { - return reinterpret_cast
(this + 1); - } - LocalSlot *locals() { - return reinterpret_cast(loopStack() + code_->maxLoopDepth()); - } - LocalSlot *stackBase() { - return locals() + code_->nlocals(); - } - Function *fun() const { - assert(fun_ && callee_->is(MapKind_Function)); - return fun_; - } - Function *maybeFun() const { - return (fun_ && callee_->is(MapKind_Function)) ? fun_ : NULL; - } - bool isNative() const { - return callee_ && callee_->is(MapKind_Native); - } - Native *native() const { - assert(isNative()); - return native_; - } - Code *code() const { - assert(code_); - return code_; - } - Frame *prev() const { - return prev_; - } - bytecode *prevpc() const { - return prevpc_; - } - Address lifoPosition() const { - return lifoPosition_; - } - LocalSlot &arg(unsigned slot) { - assert(slot < fun()->nargs()); - return *(reinterpret_cast(this) - slot - 1); - } - void enterLoop(Zone *zone); - void leaveLoop(Zone *zone); - void accept(VirtualObjectVisitor *visitor); -}; - -// RAII object for calling a function from C++. -class InvokeArgs -{ - friend class Stack; - - Stack *stack_; - LocalSlot *args_; - unsigned nargs_; - - public: - InvokeArgs() - : stack_(NULL), - args_(NULL), - nargs_(0) - { - } - - ~InvokeArgs(); - - LocalSlot &arg(unsigned index) { - assert(index < nargs_); - return args_[nargs_ - index - 1]; - } -}; - -// RAII object for calling a native from C++. -class NativeArgs -{ - friend class Stack; - - Stack *stack_; - LocalSlot *argsBase_; - - public: - NativeArgs() - : stack_(NULL), - argsBase_(NULL) - { - } - - ~NativeArgs(); - - intptr_t *args() { - return reinterpret_cast(argsBase_); - } -}; - -class Stack -{ - friend class InvokeArgs; - friend class NativeArgs; - - private: - static const size_t STACK_SIZE = 1024 * 1024; - - public: - Stack(Zone *zone); - ~Stack(); - - bool initialize(); - - public: - Frame *pushInlineFrame(Handle fun); - Frame *popInlineFrame(); - - bool pushInvokeFrame(Handle fun, InvokeArgs &args); - bool pushModuleFrame(Handle module, InvokeArgs &args); - bool pushNativeFrame(Handle native, NativeArgs &args, unsigned argc); - - Top *top() { - return &top_; - } - bool isInCallStack(Handle module); - void accept(VirtualObjectVisitor *visitor); - - private: - void popInvokeFrame(InvokeArgs &args); - void popNativeFrame(NativeArgs &args); - - private: - Zone *zone_; - char *buffer_; - char *end_; - Top top_; -}; - -class StackIter -{ - bytecode *pc_; - Frame *fp_; - - public: - StackIter(Zone *zone); - - bool done() const; - const char *function() const; - unsigned lineNumber() const; - const char *source() const; - void prev(); -}; - -} - -#endif // _include_jc_stack_h_ +/* vim: set ts=4 sw=4 tw=99 et: + * + * Copyright (C) 2012 David Anderson + * + * This file is part of JITCraft. + * + * JITCraft is free software: you can redistribute it and/or modify it under + * the terms of the GNU General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with + * JITCraft. If not, see http://www.gnu.org/licenses/. + */ +#ifndef _include_jc_stack_h_ +#define _include_jc_stack_h_ + +#include +#include "Utility.h" +#include "Code.h" +#include "Functions.h" +#include "VirtualObjectVisitor.h" + +namespace ke { + +class Object; +class Array; +class Reference; +class Frame; +class Stack; +class Zone; +class Module; + +union LocalSlot +{ + int i32; + float f; + Address address; + Object *obj; + Array *array; + Reference *ref; + Function *fun; + Module *module; +}; + +struct Top +{ + LocalSlot *sp; + bytecode *pc; + Frame *fp; +}; + +class Frame +{ + friend class Stack; + + Frame *prev_; + bytecode *prevpc_; + union { + Function *fun_; + Native *native_; + Object *callee_; + }; + Code *code_; + + // Position of the LIFO stack at function entry. + Address lifoPosition_; + + // Loop nesting level, for LIFO stack balancing. LIFO stack balancing + // is not strictly required, but it helps to avoid unnecessary waste, + // since once the LIFO stack is depleted, we must use the heap instead. + unsigned loopDepth_; + + public: + Frame(Frame *prev, bytecode *prevpc, Function *fun, Code *code, Address lifoPosition) + : prev_(prev), + prevpc_(prevpc), + fun_(fun), + code_(code), + lifoPosition_(lifoPosition), + loopDepth_(0) + { + } + + Frame(Frame *prev, bytecode *prevpc, Native *native, Address lifoPosition) + : prev_(prev), + prevpc_(prevpc), + native_(native), + code_(NULL), + lifoPosition_(lifoPosition) + { + } + + Address *loopStack() { + return reinterpret_cast
(this + 1); + } + LocalSlot *locals() { + return reinterpret_cast(loopStack() + code_->maxLoopDepth()); + } + LocalSlot *stackBase() { + return locals() + code_->nlocals(); + } + Function *fun() const { + assert(fun_ && callee_->is(MapKind_Function)); + return fun_; + } + Function *maybeFun() const { + return (fun_ && callee_->is(MapKind_Function)) ? fun_ : NULL; + } + bool isNative() const { + return callee_ && callee_->is(MapKind_Native); + } + Native *native() const { + assert(isNative()); + return native_; + } + Code *code() const { + assert(code_); + return code_; + } + Frame *prev() const { + return prev_; + } + bytecode *prevpc() const { + return prevpc_; + } + Address lifoPosition() const { + return lifoPosition_; + } + LocalSlot &arg(unsigned slot) { + assert(slot < fun()->nargs()); + return *(reinterpret_cast(this) - slot - 1); + } + void enterLoop(Zone *zone); + void leaveLoop(Zone *zone); + void accept(VirtualObjectVisitor *visitor); +}; + +// RAII object for calling a function from C++. +class InvokeArgs +{ + friend class Stack; + + Stack *stack_; + LocalSlot *args_; + unsigned nargs_; + + public: + InvokeArgs() + : stack_(NULL), + args_(NULL), + nargs_(0) + { + } + + ~InvokeArgs(); + + LocalSlot &arg(unsigned index) { + assert(index < nargs_); + return args_[nargs_ - index - 1]; + } +}; + +// RAII object for calling a native from C++. +class NativeArgs +{ + friend class Stack; + + Stack *stack_; + LocalSlot *argsBase_; + + public: + NativeArgs() + : stack_(NULL), + argsBase_(NULL) + { + } + + ~NativeArgs(); + + intptr_t *args() { + return reinterpret_cast(argsBase_); + } +}; + +class Stack +{ + friend class InvokeArgs; + friend class NativeArgs; + + private: + static const size_t STACK_SIZE = 1024 * 1024; + + public: + Stack(Zone *zone); + ~Stack(); + + bool initialize(); + + public: + Frame *pushInlineFrame(Handle fun); + Frame *popInlineFrame(); + + bool pushInvokeFrame(Handle fun, InvokeArgs &args); + bool pushModuleFrame(Handle module, InvokeArgs &args); + bool pushNativeFrame(Handle native, NativeArgs &args, unsigned argc); + + Top *top() { + return &top_; + } + bool isInCallStack(Handle module); + void accept(VirtualObjectVisitor *visitor); + + private: + void popInvokeFrame(InvokeArgs &args); + void popNativeFrame(NativeArgs &args); + + private: + Zone *zone_; + char *buffer_; + char *end_; + Top top_; +}; + +class StackIter +{ + bytecode *pc_; + Frame *fp_; + + public: + StackIter(Zone *zone); + + bool done() const; + const char *function() const; + unsigned lineNumber() const; + const char *source() const; + void prev(); +}; + +} + +#endif // _include_jc_stack_h_