src/Handles.h
author David Anderson <dvander@alliedmods.net>
Sun Jan 06 13:52:21 2013 -0800 (2013-01-06)
changeset 256 3c184218462d
parent 240 e3c851a14f16
child 257 9db4cc815ebc
permissions -rw-r--r--
Initial implementation of module imports.
[email protected]
     1
/* vim: set ts=4 sw=4 tw=99 et:
[email protected]
     2
 *
[email protected]
     3
 * Copyright (C) 2012 David Anderson
[email protected]
     4
 *
[email protected]
     5
 * This file is part of JITCraft.
[email protected]
     6
 *
[email protected]
     7
 * JITCraft is free software: you can redistribute it and/or modify it under
[email protected]
     8
 * the terms of the GNU General Public License as published by the Free
[email protected]
     9
 * Software Foundation, either version 3 of the License, or (at your option)
[email protected]
    10
 * any later version.
[email protected]
    11
 * 
[email protected]
    12
 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
[email protected]
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
[email protected]
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
[email protected]
    15
 *
[email protected]
    16
 * You should have received a copy of the GNU General Public License along with
[email protected]
    17
 * JITCraft. If not, see http://www.gnu.org/licenses/.
[email protected]
    18
 */
[email protected]
    19
#ifndef _include_jitcraft_rooting_h_
[email protected]
    20
#define _include_jitcraft_rooting_h_
[email protected]
    21
[email protected]
    22
#include <stdlib.h>
[email protected]
    23
[email protected]
    24
