Allow structs to contain arrays.
Allow structs to contain arrays.
1.1 --- a/src/BytecodeCompiler.cpp Sun Sep 16 22:49:54 2012 -0700
1.2 +++ b/src/BytecodeCompiler.cpp Sun Sep 16 23:15:13 2012 -0700
1.3 @@ -987,10 +987,17 @@
1.4 }
1.5 }
1.6 } else if (type->isStruct()) {
1.7 - Local<Map> map(zone_, type->newMap());
1.8 + Local<StructMap> map(zone_, StructMap::cast(type->newMap()));
1.9 +
1.10 + // Because structs can contain arrays, any sort of composition
1.11 + // triggers non-LIFO allocation. This is just for correctness.
1.12 + // We could do better by:
1.13 + // (1) Limiting to structs that just (recursively) contain arrays,
1.14 + // (2) Swap Stack for Default tenure in Struct::New
1.15 + // (3) JIT analysis
1.16 if (var->scope()->kind() == Scope::GLOBAL)
1.17 __ newstruct(map, Heap::Tenure_Old);
1.18 - else if (var->needsHeapAllocation())
1.19 + else if (var->needsHeapAllocation() || map->composed())
1.20 __ newstruct(map, Heap::Tenure_Default);
1.21 else
1.22 __ newstruct(map, Heap::Tenure_Stack);
2.1 --- a/src/Parser.cpp Sun Sep 16 22:49:54 2012 -0700
2.2 +++ b/src/Parser.cpp Sun Sep 16 23:15:13 2012 -0700
2.3 @@ -1162,10 +1162,10 @@
2.4 SourcePosition pos = scanner_.begin();
2.5
2.6 ExpressionList *postDimensions = NULL;
2.7 - //if (peek(TOK_LBRACKET)) {
2.8 - // if ((postDimensions = dimensions()) == NULL)
2.9 - // return NULL;
2.10 - //}
2.11 + if (peek(TOK_LBRACKET)) {
2.12 + if ((postDimensions = dimensions()) == NULL)
2.13 + return NULL;
2.14 + }
2.15
2.16 if (!matchSemicolon())
2.17 return NULL;
3.1 --- a/src/SemanticAnalysis.cpp Sun Sep 16 22:49:54 2012 -0700
3.2 +++ b/src/SemanticAnalysis.cpp Sun Sep 16 23:15:13 2012 -0700
3.3 @@ -1760,7 +1760,16 @@
3.4 if (!type)
3.5 return;
3.6
3.7 - if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
3.8 + if (field->dimensions()) {
3.9 + type = buildArrayType(type, field->dimensions(), false);
3.10 + if (!type)
3.11 + return;
3.12 +
3.13 + if (!ArrayMap::Attach(zone_, type))
3.14 + return;
3.15 + }
3.16 +
3.17 + if (IsScalarString(type)) {
3.18 cc_.reportError(field->pos(), Message_CannotDeclareStringCell);
3.19 return;
3.20 }
4.1 --- a/src/Structures.cpp Sun Sep 16 22:49:54 2012 -0700
4.2 +++ b/src/Structures.cpp Sun Sep 16 23:15:13 2012 -0700
4.3 @@ -20,6 +20,7 @@
4.4 #include "Structures.h"
4.5 #include "Zone.h"
4.6 #include "Types.h"
4.7 +#include "Array.h"
4.8 #include "Spaces-inl.h"
4.9 #include "Heap-inl.h"
4.10
4.11 @@ -98,16 +99,23 @@
4.12 // struct allocation, rather than inlined in bytecode, for simplicity.
4.13 if (map->composed()) {
4.14 Local<Descriptor> desc(zone);
4.15 - Local<Struct> child(zone);
4.16 - Local<StructMap> childMap(zone);
4.17 + Local<Object> child(zone);
4.18 + Local<StructMap> childStructMap(zone);
4.19 + Local<ArrayMap> childArrayMap(zone);
4.20 +
4.21 for (unsigned i = 0; i < map->composed()->length(); i++) {
4.22 desc = Descriptor::cast(map->composed()->at(i));
4.23
4.24 - // We don't support composing arrays yet.
4.25 - assert(desc->type()->isStruct());
4.26 -
4.27 - childMap = StructMap::cast(desc->type()->newMap());
4.28 - child = Struct::New(zone, childMap, tenure);
4.29 + if (desc->type()->isStruct()) {
4.30 + childStructMap = StructMap::cast(desc->type()->newMap());
4.31 + child = Struct::New(zone, childStructMap, tenure);
4.32 + } else if (desc->type()->isArray()) {
4.33 + childArrayMap = ArrayMap::cast(desc->type()->newMap());
4.34 + if (desc->type()->isFixedLength())
4.35 + child = Array::NewFixed(zone, childArrayMap, tenure);
4.36 + else
4.37 + child = Array::NewEmpty(zone, childArrayMap, tenure);
4.38 + }
4.39 if (!child)
4.40 return NULL;
4.41