public void Create(Type type)
 {
     if (!type.IsArray)
     {
         var constructor = type.GetConstructor(Type.EmptyTypes);
         if (constructor == null)
         {
             throw new InvalidOperationException("Missing parameterless constructor for type '" + type + "'");
         }
         Il.Newobj(constructor);
     }
     else
     {
         var rank = type.GetArrayRank();
         if (rank == 1)
         {
             Il.Ldc_I4(0);
             Il.Newarr(type.GetElementType());
         }
         else
         {
             var constructor = type.GetConstructor(Enumerable.Repeat(typeof(int), rank).ToArray());
             if (constructor == null)
             {
                 throw new InvalidOperationException(string.Format("Missing constructor accepting {0} integers for type '{1}'", rank, type));
             }
             for (int i = 0; i < rank; ++i)
             {
                 Il.Ldc_I4(0);
             }
             Il.Newobj(constructor);
         }
     }
 }
 /// <summary>
 ///     Increases <c>index</c> by 8
 /// </summary>
 public void IncreaseIndexBy8()
 {
     LoadIndexByRef();      // stack: [ref index]
     LoadIndex();           // stack: [ref index, index]
     Il.Ldc_I4(8);          // stack: [ref index, index, 8]
     Il.Add();              // stack: [ref index, index + 8]
     Il.Stind(typeof(int)); // index = index + 8
 }
 /// <summary>
 ///     Puts the specified type code at <c>result</c>[<c>index</c>]
 /// </summary>
 /// <param name="typeCode">Type code to put</param>
 public void WriteTypeCode(GroBufTypeCode typeCode)
 {
     Il.Ldc_I4(1);
     AssertLength();
     GoToCurrentLocation();    // stack: [&result[index]]
     Il.Ldc_I4((int)typeCode); // stack: [&result[index], typeCode]
     Il.Stind(typeof(byte));   // result[index] = typeCode
     IncreaseIndexBy1();       // index = index + 1
 }
        public void LoadCompiledLambda(CompiledLambda compiledLambda)
        {
            if (ParsedLambda.ConstantsParameter == null)
            {
                throw new InvalidOperationException("There is no constants parameter. Cannot load sublambda");
            }
            Type temp;
            var  delegatesAccessor = ParsedLambda.ConstantsBuilder.MakeAccess(ParsedLambda.ConstantsParameter, ParsedLambda.DelegatesFieldId);

            ExpressionEmittersCollection.Emit(delegatesAccessor, this, out temp);
            Il.Ldc_I4(compiledLambda.Index);
            Il.Ldelem(typeof(Delegate));
        }
        public void AssertTypeCode(GroBufTypeCode expectedTypeCode)
        {
            Il.Ldloc(TypeCode);               // stack: [typeCode]
            Il.Ldc_I4((int)expectedTypeCode); // stack: [typeCode, expectedTypeCode]

            var okLabel = Il.DefineLabel("ok");

            Il.Beq(okLabel);

            SkipValue();
            Il.Ret();

            Il.MarkLabel(okLabel);
        }
        public void SkipValue()
        {
            LoadIndexByRef(); // stack: [ref index]
            LoadIndex();      // stack: [ref index, index]

            // todo: сделать switch
            Il.Ldloc(TypeCode);                         // stack: [ref index, index, TypeCode]
            Il.Ldc_I4((int)GroBufTypeCode.DateTimeOld); // stack: [ref index, index, TypeCode, GroBufTypeCode.DateTimeOld]
            var notDateTimeLabel = Il.DefineLabel("notDateTime");

            Il.Bne_Un(notDateTimeLabel); // if(TypeCode != GroBufTypeCode.DateTimeOld) goto notDateTime; stack: [ref index, index]
            Il.Ldc_I4(8);                // stack: [ref index, index, 8]
            AssertLength();
            GoToCurrentLocation();       // stack: [ref index, index, &data[index]]
            Il.Ldc_I4(4);
            Il.Add();
            Il.Ldind(typeof(int)); // stack: [ref index, index, (int)(&data[index])]
            Il.Ldc_I4(31);         // stack: [ref index, index, (int)&data[index], 31]
            Il.Shr(true);          // stack: [ref index, index, (int)&data[index] >> 31]
            Il.Ldc_I4(8);          // stack: [ref index, index, (int)&data[index] >> 31, 8]
            Il.Add();              // stack: [ref index, index, (int)&data[index] >> 31 + 8]
            var increaseLabel = Il.DefineLabel("increase");

            Il.Br(increaseLabel);

            Il.MarkLabel(notDateTimeLabel);
            LoadField(Context.Lengths);

            Il.Ldloc(TypeCode);       // stack: [ref index, index, lengths, typeCode]
            Il.Ldelem(typeof(int));   // stack: [ref index, index, lengths[typeCode]]
            Il.Dup();                 // stack: [ref index, index, lengths[typeCode], lengths[typeCode]]
            Il.Ldc_I4(-1);            // stack: [ref index, index, lengths[typeCode], lengths[typeCode], -1]
            Il.Bne_Un(increaseLabel); // if(lengths[typeCode] != -1) goto increase;

            Il.Ldc_I4(4);
            AssertLength();
            Il.Pop();               // stack: [ref index, index]
            Il.Dup();               // stack: [ref index, index, index]
            LoadData();             // stack: [ref index, index, index, pinnedData]
            Il.Add();               // stack: [ref index, index, index + pinnedData]
            Il.Ldind(typeof(uint)); // stack: [ref index, index, *(uint*)(pinnedData + index)]
            Il.Ldc_I4(4);           // stack: [ref index, index, *(uint*)(pinnedData + index), 4]
            Il.Add();               // stack: [ref index, *(uint*)(pinnedData + index) + 4]

            Il.MarkLabel(increaseLabel);
            Il.Dup();              // stack: [ref index, length, length]
            AssertLength();        // stack: [ref index, length]
            Il.Add();              // stack: [ref index, index + length]
            Il.Stind(typeof(int)); // index = index + length
        }