namespace ke {
[email protected]
    25
[email protected]
    26
class Zone;
[email protected]
    27
class Object;
[email protected]
    28
[email protected]
    29
template <typename T> class Local;
[email protected]
    30
template <typename T> class ScopedRoot;
[email protected]
    31
[email protected]
    32
struct NullAddress
[email protected]
    33
{
[email protected]
    34
    static void * const Sentinel;
[email protected]
    35
};
[email protected]
    36
[email protected]
    37
/*
[email protected]
    38
 * Internal handles work differently from API handles. An API handle is a
[email protected]
    39
 * root, whereas as an internal handle points to a rooted location. This
[email protected]
    40
 * subtle difference makes handles easy for embedders, but somewhat
[email protected]
    41
 * cumbersome internally.
[email protected]
    42
 */
[email protected]
    43
template <typename T>
[email protected]
    44
class Handle
[email protected]
    45
{
[email protected]
    46
    T * const *thingp_;
[email protected]
    47
[email protected]
    48
  private:
[email protected]
    49
    Handle()
[email protected]
    50
      : thingp_(reinterpret_cast<T * const *>(&NullAddress::Sentinel))
[email protected]
    51
    {
[email protected]
    52
    }
[email protected]
    53
[email protected]
    54
  public:
[email protected]
    55
    Handle(const Handle &other) {
[email protected]
    56
        thingp_ = other.address();
[email protected]
    57
    }
[email protected]
    58
    template <typename S> Handle(const Handle<S> &handle) {
[email protected]
    59
        typeCheck<S>();
[email protected]
    60
        thingp_ = reinterpret_cast<T * const *>(handle.address());
[email protected]
    61
    }
[email protected]
    62
    template <typename S> inline Handle(const Local<S> &local);
[email protected]
    63
    template <typename S> inline Handle(const ScopedRoot<S> &root);
[email protected]
    64
[email protected]
    65
    static inline Handle Null() {
[email protected]
    66
        return Handle();
[email protected]
    67
    }
[email protected]
    68
[email protected]
    69
  public:
[email protected]
    70
    T *operator ->() {
[email protected]
    71
        return *thingp_;
[email protected]
    72
    }
[email protected]
    73
    T *operator *() {
[email protected]
    74
        return *thingp_;
[email protected]
    75
    }
[email protected]
    76
    operator T *() const { return *thingp_; }
[email protected]
    77
    operator bool() const {
[email protected]
    78
        return thingp_ && *thingp_;
[email protected]
    79
    }
[email protected]
    80
    T * const *address() const {
[email protected]
    81
        return thingp_;
[email protected]
    82
    }
[email protected]
    83
[email protected]
    84
    bool operator ==(const Handle<T> &other) const {
[email protected]
    85
        return (!thingp_ && !other.thingp_) ||
[email protected]
    86
               *thingp_ == *other.thingp_;
[email protected]
    87
    }
[email protected]
    88
    bool operator !=(const Handle<T> &other) const {
[email protected]
    89
        return (!thingp_ != !other.thingp_) ||
[email protected]
    90
               *thingp_ != *other.thingp_;
[email protected]
    91
    }
[email protected]
    92
[email protected]
    93
  private:
[email protected]
    94
    template <typename S>
[email protected]
    95
    void typeCheck() {
[email protected]
    96
#ifndef NDEBUG
[email protected]
    97
        T *v1 = NULL;
[email protected]
    98
        S *v2 = NULL;
[email protected]
    99
        v1 = v2;
[email protected]
   100
        (void)v1;
[email protected]
   101
#endif
[email protected]
   102
    }
[email protected]
   103
};
[email protected]
   104
[email protected]
   105
template <typename T>
[email protected]
   106
class Local
[email protected]
   107
{
[email protected]
   108
    friend class Zone;
[email protected]
   109
[email protected]
   110
    Zone *zone_;
[email protected]
   111
    T *thing_;
[email protected]
   112
    Local<Object> *prev_;
[email protected]
   113
[email protected]
   114
    Local<Object> *prev() {
[email protected]
   115
        return prev_;
[email protected]
   116
    }
[email protected]
   117
    Local<Object> *toRaw() {
[email protected]
   118
        return reinterpret_cast<Local<Object>*>(this);
[email protected]
   119
    }
[email protected]
   120
[email protected]
   121
  public:
[email protected]
   122
    // These are implemented in Zone.h.
[email protected]
   123
    inline explicit Local(Zone *zone, T *thing = NULL);
[email protected]
   124
    inline ~Local();
[email protected]
   125
[email protected]
   126
    const Local &operator =(T *thing) {
[email protected]
   127
        thing_ = thing;
[email protected]
   128
        return *this;
[email protected]
   129
    }
[email protected]
   130
    T *operator ->() const {
[email protected]
   131
        return operator *();
[email protected]
   132
    }
[email protected]
   133
    T *operator *() const {
[email protected]
   134
        return thing_;
[email protected]
   135
    }
[email protected]
   136
    operator bool () const {
[email protected]
   137
        return !!thing_;
[email protected]
   138
    }
[email protected]
   139
    bool operator !=(const Local &other) {
[email protected]
   140
        return thing_ != other.thing_;
[email protected]
   141
    }
[email protected]
   142
[email protected]
   143
    T **address() {
[email protected]
   144
        return (T **)&thing_;
[email protected]
   145
    }
[email protected]
   146
    T * const *address() const {
[email protected]
   147
        return (T * const *)&thing_;
[email protected]
   148
    }
[email protected]
   149
    T **ref() {
[email protected]
   150
        return &thing_;
[email protected]
   151
    }
[email protected]
   152
    operator T *() {
[email protected]
   153
        return thing_;
[email protected]
   154
    }
[email protected]
   155
[email protected]
   156
    Local &operator =(const Local &other) {
[email protected]
   157
        thing_ = other.thing_;
[email protected]
   158
        return *this;
[email protected]
   159
    }
[email protected]
   160
[email protected]
   161
  private:
[email protected]
   162
    // Disallow heap allocation.
[email protected]
   163
    void *operator new(size_t size);
[email protected]
   164
    void *operator new[](size_t size);
[email protected]
   165
[email protected]
   166
    // Disallow copy construction.
[email protected]
   167
    Local(const Local<T> &other);
[email protected]
   168
};
[email protected]
   169
[email protected]
   170
// A ScopedRoot is a special kind of handle for storing references on the
[email protected]
   171
// heap in bulk.
[email protected]
   172
template <typename T>
[email protected]
   173
class ScopedRoot : public PoolObject
[email protected]
   174
{
[email protected]
   175
    T **thingp_;
[email protected]
   176
[email protected]
   177
  private:
[email protected]
   178
    // This is implemented in Zone.h.
[email protected]
   179
    inline T **make(T *other);
[email protected]
   180
[email protected]
   181
    void assign(T *other) {
[email protected]
   182
        *thingp_ = other;
[email protected]
   183
    }
[email protected]
   184
[email protected]
   185
  public:
[email protected]
   186
    ScopedRoot();
[email protected]
   187
[email protected]
   188
    // This is implemented in Zone.h.
[email protected]
   189
    inline ScopedRoot(T *thing);
[email protected]
   190
[email protected]
   191
    ScopedRoot &operator =(const ScopedRoot<T> &other) {
[email protected]
   192
        assign(*other);
[email protected]
   193
        return *this;
[email protected]
   194
    }
[email protected]
   195
    ScopedRoot &operator =(T *other) {
[email protected]
   196
        assign(other);
[email protected]
   197
        return *this;
[email protected]
   198
    }
[email protected]
   199
    T *operator ->() const {
[email protected]
   200
        return operator *();
[email protected]
   201
    }
[email protected]
   202
    T *operator *() const {
[email protected]
   203
        return *thingp_;
[email protected]
   204
    }
[email protected]
   205
    operator T *() const {
[email protected]
   206
        return *thingp_;
[email protected]
   207
    }
[email protected]
   208
    operator bool () const {
[email protected]
   209
        return !!*thingp_;
[email protected]
   210
    }
[email protected]
   211
    T **address() const {
[email protected]
   212
        return thingp_;
[email protected]
   213
    }
[email protected]
   214
};
[email protected]
   215
[email protected]
   216
template <typename T> template <typename S> inline
[email protected]
   217
Handle<T>::Handle(const Local<S> &local)
[email protected]
   218
{
[email protected]
   219
    typeCheck<S>();
[email protected]
   220
    thingp_ = reinterpret_cast<T * const *>(local.address());
[email protected]
   221
}
[email protected]
   222
[email protected]
   223
template <typename T> template <typename S> inline
[email protected]
   224
Handle<T>::Handle(const ScopedRoot<S> &root)
[email protected]
   225
{
[email protected]
   226
    typeCheck<S>();
[email protected]
   227
    thingp_ = reinterpret_cast<T * const *>(root.address());
[email protected]
   228
}
[email protected]
   229
[email protected]
   230
}
[email protected]
   231
[email protected]
   232
#endif // _include_jitcraft_rooting_h_