示例#1
0
        //перевод декремента
        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);
                    }
                }
            }
        }
示例#2
0
        //присвоение элементу массива
        //
        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);
        }
示例#3
0
 //присвоение например 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);
     }
 }
示例#4
0
 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);
 }
示例#5
0
 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);
 }
示例#6
0
        //присвоение полю
        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);

        }
示例#7
0
 //присвоение статическому полю
 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);
 }
示例#8
0
 //присваивание локальной переменной
 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);
     }
 }
示例#9
0
        //присвоение параметру
        //полная бяка, например нужно присвоить нелокальному 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);
                }
            }
        }
示例#10
0
        //присваивание глобальной переменной
        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);
        }
示例#11
0
 private void ConvertExpression(IExpressionNode value)
 {
     make_next_spoint = false;
     value.visit(this);
 }
示例#12
0
 private void CreateUnsizedArray(ILGenerator il, TypeInfo ti, IExpressionNode size)
 {
     size.visit(this);
     il.Emit(OpCodes.Newarr, ti.tp);
 }
示例#13
0
        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;
        }
示例#14
0
        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;
        }