Esempio n. 1
0
        /// <summary>
        /// Implements the code to initialise the array.
        /// </summary>
        /// <param name="cg">The code generator object</param>
        public override void Generate(CodeGenerator cg)
        {
            if (cg == null) {
                throw new ArgumentNullException("cg");
            }
            Symbol sym = Identifier.Symbol;

            // Simple array initialisation - just initialise the
            // specified element. More complex initialisation requires
            // a loop across the elements.
            Debug.Assert(sym.IsArray);
            if (Identifier.Indexes != null && Identifier.Indexes.Count > 0) {
                if (Identifier.Indexes.Count == 1) {
                    NumberParseNode number = (NumberParseNode)Identifier.Indexes[0];
                    Debug.Assert(sym.Dimensions[0].LowerBound.IsConstant);
                    int index = number.Value.IntValue + (0 - sym.Dimensions[0].LowerBound.Value.IntValue);
                    GenerateStoreToArray(cg, sym, index, RangeValue);
                } else {
                    Type [] paramTypes = new Type[Identifier.Indexes.Count + 1];
                    int index = 0;

                    cg.LoadLocal(sym);
                    while (index < Identifier.Indexes.Count) {
                        NumberParseNode number = (NumberParseNode)Identifier.Indexes[index];
                        Debug.Assert(sym.Dimensions[index].LowerBound.IsConstant);
                        cg.Emitter.LoadInteger(number.Value.IntValue + (0 - sym.Dimensions[index].LowerBound.Value.IntValue));
                        paramTypes[index++] = typeof(Int32);
                    }
                    cg.GenerateLoad(RangeValue);
                    paramTypes[index] = Symbol.SymTypeToSystemType(RangeValue.Type);

                    cg.Emitter.Call(cg.GetMethodForType(sym.SystemType, "Set", paramTypes));
                }
            }
            else if (StartRange < EndRange + 4) {

                // When initialising arrays less than 4 values, unroll
                // the loop as it will be faster.
                int index = StartRange;
                while (index <= EndRange) {
                    GenerateStoreToArray(cg, sym, index++, RangeValue);
                }
            } else {

                // For large arrays, generate code to initialise the elements
                // to a specific value.
                Label label1 = cg.Emitter.CreateLabel();
                cg.Emitter.LoadInteger(StartRange);
                LocalDescriptor tempIndex = cg.Emitter.GetTemporary(typeof(int));
                cg.Emitter.StoreLocal(tempIndex);
                cg.Emitter.MarkLabel(label1);
                GenerateStoreToArray(cg, sym, tempIndex.Index, RangeValue);
                cg.Emitter.LoadLocal(tempIndex);
                cg.Emitter.LoadInteger(1);
                cg.Emitter.Add(SymType.INTEGER);
                cg.Emitter.Dup();
                cg.Emitter.StoreLocal(tempIndex);
                cg.Emitter.LoadInteger(EndRange);
                cg.Emitter.BranchLessOrEqual(label1);
            }
        }
Esempio n. 2
0
 /// <summary>
 /// Emit this code to load the value to the stack.
 /// </summary>
 /// <param name="cg">A CodeGenerator object</param>
 /// <param name="returnType">The type required by the caller</param>
 /// <returns>The symbol type of the value generated</returns>
 public override SymType Generate(CodeGenerator cg, SymType returnType)
 {
     if (cg == null) {
         throw new ArgumentNullException("cg");
     }
     cg.GenerateLoad(Value);
     return Value.Type;
 }
Esempio n. 3
0
 // Emit code that writes the variant value to the given array index where
 // the array is specified by the symbol..
 void GenerateStoreToArray(CodeGenerator cg, Symbol sym, int index, Variant value)
 {
     cg.LoadLocal(sym);
     cg.Emitter.LoadInteger(index);
     cg.GenerateLoad(value);
     cg.Emitter.ConvertType(value.Type, sym.Type);
     cg.Emitter.StoreElement(sym.Type);
 }