src/Environments.h
author David Anderson <dvander@alliedmods.net>
Sat Aug 04 17:51:43 2012 -0700 (2012-08-04)
changeset 146 dc7d3b7a918c
parent 91 5f4402180204
child 147 9c544823d090
permissions -rw-r--r--
Basic support for parsing and creating types from structure syntax.
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@85
    47
    inline size_t size();
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@85
   102
    unsigned size() {
dvander@85
   103
        return Align(sizeof(*this) + length() * sizeof(EnvironmentSlotDescriptorArray),
dvander@85
   104
                     kObjectAlignment);
dvander@85
   105
    }
dvander@85
   106
dvander@85
   107
    static inline EnvironmentSlotDescriptorArray *cast(Object *obj) {
dvander@85
   108
        assert(!obj || obj->is(MapKind_EnvironmentSlotDescriptorArray));
dvander@85
   109
        return reinterpret_cast<EnvironmentSlotDescriptorArray *>(obj);
dvander@85
   110
    }
dvander@85
   111
};
dvander@85
   112
dvander@85
   113
class EnvironmentMap : public Map
dvander@85
   114
{
dvander@85
   115
    unsigned structureSize_;
dvander@85
   116
    unsigned traceOffsetCount_;
dvander@85
   117
    Barriered<EnvironmentSlotDescriptorArray> slots_;
dvander@85
   118
dvander@85
   119
  public:
dvander@85
   120
    static EnvironmentMap *New(Zone *zone, unsigned nvars, Variable **vars);
dvander@85
   121
dvander@85
   122
    unsigned structureSize() {
dvander@85
   123
        return structureSize_;
dvander@85
   124
    }
dvander@85
   125
    unsigned traceOffsetCount() {
dvander@85
   126
        return traceOffsetCount_;
dvander@85
   127
    }
dvander@85
   128
    const unsigned *traceOffsets() {
dvander@85
   129
        return reinterpret_cast<unsigned *>(this + 1);
dvander@85
   130
    }
dvander@85
   131
    size_t size() {
dvander@85
   132
        return Align(sizeof(EnvironmentMap) + sizeof(unsigned) * traceOffsetCount(), kObjectAlignment);
dvander@85
   133
    }
dvander@85
   134
    EnvironmentSlotDescriptor &slotDescriptor(unsigned slot) {
dvander@85
   135
        return slots_->at(slot);
dvander@85
   136
    }
dvander@85
   137
dvander@85
   138
    static inline size_t offsetOfSlots() {
danderson@91
   139
        return OFFSETOF(EnvironmentMap, slots_);
dvander@85
   140
    }
dvander@85
   141
dvander@85
   142
    static inline EnvironmentMap *cast(Object *obj) {
dvander@85
   143
        assert(!obj || obj->is(MapKind_MetaEnvironment));
dvander@85
   144
        return reinterpret_cast<EnvironmentMap *>(obj);
dvander@85
   145
    }
dvander@85
   146
};
dvander@85
   147
dvander@85
   148
size_t
dvander@85
   149
Environment::size()
dvander@85
   150
{
dvander@85
   151
    return Align(sizeof(Environment) + map()->structureSize(), kObjectAlignment);
dvander@85
   152
}
dvander@85
   153
dvander@85
   154
EnvironmentMap *
dvander@85
   155
Environment::map()
dvander@85
   156
{
dvander@85
   157
    return EnvironmentMap::cast(Object::map());
dvander@85
   158
}
dvander@85
   159
dvander@85
   160
template <typename T> T *
dvander@85
   161
Environment::pointerToSlot(unsigned slot)
dvander@85
   162
{
dvander@85
   163
    return reinterpret_cast<T *>(reinterpret_cast<char *>(this + 1) + map()->slotDescriptor(slot).offset);
dvander@85
   164
}
dvander@85
   165
dvander@85
   166
}
dvander@85
   167
dvander@85
   168
#endif // _include_ke_environment_h_