src/Environments.h
author David Anderson <dvander@alliedmods.net>
Sun Nov 18 22:18:23 2012 -0800 (2012-11-18)
changeset 219 99e534728b76
parent 161 b3f0aaee735a
child 263 ba85a47ee414
permissions -rw-r--r--
Moved another test case.
dvander@85
     1
/*
dvander@85
     2
 * Copyright (C) 2012 David Anderson
dvander@85
     3
 *
dvander@85
     4
 * This file is part of JITCraft.
dvander@85
     5
 *
dvander@85
     6
 * JITCraft is free software: you can redistribute it and/or modify it under
dvander@85
     7
 * the terms of the GNU General Public License as published by the Free
dvander@85
     8
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@85
     9
 * any later version.
dvander@85
    10
 * 
dvander@85
    11
 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@85
    12
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@85
    13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@85
    14
 *
dvander@85
    15
 * You should have received a copy of the GNU General Public License along with
dvander@85
    16
 * JITCraft. If not, see http://www.gnu.org/licenses/.
dvander@85
    17
 */
dvander@85
    18
#ifndef _include_ke_environment_h_
dvander@85
    19
#define _include_ke_environment_h_
dvander@85
    20
dvander@85
    21
#include "Objects.h"
dvander@85
    22
#include "Handles.h"
dvander@85
    23
#include "Heap.h"
dvander@85
    24
#include "FixedArray.h"
dvander@85
    25
dvander@85
    26
