public virtual void visit(IArrayConstantNode value) { }
private void GenerateNDimArrayInitCode(ILGenerator il, LocalBuilder lb, IArrayConstantNode InitalValue, ITypeNode ArrayType, int rank) { IConstantNode[] ElementValues = InitalValue.ElementValues; Type elem_type = helper.GetTypeReference(ArrayType.element_type).tp; MethodInfo set_meth = null; if (ArrayType is ICompiledTypeNode) set_meth = lb.LocalType.GetMethod("Set"); else { List<Type> lst = new List<Type>(); for (int i = 0; i < rank; i++) lst.Add(TypeFactory.Int32Type); lst.Add(elem_type); set_meth = mb.GetArrayMethod(lb.LocalType, "Set", CallingConventions.HasThis, TypeFactory.VoidType, lst.ToArray()); } List<int> indices = new List<int>(); for (int i = 0; i < ElementValues.Length; i++) { if (i == 0) indices.Add(i); else indices[indices.Count - rank] = i; EmitArrayIndex(il, set_meth, lb, ElementValues[i] as IArrayConstantNode, rank - 1, rank, indices); } }
private void GenerateArrayInitCode(ILGenerator il, LocalBuilder lb, IArrayConstantNode InitalValue) { IExpressionNode[] ElementValues = InitalValue.ElementValues; if (ElementValues[0] is IArrayConstantNode) { bool is_unsized_array; Type FieldType, ArrType; TypeInfo ti = null; if (NETGeneratorTools.IsBoundedArray(helper.GetTypeReference(ElementValues[0].type))) { is_unsized_array = false; ti = helper.GetTypeReference(ElementValues[0].type); ArrType = ti.tp; FieldType = ti.arr_fld.FieldType; } else { is_unsized_array = true; ArrType = helper.GetTypeReference(ElementValues[0].type).tp; FieldType = ArrType; } LocalBuilder llb = il.DeclareLocal(FieldType); for (int i = 0; i < ElementValues.Length; i++) { il.Emit(OpCodes.Ldloc, lb); PushIntConst(il, i); if (!is_unsized_array) { il.Emit(OpCodes.Ldelem, ArrType); il.Emit(OpCodes.Ldfld, ti.arr_fld); } else { //il.Emit(OpCodes.Ldelema, ArrType); CreateUnsizedArray(il, helper.GetTypeReference((ElementValues[i] as IArrayConstantNode).type.element_type), (ElementValues[0] as IArrayConstantNode).ElementValues.Length, lb.LocalType.GetElementType()); il.Emit(OpCodes.Stelem, ArrType); il.Emit(OpCodes.Ldloc, lb); PushIntConst(il, i); il.Emit(OpCodes.Ldelem, ArrType); //il.Emit(OpCodes.Ldelem_Ref); } il.Emit(OpCodes.Stloc, llb); GenerateArrayInitCode(il, llb, ElementValues[i] as IArrayConstantNode); } } else if (ElementValues[0] is IRecordConstantNode) { TypeInfo ti = helper.GetTypeReference(ElementValues[0].type); LocalBuilder llb = il.DeclareLocal(ti.tp.MakePointerType()); for (int i = 0; i < ElementValues.Length; i++) { il.Emit(OpCodes.Ldloc, lb); PushIntConst(il, i); il.Emit(OpCodes.Ldelema, ti.tp); il.Emit(OpCodes.Stloc, llb); GenerateRecordInitCode(il, llb, ElementValues[i] as IRecordConstantNode); } } else for (int i = 0; i < ElementValues.Length; i++) { il.Emit(OpCodes.Ldloc, lb); TypeInfo ti = helper.GetTypeReference(ElementValues[i].type); PushIntConst(il, i); if (ti != null && ti.tp.IsValueType && !TypeFactory.IsStandType(ti.tp) && !ti.tp.IsEnum) il.Emit(OpCodes.Ldelema, ti.tp); //else //if (ti != null && ti.assign_meth != null) // il.Emit(OpCodes.Ldelem_Ref); ILGenerator ilb = this.il; this.il = il; ElementValues[i].visit(this); this.il = ilb; /*if (ti != null && ti.assign_meth != null) { il.Emit(OpCodes.Call,ti.assign_meth); this.il = ilb; continue; }*/ bool box = EmitBox(ElementValues[i], lb.LocalType.GetElementType()); this.il = ilb; if (ti != null && !box) NETGeneratorTools.PushStelem(il, ti.tp); else il.Emit(OpCodes.Stelem_Ref); } }
//глобальные переменные private void CreateArrayGlobalVariable(ILGenerator il, FieldBuilder fb, TypeInfo ti, IArrayConstantNode InitalValue, ITypeNode arr_type) { int rank = 1; if (NETGeneratorTools.IsBoundedArray(ti)) NETGeneratorTools.CreateBoundedArray(il, fb, ti); else { rank = get_rank(arr_type); if (rank == 1) CreateUnsizedArray(il, fb, helper.GetTypeReference(InitalValue.ElementType), InitalValue.ElementValues.Length); else CreateNDimUnsizedArray(il, fb, arr_type, helper.GetTypeReference(arr_type.element_type), rank, get_sizes(InitalValue, rank)); } if (InitalValue != null) { LocalBuilder lb = null; if (NETGeneratorTools.IsBoundedArray(ti)) { lb = il.DeclareLocal(ti.arr_fld.FieldType); il.Emit(OpCodes.Ldsfld, fb); il.Emit(OpCodes.Ldfld, ti.arr_fld); } else { lb = il.DeclareLocal(ti.tp); il.Emit(OpCodes.Ldsfld, fb); } il.Emit(OpCodes.Stloc, lb); if (rank == 1) GenerateArrayInitCode(il, lb, InitalValue); else GenerateNDimArrayInitCode(il, lb, InitalValue, arr_type, rank); } }
private void EmitArrayIndex(ILGenerator il, MethodInfo set_meth, LocalBuilder lb, IArrayConstantNode InitalValue, int rank, int act_rank, List<int> indices) { IConstantNode[] ElementValues = InitalValue.ElementValues; for (int i = 0; i < ElementValues.Length; i++) { if (indices.Count < act_rank) indices.Add(i); else indices[indices.Count - rank] = i; if (rank > 1) EmitArrayIndex(il, set_meth, lb, ElementValues[i] as IArrayConstantNode, rank - 1, act_rank, indices); else { if (indices.Count < act_rank) indices.Add(i); else indices[indices.Count - rank] = i; il.Emit(OpCodes.Ldloc, lb); for (int j = 0; j < indices.Count; j++) il.Emit(OpCodes.Ldc_I4, indices[j]); ILGenerator tmp_il = this.il; this.il = il; ElementValues[i].visit(this); EmitBox(InitalValue.ElementValues[i], lb.LocalType.GetElementType()); this.il = tmp_il; il.Emit(OpCodes.Call, set_meth); } } }
private int[] get_sizes(IArrayConstantNode InitalValue, int rank) { List<int> sizes = new List<int>(); sizes.Add(InitalValue.ElementValues.Length); if (rank > 1) sizes.AddRange(get_sizes(InitalValue.ElementValues[0] as IArrayConstantNode, rank - 1)); return sizes.ToArray(); }
public override void visit(IArrayConstantNode value) { il.Emit(OpCodes.Ldsfld, GetConvertedConstants(value)); }
public void visit(IArrayConstantNode value) { string s = value.GetType().Name + "."; //value.ElementType //value.ElementValues prepare_node(value.type, s + "type"); //value.value }
public void visit(IArrayConstantNode value) { throw new System.NotSupportedException(value.GetType().ToString()); }