Added support for declaring empty-length arrays.
authorDavid Anderson <dvander@alliedmods.net>
Sat Sep 15 18:25:54 2012 -0700 (2012-09-15)
changeset 18510936f3a2ba3
parent 184 387d76b1e981
child 186 03a663e96860
Added support for declaring empty-length arrays.
src/Array.cpp
src/Array.h
src/BytecodeCompiler.cpp
src/BytecodeEmitter.h
src/Interpreter.cpp
src/Opcodes.cpp
src/Opcodes.tbl
src/SemanticAnalysis.cpp
src/TypeManager.cpp
src/TypeManager.h
src/Zone.cpp
     1.1 --- a/src/Array.cpp	Sat Sep 15 17:39:45 2012 -0700
     1.2 +++ b/src/Array.cpp	Sat Sep 15 18:25:54 2012 -0700
     1.3 @@ -72,6 +72,14 @@
     1.4  }
     1.5  
     1.6  Array *
     1.7 +Array::New(Zone *zone, Handle<ArrayMap> map, Heap::Tenure tenure)
     1.8 +{
     1.9 +    assert(map->type()->isFixedLength());
    1.10 +
    1.11 +    return Array::New(zone, map, map->type()->fixedLength(), tenure);
    1.12 +}
    1.13 +
    1.14 +Array *
    1.15  Array::New(Zone *zone, Handle<ArrayMap> map, uint32 elements, Heap::Tenure tenure)
    1.16  {
    1.17      size_t elementBytes = SizeFor(map->type(), elements);
     2.1 --- a/src/Array.h	Sat Sep 15 17:39:45 2012 -0700
     2.2 +++ b/src/Array.h	Sat Sep 15 18:25:54 2012 -0700
     2.3 @@ -34,6 +34,7 @@
     2.4      void *elements_;
     2.5  
     2.6    public:
     2.7 +    static Array *New(Zone *zone, Handle<ArrayMap> map, Heap::Tenure = Heap::Tenure_Default);
     2.8      static Array *New(Zone *zone, Handle<ArrayMap> map, uint32 elements,
     2.9                        Heap::Tenure = Heap::Tenure_Default);
    2.10      static Array *NewString(Zone *zone, Handle<ArrayMap> map, Address buffer, size_t length, Heap::Tenure = Heap::Tenure_Default);
     3.1 --- a/src/BytecodeCompiler.cpp	Sat Sep 15 17:39:45 2012 -0700
     3.2 +++ b/src/BytecodeCompiler.cpp	Sat Sep 15 18:25:54 2012 -0700
     3.3 @@ -783,10 +783,17 @@
     3.4      if (type->isArray()) {
     3.5          Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, type));
     3.6          __ note_position(node->pos());
     3.7 +
     3.8 +        Opcode op;
     3.9 +        if (type->isFixedLength())
    3.10 +            op = OP_NEWFIXED;
    3.11 +        else
    3.12 +            op = OP_NEWEMPTY;
    3.13 +
    3.14          if (var->scope()->kind() == Scope::GLOBAL)
    3.15 -            __ newarray(map, Heap::Tenure_Old);
    3.16 +            __ newarray(op, map, Heap::Tenure_Old);
    3.17          else
    3.18 -            __ newarray(map, Heap::Tenure_Default);
    3.19 +            __ newarray(op, map, Heap::Tenure_Default);
    3.20  
    3.21          if (node->initialization()) {
    3.22              node->initialization()->accept(this);
    3.23 @@ -929,9 +936,9 @@
    3.24                  // Natives cannot escape array references, so we can allocate
    3.25                  // them on the LIFO stack.
    3.26                  if (funType->isNative())
    3.27 -                    __ newarray(map, Heap::Tenure_Stack);
    3.28 +                    __ newarray(OP_NEWFIXED, map, Heap::Tenure_Stack);
    3.29                  else
    3.30 -                    __ newarray(map, Heap::Tenure_Default);
    3.31 +                    __ newarray(OP_NEWFIXED, map, Heap::Tenure_Default);
    3.32                  __ dup();
    3.33                  __ object(array);
    3.34                  __ copyarray();
     4.1 --- a/src/BytecodeEmitter.h	Sat Sep 15 17:39:45 2012 -0700
     4.2 +++ b/src/BytecodeEmitter.h	Sat Sep 15 18:25:54 2012 -0700
     4.3 @@ -436,10 +436,14 @@
     4.4      void cvt_i2f() {
     4.5          singleByteOp(OP_CVT_I2F);
     4.6      }
     4.7 -    void newarray(Handle<Map> map, Heap::Tenure tenure) {
     4.8 +    void newarray(Opcode op, Handle<Map> map, Heap::Tenure tenure) {
     4.9 +        assert(op == OP_NEWFIXED ||
    4.10 +               op == OP_NEWEMPTY ||
    4.11 +               op == OP_NEWSIZED);
    4.12 +
    4.13          recordOops();
    4.14 -        ensure(OP_NEWARRAY_LENGTH);
    4.15 -        writeOp(OP_NEWARRAY);
    4.16 +        ensure(OpcodeInfo[op].length);
    4.17 +        writeOp(op);
    4.18          writeUint8(tenure);
    4.19          writeObject(map);
    4.20          markOop(1);
     5.1 --- a/src/Interpreter.cpp	Sat Sep 15 17:39:45 2012 -0700
     5.2 +++ b/src/Interpreter.cpp	Sat Sep 15 18:25:54 2012 -0700
     5.3 @@ -807,11 +807,23 @@
     5.4      break;
     5.5  }
     5.6  
     5.7 -case OP_NEWARRAY:
     5.8 +case OP_NEWFIXED:
     5.9  {
    5.10      Heap::Tenure tenure = (Heap::Tenure)top.pc[1];
    5.11      Local<ArrayMap> map(zone, ArrayMap::cast(top.fp->code()->map(READ_UINT32(top.pc + 1))));
    5.12 -    Array *array = Array::New(zone, map, map->type()->declaredLength(), tenure);
    5.13 +    Array *array = Array::New(zone, map, tenure);
    5.14 +    if (!array)
    5.15 +        goto error;
    5.16 +    top.sp->obj = array;
    5.17 +    top.sp++;
    5.18 +    break;
    5.19 +}
    5.20 +
    5.21 +case OP_NEWEMPTY:
    5.22 +{
    5.23 +    Heap::Tenure tenure = (Heap::Tenure)top.pc[1];
    5.24 +    Local<ArrayMap> map(zone, ArrayMap::cast(top.fp->code()->map(READ_UINT32(top.pc + 1))));
    5.25 +    Array *array = Array::New(zone, map, 0, tenure);
    5.26      if (!array)
    5.27          goto error;
    5.28      top.sp->obj = array;
     6.1 --- a/src/Opcodes.cpp	Sat Sep 15 17:39:45 2012 -0700
     6.2 +++ b/src/Opcodes.cpp	Sat Sep 15 18:25:54 2012 -0700
     6.3 @@ -78,8 +78,14 @@
     6.4      // safepoint, which is a bug.
     6.5  #ifndef NDEBUG
     6.6      Opcode op = Opcode(*(start() + pcOffset));
     6.7 -    assert(op == OP_CALL || op == OP_NEWARRAY || op == OP_VARREF_LIFO ||
     6.8 -           op == OP_ARGREF_LIFO || op == OP_SLOTREF_LIFO || op == OP_ARRAYREF_LIFO ||
     6.9 +    assert(op == OP_CALL ||
    6.10 +           op == OP_NEWFIXED ||
    6.11 +           op == OP_NEWEMPTY ||
    6.12 +           op == OP_NEWSIZED ||
    6.13 +           op == OP_VARREF_LIFO ||
    6.14 +           op == OP_ARGREF_LIFO ||
    6.15 +           op == OP_SLOTREF_LIFO ||
    6.16 +           op == OP_ARRAYREF_LIFO ||
    6.17             op == OP_COPYARRAY);
    6.18  #endif
    6.19  
    6.20 @@ -240,7 +246,9 @@
    6.21              fprintf(fp, "%u (%+d)", unsigned((pc + READ_INT32(pc)) - code->start()), READ_INT32(pc));
    6.22              break;
    6.23  
    6.24 -          case OP_NEWARRAY:
    6.25 +          case OP_NEWFIXED:
    6.26 +          case OP_NEWEMPTY:
    6.27 +          case OP_NEWSIZED:
    6.28            {
    6.29              Heap::Tenure tenure = (Heap::Tenure)pc[1];
    6.30              //ArrayMap *map = ArrayMap::cast(code->map(READ_UINT32(pc + 1)));
     7.1 --- a/src/Opcodes.tbl	Sat Sep 15 17:39:45 2012 -0700
     7.2 +++ b/src/Opcodes.tbl	Sat Sep 15 18:25:54 2012 -0700
     7.3 @@ -103,87 +103,94 @@
     7.4  OPDEF(OP_GETARG,        38,         "getarg",       5,      0,  1)
     7.5  OPDEF(OP_SETARG,        39,         "setarg",       5,      1,  1)
     7.6  
     7.7 -// Allocate an array. The HeapTenure is stored as a byte following pc. The
     7.8 -// ArrayMap to use is specified as an index into the script's Map table.
     7.9 +// Allocates either:
    7.10 +//   A fixed array, 
    7.11 +//   A 0-length dynamic array, or
    7.12 +//   A dynamic array whose size is specified on the stack.
    7.13 +//
    7.14 +// The HeapTenure is stored as a byte following the pc. The ArrayMap to use
    7.15 +// is specified as an index into the script's object table.
    7.16  //
    7.17  // Format:
    7.18  //  [u8 op] [u8 tenure] [u32 index]
    7.19 -OPDEF(OP_NEWARRAY,      40,         "newarray",     6,      0,  1)
    7.20 +OPDEF(OP_NEWFIXED,      40,         "newfixed",     6,      0, 1)
    7.21 +OPDEF(OP_NEWEMPTY,      41,         "newempty",     6,      0, 1)
    7.22 +OPDEF(OP_NEWSIZED,      42,         "newsized",     6,      1, 1)
    7.23  
    7.24  // Performs an array-to-array assignment.
    7.25  //   Left = pop()
    7.26  //   Right = pop()
    7.27  //   copy(Left, Right)
    7.28  //   push(Left)
    7.29 -OPDEF(OP_COPYARRAY,     41,         "arraycopy",    1,      2,  1)
    7.30 +OPDEF(OP_COPYARRAY,     43,         "arraycopy",    1,      2,  1)
    7.31  
    7.32  // Reads or writes an integer element to an unsafe array.
    7.33  //  index = pop()
    7.34  //  ref = pop()
    7.35  //  ref[index]
    7.36  //
    7.37 -OPDEF(OP_GETELEM,       42,         "getelem",      1,      2,  1)
    7.38 -OPDEF(OP_SETELEM,       43,         "setelem",      1,      3,  1)
    7.39 +OPDEF(OP_GETELEM,       44,         "getelem",      1,      2,  1)
    7.40 +OPDEF(OP_SETELEM,       45,         "setelem",      1,      3,  1)
    7.41  
    7.42  // Pushes a 32-bit IEEE-754 floating point immediate onto the stack.
    7.43 -OPDEF(OP_FLOAT,         44,         "float",        5,      0,  1)
    7.44 +OPDEF(OP_FLOAT,         46,         "float",        5,      0,  1)
    7.45  
    7.46  // Converts an integer to a 32-bit IEEE-754 floating point immediate.
    7.47 -OPDEF(OP_CVT_I2F,       45,         "cvt.i2f",      1,      1,  1)
    7.48 +OPDEF(OP_CVT_I2F,       47,         "cvt.i2f",      1,      1,  1)
    7.49  
    7.50  // Stack transitions for these binary operators:
    7.51  // rhs = pop()
    7.52  // lhs = pop()
    7.53  // push(lhs OP rhs)
    7.54 -OPDEF(OP_ADD_F,         46,         "add.f",        1,      2,  1)
    7.55 -OPDEF(OP_SUB_F,         47,         "sub.f",        1,      2,  1)
    7.56 -OPDEF(OP_MUL_F,         48,         "mul.f",        1,      2,  1)
    7.57 -OPDEF(OP_DIV_F,         49,         "div.f",        1,      2,  1)
    7.58 +OPDEF(OP_ADD_F,         48,         "add.f",        1,      2,  1)
    7.59 +OPDEF(OP_SUB_F,         49,         "sub.f",        1,      2,  1)
    7.60 +OPDEF(OP_MUL_F,         50,         "mul.f",        1,      2,  1)
    7.61 +OPDEF(OP_DIV_F,         51,         "div.f",        1,      2,  1)
    7.62  
    7.63 -OPDEF(OP_LT_F,          50,         "lt.f",         1,      2,  1)
    7.64 -OPDEF(OP_LE_F,          51,         "le.f",         1,      2,  1)
    7.65 -OPDEF(OP_GE_F,          52,         "ge.f",         1,      2,  1)
    7.66 -OPDEF(OP_GT_F,          53,         "gt.f",         1,      2,  1)
    7.67 -OPDEF(OP_EQ_F,          54,         "eq.f",         1,      2,  1)
    7.68 -OPDEF(OP_NE_F,          55,         "ne.f",         1,      2,  1)
    7.69 +OPDEF(OP_LT_F,          52,         "lt.f",         1,      2,  1)
    7.70 +OPDEF(OP_LE_F,          53,         "le.f",         1,      2,  1)
    7.71 +OPDEF(OP_GE_F,          54,         "ge.f",         1,      2,  1)
    7.72 +OPDEF(OP_GT_F,          55,         "gt.f",         1,      2,  1)
    7.73 +OPDEF(OP_EQ_F,          56,         "eq.f",         1,      2,  1)
    7.74 +OPDEF(OP_NE_F,          57,         "ne.f",         1,      2,  1)
    7.75  
    7.76 -OPDEF(OP_NOT_F,         56,         "not.f",        1,      1,  1)
    7.77 -OPDEF(OP_NEG_F,         57,         "neg.f",        1,      1,  1)
    7.78 +OPDEF(OP_NOT_F,         58,         "not.f",        1,      1,  1)
    7.79 +OPDEF(OP_NEG_F,         59,         "neg.f",        1,      1,  1)
    7.80  
    7.81  // Bitwise operators.
    7.82 -OPDEF(OP_SHL,           58,         "shl",          1,      2,  1)
    7.83 -OPDEF(OP_SHR,           59,         "shr",          1,      2,  1)
    7.84 -OPDEF(OP_USHR,          60,         "ushr",         1,      2,  1)
    7.85 -OPDEF(OP_BITAND,        61,         "bitand",       1,      2,  1)
    7.86 -OPDEF(OP_BITOR,         62,         "bitor",        1,      2,  1)
    7.87 -OPDEF(OP_BITXOR,        63,         "bitxor",       1,      2,  1)
    7.88 -OPDEF(OP_BITNOT,        64,         "bitnot",       1,      1,  1)
    7.89 +OPDEF(OP_SHL,           60,         "shl",          1,      2,  1)
    7.90 +OPDEF(OP_SHR,           61,         "shr",          1,      2,  1)
    7.91 +OPDEF(OP_USHR,          62,         "ushr",         1,      2,  1)
    7.92 +OPDEF(OP_BITAND,        63,         "bitand",       1,      2,  1)
    7.93 +OPDEF(OP_BITOR,         64,         "bitor",        1,      2,  1)
    7.94 +OPDEF(OP_BITXOR,        65,         "bitxor",       1,      2,  1)
    7.95 +OPDEF(OP_BITNOT,        66,         "bitnot",       1,      1,  1)
    7.96  
    7.97  // Saves or restores the position of the LIFO heap to/from a local slot.
    7.98 -OPDEF(OP_SAVELIFO,      65,         "savelifo",     5,      0,  0)
    7.99 -OPDEF(OP_UNWINDLIFO,    66,         "unwindlifo",   5,      0,  0)
   7.100 +OPDEF(OP_SAVELIFO,      67,         "savelifo",     5,      0,  0)
   7.101 +OPDEF(OP_UNWINDLIFO,    68,         "unwindlifo",   5,      0,  0)
   7.102  
   7.103  // Composes a variable reference to a stack slot or argument.
   7.104 -OPDEF(OP_VARREF_LIFO,   67,         "varref.lifo",  5,      0,  1)
   7.105 -OPDEF(OP_ARGREF_LIFO,   68,         "argref.lifo",  5,      0,  1)
   7.106 -OPDEF(OP_SLOTREF_LIFO,  69,         "slotref.lifo", 1,      1,  1)
   7.107 -OPDEF(OP_ARRAYREF_LIFO, 70,         "arrayref.lifo",1,      2,  1)
   7.108 -OPDEF(OP_GETREF_I,      71,         "getref.i",     1,      1,  1)
   7.109 -OPDEF(OP_SETREF_I,      72,         "setref.i",     1,      2,  1)
   7.110 -OPDEF(OP_GETREF_F,      73,         "getref.f",     1,      1,  1)
   7.111 -OPDEF(OP_SETREF_F,      74,         "setref.f",     1,      2,  1)
   7.112 +OPDEF(OP_VARREF_LIFO,   69,         "varref.lifo",  5,      0,  1)
   7.113 +OPDEF(OP_ARGREF_LIFO,   70,         "argref.lifo",  5,      0,  1)
   7.114 +OPDEF(OP_SLOTREF_LIFO,  71,         "slotref.lifo", 1,      1,  1)
   7.115 +OPDEF(OP_ARRAYREF_LIFO, 72,         "arrayref.lifo",1,      2,  1)
   7.116 +OPDEF(OP_GETREF_I,      73,         "getref.i",     1,      1,  1)
   7.117 +OPDEF(OP_SETREF_I,      74,         "setref.i",     1,      2,  1)
   7.118 +OPDEF(OP_GETREF_F,      75,         "getref.f",     1,      1,  1)
   7.119 +OPDEF(OP_SETREF_F,      76,         "setref.f",     1,      2,  1)
   7.120  
   7.121  // Pushes an object reference onto the stack.
   7.122 -OPDEF(OP_OBJECT,        75,         "object",       5,      0,  1)
   7.123 +OPDEF(OP_OBJECT,        77,         "object",       5,      0,  1)
   7.124  
   7.125  // Duplicates the top item on the stack.
   7.126 -OPDEF(OP_DUP,           76,         "dup",          1,      1,  2)
   7.127 +OPDEF(OP_DUP,           78,         "dup",          1,      1,  2)
   7.128  
   7.129  // Duplicates the top two items on the stack.
   7.130 -OPDEF(OP_DUP2,          77,         "dup2",         1,      2,  4)
   7.131 +OPDEF(OP_DUP2,          79,         "dup2",         1,      2,  4)
   7.132  
   7.133  // Swaps the two items at the top of the stack.
   7.134 -OPDEF(OP_SWAP,          78,         "swap",         1,      2,  2)
   7.135 +OPDEF(OP_SWAP,          80,         "swap",         1,      2,  2)
   7.136  
   7.137  // Roll operation is the same as Forth. It steals a value on the stack,
   7.138  // shifting all stack values down, and then places the stolen value back at
   7.139 @@ -193,14 +200,14 @@
   7.140  //  sp[-3] = sp[-2]
   7.141  //  sp[-2] = sp[-1]
   7.142  //  sp[-1] = p
   7.143 -OPDEF(OP_ROLL3,         79,         "roll3",        1,      3, 3)
   7.144 +OPDEF(OP_ROLL3,         81,         "roll3",        1,      3, 3)
   7.145  
   7.146  // Pick operation is the same as Forth. It pushes a copy of a slot at a
   7.147  // specific depth.
   7.148  //
   7.149  // push(sp[-n])
   7.150 -OPDEF(OP_PICK2,         80,         "pick2",        1,      2, 3)
   7.151 -OPDEF(OP_PICK3,         81,         "pick3",        1,      3, 4)
   7.152 +OPDEF(OP_PICK2,         82,         "pick2",        1,      2, 3)
   7.153 +OPDEF(OP_PICK3,         83,         "pick3",        1,      3, 4)
   7.154  
   7.155  // Calls a native function. During the course of calling a native, arguments
   7.156  // on the stack are re-pushed to match the cell-based native calling
   7.157 @@ -211,57 +218,57 @@
   7.158  //
   7.159  // [u8 Opcode] [u32 Index] [u32 ArgCount]
   7.160  //
   7.161 -OPDEF(OP_CALLNATIVE,    82,         "callnative",   9,      -1, 1)
   7.162 +OPDEF(OP_CALLNATIVE,    84,         "callnative",   9,      -1, 1)
   7.163  
   7.164  // Returns from a function that does return a value.
   7.165 -OPDEF(OP_RETURNVOID,    83,         "returnvoid",   1,      0, 0)
   7.166 +OPDEF(OP_RETURNVOID,    85,         "returnvoid",   1,      0, 0)
   7.167  
   7.168  // Loads the module of the running function.
   7.169 -OPDEF(OP_MODULE,        84,         "module",       1,      0, 1)
   7.170 +OPDEF(OP_MODULE,        86,         "module",       1,      0, 1)
   7.171  
   7.172  // Loads a function from a module object. The operand is the slot number
   7.173  // in the module.
   7.174 -OPDEF(OP_GETMODULE_FN,  85,         "getmodule.fn", 5,      1, 1)
   7.175 +OPDEF(OP_GETMODULE_FN,  87,         "getmodule.fn", 5,      1, 1)
   7.176  
   7.177  // Opcodes for accessing an environment slot in the global scope.
   7.178 -OPDEF(OP_SETGLOBAL_I,   86,         "setglobal.i",  5,      1, 1)
   7.179 -OPDEF(OP_SETGLOBAL_F,   87,         "setglobal.f",  5,      1, 1)
   7.180 -OPDEF(OP_SETGLOBAL_O,   88,         "setglobal.o",  5,      1, 1)
   7.181 -OPDEF(OP_GETGLOBAL_I,   89,         "getglobal.i",  5,      0, 1)
   7.182 -OPDEF(OP_GETGLOBAL_F,   90,         "getglobal.f",  5,      0, 1)
   7.183 -OPDEF(OP_GETGLOBAL_O,   91,         "getglobal.o",  5,      0, 1)
   7.184 +OPDEF(OP_SETGLOBAL_I,   88,         "setglobal.i",  5,      1, 1)
   7.185 +OPDEF(OP_SETGLOBAL_F,   89,         "setglobal.f",  5,      1, 1)
   7.186 +OPDEF(OP_SETGLOBAL_O,   90,         "setglobal.o",  5,      1, 1)
   7.187 +OPDEF(OP_GETGLOBAL_I,   91,         "getglobal.i",  5,      0, 1)
   7.188 +OPDEF(OP_GETGLOBAL_F,   92,         "getglobal.f",  5,      0, 1)
   7.189 +OPDEF(OP_GETGLOBAL_O,   93,         "getglobal.o",  5,      0, 1)
   7.190  
   7.191  // Reinterprets a 32-bit integer as a float, or vice-versa.
   7.192 -OPDEF(OP_BITS_I2F,      92,         "bits.i2f",     1,      1, 1)
   7.193 -OPDEF(OP_BITS_F2I,      93,         "bits.f2i",     1,      1, 1)
   7.194 +OPDEF(OP_BITS_I2F,      94,         "bits.i2f",     1,      1, 1)
   7.195 +OPDEF(OP_BITS_F2I,      95,         "bits.f2i",     1,      1, 1)
   7.196  
   7.197  // Pushes a boolean value.
   7.198 -OPDEF(OP_TRUE,          94,         "true",         1,      0, 1)
   7.199 -OPDEF(OP_FALSE,         95,         "false",        1,      0, 1)
   7.200 +OPDEF(OP_TRUE,          96,         "true",         1,      0, 1)
   7.201 +OPDEF(OP_FALSE,         97,         "false",        1,      0, 1)
   7.202  
   7.203  // Allocate a struct. The HeapTenure is stored as a byte following pc. The
   7.204  // StructMap to use is specified as an index into the script's Map table.
   7.205  //
   7.206  // Format:
   7.207  //  [u8 op] [u8 tenure] [u32 index]
   7.208 -OPDEF(OP_NEWSTRUCT,     96,         "newstruct",    6,      0, 1)
   7.209 +OPDEF(OP_NEWSTRUCT,     98,         "newstruct",    6,      0, 1)
   7.210  
   7.211  // Performs a struct-to-struct assignment.
   7.212  //   Left = pop()
   7.213  //   Right = pop()
   7.214  //   copy(Left, Right)
   7.215  //   push(Left)
   7.216 -OPDEF(OP_COPYSTRUCT,    97,         "structcopy",   1,      2, 1)
   7.217 +OPDEF(OP_COPYSTRUCT,    99,         "structcopy",   1,      2, 1)
   7.218  
   7.219  // Sets or gets a property in a struct. The index of the field is specified as
   7.220  // a 32-bit integer. Note that these opcodes follow a new style of deriving
   7.221  // their types at runtime.
   7.222 -OPDEF(OP_GETFIELD,      98,         "getfield",     5,      1, 1)
   7.223 -OPDEF(OP_SETFIELD,      99,         "setfield",     5,      2, 1)
   7.224 +OPDEF(OP_GETFIELD,      100,        "getfield",     5,      1, 1)
   7.225 +OPDEF(OP_SETFIELD,      101,        "setfield",     5,      2, 1)
   7.226  
   7.227 -OPDEF(OP_FIELDREF_LIFO, 100,        "fieldref.lifo", 5,     1, 1)
   7.228 +OPDEF(OP_FIELDREF_LIFO, 102,        "fieldref.lifo", 5,     1, 1)
   7.229  
   7.230  // Table-based jump.
   7.231  // [u8 op] [i32 low] [i32 high] [u32 jump] [u32 jumps...]
   7.232 -OPDEF(OP_TABLESWITCH,   101,        "tableswitch",  9,      1, 0)
   7.233 +OPDEF(OP_TABLESWITCH,   103,        "tableswitch",  9,      1, 0)
   7.234  
     8.1 --- a/src/SemanticAnalysis.cpp	Sat Sep 15 17:39:45 2012 -0700
     8.2 +++ b/src/SemanticAnalysis.cpp	Sat Sep 15 18:25:54 2012 -0700
     8.3 @@ -782,19 +782,13 @@
     8.4                      return;
     8.5                  }
     8.6              } else {
     8.7 -                // Infer the size from the initializer.
     8.8 -                if (!init) {
     8.9 -                    cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
    8.10 -                    return;
    8.11 -                }
    8.12 -                if (!init->isFixedLength()) {
    8.13 -                    cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
    8.14 -                    return;
    8.15 -                }
    8.16 -                size = init->fixedLength();
    8.17 +                if (init && init->isFixedLength())
    8.18 +                    size = init->fixedLength();
    8.19 +                else
    8.20 +                    size = Type::DYNAMIC_ARRAY_SIZE;
    8.21              }
    8.22  
    8.23 -            type = zone_->types()->unsafeArray(type, size, false);
    8.24 +            type = zone_->types()->newArray(type, size, false);
    8.25              if (!type)
    8.26                  return;
    8.27  
    8.28 @@ -941,7 +935,7 @@
    8.29                      size = box.toInt();
    8.30                  }
    8.31  
    8.32 -                type = zone_->types()->unsafeArray(type, size, parameter->isConst());
    8.33 +                type = zone_->types()->newArray(type, size, parameter->isConst());
    8.34                  if (!type)
    8.35                      return false;
    8.36              }
     9.1 --- a/src/TypeManager.cpp	Sat Sep 15 17:39:45 2012 -0700
     9.2 +++ b/src/TypeManager.cpp	Sat Sep 15 18:25:54 2012 -0700
     9.3 @@ -65,7 +65,7 @@
     9.4  }
     9.5  
     9.6  Type *
     9.7 -TypeManager::unsafeArray(Handle<Type> contained, int elements, bool isConst)
     9.8 +TypeManager::newArray(Handle<Type> contained, int elements, bool isConst)
     9.9  {
    9.10      // :TODO: cache this.
    9.11      return Type::NewArray(zone_, contained, elements, isConst);
    10.1 --- a/src/TypeManager.h	Sat Sep 15 17:39:45 2012 -0700
    10.2 +++ b/src/TypeManager.h	Sat Sep 15 18:25:54 2012 -0700
    10.3 @@ -53,7 +53,7 @@
    10.4          return uncheckedType_;
    10.5      }
    10.6      Type *getReference(Handle<Type> type, bool isConst);
    10.7 -    Type *unsafeArray(Handle<Type> contained, int elements, bool isConst);
    10.8 +    Type *newArray(Handle<Type> contained, int elements, bool isConst);
    10.9      Type *newEnum(Handle<String> name);
   10.10      Type *newFunction(Handle<Type> returnType, Handle<FixedArray> args,
   10.11                        Handle<FixedArray> deafults);
    11.1 --- a/src/Zone.cpp	Sat Sep 15 17:39:45 2012 -0700
    11.2 +++ b/src/Zone.cpp	Sat Sep 15 18:25:54 2012 -0700
    11.3 @@ -114,7 +114,7 @@
    11.4          if (!type)
    11.5              return false;
    11.6  
    11.7 -        type = types_->unsafeArray(type, Type::DYNAMIC_ARRAY_SIZE, false);
    11.8 +        type = types_->newArray(type, Type::DYNAMIC_ARRAY_SIZE, false);
    11.9          if (!type)
   11.10              return false;
   11.11  
   11.12 @@ -126,7 +126,7 @@
   11.13          if (!type)
   11.14              return false;
   11.15  
   11.16 -        type = types_->unsafeArray(type, Type::DYNAMIC_ARRAY_SIZE, false);
   11.17 +        type = types_->newArray(type, Type::DYNAMIC_ARRAY_SIZE, false);
   11.18          if (!type)
   11.19              return false;
   11.20