Beispiel #1
0
        public MethodDef(CodeGen codegen, PEAPI.MethAttr meth_attr,
                         PEAPI.CallConv call_conv, PEAPI.ImplAttr impl_attr,
                         string name, BaseTypeRef ret_type, ArrayList param_list,
                         Location start, GenericParameters gen_params, TypeDef type_def)
        {
            this.codegen    = codegen;
            this.meth_attr  = meth_attr;
            this.call_conv  = call_conv;
            this.impl_attr  = impl_attr;
            this.name       = name;
            this.param_list = param_list;
            this.type_def   = type_def;
            this.gen_params = gen_params;
            this.ret_param  = new ParamDef(PEAPI.ParamAttr.Default, "", ret_type);
            this.start      = (Location)start.Clone();

            inst_list          = new ArrayList();
            label_table        = new Hashtable();
            labelref_table     = new Hashtable();
            label_list         = new ArrayList();
            local_list         = new ArrayList();
            named_local_tables = new ArrayList();
            named_local_tables.Add(new Hashtable());
            current_scope_depth = 0;

            entry_point  = false;
            zero_init    = false;
            init_locals  = false;
            max_stack    = -1;
            pinvoke_info = false;

            is_defined  = false;
            is_resolved = false;
            ResolveGenParams();
            CreateSignature();

            codegen.BeginMethodDef(this);

            if (codegen.SymbolWriter != null)
            {
                source = codegen.SymbolWriter.BeginMethod(this, start);
            }
        }
Beispiel #2
0
                public MethodDef (CodeGen codegen, PEAPI.MethAttr meth_attr,
				  PEAPI.CallConv call_conv, PEAPI.ImplAttr impl_attr,
				  string name, BaseTypeRef ret_type, ArrayList param_list,
				  Location start, GenericParameters gen_params, TypeDef type_def)
                {
                        this.codegen = codegen;
                        this.meth_attr = meth_attr;
                        this.call_conv = call_conv;
                        this.impl_attr = impl_attr;
                        this.name = name;
                        this.param_list = param_list;
                        this.type_def = type_def;
                        this.gen_params = gen_params;
                        this.ret_param = new ParamDef (PEAPI.ParamAttr.Default, "", ret_type);
                        this.start = (Location) start.Clone ();

                        inst_list = new ArrayList ();
                        label_table = new Hashtable ();
                        labelref_table = new Hashtable ();
                        label_list = new ArrayList ();
                        local_list = new ArrayList ();
                        named_local_tables = new ArrayList ();
                        named_local_tables.Add (new Hashtable ());
                        current_scope_depth = 0;

                        entry_point = false;
                        zero_init = false;
                        init_locals = false;
                        max_stack = -1;
                        pinvoke_info = false;

                        is_defined = false;
                        is_resolved = false;
                        ResolveGenParams ();
                        CreateSignature ();

			codegen.BeginMethodDef (this);

			if (codegen.SymbolWriter != null)
				source = codegen.SymbolWriter.BeginMethod (this, start);
                }
Beispiel #3
0
 private void FixAttributes ()
 {
         if (name == ".ctor" || name == ".cctor")
                 meth_attr |= PEAPI.MethAttr.SpecialName | PEAPI.MethAttr.RTSpecialName;
         // If methods aren't flagged as static they are instance
         if ((PEAPI.MethAttr.Static & meth_attr) == 0)
                 call_conv |= PEAPI.CallConv.Instance;
 }
