Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'mcs/ilasm/codegen/Instructions.cs')
-rw-r--r--mcs/ilasm/codegen/Instructions.cs291
1 files changed, 291 insertions, 0 deletions
diff --git a/mcs/ilasm/codegen/Instructions.cs b/mcs/ilasm/codegen/Instructions.cs
new file mode 100644
index 00000000000..281b9fd87bf
--- /dev/null
+++ b/mcs/ilasm/codegen/Instructions.cs
@@ -0,0 +1,291 @@
+// Instructions.cs
+// (C) Sergey Chaban (serge@wildwestsoftware.com)
+
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Collections;
+
+namespace Mono.ILASM {
+
+
+ /// <summary>
+ /// </summary>
+ public class InstrNone : InstrBase {
+
+ /// <summary>
+ /// </summary>
+ /// <param name="tok"></param>
+ public InstrNone (OpCode op) : base (op)
+ {
+ }
+
+ /// <summary>
+ /// </summary>
+ /// <param name="ilgen"></param>
+ public override void Emit (ILGenerator ilgen, Class host)
+ {
+ ilgen.Emit (this.Opcode);
+ }
+ }
+
+
+ /// <summary>
+ /// </summary>
+ public class InstrVar : InstrBase {
+
+ private object operand;
+
+ /// <summary>
+ /// </summary>
+ /// <param name="tok"></param>
+ public InstrVar (OpCode op, object operand) : base (op)
+ {
+ this.operand = operand;
+ }
+
+
+ /// <summary>
+ /// </summary>
+ /// <param name="ilgen"></param>
+ public override void Emit (ILGenerator ilgen, Class host)
+ {
+ if (operand is string) {
+ ilgen.Emit (Opcode, operand as string);
+ } else if (operand is Int32) {
+ ilgen.Emit (Opcode, (Int32)operand);
+ }
+ }
+ }
+
+
+ /// <summary>
+ /// </summary>
+ public class InstrI : InstrBase {
+
+ private int operand;
+
+ /// <summary>
+ /// </summary>
+ /// <param name="tok"></param>
+ public InstrI (OpCode op, int operand) : base (op) {
+ this.operand = operand;
+ }
+
+
+ /// <summary>
+ /// </summary>
+ /// <param name="ilgen"></param>
+ public override void Emit (ILGenerator ilgen, Class host) {
+ ilgen.Emit (Opcode, operand);
+ }
+ }
+
+
+ /// <summary>
+ /// </summary>
+ public class InstrI8 : InstrBase {
+
+ private long operand;
+
+ /// <summary>
+ /// </summary>
+ /// <param name="tok"></param>
+ public InstrI8 (OpCode op, long operand) : base (op) {
+ this.operand = operand;
+ }
+
+
+ /// <summary>
+ /// </summary>
+ /// <param name="ilgen"></param>
+ public override void Emit (ILGenerator ilgen, Class host) {
+ ilgen.Emit (Opcode, operand);
+ }
+ }
+
+
+ /// <summary>
+ /// </summary>
+ public class InstrR : InstrBase {
+
+ private double operand;
+
+ /// <summary>
+ /// </summary>
+ /// <param name="tok"></param>
+ public InstrR (OpCode op, double operand) : base (op) {
+ this.operand = operand;
+ }
+
+
+ /// <summary>
+ /// </summary>
+ /// <param name="ilgen"></param>
+ public override void Emit (ILGenerator ilgen, Class host) {
+ if (Opcode.Name.IndexOf (".r4") != -1) {
+ ilgen.Emit (Opcode, (float) operand);
+ } else {
+ ilgen.Emit (Opcode, operand);
+ }
+ }
+ }
+
+
+
+ /// <summary>
+ /// </summary>
+ public class InstrString : InstrBase {
+
+ private string operand;
+
+ /// <summary>
+ /// </summary>
+ /// <param name="tok"></param>
+ public InstrString (OpCode op, string operand) : base (op) {
+ this.operand = operand;
+ }
+
+
+ /// <summary>
+ /// </summary>
+ /// <param name="ilgen"></param>
+ public override void Emit (ILGenerator ilgen, Class host) {
+ ilgen.Emit (Opcode, operand);
+ }
+ }
+
+
+ /// <summary>
+ /// Base class for instructions that call methods
+ /// </summary>
+ public abstract class InstrCallBase : InstrBase {
+
+ private string return_type;
+ private string binding_flags;
+ private string calling_type;
+ private string method_name;
+ private ArrayList arg_list;
+
+ /// <summary>
+ /// </summary>
+ /// <param name="tok"></param>
+ public InstrCallBase (OpCode op, string binding_flags, string return_type,
+ string calling_type, string method_name, ArrayList arg_list) : base (op) {
+
+ this.binding_flags = binding_flags;
+ this.return_type = return_type;
+ this.calling_type = calling_type;
+ this.method_name = method_name;
+ this.arg_list = arg_list;
+
+ }
+
+ protected Type[] CreateArgsTypeArray (CodeGen code_gen)
+ {
+ if (arg_list == null)
+ return new Type[0];
+
+ int size = arg_list.Count;
+ Type[] type_array = new Type[size];
+
+ for (int i=0; i<size; i++) {
+ type_array[i] = code_gen.TypeManager[(string)arg_list[i]];
+ }
+
+ return type_array;
+ }
+
+ protected BindingFlags CreateBindingFlags ()
+ {
+ if ((binding_flags == null) || (binding_flags == String.Empty))
+ return (BindingFlags.Static | BindingFlags.Public);
+
+ BindingFlags return_flags = BindingFlags.Public;
+
+ switch (binding_flags) {
+ case "instance":
+ return_flags |= BindingFlags.Instance;
+ break;
+ }
+
+ return return_flags;
+ }
+
+
+ }
+
+ /// <summary>
+ /// call void System.Console::WriteLine(string)
+ /// </summary>
+ public class InstrCall : InstrCallBase {
+
+ /// <summary>
+ /// </summary>
+ /// <param name="tok"></param>
+ public InstrCall (OpCode op, string binding_flags, string return_type, string calling_type,
+ string method_name, ArrayList arg_list) : base (op, binding_flags,
+ return_type, calling_type, method_name, arg_list) {
+
+ }
+
+
+ /// <summary>
+ /// </summary>
+ /// <param name="ilgen"></param>
+ public override void Emit (ILGenerator ilgen, Class host) {
+ Type type_to_call = host.CodeGen.TypeManager[calling_type];
+ MethodInfo calling_method;
+
+ if (type_to_call == host.TypeBuilder) {
+ calling_method = host.GetMethod (method_name, CreateBindingFlags (),
+ CreateArgsTypeArray (host.CodeGen));
+ } else {
+ calling_method = type_to_call.GetMethod (method_name, CreateBindingFlags (),
+ null, CreateArgsTypeArray (host.CodeGen), null);
+ }
+
+ if (calling_method == null) {
+ Console.WriteLine ("Method does not exist: {0}.{1}", type_to_call, method_name);
+ return;
+ }
+
+ ilgen.Emit (Opcode, calling_method);
+
+ }
+
+ }
+
+ /// <summary>
+ /// </summary>
+ public class InstrNewobj : InstrCallBase {
+
+ /// <summary>
+ /// </summary>
+ /// <param name="tok"></param>
+ public InstrNewobj (OpCode op, string binding_flags, string return_type, string calling_type,
+ string method_name, ArrayList arg_list) : base (op, binding_flags,
+ return_type, calling_type, method_name, arg_list) {
+
+ }
+
+
+ /// <summary>
+ /// </summary>
+ /// <param name="ilgen"></param>
+ public override void Emit (ILGenerator ilgen, Class host) {
+ Type type_to_call = host.CodeGen.TypeManager[calling_type];
+ ConstructorInfo calling_constructor = null;
+
+ calling_constructor = type_to_call.GetConstructor (CreateArgsTypeArray (host.CodeGen));
+
+ if (calling_constructor == null) {
+ Console.WriteLine ("Constructor does not exist for: {0}", type_to_call);
+ return;
+ }
+
+ ilgen.Emit (Opcode, calling_constructor);
+ }
+ }
+}
+