Author: zoltan
Date: 2008-02-13 09:58:33 -0500 (Wed, 13 Feb 2008)
New Revision: 95582

Added:
   trunk/mcs/class/System/System.Text.RegularExpressions/CILCompiler.cs
Modified:
   trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog
   trunk/mcs/class/System/System.Text.RegularExpressions/RxCompiler.cs
Log:
2008-02-13  Zoltan Varga  <[EMAIL PROTECTED]>

        * CILCompiler.cs: New file, extracted from RxCompiler.cs.


Added: trunk/mcs/class/System/System.Text.RegularExpressions/CILCompiler.cs
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/CILCompiler.cs        
2008-02-13 14:58:29 UTC (rev 95581)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/CILCompiler.cs        
2008-02-13 14:58:33 UTC (rev 95582)
@@ -0,0 +1,504 @@
+using System;
+using System.Collections;
+using System.Globalization;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace System.Text.RegularExpressions {
+
+       //
+       // Compiler which generates IL bytecode to perform the matching instead 
of
+       // interpreting a program.
+       // For simplicity, we inherit from RxCompiler, and generate the IL code 
based
+       // on the program generated by it. This also allows us to fallback to 
interpretation
+       // if we can't handle something.
+       // This is net 2.0, since 1.0 doesn't support DynamicMethods
+       // FIXME: Add support for 1.0, and CompileToAssembly
+       // FIXME: Emit one method with a switch instead of many methods
+       // FIXME: Avoid ref ptr, since it is bad for register allocation
+       //
+
+#if NET_2_0
+       class CILCompiler : RxCompiler, ICompiler {
+               DynamicMethod[] eval_methods;
+               bool[] eval_methods_defined;
+
+               IMachineFactory ICompiler.GetMachineFactory () {
+                       byte[] code = new byte [curpos];
+                       Buffer.BlockCopy (program, 0, code, 0, curpos);
+
+                       eval_methods = new DynamicMethod [code.Length];
+                       eval_methods_defined = new bool [code.Length];
+
+                       // The main eval method
+                   DynamicMethod main = GetEvalMethod (code, 11);
+                       if (main != null)
+                               return new RxInterpreterFactory (code, 
(EvalDelegate)main.CreateDelegate (typeof (EvalDelegate)));
+                       else
+                               return new RxInterpreterFactory (code, null);
+               }
+
+               DynamicMethod GetEvalMethod (byte[] program, int pc) {
+                       if (eval_methods_defined [pc])
+                               return eval_methods [pc];
+
+                       // FIXME: Recursion ?
+                       eval_methods_defined [pc] = true;
+
+                       eval_methods [pc] = CreateEvalMethod (program, pc);
+                       return eval_methods [pc];
+               }
+
+               private FieldInfo GetInterpreterField (string name) {
+                       return typeof (RxInterpreter).GetField (name, 
BindingFlags.Instance|BindingFlags.NonPublic);
+               }
+
+               private MethodInfo GetInterpreterMethod (string name) {
+                       return typeof (RxInterpreter).GetMethod (name, 
BindingFlags.Instance|BindingFlags.NonPublic);
+               }
+
+               private string GetString (ushort[] program, int pc) {
+                       int len = program[pc + 1];
+                       int str = pc + 2;
+
+                       char[] cs = new char[len];
+                       for (int i = 0; i < len; ++ i)
+                               cs[i] = (char)program[str ++];
+
+                       return new string (cs);
+               }
+
+               private int ReadInt (byte[] code, int pc)
+               {
+                       int val = code [pc];
+                       val |= code [pc + 1] << 8;
+                       val |= code [pc + 2] << 16;
+                       val |= code [pc + 3] << 24;
+                       return val;
+               }
+
+               private MethodInfo GetEvalMethodWithFallback (byte[] program, 
int pc, out bool fallback) {
+                       DynamicMethod eval = GetEvalMethod (program, pc);
+                       fallback = eval != null;
+                       if (eval != null) {
+                               fallback = false;
+                               return eval;
+                       } else {
+                               fallback = true;
+                               return GetInterpreterMethod ("EvalByteCode");
+                       }
+               }
+
+               //
+               // Create a dynamic method which is the Interpreter.Eval method 
specialized
+               // to the given program and a given pc.
+               // Keep this in synch with Interpreter.Eval ()
+               //
+               DynamicMethod CreateEvalMethod (byte[] program, int pc) {
+                       DynamicMethod m = new DynamicMethod ("Eval_" + pc, 
typeof (bool), new Type [] { typeof (RxInterpreter), typeof (int), typeof 
(int).MakeByRefType () }, typeof (RxInterpreter), true);
+                       ILGenerator ilgen = m.GetILGenerator ();
+
+                       /* 
+                          Args:
+                          interp - 0
+                          strpos - 1
+                          strpos_result - 2
+                       */
+
+                       int start, length, end;
+                       bool fallback;
+
+                       Label label_fail = ilgen.DefineLabel ();
+
+                       while (true) {
+                               RxOp op = (RxOp)program [pc];
+
+                               switch (op) {
+                               case RxOp.Anchor: {
+                                       length = program [pc + 3] | (program 
[pc + 4] << 8);
+                                       pc += program [pc + 1] | (program [pc + 
2] << 8);
+
+                                       // FIXME: Group support
+                                       
+                                       // Optimize some common cases by 
inlining the code generated for the
+                                       // anchor body 
+                                       RxOp anch_op = (RxOp)program [pc];
+                                       // FIXME: Do this even if the archor op 
is not the last in the regex
+                                       if (anch_op == RxOp.Char && 
(RxOp)program [pc + 2] == RxOp.True) {
+
+                                               /*
+                                                * while (strpos < string_end) {
+                                                *   if (str [strpos] == 
program [pc + 1]) {
+                                                *     match_start = strpos;
+                                                *     strpos_result = strpos + 
1;
+                                                *     return true;
+                                                *   }
+                                                *   strpos ++;
+                                                * }
+                                                * return false;
+                                                */
+                                               // Add some locals to avoid an 
indirection
+                                               LocalBuilder local_string_end = 
ilgen.DeclareLocal (typeof (int));
+                                               ilgen.Emit (OpCodes.Ldarg_0);
+                                               ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("string_end"));
+                                               ilgen.Emit (OpCodes.Stloc, 
local_string_end);
+                                               LocalBuilder local_str = 
ilgen.DeclareLocal (typeof (string));
+                                               ilgen.Emit (OpCodes.Ldarg_0);
+                                               ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("str"));
+                                               ilgen.Emit (OpCodes.Stloc, 
local_str);
+
+                                               //while (strpos < string_end) {
+                                               // -> Done at the end of the 
loop like mcs does
+                                               Label l1 = ilgen.DefineLabel ();
+                                               Label l2 = ilgen.DefineLabel ();
+                                               ilgen.Emit (OpCodes.Br, l2);
+                                               ilgen.MarkLabel (l1);
+
+                                               //  if (str [strpos] == program 
[pc + 1]) {
+                                               Label l3 = ilgen.DefineLabel ();
+                                               ilgen.Emit (OpCodes.Ldloc, 
local_str);
+                                               ilgen.Emit (OpCodes.Ldarg_1);
+                                               ilgen.Emit (OpCodes.Callvirt, 
typeof (string).GetMethod ("get_Chars"));
+                                               ilgen.Emit (OpCodes.Conv_I4);
+                                               ilgen.Emit (OpCodes.Ldc_I4, 
(int)program [pc + 1]);
+                                               ilgen.Emit (OpCodes.Bne_Un, l3);
+
+                                               //    match_start = strpos;
+                                               ilgen.Emit (OpCodes.Ldarg_0);
+                                               ilgen.Emit (OpCodes.Ldarg_1);
+                                               ilgen.Emit (OpCodes.Stfld, 
GetInterpreterField ("match_start"));
+                                               //    strpos_result = strpos + 
1;
+                                               ilgen.Emit (OpCodes.Ldarg_2);
+                                               ilgen.Emit (OpCodes.Ldarg_1);
+                                               ilgen.Emit (OpCodes.Ldc_I4_1);
+                                               ilgen.Emit (OpCodes.Add);
+                                               ilgen.Emit (OpCodes.Stind_I4);
+                                               //    return true;
+                                               ilgen.Emit (OpCodes.Ldc_I4_1);
+                                               ilgen.Emit (OpCodes.Ret);
+                                               //  }
+                                               ilgen.MarkLabel (l3);
+                                               //  strpos++;
+                                               ilgen.Emit (OpCodes.Ldarg_1);
+                                               ilgen.Emit (OpCodes.Ldc_I4_1);
+                                               ilgen.Emit (OpCodes.Add);
+                                               ilgen.Emit (OpCodes.Starg, 1);
+                                               //}
+                                               ilgen.MarkLabel (l2);
+                                               ilgen.Emit (OpCodes.Ldarg_1);
+                                               ilgen.Emit (OpCodes.Ldloc, 
local_string_end);
+                                               ilgen.Emit (OpCodes.Blt, l1);
+
+                                               //return false;
+                                               ilgen.Emit (OpCodes.Br, 
label_fail);
+                                       } else {
+                                               // General case
+
+                                               //Console.WriteLine ("Anchor op 
" + anch_op);
+
+                                               //while (strpos < string_end) {
+                                               // -> Done at the end of the 
loop like mcs does
+                                               Label l1 = ilgen.DefineLabel ();
+                                               Label l2 = ilgen.DefineLabel ();
+                                               ilgen.Emit (OpCodes.Br, l2);
+                                               ilgen.MarkLabel (l1);
+                                               //  int res = strpos;
+                                               LocalBuilder local_res = 
ilgen.DeclareLocal (typeof (int));
+                                               ilgen.Emit (OpCodes.Ldarg_1);
+                                               ilgen.Emit (OpCodes.Stloc, 
local_res);
+                                               //  if (EvalByteCode (pc, 
strpos, ref res)) {
+                                               Label l3 = ilgen.DefineLabel ();
+                                               MethodInfo eval = 
GetEvalMethodWithFallback (program, pc, out fallback);
+                                               ilgen.Emit (OpCodes.Ldarg_0);
+                                               if (fallback)
+                                                       ilgen.Emit 
(OpCodes.Ldc_I4, pc);
+                                               ilgen.Emit (OpCodes.Ldarg_1);
+                                               ilgen.Emit (OpCodes.Ldloca, 
local_res);
+                                               ilgen.Emit (OpCodes.Call, eval);
+                                               ilgen.Emit (OpCodes.Brfalse, 
l3);
+                                               //    match_start = strpos;
+                                               ilgen.Emit (OpCodes.Ldarg_0);
+                                               ilgen.Emit (OpCodes.Ldarg_1);
+                                               ilgen.Emit (OpCodes.Stfld, 
GetInterpreterField ("match_start"));
+                                               //    strpos_result = res;
+                                               ilgen.Emit (OpCodes.Ldarg_2);
+                                               ilgen.Emit (OpCodes.Ldloc, 
local_res);
+                                               ilgen.Emit (OpCodes.Stind_I4);
+                                               //    return true;
+                                               ilgen.Emit (OpCodes.Ldc_I4_1);
+                                               ilgen.Emit (OpCodes.Ret);
+                                               //  }
+                                               ilgen.MarkLabel (l3);
+                                               //  strpos++;
+                                               ilgen.Emit (OpCodes.Ldarg_1);
+                                               ilgen.Emit (OpCodes.Ldc_I4_1);
+                                               ilgen.Emit (OpCodes.Add);
+                                               ilgen.Emit (OpCodes.Starg, 1);
+                                               //}
+                                               ilgen.MarkLabel (l2);
+                                               ilgen.Emit (OpCodes.Ldarg_1);
+                                               ilgen.Emit (OpCodes.Ldarg_0);
+                                               ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("string_end"));
+                                               ilgen.Emit (OpCodes.Blt, l1);
+                                               //return false;
+                                               ilgen.Emit (OpCodes.Ldc_I4_0);
+                                               ilgen.Emit (OpCodes.Ret);
+                                       }
+
+                                       goto End;
+                               }
+                               case RxOp.Branch: {
+                                       //int res = 0;
+                                       LocalBuilder local_res = 
ilgen.DeclareLocal (typeof (int));
+                                       // FIXME: Emit a branch around the rest 
of the code instead
+                                       //if (EvalByteCode (pc + 3, strpos, ref 
res)) {
+                                       Label l1 = ilgen.DefineLabel ();
+                                       MethodInfo eval = 
GetEvalMethodWithFallback (program, pc + 3, out fallback);
+                                       ilgen.Emit (OpCodes.Ldarg_0);
+                                       if (fallback)
+                                               ilgen.Emit (OpCodes.Ldc_I4, pc 
+ 3);
+                                       ilgen.Emit (OpCodes.Ldarg_1);
+                                       ilgen.Emit (OpCodes.Ldloca, local_res);
+                                       ilgen.Emit (OpCodes.Call, eval);
+                                       ilgen.Emit (OpCodes.Brfalse, l1);
+                                       //  strpos_result = res;
+                                       ilgen.Emit (OpCodes.Ldarg_2);
+                                       ilgen.Emit (OpCodes.Ldloc, local_res);
+                                       ilgen.Emit (OpCodes.Stind_I4);
+                                       //  return true;
+                                       ilgen.Emit (OpCodes.Ldc_I4_1);
+                                       ilgen.Emit (OpCodes.Ret);
+                                       //}
+                                       ilgen.MarkLabel (l1);
+
+                                       pc += program [pc + 1] | (program [pc + 
2] << 8);
+                                       break;
+                               }
+                               case RxOp.Char: {
+                                       //if (strpos < string_end && (str 
[strpos] == program [pc + 1])) {
+                                       Label l1 = ilgen.DefineLabel ();
+                                       ilgen.Emit (OpCodes.Ldarg_1);
+                                       ilgen.Emit (OpCodes.Ldarg_0);
+                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("string_end"));
+                                       ilgen.Emit (OpCodes.Bge, l1);
+                                       ilgen.Emit (OpCodes.Ldarg_0);
+                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("str"));
+                                       ilgen.Emit (OpCodes.Ldarg_1);
+                                       ilgen.Emit (OpCodes.Callvirt, typeof 
(string).GetMethod ("get_Chars"));
+                                       ilgen.Emit (OpCodes.Conv_I4);
+                                       ilgen.Emit (OpCodes.Ldc_I4, 
(int)program [pc + 1]);
+                                       ilgen.Emit (OpCodes.Bne_Un, l1);
+                                       //  strpos++;
+                                       ilgen.Emit (OpCodes.Ldarg_1);
+                                       ilgen.Emit (OpCodes.Ldc_I4_1);
+                                       ilgen.Emit (OpCodes.Add);
+                                       ilgen.Emit (OpCodes.Starg, 1);
+                                       Label l2 = ilgen.DefineLabel ();
+                                       ilgen.Emit (OpCodes.Br, l2);
+                                       //}
+                                       ilgen.MarkLabel (l1);
+                                       //return false;
+                                       ilgen.Emit (OpCodes.Ldc_I4_0);
+                                       ilgen.Emit (OpCodes.Ret);
+                                       ilgen.MarkLabel (l2);
+
+                                       pc += 2;
+                                       break;
+                               }
+                               case RxOp.True: {
+                                       //strpos_result = strpos;
+                                       ilgen.Emit (OpCodes.Ldarg_2);
+                                       ilgen.Emit (OpCodes.Ldarg_1);
+                                       ilgen.Emit (OpCodes.Stind_I4);
+                                       //  return true;
+                                       ilgen.Emit (OpCodes.Ldc_I4_1);
+                                       ilgen.Emit (OpCodes.Ret);
+                                       goto End;
+                               }
+                               case RxOp.False: {
+                                       //  return false;
+                                       ilgen.Emit (OpCodes.Ldc_I4_0);
+                                       ilgen.Emit (OpCodes.Ret);
+                                       goto End;
+                               }
+                               case RxOp.Bitmap: {
+                                       //if (strpos < string_end) {
+                                       Label l1 = ilgen.DefineLabel ();
+                                       Label l2 = ilgen.DefineLabel ();
+                                       ilgen.Emit (OpCodes.Ldarg_1);
+                                       ilgen.Emit (OpCodes.Ldarg_0);
+                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("string_end"));
+                                       ilgen.Emit (OpCodes.Bge, l1);
+                                       //  int c = str [strpos];
+                                       LocalBuilder local_c = 
ilgen.DeclareLocal (typeof (int));
+                                       ilgen.Emit (OpCodes.Ldarg_0);
+                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("str"));
+                                       ilgen.Emit (OpCodes.Ldarg_1);
+                                       ilgen.Emit (OpCodes.Callvirt, typeof 
(string).GetMethod ("get_Chars"));
+                                       ilgen.Emit (OpCodes.Conv_I4);
+                                       //  c -= program [pc + 1];
+                                       ilgen.Emit (OpCodes.Ldc_I4, 
(int)program [pc + 1]);
+                                       ilgen.Emit (OpCodes.Sub);
+                                       ilgen.Emit (OpCodes.Stloc, local_c);
+                                       length =  program [pc + 2];
+                                       //  if (c < 0 || c >= (length << 3))
+                                       //    return false;
+                                       ilgen.Emit (OpCodes.Ldloc, local_c);
+                                       ilgen.Emit (OpCodes.Ldc_I4_0);
+                                       ilgen.Emit (OpCodes.Blt, label_fail);
+                                       ilgen.Emit (OpCodes.Ldloc, local_c);
+                                       ilgen.Emit (OpCodes.Ldc_I4, length << 
3);
+                                       ilgen.Emit (OpCodes.Bge, label_fail);
+                                       pc += 3;
+
+                                       // Optimized version for small bitmaps
+                                       if (length <= 4) {
+                                               uint bitmap = program [pc];
+                                               
+                                               if (length > 1)
+                                                       bitmap |= 
((uint)program [pc + 1] << 8);
+                                               if (length > 2)
+                                                       bitmap |= 
((uint)program [pc + 2] << 16);
+                                               if (length > 3)
+                                                       bitmap |= 
((uint)program [pc + 3] << 24);
+
+                                               //if ((bitmap >> c) & 1)
+                                               ilgen.Emit (OpCodes.Ldc_I4, 
bitmap);
+                                               ilgen.Emit (OpCodes.Ldloc, 
local_c);
+                                               ilgen.Emit (OpCodes.Shr_Un);
+                                               ilgen.Emit (OpCodes.Ldc_I4_1);
+                                               ilgen.Emit (OpCodes.And);
+                                               ilgen.Emit (OpCodes.Brfalse, 
l1);
+                                       } else {
+                                               //  if ((program [pc + (c >> 
3)] & (1 << (c & 0x7))) != 0) {
+                                               ilgen.Emit (OpCodes.Ldarg_0);
+                                               ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("program"));
+                                               ilgen.Emit (OpCodes.Ldloc, 
local_c);
+                                               ilgen.Emit (OpCodes.Ldc_I4_3);
+                                               ilgen.Emit (OpCodes.Shr);
+                                               ilgen.Emit (OpCodes.Ldc_I4, pc);
+                                               ilgen.Emit (OpCodes.Add);
+                                               ilgen.Emit (OpCodes.Ldelem_I1);
+                                               ilgen.Emit (OpCodes.Ldc_I4_1);
+                                               ilgen.Emit (OpCodes.Ldloc, 
local_c);
+                                               ilgen.Emit (OpCodes.Ldc_I4, 7);
+                                               ilgen.Emit (OpCodes.And);
+                                               ilgen.Emit (OpCodes.Shl);
+                                               ilgen.Emit (OpCodes.And);
+                                               ilgen.Emit (OpCodes.Ldc_I4_0);
+                                               ilgen.Emit (OpCodes.Beq, l1);
+                                       }
+                                       //    strpos++;
+                                       ilgen.Emit (OpCodes.Ldarg_1);
+                                       ilgen.Emit (OpCodes.Ldc_I4_1);
+                                       ilgen.Emit (OpCodes.Add);
+                                       ilgen.Emit (OpCodes.Starg, 1);
+                                       //    continue;
+                                       ilgen.Emit (OpCodes.Br, l2);
+                                       //  }
+                                       //}
+                                       //return false;
+                                       ilgen.MarkLabel (l1);
+                                       ilgen.Emit (OpCodes.Ldc_I4_0);
+                                       ilgen.Emit (OpCodes.Ret);
+
+                                       ilgen.MarkLabel (l2);
+
+                                       pc += length;
+                                       break;
+                               }
+                               case RxOp.String: {
+                                       start = pc + 2;
+                                       length = program [pc + 1];
+                                       //if (strpos + length > string_end)
+                                       //      return false;
+                                       ilgen.Emit (OpCodes.Ldarg_1);
+                                       ilgen.Emit (OpCodes.Ldc_I4, length);
+                                       ilgen.Emit (OpCodes.Add);
+                                       ilgen.Emit (OpCodes.Ldarg_0);
+                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("string_end"));
+                                       ilgen.Emit (OpCodes.Bgt, label_fail);
+
+                                       /* Avoid unsafe code in Moonlight build 
*/
+#if false && !NET_2_1
+                                       LocalBuilder local_strptr = 
ilgen.DeclareLocal (typeof (char).MakePointerType ());
+                                       // char *strptr = &str.start_char + 
strpos
+                                       ilgen.Emit (OpCodes.Ldarg_0);
+                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("str"));
+                                       ilgen.Emit (OpCodes.Ldflda, typeof 
(String).GetField ("start_char", BindingFlags.Instance|BindingFlags.NonPublic));
+                                       ilgen.Emit (OpCodes.Ldarg_1);
+                                       ilgen.Emit (OpCodes.Ldc_I4_1);
+                                       ilgen.Emit (OpCodes.Shl);
+                                       ilgen.Emit (OpCodes.Add);
+                                       ilgen.Emit (OpCodes.Stloc, 
local_strptr);
+
+                                       end = start + length;
+                                       for (; start < end; ++start) {
+                                               // if (*(strptr + start) != 
program [start])
+                                               //   return false;
+                                               ilgen.Emit (OpCodes.Ldloc, 
local_strptr);
+                                               ilgen.Emit (OpCodes.Ldc_I4, 
start * 2);
+                                               ilgen.Emit (OpCodes.Add);
+                                               ilgen.Emit (OpCodes.Ldind_I2);
+                                               ilgen.Emit (OpCodes.Ldc_I4, 
(int)program [start]);
+                                               ilgen.Emit (OpCodes.Bne_Un, 
label_fail);
+                                       }
+
+                                       // strpos += length
+                                       ilgen.Emit (OpCodes.Ldarg_1);
+                                       ilgen.Emit (OpCodes.Ldc_I4, length);
+                                       ilgen.Emit (OpCodes.Add);
+                                       ilgen.Emit (OpCodes.Starg, 1);
+
+#else
+                                       // Allocate a local for 'str' to save 
an indirection
+                                       LocalBuilder local_str = 
ilgen.DeclareLocal (typeof (string));
+                                       ilgen.Emit (OpCodes.Ldarg_0);
+                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("str"));
+                                       ilgen.Emit (OpCodes.Stloc, local_str);
+
+                                       // FIXME: Emit a loop for long strings
+                                       end = start + length;
+                                       for (; start < end; ++start) {
+                                               //if (str [strpos] != program 
[start])
+                                               //      return false;
+                                               ilgen.Emit (OpCodes.Ldloc, 
local_str);
+                                               ilgen.Emit (OpCodes.Ldarg_1);
+                                               ilgen.Emit (OpCodes.Callvirt, 
typeof (string).GetMethod ("get_Chars"));
+                                               ilgen.Emit (OpCodes.Ldc_I4, 
(int)program [start]);
+                                               ilgen.Emit (OpCodes.Bne_Un, 
label_fail);
+                                               //strpos++;
+                                               ilgen.Emit (OpCodes.Ldarg_1);
+                                               ilgen.Emit (OpCodes.Ldc_I4_1);
+                                               ilgen.Emit (OpCodes.Add);
+                                               ilgen.Emit (OpCodes.Starg, 1);
+                                       }
+#endif
+
+                                       pc = end;
+                                       break;
+                               }
+                               case RxOp.Jump:
+                                       pc += program [pc + 1] | (program [pc + 
2] << 8);
+                                       continue;
+                               default:
+                                       Console.WriteLine ("Opcode " + op + " 
not supported.");
+                                       return null;
+                               }
+                       }
+
+               End:
+                       ilgen.MarkLabel (label_fail);
+                       ilgen.Emit (OpCodes.Ldc_I4_0);
+                       ilgen.Emit (OpCodes.Ret);
+
+                       return m;
+               }
+       }
+#else
+       class CILCompiler : RxCompiler {
+       }
+#endif
+
+}
+