Beispiel #4
0
                protected void WriteCode (CodeGen code_gen, PEAPI.MethodDef methoddef)
                {
                        /// Add the custrom attributes to this method
                        if (customattr_list != null)
                                foreach (CustomAttr customattr in customattr_list) {
                                        customattr.AddTo (code_gen, methoddef);
                                        if (customattr.IsSuppressUnmanaged (code_gen))
                                                methoddef.AddMethAttribute (PEAPI.MethAttr.HasSecurity);
				}

                        /// Add declarative security to this method
			if (decl_sec != null) {
				decl_sec.AddTo (code_gen, methoddef);
                                methoddef.AddMethAttribute (PEAPI.MethAttr.HasSecurity);
                        }        

                        // Generic type parameters
                        if (gen_params != null)
                                gen_params.Resolve (code_gen, methoddef);

                        if (type_def == null) {
                                //Global method
                                meth_attr &= ~PEAPI.MethAttr.Abstract;
                                meth_attr |= PEAPI.MethAttr.Static;
                        } else {
                                if ((inst_list.Count > 0) && type_def.IsInterface && !IsStatic)
                                        Report.Error (start, "Method cannot have body if it is non-static declared in an interface");
                                
                                if (IsAbstract) {
                                        if (!type_def.IsAbstract)
                                                Report.Error (start, String.Format ("Abstract method '{0}' in non-abstract class '{1}'", 
                                                                        Name, type_def.FullName));
                                        if (inst_list.Count > 0)
                                                Report.Error (start, "Method cannot have body if it is abstract.");
                                        return;
                                }
                        }

                        if (entry_point)
                                methoddef.DeclareEntryPoint ();

                        if (local_list.Count > 0) {
                                int ec = Report.ErrorCount;
                                PEAPI.Local[] local_array = new PEAPI.Local[local_list.Count];

                                foreach (Local local in local_list)
                                        local_array[local.Slot]  = local.GetPeapiLocal (code_gen);

                                if (Report.ErrorCount > ec)
                                        return;

                                if (zero_init)
                                        init_locals = true;
                                
                                methoddef.AddLocals (local_array, init_locals);
                        }

                        /// Nothing seems to work if maxstack is not set,
                        /// i need to find out if this NEEDs to be set
                        /// and what its default value should be
                        if (max_stack < 0)
                                max_stack = 8;
                        methoddef.SetMaxStack (max_stack);

                        if (pinvoke_info) {
                                methoddef.AddPInvokeInfo (pinvoke_mod.ModuleRef,
                                                (pinvoke_name != null ? pinvoke_name : name), pinvoke_attr);
                        }

                        if ((impl_attr & PEAPI.ImplAttr.Runtime) == PEAPI.ImplAttr.Runtime) {
                                if (inst_list.Count > 0)
                                        Report.Error (start, String.Format ("Method cannot have body if it is non-IL runtime-supplied, '{0}'", 
                                                                FullName));
                        } else {
                                if (((impl_attr & PEAPI.ImplAttr.Native) != 0) ||
                                        ((impl_attr & PEAPI.ImplAttr.Unmanaged) != 0))
                                        Report.Error (start, String.Format ("Cannot compile native/unmanaged method, '{0}'", 
                                                                FullName));
                        }

                        if (inst_list.Count > 0) {
                                /* Has body */
                                if ((impl_attr & PEAPI.ImplAttr.InternalCall) != 0)
                                        Report.Error (start, String.Format ("Method cannot have body if it is an internal call, '{0}'", 
                                                                FullName));

                                if (pinvoke_info)
                                        Report.Error (start, String.Format ("Method cannot have body if it is pinvoke, '{0}'",
                                                                FullName));
                        } else {
                                if (pinvoke_info ||
                                        ((impl_attr & PEAPI.ImplAttr.Runtime) != 0) ||
                                        ((impl_attr & PEAPI.ImplAttr.InternalCall) != 0))
                                        /* No body required */
                                        return;

                                Report.Warning (start, "Method has no body, 'ret' emitted.");
                                AddInstr (new SimpInstr (PEAPI.Op.ret, start));
                        }

                        PEAPI.CILInstructions cil = methoddef.CreateCodeBuffer ();
                        /// Create all the labels
                        /// TODO: Most labels don't actually need to be created so we could
                        /// probably only create the ones that need to be
                        LabelInfo[] label_info = new LabelInfo[label_table.Count + label_list.Count];
                        label_table.Values.CopyTo (label_info, 0);
                        label_list.CopyTo (label_info, label_table.Count);
                        int previous_pos = -1;
                        LabelInfo previous_label = null;
                        Array.Sort (label_info);

                        foreach (LabelInfo label in label_info) {
                                if (label.UseOffset) {
                                        label.Define (new PEAPI.CILLabel (label.Offset, true));
                                        continue;
                                }
                                if (label.Pos == previous_pos)
                                        label.Label = previous_label.Label;
                                else
                                        label.Define (cil.NewLabel ());

                                previous_label = label;
                                previous_pos = label.Pos;
                        }

                        // Set all the label refs
                        foreach (LabelInfo label in labelref_table.Values) {
                                LabelInfo def = (LabelInfo) label_table[label.Name];
                                if (def == null) {
                                        Report.Error ("Undefined Label:  " + label);
                                        return;
                                }
                                label.Label = def.Label;
                        }

                        int label_pos = 0;
                        int next_label_pos = (label_info.Length > 0 ? label_info[0].Pos : -1);

                        for (int i=0; i<inst_list.Count; i++) {
                                IInstr instr = (IInstr) inst_list[i];
                                if (next_label_pos == i) {
                                        cil.CodeLabel (label_info[label_pos].Label);
                                        if (label_pos < label_info.Length) {
                                                while (next_label_pos == i && ++label_pos < label_info.Length) {
                                                        if (label_info[label_pos].UseOffset)
                                                                cil.CodeLabel (label_info[label_pos].Label);
                                                       next_label_pos = label_info[label_pos].Pos;
                                                }
                                        }
                                        if (label_pos >= label_info.Length)
                                                next_label_pos = -1;
                                }
				if (source != null)
					source.MarkLocation (instr.Location.line, cil.Offset);
                                instr.Emit (code_gen, this, cil);
                        }

			if (source != null)
				source.MarkLocation (source.EndLine, cil.Offset);
                }
