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
*/
/*
* Recursive calls to EvalByteCode are inlined manually by calling
* EmitEvalMethodBody with the pc of the recursive call. Frame objects hold
* the information required to link together the code generated by the recursive
* call with the rest of the code.
*/
Frame frame = new Frame (ilgen);
/* Cache the textinfo used by Char.ToLower () */
local_textinfo = ilgen.DeclareLocal (typeof (TextInfo));
ilgen.Emit (OpCodes.Call, typeof (Thread).GetMethod ("get_CurrentThread"));
ilgen.Emit (OpCodes.Call, typeof (Thread).GetMethod ("get_CurrentCulture"));
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;
ilgen.MarkLabel (frame.label_pass);
ilgen.Emit (OpCodes.Ldarg_2);
ilgen.Emit (OpCodes.Ldarg_1);
ilgen.Emit (OpCodes.Stind_I4);
ilgen.Emit (OpCodes.Ldc_I4_1);
ilgen.Emit (OpCodes.Ret);
ilgen.MarkLabel (frame.label_fail);
ilgen.Emit (OpCodes.Ldc_I4_0);
ilgen.Emit (OpCodes.Ret);
return m;
}