namespace ke {
dvander@85
    27
dvander@85
    28
class EnvironmentMap;
dvander@85
    29
class Variable;
dvander@85
    30
class ByteArray;
dvander@85
    31
class Type;
dvander@85
    32
dvander@85
    33
// An environment represents the lexical environment of a code or function
dvander@85
    34
// object. It used for variables which may be accessed outside a function's
dvander@85
    35
// normal activation (i.e., upvars).
dvander@85
    36
//
dvander@85
    37
// A module uses an Environment to store its global variables.
dvander@85
    38
class Environment : public Object
dvander@85
    39
{
dvander@85
    40
    template <typename T>
dvander@85
    41
    inline T *pointerToSlot(unsigned slot);
dvander@85
    42
dvander@85
    43
  public:
dvander@85
    44
    static Environment *New(Zone *zone, Handle<EnvironmentMap> map, Heap::Tenure tenure = Heap::Tenure_Default);
dvander@85
    45
dvander@85
    46
    inline EnvironmentMap *map();
dvander@161
    47
    inline size_t objSize();
dvander@85
    48
dvander@85
    49
    float getFloat(unsigned slot) {
dvander@85
    50
        return *pointerToSlot<float>(slot);
dvander@85
    51
    }
dvander@85
    52
    int getInt32(unsigned slot) {
dvander@85
    53
        return *pointerToSlot<int>(slot);
dvander@85
    54
    }
dvander@85
    55
    Object *getObject(unsigned slot) {
dvander@85
    56
        return *pointerToSlot<Object *>(slot);
dvander@85
    57
    }
dvander@85
    58
    void setFloat(unsigned slot, float f) {
dvander@85
    59
        *pointerToSlot<float>(slot) = f;
dvander@85
    60
    }
dvander@85
    61
    void setInt32(unsigned slot, int i) {
dvander@85
    62
        *pointerToSlot<int>(slot) = i;
dvander@85
    63
    }
dvander@85
    64
    void setObject(unsigned slot, Object *obj) {
dvander@85
    65
        // :TODO: write barrier
dvander@85
    66
        *pointerToSlot<Object *>(slot) = obj;
dvander@85
    67
    }
dvander@85
    68
dvander@85
    69
    static inline size_t offsetOfSlotOffset(unsigned offset) {
dvander@85
    70
        return sizeof(Environment) + offset;
dvander@85
    71
    }
dvander@85
    72
dvander@85
    73
    static inline Environment *cast(Object *obj) {
dvander@85
    74
        assert(!obj || obj->is(MapKind_Environment));
dvander@85
    75
        return reinterpret_cast<Environment *>(obj);
dvander@85
    76
    }
dvander@85
    77
};
dvander@85
    78
dvander@85
    79
struct EnvironmentSlotDescriptor
dvander@85
    80
{
dvander@85
    81
    Barriered<Type> type;
dvander@85
    82
    unsigned offset;
dvander@85
    83
};
dvander@85
    84
dvander@85
    85
class EnvironmentSlotDescriptorArray : public Object
dvander@85
    86
{
dvander@85
    87
    unsigned length_;
dvander@85
    88
dvander@85
    89
  public:
dvander@85
    90
    static EnvironmentSlotDescriptorArray *New(Zone *zone, unsigned length);
dvander@85
    91
dvander@85
    92
    EnvironmentSlotDescriptor *slots() {
dvander@85
    93
        return reinterpret_cast<EnvironmentSlotDescriptor *>(this + 1);
dvander@85
    94
    }
dvander@85
    95
    EnvironmentSlotDescriptor &at(unsigned slot) {
dvander@85
    96
        assert(slot < length_);
dvander@85
    97
        return slots()[slot];
dvander@85
    98
    }
dvander@85
    99
    unsigned length() {
dvander@85
   100
        return length_;
dvander@85
   101
    }
dvander@161
   102
    unsigned objSize() {
dvander@161
   103
        return sizeof(*this) + length() * sizeof(EnvironmentSlotDescriptorArray);
dvander@85
   104
    }
dvander@85
   105
dvander@85
   106
    static inline EnvironmentSlotDescriptorArray *cast(Object *obj) {
dvander@85
   107
        assert(!obj || obj->is(MapKind_EnvironmentSlotDescriptorArray));
dvander@85
   108
        return reinterpret_cast<EnvironmentSlotDescriptorArray *>(obj);
dvander@85
   109
    }
dvander@85
   110
};
dvander@85
   111
dvander@85
   112
class EnvironmentMap : public Map
dvander@85
   113
{
dvander@85
   114
    unsigned structureSize_;
dvander@85
   115
    unsigned traceOffsetCount_;
dvander@85
   116
    Barriered<EnvironmentSlotDescriptorArray> slots_;
dvander@85
   117
dvander@85
   118
  public:
dvander@85
   119
    static EnvironmentMap *New(Zone *zone, unsigned nvars, Variable **vars);
dvander@85
   120
dvander@85
   121
    unsigned structureSize() {
dvander@85
   122
        return structureSize_;
dvander@85
   123
    }
dvander@85
   124
    unsigned traceOffsetCount() {
dvander@85
   125
        return traceOffsetCount_;
dvander@85
   126
    }
dvander@85
   127
    const unsigned *traceOffsets() {
dvander@85
   128
        return reinterpret_cast<unsigned *>(this + 1);
dvander@85
   129
    }
dvander@161
   130
    size_t objSize() {
dvander@161
   131
        return sizeof(EnvironmentMap) + sizeof(unsigned) * traceOffsetCount();
dvander@85
   132
    }
dvander@85
   133
    EnvironmentSlotDescriptor &slotDescriptor(unsigned slot) {
dvander@85
   134
        return slots_->at(slot);
dvander@85
   135
    }
dvander@85
   136
dvander@147
   137
    // Begin GC descriptors.
dvander@85
   138
    static inline size_t offsetOfSlots() {
danderson@91
   139
        return OFFSETOF(EnvironmentMap, slots_);
dvander@85
   140
    }
dvander@147
   141
    // End GC descriptors.
dvander@85
   142
dvander@85
   143
    static inline EnvironmentMap *cast(Object *obj) {
dvander@85
   144
        assert(!obj || obj->is(MapKind_MetaEnvironment));
dvander@85
   145
        return reinterpret_cast<EnvironmentMap *>(obj);
dvander@85
   146
    }
dvander@85
   147
};
dvander@85
   148
dvander@85
   149
size_t
dvander@161
   150
Environment::objSize()
dvander@85
   151
{
dvander@161
   152
    return sizeof(Environment) + map()->structureSize();
dvander@85
   153
}
dvander@85
   154
dvander@85
   155
EnvironmentMap *
dvander@85
   156
Environment::map()
dvander@85
   157
{
dvander@85
   158
    return EnvironmentMap::cast(Object::map());
dvander@85
   159
}
dvander@85
   160
dvander@85
   161
template <typename T> T *
dvander@85
   162
Environment::pointerToSlot(unsigned slot)
dvander@85
   163
{
dvander@85
   164
    return reinterpret_cast<T *>(reinterpret_cast<char *>(this + 1) + map()->slotDescriptor(slot).offset);
dvander@85
   165
}
dvander@85
   166
dvander@85
   167
}
dvander@85
   168
dvander@85
   169
#endif // _include_ke_environment_h_