Split ArrayType from Type.
authorDavid Anderson <dvander@alliedmods.net>
Sat Nov 17 23:11:38 2012 -0800 (2012-11-17)
changeset 2095cbec15fadfe
parent 208 7c5be05296e3
child 210 2f9997088e9b
Split ArrayType from Type.
src/API.cpp
src/Array.cpp
src/Array.h
src/Interpreter.cpp
src/ObjectVisitor.h
src/Objects.h
src/TypeManager.cpp
src/TypeManager.h
src/Types.cpp
src/Types.h
src/Zone.cpp
src/compiler/AST.h
src/compiler/HIR.cpp
src/compiler/NameBinding.cpp
src/compiler/Parser.cpp
src/compiler/Symbols.h
src/jitcraft.vcxproj
tests/basic/float-arrays.sp
tests/prototype/float-arrays.sp
     1.1 --- a/src/API.cpp	Sat Nov 17 22:02:08 2012 -0800
     1.2 +++ b/src/API.cpp	Sat Nov 17 23:11:38 2012 -0800
     1.3 @@ -275,20 +275,25 @@
     1.4  {
     1.5      switch (param.type()) {
     1.6        case Ke::Parameter::Array:
     1.7 -        return type->isArray() &&
     1.8 -               type->levels() == 1 &&
     1.9 -               (type->contained()->isPrimitive() || type->contained()->isEnum()) &&
    1.10 -               (type->contained()->primitive() != PrimitiveType_Char);
    1.11 +      {
    1.12 +        if (!type->isArray())
    1.13 +            return false;
    1.14 +
    1.15 +        ArrayType *atype = ArrayType::cast(type);
    1.16 +        return atype->levels() == 1 &&
    1.17 +               (atype->contained()->isPrimitive() || atype->contained()->isEnum()) &&
    1.18 +               (atype->contained()->primitive() != PrimitiveType_Char);
    1.19 +      }
    1.20        case Ke::Parameter::CharArray:
    1.21 -        return type->isCharArray();
    1.22 +        return type->isArray() && ArrayType::cast(type)->isCharArray();
    1.23        case Ke::Parameter::Float:
    1.24          return type->isFloat();
    1.25        case Ke::Parameter::FloatRef:
    1.26 -        return type->isReference() && type->contained()->isFloat();
    1.27 +        return type->isReference() && type->contained_ref()->isFloat();
    1.28        case Ke::Parameter::Int:
    1.29          return type->isInt32() || type->isEnum();
    1.30        case Ke::Parameter::IntRef:
    1.31 -       return type->isReference() && (type->contained()->isInt32() || type->contained()->isEnum());
    1.32 +       return type->isReference() && (type->contained_ref()->isInt32() || type->contained_ref()->isEnum());
    1.33        default:
    1.34          return false;
    1.35      }
     2.1 --- a/src/Array.cpp	Sat Nov 17 22:02:08 2012 -0800
     2.2 +++ b/src/Array.cpp	Sat Nov 17 23:11:38 2012 -0800
     2.3 @@ -27,7 +27,7 @@
     2.4  using namespace ke;
     2.5  
     2.6  ArrayMap *
     2.7 -ArrayMap::New(Zone *zone, Handle<Type> type)
     2.8 +ArrayMap::New(Zone *zone, Handle<ArrayType> type)
     2.9  {
    2.10      Local<Map> obj(zone, zone->allocateMap(MapKind_Array, sizeof(ArrayMap), MapKind_MetaArray));
    2.11      if (!obj)
    2.12 @@ -39,7 +39,7 @@
    2.13  }
    2.14  
    2.15  ArrayMap *
    2.16 -ArrayMap::Attach(Zone *zone, Handle<Type> type)
    2.17 +ArrayMap::Attach(Zone *zone, Handle<ArrayType> type)
    2.18  {
    2.19      if (type->newMap())
    2.20          return ArrayMap::cast(type->newMap());
    2.21 @@ -50,7 +50,7 @@
    2.22  
    2.23      // Ensure the inner type has an ArrayMap if needed.
    2.24      if (type->contained()->isArray()) {
    2.25 -        Local<Type> contained(zone, type->contained());
    2.26 +        Local<ArrayType> contained(zone, ArrayType::cast(type->contained()));
    2.27          if (!ArrayMap::Attach(zone, contained))
    2.28              return NULL;
    2.29      }
    2.30 @@ -114,7 +114,8 @@
    2.31  
    2.32      // If this is an array of structs, we're required to allocate those structs now.
    2.33      if (map->type()->contained()->isStruct()) {
    2.34 -        Local<StructMap> childMap(zone, StructMap::cast(map->type()->contained()->newMap()));
    2.35 +        Local<StructType> childType(zone, StructType::cast(map->type()->contained()));
    2.36 +        Local<StructMap> childMap(zone, childType->newMap());
    2.37          Local<Struct> child(zone);
    2.38          for (unsigned i = 0; i < nelements; i++) {
    2.39              child = Struct::New(zone, childMap, tenure);
    2.40 @@ -137,7 +138,8 @@
    2.41          return NULL;
    2.42  
    2.43      if (map->type()->contained()->isArray()) {
    2.44 -        Local<ArrayMap> childMap(zone, ArrayMap::cast(map->type()->contained()->newMap()));
    2.45 +        Local<ArrayType> childType(zone, ArrayType::cast(map->type()->contained()));
    2.46 +        Local<ArrayMap> childMap(zone, childType->newMap());
    2.47          Local<Array> child(zone);
    2.48  
    2.49          for (unsigned i = 0; i < unsigned(dims[level]); i++) {
    2.50 @@ -174,7 +176,8 @@
    2.51          return NULL;
    2.52  
    2.53      if (map->type()->contained()->isArray()) {
    2.54 -        Local<ArrayMap> childMap(zone, ArrayMap::cast(map->type()->contained()->newMap()));
    2.55 +        Local<ArrayType> childType(zone, ArrayType::cast(map->type()->contained()));
    2.56 +        Local<ArrayMap> childMap(zone, childType->newMap());
    2.57          Local<Array> child(zone);
    2.58  
    2.59          if (childMap->type()->isFixedLength()) {
     3.1 --- a/src/Array.h	Sat Nov 17 22:02:08 2012 -0800
     3.2 +++ b/src/Array.h	Sat Nov 17 23:11:38 2012 -0800
     3.3 @@ -65,7 +65,7 @@
     3.4          return length_;
     3.5      }
     3.6  
     3.7 -    inline Type *type();
     3.8 +    inline ArrayType *type();
     3.9  
    3.10      inline int *int32Vec();
    3.11      inline float *floatVec();
    3.12 @@ -73,7 +73,7 @@
    3.13      inline void *bytes();
    3.14  
    3.15  
    3.16 -    static inline size_t SizeForElement(Type *type) {
    3.17 +    static inline size_t SizeForElement(ArrayType *type) {
    3.18          if (type->contained()->isTraceable())
    3.19              return sizeof(ke::Object *);
    3.20          if (type->contained()->isInt32())
    3.21 @@ -131,13 +131,13 @@
    3.22  
    3.23  class ArrayMap : public Map
    3.24  {
    3.25 -    Barriered<Type> type_;
    3.26 +    Barriered<ArrayType> type_;
    3.27  
    3.28    public:
    3.29 -    static ArrayMap *New(Zone *zone, Handle<Type> type);
    3.30 -    static ArrayMap *Attach(Zone *zone, Handle<Type> type);
    3.31 +    static ArrayMap *New(Zone *zone, Handle<ArrayType> type);
    3.32 +    static ArrayMap *Attach(Zone *zone, Handle<ArrayType> type);
    3.33  
    3.34 -    Type *type() {
    3.35 +    ArrayType *type() {
    3.36          return type_;
    3.37      }
    3.38  
    3.39 @@ -186,7 +186,7 @@
    3.40      return reinterpret_cast<char *>(bytes());
    3.41  }
    3.42  
    3.43 -inline Type *
    3.44 +inline ArrayType *
    3.45  Array::type()
    3.46  {
    3.47      return ArrayMap::cast(map())->type();
     4.1 --- a/src/Interpreter.cpp	Sat Nov 17 22:02:08 2012 -0800
     4.2 +++ b/src/Interpreter.cpp	Sat Nov 17 23:11:38 2012 -0800
     4.3 @@ -101,7 +101,7 @@
     4.4      }
     4.5  
     4.6      Local<Type> contained(zone, source->type()->contained());
     4.7 -    if (contained->isArray() && contained->isFixedLength()) {
     4.8 +    if (contained->isArray() && ArrayType::cast(contained)->isFixedLength()) {
     4.9          assert(dest->type()->contained()->isArray());
    4.10          assert(source->length() == dest->length());
    4.11  
     5.1 --- a/src/ObjectVisitor.h	Sat Nov 17 22:02:08 2012 -0800
     5.2 +++ b/src/ObjectVisitor.h	Sat Nov 17 23:11:38 2012 -0800
     5.3 @@ -46,22 +46,26 @@
     5.4      }
     5.5  
     5.6      size_t iterateType(Object *obj) {
     5.7 -        visitField(obj, Type::offsetOfContained());
     5.8          visitField(obj, Type::offsetOfName());
     5.9          return sizeof(Type);
    5.10      }
    5.11  
    5.12 +    size_t iterateArrayType(Object *obj) {
    5.13 +        iterateType(obj);
    5.14 +        visitField(obj, ArrayType::offsetOfContained());
    5.15 +        visitField(obj, ArrayType::offsetOfNewMap());
    5.16 +        return sizeof(ArrayType);
    5.17 +    }
    5.18 +
    5.19      size_t iterateStructType(Object *obj) {
    5.20 -        visitField(obj, Type::offsetOfContained());
    5.21 -        visitField(obj, Type::offsetOfName());
    5.22 +        iterateType(obj);
    5.23          visitField(obj, StructType::offsetOfFields());
    5.24          visitField(obj, StructType::offsetOfNewMap());
    5.25          return sizeof(StructType);
    5.26      }
    5.27  
    5.28      size_t iterateFunctionType(Object *obj) {
    5.29 -        visitField(obj, Type::offsetOfContained());
    5.30 -        visitField(obj, Type::offsetOfName());
    5.31 +        iterateType(obj);
    5.32          visitField(obj, FunctionType::offsetOfReturnType());
    5.33          visitField(obj, FunctionType::offsetOfParameters());      
    5.34          visitField(obj, FunctionType::offsetOfDefaults());
    5.35 @@ -191,6 +195,9 @@
    5.36            case MapKind_Type:
    5.37              return iterateType(obj);
    5.38  
    5.39 +          case MapKind_ArrayType:
    5.40 +            return iterateArrayType(obj);
    5.41 +
    5.42            case MapKind_FunctionType:
    5.43              return iterateFunctionType(obj);
    5.44  
    5.45 @@ -271,6 +278,9 @@
    5.46        case MapKind_Type:
    5.47          return sizeof(Type);
    5.48  
    5.49 +      case MapKind_ArrayType:
    5.50 +        return sizeof(ArrayType);
    5.51 +
    5.52        case MapKind_FunctionType:
    5.53          return sizeof(FunctionType);
    5.54  
     6.1 --- a/src/Objects.h	Sat Nov 17 22:02:08 2012 -0800
     6.2 +++ b/src/Objects.h	Sat Nov 17 23:11:38 2012 -0800
     6.3 @@ -37,6 +37,7 @@
     6.4      MapKind_Type,
     6.5      MapKind_FunctionType,
     6.6      MapKind_StructType,
     6.7 +    MapKind_ArrayType,
     6.8  
     6.9      // Represents basic data structures. When adding to this, don't forget
    6.10      // to update Zone::initialize(), or you'll get a NULL crash trying to
     7.1 --- a/src/TypeManager.cpp	Sat Nov 17 22:02:08 2012 -0800
     7.2 +++ b/src/TypeManager.cpp	Sat Nov 17 23:11:38 2012 -0800
     7.3 @@ -65,16 +65,16 @@
     7.4  }
     7.5  
     7.6  Type *
     7.7 -TypeManager::newArray(Handle<Type> contained, int elements, bool isConst)
     7.8 +TypeManager::newArray(Handle<Type> contained, int elements)
     7.9  {
    7.10      // :TODO: cache this.
    7.11 -    return Type::NewArray(zone_, contained, elements, isConst);
    7.12 +    return ArrayType::New(zone_, contained, elements);
    7.13  }
    7.14  
    7.15  Type *
    7.16  TypeManager::newExternalArray(Handle<Type> contained)
    7.17  {
    7.18 -    return Type::NewExternalArray(zone_, contained);
    7.19 +    return ArrayType::NewExternal(zone_, contained);
    7.20  }
    7.21  
    7.22  Type *
     8.1 --- a/src/TypeManager.h	Sat Nov 17 22:02:08 2012 -0800
     8.2 +++ b/src/TypeManager.h	Sat Nov 17 23:11:38 2012 -0800
     8.3 @@ -53,7 +53,7 @@
     8.4          return uncheckedType_;
     8.5      }
     8.6      Type *getReference(Handle<Type> type, bool isConst);
     8.7 -    Type *newArray(Handle<Type> contained, int elements, bool isConst);
     8.8 +    Type *newArray(Handle<Type> contained, int elements);
     8.9      Type *newExternalArray(Handle<Type> contained);
    8.10      Type *newEnum(Handle<String> name);
    8.11      
     9.1 --- a/src/Types.cpp	Sat Nov 17 22:02:08 2012 -0800
     9.2 +++ b/src/Types.cpp	Sat Nov 17 23:11:38 2012 -0800
     9.3 @@ -33,7 +33,6 @@
     9.4          return NULL;
     9.5  
     9.6      type->kind_ = VOID;
     9.7 -    type->contained_ = NULL;
     9.8      return type;
     9.9  }
    9.10  
    9.11 @@ -45,7 +44,6 @@
    9.12          return NULL;
    9.13  
    9.14      type->kind_ = UNCHECKED;
    9.15 -    type->contained_ = NULL;
    9.16      return type;
    9.17  }
    9.18  
    9.19 @@ -58,15 +56,14 @@
    9.20  
    9.21      type->kind_ = PRIMITIVE;
    9.22      type->name_ = NULL;
    9.23 -    type->contained_ = NULL;
    9.24 -    type->primitive_ = prim;
    9.25 +     type->primitive_ = prim;
    9.26      return type;
    9.27  }
    9.28  
    9.29 -Type *
    9.30 -Type::NewArray(Zone *zone, Handle<Type> contained, int elements, bool isConst)
    9.31 +ArrayType *
    9.32 +ArrayType::New(Zone *zone, Handle<Type> contained, int elements)
    9.33  {
    9.34 -    Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    9.35 +    Local<ArrayType> type(zone, ArrayType::cast(zone->allocate(MapKind_ArrayType, sizeof(ArrayType), Heap::Tenure_Old)));
    9.36      if (!type)
    9.37          return NULL;
    9.38  
    9.39 @@ -77,15 +74,14 @@
    9.40      if (!contained->isArray())
    9.41          type->levels_ = 1;
    9.42      else
    9.43 -        type->levels_ = contained->levels() + 1;
    9.44 -    type->const_ = isConst;
    9.45 +        type->levels_ = ArrayType::cast(contained)->levels() + 1;
    9.46      return type;
    9.47  }
    9.48  
    9.49 -Type *
    9.50 -Type::NewExternalArray(Zone *zone, Handle<Type> contained)
    9.51 +ArrayType *
    9.52 +ArrayType::NewExternal(Zone *zone, Handle<Type> contained)
    9.53  {
    9.54 -    Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
    9.55 +    Local<ArrayType> type(zone, ArrayType::cast(zone->allocate(MapKind_ArrayType, sizeof(ArrayType), Heap::Tenure_Old)));
    9.56      if (!type)
    9.57          return NULL;
    9.58  
    9.59 @@ -96,7 +92,6 @@
    9.60      type->contained_ = contained;
    9.61      type->elements_ = DYNAMIC_ARRAY_SIZE;
    9.62      type->levels_ = 1;
    9.63 -    type->const_ = false;
    9.64      return type;
    9.65  }
    9.66  
    9.67 @@ -109,7 +104,6 @@
    9.68  
    9.69      type->kind_ = REFERENCE;
    9.70      type->name_ = NULL;
    9.71 -    type->contained_ = contained;
    9.72      type->const_ = isConst;
    9.73      return type;
    9.74  }
    9.75 @@ -123,7 +117,6 @@
    9.76  
    9.77      type->kind_ = ENUM;
    9.78      type->name_ = name;
    9.79 -    type->contained_ = NULL;
    9.80      return type;
    9.81  }
    9.82  
    9.83 @@ -164,11 +157,15 @@
    9.84  
    9.85        case Type::ARRAY:
    9.86        {
    9.87 -        if (left->levels() != right->levels())
    9.88 -          return false;
    9.89 -        if (left->elements_ != right->elements_)
    9.90 +        ArrayType *aleft = ArrayType::cast(left);
    9.91 +        ArrayType *aright = ArrayType::cast(right);
    9.92 +        if (aleft->levels() != aright->levels())
    9.93              return false;
    9.94 -        return Compare(left->contained(), right->contained());
    9.95 +        if (aleft->isFixedLength() != aright->isFixedLength())
    9.96 +            return false;
    9.97 +        if (aleft->isFixedLength() && aleft->fixedLength() != aright->fixedLength())
    9.98 +            return false;
    9.99 +        return Compare(aleft->contained(), aright->contained());
   9.100        }
   9.101  
   9.102        case Type::FUNCTION:
   9.103 @@ -200,7 +197,7 @@
   9.104  
   9.105        default:
   9.106          assert(left->kind() == Type::REFERENCE);
   9.107 -        return Compare(left->contained(), right->contained());
   9.108 +        return Compare(left->contained_ref(), right->contained_ref());
   9.109      }
   9.110  }
   9.111  
   9.112 @@ -214,7 +211,6 @@
   9.113  
   9.114      type->kind_ = STRUCT;
   9.115      type->name_ = name;
   9.116 -    type->contained_ = NULL;
   9.117      type->newMap_ = NULL;
   9.118      type->fields_ = fields;
   9.119  
   9.120 @@ -264,7 +260,6 @@
   9.121  
   9.122      type->kind_ = FUNCTION;
   9.123      type->name_ = NULL;
   9.124 -    type->contained_ = NULL;
   9.125      type->parameters_ = NULL;
   9.126      type->defaults_ = NULL;
   9.127      type->returnType_ = NULL;
   9.128 @@ -285,7 +280,7 @@
   9.129      if (type->isEnum() || type->isStruct())
   9.130          return type->name()->chars();
   9.131      if (type->isReference())
   9.132 -        type = type->contained();
   9.133 +        type = type->contained_ref();
   9.134      switch (type->primitive()) {
   9.135        case PrimitiveType_Bool:
   9.136          return "bool";
    10.1 --- a/src/Types.h	Sat Nov 17 22:02:08 2012 -0800
    10.2 +++ b/src/Types.h	Sat Nov 17 23:11:38 2012 -0800
    10.3 @@ -29,6 +29,7 @@
    10.4  class String;
    10.5  class Descriptor;
    10.6  class StructMap;
    10.7 +class ArrayMap;
    10.8  
    10.9  #define MAX_ARRAY_DEPTH     5
   10.10  
   10.11 @@ -105,8 +106,6 @@
   10.12      static Type *NewVoid(Zone *zone);
   10.13      static Type *NewUnchecked(Zone *zone);
   10.14      static Type *NewPrimitive(Zone *zone, PrimitiveType type);
   10.15 -    static Type *NewArray(Zone *zone, Handle<Type> contained, int elements, bool isConst);
   10.16 -    static Type *NewExternalArray(Zone *zone, Handle<Type> contained);
   10.17      static Type *NewReference(Zone *zone, Handle<Type> contained, bool isConst);
   10.18      static Type *NewEnum(Zone *zone, Handle<String> name);
   10.19  
   10.20 @@ -116,7 +115,8 @@
   10.21          assert(!obj ||
   10.22                 obj->is(MapKind_Type) ||
   10.23                 obj->is(MapKind_FunctionType) ||
   10.24 -               obj->is(MapKind_StructType));
   10.25 +               obj->is(MapKind_StructType) ||
   10.26 +               obj->is(MapKind_ArrayType));
   10.27          return (Type *)obj;
   10.28      }
   10.29  
   10.30 @@ -156,37 +156,6 @@
   10.31                   : primitive()
   10.32                 : PrimitiveType_Int32;
   10.33      }
   10.34 -    Type *contained() {
   10.35 -        assert(isArray() || isReference());
   10.36 -        return Type::cast(contained_);
   10.37 -    }
   10.38 -    bool isFixedLength() {
   10.39 -        assert(isArray());
   10.40 -        return elements_ > 0;
   10.41 -    }
   10.42 -    unsigned fixedLength() {
   10.43 -        assert(isFixedLength());
   10.44 -        return elements_;
   10.45 -    }
   10.46 -    unsigned levels() {
   10.47 -        assert(isArray());
   10.48 -        return levels_;
   10.49 -    }
   10.50 -    bool hasInlineElements() {
   10.51 -        assert(isArray());
   10.52 -
   10.53 -        // We don't allocate traceable elements inline, since there's no
   10.54 -        // point to the optimization; we're going to be allocating lots of
   10.55 -        // objects anyway (in theory).
   10.56 -        return isFixedLength() && !contained()->isTraceable();
   10.57 -    }
   10.58 -    Type *innermost() {
   10.59 -        assert(isArray());
   10.60 -        Type *temp = contained();
   10.61 -        while (temp->isArray())
   10.62 -            temp = temp->contained();
   10.63 -        return temp;
   10.64 -    }
   10.65      bool isFloat() {
   10.66          return isPrimitive() && primitive() == PrimitiveType_Float;
   10.67      }
   10.68 @@ -199,11 +168,6 @@
   10.69      bool isBool() {
   10.70          return isPrimitive() && primitive() == PrimitiveType_Bool;
   10.71      }
   10.72 -    bool isCharArray() {
   10.73 -        return isArray() &&
   10.74 -               contained()->isPrimitive() &&
   10.75 -               contained()->primitive() == PrimitiveType_Char;
   10.76 -    }
   10.77      bool isExternalArray() {
   10.78          return kind() == EXTERNAL_ARRAY;
   10.79      }
   10.80 @@ -224,19 +188,12 @@
   10.81          assert(isEnum() || isStruct());
   10.82          return name_;
   10.83      }
   10.84 -
   10.85 -    Map *newMap() {
   10.86 +    Type *contained_ref() {
   10.87          assert(false);
   10.88          return NULL;
   10.89      }
   10.90 -    void setNewMap(void *p) {
   10.91 -        assert(false);
   10.92 -    }
   10.93  
   10.94      // GC Descriptor.
   10.95 -    static inline size_t offsetOfContained() {
   10.96 -        return OFFSETOF(Type, contained_);
   10.97 -    }
   10.98      static inline size_t offsetOfName() {
   10.99          return OFFSETOF(Type, name_);
  10.100      }
  10.101 @@ -249,15 +206,80 @@
  10.102      // Primitives, arrays, and references.
  10.103      bool const_;
  10.104  
  10.105 -    // Arrays only.
  10.106 +    // Enums and structs only.
  10.107 +    Barriered<String> name_;
  10.108 +};
  10.109 +
  10.110 +class ArrayType : public Type
  10.111 +{
  10.112 +  public:
  10.113 +    static ArrayType *New(Zone *zone, Handle<Type> contained, int elements);
  10.114 +    static ArrayType *NewExternal(Zone *zone, Handle<Type> contained);
  10.115 +
  10.116 +    Type *innermost() {
  10.117 +        assert(isArray());
  10.118 +        Type *temp = contained();
  10.119 +        while (temp->isArray())
  10.120 +            temp = ArrayType::cast(temp)->contained();
  10.121 +        return temp;
  10.122 +    }
  10.123 +
  10.124 +    Type *contained() {
  10.125 +        return contained_;
  10.126 +    }
  10.127 +    bool isFixedLength() {
  10.128 +        assert(isArray());
  10.129 +        return elements_ > 0;
  10.130 +    }
  10.131 +    bool isCharArray() {
  10.132 +        return contained()->isPrimitive() &&
  10.133 +               contained()->primitive() == PrimitiveType_Char;
  10.134 +    }
  10.135 +    unsigned fixedLength() {
  10.136 +        assert(isFixedLength());
  10.137 +        return elements_;
  10.138 +    }
  10.139 +    unsigned levels() {
  10.140 +        assert(isArray());
  10.141 +        return levels_;
  10.142 +    }
  10.143 +    bool hasInlineElements() {
  10.144 +        assert(isArray());
  10.145 +
  10.146 +        // We don't allocate traceable elements inline, since there's no
  10.147 +        // point to the optimization; we're going to be allocating lots of
  10.148 +        // objects anyway (in theory).
  10.149 +        return isFixedLength() && !contained()->isTraceable();
  10.150 +    }
  10.151 +
  10.152 +    // Arrays of this type can be created with this cached map.
  10.153 +    ArrayMap *newMap() {
  10.154 +        return newMap_;
  10.155 +    }
  10.156 +    void setNewMap(ArrayMap *map) {
  10.157 +        assert(!newMap());
  10.158 +        newMap_ = map;
  10.159 +    }
  10.160 +
  10.161 +    // GC Descriptor.
  10.162 +    static inline size_t offsetOfContained() {
  10.163 +        return OFFSETOF(ArrayType, contained_);
  10.164 +    }
  10.165 +    static inline size_t offsetOfNewMap() {
  10.166 +        return OFFSETOF(ArrayType, newMap_);
  10.167 +    }
  10.168 +    // End GC Descriptor.
  10.169 +
  10.170 +    static ArrayType *cast(Object *obj) {
  10.171 +        assert(!obj || obj->is(MapKind_ArrayType));
  10.172 +        return (ArrayType *)obj;
  10.173 +    }
  10.174 +
  10.175 +  private:
  10.176      int32 elements_;
  10.177      unsigned levels_;
  10.178 -
  10.179 -    // Arrays and references only.
  10.180      Barriered<Type> contained_;
  10.181 -
  10.182 -    // Enums and structs only.
  10.183 -    Barriered<String> name_;
  10.184 +    Barriered<ArrayMap> newMap_;
  10.185  };
  10.186  
  10.187  class StructType : public Type
    11.1 --- a/src/Zone.cpp	Sat Nov 17 22:02:08 2012 -0800
    11.2 +++ b/src/Zone.cpp	Sat Nov 17 23:11:38 2012 -0800
    11.3 @@ -74,45 +74,33 @@
    11.4      if (!nativeTable_ || !nativeTable_->initialize())
    11.5          return false;
    11.6  
    11.7 +    MapKind maps[] =
    11.8 +    {
    11.9 +        MapKind_Type,
   11.10 +        MapKind_ArrayType,
   11.11 +        MapKind_FunctionType,
   11.12 +        MapKind_StructType,
   11.13 +        MapKind_FixedArray,
   11.14 +        MapKind_ByteArray,
   11.15 +        MapKind_Code,
   11.16 +        MapKind_Reference,
   11.17 +        MapKind_MetaArray,
   11.18 +        MapKind_MetaStruct,
   11.19 +        MapKind_MetaEnvironment,
   11.20 +        MapKind_Module,
   11.21 +        MapKind_Function,
   11.22 +        MapKind_String,
   11.23 +        MapKind_Native,
   11.24 +        MapKind_Descriptor,
   11.25 +        MapKind_Box,
   11.26 +        MapKind_FreeRegion,
   11.27 +        MapKind_EnvironmentSlotDescriptorArray
   11.28 +    };
   11.29 +
   11.30      maps_[MapKind_Meta] = heap_.metaMap();
   11.31 -    if ((maps_[MapKind_Type] = allocateMap(MapKind_Type, sizeof(Map))) == NULL)
   11.32 -        return false;
   11.33 -    if ((maps_[MapKind_FunctionType] = allocateMap(MapKind_FunctionType, sizeof(Map))) == NULL)
   11.34 -        return false;
   11.35 -    if ((maps_[MapKind_StructType] = allocateMap(MapKind_StructType, sizeof(Map))) == NULL)
   11.36 -        return false;
   11.37 -    if ((maps_[MapKind_FixedArray] = allocateMap(MapKind_FixedArray, sizeof(Map))) == NULL)
   11.38 -        return false;
   11.39 -    if ((maps_[MapKind_ByteArray] = allocateMap(MapKind_ByteArray, sizeof(Map))) == NULL)
   11.40 -        return false;
   11.41 -    if ((maps_[MapKind_Code] = allocateMap(MapKind_Code, sizeof(Map))) == NULL)
   11.42 -        return false;
   11.43 -    if ((maps_[MapKind_Reference] = allocateMap(MapKind_Reference, sizeof(Map))) == NULL)
   11.44 -        return false;
   11.45 -    if ((maps_[MapKind_MetaArray] = allocateMap(MapKind_MetaArray, sizeof(Map))) == NULL)
   11.46 -        return false;
   11.47 -    if ((maps_[MapKind_MetaStruct] = allocateMap(MapKind_MetaStruct, sizeof(Map))) == NULL)
   11.48 -        return false;
   11.49 -    if ((maps_[MapKind_MetaEnvironment] = allocateMap(MapKind_MetaEnvironment, sizeof(Map))) == NULL)
   11.50 -        return false;
   11.51 -    if ((maps_[MapKind_Module] = allocateMap(MapKind_Module, sizeof(Map))) == NULL)
   11.52 -        return false;
   11.53 -    if ((maps_[MapKind_Function] = allocateMap(MapKind_Function, sizeof(Map))) == NULL)
   11.54 -        return false;
   11.55 -    if ((maps_[MapKind_String] = allocateMap(MapKind_String, sizeof(Map))) == NULL)
   11.56 -        return false;
   11.57 -    if ((maps_[MapKind_Native] = allocateMap(MapKind_Native, sizeof(Map))) == NULL)
   11.58 -        return false;
   11.59 -    if ((maps_[MapKind_Descriptor] = allocateMap(MapKind_Descriptor, sizeof(Map))) == NULL)
   11.60 -        return false;
   11.61 -    if ((maps_[MapKind_Box] = allocateMap(MapKind_Box, sizeof(Map))) == NULL)
   11.62 -        return false;
   11.63 -    if ((maps_[MapKind_FreeRegion] = allocateMap(MapKind_FreeRegion, sizeof(Map))) == NULL)
   11.64 -        return false;
   11.65 -    if ((maps_[MapKind_EnvironmentSlotDescriptorArray] =
   11.66 -         allocateMap(MapKind_EnvironmentSlotDescriptorArray, sizeof(Map))) == NULL)
   11.67 -    {
   11.68 -        return false;
   11.69 +    for (size_t i = 0; i < sizeof(maps) / sizeof(maps[0]); i++) {
   11.70 +        if ((maps_[maps[i]] = allocateMap(maps[i], sizeof(Map))) == NULL)
   11.71 +            return false;
   11.72      }
   11.73  
   11.74      types_ = new TypeManager(this);
    12.1 --- a/src/compiler/AST.h	Sat Nov 17 22:02:08 2012 -0800
    12.2 +++ b/src/compiler/AST.h	Sat Nov 17 23:11:38 2012 -0800
    12.3 @@ -153,16 +153,18 @@
    12.4      TypeQualifiers qual_;
    12.5      ScopedRoot<String> name_;
    12.6      Expression *initialization_;
    12.7 +    ExpressionList *dims_;
    12.8      Expression *type_;
    12.9      VariableSymbol *sym_;
   12.10  
   12.11    public:
   12.12      VariableDeclaration(const SourcePosition &pos, TypeQualifiers qual, Handle<String> name,
   12.13 -                        Expression *type, Expression *initialization)
   12.14 +                        Expression *type, ExpressionList *dims, Expression *initialization)
   12.15        : Statement(pos),
   12.16          qual_(qual),
   12.17          name_(name),
   12.18          initialization_(initialization),
   12.19 +        dims_(dims),
   12.20          type_(type),
   12.21          sym_(NULL)
   12.22      {
   12.23 @@ -189,6 +191,9 @@
   12.24      Expression *type() const {
   12.25          return type_;
   12.26      }
   12.27 +    ExpressionList *dims() const {
   12.28 +        return dims_;
   12.29 +    }
   12.30  };
   12.31  
   12.32  class Parameter : public PoolObject
    13.1 --- a/src/compiler/HIR.cpp	Sat Nov 17 22:02:08 2012 -0800
    13.2 +++ b/src/compiler/HIR.cpp	Sat Nov 17 23:11:38 2012 -0800
    13.3 @@ -110,7 +110,7 @@
    13.4  HLocal::store(BytecodeEmitter &emitter_)
    13.5  {
    13.6      if (sym_->type()->isReference())
    13.7 -        __ setref(sym_->type()->contained());
    13.8 +        __ setref(sym_->type()->contained_ref());
    13.9      else
   13.10          __ setlocal(sym_);
   13.11  }
    14.1 --- a/src/compiler/NameBinding.cpp	Sat Nov 17 22:02:08 2012 -0800
    14.2 +++ b/src/compiler/NameBinding.cpp	Sat Nov 17 23:11:38 2012 -0800
    14.3 @@ -21,6 +21,7 @@
    14.4  #include "../TypeManager.h"
    14.5  #include "NameBinding.h"
    14.6  #include "Scopes.h"
    14.7 +#include "ConstantEvaluator.h"
    14.8  #include "../Spaces-inl.h"
    14.9  #include "../Heap-inl.h"
   14.10  
   14.11 @@ -492,10 +493,15 @@
   14.12          if (!type)
   14.13              return;
   14.14  
   14.15 +        if (node->dims()) {
   14.16 +            
   14.17 +        }
   14.18 +
   14.19          // If the node already has a symbol (meaning it was a global), then
   14.20          // we don't have to do anything more.
   14.21          if (node->sym()) {
   14.22              assert(node->sym()->scope()->kind() == Scope::GLOBAL);
   14.23 +            node->sym()->setType(type);
   14.24              return;
   14.25          }
   14.26  
    15.1 --- a/src/compiler/Parser.cpp	Sat Nov 17 22:02:08 2012 -0800
    15.2 +++ b/src/compiler/Parser.cpp	Sat Nov 17 23:11:38 2012 -0800
    15.3 @@ -881,6 +881,12 @@
    15.4      if (!typeAndName(&type, name.ref()))
    15.5          return NULL;
    15.6  
    15.7 +    ExpressionList *dims = NULL;
    15.8 +    if (match(TOK_LBRACE)) {
    15.9 +        if ((dims = dimensions()) == NULL)
   15.10 +            return NULL;;
   15.11 +    }
   15.12 +
   15.13      SourcePosition pos = scanner_.begin();
   15.14      
   15.15      Expression *expr = NULL;
   15.16 @@ -899,7 +905,7 @@
   15.17          }
   15.18      }
   15.19  
   15.20 -    return new (pool_) VariableDeclaration(pos, qual, name, type, expr);
   15.21 +    return new (pool_) VariableDeclaration(pos, qual, name, type, dims, expr);
   15.22  }
   15.23  
   15.24  Statement *
    16.1 --- a/src/compiler/Symbols.h	Sat Nov 17 22:02:08 2012 -0800
    16.2 +++ b/src/compiler/Symbols.h	Sat Nov 17 23:11:38 2012 -0800
    16.3 @@ -134,6 +134,7 @@
    16.4          return kVariable;
    16.5      }
    16.6      void setType(Type *type) {
    16.7 +        assert(!type_);
    16.8          type_ = type;
    16.9      }
   16.10      void allocate(Storage storage, unsigned slot) {
    17.1 --- a/src/jitcraft.vcxproj	Sat Nov 17 22:02:08 2012 -0800
    17.2 +++ b/src/jitcraft.vcxproj	Sat Nov 17 23:11:38 2012 -0800
    17.3 @@ -141,6 +141,7 @@
    17.4      <ClInclude Include="compiler\AST.h" />
    17.5      <ClInclude Include="compiler\BytecodeEmitter.h" />
    17.6      <ClInclude Include="compiler\CompileContext.h" />
    17.7 +    <ClInclude Include="compiler\ConstantEvaluator.h" />
    17.8      <ClInclude Include="compiler\HIR.h" />
    17.9      <ClInclude Include="compiler\NameBinding.h" />
   17.10      <ClInclude Include="compiler\Parser.h" />
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/tests/basic/float-arrays.sp	Sat Nov 17 23:11:38 2012 -0800
    18.3 @@ -0,0 +1,9 @@
    18.4 +native PrintFloat(Float:num);
    18.5 +
    18.6 +public main()
    18.7 +{
    18.8 +   new float:vec[3];
    18.9 +   for (new i = 0; i < 3; i = i + 1)
   18.10 +     vec[i] = i + 9.5;
   18.11 +   PrintFloat(vec[2]);
   18.12 +}
    19.1 --- a/tests/prototype/float-arrays.sp	Sat Nov 17 22:02:08 2012 -0800
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,7 +0,0 @@
    19.4 -main()
    19.5 -{
    19.6 -   new Float:vec[3];
    19.7 -   for (new i = 0; i < 3; i = i + 1)
    19.8 -     vec[i] = i + 9.5;
    19.9 -   return vec[2];
   19.10 -}