Example #1
0
 //перевод тела функции
 private void ConvertFunctionBody(ICommonFunctionNode func, MethInfo mi, bool conv_first_stmt)
 {
     //if (is_in_unit && helper.IsUsed(func)==false) return;
     num_scope++;
     TypeBuilder tmp_type = cur_type;
     if (mi.disp != null) cur_type = mi.disp.tb;
     MethodBuilder tmp = cur_meth;
     cur_meth = (MethodBuilder)mi.mi;
     ILGenerator tmp_il = il;
     il = cur_meth.GetILGenerator();
     smi.Push(mi);
     funcs.Add(func);
     if (conv_first_stmt)
         ConvertBody(func.function_code);//переводим тело
     else
     {
         ConvertStatementsListWithoutFirstStatement(func.function_code as IStatementsListNode);
         OptMakeExitLabel();
     }
     //ivan for debug
     if (save_debug_info)
     {
         AddSpecialDebugVariables();
     }
     //\ivan for debug
     if (cur_meth.ReturnType == TypeFactory.VoidType)
         il.Emit(OpCodes.Ret);
     //восстановление значений
     cur_meth = tmp;
     cur_type = tmp_type;
     il = tmp_il;
     smi.Pop();
     funcs.RemoveAt(funcs.Count - 1);
     num_scope--;
 }
Example #2
0
        //процедура получения типов параметров процедуры
        private Type[] GetParamTypes(ICommonFunctionNode func)
        {
            Type[] tt = null;
            int num = 0;
            IParameterNode[] parameters = func.parameters;
            if (funcs.Count > 0)
            {
                tt = new Type[parameters.Length + 1];
                tt[num++] = cur_type.DeclaringType;
            }
            else
                tt = new Type[parameters.Length];
            for (int i = 0; i < parameters.Length; i++)
            {
                //этот тип уже был определен, поэтому получаем его с помощью хелпера
                Type tp = helper.GetTypeReference(parameters[i].type).tp;
                if (parameters[i].parameter_type == parameter_type.value)
                    tt[i + num] = tp;
                else
                {
                    //если var-параметр, то прибавляем &

                    //(ssyy) 12.04.2008. Это полная ерунда. Написал нормально.
                    tt[i + num] = tp.MakeByRefType();
                }
            }
            return tt;
        }