Modified: trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog     
2008-02-13 14:58:29 UTC (rev 95581)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/ChangeLog     
2008-02-13 14:58:33 UTC (rev 95582)
@@ -1,5 +1,7 @@
 2008-02-13  Zoltan Varga  <[EMAIL PROTECTED]>
 
+       * CILCompiler.cs: New file, extracted from RxCompiler.cs.
+
        * RxInterpreter.cs RxCompiler.cs: First version of regex IL compiler.
 
 Wed Feb 13 13:18:12 CET 2008 Paolo Molaro <[EMAIL PROTECTED]>

Modified: trunk/mcs/class/System/System.Text.RegularExpressions/RxCompiler.cs
===================================================================
--- trunk/mcs/class/System/System.Text.RegularExpressions/RxCompiler.cs 
2008-02-13 14:58:29 UTC (rev 95581)
+++ trunk/mcs/class/System/System.Text.RegularExpressions/RxCompiler.cs 
2008-02-13 14:58:33 UTC (rev 95582)
@@ -688,499 +688,6 @@
 
        }
 
-       //
-       // Compiler which generates IL bytecode to perform the matching instead 
of
-       // interpreting a program.
-       // For simplicity, we inherit from RxCompiler, and generate the IL code 
based
-       // on the program generated by it. This also allows us to fallback to 
interpretation
-       // if we can't handle something.
-       // This is net 2.0, since 1.0 doesn't support DynamicMethods
-       // FIXME: Add support for 1.0, and CompileToAssembly
-       // FIXME: Emit one method with a switch instead of many methods
-       // FIXME: Avoid ref ptr, since it is bad for register allocation
-       //
-
-#if NET_2_0
-       class CILCompiler : RxCompiler, ICompiler {
-               DynamicMethod[] eval_methods;
-               bool[] eval_methods_defined;
-
-               IMachineFactory ICompiler.GetMachineFactory () {
-                       byte[] code = new byte [curpos];
-                       Buffer.BlockCopy (program, 0, code, 0, curpos);
-
-                       eval_methods = new DynamicMethod [code.Length];
-                       eval_methods_defined = new bool [code.Length];
-
-                       // The main eval method
-                   DynamicMethod main = GetEvalMethod (code, 11);
-                       if (main != null)
-                               return new RxInterpreterFactory (code, 
(EvalDelegate)main.CreateDelegate (typeof (EvalDelegate)));
-                       else
-                               return new RxInterpreterFactory (code, null);
-               }
-
-               DynamicMethod GetEvalMethod (byte[] program, int pc) {
-                       if (eval_methods_defined [pc])
-                               return eval_methods [pc];
-
-                       // FIXME: Recursion ?
-                       eval_methods_defined [pc] = true;
-
-                       eval_methods [pc] = CreateEvalMethod (program, pc);
-                       return eval_methods [pc];
-               }
-
-               private FieldInfo GetInterpreterField (string name) {
-                       return typeof (RxInterpreter).GetField (name, 
BindingFlags.Instance|BindingFlags.NonPublic);
-               }
-
-               private MethodInfo GetInterpreterMethod (string name) {
-                       return typeof (RxInterpreter).GetMethod (name, 
BindingFlags.Instance|BindingFlags.NonPublic);
-               }
-
-               private string GetString (ushort[] program, int pc) {
-                       int len = program[pc + 1];
-                       int str = pc + 2;
-
-                       char[] cs = new char[len];
-                       for (int i = 0; i < len; ++ i)
-                               cs[i] = (char)program[str ++];
-
-                       return new string (cs);
-               }
-
-               private int ReadInt (byte[] code, int pc)
-               {
-                       int val = code [pc];
-                       val |= code [pc + 1] << 8;
-                       val |= code [pc + 2] << 16;
-                       val |= code [pc + 3] << 24;
-                       return val;
-               }
-
-               private MethodInfo GetEvalMethodWithFallback (byte[] program, 
int pc, out bool fallback) {
-                       DynamicMethod eval = GetEvalMethod (program, pc);
-                       fallback = eval != null;
-                       if (eval != null) {
-                               fallback = false;
-                               return eval;
-                       } else {
-                               fallback = true;
-                               return GetInterpreterMethod ("EvalByteCode");
-                       }
-               }
-
-               //
-               // Create a dynamic method which is the Interpreter.Eval method 
specialized
-               // to the given program and a given pc.
-               // Keep this in synch with Interpreter.Eval ()
-               //
-               DynamicMethod CreateEvalMethod (byte[] program, int pc) {
-                       DynamicMethod m = new DynamicMethod ("Eval_" + pc, 
typeof (bool), new Type [] { typeof (RxInterpreter), typeof (int), typeof 
(int).MakeByRefType () }, typeof (RxInterpreter), true);
-                       ILGenerator ilgen = m.GetILGenerator ();
-
-                       /* 
-                          Args:
-                          interp - 0
-                          strpos - 1
-                          strpos_result - 2
-                       */
-
-                       int start, length, end;
-                       bool fallback;
-
-                       Label label_fail = ilgen.DefineLabel ();
-
-                       while (true) {
-                               RxOp op = (RxOp)program [pc];
-
-                               switch (op) {
-                               case RxOp.Anchor: {
-                                       length = program [pc + 3] | (program 
[pc + 4] << 8);
-                                       pc += program [pc + 1] | (program [pc + 
2] << 8);
-
-                                       // FIXME: Group support
-                                       
-                                       // Optimize some common cases by 
inlining the code generated for the
-                                       // anchor body 
-                                       RxOp anch_op = (RxOp)program [pc];
-                                       // FIXME: Do this even if the archor op 
is not the last in the regex
-                                       if (anch_op == RxOp.Char && 
(RxOp)program [pc + 2] == RxOp.True) {
-
-                                               /*
-                                                * while (strpos < string_end) {
-                                                *   if (str [strpos] == 
program [pc + 1]) {
-                                                *     match_start = strpos;
-                                                *     strpos_result = strpos + 
1;
-                                                *     return true;
-                                                *   }
-                                                *   strpos ++;
-                                                * }
-                                                * return false;
-                                                */
-                                               // Add some locals to avoid an 
indirection
-                                               LocalBuilder local_string_end = 
ilgen.DeclareLocal (typeof (int));
-                                               ilgen.Emit (OpCodes.Ldarg_0);
-                                               ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("string_end"));
-                                               ilgen.Emit (OpCodes.Stloc, 
local_string_end);
-                                               LocalBuilder local_str = 
ilgen.DeclareLocal (typeof (string));
-                                               ilgen.Emit (OpCodes.Ldarg_0);
-                                               ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("str"));
-                                               ilgen.Emit (OpCodes.Stloc, 
local_str);
-
-                                               //while (strpos < string_end) {
-                                               // -> Done at the end of the 
loop like mcs does
-                                               Label l1 = ilgen.DefineLabel ();
-                                               Label l2 = ilgen.DefineLabel ();
-                                               ilgen.Emit (OpCodes.Br, l2);
-                                               ilgen.MarkLabel (l1);
-
-                                               //  if (str [strpos] == program 
[pc + 1]) {
-                                               Label l3 = ilgen.DefineLabel ();
-                                               ilgen.Emit (OpCodes.Ldloc, 
local_str);
-                                               ilgen.Emit (OpCodes.Ldarg_1);
-                                               ilgen.Emit (OpCodes.Callvirt, 
typeof (string).GetMethod ("get_Chars"));
-                                               ilgen.Emit (OpCodes.Conv_I4);
-                                               ilgen.Emit (OpCodes.Ldc_I4, 
(int)program [pc + 1]);
-                                               ilgen.Emit (OpCodes.Bne_Un, l3);
-
-                                               //    match_start = strpos;
-                                               ilgen.Emit (OpCodes.Ldarg_0);
-                                               ilgen.Emit (OpCodes.Ldarg_1);
-                                               ilgen.Emit (OpCodes.Stfld, 
GetInterpreterField ("match_start"));
-                                               //    strpos_result = strpos + 
1;
-                                               ilgen.Emit (OpCodes.Ldarg_2);
-                                               ilgen.Emit (OpCodes.Ldarg_1);
-                                               ilgen.Emit (OpCodes.Ldc_I4_1);
-                                               ilgen.Emit (OpCodes.Add);
-                                               ilgen.Emit (OpCodes.Stind_I4);
-                                               //    return true;
-                                               ilgen.Emit (OpCodes.Ldc_I4_1);
-                                               ilgen.Emit (OpCodes.Ret);
-                                               //  }
-                                               ilgen.MarkLabel (l3);
-                                               //  strpos++;
-                                               ilgen.Emit (OpCodes.Ldarg_1);
-                                               ilgen.Emit (OpCodes.Ldc_I4_1);
-                                               ilgen.Emit (OpCodes.Add);
-                                               ilgen.Emit (OpCodes.Starg, 1);
-                                               //}
-                                               ilgen.MarkLabel (l2);
-                                               ilgen.Emit (OpCodes.Ldarg_1);
-                                               ilgen.Emit (OpCodes.Ldloc, 
local_string_end);
-                                               ilgen.Emit (OpCodes.Blt, l1);
-
-                                               //return false;
-                                               ilgen.Emit (OpCodes.Br, 
label_fail);
-                                       } else {
-                                               // General case
-
-                                               //Console.WriteLine ("Anchor op 
" + anch_op);
-
-                                               //while (strpos < string_end) {
-                                               Label l1 = ilgen.DefineLabel ();
-                                               Label l2 = ilgen.DefineLabel ();
-                                               ilgen.MarkLabel (l1);
-                                               ilgen.Emit (OpCodes.Ldarg_1);
-                                               ilgen.Emit (OpCodes.Ldarg_0);
-                                               ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("string_end"));
-                                               ilgen.Emit (OpCodes.Bge, l2);
-                                               //  int res = strpos;
-                                               LocalBuilder local_res = 
ilgen.DeclareLocal (typeof (int));
-                                               ilgen.Emit (OpCodes.Ldarg_1);
-                                               ilgen.Emit (OpCodes.Stloc, 
local_res);
-                                               //  if (EvalByteCode (pc, 
strpos, ref res)) {
-                                               Label l3 = ilgen.DefineLabel ();
-                                               MethodInfo eval = 
GetEvalMethodWithFallback (program, pc, out fallback);
-                                               ilgen.Emit (OpCodes.Ldarg_0);
-                                               if (fallback)
-                                                       ilgen.Emit 
(OpCodes.Ldc_I4, pc);
-                                               ilgen.Emit (OpCodes.Ldarg_1);
-                                               ilgen.Emit (OpCodes.Ldloca, 
local_res);
-                                               ilgen.Emit (OpCodes.Call, eval);
-                                               ilgen.Emit (OpCodes.Brfalse, 
l3);
-                                               //    match_start = strpos;
-                                               ilgen.Emit (OpCodes.Ldarg_0);
-                                               ilgen.Emit (OpCodes.Ldarg_1);
-                                               ilgen.Emit (OpCodes.Stfld, 
GetInterpreterField ("match_start"));
-                                               //    strpos_result = res;
-                                               ilgen.Emit (OpCodes.Ldarg_2);
-                                               ilgen.Emit (OpCodes.Ldloc, 
local_res);
-                                               ilgen.Emit (OpCodes.Stind_I4);
-                                               //    return true;
-                                               ilgen.Emit (OpCodes.Ldc_I4_1);
-                                               ilgen.Emit (OpCodes.Ret);
-                                               //  }
-                                               ilgen.MarkLabel (l3);
-                                               //  strpos++;
-                                               ilgen.Emit (OpCodes.Ldarg_1);
-                                               ilgen.Emit (OpCodes.Ldc_I4_1);
-                                               ilgen.Emit (OpCodes.Add);
-                                               ilgen.Emit (OpCodes.Starg, 1);
-                                               //}
-                                               ilgen.Emit (OpCodes.Br, l1);
-                                               ilgen.MarkLabel (l2);
-                                               //return false;
-                                               ilgen.Emit (OpCodes.Ldc_I4_0);
-                                               ilgen.Emit (OpCodes.Ret);
-                                       }
-
-                                       goto End;
-                               }
-                               case RxOp.Branch: {
-                                       //int res = 0;
-                                       LocalBuilder local_res = 
ilgen.DeclareLocal (typeof (int));
-                                       // FIXME: Emit a branch around the rest 
of the code instead
-                                       //if (EvalByteCode (pc + 3, strpos, ref 
res)) {
-                                       Label l1 = ilgen.DefineLabel ();
-                                       MethodInfo eval = 
GetEvalMethodWithFallback (program, pc + 3, out fallback);
-                                       ilgen.Emit (OpCodes.Ldarg_0);
-                                       if (fallback)
-                                               ilgen.Emit (OpCodes.Ldc_I4, pc 
+ 3);
-                                       ilgen.Emit (OpCodes.Ldarg_1);
-                                       ilgen.Emit (OpCodes.Ldloca, local_res);
-                                       ilgen.Emit (OpCodes.Call, eval);
-                                       ilgen.Emit (OpCodes.Brfalse, l1);
-                                       //  strpos_result = res;
-                                       ilgen.Emit (OpCodes.Ldarg_2);
-                                       ilgen.Emit (OpCodes.Ldloc, local_res);
-                                       ilgen.Emit (OpCodes.Stind_I4);
-                                       //  return true;
-                                       ilgen.Emit (OpCodes.Ldc_I4_1);
-                                       ilgen.Emit (OpCodes.Ret);
-                                       //}
-                                       ilgen.MarkLabel (l1);
-
-                                       pc += program [pc + 1] | (program [pc + 
2] << 8);
-                                       break;
-                               }
-                               case RxOp.Char: {
-                                       //if (strpos < string_end && (str 
[strpos] == program [pc + 1])) {
-                                       Label l1 = ilgen.DefineLabel ();
-                                       ilgen.Emit (OpCodes.Ldarg_1);
-                                       ilgen.Emit (OpCodes.Ldarg_0);
-                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("string_end"));
-                                       ilgen.Emit (OpCodes.Bge, l1);
-                                       ilgen.Emit (OpCodes.Ldarg_0);
-                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("str"));
-                                       ilgen.Emit (OpCodes.Ldarg_1);
-                                       ilgen.Emit (OpCodes.Callvirt, typeof 
(string).GetMethod ("get_Chars"));
-                                       ilgen.Emit (OpCodes.Conv_I4);
-                                       ilgen.Emit (OpCodes.Ldc_I4, 
(int)program [pc + 1]);
-                                       ilgen.Emit (OpCodes.Bne_Un, l1);
-                                       //  strpos++;
-                                       ilgen.Emit (OpCodes.Ldarg_1);
-                                       ilgen.Emit (OpCodes.Ldc_I4_1);
-                                       ilgen.Emit (OpCodes.Add);
-                                       ilgen.Emit (OpCodes.Starg, 1);
-                                       Label l2 = ilgen.DefineLabel ();
-                                       ilgen.Emit (OpCodes.Br, l2);
-                                       //}
-                                       ilgen.MarkLabel (l1);
-                                       //return false;
-                                       ilgen.Emit (OpCodes.Ldc_I4_0);
-                                       ilgen.Emit (OpCodes.Ret);
-                                       ilgen.MarkLabel (l2);
-
-                                       pc += 2;
-                                       break;
-                               }
-                               case RxOp.True: {
-                                       //strpos_result = strpos;
-                                       ilgen.Emit (OpCodes.Ldarg_2);
-                                       ilgen.Emit (OpCodes.Ldarg_1);
-                                       ilgen.Emit (OpCodes.Stind_I4);
-                                       //  return true;
-                                       ilgen.Emit (OpCodes.Ldc_I4_1);
-                                       ilgen.Emit (OpCodes.Ret);
-                                       goto End;
-                               }
-                               case RxOp.False: {
-                                       //  return false;
-                                       ilgen.Emit (OpCodes.Ldc_I4_0);
-                                       ilgen.Emit (OpCodes.Ret);
-                                       goto End;
-                               }
-                               case RxOp.Bitmap: {
-                                       //if (strpos < string_end) {
-                                       Label l1 = ilgen.DefineLabel ();
-                                       Label l2 = ilgen.DefineLabel ();
-                                       ilgen.Emit (OpCodes.Ldarg_1);
-                                       ilgen.Emit (OpCodes.Ldarg_0);
-                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("string_end"));
-                                       ilgen.Emit (OpCodes.Bge, l1);
-                                       //  int c = str [strpos];
-                                       LocalBuilder local_c = 
ilgen.DeclareLocal (typeof (int));
-                                       ilgen.Emit (OpCodes.Ldarg_0);
-                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("str"));
-                                       ilgen.Emit (OpCodes.Ldarg_1);
-                                       ilgen.Emit (OpCodes.Callvirt, typeof 
(string).GetMethod ("get_Chars"));
-                                       ilgen.Emit (OpCodes.Conv_I4);
-                                       //  c -= program [pc + 1];
-                                       ilgen.Emit (OpCodes.Ldc_I4, 
(int)program [pc + 1]);
-                                       ilgen.Emit (OpCodes.Sub);
-                                       ilgen.Emit (OpCodes.Stloc, local_c);
-                                       length =  program [pc + 2];
-                                       //  if (c < 0 || c >= (length << 3))
-                                       //    return false;
-                                       ilgen.Emit (OpCodes.Ldloc, local_c);
-                                       ilgen.Emit (OpCodes.Ldc_I4_0);
-                                       ilgen.Emit (OpCodes.Blt, label_fail);
-                                       ilgen.Emit (OpCodes.Ldloc, local_c);
-                                       ilgen.Emit (OpCodes.Ldc_I4, length << 
3);
-                                       ilgen.Emit (OpCodes.Bge, label_fail);
-                                       pc += 3;
-
-                                       // Optimized version for small bitmaps
-                                       if (length <= 4) {
-                                               uint bitmap = program [pc];
-                                               
-                                               if (length > 1)
-                                                       bitmap |= 
((uint)program [pc + 1] << 8);
-                                               if (length > 2)
-                                                       bitmap |= 
((uint)program [pc + 2] << 16);
-                                               if (length > 3)
-                                                       bitmap |= 
((uint)program [pc + 3] << 24);
-
-                                               //if ((bitmap >> c) & 1)
-                                               ilgen.Emit (OpCodes.Ldc_I4, 
bitmap);
-                                               ilgen.Emit (OpCodes.Ldloc, 
local_c);
-                                               ilgen.Emit (OpCodes.Shr_Un);
-                                               ilgen.Emit (OpCodes.Ldc_I4_1);
-                                               ilgen.Emit (OpCodes.And);
-                                               ilgen.Emit (OpCodes.Brfalse, 
l1);
-                                       } else {
-                                               //  if ((program [pc + (c >> 
3)] & (1 << (c & 0x7))) != 0) {
-                                               ilgen.Emit (OpCodes.Ldarg_0);
-                                               ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("program"));
-                                               ilgen.Emit (OpCodes.Ldloc, 
local_c);
-                                               ilgen.Emit (OpCodes.Ldc_I4_3);
-                                               ilgen.Emit (OpCodes.Shr);
-                                               ilgen.Emit (OpCodes.Ldc_I4, pc);
-                                               ilgen.Emit (OpCodes.Add);
-                                               ilgen.Emit (OpCodes.Ldelem_I1);
-                                               ilgen.Emit (OpCodes.Ldc_I4_1);
-                                               ilgen.Emit (OpCodes.Ldloc, 
local_c);
-                                               ilgen.Emit (OpCodes.Ldc_I4, 7);
-                                               ilgen.Emit (OpCodes.And);
-                                               ilgen.Emit (OpCodes.Shl);
-                                               ilgen.Emit (OpCodes.And);
-                                               ilgen.Emit (OpCodes.Ldc_I4_0);
-                                               ilgen.Emit (OpCodes.Beq, l1);
-                                       }
-                                       //    strpos++;
-                                       ilgen.Emit (OpCodes.Ldarg_1);
-                                       ilgen.Emit (OpCodes.Ldc_I4_1);
-                                       ilgen.Emit (OpCodes.Add);
-                                       ilgen.Emit (OpCodes.Starg, 1);
-                                       //    continue;
-                                       ilgen.Emit (OpCodes.Br, l2);
-                                       //  }
-                                       //}
-                                       //return false;
-                                       ilgen.MarkLabel (l1);
-                                       ilgen.Emit (OpCodes.Ldc_I4_0);
-                                       ilgen.Emit (OpCodes.Ret);
-
-                                       ilgen.MarkLabel (l2);
-
-                                       pc += length;
-                                       break;
-                               }
-                               case RxOp.String: {
-                                       start = pc + 2;
-                                       length = program [pc + 1];
-                                       //if (strpos + length > string_end)
-                                       //      return false;
-                                       ilgen.Emit (OpCodes.Ldarg_1);
-                                       ilgen.Emit (OpCodes.Ldc_I4, length);
-                                       ilgen.Emit (OpCodes.Add);
-                                       ilgen.Emit (OpCodes.Ldarg_0);
-                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("string_end"));
-                                       ilgen.Emit (OpCodes.Bgt, label_fail);
-
-                                       /* Avoid unsafe code in Moonlight build 
*/
-#if false && !NET_2_1
-                                       LocalBuilder local_strptr = 
ilgen.DeclareLocal (typeof (char).MakePointerType ());
-                                       // char *strptr = &str.start_char + 
strpos
-                                       ilgen.Emit (OpCodes.Ldarg_0);
-                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("str"));
-                                       ilgen.Emit (OpCodes.Ldflda, typeof 
(String).GetField ("start_char", BindingFlags.Instance|BindingFlags.NonPublic));
-                                       ilgen.Emit (OpCodes.Ldarg_1);
-                                       ilgen.Emit (OpCodes.Ldc_I4_1);
-                                       ilgen.Emit (OpCodes.Shl);
-                                       ilgen.Emit (OpCodes.Add);
-                                       ilgen.Emit (OpCodes.Stloc, 
local_strptr);
-
-                                       end = start + length;
-                                       for (; start < end; ++start) {
-                                               // if (*(strptr + start) != 
program [start])
-                                               //   return false;
-                                               ilgen.Emit (OpCodes.Ldloc, 
local_strptr);
-                                               ilgen.Emit (OpCodes.Ldc_I4, 
start * 2);
-                                               ilgen.Emit (OpCodes.Add);
-                                               ilgen.Emit (OpCodes.Ldind_I2);
-                                               ilgen.Emit (OpCodes.Ldc_I4, 
(int)program [start]);
-                                               ilgen.Emit (OpCodes.Bne_Un, 
label_fail);
-                                       }
-
-                                       // strpos += length
-                                       ilgen.Emit (OpCodes.Ldarg_1);
-                                       ilgen.Emit (OpCodes.Ldc_I4, length);
-                                       ilgen.Emit (OpCodes.Add);
-                                       ilgen.Emit (OpCodes.Starg, 1);
-
-#else
-                                       // Allocate a local for 'str' to save 
an indirection
-                                       LocalBuilder local_str = 
ilgen.DeclareLocal (typeof (string));
-                                       ilgen.Emit (OpCodes.Ldarg_0);
-                                       ilgen.Emit (OpCodes.Ldfld, 
GetInterpreterField ("str"));
-                                       ilgen.Emit (OpCodes.Stloc, local_str);
-
-                                       // FIXME: Emit a loop for long strings
-                                       end = start + length;
-                                       for (; start < end; ++start) {
-                                               //if (str [strpos] != program 
[start])
-                                               //      return false;
-                                               ilgen.Emit (OpCodes.Ldloc, 
local_str);
-                                               ilgen.Emit (OpCodes.Ldarg_1);
-                                               ilgen.Emit (OpCodes.Callvirt, 
typeof (string).GetMethod ("get_Chars"));
-                                               ilgen.Emit (OpCodes.Ldc_I4, 
(int)program [start]);
-                                               ilgen.Emit (OpCodes.Bne_Un, 
label_fail);
-                                               //strpos++;
-                                               ilgen.Emit (OpCodes.Ldarg_1);
-                                               ilgen.Emit (OpCodes.Ldc_I4_1);
-                                               ilgen.Emit (OpCodes.Add);
-                                               ilgen.Emit (OpCodes.Starg, 1);
-                                       }
-#endif
-
-                                       pc = end;
-                                       break;
-                               }
-                               case RxOp.Jump:
-                                       pc += program [pc + 1] | (program [pc + 
2] << 8);
-                                       continue;
-                               default:
-                                       Console.WriteLine ("Opcode " + op + " 
not supported.");
-                                       return null;
-                               }
-                       }
-
-               End:
-                       ilgen.MarkLabel (label_fail);
-                       ilgen.Emit (OpCodes.Ldc_I4_0);
-                       ilgen.Emit (OpCodes.Ret);
-
-                       return m;
-               }
-       }
-#else
-       class CILCompiler : RxCompiler {
-       }
-#endif
-
        class RxInterpreterFactory : IMachineFactory {
                public RxInterpreterFactory (byte[] program, EvalDelegate 
eval_del) {
                        this.program = program;

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to