From 356f59ac45453e26b3d75742eb2e6fe01f85eeb7 Mon Sep 17 00:00:00 2001 From: Tedd Hansen Date: Wed, 8 Aug 2007 14:36:54 +0000 Subject: Added ScriptEngine to solution (prebuild.xml) --- .../DotNetEngine.Compiler.LSL/temp_rc.cs | 3293 -------------------- 1 file changed, 3293 deletions(-) delete mode 100644 OpenSim/Region/ScriptEngine/DotNetEngine.Compiler.LSL/temp_rc.cs (limited to 'OpenSim/Region/ScriptEngine/DotNetEngine.Compiler.LSL') diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine.Compiler.LSL/temp_rc.cs b/OpenSim/Region/ScriptEngine/DotNetEngine.Compiler.LSL/temp_rc.cs deleted file mode 100644 index fa7de2b..0000000 --- a/OpenSim/Region/ScriptEngine/DotNetEngine.Compiler.LSL/temp_rc.cs +++ /dev/null @@ -1,3293 +0,0 @@ -//------------------------------------------------------------------------------ -// -// -// Copyright (c) 2002 Microsoft Corporation. All rights reserved. -// -// The use and distribution terms for this software are contained in the file -// named license.txt, which can be found in the root of this distribution. -// By using this software in any fashion, you are agreeing to be bound by the -// terms of this license. -// -// You must not remove this notice, or any other, from this software. -// -// -//------------------------------------------------------------------------------ - -// The RegexCompiler class is internal to the Regex package. -// It translates a block of RegexCode to MSIL, and creates a -// subclass of the RegexRunner type. -// -#define ECMA - -namespace System.Text.RegularExpressions -{ - - using System.Collections; - using System.Threading; - using System.Reflection; - using System.Reflection.Emit; - using System.Security; - using System.Security.Permissions; - using System.Diagnostics; - using System.Globalization; - - // RegexDynamicModule - // - // Because dynamic modules are expensive and not thread-safe, we create - // one dynamic module per-thread, and cache as much information about it - // as we can. - // - // While we're at it, we just create one RegexCompiler per thread - // as well, and have RegexCompiler inherit from RegexDynamicModule. - internal class RegexDynamicModule - { - internal AssemblyBuilder _assembly; - internal ModuleBuilder _module; - - // fields that never change (making them saves about 6% overall running time) - - internal static FieldInfo _textbegF; - internal static FieldInfo _textendF; - internal static FieldInfo _textstartF; - internal static FieldInfo _textposF; - internal static FieldInfo _textF; - internal static FieldInfo _trackposF; - internal static FieldInfo _trackF; - internal static FieldInfo _stackposF; - internal static FieldInfo _stackF; - internal static FieldInfo _crawlposF; - internal static FieldInfo _crawlF; - internal static FieldInfo _matchF; - internal static FieldInfo _trackcountF; - - // note some methods - - internal static MethodInfo _ensurestorageM; - internal static MethodInfo _captureM; - internal static MethodInfo _transferM; - internal static MethodInfo _uncaptureM; - internal static MethodInfo _ismatchedM; - internal static MethodInfo _matchlengthM; - internal static MethodInfo _matchindexM; - internal static MethodInfo _isboundaryM; - internal static MethodInfo _isECMABoundaryM; - internal static MethodInfo _chartolowerM; - internal static MethodInfo _getcharM; - internal static MethodInfo _crawlposM; - internal static MethodInfo _charInSetM; - internal static MethodInfo _getCurrentCulture; - internal static MethodInfo _getInvariantCulture; -#if DBG - internal static MethodInfo _dumpstateM; -#endif - - - protected RegexDynamicModule(int moduleNum, AssemblyName an, CustomAttributeBuilder[] attribs, String resourceFile) - { - new ReflectionPermission(PermissionState.Unrestricted).Assert(); - try - { - if (an == null) - { - an = new AssemblyName(); - an.Name = "RegexAssembly" + AppDomain.CurrentDomain.GetHashCode().ToString() + "_" + moduleNum.ToString(); - _assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); - } - else - { - _assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave); - } - - _module = _assembly.DefineDynamicModule(an.Name + ".dll"); - - if (attribs != null) - { - for (int i = 0; i < attribs.Length; i++) - { - _assembly.SetCustomAttribute(attribs[i]); - } - } - - if (resourceFile != null) - { - // unmanaged resources are not supported - throw new ArgumentOutOfRangeException("resourceFile"); - } - } - finally - { - CodeAccessPermission.RevertAssert(); - } - } - - static RegexDynamicModule() - { - - new ReflectionPermission(PermissionState.Unrestricted).Assert(); - try - { - // note some fields - _textbegF = RegexRunnerField("runtextbeg"); - _textendF = RegexRunnerField("runtextend"); - _textstartF = RegexRunnerField("runtextstart"); - _textposF = RegexRunnerField("runtextpos"); - _textF = RegexRunnerField("runtext"); - _trackposF = RegexRunnerField("runtrackpos"); - _trackF = RegexRunnerField("runtrack"); - _stackposF = RegexRunnerField("runstackpos"); - _stackF = RegexRunnerField("runstack"); - _crawlposF = RegexRunnerField("runcrawlpos"); - _crawlF = RegexRunnerField("runcrawl"); - _matchF = RegexRunnerField("runmatch"); - _trackcountF = RegexRunnerField("runtrackcount"); - - // note some methods - _ensurestorageM = RegexRunnerMethod("EnsureStorage"); - _captureM = RegexRunnerMethod("Capture"); - _transferM = RegexRunnerMethod("TransferCapture"); - _uncaptureM = RegexRunnerMethod("Uncapture"); - _ismatchedM = RegexRunnerMethod("IsMatched"); - _matchlengthM = RegexRunnerMethod("MatchLength"); - _matchindexM = RegexRunnerMethod("MatchIndex"); - _isboundaryM = RegexRunnerMethod("IsBoundary"); - _charInSetM = RegexRunnerMethod("CharInSet"); - _isECMABoundaryM = RegexRunnerMethod("IsECMABoundary"); - _crawlposM = RegexRunnerMethod("Crawlpos"); - - _chartolowerM = typeof(Char).GetMethod("ToLower", new Type[] { typeof(Char), typeof(CultureInfo) }); - _getcharM = typeof(String).GetMethod("get_Chars", new Type[] { typeof(int) }); - _getCurrentCulture = typeof(CultureInfo).GetMethod("get_CurrentCulture"); - _getInvariantCulture = typeof(CultureInfo).GetMethod("get_InvariantCulture"); - - -#if DBG - _dumpstateM = RegexRunnerMethod("DumpState"); -#endif - } - finally - { - CodeAccessPermission.RevertAssert(); - } - } - - private static FieldInfo RegexRunnerField(String fieldname) - { - return typeof(RegexRunner).GetField(fieldname, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); - } - - private static MethodInfo RegexRunnerMethod(String methname) - { - return typeof(RegexRunner).GetMethod(methname, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static); - } - } - - - internal sealed class RegexCompiler : RegexDynamicModule - { - internal static Object _syncObject = new Object(); - internal static int _typeCount = 0; - internal static int _moduleCount = 0; - internal static LocalDataStoreSlot _moduleSlot = Thread.AllocateDataSlot(); - - // state of the type builder - internal TypeBuilder _typebuilder; - internal MethodBuilder _methbuilder; - internal ILGenerator _ilg; - - // tokens representing local variables - internal LocalBuilder _textstartV; - internal LocalBuilder _textbegV; - internal LocalBuilder _textendV; - internal LocalBuilder _textposV; - internal LocalBuilder _textV; - internal LocalBuilder _trackposV; - internal LocalBuilder _trackV; - internal LocalBuilder _stackposV; - internal LocalBuilder _stackV; - internal LocalBuilder _tempV; - internal LocalBuilder _temp2V; - internal LocalBuilder _temp3V; - - - internal RegexCode _code; // the RegexCode object (used for debugging only) - internal int[] _codes; // the RegexCodes being translated - internal String[] _strings; // the stringtable associated with the RegexCodes - internal RegexPrefix _fcPrefix; // the possible first chars computed by RegexFCD - internal RegexPrefix _scPrefix; // the set of eaten prefix chars - internal RegexBoyerMoore _bmPrefix; // a prefix as a boyer-moore machine - internal int _anchors; // the set of anchors - - internal Label[] _labels; // a label for every operation in _codes - internal BacktrackNote[] _notes; // a list of the backtracking states to be generated - internal int _notecount; // true count of _notes (allocation grows exponentially) - internal int _trackcount; // count of backtracking states (used to reduce allocations) - - internal Label _backtrack; // label for backtracking - - - internal int _regexopcode; // the current opcode being processed - internal int _codepos; // the current code being translated - internal int _backpos; // the current backtrack-note being translated - - internal RegexOptions _options; // options - - internal const int infinite = RegexNode.infinite; // an infinity - - // special code fragments - internal int[] _uniquenote; // _notes indices for code that should be emitted <= once - internal int[] _goto; // indices for forward-jumps-through-switch (for allocations) - - // indices for unique code fragments - internal const int stackpop = 0; // pop one - internal const int stackpop2 = 1; // pop two - internal const int stackpop3 = 2; // pop three - internal const int capback = 3; // uncapture - internal const int capback2 = 4; // uncapture 2 - internal const int branchmarkback2 = 5; // back2 part of branchmark - internal const int lazybranchmarkback2 = 6; // back2 part of lazybranchmark - internal const int branchcountback2 = 7; // back2 part of branchcount - internal const int lazybranchcountback2 = 8; // back2 part of lazybranchcount - internal const int forejumpback = 9; // back part of forejump - internal const int uniquecount = 10; - - - private RegexCompiler(int moduleNum) - : base(moduleNum, null, null, null) - { - } - - private RegexCompiler(int moduleNum, AssemblyName an, CustomAttributeBuilder[] attribs, String resourceFile) - : base(moduleNum, an, attribs, resourceFile) - { - } - - // Entry point to dynamically compile a regular expression. The expression is compiled to - // an in memory assembly. - internal static RegexRunnerFactory Compile(RegexCode code, RegexOptions options) - { - RegexCompiler c; - - c = GetThreadCompiler(); - - Type factory; - RegexRunnerFactory rrf; - - new ReflectionPermission(PermissionState.Unrestricted).Assert(); - try - { - factory = c.FactoryFromCode(code, options, "Regex"); - rrf = (RegexRunnerFactory)(Activator.CreateInstance(factory, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.CreateInstance, null, null, null)); - } - finally - { - CodeAccessPermission.RevertAssert(); - } - return rrf; - } - - // Compile regular expressions into an assembly on disk. - internal static void CompileToAssembly(RegexCompilationInfo[] regexes, AssemblyName an, CustomAttributeBuilder[] attribs, String resourceFile) - { - RegexCompiler c = new RegexCompiler(0, an, attribs, resourceFile); - - for (int i = 0; i < regexes.Length; i++) - { - String pattern = regexes[i].Pattern; - RegexOptions options = regexes[i].Options; - String fullname = regexes[i].Namespace + "." + regexes[i].Name; - - RegexTree tree = RegexParser.Parse(pattern, options); - RegexCode code = RegexWriter.Write(tree); - - Type factory; - - new ReflectionPermission(PermissionState.Unrestricted).Assert(); - try - { - factory = c.FactoryFromCode(code, options, fullname); - c.GenerateRegexType(pattern, options, fullname, regexes[i].IsPublic, code, tree, factory); - } - finally - { - CodeAccessPermission.RevertAssert(); - } - } - - c.Save(); - } - - // The top-level driver. Initializes everything then calls the Generate* methods. - internal Type FactoryFromCode(RegexCode code, RegexOptions options, String typeprefix) - { - String runnertypename; - String runnerfactoryname; - Type runnertype; - Type factory; - - _code = code; - _codes = code._codes; - _strings = code._strings; - _fcPrefix = code._fcPrefix; - _scPrefix = code._scPrefix; - _bmPrefix = code._bmPrefix; - _anchors = code._anchors; - _trackcount = code._trackcount; - _options = options; - - // pick a name for the class - - lock (_syncObject) - { - - // Note: Class names must be unique within assemblies, not just - // within modules. We append the modulename to the runner name - // to make our name unique across the assembly - - runnertypename = typeprefix + "Runner" + _typeCount.ToString(); - runnerfactoryname = typeprefix + "Factory" + _typeCount.ToString(); - _typeCount++; - } - - // Generate a RegexRunner class - // (blocks are simply illustrative) - - DefineType(runnertypename, false, typeof(RegexRunner)); - { - DefineMethod("Go", null); - { - GenerateGo(); - BakeMethod(); - } - - DefineMethod("FindFirstChar", typeof(bool)); - { - GenerateFindFirstChar(); - BakeMethod(); - } - - DefineMethod("InitTrackCount", null); - { - GenerateInitTrackCount(); - BakeMethod(); - } - - runnertype = BakeType(); - } - - // Generate a RegexRunnerFactory class - - DefineType(runnerfactoryname, false, typeof(RegexRunnerFactory)); - { - DefineMethod("CreateInstance", typeof(RegexRunner)); - { - GenerateCreateInstance(runnertype); - BakeMethod(); - } - - factory = BakeType(); - } - - return factory; - } - - - internal void GenerateRegexType(String pattern, RegexOptions opts, String name, bool ispublic, RegexCode code, RegexTree tree, Type factory) - { - FieldInfo patternF = RegexField("pattern"); - FieldInfo optionsF = RegexField("roptions"); - FieldInfo factoryF = RegexField("factory"); - FieldInfo capsF = RegexField("caps"); - FieldInfo capnamesF = RegexField("capnames"); - FieldInfo capslistF = RegexField("capslist"); - FieldInfo capsizeF = RegexField("capsize"); - Type[] noTypeArray = new Type[0]; - ConstructorBuilder cbuilder; - - DefineType(name, ispublic, typeof(Regex)); - { - // define constructor - _methbuilder = null; - MethodAttributes ma = System.Reflection.MethodAttributes.Public; - cbuilder = _typebuilder.DefineConstructor(ma, CallingConventions.Standard, noTypeArray); - _ilg = cbuilder.GetILGenerator(); - { - // call base constructor - Ldthis(); - _ilg.Emit(OpCodes.Call, typeof(Regex).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, - null, new Type[0], new ParameterModifier[0])); - // set pattern - Ldthis(); - Ldstr(pattern); - Stfld(patternF); - - // set options - Ldthis(); - Ldc((int)opts); - Stfld(optionsF); - - // set factory - Ldthis(); - Newobj(factory.GetConstructor(noTypeArray)); - Stfld(factoryF); - - // set caps - if (code._caps != null) - GenerateCreateHashtable(capsF, code._caps); - - // set capnames - if (tree._capnames != null) - GenerateCreateHashtable(capnamesF, tree._capnames); - - // set capslist - if (tree._capslist != null) - { - Ldthis(); - Ldc(tree._capslist.Length); - _ilg.Emit(OpCodes.Newarr, typeof(String)); // create new string array - Stfld(capslistF); - - for (int i = 0; i < tree._capslist.Length; i++) - { - Ldthisfld(capslistF); - - Ldc(i); - Ldstr(tree._capslist[i]); - _ilg.Emit(OpCodes.Stelem_Ref); - } - } - - // set capsize - Ldthis(); - Ldc(code._capsize); - Stfld(capsizeF); - - // set runnerref and replref by calling InitializeReferences() - Ldthis(); - Call(typeof(Regex).GetMethod("InitializeReferences", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); - - - Ret(); - } - } - - // bake the constructor and type, then save the assembly - cbuilder = null; - _typebuilder.CreateType(); - _ilg = null; - _typebuilder = null; - } - - internal void GenerateCreateHashtable(FieldInfo field, Hashtable ht) - { - MethodInfo addMethod = typeof(Hashtable).GetMethod("Add", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); - - Ldthis(); - Newobj(typeof(Hashtable).GetConstructor(new Type[0])); - Stfld(field); - - IDictionaryEnumerator en = ht.GetEnumerator(); - while (en.MoveNext()) - { - Ldthisfld(field); - - if (en.Key is int) - { - Ldc((int)en.Key); - _ilg.Emit(OpCodes.Box, typeof(Int32)); - } - else - Ldstr((String)en.Key); - - Ldc((int)en.Value); - _ilg.Emit(OpCodes.Box, typeof(Int32)); - Callvirt(addMethod); - } - } - - private FieldInfo RegexField(String fieldname) - { - return typeof(Regex).GetField(fieldname, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); - } - - internal void Save() - { - _assembly.Save(_assembly.GetName().Name + ".dll"); - } - - // Keeps track of an operation that needs to be referenced in the backtrack-jump - // switch table, and that needs backtracking code to be emitted (if flags != 0) - internal sealed class BacktrackNote - { - internal BacktrackNote(int flags, Label label, int codepos) - { - _codepos = codepos; - _flags = flags; - _label = label; - } - - internal int _codepos; - internal int _flags; - internal Label _label; - } - - // Adds a backtrack note to the list of them, and returns the index of the new - // note (which is also the index for the jump used by the switch table) - internal int AddBacktrackNote(int flags, Label l, int codepos) - { - if (_notes == null || _notecount >= _notes.Length) - { - BacktrackNote[] newnotes = new BacktrackNote[_notes == null ? 16 : _notes.Length * 2]; - if (_notes != null) - System.Array.Copy(_notes, 0, newnotes, 0, _notecount); - _notes = newnotes; - } - - _notes[_notecount] = new BacktrackNote(flags, l, codepos); - - return _notecount++; - } - - // Adds a backtrack note for the current operation; creates a new label for - // where the code will be, and returns the switch index. - internal int AddTrack() - { - return AddTrack(RegexCode.Back); - } - - // Adds a backtrack note for the current operation; creates a new label for - // where the code will be, and returns the switch index. - internal int AddTrack(int flags) - { - return AddBacktrackNote(flags, DefineLabel(), _codepos); - } - - // Adds a switchtable entry for the specified position (for the forward - // logic; does not cause backtracking logic to be generated) - internal int AddGoto(int destpos) - { - if (_goto[destpos] == -1) - _goto[destpos] = AddBacktrackNote(0, _labels[destpos], destpos); - - return _goto[destpos]; - } - - // Adds a note for backtracking code that only needs to be generated once; - // if it's already marked to be generated, returns the switch index - // for the unique piece of code. - internal int AddUniqueTrack(int i) - { - return AddUniqueTrack(i, RegexCode.Back); - } - - // Adds a note for backtracking code that only needs to be generated once; - // if it's already marked to be generated, returns the switch index - // for the unique piece of code. - internal int AddUniqueTrack(int i, int flags) - { - if (_uniquenote[i] == -1) - _uniquenote[i] = AddTrack(flags); - - return _uniquenote[i]; - } - - // A macro for _ilg.DefineLabel - internal Label DefineLabel() - { - return _ilg.DefineLabel(); - } - - // A macro for _ilg.MarkLabel - internal void MarkLabel(Label l) - { - _ilg.MarkLabel(l); - } - - // Returns the ith operand of the current operation - internal int Operand(int i) - { - return _codes[_codepos + i + 1]; - } - - // True if the current operation is marked for the leftward direction - internal bool IsRtl() - { - return (_regexopcode & RegexCode.Rtl) != 0; - } - - // True if the current operation is marked for the leftward direction - internal bool IsCi() - { - return (_regexopcode & RegexCode.Ci) != 0; - } - -#if DBG - // True if we need to do the backtrack logic for the current operation - internal bool IsBack() { - return(_regexopcode & RegexCode.Back) != 0; - } - - // True if we need to do the second-backtrack logic for the current operation - internal bool IsBack2() { - return(_regexopcode & RegexCode.Back2) != 0; - } -#endif - - // Returns the raw regex opcode (masking out Back and Rtl) - internal int Code() - { - return _regexopcode & RegexCode.Mask; - } - - internal void Ldstr(string str) - { - _ilg.Emit(OpCodes.Ldstr, str); - } - - // A macro for the various forms of Ldc - internal void Ldc(int i) - { - if (i <= 127 && i >= -128) - _ilg.Emit(OpCodes.Ldc_I4_S, (byte)i); - else - _ilg.Emit(OpCodes.Ldc_I4, i); - } - - // A macro for _ilg.Emit(OpCodes.Dup) - internal void Dup() - { - _ilg.Emit(OpCodes.Dup); - } - - // A macro for _ilg.Emit(OpCodes.Ret) - internal void Ret() - { - _ilg.Emit(OpCodes.Ret); - } - - // A macro for _ilg.Emit(OpCodes.Pop) - internal void Pop() - { - _ilg.Emit(OpCodes.Pop); - } - - // A macro for _ilg.Emit(OpCodes.Add) - internal void Add() - { - _ilg.Emit(OpCodes.Add); - } - - // A macro for _ilg.Emit(OpCodes.Add); a true flag can turn it into a Sub - internal void Add(bool negate) - { - if (negate) - _ilg.Emit(OpCodes.Sub); - else - _ilg.Emit(OpCodes.Add); - } - - // A macro for _ilg.Emit(OpCodes.Sub) - internal void Sub() - { - _ilg.Emit(OpCodes.Sub); - } - - // A macro for _ilg.Emit(OpCodes.Sub); a true flag can turn it into a Add - internal void Sub(bool negate) - { - if (negate) - _ilg.Emit(OpCodes.Add); - else - _ilg.Emit(OpCodes.Sub); - } - - // A macro for _ilg.Emit(OpCodes.Ldloc); - internal void Ldloc(LocalBuilder lt) - { - _ilg.Emit(OpCodes.Ldloc_S, lt); - } - - // A macro for _ilg.Emit(OpCodes.Stloc); - internal void Stloc(LocalBuilder lt) - { - _ilg.Emit(OpCodes.Stloc_S, lt); - } - - // A macro for _ilg.Emit(OpCodes.Ldarg_0); - internal void Ldthis() - { - _ilg.Emit(OpCodes.Ldarg_0); - } - - // A macro for Ldthis(); Ldfld(); - internal void Ldthisfld(FieldInfo ft) - { - Ldthis(); - _ilg.Emit(OpCodes.Ldfld, ft); - } - - // A macro for Ldthis(); Ldfld(); Stloc(); - internal void Mvfldloc(FieldInfo ft, LocalBuilder lt) - { - Ldthisfld(ft); - Stloc(lt); - } - - // A macro for Ldthis(); Ldthisfld(); Stloc(); - internal void Mvlocfld(LocalBuilder lt, FieldInfo ft) - { - Ldthis(); - Ldloc(lt); - Stfld(ft); - } - - // A macro for _ilg.Emit(OpCodes.Stfld); - internal void Stfld(FieldInfo ft) - { - _ilg.Emit(OpCodes.Stfld, ft); - } - - // A macro for _ilg.Emit(OpCodes.Callvirt); - internal void Callvirt(MethodInfo mt) - { - _ilg.Emit(OpCodes.Callvirt, mt); - } - - // A macro for _ilg.Emit(OpCodes.Call); - internal void Call(MethodInfo mt) - { - _ilg.Emit(OpCodes.Call, mt); - } - - // A macro for _ilg.Emit(OpCodes.Newobj); - internal void Newobj(ConstructorInfo ct) - { - _ilg.Emit(OpCodes.Newobj, ct); - } - - // A macro for _ilg.Emit(OpCodes.Brfalse) (long form) - internal void BrfalseFar(Label l) - { - _ilg.Emit(OpCodes.Brfalse, l); - } - - // A macro for _ilg.Emit(OpCodes.Brtrue) (long form) - internal void BrtrueFar(Label l) - { - _ilg.Emit(OpCodes.Brtrue, l); - } - - // A macro for _ilg.Emit(OpCodes.Br) (long form) - internal void BrFar(Label l) - { - _ilg.Emit(OpCodes.Br, l); - } - - // A macro for _ilg.Emit(OpCodes.Ble) (long form) - internal void BleFar(Label l) - { - _ilg.Emit(OpCodes.Ble, l); - } - - // A macro for _ilg.Emit(OpCodes.Blt) (long form) - internal void BltFar(Label l) - { - _ilg.Emit(OpCodes.Blt, l); - } - - // A macro for _ilg.Emit(OpCodes.Bge) (long form) - internal void BgeFar(Label l) - { - _ilg.Emit(OpCodes.Bge, l); - } - - // A macro for _ilg.Emit(OpCodes.Bgt) (long form) - internal void BgtFar(Label l) - { - _ilg.Emit(OpCodes.Bgt, l); - } - - // A macro for _ilg.Emit(OpCodes.Bne) (long form) - internal void BneFar(Label l) - { - _ilg.Emit(OpCodes.Bne_Un, l); - } - - // A macro for _ilg.Emit(OpCodes.Beq) (long form) - internal void BeqFar(Label l) - { - _ilg.Emit(OpCodes.Beq, l); - } - - // A macro for _ilg.Emit(OpCodes.Brfalse_S) (short jump) - internal void Brfalse(Label l) - { - _ilg.Emit(OpCodes.Brfalse_S, l); - } - - // A macro for _ilg.Emit(OpCodes.Br_S) (short jump) - internal void Br(Label l) - { - _ilg.Emit(OpCodes.Br_S, l); - } - - // A macro for _ilg.Emit(OpCodes.Ble_S) (short jump) - internal void Ble(Label l) - { - _ilg.Emit(OpCodes.Ble_S, l); - } - - // A macro for _ilg.Emit(OpCodes.Blt_S) (short jump) - internal void Blt(Label l) - { - _ilg.Emit(OpCodes.Blt_S, l); - } - - // A macro for _ilg.Emit(OpCodes.Bge_S) (short jump) - internal void Bge(Label l) - { - _ilg.Emit(OpCodes.Bge_S, l); - } - - // A macro for _ilg.Emit(OpCodes.Bgt_S) (short jump) - internal void Bgt(Label l) - { - _ilg.Emit(OpCodes.Bgt_S, l); - } - - // A macro for _ilg.Emit(OpCodes.Bleun_S) (short jump) - internal void Bgtun(Label l) - { - _ilg.Emit(OpCodes.Bgt_Un_S, l); - } - - // A macro for _ilg.Emit(OpCodes.Bne_S) (short jump) - internal void Bne(Label l) - { - _ilg.Emit(OpCodes.Bne_Un_S, l); - } - - // A macro for _ilg.Emit(OpCodes.Beq_S) (short jump) - internal void Beq(Label l) - { - _ilg.Emit(OpCodes.Beq_S, l); - } - - // A macro for the Ldlen instruction - internal void Ldlen() - { - _ilg.Emit(OpCodes.Ldlen); - } - - // Loads the char to the right of the current position - internal void Rightchar() - { - Ldloc(_textV); - Ldloc(_textposV); - Callvirt(_getcharM); - } - - // Loads the char to the right of the current position and advances the current position - internal void Rightcharnext() - { - Ldloc(_textV); - Ldloc(_textposV); - Dup(); - Ldc(1); - Add(); - Stloc(_textposV); - Callvirt(_getcharM); - } - - // Loads the char to the left of the current position - internal void Leftchar() - { - Ldloc(_textV); - Ldloc(_textposV); - Ldc(1); - Sub(); - Callvirt(_getcharM); - } - - // Loads the char to the left of the current position and advances (leftward) - internal void Leftcharnext() - { - Ldloc(_textV); - Ldloc(_textposV); - Ldc(1); - Sub(); - Dup(); - Stloc(_textposV); - Callvirt(_getcharM); - } - - // Creates a backtrack note and pushes the switch index it on the tracking stack - internal void Track() - { - ReadyPushTrack(); - Ldc(AddTrack()); - DoPush(); - } - - // Pushes the current switch index on the tracking stack so the backtracking - // logic will be repeated again next time we backtrack here. - // - internal void Trackagain() - { - ReadyPushTrack(); - Ldc(_backpos); - DoPush(); - } - - // Saves the value of a local variable on the tracking stack - internal void PushTrack(LocalBuilder lt) - { - ReadyPushTrack(); - Ldloc(lt); - DoPush(); - } - - // Creates a backtrack note for a piece of code that should only be generated once, - // and emits code that pushes the switch index on the backtracking stack. - internal void TrackUnique(int i) - { - ReadyPushTrack(); - Ldc(AddUniqueTrack(i)); - DoPush(); - } - - // Creates a second-backtrack note for a piece of code that should only be - // generated once, and emits code that pushes the switch index on the - // backtracking stack. - internal void TrackUnique2(int i) - { - ReadyPushTrack(); - Ldc(AddUniqueTrack(i, RegexCode.Back2)); - DoPush(); - } - - // Prologue to code that will push an element on the tracking stack - internal void ReadyPushTrack() - { - _ilg.Emit(OpCodes.Ldloc_S, _trackV); - _ilg.Emit(OpCodes.Ldloc_S, _trackposV); - _ilg.Emit(OpCodes.Ldc_I4_1); - _ilg.Emit(OpCodes.Sub); - _ilg.Emit(OpCodes.Dup); - _ilg.Emit(OpCodes.Stloc_S, _trackposV); - } - - // Pops an element off the tracking stack (leave it on the operand stack) - internal void PopTrack() - { - _ilg.Emit(OpCodes.Ldloc_S, _trackV); - _ilg.Emit(OpCodes.Ldloc_S, _trackposV); - _ilg.Emit(OpCodes.Dup); - _ilg.Emit(OpCodes.Ldc_I4_1); - _ilg.Emit(OpCodes.Add); - _ilg.Emit(OpCodes.Stloc_S, _trackposV); - _ilg.Emit(OpCodes.Ldelem_I4); - } - - // Retrieves the top entry on the tracking stack without popping - internal void TopTrack() - { - _ilg.Emit(OpCodes.Ldloc_S, _trackV); - _ilg.Emit(OpCodes.Ldloc_S, _trackposV); - _ilg.Emit(OpCodes.Ldelem_I4); - } - - // Saves the value of a local variable on the grouping stack - internal void PushStack(LocalBuilder lt) - { - ReadyPushStack(); - _ilg.Emit(OpCodes.Ldloc_S, lt); - DoPush(); - } - - // Prologue to code that will replace the ith element on the grouping stack - internal void ReadyReplaceStack(int i) - { - _ilg.Emit(OpCodes.Ldloc_S, _stackV); - _ilg.Emit(OpCodes.Ldloc_S, _stackposV); - if (i != 0) - { - Ldc(i); - _ilg.Emit(OpCodes.Add); - } - } - - // Prologue to code that will push an element on the grouping stack - internal void ReadyPushStack() - { - _ilg.Emit(OpCodes.Ldloc_S, _stackV); - _ilg.Emit(OpCodes.Ldloc_S, _stackposV); - _ilg.Emit(OpCodes.Ldc_I4_1); - _ilg.Emit(OpCodes.Sub); - _ilg.Emit(OpCodes.Dup); - _ilg.Emit(OpCodes.Stloc_S, _stackposV); - } - - // Retrieves the top entry on the stack without popping - internal void TopStack() - { - _ilg.Emit(OpCodes.Ldloc_S, _stackV); - _ilg.Emit(OpCodes.Ldloc_S, _stackposV); - _ilg.Emit(OpCodes.Ldelem_I4); - } - - // Pops an element off the grouping stack (leave it on the operand stack) - internal void PopStack() - { - _ilg.Emit(OpCodes.Ldloc_S, _stackV); - _ilg.Emit(OpCodes.Ldloc_S, _stackposV); - _ilg.Emit(OpCodes.Dup); - _ilg.Emit(OpCodes.Ldc_I4_1); - _ilg.Emit(OpCodes.Add); - _ilg.Emit(OpCodes.Stloc_S, _stackposV); - _ilg.Emit(OpCodes.Ldelem_I4); - } - - // Pops 1 element off the grouping stack and discards it - internal void PopDiscardStack() - { - PopDiscardStack(1); - } - - // Pops i elements off the grouping stack and discards them - internal void PopDiscardStack(int i) - { - _ilg.Emit(OpCodes.Ldloc_S, _stackposV); - Ldc(i); - _ilg.Emit(OpCodes.Add); - _ilg.Emit(OpCodes.Stloc_S, _stackposV); - } - - // Epilogue to code that will replace an element on a stack (use Ld* in between) - internal void DoReplace() - { - _ilg.Emit(OpCodes.Stelem_I4); - } - - // Epilogue to code that will push an element on a stack (use Ld* in between) - internal void DoPush() - { - _ilg.Emit(OpCodes.Stelem_I4); - } - - // Jump to the backtracking switch - internal void Back() - { - _ilg.Emit(OpCodes.Br, _backtrack); - } - - // Branch to the MSIL corresponding to the regex code at i - // - // A trick: since track and stack space is gobbled up unboundedly - // only as a result of branching backwards, this is where we check - // for sufficient space and trigger reallocations. - // - // If the "goto" is backwards, we generate code that checks - // available space against the amount of space that would be needed - // in the worst case by code that will only go forward; if there's - // not enough, we push the destination on the tracking stack, then - // we jump to the place where we invoke the allocator. - // - // Since forward gotos pose no threat, they just turn into a Br. - internal void Goto(int i) - { - if (i < _codepos) - { - Label l1 = DefineLabel(); - - // When going backwards, ensure enough space. - Ldloc(_trackposV); - Ldc(_trackcount * 4); - Ble(l1); - Ldloc(_stackposV); - Ldc(_trackcount * 3); - BgtFar(_labels[i]); - MarkLabel(l1); - ReadyPushTrack(); - Ldc(AddGoto(i)); - DoPush(); - BrFar(_backtrack); - } - else - { - BrFar(_labels[i]); - } - } - - // Returns the position of the next operation in the regex code, taking - // into account the different numbers of arguments taken by operations - internal int NextCodepos() - { - return _codepos + RegexCode.OpcodeSize(_codes[_codepos]); - } - - // The label for the next (forward) operation - internal Label AdvanceLabel() - { - return _labels[NextCodepos()]; - } - - // Goto the next (forward) operation - internal void Advance() - { - _ilg.Emit(OpCodes.Br, AdvanceLabel()); - } - - internal void CallToLower() - { - if ((_options & RegexOptions.CultureInvariant) != 0) - Call(_getInvariantCulture); - else - Call(_getCurrentCulture); - - Call(_chartolowerM); - } - - // Generates the first section of the MSIL. This section contains all - // the forward logic, and corresponds directly to the regex codes. - // - // In the absence of backtracking, this is all we would need. - internal void GenerateForwardSection() - { - int codepos; - - _labels = new Label[_codes.Length]; - _goto = new int[_codes.Length]; - - // initialize - - for (codepos = 0; codepos < _codes.Length; codepos += RegexCode.OpcodeSize(_codes[codepos])) - { - _goto[codepos] = -1; - _labels[codepos] = _ilg.DefineLabel(); - } - - _uniquenote = new int[uniquecount]; - for (int i = 0; i < uniquecount; i++) - _uniquenote[i] = -1; - - // emit variable initializers - - Mvfldloc(_textF, _textV); - Mvfldloc(_textstartF, _textstartV); - Mvfldloc(_textbegF, _textbegV); - Mvfldloc(_textendF, _textendV); - Mvfldloc(_textposF, _textposV); - Mvfldloc(_trackF, _trackV); - Mvfldloc(_trackposF, _trackposV); - Mvfldloc(_stackF, _stackV); - Mvfldloc(_stackposF, _stackposV); - - _backpos = -1; - - for (codepos = 0; codepos < _codes.Length; codepos += RegexCode.OpcodeSize(_codes[codepos])) - { - MarkLabel(_labels[codepos]); - _codepos = codepos; - _regexopcode = _codes[codepos]; - GenerateOneCode(); - } - } - - // Generates the middle section of the MSIL. This section contains the - // big switch jump that allows us to simulate a stack of addresses, - // and it also contains the calls that expand the tracking and the - // grouping stack when they get too full. - internal void GenerateMiddleSection() - { - Label l1 = DefineLabel(); - Label[] table; - int i; - - // Backtrack switch - MarkLabel(_backtrack); - - // first call EnsureStorage - Mvlocfld(_trackposV, _trackposF); - Mvlocfld(_stackposV, _stackposF); - Ldthis(); - Callvirt(_ensurestorageM); - Mvfldloc(_trackposF, _trackposV); - Mvfldloc(_stackposF, _stackposV); - Mvfldloc(_trackF, _trackV); - Mvfldloc(_stackF, _stackV); - - - PopTrack(); - - table = new Label[_notecount]; - for (i = 0; i < _notecount; i++) - table[i] = _notes[i]._label; - - _ilg.Emit(OpCodes.Switch, table); - - } - - // Generates the last section of the MSIL. This section contains all of - // the backtracking logic. - internal void GenerateBacktrackSection() - { - int i; - - for (i = 0; i < _notecount; i++) - { - BacktrackNote n = _notes[i]; - if (n._flags != 0) - { - _ilg.MarkLabel(n._label); - _codepos = n._codepos; - _backpos = i; - _regexopcode = _codes[n._codepos] | n._flags; - GenerateOneCode(); - } - } - } - - // Generates FindFirstChar - internal void GenerateFindFirstChar() - { - _textposV = DeclareInt(); - _textV = DeclareString(); - _tempV = DeclareInt(); - _temp2V = DeclareInt(); - - if (0 != (_anchors & (RegexFCD.Beginning | RegexFCD.Start | RegexFCD.EndZ | RegexFCD.End))) - { - if (!_code._rightToLeft) - { - if (0 != (_anchors & RegexFCD.Beginning)) - { - Label l1 = DefineLabel(); - Ldthisfld(_textposF); - Ldthisfld(_textbegF); - Ble(l1); - Ldthis(); - Ldthisfld(_textendF); - Stfld(_textposF); - Ldc(0); - Ret(); - MarkLabel(l1); - } - - if (0 != (_anchors & RegexFCD.Start)) - { - Label l1 = DefineLabel(); - Ldthisfld(_textposF); - Ldthisfld(_textstartF); - Ble(l1); - Ldthis(); - Ldthisfld(_textendF); - Stfld(_textposF); - Ldc(0); - Ret(); - MarkLabel(l1); - } - - if (0 != (_anchors & RegexFCD.EndZ)) - { - Label l1 = DefineLabel(); - Ldthisfld(_textposF); - Ldthisfld(_textendF); - Ldc(1); - Sub(); - Bge(l1); - Ldthis(); - Ldthisfld(_textendF); - Ldc(1); - Sub(); - Stfld(_textposF); - MarkLabel(l1); - } - - if (0 != (_anchors & RegexFCD.End)) - { - Label l1 = DefineLabel(); - Ldthisfld(_textposF); - Ldthisfld(_textendF); - Bge(l1); - Ldthis(); - Ldthisfld(_textendF); - Stfld(_textposF); - MarkLabel(l1); - } - } - else - { - if (0 != (_anchors & RegexFCD.End)) - { - Label l1 = DefineLabel(); - Ldthisfld(_textposF); - Ldthisfld(_textendF); - Bge(l1); - Ldthis(); - Ldthisfld(_textbegF); - Stfld(_textposF); - Ldc(0); - Ret(); - MarkLabel(l1); - } - - if (0 != (_anchors & RegexFCD.EndZ)) - { - Label l1 = DefineLabel(); - Label l2 = DefineLabel(); - Ldthisfld(_textposF); - Ldthisfld(_textendF); - Ldc(1); - Sub(); - Blt(l1); - Ldthisfld(_textposF); - Ldthisfld(_textendF); - Beq(l2); - Ldthisfld(_textF); - Ldthisfld(_textposF); - Callvirt(_getcharM); - Ldc((int)'\n'); - Beq(l2); - MarkLabel(l1); - Ldthis(); - Ldthisfld(_textbegF); - Stfld(_textposF); - Ldc(0); - Ret(); - MarkLabel(l2); - } - - if (0 != (_anchors & RegexFCD.Start)) - { - Label l1 = DefineLabel(); - Ldthisfld(_textposF); - Ldthisfld(_textstartF); - Bge(l1); - Ldthis(); - Ldthisfld(_textbegF); - Stfld(_textposF); - Ldc(0); - Ret(); - MarkLabel(l1); - } - - if (0 != (_anchors & RegexFCD.Beginning)) - { - Label l1 = DefineLabel(); - Ldthisfld(_textposF); - Ldthisfld(_textbegF); - Ble(l1); - Ldthis(); - Ldthisfld(_textbegF); - Stfld(_textposF); - MarkLabel(l1); - } - } - - - Ldc(1); - Ret(); - } - else if (_bmPrefix != null && _bmPrefix._negativeUnicode == null) - { - // Compiled Boyer-Moore string matching - - LocalBuilder chV = _tempV; - LocalBuilder testV = _tempV; - LocalBuilder limitV = _temp2V; - Label lDefaultAdvance = DefineLabel(); - Label lAdvance = DefineLabel(); - Label lFail = DefineLabel(); - Label lStart = DefineLabel(); - Label lOutOfRange = DefineLabel(); - Label lPartialMatch = DefineLabel(); - - - int chLast; - int i; - int beforefirst; - int last; - Label[] table; - - if (!_code._rightToLeft) - { - beforefirst = -1; - last = _bmPrefix._pattern.Length - 1; - } - else - { - beforefirst = _bmPrefix._pattern.Length; - last = 0; - } - - chLast = _bmPrefix._pattern[last]; - - Mvfldloc(_textF, _textV); - if (!_code._rightToLeft) - Ldthisfld(_textendF); - else - Ldthisfld(_textbegF); - Stloc(limitV); - - Ldthisfld(_textposF); - if (!_code._rightToLeft) - { - Ldc(_bmPrefix._pattern.Length - 1); - Add(); - } - else - { - Ldc(_bmPrefix._pattern.Length); - Sub(); - } - Stloc(_textposV); - Br(lStart); - - MarkLabel(lDefaultAdvance); - - if (!_code._rightToLeft) - Ldc(_bmPrefix._pattern.Length); - else - Ldc(-_bmPrefix._pattern.Length); - - MarkLabel(lAdvance); - - Ldloc(_textposV); - Add(); - Stloc(_textposV); - - MarkLabel(lStart); - - Ldloc(_textposV); - Ldloc(limitV); - if (!_code._rightToLeft) - BgeFar(lFail); - else - BltFar(lFail); - - Rightchar(); - if (_bmPrefix._caseInsensitive) - CallToLower(); - - Dup(); - Stloc(chV); - Ldc(chLast); - BeqFar(lPartialMatch); - - Ldloc(chV); - Ldc(_bmPrefix._lowASCII); - Sub(); - Dup(); - Stloc(chV); - Ldc(_bmPrefix._highASCII - _bmPrefix._lowASCII); - Bgtun(lDefaultAdvance); - - table = new Label[_bmPrefix._highASCII - _bmPrefix._lowASCII + 1]; - - for (i = _bmPrefix._lowASCII; i <= _bmPrefix._highASCII; i++) - { - if (_bmPrefix._negativeASCII[i] == beforefirst) - table[i - _bmPrefix._lowASCII] = lDefaultAdvance; - else - table[i - _bmPrefix._lowASCII] = DefineLabel(); - } - - Ldloc(chV); - _ilg.Emit(OpCodes.Switch, table); - - for (i = _bmPrefix._lowASCII; i <= _bmPrefix._highASCII; i++) - { - if (_bmPrefix._negativeASCII[i] == beforefirst) - continue; - - MarkLabel(table[i - _bmPrefix._lowASCII]); - - Ldc(_bmPrefix._negativeASCII[i]); - BrFar(lAdvance); - } - - MarkLabel(lPartialMatch); - - Ldloc(_textposV); - Stloc(testV); - - for (i = _bmPrefix._pattern.Length - 2; i >= 0; i--) - { - Label lNext = DefineLabel(); - int charindex; - - if (!_code._rightToLeft) - charindex = i; - else - charindex = _bmPrefix._pattern.Length - 1 - i; - - Ldloc(_textV); - Ldloc(testV); - Ldc(1); - Sub(_code._rightToLeft); - Dup(); - Stloc(testV); - Callvirt(_getcharM); - if (_bmPrefix._caseInsensitive) - CallToLower(); - - Ldc(_bmPrefix._pattern[charindex]); - Beq(lNext); - Ldc(_bmPrefix._positive[charindex]); - BrFar(lAdvance); - - MarkLabel(lNext); - - } - - Ldthis(); - Ldloc(testV); - if (_code._rightToLeft) - { - Ldc(1); - Add(); - } - Stfld(_textposF); - Ldc(1); - Ret(); - - MarkLabel(lFail); - - Ldthis(); - if (!_code._rightToLeft) - Ldthisfld(_textendF); - else - Ldthisfld(_textbegF); - Stfld(_textposF); - Ldc(0); - Ret(); - } - else if (_fcPrefix == null) - { - Ldc(1); - Ret(); - } - else - { - LocalBuilder cV = _temp2V; - LocalBuilder chV = _tempV; - Label l1 = DefineLabel(); - Label l2 = DefineLabel(); - Label l3 = DefineLabel(); - Label l4 = DefineLabel(); - Label l5 = DefineLabel(); - - Mvfldloc(_textposF, _textposV); - Mvfldloc(_textF, _textV); - - if (!_code._rightToLeft) - { - Ldthisfld(_textendF); - Ldloc(_textposV); - } - else - { - Ldloc(_textposV); - Ldthisfld(_textbegF); - } - Sub(); - Stloc(cV); - - Ldloc(cV); - Ldc(0); - BleFar(l4); - - MarkLabel(l1); - - Ldloc(cV); - Ldc(1); - Sub(); - Stloc(cV); - - if (_code._rightToLeft) - Leftcharnext(); - else - Rightcharnext(); - - if (_fcPrefix.CaseInsensitive) - CallToLower(); - - if (!RegexCharClass.IsSingleton(_fcPrefix.Prefix)) - { - Ldstr(_fcPrefix.Prefix); - Ldstr(String.Empty); - Call(_charInSetM); - - BrtrueFar(l2); - } - else - { - Ldc(RegexCharClass.SingletonChar(_fcPrefix.Prefix)); - Beq(l2); - } - - MarkLabel(l5); - - Ldloc(cV); - Ldc(0); - if (!RegexCharClass.IsSingleton(_fcPrefix.Prefix)) - BgtFar(l1); - else - Bgt(l1); - - Ldc(0); - BrFar(l3); - - MarkLabel(l2); - - /* // CURRENTLY DISABLED - // If for some reason we have a prefix we didn't use, use it now. - - if (_bmPrefix != null) { - if (!_code._rightToLeft) { - Ldthisfld(_textendF); - Ldloc(_textposV); - } - else { - Ldloc(_textposV); - Ldthisfld(_textbegF); - } - Sub(); - Ldc(_bmPrefix._pattern.Length - 1); - BltFar(l5); - - for (int i = 1; i < _bmPrefix._pattern.Length; i++) { - Ldloc(_textV); - Ldloc(_textposV); - if (!_code._rightToLeft) { - Ldc(i - 1); - Add(); - } - else { - Ldc(i); - Sub(); - } - Callvirt(_getcharM); - if (!_code._rightToLeft) - Ldc(_bmPrefix._pattern[i]); - else - Ldc(_bmPrefix._pattern[_bmPrefix._pattern.Length - 1 - i]); - BneFar(l5); - } - } - */ - - Ldloc(_textposV); - Ldc(1); - Sub(_code._rightToLeft); - Stloc(_textposV); - Ldc(1); - - MarkLabel(l3); - - Mvlocfld(_textposV, _textposF); - Ret(); - - MarkLabel(l4); - Ldc(0); - Ret(); - } - - } - - // Generates a very simple method that sets the _trackcount field. - internal void GenerateInitTrackCount() - { - Ldthis(); - Ldc(_trackcount); - Stfld(_trackcountF); - Ret(); - } - - // Generates a very simple factory method. - internal void GenerateCreateInstance(Type newtype) - { - Newobj(newtype.GetConstructor(new Type[0])); - Ret(); - } - - // Gets the unique-for-regex dynamic module for this thread - internal static RegexCompiler GetThreadCompiler() - { - RegexCompiler compiler = (RegexCompiler)Thread.GetData(_moduleSlot); - - if (compiler == null) - { - int moduleNum; - - lock (_syncObject) - { - moduleNum = _moduleCount++; - } - - compiler = new RegexCompiler(moduleNum); - Thread.SetData(_moduleSlot, compiler); - } - - return compiler; - } - - // Begins the definition of a new type with a specified base class - internal void DefineType(String typename, bool ispublic, Type inheritfromclass) - { - if (ispublic) - _typebuilder = _module.DefineType(typename, TypeAttributes.Class | TypeAttributes.Public, inheritfromclass); - else - _typebuilder = _module.DefineType(typename, TypeAttributes.Class | TypeAttributes.NotPublic, inheritfromclass); - - } - - // Begins the definition of a new method (no args) with a specified return value - internal void DefineMethod(String methname, Type returntype) - { - MethodAttributes ma = System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.Virtual; - - _methbuilder = _typebuilder.DefineMethod(methname, ma, returntype, null); - _ilg = _methbuilder.GetILGenerator(); - } - - // Ends the definition of a method - internal void BakeMethod() - { - _methbuilder = null; - } - - // Ends the definition of a class and returns the type - internal Type BakeType() - { - Type retval = _typebuilder.CreateType(); - _typebuilder = null; - - return retval; - } - - // Declares a local int - internal LocalBuilder DeclareInt() - { - return _ilg.DeclareLocal(typeof(int)); - } - - // Declares a local int array - internal LocalBuilder DeclareIntArray() - { - return _ilg.DeclareLocal(typeof(int[])); - } - - // Declares a local char array - internal LocalBuilder DeclareCharArray() - { - return _ilg.DeclareLocal(typeof(char[])); - } - - // Declares a local string - internal LocalBuilder DeclareString() - { - return _ilg.DeclareLocal(typeof(string)); - } - - // Generates the code for "RegexRunner.Go" - internal void GenerateGo() - { - // declare some locals - - _textposV = DeclareInt(); - _textV = DeclareString(); - _trackposV = DeclareInt(); - _trackV = DeclareIntArray(); - _stackposV = DeclareInt(); - _stackV = DeclareIntArray(); - _tempV = DeclareInt(); - _temp2V = DeclareInt(); - _temp3V = DeclareInt(); - _textbegV = DeclareInt(); - _textendV = DeclareInt(); - _textstartV = DeclareInt(); - - // clear some tables - - _labels = null; - _notes = null; - _notecount = 0; - - // globally used labels - - _backtrack = DefineLabel(); - - // emit the code! - - GenerateForwardSection(); - GenerateMiddleSection(); - GenerateBacktrackSection(); - } - -#if DBG - // Some simple debugging stuff - internal static char[] Hex = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; - internal static MethodInfo _debugWriteLine = typeof(Debug).GetMethod("WriteLine", new Type[] {typeof(string)}); - - internal static String BaDescription(byte[] ba) { - StringBuilder sb = new StringBuilder(); - - sb.Append("Length " + ba.Length.ToString() + "\n"); - - for (int i = 0; i < ba.Length; i++) { - sb.Append(Hex[ba[i] >> 4]); - sb.Append(Hex[ba[i] & 0xF]); - sb.Append(' '); - } - return sb.ToString(); - } - - // Debug only: emit code to print out a message - internal void Message(String str) { - Ldstr(str); - Call(_debugWriteLine); - } - -#endif - - // The main translation function. It translates the logic for a single opcode at - // the current position. The structure of this function exactly mirrors - // the structure of the inner loop of RegexInterpreter.Go(). - // - // The C# code from RegexInterpreter.Go() that corresponds to each case is - // included as a comment. - // - // Note that since we're generating code, we can collapse many cases that are - // dealt with one-at-a-time in RegexIntepreter. We can also unroll loops that - // iterate over constant strings or sets. - internal void GenerateOneCode() - { -#if DBG - if ((_options & RegexOptions.Debug) != 0) { - Mvlocfld(_textposV, _textposF); - Mvlocfld(_trackposV, _trackposF); - Mvlocfld(_stackposV, _stackposF); - Ldthis(); - Callvirt(_dumpstateM); - StringBuilder sb = new StringBuilder(); - if (_backpos > 0) - sb.AppendFormat("{0:D6} ", _backpos); - else - sb.Append(" "); - sb.Append(_code.OpcodeDescription(_codepos)); - if (IsBack()) - sb.Append(" Back"); - if (IsBack2()) - sb.Append(" Back2"); - Message(sb.ToString()); - } -#endif - - switch (_regexopcode) - { - case RegexCode.Stop: - //: return; - Mvlocfld(_textposV, _textposF); // update _textpos - Ret(); - break; - - case RegexCode.Nothing: - //: break Backward; - Back(); - break; - - case RegexCode.Goto: - //: Goto(Operand(0)); - Goto(Operand(0)); - break; - - case RegexCode.Testref: - //: if (!_match.IsMatched(Operand(0))) - //: break Backward; - Ldthis(); - Ldc(Operand(0)); - Callvirt(_ismatchedM); - BrfalseFar(_backtrack); - break; - - case RegexCode.Lazybranch: - //: Track(Textpos()); - PushTrack(_textposV); - Track(); - break; - - case RegexCode.Lazybranch | RegexCode.Back: - //: Trackframe(1); - //: Textto(Tracked(0)); - //: Goto(Operand(0)); - PopTrack(); - Stloc(_textposV); - Goto(Operand(0)); - break; - - case RegexCode.Nullmark: - //: Stack(-1); - //: Track(); - ReadyPushStack(); - Ldc(-1); - DoPush(); - TrackUnique(stackpop); - break; - - case RegexCode.Setmark: - //: Stack(Textpos()); - //: Track(); - PushStack(_textposV); - TrackUnique(stackpop); - break; - - case RegexCode.Nullmark | RegexCode.Back: - case RegexCode.Setmark | RegexCode.Back: - //: Stackframe(1); - //: break Backward; - PopDiscardStack(); - Back(); - break; - - case RegexCode.Getmark: - //: Stackframe(1); - //: Track(Stacked(0)); - //: Textto(Stacked(0)); - ReadyPushTrack(); - PopStack(); - Dup(); - Stloc(_textposV); - DoPush(); - - Track(); - break; - - case RegexCode.Getmark | RegexCode.Back: - //: Trackframe(1); - //: Stack(Tracked(0)); - //: break Backward; - ReadyPushStack(); - PopTrack(); - DoPush(); - Back(); - break; - - case RegexCode.Capturemark: - //: if (!IsMatched(Operand(1))) - //: break Backward; - //: Stackframe(1); - //: if (Operand(1) != -1) - //: TransferCapture(Operand(0), Operand(1), Stacked(0), Textpos()); - //: else - //: Capture(Operand(0), Stacked(0), Textpos()); - //: Track(Stacked(0)); - - //: Stackframe(1); - //: Capture(Operand(0), Stacked(0), Textpos()); - //: Track(Stacked(0)); - - if (Operand(1) != -1) - { - Ldthis(); - Ldc(Operand(1)); - Callvirt(_ismatchedM); - BrfalseFar(_backtrack); - } - - PopStack(); - Stloc(_tempV); - - if (Operand(1) != -1) - { - Ldthis(); - Ldc(Operand(0)); - Ldc(Operand(1)); - Ldloc(_tempV); - Ldloc(_textposV); - Callvirt(_transferM); - } - else - { - Ldthis(); - Ldc(Operand(0)); - Ldloc(_tempV); - Ldloc(_textposV); - Callvirt(_captureM); - } - - PushTrack(_tempV); - - if (Operand(0) != -1 && Operand(1) != -1) - TrackUnique(capback2); - else - TrackUnique(capback); - - break; - - - case RegexCode.Capturemark | RegexCode.Back: - //: Trackframe(1); - //: Stack(Tracked(0)); - //: Uncapture(); - //: if (Operand(0) != -1 && Operand(1) != -1) - //: Uncapture(); - //: break Backward; - ReadyPushStack(); - PopTrack(); - DoPush(); - Ldthis(); - Callvirt(_uncaptureM); - if (Operand(0) != -1 && Operand(1) != -1) - { - Ldthis(); - Callvirt(_uncaptureM); - } - Back(); - break; - - case RegexCode.Branchmark: - //: Stackframe(1); - //: - //: if (Textpos() != Stacked(0)) - //: { // Nonempty match -> loop now - //: Track(Stacked(0), Textpos()); // Save old mark, textpos - //: Stack(Textpos()); // Make new mark - //: Goto(Operand(0)); // Loop - //: } - //: else - //: { // Empty match -> straight now - //: Track2(Stacked(0)); // Save old mark - //: Advance(1); // Straight - //: } - //: continue Forward; - { - LocalBuilder mark = _tempV; - Label l1 = DefineLabel(); - - PopStack(); - Dup(); - Stloc(mark); // Stacked(0) -> temp - PushTrack(mark); - Ldloc(_textposV); - Beq(l1); // mark == textpos -> branch - - // (matched != 0) - - PushTrack(_textposV); - PushStack(_textposV); - Track(); - Goto(Operand(0)); // Goto(Operand(0)) - - // else - - MarkLabel(l1); - TrackUnique2(branchmarkback2); - break; - } - - case RegexCode.Branchmark | RegexCode.Back: - //: Trackframe(2); - //: Stackframe(1); - //: Textto(Tracked(1)); // Recall position - //: Track2(Tracked(0)); // Save old mark - //: Advance(1); - PopTrack(); - Stloc(_textposV); - PopStack(); - Pop(); - // track spot 0 is already in place - TrackUnique2(branchmarkback2); - Advance(); - break; - - case RegexCode.Branchmark | RegexCode.Back2: - //: Trackframe(1); - //: Stack(Tracked(0)); // Recall old mark - //: break Backward; // Backtrack - ReadyPushStack(); - PopTrack(); - DoPush(); - Back(); - break; - - - case RegexCode.Lazybranchmark: - //: Stackframe(1); - //: - //: if (Textpos() != Stacked(0)) - //: { // Nonempty match -> next loop - //: Track(Stacked(0), Textpos()); // Save old mark, textpos - //: } - //: else - //: { // Empty match -> no loop - //: Track2(Stacked(0)); // Save old mark - //: } - //: Advance(1); - //: continue Forward; - { - LocalBuilder mark = _tempV; - Label l1 = DefineLabel(); - - PopStack(); - Dup(); - Stloc(mark); // Stacked(0) -> temp - PushTrack(mark); - Ldloc(_textposV); - Beq(l1); // mark == textpos -> branch - - // (matched != 0) - - PushTrack(_textposV); - Track(); - Br(AdvanceLabel()); // Advance (near) - - // else - - MarkLabel(l1); - TrackUnique2(lazybranchmarkback2); - break; - } - - case RegexCode.Lazybranchmark | RegexCode.Back: - //: Trackframe(2); - //: Track2(Tracked(0)); // Save old mark - //: Stack(Textpos()); // Make new mark - //: Textto(Tracked(1)); // Recall position - //: Goto(Operand(0)); // Loop - - PopTrack(); - Stloc(_textposV); - PushStack(_textposV); - TrackUnique2(lazybranchmarkback2); - Goto(Operand(0)); - break; - - case RegexCode.Lazybranchmark | RegexCode.Back2: - //: Stackframe(1); - //: Trackframe(1); - //: Stack(Tracked(0)); // Recall old mark - //: break Backward; - ReadyReplaceStack(0); - PopTrack(); - DoReplace(); - Back(); - break; - - case RegexCode.Nullcount: - //: Stack(-1, Operand(0)); - //: Track(); - ReadyPushStack(); - Ldc(-1); - DoPush(); - ReadyPushStack(); - Ldc(Operand(0)); - DoPush(); - TrackUnique(stackpop2); - break; - - case RegexCode.Setcount: - //: Stack(Textpos(), Operand(0)); - //: Track(); - PushStack(_textposV); - ReadyPushStack(); - Ldc(Operand(0)); - DoPush(); - TrackUnique(stackpop2); - break; - - - case RegexCode.Nullcount | RegexCode.Back: - case RegexCode.Setcount | RegexCode.Back: - //: Stackframe(2); - //: break Backward; - PopDiscardStack(2); - Back(); - break; - - - case RegexCode.Branchcount: - //: Stackframe(2); - //: int mark = Stacked(0); - //: int count = Stacked(1); - //: - //: if (count >= Operand(1) || Textpos() == mark && count >= 0) - //: { // Max loops or empty match -> straight now - //: Track2(mark, count); // Save old mark, count - //: Advance(2); // Straight - //: } - //: else - //: { // Nonempty match -> count+loop now - //: Track(mark); // remember mark - //: Stack(Textpos(), count + 1); // Make new mark, incr count - //: Goto(Operand(0)); // Loop - //: } - //: continue Forward; - { - LocalBuilder count = _tempV; - LocalBuilder mark = _temp2V; - Label l1 = DefineLabel(); - Label l2 = DefineLabel(); - - PopStack(); - Stloc(count); // count -> temp - PopStack(); - Dup(); - Stloc(mark); // mark -> temp2 - PushTrack(mark); - - Ldloc(_textposV); - Bne(l1); // mark != textpos -> l1 - Ldloc(count); - Ldc(0); - Bge(l2); // count >= 0 && mark == textpos -> l2 - - MarkLabel(l1); - Ldloc(count); - Ldc(Operand(1)); - Bge(l2); // count >= Operand(1) -> l2 - - // else - PushStack(_textposV); - ReadyPushStack(); - Ldloc(count); // mark already on track - Ldc(1); - Add(); - DoPush(); - Track(); - Goto(Operand(0)); - - // if (count >= Operand(1) || Textpos() == mark) - MarkLabel(l2); - PushTrack(count); // mark already on track - TrackUnique2(branchcountback2); - break; - } - - case RegexCode.Branchcount | RegexCode.Back: - //: Trackframe(1); - //: Stackframe(2); - //: if (Stacked(1) > 0) // Positive -> can go straight - //: { - //: Textto(Stacked(0)); // Zap to mark - //: Track2(Tracked(0), Stacked(1) - 1); // Save old mark, old count - //: Advance(2); // Straight - //: continue Forward; - //: } - //: Stack(Tracked(0), Stacked(1) - 1); // recall old mark, old count - //: break Backward; - { - - LocalBuilder count = _tempV; - Label l1 = DefineLabel(); - PopStack(); - Ldc(1); - Sub(); - Dup(); - Stloc(count); - Ldc(0); - Blt(l1); - - // if (count >= 0) - PopStack(); - Stloc(_textposV); - PushTrack(count); // Tracked(0) is alredy on the track - TrackUnique2(branchcountback2); - Advance(); - - // else - MarkLabel(l1); - ReadyReplaceStack(0); - PopTrack(); - DoReplace(); - PushStack(count); - Back(); - break; - } - - case RegexCode.Branchcount | RegexCode.Back2: - //: Trackframe(2); - //: Stack(Tracked(0), Tracked(1)); // Recall old mark, old count - //: break Backward; // Backtrack - - PopTrack(); - Stloc(_tempV); - ReadyPushStack(); - PopTrack(); - DoPush(); - PushStack(_tempV); - Back(); - break; - - case RegexCode.Lazybranchcount: - //: Stackframe(2); - //: int mark = Stacked(0); - //: int count = Stacked(1); - //: - //: if (count < 0) - //: { // Negative count -> loop now - //: Track2(mark); // Save old mark - //: Stack(Textpos(), count + 1); // Make new mark, incr count - //: Goto(Operand(0)); // Loop - //: } - //: else - //: { // Nonneg count or empty match -> straight now - //: Track(mark, count, Textpos()); // Save mark, count, position - //: } - { - LocalBuilder count = _tempV; - LocalBuilder mark = _temp2V; - Label l1 = DefineLabel(); - Label l2 = DefineLabel(); - Label l3 = _labels[NextCodepos()]; - - PopStack(); - Stloc(count); // count -> temp - PopStack(); - Stloc(mark); // mark -> temp2 - - Ldloc(count); - Ldc(0); - Bge(l1); // count >= 0 -> l1 - - // if (count < 0) - PushTrack(mark); - PushStack(_textposV); - ReadyPushStack(); - Ldloc(count); - Ldc(1); - Add(); - DoPush(); - TrackUnique2(lazybranchcountback2); - Goto(Operand(0)); - - // else - MarkLabel(l1); - PushTrack(mark); - PushTrack(count); - PushTrack(_textposV); - Track(); - break; - } - - case RegexCode.Lazybranchcount | RegexCode.Back: - //: Trackframe(3); - //: int mark = Tracked(0); - //: int textpos = Tracked(2); - //: if (Tracked(1) <= Operand(1) && textpos != mark) - //: { - //: Textto(Tracked(2)); // Recall position - //: Stack(Textpos(), Tracked(1) + 1); // Make new mark, incr count - //: Track2(Tracked(0)); // Save old mark - //: Goto(Operand(0)); // Loop - //: continue Forward; - //: } - //: else - //: { - //: Stack(Tracked(0), Tracked(1)); // Recall old mark, count - //: break Backward; // backtrack - //: } - { - Label l1 = DefineLabel(); - LocalBuilder cV = _tempV; - PopTrack(); - Stloc(_textposV); - PopTrack(); - Dup(); - Stloc(cV); - Ldc(Operand(1)); - Bgt(l1); // Tracked(1) > Operand(1) -> l1 - - Ldloc(_textposV); - TopTrack(); - Beq(l1); // textpos == mark -> l1 - - PushStack(_textposV); - ReadyPushStack(); - Ldloc(cV); - Ldc(1); - Add(); - DoPush(); - TrackUnique2(lazybranchcountback2); - Goto(Operand(0)); - - MarkLabel(l1); - ReadyPushStack(); - PopTrack(); - DoPush(); - PushStack(cV); - Back(); - break; - } - - case RegexCode.Lazybranchcount | RegexCode.Back2: - //: Trackframe(1); - //: Stackframe(2); - //: Stack(Tracked(0), Stacked(1) - 1); // Recall old mark, count - //: break Backward; // Backtrack - - ReadyReplaceStack(1); - PopTrack(); - DoReplace(); - ReadyReplaceStack(0); - TopStack(); - Ldc(1); - Sub(); - DoReplace(); - Back(); - break; - - - case RegexCode.Setjump: - //: Stack(Trackpos(), Crawlpos()); - //: Track(); - ReadyPushStack(); - Ldthisfld(_trackF); - Ldlen(); - Ldloc(_trackposV); - Sub(); - DoPush(); - ReadyPushStack(); - Ldthis(); - Callvirt(_crawlposM); - DoPush(); - TrackUnique(stackpop2); - break; - - case RegexCode.Setjump | RegexCode.Back: - //: Stackframe(2); - PopDiscardStack(2); - Back(); - break; - - - case RegexCode.Backjump: - //: Stackframe(2); - //: Trackto(Stacked(0)); - //: while (Crawlpos() != Stacked(1)) - //: Uncapture(); - //: break Backward; - { - Label l1 = DefineLabel(); - Label l2 = DefineLabel(); - - PopStack(); - Ldthisfld(_trackF); - Ldlen(); - PopStack(); - Sub(); - Stloc(_trackposV); - Dup(); - Ldthis(); - Callvirt(_crawlposM); - Beq(l2); - - MarkLabel(l1); - Ldthis(); - Callvirt(_uncaptureM); - Dup(); - Ldthis(); - Callvirt(_crawlposM); - Bne(l1); - - MarkLabel(l2); - Pop(); - Back(); - break; - } - - case RegexCode.Forejump: - //: Stackframe(2); - //: Trackto(Stacked(0)); - //: Track(Stacked(1)); - PopStack(); - Stloc(_tempV); - Ldthisfld(_trackF); - Ldlen(); - PopStack(); - Sub(); - Stloc(_trackposV); - PushTrack(_tempV); - TrackUnique(forejumpback); - break; - - case RegexCode.Forejump | RegexCode.Back: - //: Trackframe(1); - //: while (Crawlpos() != Tracked(0)) - //: Uncapture(); - //: break Backward; - { - Label l1 = DefineLabel(); - Label l2 = DefineLabel(); - - PopTrack(); - - Dup(); - Ldthis(); - Callvirt(_crawlposM); - Beq(l2); - - MarkLabel(l1); - Ldthis(); - Callvirt(_uncaptureM); - Dup(); - Ldthis(); - Callvirt(_crawlposM); - Bne(l1); - - MarkLabel(l2); - Pop(); - Back(); - break; - } - - case RegexCode.Bol: - //: if (Leftchars() > 0 && CharAt(Textpos() - 1) != '\n') - //: break Backward; - { - Label l1 = _labels[NextCodepos()]; - Ldloc(_textposV); - Ldloc(_textbegV); - Ble(l1); - Leftchar(); - Ldc((int)'\n'); - BneFar(_backtrack); - break; - } - - case RegexCode.Eol: - //: if (Rightchars() > 0 && CharAt(Textpos()) != '\n') - //: break Backward; - { - Label l1 = _labels[NextCodepos()]; - Ldloc(_textposV); - Ldloc(_textendV); - Bge(l1); - Rightchar(); - Ldc((int)'\n'); - BneFar(_backtrack); - break; - } - - case RegexCode.Boundary: - case RegexCode.Nonboundary: - //: if (!IsBoundary(Textpos(), _textbeg, _textend)) - //: break Backward; - Ldthis(); - Ldloc(_textposV); - Ldloc(_textbegV); - Ldloc(_textendV); - Callvirt(_isboundaryM); - if (Code() == RegexCode.Boundary) - BrfalseFar(_backtrack); - else - BrtrueFar(_backtrack); - break; - - case RegexCode.ECMABoundary: - case RegexCode.NonECMABoundary: - //: if (!IsECMABoundary(Textpos(), _textbeg, _textend)) - //: break Backward; - Ldthis(); - Ldloc(_textposV); - Ldloc(_textbegV); - Ldloc(_textendV); - Callvirt(_isECMABoundaryM); - if (Code() == RegexCode.ECMABoundary) - BrfalseFar(_backtrack); - else - BrtrueFar(_backtrack); - break; - - case RegexCode.Beginning: - //: if (Leftchars() > 0) - //: break Backward; - Ldloc(_textposV); - Ldloc(_textbegV); - BgtFar(_backtrack); - break; - - case RegexCode.Start: - //: if (Textpos() != Textstart()) - //: break Backward; - Ldloc(_textposV); - Ldthisfld(_textstartF); - BneFar(_backtrack); - break; - - case RegexCode.EndZ: - //: if (Rightchars() > 1 || Rightchars() == 1 && CharAt(Textpos()) != '\n') - //: break Backward; - Ldloc(_textposV); - Ldloc(_textendV); - Ldc(1); - Sub(); - BltFar(_backtrack); - Ldloc(_textposV); - Ldloc(_textendV); - Bge(_labels[NextCodepos()]); - Rightchar(); - Ldc((int)'\n'); - BneFar(_backtrack); - break; - - case RegexCode.End: - //: if (Rightchars() > 0) - //: break Backward; - Ldloc(_textposV); - Ldloc(_textendV); - BltFar(_backtrack); - break; - - case RegexCode.One: - case RegexCode.Notone: - case RegexCode.Set: - case RegexCode.One | RegexCode.Rtl: - case RegexCode.Notone | RegexCode.Rtl: - case RegexCode.Set | RegexCode.Rtl: - case RegexCode.One | RegexCode.Ci: - case RegexCode.Notone | RegexCode.Ci: - case RegexCode.Set | RegexCode.Ci: - case RegexCode.One | RegexCode.Ci | RegexCode.Rtl: - case RegexCode.Notone | RegexCode.Ci | RegexCode.Rtl: - case RegexCode.Set | RegexCode.Ci | RegexCode.Rtl: - - //: if (Rightchars() < 1 || Rightcharnext() != (char)Operand(0)) - //: break Backward; - Ldloc(_textposV); - - if (!IsRtl()) - { - Ldloc(_textendV); - BgeFar(_backtrack); - Rightcharnext(); - } - else - { - Ldloc(_textbegV); - BleFar(_backtrack); - Leftcharnext(); - } - - if (IsCi()) - CallToLower(); - - if (Code() == RegexCode.Set) - { - - Ldstr(_strings[Operand(0)]); - Ldstr(_strings[Operand(1)]); - Call(_charInSetM); - - BrfalseFar(_backtrack); - } - else - { - Ldc(Operand(0)); - if (Code() == RegexCode.One) - BneFar(_backtrack); - else - BeqFar(_backtrack); - } - break; - - case RegexCode.Multi: - case RegexCode.Multi | RegexCode.Ci: - // - // - - //: String Str = _strings[Operand(0)]; - //: int i, c; - //: if (Rightchars() < (c = Str.Length)) - //: break Backward; - //: for (i = 0; c > 0; i++, c--) - //: if (Str[i] != Rightcharnext()) - //: break Backward; - { - int i; - String str; - - str = _strings[Operand(0)]; - - Ldc(str.Length); - Ldloc(_textendV); - Ldloc(_textposV); - Sub(); - BgtFar(_backtrack); - - // unroll the string - for (i = 0; i < str.Length; i++) - { - Ldloc(_textV); - Ldloc(_textposV); - if (i != 0) - { - Ldc(i); - Add(); - } - Callvirt(_getcharM); - if (IsCi()) - CallToLower(); - - Ldc((int)str[i]); - BneFar(_backtrack); - } - - Ldloc(_textposV); - Ldc(str.Length); - Add(); - Stloc(_textposV); - break; - } - - - case RegexCode.Multi | RegexCode.Rtl: - case RegexCode.Multi | RegexCode.Ci | RegexCode.Rtl: - //: String Str = _strings[Operand(0)]; - //: int c; - //: if (Leftchars() < (c = Str.Length)) - //: break Backward; - //: while (c > 0) - //: if (Str[--c] != Leftcharnext()) - //: break Backward; - { - int i; - String str; - - str = _strings[Operand(0)]; - - Ldc(str.Length); - Ldloc(_textposV); - Ldloc(_textbegV); - Sub(); - BgtFar(_backtrack); - - // unroll the string - for (i = str.Length; i > 0; ) - { - i--; - Ldloc(_textV); - Ldloc(_textposV); - Ldc(str.Length - i); - Sub(); - Callvirt(_getcharM); - if (IsCi()) - { - CallToLower(); - } - Ldc((int)str[i]); - BneFar(_backtrack); - } - - Ldloc(_textposV); - Ldc(str.Length); - Sub(); - Stloc(_textposV); - - break; - } - - case RegexCode.Ref: - case RegexCode.Ref | RegexCode.Rtl: - case RegexCode.Ref | RegexCode.Ci: - case RegexCode.Ref | RegexCode.Ci | RegexCode.Rtl: - //: int capnum = Operand(0); - //: int j, c; - //: if (!_match.IsMatched(capnum)) { - //: #if ECMA - //: if (!RegexOptions.ECMAScript) - //: #endif - //: break Backward; - //: } else { - //: if (Rightchars() < (c = _match.MatchLength(capnum))) - //: break Backward; - //: for (j = _match.MatchIndex(capnum); c > 0; j++, c--) - //: if (CharAt(j) != Rightcharnext()) - //: break Backward; - //: } - { - LocalBuilder lenV = _tempV; - LocalBuilder indexV = _temp2V; - Label l1 = DefineLabel(); - - Ldthis(); - Ldc(Operand(0)); - Callvirt(_ismatchedM); - if ((_options & RegexOptions.ECMAScript) != 0) - Brfalse(AdvanceLabel()); - else - BrfalseFar(_backtrack); // !IsMatched() -> back - - Ldthis(); - Ldc(Operand(0)); - Callvirt(_matchlengthM); - Dup(); - Stloc(lenV); - if (!IsRtl()) - { - Ldloc(_textendV); - Ldloc(_textposV); - } - else - { - Ldloc(_textposV); - Ldloc(_textbegV); - } - Sub(); - BgtFar(_backtrack); // Matchlength() > Rightchars() -> back - - Ldthis(); - Ldc(Operand(0)); - Callvirt(_matchindexM); - if (!IsRtl()) - { - Ldloc(lenV); - Add(IsRtl()); - } - Stloc(indexV); // index += len - - Ldloc(_textposV); - Ldloc(lenV); - Add(IsRtl()); - Stloc(_textposV); // texpos += len - - MarkLabel(l1); - Ldloc(lenV); - Ldc(0); - Ble(AdvanceLabel()); - Ldloc(_textV); - Ldloc(indexV); - Ldloc(lenV); - if (IsRtl()) - { - Ldc(1); - Sub(); - Dup(); - Stloc(lenV); - } - Sub(IsRtl()); - Callvirt(_getcharM); - if (IsCi()) - CallToLower(); - - Ldloc(_textV); - Ldloc(_textposV); - Ldloc(lenV); - if (!IsRtl()) - { - Dup(); - Ldc(1); - Sub(); - Stloc(lenV); - } - Sub(IsRtl()); - Callvirt(_getcharM); - if (IsCi()) - CallToLower(); - - Beq(l1); - Back(); - break; - } - - - case RegexCode.Onerep: - case RegexCode.Notonerep: - case RegexCode.Setrep: - case RegexCode.Onerep | RegexCode.Rtl: - case RegexCode.Notonerep | RegexCode.Rtl: - case RegexCode.Setrep | RegexCode.Rtl: - case RegexCode.Onerep | RegexCode.Ci: - case RegexCode.Notonerep | RegexCode.Ci: - case RegexCode.Setrep | RegexCode.Ci: - case RegexCode.Onerep | RegexCode.Ci | RegexCode.Rtl: - case RegexCode.Notonerep | RegexCode.Ci | RegexCode.Rtl: - case RegexCode.Setrep | RegexCode.Ci | RegexCode.Rtl: - //: int c = Operand(1); - //: if (Rightchars() < c) - //: break Backward; - //: char ch = (char)Operand(0); - //: while (c-- > 0) - //: if (Rightcharnext() != ch) - //: break Backward; - { - LocalBuilder lenV = _tempV; - Label l1 = DefineLabel(); - - int c = (Code() == RegexCode.Setrep) ? Operand(2) : Operand(1); - - if (c == 0) - break; - - Ldc(c); - if (!IsRtl()) - { - Ldloc(_textendV); - Ldloc(_textposV); - } - else - { - Ldloc(_textposV); - Ldloc(_textbegV); - } - Sub(); - BgtFar(_backtrack); // Matchlength() > Rightchars() -> back - - Ldloc(_textposV); - Ldc(c); - Add(IsRtl()); - Stloc(_textposV); // texpos += len - - Ldc(c); - Stloc(lenV); - - MarkLabel(l1); - Ldloc(_textV); - Ldloc(_textposV); - Ldloc(lenV); - if (IsRtl()) - { - Ldc(1); - Sub(); - Dup(); - Stloc(lenV); - Add(); - } - else - { - Dup(); - Ldc(1); - Sub(); - Stloc(lenV); - Sub(); - } - Callvirt(_getcharM); - if (IsCi()) - CallToLower(); - - if (Code() == RegexCode.Setrep) - { - Ldstr(_strings[Operand(0)]); - Ldstr(_strings[Operand(1)]); - Call(_charInSetM); - - BrfalseFar(_backtrack); - } - else - { - Ldc(Operand(0)); - if (Code() == RegexCode.Onerep) - BneFar(_backtrack); - else - BeqFar(_backtrack); - } - Ldloc(lenV); - Ldc(0); - if (Code() == RegexCode.Setrep) - BgtFar(l1); - else - Bgt(l1); - break; - } - - - case RegexCode.Oneloop: - case RegexCode.Notoneloop: - case RegexCode.Setloop: - case RegexCode.Oneloop | RegexCode.Rtl: - case RegexCode.Notoneloop | RegexCode.Rtl: - case RegexCode.Setloop | RegexCode.Rtl: - case RegexCode.Oneloop | RegexCode.Ci: - case RegexCode.Notoneloop | RegexCode.Ci: - case RegexCode.Setloop | RegexCode.Ci: - case RegexCode.Oneloop | RegexCode.Ci | RegexCode.Rtl: - case RegexCode.Notoneloop | RegexCode.Ci | RegexCode.Rtl: - case RegexCode.Setloop | RegexCode.Ci | RegexCode.Rtl: - //: int c = Operand(1); - //: if (c > Rightchars()) - //: c = Rightchars(); - //: char ch = (char)Operand(0); - //: int i; - //: for (i = c; i > 0; i--) - //: { - //: if (Rightcharnext() != ch) - //: { - //: Leftnext(); - //: break; - //: } - //: } - //: if (c > i) - //: Track(c - i - 1, Textpos() - 1); - { - LocalBuilder cV = _tempV; - LocalBuilder lenV = _temp2V; - Label l1 = DefineLabel(); - Label l2 = DefineLabel(); - - int c = (Code() == RegexCode.Setloop) ? Operand(2) : Operand(1); - - if (c == 0) - break; - if (!IsRtl()) - { - Ldloc(_textendV); - Ldloc(_textposV); - } - else - { - Ldloc(_textposV); - Ldloc(_textbegV); - } - Sub(); - if (c != infinite) - { - Label l4 = DefineLabel(); - Dup(); - Ldc(c); - Blt(l4); - Pop(); - Ldc(c); - MarkLabel(l4); - } - Dup(); - Stloc(lenV); - Ldc(1); - Add(); - Stloc(cV); - - MarkLabel(l1); - Ldloc(cV); - Ldc(1); - Sub(); - Dup(); - Stloc(cV); - Ldc(0); - if (Code() == RegexCode.Setloop) - BleFar(l2); - else - Ble(l2); - - if (IsRtl()) - Leftcharnext(); - else - Rightcharnext(); - if (IsCi()) - CallToLower(); - - if (Code() == RegexCode.Setloop) - { - Ldstr(_strings[Operand(0)]); - Ldstr(_strings[Operand(1)]); - Call(_charInSetM); - - BrtrueFar(l1); - } - else - { - Ldc(Operand(0)); - if (Code() == RegexCode.Oneloop) - Beq(l1); - else - Bne(l1); - } - - Ldloc(_textposV); - Ldc(1); - Sub(IsRtl()); - Stloc(_textposV); - - MarkLabel(l2); - Ldloc(lenV); - Ldloc(cV); - Ble(AdvanceLabel()); - - ReadyPushTrack(); - Ldloc(lenV); - Ldloc(cV); - Sub(); - Ldc(1); - Sub(); - DoPush(); - - ReadyPushTrack(); - Ldloc(_textposV); - Ldc(1); - Sub(IsRtl()); - DoPush(); - - Track(); - break; - } - - case RegexCode.Oneloop | RegexCode.Back: - case RegexCode.Notoneloop | RegexCode.Back: - case RegexCode.Setloop | RegexCode.Back: - case RegexCode.Oneloop | RegexCode.Rtl | RegexCode.Back: - case RegexCode.Notoneloop | RegexCode.Rtl | RegexCode.Back: - case RegexCode.Setloop | RegexCode.Rtl | RegexCode.Back: - case RegexCode.Oneloop | RegexCode.Ci | RegexCode.Back: - case RegexCode.Notoneloop | RegexCode.Ci | RegexCode.Back: - case RegexCode.Setloop | RegexCode.Ci | RegexCode.Back: - case RegexCode.Oneloop | RegexCode.Ci | RegexCode.Rtl | RegexCode.Back: - case RegexCode.Notoneloop | RegexCode.Ci | RegexCode.Rtl | RegexCode.Back: - case RegexCode.Setloop | RegexCode.Ci | RegexCode.Rtl | RegexCode.Back: - //: Trackframe(2); - //: int i = Tracked(0); - //: int pos = Tracked(1); - //: Textto(pos); - //: if (i > 0) - //: Track(i - 1, pos - 1); - //: Advance(2); - PopTrack(); - Stloc(_textposV); - PopTrack(); - Stloc(_tempV); - Ldloc(_tempV); - Ldc(0); - BleFar(AdvanceLabel()); - ReadyPushTrack(); - Ldloc(_tempV); - Ldc(1); - Sub(); - DoPush(); - ReadyPushTrack(); - Ldloc(_textposV); - Ldc(1); - Sub(IsRtl()); - DoPush(); - Trackagain(); - Advance(); - break; - - case RegexCode.Onelazy: - case RegexCode.Notonelazy: - case RegexCode.Setlazy: - case RegexCode.Onelazy | RegexCode.Rtl: - case RegexCode.Notonelazy | RegexCode.Rtl: - case RegexCode.Setlazy | RegexCode.Rtl: - case RegexCode.Onelazy | RegexCode.Ci: - case RegexCode.Notonelazy | RegexCode.Ci: - case RegexCode.Setlazy | RegexCode.Ci: - case RegexCode.Onelazy | RegexCode.Ci | RegexCode.Rtl: - case RegexCode.Notonelazy | RegexCode.Ci | RegexCode.Rtl: - case RegexCode.Setlazy | RegexCode.Ci | RegexCode.Rtl: - //: int c = Operand(1); - //: if (c > Rightchars()) - //: c = Rightchars(); - //: if (c > 0) - //: Track(c - 1, Textpos()); - { - LocalBuilder cV = _tempV; - - int c = (Code() == RegexCode.Setlazy) ? Operand(2) : Operand(1); - - if (c == 0) - break; - - if (!IsRtl()) - { - Ldloc(_textendV); - Ldloc(_textposV); - } - else - { - Ldloc(_textposV); - Ldloc(_textbegV); - } - Sub(); - if (c != infinite) - { - Label l4 = DefineLabel(); - Dup(); - Ldc(c); - Blt(l4); - Pop(); - Ldc(c); - MarkLabel(l4); - } - Dup(); - Stloc(cV); - Ldc(0); - Ble(AdvanceLabel()); - ReadyPushTrack(); - Ldloc(cV); - Ldc(1); - Sub(); - DoPush(); - PushTrack(_textposV); - Track(); - break; - } - - case RegexCode.Onelazy | RegexCode.Back: - case RegexCode.Notonelazy | RegexCode.Back: - case RegexCode.Setlazy | RegexCode.Back: - case RegexCode.Onelazy | RegexCode.Rtl | RegexCode.Back: - case RegexCode.Notonelazy | RegexCode.Rtl | RegexCode.Back: - case RegexCode.Setlazy | RegexCode.Rtl | RegexCode.Back: - case RegexCode.Onelazy | RegexCode.Ci | RegexCode.Back: - case RegexCode.Notonelazy | RegexCode.Ci | RegexCode.Back: - case RegexCode.Setlazy | RegexCode.Ci | RegexCode.Back: - case RegexCode.Onelazy | RegexCode.Ci | RegexCode.Rtl | RegexCode.Back: - case RegexCode.Notonelazy | RegexCode.Ci | RegexCode.Rtl | RegexCode.Back: - case RegexCode.Setlazy | RegexCode.Ci | RegexCode.Rtl | RegexCode.Back: - //: Trackframe(2); - //: int pos = Tracked(1); - //: Textto(pos); - //: if (Rightcharnext() != (char)Operand(0)) - //: break Backward; - //: int i = Tracked(0); - //: if (i > 0) - //: Track(i - 1, pos + 1); - - PopTrack(); - Stloc(_textposV); - PopTrack(); - Stloc(_temp2V); - - if (!IsRtl()) - Rightcharnext(); - else - Leftcharnext(); - - if (IsCi()) - CallToLower(); - - if (Code() == RegexCode.Setlazy) - { - Ldstr(_strings[Operand(0)]); - Ldstr(_strings[Operand(1)]); - Call(_charInSetM); - - BrfalseFar(_backtrack); - } - else - { - Ldc(Operand(0)); - if (Code() == RegexCode.Onelazy) - BneFar(_backtrack); - else - BeqFar(_backtrack); - } - - Ldloc(_temp2V); - Ldc(0); - BleFar(AdvanceLabel()); - ReadyPushTrack(); - Ldloc(_temp2V); - Ldc(1); - Sub(); - DoPush(); - PushTrack(_textposV); - Trackagain(); - Advance(); - break; - - default: - throw new NotImplementedException(SR.GetString(SR.UnimplementedState)); - } - } - } - -} - -- cgit v1.1