Basic support for parsing and creating types from structure syntax.
authorDavid Anderson <dvander@alliedmods.net>
Sat Aug 04 17:51:43 2012 -0700 (2012-08-04)
changeset 146dc7d3b7a918c
parent 145 e9d804821c48
child 147 9c544823d090
Basic support for parsing and creating types from structure syntax.
src/AST.h
src/BytecodeCompiler.cpp
src/BytecodeCompiler.h
src/ObjectVisitor.h
src/Objects.h
src/Parser.cpp
src/Parser.h
src/Scanner.cpp
src/SemanticAnalysis.cpp
src/SemanticAnalysis.h
src/Structures.cpp
src/Structures.h
src/Token.h
src/TypeManager.cpp
src/TypeManager.h
src/Types.cpp
src/Types.h
src/Zone.cpp
     1.1 --- a/src/AST.h	Wed Aug 01 22:32:59 2012 -0700
     1.2 +++ b/src/AST.h	Sat Aug 04 17:51:43 2012 -0700
     1.3 @@ -49,7 +49,8 @@
     1.4      _(IncDecExpression)         \
     1.5      _(UnaryExpression)          \
     1.6      _(TernaryExpression)        \
     1.7 -    _(BooleanLiteral)
     1.8 +    _(BooleanLiteral)           \
     1.9 +    _(StructureStatement)
    1.10  
    1.11  // Forward declarations.
    1.12  #define _(name) class name;
    1.13 @@ -866,6 +867,72 @@
    1.14      }
    1.15  };
    1.16  
    1.17 +class StructureStatement : public Statement
    1.18 +{
    1.19 +  public:
    1.20 +    class Field : public PoolObject
    1.21 +    {
    1.22 +        SourcePosition pos_;
    1.23 +        BoundName *type_;
    1.24 +        ScopedRoot<String> name_;
    1.25 +        ExpressionList *dimensions_;
    1.26 +
    1.27 +      public:
    1.28 +        Field(const SourcePosition &pos,
    1.29 +              BoundName *type,
    1.30 +              Handle<String> name,
    1.31 +              ExpressionList *dimensions)
    1.32 +          : pos_(pos),
    1.33 +            type_(type),
    1.34 +            name_(name),
    1.35 +            dimensions_(dimensions)
    1.36 +        {
    1.37 +        }
    1.38 +
    1.39 +        const SourcePosition &pos() const {
    1.40 +            return pos_;
    1.41 +        }
    1.42 +        BoundName *type() const {
    1.43 +            return type_;
    1.44 +        }
    1.45 +        String *name() const {
    1.46 +            return name_;
    1.47 +        }
    1.48 +        ExpressionList *dimensions() const {
    1.49 +            return dimensions_;
    1.50 +        }
    1.51 +    };
    1.52 +
    1.53 +    typedef PoolList<StructureStatement::Field *> FieldList;
    1.54 +
    1.55 +  public:
    1.56 +    StructureStatement(const SourcePosition &pos, NamedType *decl, FieldList *fields)
    1.57 +      : Statement(pos),
    1.58 +        decl_(decl),
    1.59 +        fields_(fields)
    1.60 +    {
    1.61 +    }
    1.62 +
    1.63 +    Kind kind() const {
    1.64 +        return kStructureStatement;
    1.65 +    }
    1.66 +    FieldList *fields() const {
    1.67 +        return fields_;
    1.68 +    }
    1.69 +    NamedType *decl() const {
    1.70 +        return decl_;
    1.71 +    }
    1.72 +    void accept(AstVisitor *visitor) {
    1.73 +        visitor->visit(this);
    1.74 +    }
    1.75 +
    1.76 +  private:
    1.77 +    NamedType *decl_;
    1.78 +    FieldList *fields_;
    1.79 +};
    1.80 +
    1.81 +typedef StructureStatement::FieldList FieldList;
    1.82 +
    1.83  class Scope;
    1.84  
    1.85  typedef PoolList<NameProxy *> NameProxyList;
     2.1 --- a/src/BytecodeCompiler.cpp	Wed Aug 01 22:32:59 2012 -0700
     2.2 +++ b/src/BytecodeCompiler.cpp	Sat Aug 04 17:51:43 2012 -0700
     2.3 @@ -929,6 +929,11 @@
     2.4      // :TODO: eventually, we'll export these.
     2.5  }
     2.6  
     2.7 +void
     2.8 +BytecodeCompiler::visit(StructureStatement *node)
     2.9 +{
    2.10 +}
    2.11 +
    2.12  Code *
    2.13  BytecodeCompiler::compileCode(Scope *scope, unsigned lineno)
    2.14  {
     3.1 --- a/src/BytecodeCompiler.h	Wed Aug 01 22:32:59 2012 -0700
     3.2 +++ b/src/BytecodeCompiler.h	Sat Aug 04 17:51:43 2012 -0700
     3.3 @@ -143,6 +143,7 @@
     3.4      void visit(IncDecExpression *node);
     3.5      void visit(UnaryExpression *node);
     3.6      void visit(TernaryExpression *node);
     3.7 +    void visit(StructureStatement *node);
     3.8  };
     3.9  
    3.10  }
     4.1 --- a/src/ObjectVisitor.h	Wed Aug 01 22:32:59 2012 -0700
     4.2 +++ b/src/ObjectVisitor.h	Sat Aug 04 17:51:43 2012 -0700
     4.3 @@ -29,6 +29,7 @@
     4.4  #include "Array.h"
     4.5  #include "Strings.h"
     4.6  #include "Environments.h"
     4.7 +#include "Structures.h"
     4.8  
     4.9  namespace ke {
    4.10  
    4.11 @@ -48,6 +49,7 @@
    4.12          visitField(obj, Type::offsetOfReturnType());
    4.13          visitField(obj, Type::offsetOfParameters());
    4.14          visitField(obj, Type::offsetOfName());
    4.15 +        visitField(obj, Type::offsetOfFields());
    4.16          return sizeof(Type);
    4.17      }
    4.18  
    4.19 @@ -95,6 +97,12 @@
    4.20          return sizeof(Function);
    4.21      }
    4.22  
    4.23 +    size_t iterateDescriptor(Object *obj) {
    4.24 +        visitField(obj, Descriptor::offsetOfName());
    4.25 +        visitField(obj, Descriptor::offsetOfType());
    4.26 +        return sizeof(Descriptor);
    4.27 +    }
    4.28 +
    4.29      size_t iterateNative(Object *obj) {
    4.30          visitField(obj, Native::offsetOfType());
    4.31          visitField(obj, Native::offsetOfName());
    4.32 @@ -173,6 +181,9 @@
    4.33            case MapKind_Function:
    4.34              return iterateFunction(obj);
    4.35  
    4.36 +          case MapKind_Descriptor:
    4.37 +            return iterateDescriptor(obj);
    4.38 +
    4.39            case MapKind_String:
    4.40              return iterateString(obj);
    4.41  
    4.42 @@ -223,6 +234,9 @@
    4.43        case MapKind_Module:
    4.44          return sizeof(Module);
    4.45  
    4.46 +      case MapKind_Descriptor:
    4.47 +        return sizeof(Descriptor);
    4.48 +
    4.49        case MapKind_Function:
    4.50          return sizeof(Function);
    4.51  
     5.1 --- a/src/Objects.h	Wed Aug 01 22:32:59 2012 -0700
     5.2 +++ b/src/Objects.h	Sat Aug 04 17:51:43 2012 -0700
     5.3 @@ -50,6 +50,7 @@
     5.4      MapKind_FreeRegion,     // Special map denoting freed space.
     5.5      MapKind_EnvironmentSlotDescriptorArray,
     5.6      MapKind_Environment,
     5.7 +    MapKind_Descriptor,
     5.8  
     5.9      // Used to represent Arrays. This does not have a canonical map.
    5.10      MapKind_Array,
     6.1 --- a/src/Parser.cpp	Wed Aug 01 22:32:59 2012 -0700
     6.2 +++ b/src/Parser.cpp	Sat Aug 04 17:51:43 2012 -0700
     6.3 @@ -892,6 +892,11 @@
     6.4              return NULL;
     6.5          break;
     6.6  
     6.7 +      case TOK_STRUCT:
     6.8 +        if ((statement = struct_()) == NULL)
     6.9 +            return NULL;
    6.10 +        break;
    6.11 +
    6.12        case TOK_IF:
    6.13          return if_();
    6.14  
    6.15 @@ -914,6 +919,68 @@
    6.16  }
    6.17  
    6.18  Statement *
    6.19 +Parser::struct_()
    6.20 +{
    6.21 +    expect(TOK_STRUCT);
    6.22 +
    6.23 +    Local<String> name(zone_, expectName());
    6.24 +    if (!name)
    6.25 +        return NULL;
    6.26 +
    6.27 +    SourcePosition pos = scanner_.begin();
    6.28 +
    6.29 +    if (BoundName *other = scope_->localLookup(name)) {
    6.30 +        redeclarationError(other);
    6.31 +        return NULL;
    6.32 +    }
    6.33 +
    6.34 +    NamedType *type;
    6.35 +    if ((type = scope_->declareType(name, scanner_.begin())) == NULL)
    6.36 +        return NULL;
    6.37 +
    6.38 +    if (!expect(TOK_LBRACE))
    6.39 +        return NULL;
    6.40 +
    6.41 +    FieldList *fields = new (pool_) FieldList();
    6.42 +
    6.43 +    while (!peek(TOK_RBRACE)) {
    6.44 +        if (matchName(name.ref(), TOK_LABEL) && !name)
    6.45 +            return NULL;
    6.46 +
    6.47 +        BoundName *type = NULL;
    6.48 +        if (name) {
    6.49 +            if ((type = bindType(name)) == NULL)
    6.50 +                return NULL;
    6.51 +        }
    6.52 +
    6.53 +        name = expectName();
    6.54 +        if (!name)
    6.55 +            return NULL;
    6.56 +
    6.57 +        SourcePosition pos = scanner_.begin();
    6.58 +
    6.59 +        ExpressionList *postDimensions = NULL;
    6.60 +        if (peek(TOK_LBRACKET)) {
    6.61 +            if ((postDimensions = dimensions()) == NULL)
    6.62 +                return NULL;
    6.63 +        }
    6.64 +
    6.65 +        if (!matchSemicolon())
    6.66 +            return NULL;
    6.67 +
    6.68 +        StructureStatement::Field *field =
    6.69 +            new (pool_) StructureStatement::Field(pos, type, name, postDimensions);
    6.70 +        if (!field || !fields->append(field))
    6.71 +            return NULL;
    6.72 +    }
    6.73 +
    6.74 +    if (!expect(TOK_RBRACE))
    6.75 +        return NULL;
    6.76 +
    6.77 +    return new (pool_) StructureStatement(pos, type, fields);
    6.78 +}
    6.79 +
    6.80 +Statement *
    6.81  Parser::enum_()
    6.82  {
    6.83      expect(TOK_ENUM);
    6.84 @@ -1202,6 +1269,13 @@
    6.85                  return NULL;
    6.86              break;
    6.87  
    6.88 +          case TOK_STRUCT:
    6.89 +            if ((statement = struct_()) == NULL)
    6.90 +                return NULL;
    6.91 +            if (!matchSemicolon())
    6.92 +                return NULL;
    6.93 +            break;
    6.94 +
    6.95            default:
    6.96              cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
    6.97              return NULL;
    6.98 @@ -1417,6 +1491,10 @@
    6.99          node->expression()->accept(this);
   6.100          unindent();
   6.101      }
   6.102 +    void visit(StructureStatement *node) {
   6.103 +        prefix();
   6.104 +        fprintf(fp_, "[ StructureStatement\n");
   6.105 +    }
   6.106  };
   6.107  
   6.108  void
     7.1 --- a/src/Parser.h	Wed Aug 01 22:32:59 2012 -0700
     7.2 +++ b/src/Parser.h	Sat Aug 04 17:51:43 2012 -0700
     7.3 @@ -76,6 +76,7 @@
     7.4      Expression *assignment();
     7.5      Expression *expression();
     7.6  
     7.7 +    Statement *struct_();
     7.8      Statement *enum_();
     7.9      Statement *if_();
    7.10      Statement *block(Scope *scope = NULL);
     8.1 --- a/src/Scanner.cpp	Wed Aug 01 22:32:59 2012 -0700
     8.2 +++ b/src/Scanner.cpp	Sat Aug 04 17:51:43 2012 -0700
     8.3 @@ -409,6 +409,8 @@
     8.4          return TOK_TRUE;
     8.5      if (!strcmp(literal(),  "false"))
     8.6          return TOK_FALSE;
     8.7 +    if (!strcmp(literal(), "struct"))
     8.8 +        return TOK_STRUCT;
     8.9      return (c == ':') ? TOK_LABEL : TOK_NAME;
    8.10  }
    8.11  
     9.1 --- a/src/SemanticAnalysis.cpp	Wed Aug 01 22:32:59 2012 -0700
     9.2 +++ b/src/SemanticAnalysis.cpp	Sat Aug 04 17:51:43 2012 -0700
     9.3 @@ -159,6 +159,8 @@
     9.4                  return false;
     9.5  
     9.6              enumstmt->decl()->setType(type);
     9.7 +        } else if (statement->isStructureStatement()) {
     9.8 +            statement->accept(this);
     9.9          }
    9.10      }
    9.11  
    9.12 @@ -1208,6 +1210,50 @@
    9.13  }
    9.14  
    9.15  void
    9.16 +SemanticAnalysis::visit(StructureStatement *node)
    9.17 +{
    9.18 +    // If this node already has a type, it was pre-analyzed, so skip it.
    9.19 +    if (node->decl()->type())
    9.20 +        return;
    9.21 +
    9.22 +    FieldList *fields = node->fields();
    9.23 +    Local<FixedArray> desctable(zone_, FixedArray::New(zone_, fields->length(), Heap::Tenure_Old));
    9.24 +    if (!desctable)
    9.25 +        return;
    9.26 +
    9.27 +    StructureBufferBuilder builder;
    9.28 +
    9.29 +    Local<Type> type(zone_);
    9.30 +    Local<String> name(zone_);
    9.31 +    Local<Descriptor> desc(zone_);
    9.32 +    for (size_t i = 0; i < fields->length(); i++) {
    9.33 +        StructureStatement::Field *field = fields->at(i);
    9.34 +
    9.35 +        type = bindType(field->pos(), field->type());
    9.36 +        if (!type)
    9.37 +            return;
    9.38 +
    9.39 +        unsigned offset;
    9.40 +        if (!builder.add(type, &offset))
    9.41 +            return;
    9.42 +
    9.43 +        name = field->name();
    9.44 +        desc = Descriptor::New(zone_, name, type, offset);
    9.45 +        if (!desc)
    9.46 +            return;
    9.47 +
    9.48 +        desctable->set(zone_, i, desc);
    9.49 +    }
    9.50 +
    9.51 +    name = node->decl()->name();
    9.52 +    type = zone_->types()->newStruct(name, desctable);
    9.53 +    if (!type)
    9.54 +        return;
    9.55 +
    9.56 +    node->decl()->setType(type);
    9.57 +}
    9.58 +
    9.59 +void
    9.60  SemanticAnalysis::visit(StringLiteral *node)
    9.61  {
    9.62      Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
    10.1 --- a/src/SemanticAnalysis.h	Wed Aug 01 22:32:59 2012 -0700
    10.2 +++ b/src/SemanticAnalysis.h	Sat Aug 04 17:51:43 2012 -0700
    10.3 @@ -203,6 +203,7 @@
    10.4      void visit(UnaryExpression *node);
    10.5      void visit(TernaryExpression *node);
    10.6      void visit(BooleanLiteral *node);
    10.7 +    void visit(StructureStatement *node);
    10.8  };
    10.9  
   10.10  const char *GetTypeName(Type *type);
    11.1 --- a/src/Structures.cpp	Wed Aug 01 22:32:59 2012 -0700
    11.2 +++ b/src/Structures.cpp	Sat Aug 04 17:51:43 2012 -0700
    11.3 @@ -1,22 +1,23 @@
    11.4 -/* vim: set ts=4 sw=4 tw=99 et
    11.5 +/* vim: set ts=4 sw=4 tw=99 et:
    11.6   *
    11.7   * Copyright (C) 2012 David Anderson
    11.8   *
    11.9 - * This file is part of JITCraft.
   11.10 + * This file is part of SourcePawn.
   11.11   *
   11.12 - * JITCraft is free software: you can redistribute it and/or modify it under
   11.13 + * SourcePawn is free software: you can redistribute it and/or modify it under
   11.14   * the terms of the GNU General Public License as published by the Free
   11.15   * Software Foundation, either version 3 of the License, or (at your option)
   11.16   * any later version.
   11.17   * 
   11.18 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   11.19 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
   11.20   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   11.21   * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   11.22   *
   11.23   * You should have received a copy of the GNU General Public License along with
   11.24 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   11.25 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
   11.26   */
   11.27  #include "Structures.h"
   11.28 +#include "Zone.h"
   11.29  #include "Types.h"
   11.30  #include "Spaces-inl.h"
   11.31  #include "Heap-inl.h"
   11.32 @@ -46,3 +47,18 @@
   11.33      size_ += sizeof(Object *);
   11.34      return true;
   11.35  }
   11.36 +
   11.37 +Descriptor *
   11.38 +Descriptor::New(Zone *zone, Handle<String> name, Handle<Type> type, unsigned offset)
   11.39 +{
   11.40 +    Local<Descriptor> desc(zone,
   11.41 +        Descriptor::cast(zone->allocate(MapKind_Descriptor, sizeof(Descriptor), Heap::Tenure_Old)));
   11.42 +    if (!desc)
   11.43 +        return NULL;
   11.44 +
   11.45 +    desc->name_ = name;
   11.46 +    desc->type_ = type;
   11.47 +    desc->offset_ = offset;
   11.48 +    return desc;
   11.49 +}
   11.50 +
    12.1 --- a/src/Structures.h	Wed Aug 01 22:32:59 2012 -0700
    12.2 +++ b/src/Structures.h	Sat Aug 04 17:51:43 2012 -0700
    12.3 @@ -1,20 +1,20 @@
    12.4 -/* vim: set ts=4 sw=4 tw=99 et
    12.5 +/* vim: set ts=4 sw=4 tw=99 et:
    12.6   *
    12.7   * Copyright (C) 2012 David Anderson
    12.8   *
    12.9 - * This file is part of JITCraft.
   12.10 + * This file is part of SourcePawn.
   12.11   *
   12.12 - * JITCraft is free software: you can redistribute it and/or modify it under
   12.13 + * SourcePawn is free software: you can redistribute it and/or modify it under
   12.14   * the terms of the GNU General Public License as published by the Free
   12.15   * Software Foundation, either version 3 of the License, or (at your option)
   12.16   * any later version.
   12.17   * 
   12.18 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   12.19 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
   12.20   * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   12.21   * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   12.22   *
   12.23   * You should have received a copy of the GNU General Public License along with
   12.24 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   12.25 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
   12.26   */
   12.27  #ifndef _include_jc_structure_h_
   12.28  #define _include_jc_structure_h_
   12.29 @@ -55,6 +55,48 @@
   12.30      unsigned size_;
   12.31  };
   12.32  
   12.33 +// Represents a property descriptor for a structure field.
   12.34 +class Descriptor : public Object
   12.35 +{
   12.36 +    // The name of the field.
   12.37 +    Barriered<String> name_;
   12.38 +
   12.39 +    // The type of the field.
   12.40 +    Barriered<Type> type_;
   12.41 +
   12.42 +    // The offset into an object at which this field can be accessed.
   12.43 +    unsigned offset_;
   12.44 +
   12.45 +  public:
   12.46 +    static Descriptor *New(Zone *zone, Handle<String> name, Handle<Type> type,
   12.47 +                           unsigned offset);
   12.48 +
   12.49 +    String *name() {
   12.50 +        return name_;
   12.51 +    }
   12.52 +    Type *type() {
   12.53 +        return type_;
   12.54 +    }
   12.55 +    unsigned offset() {
   12.56 +        return offset_;
   12.57 +    }
   12.58 +
   12.59 +    // Begin GC descriptor.
   12.60 +    static inline size_t offsetOfName() {
   12.61 +        return OFFSETOF(Descriptor, name_);
   12.62 +    }
   12.63 +    static inline size_t offsetOfType() {
   12.64 +        return OFFSETOF(Descriptor, type_);
   12.65 +    }
   12.66 +    // End GC descriptor.
   12.67 +    
   12.68 +    static inline Descriptor *cast(Object *obj) {
   12.69 +        assert(!obj || obj->is(MapKind_Descriptor));
   12.70 +        return reinterpret_cast<Descriptor *>(obj);
   12.71 +    }
   12.72 +};
   12.73 +
   12.74  }
   12.75  
   12.76  #endif // _include_jc_structure_h_
   12.77 +
    13.1 --- a/src/Token.h	Wed Aug 01 22:32:59 2012 -0700
    13.2 +++ b/src/Token.h	Sat Aug 04 17:51:43 2012 -0700
    13.3 @@ -68,6 +68,7 @@
    13.4      _(STOCK,              "<stock>")                    \
    13.5      _(TRUE,               "<true>")                     \
    13.6      _(FALSE,              "<false>")                    \
    13.7 +    _(STRUCT,             "<struct>")                   \
    13.8      _(ELLIPSES,           "...")                        \
    13.9      _(PLUS,               "+")                          \
   13.10      _(MINUS,              "-")                          \
    14.1 --- a/src/TypeManager.cpp	Wed Aug 01 22:32:59 2012 -0700
    14.2 +++ b/src/TypeManager.cpp	Sat Aug 04 17:51:43 2012 -0700
    14.3 @@ -97,6 +97,12 @@
    14.4      return Type::NewEnum(zone_, name);
    14.5  }
    14.6  
    14.7 +Type *
    14.8 +TypeManager::newStruct(Handle<String> name, Handle<FixedArray> fields)
    14.9 +{
   14.10 +    return Type::NewStruct(zone_, name, fields);
   14.11 +}
   14.12 +
   14.13  void
   14.14  TypeManager::accept(VirtualObjectVisitor *visitor)
   14.15  {
    15.1 --- a/src/TypeManager.h	Wed Aug 01 22:32:59 2012 -0700
    15.2 +++ b/src/TypeManager.h	Sat Aug 04 17:51:43 2012 -0700
    15.3 @@ -52,6 +52,7 @@
    15.4      Type *newEnum(Handle<String> name);
    15.5      Type *newFunction(Handle<Type> returnType, Handle<FixedArray> args);
    15.6      Type *newNative(Handle<Type> returnType, Handle<FixedArray> args, bool variadic);
    15.7 +    Type *newStruct(Handle<String> name, Handle<FixedArray> fields);
    15.8      
    15.9      void accept(VirtualObjectVisitor *visitor);
   15.10  };
    16.1 --- a/src/Types.cpp	Wed Aug 01 22:32:59 2012 -0700
    16.2 +++ b/src/Types.cpp	Sat Aug 04 17:51:43 2012 -0700
    16.3 @@ -35,6 +35,7 @@
    16.4      type->contained_ = NULL;
    16.5      type->returnType_ = NULL;
    16.6      type->parameters_ = NULL;
    16.7 +    type->fields_ = NULL;
    16.8      return type;
    16.9  }
   16.10  
   16.11 @@ -50,6 +51,7 @@
   16.12      type->contained_ = NULL;
   16.13      type->returnType_ = NULL;
   16.14      type->parameters_ = NULL;
   16.15 +    type->fields_ = NULL;
   16.16      type->primitive_ = prim;
   16.17      return type;
   16.18  }
   16.19 @@ -66,6 +68,7 @@
   16.20      type->contained_ = contained;
   16.21      type->returnType_ = NULL;
   16.22      type->parameters_ = NULL;
   16.23 +    type->fields_ = NULL;
   16.24      type->elements_ = elements;
   16.25      if (!contained->isArray())
   16.26          type->levels_ = 1;
   16.27 @@ -87,6 +90,7 @@
   16.28      type->contained_ = contained;
   16.29      type->returnType_ = NULL;
   16.30      type->parameters_ = NULL;
   16.31 +    type->fields_ = NULL;
   16.32      type->const_ = isConst;
   16.33      return type;
   16.34  }
   16.35 @@ -101,6 +105,7 @@
   16.36      type->kind_ = FUNCTION;
   16.37      type->name_ = NULL;
   16.38      type->contained_ = NULL;
   16.39 +    type->fields_ = NULL;
   16.40      type->returnType_ = returnType;
   16.41      type->parameters_ = parameters;
   16.42      return type;
   16.43 @@ -118,6 +123,23 @@
   16.44      type->contained_ = NULL;
   16.45      type->returnType_ = NULL;
   16.46      type->parameters_ = NULL;
   16.47 +    type->fields_ = NULL;
   16.48 +    return type;
   16.49 +}
   16.50 +
   16.51 +Type *
   16.52 +Type::NewStruct(Zone *zone, Handle<String> name, Handle<FixedArray> fields)
   16.53 +{
   16.54 +    Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   16.55 +    if (!type)
   16.56 +        return NULL;
   16.57 +
   16.58 +    type->kind_ = STRUCT;
   16.59 +    type->name_ = name;
   16.60 +    type->contained_ = NULL;
   16.61 +    type->returnType_ = NULL;
   16.62 +    type->parameters_ = NULL;
   16.63 +    type->fields_ = fields;
   16.64      return type;
   16.65  }
   16.66  
   16.67 @@ -131,6 +153,7 @@
   16.68      type->kind_ = NATIVE;
   16.69      type->name_ = NULL;
   16.70      type->contained_ = NULL;
   16.71 +    type->fields_ = NULL;
   16.72      type->returnType_ = returnType;
   16.73      type->parameters_ = parameters;
   16.74      type->variadicNative_ = variadic;
    17.1 --- a/src/Types.h	Wed Aug 01 22:32:59 2012 -0700
    17.2 +++ b/src/Types.h	Sat Aug 04 17:51:43 2012 -0700
    17.3 @@ -63,7 +63,8 @@
    17.4          FUNCTION,
    17.5          NATIVE,
    17.6          VOID,
    17.7 -        ENUM
    17.8 +        ENUM,
    17.9 +        STRUCT
   17.10      };
   17.11  
   17.12    private:
   17.13 @@ -82,6 +83,7 @@
   17.14      static Type *NewFunction(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters);
   17.15      static Type *NewNative(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters, bool isVariadic);
   17.16      static Type *NewEnum(Zone *zone, Handle<String> name);
   17.17 +    static Type *NewStruct(Zone *zone, Handle<String> name, Handle<FixedArray> fields);
   17.18  
   17.19      static bool Compare(Type *left, Type *right);
   17.20  
   17.21 @@ -195,6 +197,9 @@
   17.22      static inline size_t offsetOfName() {
   17.23          return OFFSETOF(Type, name_);
   17.24      }
   17.25 +    static inline size_t offsetOfFields() {
   17.26 +        return OFFSETOF(Type, fields_);
   17.27 +    }
   17.28      // End GC Descriptor.
   17.29  
   17.30    private:
   17.31 @@ -216,8 +221,11 @@
   17.32      Barriered<FixedArray> parameters_;
   17.33      bool variadicNative_;
   17.34  
   17.35 -    // Enums only.
   17.36 +    // Enums and structs only.
   17.37      Barriered<String> name_;
   17.38 +
   17.39 +    // Structs only.
   17.40 +    Barriered<FixedArray> fields_;
   17.41  };
   17.42  
   17.43  class BoxedPrimitive
    18.1 --- a/src/Zone.cpp	Wed Aug 01 22:32:59 2012 -0700
    18.2 +++ b/src/Zone.cpp	Sat Aug 04 17:51:43 2012 -0700
    18.3 @@ -88,6 +88,8 @@
    18.4          return false;
    18.5      if ((maps_[MapKind_Native] = allocateMap(MapKind_Native, sizeof(Map))) == NULL)
    18.6          return false;
    18.7 +    if ((maps_[MapKind_Descriptor] = allocateMap(MapKind_Descriptor, sizeof(Map))) == NULL)
    18.8 +        return false;
    18.9      if ((maps_[MapKind_FreeRegion] = allocateMap(MapKind_FreeRegion, sizeof(Map))) == NULL)
   18.10          return false;
   18.11      if ((maps_[MapKind_EnvironmentSlotDescriptorArray] =