Example #3
0
        //перевод заголовка функции
        private void ConvertFunctionHeader(ICommonFunctionNode func)
        {
            //if (is_in_unit && helper.IsUsed(func)==false) return;
            num_scope++; //увеличиваем глубину обл. видимости
            TypeBuilder tb = null, tmp_type = cur_type;
            Frame frm = null;
            bool nested = false;

            //func.functions_nodes.Length > 0 - имеет вложенные
            //funcs.Count > 0 - сама вложенная
            if (func.functions_nodes.Length > 0 || funcs.Count > 0)
            {
                nested = true;
                frm = MakeAuxType(func);//создаем запись активации
                tb = frm.tb;
                cur_type = tb;
            }
            else tb = cur_type;
            MethodAttributes attrs = MethodAttributes.Public | MethodAttributes.Static;
            //определяем саму процедуру/функцию
            MethodBuilder methb = null;
            methb = tb.DefineMethod(func.name, attrs);

            if (func.is_generic_function)
            {
                int count = func.generic_params.Count;
                string[] names = new string[count];
                for (int i = 0; i < count; i++)
                {
                    names[i] = func.generic_params[i].name;
                }
                methb.DefineGenericParameters(names);
                Type[] genargs = methb.GetGenericArguments();
                for (int i = 0; i < count; i++)
                {
                    helper.AddExistingType(func.generic_params[i], genargs[i]);
                }
                foreach (ICommonTypeNode par in func.generic_params)
                {
                    converting_generic_param = par;
                    ConvertTypeHeaderInSpecialOrder(par);
                }
                ConvertTypeInstancesInFunction(func);
            }

            Type ret_type = null;
            //получаем тип возвр. значения
            if (func.return_value_type == null)
                ret_type = TypeFactory.VoidType;
            else
                ret_type = helper.GetTypeReference(func.return_value_type).tp;
            //получаем типы параметров
            Type[] param_types = GetParamTypes(func);

            methb.SetParameters(param_types);
            methb.SetReturnType(ret_type);

            MethInfo mi = null;
            if (smi.Count != 0)
                //добавляем вложенную процедуру, привязывая ее к верхней процедуре
                mi = helper.AddMethod(func, methb, smi.Peek());
            else
                mi = helper.AddMethod(func, methb);
            mi.num_scope = num_scope;
            mi.disp = frm;//тип - запись активации
            smi.Push(mi);
            ParameterBuilder pb = null;
            int num = 0;
            ILGenerator tmp_il = il;
            il = methb.GetILGenerator();

            if (save_debug_info)
            {
                if (func.function_code is IStatementsListNode)
                    MarkSequencePoint(((IStatementsListNode)func.function_code).LeftLogicalBracketLocation);
                else
                    MarkSequencePoint(func.function_code.Location);
            }

            //if (ret_type != typeof(void)) mi.ret_val = il.DeclareLocal(ret_type);
            //если функция вложенная, то добавляем фиктивный параметр
            //ссылку на верхнюю запись активации
            if (funcs.Count > 0)
            {
                mi.nested = true;//это вложенная процедура
                methb.DefineParameter(1, ParameterAttributes.None, "$up$");
                num = 1;
            }
            //все нелокальные параметры будем хранить в нестатических полях
            //записи активации. В начале функции инициализируем эти поля
            //параметрами
            IParameterNode[] parameters = func.parameters;
            FieldBuilder[] fba = new FieldBuilder[parameters.Length];

            for (int i = 0; i < parameters.Length; i++)
            {
                object default_value = null;
                if (parameters[i].default_value != null)
                {
                    default_value = helper.GetConstantForExpression(parameters[i].default_value);
                }
                ParameterAttributes pa = ParameterAttributes.None;
                //if (func.parameters[i].parameter_type == parameter_type.var)
                //    pa = ParameterAttributes.Retval;
                if (default_value != null)
                    pa |= ParameterAttributes.Optional;
                pb = methb.DefineParameter(i + num + 1, pa, parameters[i].name);

                if (parameters[i].is_params)
                    pb.SetCustomAttribute(TypeFactory.ParamArrayAttributeConstructor, new byte[] { 0x1, 0x0, 0x0, 0x0 });
                if (default_value != null)
                    pb.SetConstant(default_value);
                if (func.functions_nodes.Length > 0)
                {
                    FieldBuilder fb = null;
                    //если параметр передается по значению, то все нормально
                    if (parameters[i].parameter_type == parameter_type.value)
                        fb = frm.tb.DefineField(parameters[i].name, param_types[i + num], FieldAttributes.Public);
                    else
                    {
                        //иначе параметр передается по ссылке
                        //тогда вместо типа параметра тип& используем тип*
                        //например System.Int32& - System.Int32* (unmanaged pointer)

                        //Type pt = param_types[i + num].Module.GetType(param_types[i + num].FullName.Substring(0, param_types[i + num].FullName.IndexOf('&')) + "*");
                        ////это означает, что тип определен в генерируемой сборке
                        //if (pt == null) mb.GetType(param_types[i + num].FullName.Substring(0, param_types[i + num].FullName.IndexOf('&')) + "*");
                        Type pt = param_types[i + num].GetElementType().MakePointerType();

                        //определяем поле для параметра
                        fb = frm.tb.DefineField(parameters[i].name, pt, FieldAttributes.Public);
                    }

                    //добавляем как глобальный параметр
                    helper.AddGlobalParameter(parameters[i], fb).meth = smi.Peek();
                    fba[i] = fb;
                }
                else
                {
                    //если проца не содержит вложенных, то все хорошо
                    helper.AddParameter(parameters[i], pb).meth = smi.Peek();
                }
            }

            if (func is ICommonNamespaceFunctionNode && (func as ICommonNamespaceFunctionNode).ConnectedToType != null)
            {
                if (!marked_with_extension_attribute.ContainsKey(cur_unit_type))
                {
                    cur_unit_type.SetCustomAttribute(TypeFactory.ExtensionAttributeType.GetConstructor(new Type[0]), new byte[0]);
                    marked_with_extension_attribute[cur_unit_type] = cur_unit_type;
                }
                methb.SetCustomAttribute(TypeFactory.ExtensionAttributeType.GetConstructor(new Type[0]), new byte[0]);
            }
            if (func.functions_nodes.Length > 0 || funcs.Count > 0)
            {
                //определяем переменную, хранящую ссылку на запись активации данной процедуры
                LocalBuilder frame = il.DeclareLocal(cur_type);
                mi.frame = frame;
                if (doc != null) frame.SetLocalSymInfo("$disp$");
                if (funcs.Count > 0)
                {
                    //если она вложенная, то конструктору зап. акт. передаем ссылку на верх. з. а.
                    il.Emit(OpCodes.Ldarg_0);
                    //создаем запись активации
                    il.Emit(OpCodes.Newobj, frm.cb);
                    il.Emit(OpCodes.Stloc, frame);
                }
                else
                {
                    //в противном случае просто создаем з. а.
                    il.Emit(OpCodes.Newobj, frm.cb);
                    il.Emit(OpCodes.Stloc_0, frame);
                }
                if (func.functions_nodes.Length > 0)
                    for (int j = 0; j < fba.Length; j++)
                    {
                        //сохраняем нелокальные параметры в полях
                        il.Emit(OpCodes.Ldloc_0);
                        parameters = func.parameters;
                        if (parameters[j].parameter_type == parameter_type.value)
                        {
                            if (funcs.Count > 0) il.Emit(OpCodes.Ldarg_S, (byte)(j + 1));
                            else il.Emit(OpCodes.Ldarg_S, (byte)j);
                        }
                        else
                        {
                            if (funcs.Count > 0) il.Emit(OpCodes.Ldarga_S, (byte)(j + 1));
                            else il.Emit(OpCodes.Ldarg_S, (byte)j);
                        }
                        il.Emit(OpCodes.Stfld, fba[j]);
                    }
            }
            funcs.Add(func); //здесь наверное дублирование
            MethodBuilder tmp = cur_meth;
            cur_meth = methb;
            ConvertCommonFunctionConstantDefinitions(func.constants);
            //если функция не содержит вложенных процедур, то
            //переводим переменные как локальные
            if (func.functions_nodes.Length > 0)
                ConvertNonLocalVariables(func.var_definition_nodes, frm.mb);
            /*if (func.functions_nodes.Length == 0)
                ConvertLocalVariables(func.var_definition_nodes);
            else
                //иначе как нелокальные
                ConvertNonLocalVariables(func.var_definition_nodes, frm.mb);*/
            //переводим заголовки вложенных функций
            ConvertNestedFunctionHeaders(func.functions_nodes);
            //переводим тела вложенных функций
            //foreach (ICommonNestedInFunctionFunctionNode f in func.functions_nodes)
            //	ConvertFunctionBody(f);
            if (frm != null)
                frm.mb.GetILGenerator().Emit(OpCodes.Ret);
            //восстанавливаем текущие значения
            cur_type = tmp_type;
            num_scope--;
            smi.Pop();
            funcs.RemoveAt(funcs.Count - 1);
        }
