jitcraft/Handles.h
author David Anderson <dvander@alliedmods.net>
Mon Jul 02 14:04:29 2012 -0700 (2012-07-02)
changeset 27 28697d267222
parent 11 a350c2cc736a
child 28 a9665857cfd5
permissions -rw-r--r--
Temporary checkin of rooting stuff (breaks build).
     1 /*
     2  * Copyright (C) 2012 David Anderson
     3  *
     4  * This file is part of JITCraft.
     5  *
     6  * JITCraft is free software: you can redistribute it and/or modify it under
     7  * the terms of the GNU General Public License as published by the Free
     8  * Software Foundation, either version 3 of the License, or (at your option)
     9  * any later version.
    10  * 
    11  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    12  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    13  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License along with
    16  * JITCraft. If not, see http://www.gnu.org/licenses/.
    17  */
    18 #ifndef _include_jitcraft_rooting_h_
    19 #define _include_jitcraft_rooting_h_
    20 
    21 #include "Heap.h"
    22 
    23 namespace jc {
    24 
    25 class Zone;
    26 
    27 template <typename T> class Local;
    28 template <typename T> class ScopedRoot;
    29 
    30 template <typename T>
    31 class Handle
    32 {
    33     T * const *thingp_;
    34 
    35   public:
    36     template <typename S> Handle(const Handle<S> &handle) {
    37         typeCheck<S>();
    38         thingp_ = reinterpret_cast<const T **>(handle.thingp_);
    39     }
    40     template <typename S> inline Handle(const Local<S> &local);
    41     template <typename S> inline Handle(const ScopedRoot<S> &root);
    42 
    43   public:
    44     T *operator ->() {
    45         return *thingp_;
    46     }
    47     T *operator *() {
    48         return *thingp_;
    49     }
    50     operator T() { return *thingp_; }
    51     operator bool() const {
    52         return thingp_ && *thingp_;
    53     }
    54     T **addr() const {
    55         return thingp_;
    56     }
    57 
    58   private:
    59     template <typename S>
    60     void typeCheck() {
    61 #ifdef DEBUG
    62         T *v1 = NULL;
    63         S *v2 = NULL;
    64         v1 = v2;
    65         (void)v1;
    66 #endif
    67     }
    68 };
    69 
    70 template <typename T>
    71 class Local
    72 {
    73     friend class Zone;
    74 
    75     Zone *zone_;
    76     Local<Object> *prev_;
    77     T *thing_;
    78 
    79     Local<Object> *prev() {
    80         return prev_;
    81     }
    82     Local<Object> *toRaw() {
    83         return reinterpret_cast<Local<Object>*>(this);
    84     }
    85 
    86   public:
    87     inline explicit Local(Zone *zone);
    88     inline explicit Local(Zone *zone, T *thing);
    89     inline ~Local();
    90 
    91     const Local &operator =(T *thing) {
    92         thing_ = thing;
    93         return *this;
    94     }
    95     T *operator ->() const {
    96         return operator *();
    97     }
    98     T *operator *() const {
    99         return thing_;
   100     }
   101     operator bool () const {
   102         return !!thing_;
   103     }
   104 
   105     Object **addr() {
   106         return (Object **)&thing_;
   107     }
   108     Object * const *addr() const {
   109         return (Object * const *)&thing_;
   110     }
   111     operator T *() {
   112         return thing_;
   113     }
   114 
   115   private:
   116     // Disallow heap allocation.
   117     void *operator new(size_t size);
   118     void *operator new[](size_t size);
   119 
   120     // Disallow copy construction.
   121     Local(const Local<T> &other);
   122     Local &operator =(const Local &other);
   123 };
   124 
   125 // A ScopedRoot is a special kind of handle for storing references on the
   126 // heap in bulk.
   127 template <typename T>
   128 class ScopedRoot
   129 {
   130     T *thingp_;
   131 
   132   private:
   133     inline T **make(const T *&other);
   134     inline void assign(const T *&other) {
   135         if (!thingp_)
   136             thingp_ = make(other);
   137         else
   138             *thingp_ = other;
   139     }
   140 
   141   public:
   142     ScopedRoot()
   143     { }
   144     inline ScopedRoot(const T *&thing);
   145     inline ScopedRoot(const ScopedRoot<T> &other);
   146     ScopedRoot &operator =(const ScopedRoot<T> &other) {
   147         assign(*other);
   148         return *this;
   149     }
   150     ScopedRoot &operator =(const T *&other) {
   151         assign(other);
   152         return *this;
   153     }
   154     T *operator ->() const {
   155         return operator *();
   156     }
   157     T *operator *() const {
   158         return thing_;
   159     }
   160     operator bool () const {
   161         return !!thing_;
   162     }
   163 };
   164 
   165 template <typename T> template <typename S> inline
   166 Handle<T>::Handle(const Local<S> &local)
   167 {
   168     typeCheck<S>();
   169     thingp_ = reinterpret_cast<T * const*>(local.addr());
   170 }
   171 
   172 // A RootScope is necessary for using ScopedRoot<>.
   173 class RootScope
   174 {
   175     friend class Zone;
   176 
   177     struct Block
   178     {
   179         static const size_t kItemsPerBlock = 4096 / sizeof(Object *);
   180 
   181         Object **base;
   182         Object **ptr;
   183         Object **end;
   184         Block *prev;
   185         
   186         Block(Block *prev, Object **base)
   187           : base(base),
   188             ptr(base),
   189             end(base + kItemsPerBlock),
   190             prev(prev)
   191         {
   192         }
   193     };
   194 
   195   private:
   196     
   197 };
   198 
   199 }
   200 
   201 #endif // _include_jitcraft_rooting_h_