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