Example #4
0
        //перевод тела процедуры
        //(ssyy) По-моему, это вызывается только для вложенных процедур.
        private void ConvertFunctionBody(ICommonFunctionNode func)
        {
            //if (is_in_unit && helper.IsUsed(func)==false) return;
            num_scope++;
            MakeAttribute(func);
            IStatementsListNode sl = (IStatementsListNode)func.function_code;
            IStatementNode[] statements = sl.statements;
            if (sl.statements.Length > 0 && (statements[0] is IPInvokeStatementNode || (statements[0] is IExternalStatementNode)))
            {
                num_scope--;
                return;
            }
            MethInfo mi = helper.GetMethod(func);
            TypeBuilder tmp_type = cur_type;
            if (mi.disp != null) cur_type = mi.disp.tb;
            MethodBuilder tmp = cur_meth;
            cur_meth = (MethodBuilder)mi.mi;
            ILGenerator tmp_il = il;
            il = cur_meth.GetILGenerator();
            smi.Push(mi);
            funcs.Add(func);
            if (func.functions_nodes.Length == 0)
                ConvertLocalVariables(func.var_definition_nodes);
            /*else
                //иначе как нелокальные
                ConvertNonLocalVariables(func.var_definition_nodes, mi.disp.mb);*/

            foreach (ICommonNestedInFunctionFunctionNode f in func.functions_nodes)
                ConvertFunctionBody(f);
            //перевод тела
            ConvertBody(func.function_code);
            //ivan for debug
            if (save_debug_info)
            {
                AddSpecialDebugVariables();
            }
            //\ivan for debug
            //if (cur_meth.ReturnType == typeof(void))
            if (func.return_value_type == null || func.return_value_type == SystemLibrary.SystemLibrary.void_type)
                il.Emit(OpCodes.Ret);
            cur_meth = tmp;
            cur_type = tmp_type;
            il = tmp_il;
            smi.Pop();
            funcs.RemoveAt(funcs.Count - 1);
            num_scope--;
        }
