jitcraft/Environments.h
changeset 85 06a0015b6a5c
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/jitcraft/Environments.h	Mon Jul 23 01:19:44 2012 -0700
     1.3 @@ -0,0 +1,168 @@
     1.4 +/*
     1.5 + * Copyright (C) 2012 David Anderson
     1.6 + *
     1.7 + * This file is part of JITCraft.
     1.8 + *
     1.9 + * JITCraft is free software: you can redistribute it and/or modify it under
    1.10 + * the terms of the GNU General Public License as published by the Free
    1.11 + * Software Foundation, either version 3 of the License, or (at your option)
    1.12 + * any later version.
    1.13 + * 
    1.14 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    1.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License along with
    1.19 + * JITCraft. If not, see http://www.gnu.org/licenses/.
    1.20 + */
    1.21 +#ifndef _include_ke_environment_h_
    1.22 +#define _include_ke_environment_h_
    1.23 +
    1.24 +#include "Objects.h"
    1.25 +#include "Handles.h"
    1.26 +#include "Heap.h"
    1.27 +#include "FixedArray.h"
    1.28 +
    1.29 +namespace ke {
    1.30 +
    1.31 +class EnvironmentMap;
    1.32 +class Variable;
    1.33 +class ByteArray;
    1.34 +class Type;
    1.35 +
    1.36 +// An environment represents the lexical environment of a code or function
    1.37 +// object. It used for variables which may be accessed outside a function's
    1.38 +// normal activation (i.e., upvars).
    1.39 +//
    1.40 +// A module uses an Environment to store its global variables.
    1.41 +class Environment : public Object
    1.42 +{
    1.43 +    template <typename T>
    1.44 +    inline T *pointerToSlot(unsigned slot);
    1.45 +
    1.46 +  public:
    1.47 +    static Environment *New(Zone *zone, Handle<EnvironmentMap> map, Heap::Tenure tenure = Heap::Tenure_Default);
    1.48 +
    1.49 +    inline EnvironmentMap *map();
    1.50 +    inline size_t size();
    1.51 +
    1.52 +    float getFloat(unsigned slot) {
    1.53 +        return *pointerToSlot<float>(slot);
    1.54 +    }
    1.55 +    int getInt32(unsigned slot) {
    1.56 +        return *pointerToSlot<int>(slot);
    1.57 +    }
    1.58 +    Object *getObject(unsigned slot) {
    1.59 +        return *pointerToSlot<Object *>(slot);
    1.60 +    }
    1.61 +    void setFloat(unsigned slot, float f) {
    1.62 +        *pointerToSlot<float>(slot) = f;
    1.63 +    }
    1.64 +    void setInt32(unsigned slot, int i) {
    1.65 +        *pointerToSlot<int>(slot) = i;
    1.66 +    }
    1.67 +    void setObject(unsigned slot, Object *obj) {
    1.68 +        // :TODO: write barrier
    1.69 +        *pointerToSlot<Object *>(slot) = obj;
    1.70 +    }
    1.71 +
    1.72 +    static inline size_t offsetOfSlotOffset(unsigned offset) {
    1.73 +        return sizeof(Environment) + offset;
    1.74 +    }
    1.75 +
    1.76 +    static inline Environment *cast(Object *obj) {
    1.77 +        assert(!obj || obj->is(MapKind_Environment));
    1.78 +        return reinterpret_cast<Environment *>(obj);
    1.79 +    }
    1.80 +};
    1.81 +
    1.82 +struct EnvironmentSlotDescriptor
    1.83 +{
    1.84 +    Barriered<Type> type;
    1.85 +    unsigned offset;
    1.86 +};
    1.87 +
    1.88 +class EnvironmentSlotDescriptorArray : public Object
    1.89 +{
    1.90 +    unsigned length_;
    1.91 +
    1.92 +  public:
    1.93 +    static EnvironmentSlotDescriptorArray *New(Zone *zone, unsigned length);
    1.94 +
    1.95 +    EnvironmentSlotDescriptor *slots() {
    1.96 +        return reinterpret_cast<EnvironmentSlotDescriptor *>(this + 1);
    1.97 +    }
    1.98 +    EnvironmentSlotDescriptor &at(unsigned slot) {
    1.99 +        assert(slot < length_);
   1.100 +        return slots()[slot];
   1.101 +    }
   1.102 +    unsigned length() {
   1.103 +        return length_;
   1.104 +    }
   1.105 +    unsigned size() {
   1.106 +        return Align(sizeof(*this) + length() * sizeof(EnvironmentSlotDescriptorArray),
   1.107 +                     kObjectAlignment);
   1.108 +    }
   1.109 +
   1.110 +    static inline EnvironmentSlotDescriptorArray *cast(Object *obj) {
   1.111 +        assert(!obj || obj->is(MapKind_EnvironmentSlotDescriptorArray));
   1.112 +        return reinterpret_cast<EnvironmentSlotDescriptorArray *>(obj);
   1.113 +    }
   1.114 +};
   1.115 +
   1.116 +class EnvironmentMap : public Map
   1.117 +{
   1.118 +    unsigned structureSize_;
   1.119 +    unsigned traceOffsetCount_;
   1.120 +    Barriered<EnvironmentSlotDescriptorArray> slots_;
   1.121 +
   1.122 +  public:
   1.123 +    static EnvironmentMap *New(Zone *zone, unsigned nvars, Variable **vars);
   1.124 +
   1.125 +    unsigned structureSize() {
   1.126 +        return structureSize_;
   1.127 +    }
   1.128 +    unsigned traceOffsetCount() {
   1.129 +        return traceOffsetCount_;
   1.130 +    }
   1.131 +    const unsigned *traceOffsets() {
   1.132 +        return reinterpret_cast<unsigned *>(this + 1);
   1.133 +    }
   1.134 +    size_t size() {
   1.135 +        return Align(sizeof(EnvironmentMap) + sizeof(unsigned) * traceOffsetCount(), kObjectAlignment);
   1.136 +    }
   1.137 +    EnvironmentSlotDescriptor &slotDescriptor(unsigned slot) {
   1.138 +        return slots_->at(slot);
   1.139 +    }
   1.140 +
   1.141 +    static inline size_t offsetOfSlots() {
   1.142 +        return offsetof(EnvironmentMap, slots_);
   1.143 +    }
   1.144 +
   1.145 +    static inline EnvironmentMap *cast(Object *obj) {
   1.146 +        assert(!obj || obj->is(MapKind_MetaEnvironment));
   1.147 +        return reinterpret_cast<EnvironmentMap *>(obj);
   1.148 +    }
   1.149 +};
   1.150 +
   1.151 +size_t
   1.152 +Environment::size()
   1.153 +{
   1.154 +    return Align(sizeof(Environment) + map()->structureSize(), kObjectAlignment);
   1.155 +}
   1.156 +
   1.157 +EnvironmentMap *
   1.158 +Environment::map()
   1.159 +{
   1.160 +    return EnvironmentMap::cast(Object::map());
   1.161 +}
   1.162 +
   1.163 +template <typename T> T *
   1.164 +Environment::pointerToSlot(unsigned slot)
   1.165 +{
   1.166 +    return reinterpret_cast<T *>(reinterpret_cast<char *>(this + 1) + map()->slotDescriptor(slot).offset);
   1.167 +}
   1.168 +
   1.169 +}
   1.170 +
   1.171 +#endif // _include_ke_environment_h_