//перевод декремента private void ConvertDec(IExpressionNode e) { Type tp = helper.GetTypeReference(e.type).tp; if (e is INamespaceVariableReferenceNode) { e.visit(this); //DS0030 fixed NETGeneratorTools.PushLdc(il, tp, 1); //il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Sub); INamespaceVariableReferenceNode var = (INamespaceVariableReferenceNode)e; VarInfo vi = helper.GetVariable(var.variable); FieldBuilder fb = vi.fb; il.Emit(OpCodes.Stsfld, fb); } else if (e is ILocalVariableReferenceNode || e is ILocalBlockVariableReferenceNode) { IReferenceNode var = (IReferenceNode)e; VarInfo vi = helper.GetVariable(var.Variable); if (vi.kind == VarKind.vkLocal) { LocalBuilder lb = vi.lb; e.visit(this); //DS0030 fixed NETGeneratorTools.PushLdc(il, tp, 1); //il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Sub); il.Emit(OpCodes.Stloc, lb); } else if (vi.kind == VarKind.vkNonLocal) { FieldBuilder fb = vi.fb; MethInfo cur_mi = smi.Peek(); int dist = (smi.Peek()).num_scope - vi.meth.num_scope; il.Emit(OpCodes.Ldloc, cur_mi.frame); for (int i = 0; i < dist; i++) { il.Emit(OpCodes.Ldfld, cur_mi.disp.parent); cur_mi = cur_mi.up_meth; } e.visit(this); //DS0030 fixed NETGeneratorTools.PushLdc(il, tp, 1); //il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Sub); il.Emit(OpCodes.Stfld, fb); } } else if (e is ICommonParameterReferenceNode) { ICommonParameterReferenceNode var = (ICommonParameterReferenceNode)e; ParamInfo pi = helper.GetParameter(var.parameter); if (pi.kind == ParamKind.pkNone) { ParameterBuilder pb = pi.pb; //byte pos = (byte)(pb.Position-1); //***********************Kolay modified********************** byte pos = (byte)(pb.Position - 1); if (is_constructor || cur_meth.IsStatic == false) pos = (byte)pb.Position; else pos = (byte)(pb.Position - 1); //***********************End of Kolay modified********************** if (var.parameter.parameter_type == parameter_type.value) { e.visit(this); //DS0030 fixed NETGeneratorTools.PushLdc(il, tp, 1); //il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Sub); if (pos <= 255) il.Emit(OpCodes.Starg_S, pos); else il.Emit(OpCodes.Starg, pos); } else { PushParameter(pos); e.visit(this); //DS0030 fixed NETGeneratorTools.PushLdc(il, tp, 1); //il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Sub); TypeInfo ti = helper.GetTypeReference(var.type); StoreParameterByReference(ti.tp); } } else { FieldBuilder fb = pi.fb; MethInfo cur_mi = smi.Peek(); int dist = (smi.Peek()).num_scope - pi.meth.num_scope; il.Emit(OpCodes.Ldloc, cur_mi.frame); for (int i = 0; i < dist; i++) { il.Emit(OpCodes.Ldfld, cur_mi.disp.parent); cur_mi = cur_mi.up_meth; } if (var.parameter.parameter_type == parameter_type.value) { e.visit(this); //DS0030 fixed NETGeneratorTools.PushLdc(il, tp, 1); //il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Sub); il.Emit(OpCodes.Stfld, fb); } else { il.Emit(OpCodes.Ldfld, fb); e.visit(this); //DS0030 fixed NETGeneratorTools.PushLdc(il, tp, 1); //il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Sub); TypeInfo ti = helper.GetTypeReference(var.type); StoreParameterByReference(ti.tp); } } } }
//присвоение элементу массива // private void AssignToSimpleArrayNode(IExpressionNode to, IExpressionNode from) { ISimpleArrayIndexingNode value = (ISimpleArrayIndexingNode)to; TypeInfo ti = helper.GetTypeReference(value.array.type); ISimpleArrayNode arr_type = value.array.type as ISimpleArrayNode; TypeInfo elem_ti = null; if (arr_type != null) elem_ti = helper.GetTypeReference(arr_type.element_type); else if (value.array.type.type_special_kind == type_special_kind.array_kind && value.array.type is ICommonTypeNode) elem_ti = helper.GetTypeReference(value.array.type.element_type); Type elem_type = null; if (elem_ti != null) elem_type = elem_ti.tp; else elem_type = ti.tp.GetElementType(); value.array.visit(this); if (elem_ti != null) { //il.Emit(OpCodes.Ldarg_0); //il.Emit(OpCodes.Ldfld, ti.arr_fld); } //else MethodInfo get_meth = null; MethodInfo addr_meth = null; MethodInfo set_meth = null; if (value.indices == null) { value.index.visit(this); } else { if (value.array.type is ICompiledTypeNode) { get_meth = ti.tp.GetMethod("Get"); addr_meth = ti.tp.GetMethod("Address"); set_meth = ti.tp.GetMethod("Set"); } else { List<Type> lst = new List<Type>(); for (int i = 0; i < value.indices.Length; i++) lst.Add(TypeFactory.Int32Type); get_meth = mb.GetArrayMethod(ti.tp, "Get", CallingConventions.HasThis, elem_type, lst.ToArray()); addr_meth = mb.GetArrayMethod(ti.tp, "Address", CallingConventions.HasThis, elem_type.MakeByRefType(), lst.ToArray()); lst.Add(elem_type); set_meth = mb.GetArrayMethod(ti.tp, "Set", CallingConventions.HasThis, TypeFactory.VoidType, lst.ToArray()); } for (int i = 0; i < value.indices.Length; i++) value.indices[i].visit(this); } if (elem_type.IsValueType == true && TypeFactory.IsStandType(elem_type) == false && !TypeIsEnum(elem_type)) { if (value.indices == null) il.Emit(OpCodes.Ldelema, elem_type); //else // il.Emit(OpCodes.Call, addr_meth); } else if (elem_ti != null && elem_ti.assign_meth != null) { if (value.indices == null) il.Emit(OpCodes.Ldelem_Ref); else il.Emit(OpCodes.Call, get_meth); } from.visit(this); if (elem_ti != null && elem_ti.assign_meth != null) { il.Emit(OpCodes.Call, elem_ti.assign_meth); return; } ICompiledTypeNode ctn2 = to.type as ICompiledTypeNode; if ((from.type.is_value_type || from.type.is_generic_parameter) && ctn2 != null && ctn2.compiled_type == TypeFactory.ObjectType) { il.Emit(OpCodes.Box, helper.GetTypeReference(from.type).tp); } CheckArrayAssign(to, from, il); if (value.indices == null) NETGeneratorTools.PushStelem(il, elem_type); else il.Emit(OpCodes.Call, set_meth); }
//присвоение например a^ := 1 private void AssignToDereferenceNode(IExpressionNode to, IExpressionNode from) { IDereferenceNode value = (IDereferenceNode)to; TypeInfo ti = helper.GetTypeReference(to.type); value.derefered_expr.visit(this); if (ti != null && ti.assign_meth != null && !ti.tp.IsValueType) il.Emit(OpCodes.Ldind_Ref); from.visit(this); if (ti != null && ti.assign_meth != null) { il.Emit(OpCodes.Call, ti.assign_meth); if (ti.tp.IsValueType && ti.fix_meth != null) { value.derefered_expr.visit(this); il.Emit(OpCodes.Call, ti.fix_meth); } return; } //ICompiledTypeNode ctn = from.type as ICompiledTypeNode; ICompiledTypeNode ctn2 = to.type as ICompiledTypeNode; if ((from.type.is_value_type || from.type.is_generic_parameter) && ctn2 != null && ctn2.compiled_type == TypeFactory.ObjectType) { il.Emit(OpCodes.Box, helper.GetTypeReference(from.type).tp); } CheckArrayAssign(to, from, il); NETGeneratorTools.PushStind(il, ti.tp); if (TypeNeedToFix(value.type)) { value.derefered_expr.visit(this); il.Emit(OpCodes.Ldind_Ref); FixPointer(); } else if (ti.tp.IsValueType && ti.fix_meth != null) { value.derefered_expr.visit(this); il.Emit(OpCodes.Call, ti.fix_meth); } }
private void AssignToCompiledField(IExpressionNode to, IExpressionNode from) { ICompiledFieldReferenceNode value = (ICompiledFieldReferenceNode)to; FieldInfo fi = value.field.compiled_field; is_dot_expr = true; value.obj.visit(this); is_dot_expr = false; from.visit(this); EmitBox(from, fi.FieldType); il.Emit(OpCodes.Stfld, fi); }
private void AssignToStaticCompiledField(IExpressionNode to, IExpressionNode from) { IStaticCompiledFieldReferenceNode value = (IStaticCompiledFieldReferenceNode)to; FieldInfo fi = value.static_field.compiled_field; from.visit(this); EmitBox(from, fi.FieldType); il.Emit(OpCodes.Stsfld, fi); }
//присвоение полю private void AssignToField(IExpressionNode to, IExpressionNode from) { ICommonClassFieldReferenceNode value = (ICommonClassFieldReferenceNode)to; FldInfo fi_info = helper.GetField(value.field); FieldInfo fi = fi_info.fi; is_dot_expr = true; has_dereferences = false; value.obj.visit(this); bool has_dereferences_tmp = has_dereferences; has_dereferences = false; is_dot_expr = false; TypeInfo ti = helper.GetTypeReference(to.type); if (to.type.is_value_type) { //ti = helper.GetTypeReference(to.type); if (ti.assign_meth != null) il.Emit(OpCodes.Ldflda, fi); } else if (to.type.type_special_kind == type_special_kind.set_type && !in_var_init) { il.Emit(OpCodes.Ldfld, fi); from.visit(this); il.Emit(OpCodes.Call, ti.assign_meth); return; } else ti = null; //что присвоить from.visit(this); if (ti != null && ti.assign_meth != null) { il.Emit(OpCodes.Call, ti.assign_meth); if (ti.fix_meth != null && has_dereferences_tmp) { is_dot_expr = true; value.obj.visit(this); is_dot_expr = false; il.Emit(OpCodes.Ldflda, fi); il.Emit(OpCodes.Call, ti.fix_meth); } return; } EmitBox(from, fi_info.field_type); CheckArrayAssign(to, from, il); il.Emit(OpCodes.Stfld, fi); }
//присвоение статическому полю private void AssignToStaticField(IExpressionNode to, IExpressionNode from) { IStaticCommonClassFieldReferenceNode value = (IStaticCommonClassFieldReferenceNode)to; FieldInfo fi = helper.GetField(value.static_field).fi; TypeInfo ti = helper.GetTypeReference(to.type); if (to.type.is_value_type) { //ti = helper.GetTypeReference(to.type); if (ti.assign_meth != null) il.Emit(OpCodes.Ldsflda, fi); } else if (to.type.type_special_kind == type_special_kind.set_type) { il.Emit(OpCodes.Ldsfld, fi); from.visit(this); il.Emit(OpCodes.Call, ti.assign_meth); return; } else ti = null; //что присвоить from.visit(this); if (ti != null && ti.assign_meth != null) { il.Emit(OpCodes.Call, ti.assign_meth); return; } EmitBox(from, fi.FieldType); CheckArrayAssign(to, from, il); il.Emit(OpCodes.Stsfld, fi); }
//присваивание локальной переменной private void AssignToLocalVariableNode(IExpressionNode to, IExpressionNode from) { IReferenceNode var = (IReferenceNode)to; VarInfo vi = helper.GetVariable(var.Variable); if (vi.kind == VarKind.vkLocal) { LocalBuilder lb = vi.lb; TypeInfo ti = helper.GetTypeReference(to.type); if (to.type.is_value_type) { //ti = helper.GetTypeReference(to.type); if (ti.assign_meth != null) il.Emit(OpCodes.Ldloca, lb); } else if (to.type.type_special_kind == type_special_kind.set_type && !in_var_init) { il.Emit(OpCodes.Ldloc, lb); from.visit(this); il.Emit(OpCodes.Call, ti.assign_meth); return; } else ti = null; //что присвоить from.visit(this); if (ti != null && ti.assign_meth != null) { il.Emit(OpCodes.Call, ti.assign_meth); return; } EmitBox(from, lb.LocalType); CheckArrayAssign(to, from, il); il.Emit(OpCodes.Stloc, lb); } else if (vi.kind == VarKind.vkNonLocal) { FieldBuilder fb = vi.fb; MethInfo cur_mi = smi.Peek(); int dist = smi.Peek().num_scope - vi.meth.num_scope; il.Emit(OpCodes.Ldloc, cur_mi.frame); for (int i = 0; i < dist; i++) { il.Emit(OpCodes.Ldfld, cur_mi.disp.parent); cur_mi = cur_mi.up_meth; } TypeInfo ti = helper.GetTypeReference(to.type); if (to.type.is_value_type) { //ti = helper.GetTypeReference(to.type); if (ti.assign_meth != null) il.Emit(OpCodes.Ldflda, fb); } else if (to.type.type_special_kind == type_special_kind.set_type && !in_var_init) { il.Emit(OpCodes.Ldfld, fb); from.visit(this); il.Emit(OpCodes.Call, ti.assign_meth); return; } else ti = null; //что присвоить from.visit(this); if (ti != null && ti.assign_meth != null) { il.Emit(OpCodes.Call, ti.assign_meth); return; } EmitBox(from, fb.FieldType); CheckArrayAssign(to, from, il); il.Emit(OpCodes.Stfld, fb); } }
//присвоение параметру //полная бяка, например нужно присвоить нелокальному var-параметру какое-то значение private void AssignToParameterNode(IExpressionNode to, IExpressionNode from) { ICommonParameterReferenceNode var = (ICommonParameterReferenceNode)to; ParamInfo pi = helper.GetParameter(var.parameter); if (pi.kind == ParamKind.pkNone)//если параметр локальный { ParameterBuilder pb = pi.pb; //byte pos = (byte)(pb.Position-1); //***********************Kolay modified********************** ushort pos = (ushort)(pb.Position - 1); if (is_constructor || cur_meth.IsStatic == false) pos = (ushort)pb.Position; else pos = (ushort)(pb.Position - 1); //***********************End of Kolay modified********************** if (var.parameter.parameter_type == parameter_type.value) { TypeInfo ti = helper.GetTypeReference(to.type); if (to.type.is_value_type) { if (ti.assign_meth != null) il.Emit(OpCodes.Ldarga, pos); } else if (to.type.type_special_kind == type_special_kind.set_type) { il.Emit(OpCodes.Ldarg, pos); from.visit(this); il.Emit(OpCodes.Call, ti.assign_meth); return; } else ti = null; //что присвоить from.visit(this); if (ti != null && ti.assign_meth != null) { il.Emit(OpCodes.Call, ti.assign_meth); return; } BoxAssignToParameter(to, from); //il.Emit(OpCodes.Dup); if (pos <= 255) il.Emit(OpCodes.Starg_S, pos); else il.Emit(OpCodes.Starg, pos); } else { TypeInfo ti = helper.GetTypeReference(to.type); if (to.type.is_value_type) { //ti = helper.GetTypeReference(to.type); if (ti.assign_meth != null) { //здесь надо быть внимательнее il.Emit(OpCodes.Ldarg, pos); from.visit(this); il.Emit(OpCodes.Call, ti.assign_meth); return; } } else if (to.type.type_special_kind == type_special_kind.set_type) { il.Emit(OpCodes.Ldarg, pos); il.Emit(OpCodes.Ldind_Ref); from.visit(this); il.Emit(OpCodes.Call, ti.assign_meth); return; } else ti = null; PushParameter(pos); from.visit(this); BoxAssignToParameter(to, from); //il.Emit(OpCodes.Dup); ti = helper.GetTypeReference(var.type); StoreParameterByReference(ti.tp); } } else//иначе нелокальный { FieldBuilder fb = pi.fb; MethInfo cur_mi = (MethInfo)smi.Peek(); int dist = ((MethInfo)smi.Peek()).num_scope - pi.meth.num_scope; il.Emit(OpCodes.Ldloc, cur_mi.frame); for (int i = 0; i < dist; i++) { il.Emit(OpCodes.Ldfld, cur_mi.disp.parent); cur_mi = cur_mi.up_meth; } if (var.parameter.parameter_type == parameter_type.value) { TypeInfo ti = helper.GetTypeReference(to.type); if (to.type.is_value_type) { //ti = helper.GetTypeReference(to.type); if (ti.assign_meth != null) il.Emit(OpCodes.Ldflda, fb); } else if (to.type.type_special_kind == type_special_kind.set_type) { il.Emit(OpCodes.Ldfld, fb); from.visit(this); il.Emit(OpCodes.Call, ti.assign_meth); return; } else ti = null; //что присвоить from.visit(this); if (ti != null && ti.assign_meth != null) { il.Emit(OpCodes.Call, ti.assign_meth); return; } BoxAssignToParameter(to, from); //il.Emit(OpCodes.Dup); il.Emit(OpCodes.Stfld, fb); } else { TypeInfo ti = helper.GetTypeReference(to.type); il.Emit(OpCodes.Ldfld, fb); if (to.type.is_value_type) { //ti = helper.GetTypeReference(to.type); if (ti.assign_meth != null) { il.Emit(OpCodes.Call, ti.assign_meth); return; } } else if (to.type.type_special_kind == type_special_kind.set_type) { //il.Emit(OpCodes.Ldarg, pos); //il.Emit(OpCodes.Ldind_Ref); //from.visit(this); il.Emit(OpCodes.Ldind_Ref); from.visit(this); il.Emit(OpCodes.Call, ti.assign_meth); return; } else ti = null; from.visit(this); BoxAssignToParameter(to, from); //il.Emit(OpCodes.Dup); ti = helper.GetTypeReference(var.type); StoreParameterByReference(ti.tp); } } }
//присваивание глобальной переменной private void AssignToNamespaceVariableNode(IExpressionNode to, IExpressionNode from) { INamespaceVariableReferenceNode var = (INamespaceVariableReferenceNode)to; //получаем переменную VarInfo vi = helper.GetVariable(var.variable); FieldBuilder fb = vi.fb; TypeInfo ti = helper.GetTypeReference(to.type); if (to.type.is_value_type) { //ti = helper.GetTypeReference(to.type); if (ti.assign_meth != null) il.Emit(OpCodes.Ldsflda, fb); } else if (to.type.type_special_kind == type_special_kind.set_type && !in_var_init) { il.Emit(OpCodes.Ldsfld, fb); from.visit(this); il.Emit(OpCodes.Call, ti.assign_meth); return; } else ti = null; //что присвоить from.visit(this); if (ti != null && ti.assign_meth != null) { il.Emit(OpCodes.Call, ti.assign_meth); return; } //это если например переменной типа object присваивается число EmitBox(from, fb.FieldType); CheckArrayAssign(to, from, il); //присваиваем il.Emit(OpCodes.Stsfld, fb); }
private void ConvertExpression(IExpressionNode value) { make_next_spoint = false; value.visit(this); }
private void CreateUnsizedArray(ILGenerator il, TypeInfo ti, IExpressionNode size) { size.visit(this); il.Emit(OpCodes.Newarr, ti.tp); }
private void CreateInitCodeForUnsizedArray(ILGenerator il, TypeInfo ti, IExpressionNode arr, IExpressionNode size) { ILGenerator tmp_il = this.il; this.il = il; if (ti.tp.IsValueType && ti.init_meth != null || ti.is_arr || ti.is_set || ti.is_typed_file || ti.is_text_file || ti.tp == TypeFactory.StringType) { LocalBuilder clb = il.DeclareLocal(TypeFactory.Int32Type); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Stloc, clb); Label tlabel = il.DefineLabel(); Label flabel = il.DefineLabel(); il.MarkLabel(tlabel); il.Emit(OpCodes.Ldloc, clb); size.visit(this); il.Emit(OpCodes.Bge, flabel); arr.visit(this); il.Emit(OpCodes.Ldloc, clb); if (!ti.is_arr && !ti.is_set && !ti.is_typed_file && !ti.is_text_file) { if (ti.tp != TypeFactory.StringType) { il.Emit(OpCodes.Ldelema, ti.tp); il.Emit(OpCodes.Call, ti.init_meth); } else { Label lb1 = il.DefineLabel(); Label lb2 = il.DefineLabel(); il.Emit(OpCodes.Ldelem_Ref); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Beq, lb2); arr.visit(this); il.Emit(OpCodes.Ldloc, clb); il.Emit(OpCodes.Ldelem_Ref); il.Emit(OpCodes.Ldstr, ""); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brfalse, lb1); il.MarkLabel(lb2); arr.visit(this); il.Emit(OpCodes.Ldloc, clb); il.Emit(OpCodes.Ldstr, ""); il.Emit(OpCodes.Stelem_Ref); il.MarkLabel(lb1); } } else { Label label1 = il.DefineLabel(); il.Emit(OpCodes.Ldelem_Ref); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brfalse, label1); arr.visit(this); il.Emit(OpCodes.Ldloc, clb); if (ti.is_set) { IConstantNode cn1 = (arr.type.element_type as ICommonTypeNode).lower_value; IConstantNode cn2 = (arr.type.element_type as ICommonTypeNode).upper_value; if (cn1 != null && cn2 != null) { cn1.visit(this); il.Emit(OpCodes.Box, helper.GetTypeReference(cn1.type).tp); cn2.visit(this); il.Emit(OpCodes.Box, helper.GetTypeReference(cn2.type).tp); } else { il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ldnull); } } else if (ti.is_typed_file) { NETGeneratorTools.PushTypeOf(il, helper.GetTypeReference((arr.type.element_type as ICommonTypeNode).element_type).tp); } il.Emit(OpCodes.Newobj, ti.def_cnstr); il.Emit(OpCodes.Stelem_Ref); il.MarkLabel(label1); } il.Emit(OpCodes.Ldloc, clb); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Stloc, clb); il.Emit(OpCodes.Br, tlabel); il.MarkLabel(flabel); } this.il = tmp_il; }
private void CreateInitCodeForUnsizedArray(ILGenerator il, ITypeNode itn, IExpressionNode arr, LocalBuilder len) { ILGenerator tmp_il = this.il; TypeInfo ti = helper.GetTypeReference(itn); ICommonTypeNode ictn = itn as ICommonTypeNode; bool generic_param = (ictn != null && ictn.runtime_initialization_marker != null); FieldInfo finfo = null; MethodInfo rif = null; Label lab = default(Label); this.il = il; if (generic_param) { finfo = helper.GetField(ictn.runtime_initialization_marker).fi; lab = il.DefineLabel(); il.Emit(OpCodes.Ldsfld, finfo); il.Emit(OpCodes.Brfalse, lab); if (SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction.sym_info is ICompiledMethodNode) rif = (SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction.sym_info as ICompiledMethodNode).method_info; else rif = helper.GetMethod(SystemLibrary.SystemLibInitializer.RuntimeInitializeFunction.sym_info as IFunctionNode).mi; } if (ti.tp.IsValueType && ti.init_meth != null || ti.is_arr || ti.is_set || ti.is_typed_file || ti.is_text_file || ti.tp == TypeFactory.StringType || (generic_param)) { LocalBuilder clb = il.DeclareLocal(TypeFactory.Int32Type); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Stloc, clb); Label tlabel = il.DefineLabel(); Label flabel = il.DefineLabel(); il.MarkLabel(tlabel); il.Emit(OpCodes.Ldloc, clb); il.Emit(OpCodes.Ldloc, len); il.Emit(OpCodes.Bge, flabel); if (generic_param) { arr.visit(this); il.Emit(OpCodes.Ldloc, clb); il.Emit(OpCodes.Ldsfld, finfo); } arr.visit(this); il.Emit(OpCodes.Ldloc, clb); if (!ti.is_arr && !ti.is_set && !ti.is_typed_file && !ti.is_text_file) { if (generic_param) { il.Emit(OpCodes.Ldelem, ti.tp); il.Emit(OpCodes.Box, ti.tp); il.EmitCall(OpCodes.Call, rif, null); il.Emit(OpCodes.Unbox_Any, ti.tp); il.Emit(OpCodes.Stelem, ti.tp); } else if (ti.tp != TypeFactory.StringType) { il.Emit(OpCodes.Ldelema, ti.tp); il.Emit(OpCodes.Call, ti.init_meth); } else { Label lb1 = il.DefineLabel(); Label lb2 = il.DefineLabel(); il.Emit(OpCodes.Ldelem_Ref); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Beq, lb2); arr.visit(this); il.Emit(OpCodes.Ldloc, clb); il.Emit(OpCodes.Ldelem_Ref); il.Emit(OpCodes.Ldstr, ""); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brfalse, lb1); il.MarkLabel(lb2); arr.visit(this); il.Emit(OpCodes.Ldloc, clb); il.Emit(OpCodes.Ldstr, ""); il.Emit(OpCodes.Stelem_Ref); il.MarkLabel(lb1); } } else { Label label1 = il.DefineLabel(); il.Emit(OpCodes.Ldelem_Ref); il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ceq); il.Emit(OpCodes.Brfalse, label1); arr.visit(this); il.Emit(OpCodes.Ldloc, clb); if (ti.is_set) { IConstantNode cn1 = (arr.type.element_type as ICommonTypeNode).lower_value; IConstantNode cn2 = (arr.type.element_type as ICommonTypeNode).upper_value; if (cn1 != null && cn2 != null) { cn1.visit(this); il.Emit(OpCodes.Box, helper.GetTypeReference(cn1.type).tp); cn2.visit(this); il.Emit(OpCodes.Box, helper.GetTypeReference(cn2.type).tp); } else { il.Emit(OpCodes.Ldnull); il.Emit(OpCodes.Ldnull); } } else if (ti.is_typed_file) { NETGeneratorTools.PushTypeOf(il, helper.GetTypeReference((arr.type.element_type as ICommonTypeNode).element_type).tp); } il.Emit(OpCodes.Newobj, ti.def_cnstr); il.Emit(OpCodes.Stelem_Ref); il.MarkLabel(label1); } il.Emit(OpCodes.Ldloc, clb); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Stloc, clb); il.Emit(OpCodes.Br, tlabel); il.MarkLabel(flabel); } if (generic_param) { il.MarkLabel(lab); } this.il = tmp_il; }