Example #5
0
 //перевод тел функций
 private void ConvertFunctionsBodies(ICommonFunctionNode[] funcs)
 {
     for (int i = 0; i < funcs.Length; i++)
     {
         IStatementsListNode sl = (IStatementsListNode)funcs[i].function_code;
         /*if (sl.statements.Length > 0 && (sl.statements[0] is IExternalStatementNode))
         {
             continue;
         }*/
         ConvertFunctionBody(funcs[i]);
     }
 }
Example #6
0
        //создание записи активации для влож. процедур
        private Frame MakeAuxType(ICommonFunctionNode func)
        {

            TypeBuilder tb = cur_type.DefineNestedType("$" + func.name + "$" + uid++, TypeAttributes.NestedPublic);
            //определяем поле - ссылку на верхнюю запись активации
            FieldBuilder fb = tb.DefineField("$parent$", tb.DeclaringType.IsValueType ? tb.DeclaringType.MakePointerType() : tb.DeclaringType, FieldAttributes.Public);
            //конструктор в кач-ве параметра, которого передается ссылка на верх. з/а
            ConstructorBuilder cb = null;
            //определяем метод для инициализации
            MethodBuilder mb = tb.DefineMethod("$Init$", MethodAttributes.Private, TypeFactory.VoidType, Type.EmptyTypes);
            if (funcs.Count > 0)
            {
                cb = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[1] { tb.DeclaringType.IsValueType ? tb.DeclaringType.MakeByRefType() : tb.DeclaringType });
                cb.DefineParameter(1, ParameterAttributes.None, "$parent$");
            }
            else
                cb = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, Type.EmptyTypes);
            ILGenerator il = cb.GetILGenerator();
            //сохраняем ссылку на верхнюю запись активации
            if (func is ICommonNestedInFunctionFunctionNode)
            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Stfld, fb);
            }
            //вызываем метод $Init$
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Call, mb);
            il.Emit(OpCodes.Ret);
            types.Add(tb);
            //создаем кадр записи активации
            Frame frm = new Frame();
            frm.cb = cb;
            frm.mb = mb;
            frm.tb = tb;
            frm.parent = fb;
            return frm;
        }
Example #7
0
 public void ConvertTypeInstancesInFunction(ICommonFunctionNode func)
 {
     List<IGenericTypeInstance> insts;
     bool flag = instances_in_functions.TryGetValue(func, out insts);
     if (!flag) return;
     foreach (IGenericTypeInstance igi in insts)
     {
         ConvertTypeHeaderInSpecialOrder(igi);
     }
 }
Example #8
0
 public static string build_name_with_possible_generic(ICommonFunctionNode f, bool use_lt)
 {
     StringBuilder sb = new StringBuilder();
     sb.Append(f.name);
     if (f.generic_params != null)
     {
         if (use_lt)
             sb.Append("&lt");
         else
             sb.Append("<");
         for (int i = 0; i < f.generic_params.Count; i++)
         {
             sb.Append(f.generic_params[i].name);
             if (i < f.generic_params.Count - 1)
                 sb.Append(',');
         }
         if (use_lt)
             sb.Append("&gt");
         else sb.Append(">");
     }
     return sb.ToString();
 }
Example #9
0
 private void AddTypeInstanceToFunction(ICommonFunctionNode func, IGenericTypeInstance gti)
 {
     List<IGenericTypeInstance> instances;
     //if (func == null) // SSM 3.07.16 Это решает проблему с оставшимся после перевода в сем. дерево узлом IEnumerable<UnknownType>, но очень грубо - пробую найти ошибку раньше
     //    return;
     bool found = instances_in_functions.TryGetValue(func, out instances);
     if (!found)
     {
         instances = new List<IGenericTypeInstance>();
         instances_in_functions.Add(func, instances);
     }
     if (!instances.Contains(gti))
     {
         instances.Add(gti);
     }
 }
