Hi,
I've implement support for compiled regular expressions in profile 1.x
using dynamic assemblies.
I also have cleaned up the code by removing GetEvalMethod and
CreateEvalMethod methods and moving their functionality to
GetMachineFactory.
I also modified the signature of EmitEvalMethodBody and replaced generic
dictionaries with hashtables in profile 1.x that results in a larger
patch but I haven't modify the actual code generator.
I also had to modify some visibility levels to pass runtime type checks.
Please review the attached patch.
Kornél
Index: RxCompiler.cs
===================================================================
--- RxCompiler.cs (revision 130801)
+++ RxCompiler.cs (working copy)
@@ -727,15 +727,33 @@
}
class RxInterpreterFactory : IMachineFactory {
+#if NET_2_0
+ private EvalDelegate eval_del;
+
public RxInterpreterFactory (byte[] program, EvalDelegate
eval_del) {
this.program = program;
this.eval_del = eval_del;
}
-
+
public IMachine NewInstance () {
return new RxInterpreter (program, eval_del);
}
+#else
+ private Type type;
+ public RxInterpreterFactory (byte[] program, Type type) {
+ this.program = program;
+ this.type = type;
+ }
+
+ public IMachine NewInstance () {
+ if (type == null)
+ return new RxInterpreter (program);
+
+ return (IMachine) Activator.CreateInstance (type,
BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.NonPublic |
BindingFlags.Instance, null, new object[] { program }, null, null);
+ }
+#endif
+
public int GroupCount {
get {
return (int)program [1] | ((int)program [2] <<
8);
@@ -754,7 +772,6 @@
private IDictionary mapping;
private byte[] program;
- private EvalDelegate eval_del;
private string[] namesMapping;
}
Index: RxInterpreter.cs
===================================================================
--- RxInterpreter.cs (revision 130801)
+++ RxInterpreter.cs (working copy)
@@ -8,26 +8,30 @@
namespace System.Text.RegularExpressions {
+#if NET_2_0
internal delegate bool EvalDelegate (RxInterpreter interp, int strpos,
ref int strpos_result);
+#endif
- sealed class RxInterpreter: BaseMachine {
- byte[] program;
- string str;
- int string_start;
- int string_end;
+ class RxInterpreter: BaseMachine {
+ public byte[] program;
+ public string str;
+ public int string_start;
+ public int string_end;
int group_count;
// int match_start;
- int[] groups;
+ public int[] groups;
+#if NET_2_0
EvalDelegate eval_del; // optimized EvalByteCode method created
by the CILCompiler
+#endif
- Mark[] marks = null; // mark stack
+ public Mark[] marks = null; // mark stack
int mark_start; // start of current checkpoint
int mark_end; // end of checkpoint/next free mark
- IntStack stack; // utility stack
+ public IntStack stack; // utility stack
RepeatContext repeat; // current repeat context
- RepeatContext deep; // points to the most-nested
repeat context
+ public RepeatContext deep; // points to the most-nested
repeat context
/* The readonly ensures the JIT can optimize out if (trace_rx)
statements */
public static readonly bool trace_rx =
@@ -73,7 +77,7 @@
}
}
- private class RepeatContext {
+ internal class RepeatContext {
public RepeatContext (RepeatContext previous, int min,
int max, bool lazy, int expr_pc) {
this.previous = previous;
this.min = min;
@@ -133,11 +137,17 @@
return val;
}
+#if NET_2_0
public RxInterpreter (byte[] program, EvalDelegate eval_del)
+#else
+ public RxInterpreter (byte[] program)
+#endif
{
this.program = program;
+#if NET_2_0
this.eval_del = eval_del;
- group_count = 1 + (program [1] | ((int)program [2] <<
8));
+#endif
+ group_count = 1 + (program [1] | ((int) program [2] <<
8));
groups = new int [group_count];
stack = new IntStack ();
@@ -151,11 +161,15 @@
int res = 0;
bool match;
+#if NET_2_0
if (eval_del != null) {
match = eval_del (this, start, ref res);
} else {
match = EvalByteCode (11, start, ref res);
}
+#else
+ match = EvalByteCode (start, ref res);
+#endif
marks [groups [0]].End = res;
if (match) {
return GenerateMatch (regex);
@@ -166,7 +180,7 @@
}
// capture management
- private void Open (int gid, int ptr) {
+ public void Open (int gid, int ptr) {
int m = groups [gid];
if (m < mark_start || marks [m].IsDefined) {
m = CreateMark (m);
@@ -176,7 +190,7 @@
marks [m].Start = ptr;
}
- private void Close (int gid, int ptr) {
+ public void Close (int gid, int ptr) {
marks [groups [gid]].End = ptr;
}
@@ -198,12 +212,12 @@
return true;
}
- private int Checkpoint () {
+ public int Checkpoint () {
mark_start = mark_end;
return mark_start;
}
- private void Backtrack (int cp) {
+ public void Backtrack (int cp) {
for (int i = 0; i < groups.Length; ++ i) {
int m = groups [i];
while (cp <= m)
@@ -212,7 +226,7 @@
}
}
- private void ResetGroups () {
+ public void ResetGroups () {
int n = groups.Length;
if (marks == null)
marks = new Mark [n];
@@ -228,7 +242,7 @@
mark_end = n;
}
- private int GetLastDefined (int gid) {
+ public int GetLastDefined (int gid) {
int m = groups [gid];
while (m >= 0 && !marks [m].IsDefined)
m = marks [m].Previous;
@@ -303,16 +317,23 @@
}
// used by the IL backend
- internal void SetStartOfMatch (int pos)
+ public void SetStartOfMatch (int pos)
{
marks [groups [0]].Start = pos;
}
- static bool IsWordChar (char c)
+ public static bool IsWordChar (char c)
{
return Char.IsLetterOrDigit (c) ||
Char.GetUnicodeCategory (c) == UnicodeCategory.ConnectorPunctuation;
}
+#if !NET_2_0
+ public virtual bool EvalByteCode (int strpos, ref int
strpos_result)
+ {
+ return EvalByteCode (11, strpos, ref strpos_result);
+ }
+#endif
+
bool EvalByteCode (int pc, int strpos, ref int strpos_result)
{
// luckily the IL engine can deal with char_group_end
at compile time
Index: CILCompiler.cs
===================================================================
--- CILCompiler.cs (revision 130801)
+++ CILCompiler.cs (working copy)
@@ -17,82 +17,72 @@
// 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: Add support for CompileToAssembly
// FIXME: Overwrite RxCompiler methods so we don't have to decode char
// matching opcodes
//
-#if NET_2_0
class CILCompiler : RxCompiler, ICompiler {
- DynamicMethod[] eval_methods;
- bool[] eval_methods_defined;
-
/*
* To avoid the overhead of decoding the countless opcode
variants created
* by RxCompiler, we save the original, 'generic' version and
its flags
* in these two tables.
*/
- private Dictionary<int, int> generic_ops;
- private Dictionary<int, int> op_flags;
- private Dictionary<int, Label> labels;
+#if NET_2_0
+ private Dictionary <int, int> generic_ops;
+ private Dictionary <int, int> op_flags;
+ private Dictionary <int, Label> labels;
+#else
+ private Hashtable generic_ops;
+ private Hashtable op_flags;
+ private Hashtable labels;
+#endif
- static FieldInfo fi_str = typeof (RxInterpreter).GetField
("str", BindingFlags.Instance|BindingFlags.NonPublic);
- static FieldInfo fi_string_start = typeof
(RxInterpreter).GetField ("string_start",
BindingFlags.Instance|BindingFlags.NonPublic);
- static FieldInfo fi_string_end = typeof
(RxInterpreter).GetField ("string_end",
BindingFlags.Instance|BindingFlags.NonPublic);
- static FieldInfo fi_program = typeof (RxInterpreter).GetField
("program", BindingFlags.Instance|BindingFlags.NonPublic);
- static FieldInfo fi_marks = typeof (RxInterpreter).GetField
("marks", BindingFlags.Instance|BindingFlags.NonPublic);
- static FieldInfo fi_groups = typeof (RxInterpreter).GetField
("groups", BindingFlags.Instance|BindingFlags.NonPublic);
+ static FieldInfo fi_str = typeof (RxInterpreter).GetField
("str", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+ static FieldInfo fi_string_start = typeof
(RxInterpreter).GetField ("string_start",
BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+ static FieldInfo fi_string_end = typeof
(RxInterpreter).GetField ("string_end",
BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+ static FieldInfo fi_program = typeof (RxInterpreter).GetField
("program", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+ static FieldInfo fi_marks = typeof (RxInterpreter).GetField
("marks", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+ static FieldInfo fi_groups = typeof (RxInterpreter).GetField
("groups", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
static FieldInfo fi_deep = typeof (RxInterpreter).GetField
("deep", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
static FieldInfo fi_stack = typeof (RxInterpreter).GetField
("stack", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
static FieldInfo fi_mark_start = typeof (Mark).GetField
("Start", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
static FieldInfo fi_mark_end = typeof (Mark).GetField ("End",
BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
- static FieldInfo fi_mark_index = typeof (Mark).GetField
("Index", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
static MethodInfo mi_stack_get_count, mi_stack_set_count,
mi_stack_push, mi_stack_pop;
static MethodInfo mi_set_start_of_match, mi_is_word_char,
mi_reset_groups;
static MethodInfo mi_checkpoint, mi_backtrack, mi_open,
mi_close;
static MethodInfo mi_get_last_defined, mi_mark_get_index,
mi_mark_get_length;
+#if !NET_2_0
+ static ConstructorInfo ci_rx_interpreter = typeof
(RxInterpreter).GetConstructor (new Type[] { typeof (byte[]) });
+
+ static Stack module_builders = new Stack();
+
+ private class ModuleBuilderInstance
+ {
+ public ModuleBuilder module_builder;
+ public int type_count;
+ }
+#endif
+
public static readonly bool trace_compile =
Environment.GetEnvironmentVariable ("MONO_TRACE_RX_COMPILE") != null;
public CILCompiler () {
+#if NET_2_0
generic_ops = new Dictionary <int, int> ();
op_flags = new Dictionary <int, int> ();
+#else
+ generic_ops = new Hashtable ();
+ op_flags = new Hashtable ();
+#endif
}
- 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 MethodInfo GetMethod (Type t, string name, ref
MethodInfo cached) {
if (cached == null) {
cached = t.GetMethod (name,
BindingFlags.Static|BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
if (cached == null)
- throw new Exception ("Method not found:
" + name);
+ throw new MissingMethodException
("Method not found: " + name);
}
return cached;
}
@@ -151,14 +141,48 @@
LocalBuilder local_textinfo;
/*
- * Create a dynamic method which is equivalent to the
RxInterpreter.EvalByteCode
- * method specialized to the given program and a given pc.
Return the newly
- * created method or null if a not-supported opcode was
encountered.
+ * Create a dynamic method which is equivalent to the
RxInterpreter.EvalByteCode
+ * method specialized to the given program and a given pc.
Fallback to
+ * interpretation if an unsupported opcode was encountered.
*/
- 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);
+ IMachineFactory ICompiler.GetMachineFactory ()
+ {
+ byte[] program = new byte [curpos];
+ Buffer.BlockCopy (this.program, 0, program, 0, curpos);
+
+#if NET_2_0
+ DynamicMethod m = new DynamicMethod ("EvalByteCode",
typeof (bool), new Type[] { typeof (RxInterpreter), typeof (int), typeof
(int).MakeByRefType () }, typeof (RxInterpreter), true);
ILGenerator ilgen = m.GetILGenerator ();
+#else
+ ModuleBuilderInstance module_builder = null;
+ lock (module_builders)
+ {
+ if (module_builders.Count > 0)
+ module_builder =
(ModuleBuilderInstance) module_builders.Pop ();
+ }
+ if (module_builder == null) {
+ module_builder = new ModuleBuilderInstance ();
+ AssemblyName an = new AssemblyName ();
+ an.Name = "RegexAssembly";
+ AssemblyBuilder ab =
AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Run);
+ module_builder.module_builder =
ab.DefineDynamicModule ("RegexAssembly.dll");
+ }
+
+ try {
+ TypeBuilder type =
module_builder.module_builder.DefineType ("CompiledRegex" +
(module_builder.type_count++).ToString (CultureInfo.InvariantCulture),
TypeAttributes.Class, typeof (RxInterpreter));
+ ConstructorBuilder c = type.DefineConstructor
(MethodAttributes.Private, CallingConventions.Standard, new Type[] { typeof
(byte[]) });
+ ILGenerator ilgen = c.GetILGenerator ();
+
+ ilgen.Emit (OpCodes.Ldarg_0);
+ ilgen.Emit (OpCodes.Ldarg_1);
+ ilgen.Emit (OpCodes.Call, ci_rx_interpreter);
+ ilgen.Emit (OpCodes.Ret);
+
+ MethodBuilder m = type.DefineMethod
("EvalByteCode", MethodAttributes.Public | MethodAttributes.Virtual, typeof
(bool), new Type[] { typeof (int), typeof (int).Assembly.GetType
("System.Int32&") });
+ ilgen = m.GetILGenerator ();
+#endif
+
/*
Args:
interp - 0
@@ -181,9 +205,9 @@
ilgen.Emit (OpCodes.Call, typeof
(CultureInfo).GetMethod ("get_TextInfo"));
ilgen.Emit (OpCodes.Stloc, local_textinfo);
- m = EmitEvalMethodBody (m, ilgen, frame, program, pc,
program.Length, false, false, out pc);
- if (m == null)
- return null;
+ int pc;
+ if (!EmitEvalMethodBody (ilgen, frame, program, 11,
program.Length, false, false, out pc))
+ return new RxInterpreterFactory (program, null);
ilgen.MarkLabel (frame.label_pass);
ilgen.Emit (OpCodes.Ldarg_2);
@@ -196,7 +220,17 @@
ilgen.Emit (OpCodes.Ldc_I4_0);
ilgen.Emit (OpCodes.Ret);
- return m;
+#if NET_2_0
+ return new RxInterpreterFactory (program,
(EvalDelegate) m.CreateDelegate (typeof (EvalDelegate)));
+#else
+ return new RxInterpreterFactory (program,
type.CreateType ());
+ } finally {
+ lock (module_builders)
+ {
+ module_builders.Push(module_builder);
+ }
+ }
+#endif
}
private int ReadShort (byte[] program, int pc) {
@@ -204,14 +238,28 @@
}
private Label CreateLabelForPC (ILGenerator ilgen, int pc) {
+ Label l;
+
+#if NET_2_0
if (labels == null)
labels = new Dictionary <int, Label> ();
- Label l;
+
if (!labels.TryGetValue (pc, out l)) {
l = ilgen.DefineLabel ();
labels [pc] = l;
}
+#else
+ if (labels == null)
+ labels = new Hashtable ();
+ object o = labels [pc];
+ if (o == null) {
+ l = ilgen.DefineLabel ();
+ labels [pc] = l;
+ } else
+ l = (Label) o;
+#endif
+
return l;
}
@@ -233,11 +281,10 @@
* FIXME: Modify the regex tests so they are run with
RegexOptions.Compiled as
* well.
*/
- private DynamicMethod EmitEvalMethodBody (DynamicMethod m,
ILGenerator ilgen,
-
Frame frame, byte[] program,
-
int pc, int end_pc,
-
bool one_op, bool no_bump,
-
out int out_pc)
+ private bool EmitEvalMethodBody (ILGenerator ilgen, Frame frame,
+
byte[] program, int pc, int end_pc,
+
bool one_op, bool no_bump,
+
out int out_pc)
{
int start, length, end;
@@ -248,20 +295,36 @@
while (pc < end_pc) {
RxOp op = (RxOp)program [pc];
- // FIXME: Optimize this
- if (generic_ops.ContainsKey (pc))
- op = (RxOp)generic_ops [pc];
+ {
+#if NET_2_0
+ int i;
+ if (generic_ops.TryGetValue (pc, out i))
+ op = (RxOp) i;
+#else
+ object i = generic_ops [pc];
+ if (i != null)
+ op = (RxOp) (int) i;
+#endif
+ }
if (trace_compile) {
Console.WriteLine ("compiling {0}
pc={1} end_pc={2}, il_offset=0x{3:x}", op, pc, end_pc, GetILOffset (ilgen));
}
if (labels != null) {
+#if NET_2_0
Label l;
if (labels.TryGetValue (pc, out l)) {
ilgen.MarkLabel (l);
labels.Remove (pc);
}
+#else
+ object l = labels [pc];
+ if (l != null) {
+ ilgen.MarkLabel ((Label) l);
+ labels.Remove (pc);
+ }
+#endif
}
if (RxInterpreter.trace_rx) {
@@ -409,9 +472,8 @@
ilgen.Emit (OpCodes.Ldarg_1);
ilgen.Emit (OpCodes.Stloc,
local_old_strpos);
- m = EmitEvalMethodBody (m,
ilgen, new_frame, program, pc, end_pc, false, false, out out_pc);
- if (m == null)
- return null;
+ if (!EmitEvalMethodBody (ilgen,
new_frame, program, pc, end_pc, false, false, out out_pc))
+ return false;
// Pass
ilgen.MarkLabel
(new_frame.label_pass);
@@ -482,9 +544,8 @@
ilgen.Emit (OpCodes.Ldarg_1);
ilgen.Emit (OpCodes.Stloc,
local_old_strpos);
- m = EmitEvalMethodBody (m, ilgen,
new_frame, program, pc + 3, target_pc, false, false, out out_pc);
- if (m == null)
- return null;
+ if (!EmitEvalMethodBody (ilgen,
new_frame, program, pc + 3, target_pc, false, false, out out_pc))
+ return false;
// Pass
ilgen.MarkLabel (new_frame.label_pass);
@@ -504,7 +565,7 @@
case RxOp.UnicodeChar:
case RxOp.Range:
case RxOp.UnicodeRange: {
- OpFlags flags = (OpFlags)op_flags [pc];
+ OpFlags flags = (OpFlags) (int)
op_flags [pc];
bool negate = (flags & OpFlags.Negate)
> 0;
bool ignore = (flags &
OpFlags.IgnoreCase) > 0;
bool reverse = (flags &
OpFlags.RightToLeft) > 0;
@@ -817,7 +878,7 @@
}
case RxOp.Bitmap:
case RxOp.UnicodeBitmap: {
- OpFlags flags = (OpFlags)op_flags [pc];
+ OpFlags flags = (OpFlags) (int)
op_flags [pc];
bool negate = (flags & OpFlags.Negate)
> 0;
bool ignore = (flags &
OpFlags.IgnoreCase) > 0;
bool reverse = (flags &
OpFlags.RightToLeft) > 0;
@@ -938,7 +999,7 @@
}
case RxOp.String:
case RxOp.UnicodeString: {
- OpFlags flags = (OpFlags)op_flags [pc];
+ OpFlags flags = (OpFlags) (int)
op_flags [pc];
bool ignore = (flags &
OpFlags.IgnoreCase) > 0;
bool reverse = (flags &
OpFlags.RightToLeft) > 0;
bool unicode = (op ==
RxOp.UnicodeString);
@@ -1087,11 +1148,9 @@
*
https://bugzilla.novell.com/show_bug.cgi?id=466151
* for an example.
*/
- return null;
+ return false;
if (trace_compile)
Console.WriteLine ("\tjump
target: {0}", target_pc);
- if (labels == null)
- labels = new Dictionary <int,
Label> ();
Label l = CreateLabelForPC (ilgen,
target_pc);
ilgen.Emit (OpCodes.Br, l);
pc += 3;
@@ -1110,9 +1169,8 @@
ilgen.Emit (OpCodes.Stloc,
local_old_strpos);
Frame new_frame = new Frame (ilgen);
- m = EmitEvalMethodBody (m, ilgen,
new_frame, program, pc + 5, target1 < target2 ? target1 : target2, false,
false, out pc);
- if (m == null)
- return null;
+ if (!EmitEvalMethodBody (ilgen,
new_frame, program, pc + 5, target1 < target2 ? target1 : target2, false,
false, out pc))
+ return false;
if (trace_compile) {
Console.WriteLine ("\temitted
<test_expr>");
@@ -1152,9 +1210,8 @@
ilgen.Emit (OpCodes.Stloc,
local_old_strpos);
Frame new_frame = new Frame (ilgen);
- m = EmitEvalMethodBody (m, ilgen,
new_frame, program, pc + 3, target, false, false, out pc);
- if (m == null)
- return null;
+ if (!EmitEvalMethodBody (ilgen,
new_frame, program, pc + 3, target, false, false, out pc))
+ return false;
if (trace_compile) {
Console.WriteLine ("\temitted
<sub_expr>");
@@ -1184,7 +1241,7 @@
Label label_match = ilgen.DefineLabel
();
/* Determine the negate/reverse flags
by examining the first op */
- OpFlags flags = (OpFlags)op_flags [pc];
+ OpFlags flags = (OpFlags) (int)
op_flags [pc];
/* Determine whenever this is a negated
character class */
/* If it is, then the conditions are
ANDed together, not ORed */
@@ -1196,9 +1253,8 @@
*/
while (pc < char_group_end) {
Frame new_frame = new Frame
(ilgen);
- m = EmitEvalMethodBody (m,
ilgen, new_frame, program, pc, Int32.MaxValue, true, true, out pc);
- if (m == null)
- return null;
+ if (!EmitEvalMethodBody (ilgen,
new_frame, program, pc, Int32.MaxValue, true, true, out pc))
+ return false;
if (!revert) {
// Pass
@@ -1286,9 +1342,8 @@
// if (!EvalByteCode (pc + 11,
strpos, ref res))
Frame new_frame = new Frame
(ilgen);
- m = EmitEvalMethodBody (m,
ilgen, new_frame, program, pc + 11, tail, false, false, out out_pc);
- if (m == null)
- return null;
+ if (!EmitEvalMethodBody (ilgen,
new_frame, program, pc + 11, tail, false, false, out out_pc))
+ return false;
// Fail
// return false;
@@ -1328,9 +1383,8 @@
// if (EvalByteCode (tail,
strpos, ref res)) {
Frame new_frame = new Frame
(ilgen);
- m = EmitEvalMethodBody (m,
ilgen, new_frame, program, tail, end_pc, false, false, out out_pc);
- if (m == null)
- return null;
+ if (!EmitEvalMethodBody (ilgen,
new_frame, program, tail, end_pc, false, false, out out_pc))
+ return false;
// Success:
ilgen.MarkLabel
(new_frame.label_pass);
@@ -1356,9 +1410,8 @@
// Match an item
//if (!EvalByteCode (pc + 11,
strpos, ref res))
new_frame = new Frame (ilgen);
- m = EmitEvalMethodBody (m,
ilgen, new_frame, program, pc + 11, tail, false, false, out out_pc);
- if (m == null)
- return null;
+ if (!EmitEvalMethodBody (ilgen,
new_frame, program, pc + 11, tail, false, false, out out_pc))
+ return false;
// Success:
ilgen.MarkLabel
(new_frame.label_pass);
@@ -1404,9 +1457,8 @@
// if (!EvalByteCode (pc + 11,
strpos, ref res)) {
Frame new_frame = new Frame
(ilgen);
- m = EmitEvalMethodBody (m,
ilgen, new_frame, program, pc + 11, tail, false, false, out out_pc);
- if (m == null)
- return null;
+ if (!EmitEvalMethodBody (ilgen,
new_frame, program, pc + 11, tail, false, false, out out_pc))
+ return false;
// Fail:
ilgen.MarkLabel
(new_frame.label_fail);
@@ -1465,9 +1517,8 @@
// if (EvalByteCode (tail,
strpos, ref res)) {
new_frame = new Frame (ilgen);
- m = EmitEvalMethodBody (m,
ilgen, new_frame, program, tail, end_pc, false, false, out out_pc);
- if (m == null)
- return null;
+ if (!EmitEvalMethodBody (ilgen,
new_frame, program, tail, end_pc, false, false, out out_pc))
+ return false;
// Success:
ilgen.MarkLabel
(new_frame.label_pass);
@@ -1545,7 +1596,7 @@
case RxOp.CategoryEcmaWhiteSpace:
case RxOp.CategoryUnicodeSpecials:
case RxOp.CategoryUnicode: {
- OpFlags flags = (OpFlags)op_flags [pc];
+ OpFlags flags = (OpFlags) (int)
op_flags [pc];
bool negate = (flags & OpFlags.Negate)
> 0;
bool reverse = (flags &
OpFlags.RightToLeft) > 0;
@@ -1727,7 +1778,7 @@
break;
}
case RxOp.Reference: {
- OpFlags flags = (OpFlags)op_flags [pc];
+ OpFlags flags = (OpFlags) (int)
op_flags [pc];
bool ignore = (flags &
OpFlags.IgnoreCase) > 0;
bool reverse = (flags &
OpFlags.RightToLeft) > 0;
@@ -1845,7 +1896,7 @@
// FIXME:
if (RxInterpreter.trace_rx ||
trace_compile)
Console.WriteLine ("Opcode " +
op + " not supported.");
- return null;
+ return false;
default:
throw new NotImplementedException
("Opcode '" + op + "' not supported by the regex->IL compiler.");
}
@@ -1858,13 +1909,7 @@
out_pc = pc;
- return m;
+ return true;
}
}
-#else
- class CILCompiler : RxCompiler {
- }
-#endif
-
}
-
_______________________________________________
Mono-devel-list mailing list
Mono-devel-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-devel-list