Beispiel #5
0
        protected void WriteCode(CodeGen code_gen, PEAPI.MethodDef methoddef)
        {
            /// Add the custrom attributes to this method
            if (customattr_list != null)
            {
                foreach (CustomAttr customattr in customattr_list)
                {
                    customattr.AddTo(code_gen, methoddef);
                    if (customattr.IsSuppressUnmanaged(code_gen))
                    {
                        methoddef.AddMethAttribute(PEAPI.MethAttr.HasSecurity);
                    }
                }
            }

            /// Add declarative security to this method
            if (decl_sec != null)
            {
                decl_sec.AddTo(code_gen, methoddef);
                methoddef.AddMethAttribute(PEAPI.MethAttr.HasSecurity);
            }

            // Generic type parameters
            if (gen_params != null)
            {
                gen_params.Resolve(code_gen, methoddef);
            }

            if (type_def == null)
            {
                //Global method
                meth_attr &= ~PEAPI.MethAttr.Abstract;
                meth_attr |= PEAPI.MethAttr.Static;
            }
            else
            {
                if ((inst_list.Count > 0) && type_def.IsInterface && !IsStatic)
                {
                    Report.Error(start, "Method cannot have body if it is non-static declared in an interface");
                }

                if (IsAbstract)
                {
                    if (!type_def.IsAbstract)
                    {
                        Report.Error(start, String.Format("Abstract method '{0}' in non-abstract class '{1}'",
                                                          Name, type_def.FullName));
                    }
                    if (inst_list.Count > 0)
                    {
                        Report.Error(start, "Method cannot have body if it is abstract.");
                    }
                    return;
                }
            }

            if (entry_point)
            {
                methoddef.DeclareEntryPoint();
            }

            if (local_list.Count > 0)
            {
                int           ec          = Report.ErrorCount;
                PEAPI.Local[] local_array = new PEAPI.Local[local_list.Count];

                foreach (Local local in local_list)
                {
                    local_array[local.Slot] = local.GetPeapiLocal(code_gen);
                }

                if (Report.ErrorCount > ec)
                {
                    return;
                }

                if (zero_init)
                {
                    init_locals = true;
                }

                methoddef.AddLocals(local_array, init_locals);
            }

            /// Nothing seems to work if maxstack is not set,
            /// i need to find out if this NEEDs to be set
            /// and what its default value should be
            if (max_stack < 0)
            {
                max_stack = 8;
            }
            methoddef.SetMaxStack(max_stack);

            if (pinvoke_info)
            {
                methoddef.AddPInvokeInfo(pinvoke_mod.ModuleRef,
                                         (pinvoke_name != null ? pinvoke_name : name), pinvoke_attr);
            }

            if ((impl_attr & PEAPI.ImplAttr.Runtime) == PEAPI.ImplAttr.Runtime)
            {
                if (inst_list.Count > 0)
                {
                    Report.Error(start, String.Format("Method cannot have body if it is non-IL runtime-supplied, '{0}'",
                                                      FullName));
                }
            }
            else
            {
                if (((impl_attr & PEAPI.ImplAttr.Native) != 0) ||
                    ((impl_attr & PEAPI.ImplAttr.Unmanaged) != 0))
                {
                    Report.Error(start, String.Format("Cannot compile native/unmanaged method, '{0}'",
                                                      FullName));
                }
            }

            if (inst_list.Count > 0)
            {
                /* Has body */
                if ((impl_attr & PEAPI.ImplAttr.InternalCall) != 0)
                {
                    Report.Error(start, String.Format("Method cannot have body if it is an internal call, '{0}'",
                                                      FullName));
                }

                if (pinvoke_info)
                {
                    Report.Error(start, String.Format("Method cannot have body if it is pinvoke, '{0}'",
                                                      FullName));
                }
            }
            else
            {
                if (pinvoke_info ||
                    ((impl_attr & PEAPI.ImplAttr.Runtime) != 0) ||
                    ((impl_attr & PEAPI.ImplAttr.InternalCall) != 0))
                {
                    /* No body required */
                    return;
                }

                Report.Warning(start, "Method has no body, 'ret' emitted.");
                AddInstr(new SimpInstr(PEAPI.Op.ret, start));
            }

            PEAPI.CILInstructions cil = methoddef.CreateCodeBuffer();
            /// Create all the labels
            /// TODO: Most labels don't actually need to be created so we could
            /// probably only create the ones that need to be
            LabelInfo[] label_info = new LabelInfo[label_table.Count + label_list.Count];
            label_table.Values.CopyTo(label_info, 0);
            label_list.CopyTo(label_info, label_table.Count);
            int       previous_pos   = -1;
            LabelInfo previous_label = null;

            Array.Sort(label_info);

            foreach (LabelInfo label in label_info)
            {
                if (label.UseOffset)
                {
                    label.Define(new PEAPI.CILLabel(label.Offset, true));
                    continue;
                }
                if (label.Pos == previous_pos)
                {
                    label.Label = previous_label.Label;
                }
                else
                {
                    label.Define(cil.NewLabel());
                }

                previous_label = label;
                previous_pos   = label.Pos;
            }

            // Set all the label refs
            foreach (LabelInfo label in labelref_table.Values)
            {
                LabelInfo def = (LabelInfo)label_table[label.Name];
                if (def == null)
                {
                    Report.Error("Undefined Label:  " + label);
                    return;
                }
                label.Label = def.Label;
            }

            int label_pos      = 0;
            int next_label_pos = (label_info.Length > 0 ? label_info[0].Pos : -1);

            for (int i = 0; i < inst_list.Count; i++)
            {
                IInstr instr = (IInstr)inst_list[i];
                if (next_label_pos == i)
                {
                    cil.CodeLabel(label_info[label_pos].Label);
                    if (label_pos < label_info.Length)
                    {
                        while (next_label_pos == i && ++label_pos < label_info.Length)
                        {
                            if (label_info[label_pos].UseOffset)
                            {
                                cil.CodeLabel(label_info[label_pos].Label);
                            }
                            next_label_pos = label_info[label_pos].Pos;
                        }
                    }
                    if (label_pos >= label_info.Length)
                    {
                        next_label_pos = -1;
                    }
                }
                if (source != null)
                {
                    source.MarkLocation(instr.Location.line, cil.Offset);
                }
                instr.Emit(code_gen, this, cil);
            }

            if (source != null)
            {
                source.MarkLocation(source.EndLine, cil.Offset);
            }
        }
Beispiel #6
0
        static string CreateSignature(BaseTypeRef RetType, string name, IList param_list, int gen_param_count, PEAPI.MethAttr attrs)
        {
            StringBuilder builder = new StringBuilder();

            if ((attrs & PEAPI.MethAttr.Static) == 0)
            {
                builder.Append("instance ");
            }

            builder.Append(RetType.FullName);
            builder.Append(" ");
            builder.Append(name);
            if (gen_param_count > 0)
            {
                builder.AppendFormat("`{0}", gen_param_count);
            }
            builder.Append('(');

            if (param_list != null)
            {
                bool first = true;
                foreach (ParamDef paramdef in param_list)
                {
                    if (!first)
                    {
                        builder.Append(',');
                    }
                    builder.Append(paramdef.TypeName);
                    first = false;
                }
            }
            builder.Append(')');

            return(builder.ToString());
        }