Example #10
0
        private void MakeAttribute(ICommonFunctionNode func)
        {
            MethodBuilder mb = helper.GetMethod(func).mi as MethodBuilder;
            IAttributeNode[] attrs = func.Attributes;
            for (int i = 0; i < attrs.Length; i++)
            {

                CustomAttributeBuilder cab = new CustomAttributeBuilder
                    ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments),
                    get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers),
                    get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers));
                mb.SetCustomAttribute(cab);
            }
            foreach (IParameterNode pn in func.parameters)
            {
                ParamInfo pi = helper.GetParameter(pn);
                if (pi == null) continue;
                ParameterBuilder pb = pi.pb;
                attrs = pn.Attributes;
                for (int i = 0; i < attrs.Length; i++)
                {
                    CustomAttributeBuilder cab = new CustomAttributeBuilder
                        ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments),
                        get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers),
                        get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers));
                    pb.SetCustomAttribute(cab);
                }
            }
        }
Example #11
0
 public void visit(ICommonFunctionNode value)
 {
     string s = value.GetType().ToString() + ".";
     prepare_string_node(value.name, s + "name");
     prepare_collection(value.constants, s + "constants", "constants", value.constants.Length);
     prepare_node(value.function_code, s + "function_code");
     prepare_collection(value.functions_nodes, s + "function_nodes", "function_nodes", value.functions_nodes.Length);
     prepare_string_node(value.node_kind.ToString(), s + "node_kind");
     prepare_string_node(value.node_location_kind.ToString(), s + "node_location_kind");
     prepare_collection(value.parameters, s + "parameters", "parameters", value.parameters.Length);
     prepare_string_node(value.return_value_type.ToString(), s + "return_value_type");
     //prepare_node(value.return_variable, s + "return_variable");  
     prepare_up_link_node(value.return_variable.name, s + "return_variable", value.return_variable);
     prepare_string_node(value.SpecialFunctionKind.ToString(), s + "SpecialFunctionKind");
     prepare_collection(value.var_definition_nodes, s + "var_definition_nodes", "var_definition_nodes", value.var_definition_nodes.Length);
 }
Example #12
0
		public virtual void visit(ICommonFunctionNode value)
		{
		}
Example #13
0
 public void visit(ICommonFunctionNode value)
 {
     throw new System.NotSupportedException(value.GetType().ToString());            
 }
Example #14
0
 private void AddTypeInstanceToFunction(ICommonFunctionNode func, IGenericTypeInstance gti)
 {
     List<IGenericTypeInstance> instances;
     bool found = instances_in_functions.TryGetValue(func, out instances);
     if (!found)
     {
         instances = new List<IGenericTypeInstance>();
         instances_in_functions.Add(func, instances);
     }
     if (!instances.Contains(gti))
     {
         instances.Add(gti);
     }
 }
Example #15
0
 public void ConvertTypeInstancesMembersInFunction(ICommonFunctionNode func)
 {
     List<IGenericTypeInstance> insts;
     bool flag = instances_in_functions.TryGetValue(func, out insts);
     if (!flag) return;
     foreach (IGenericTypeInstance igi in insts)
     {
         ConvertGenericInstanceTypeMembers(igi);
     }
 }
 public virtual void visit(ICommonFunctionNode value)
 {
 }
Example #17
0
		public static string get_simple_meth_header(ICommonFunctionNode f)
		{
			StringBuilder sb = new StringBuilder();
			string hdr = HelpUtils.extract_user_defined_header(f.Documentation);
			if (!string.IsNullOrEmpty(hdr))
			{
				sb.Append(hdr);
				return sb.ToString();
			}
			sb.Append(f.name);
			sb.Append(get_generic_string(f.generic_params));
            if (f.parameters.Length > 0)
            {
                sb.Append('(');
                for (int i = 0; i < f.parameters.Length; i++)
                {
                    sb.Append(get_type_text(f.parameters[i].type));
                    if (i < f.parameters.Length - 1)
                        sb.Append(", ");
                }
                sb.Append(')');
            }
			return sb.ToString();
		}