예제 #1
0
        protected internal override object GetInstanceIdValue(int id)
        {
            int shifted = id - base.MaxInstanceId;

            if (1 <= shifted && shifted <= MAX_INSTANCE_ID)
            {
                RegExpImpl impl = Impl;
                object     stringResult;
                switch (shifted)
                {
                case Id_multiline:
                case Id_STAR:
                    return(impl.multiline);


                case Id_input:
                case Id_UNDERSCORE:
                    stringResult = impl.input;
                    break;


                case Id_lastMatch:
                case Id_AMPERSAND:
                    stringResult = impl.lastMatch;
                    break;


                case Id_lastParen:
                case Id_PLUS:
                    stringResult = impl.lastParen;
                    break;


                case Id_leftContext:
                case Id_BACK_QUOTE:
                    stringResult = impl.leftContext;
                    break;


                case Id_rightContext:
                case Id_QUOTE:
                    stringResult = impl.rightContext;
                    break;


                default: {
                    // Must be one of $1..$9, convert to 0..8
                    int substring_number = shifted - DOLLAR_ID_BASE - 1;
                    stringResult = impl.getParenSubString(substring_number);
                    break;
                }
                }
                return((stringResult == null) ? "" : stringResult.ToString());
            }
            return(base.GetInstanceIdValue(id));
        }
예제 #2
0
        /// <summary> Analog of do_replace in jsstr.c</summary>
        private static void do_replace(GlobData rdata, Context cx, RegExpImpl regExpImpl)
        {
            System.Text.StringBuilder charBuf = rdata.charBuf;
            int    cp = 0;
            string da = rdata.repstr;
            int    dp = rdata.dollar;

            if (dp != -1)
            {
                int [] skip = new int [1];
                do
                {
                    int len = dp - cp;
                    charBuf.Append(da.Substring(cp, (dp) - (cp)));
                    cp = dp;
                    SubString sub = interpretDollar(cx, regExpImpl, da, dp, skip);
                    if (sub != null)
                    {
                        len = sub.length;
                        if (len > 0)
                        {
                            charBuf.Append(sub.charArray, sub.index, len);
                        }
                        cp += skip [0];
                        dp += skip [0];
                    }
                    else
                    {
                        ++dp;
                    }
                    dp = da.IndexOf((char)'$', dp);
                }while (dp >= 0);
            }
            int daL = da.Length;

            if (daL > cp)
            {
                charBuf.Append(da.Substring(cp, (daL) - (cp)));
            }
        }
예제 #3
0
        /// <summary> Analog of C match_or_replace.</summary>
        private static object matchOrReplace (Context cx, IScriptable scope, IScriptable thisObj, object [] args, RegExpImpl reImpl, GlobData data, bool forceFlat)
        {
            BuiltinRegExp re;

            string str = ScriptConvert.ToString (thisObj);
            data.str = str;
            IScriptable topScope = ScriptableObject.GetTopLevelScope (scope);

            if (args.Length == 0) {
                object compiled = BuiltinRegExp.compileRE ("", "", false);
                re = new BuiltinRegExp (topScope, compiled);
            }
            else if (args [0] is BuiltinRegExp) {
                re = (BuiltinRegExp)args [0];
            }
            else {
                string src = ScriptConvert.ToString (args [0]);
                string opt;
                if (data.optarg < args.Length) {
                    args [0] = src;
                    opt = ScriptConvert.ToString (args [data.optarg]);
                }
                else {
                    opt = null;
                }
                object compiled = BuiltinRegExp.compileRE (src, opt, forceFlat);
                re = new BuiltinRegExp (topScope, compiled);
            }
            data.regexp = re;

            data.global = (re.Flags & BuiltinRegExp.JSREG_GLOB) != 0;
            int [] indexp = new int [] { 0 };
            object result = null;
            if (data.mode == EcmaScript.NET.RegExpActions.Search) {
                result = re.executeRegExp (cx, scope, reImpl, str, indexp, BuiltinRegExp.TEST);
                if (result != null && result.Equals (true))
                    result = (int)reImpl.leftContext.length;
                else
                    result = -1;
            }
            else if (data.global) {
                re.lastIndex = 0;
                for (int count = 0; indexp [0] <= str.Length; count++) {
                    result = re.executeRegExp (cx, scope, reImpl, str, indexp, BuiltinRegExp.TEST);
                    if (result == null || !result.Equals (true))
                        break;
                    if (data.mode == EcmaScript.NET.RegExpActions.Match) {
                        match_glob (data, cx, scope, count, reImpl);
                    }
                    else {
                        if (data.mode != EcmaScript.NET.RegExpActions.Replace)
                            Context.CodeBug ();
                        SubString lastMatch = reImpl.lastMatch;
                        int leftIndex = data.leftIndex;
                        int leftlen = lastMatch.index - leftIndex;
                        data.leftIndex = lastMatch.index + lastMatch.length;
                        replace_glob (data, cx, scope, reImpl, leftIndex, leftlen);
                    }
                    if (reImpl.lastMatch.length == 0) {
                        if (indexp [0] == str.Length)
                            break;
                        indexp [0]++;
                    }
                }
            }
            else {
                result = re.executeRegExp (cx, scope, reImpl, str, indexp, ((data.mode == EcmaScript.NET.RegExpActions.Replace) ? BuiltinRegExp.TEST : BuiltinRegExp.MATCH));
            }

            return result;
        }
예제 #4
0
 /// <summary> Analog of do_replace in jsstr.c</summary>
 private static void do_replace (GlobData rdata, Context cx, RegExpImpl regExpImpl)
 {
     System.Text.StringBuilder charBuf = rdata.charBuf;
     int cp = 0;
     string da = rdata.repstr;
     int dp = rdata.dollar;
     if (dp != -1) {
         int [] skip = new int [1];
         do {
             int len = dp - cp;
             charBuf.Append (da.Substring (cp, (dp) - (cp)));
             cp = dp;
             SubString sub = interpretDollar (cx, regExpImpl, da, dp, skip);
             if (sub != null) {
                 len = sub.length;
                 if (len > 0) {
                     charBuf.Append (sub.charArray, sub.index, len);
                 }
                 cp += skip [0];
                 dp += skip [0];
             }
             else {
                 ++dp;
             }
             dp = da.IndexOf ((char)'$', dp);
         }
         while (dp >= 0);
     }
     int daL = da.Length;
     if (daL > cp) {
         charBuf.Append (da.Substring (cp, (daL) - (cp)));
     }
 }
예제 #5
0
        private static SubString interpretDollar (Context cx, RegExpImpl res, string da, int dp, int [] skip)
        {
            char dc;
            int num, tmp;

            if (da [dp] != '$')
                Context.CodeBug ();

            /* Allow a real backslash (literal "\\") to escape "$1" etc. */
            Context.Versions version = cx.Version;
            if (version != Context.Versions.Default && version <= Context.Versions.JS1_4) {
                if (dp > 0 && da [dp - 1] == '\\')
                    return null;
            }
            int daL = da.Length;
            if (dp + 1 >= daL)
                return null;
            /* Interpret all Perl match-induced dollar variables. */
            dc = da [dp + 1];
            if (BuiltinRegExp.isDigit (dc)) {
                int cp;
                if (version != Context.Versions.Default && version <= Context.Versions.JS1_4) {
                    if (dc == '0')
                        return null;
                    /* Check for overflow to avoid gobbling arbitrary decimal digits. */
                    num = 0;
                    cp = dp;
                    while (++cp < daL && BuiltinRegExp.isDigit (dc = da [cp])) {
                        tmp = 10 * num + (dc - '0');
                        if (tmp < num)
                            break;
                        num = tmp;
                    }
                }
                else {
                    /* ECMA 3, 1-9 or 01-99 */
                    int parenCount = (res.parens == null) ? 0 : res.parens.Length;
                    num = dc - '0';
                    if (num > parenCount)
                        return null;
                    cp = dp + 2;
                    if ((dp + 2) < daL) {
                        dc = da [dp + 2];
                        if (BuiltinRegExp.isDigit (dc)) {
                            tmp = 10 * num + (dc - '0');
                            if (tmp <= parenCount) {
                                cp++;
                                num = tmp;
                            }
                        }
                    }
                    if (num == 0)
                        return null; /* $0 or $00 is not valid */
                }
                /* Adjust num from 1 $n-origin to 0 array-index-origin. */
                num--;
                skip [0] = cp - dp;
                return res.getParenSubString (num);
            }

            skip [0] = 2;
            switch (dc) {

                case '$':
                    return new SubString ("$");

                case '&':
                    return res.lastMatch;

                case '+':
                    return res.lastParen;

                case '`':
                    if (version == Context.Versions.JS1_2) {
                        /*
                        * JS1.2 imitated the Perl4 bug where left context at each step
                        * in an iterative use of a global regexp started from last match,
                        * not from the start of the target string.  But Perl4 does start
                        * $` at the beginning of the target string when it is used in a
                        * substitution, so we emulate that special case here.
                        */
                        res.leftContext.index = 0;
                        res.leftContext.length = res.lastMatch.index;
                    }
                    return res.leftContext;

                case '\'':
                    return res.rightContext;
            }
            return null;
        }
예제 #6
0
        /*
        * Analog of replace_glob() in jsstr.c
        */
        private static void replace_glob (GlobData rdata, Context cx, IScriptable scope, RegExpImpl reImpl, int leftIndex, int leftlen)
        {
            int replen;
            string lambdaStr;
            if (rdata.lambda != null) {
                // invoke lambda function with args lastMatch, $1, $2, ... $n,
                // leftContext.length, whole string.
                SubString [] parens = reImpl.parens;
                int parenCount = (parens == null) ? 0 : parens.Length;
                object [] args = new object [parenCount + 3];
                args [0] = reImpl.lastMatch.ToString ();
                for (int i = 0; i < parenCount; i++) {
                    SubString sub = parens [i];
                    if (sub != null) {
                        args [i + 1] = sub.ToString ();
                    }
                    else {
                        args [i + 1] = Undefined.Value;
                    }
                }
                args [parenCount + 1] = (int)reImpl.leftContext.length;
                args [parenCount + 2] = rdata.str;
                // This is a hack to prevent expose of reImpl data to
                // JS function which can run new regexps modifing
                // regexp that are used later by the engine.
                // TODO: redesign is necessary
                if (reImpl != cx.RegExpProxy)
                    Context.CodeBug ();
                RegExpImpl re2 = new RegExpImpl ();
                re2.multiline = reImpl.multiline;
                re2.input = reImpl.input;
                cx.RegExpProxy = re2;
                try {
                    IScriptable parent = ScriptableObject.GetTopLevelScope (scope);
                    object result = rdata.lambda.Call (cx, parent, parent, args);
                    lambdaStr = ScriptConvert.ToString (result);
                }
                finally {
                    cx.RegExpProxy = reImpl;
                }
                replen = lambdaStr.Length;
            }
            else {
                lambdaStr = null;
                replen = rdata.repstr.Length;
                if (rdata.dollar >= 0) {
                    int [] skip = new int [1];
                    int dp = rdata.dollar;
                    do {
                        SubString sub = interpretDollar (cx, reImpl, rdata.repstr, dp, skip);
                        if (sub != null) {
                            replen += sub.length - skip [0];
                            dp += skip [0];
                        }
                        else {
                            ++dp;
                        }
                        dp = rdata.repstr.IndexOf ((char)'$', dp);
                    }
                    while (dp >= 0);
                }
            }

            int growth = leftlen + replen + reImpl.rightContext.length;
            System.Text.StringBuilder charBuf = rdata.charBuf;
            if (charBuf == null) {
                charBuf = new System.Text.StringBuilder (growth);
                rdata.charBuf = charBuf;
            }
            else {
                charBuf.EnsureCapacity (rdata.charBuf.Length + growth);
            }

            charBuf.Append (reImpl.leftContext.charArray, leftIndex, leftlen);
            if (rdata.lambda != null) {
                charBuf.Append (lambdaStr);
            }
            else {
                do_replace (rdata, cx, reImpl);
            }
        }
예제 #7
0
 /*
 * Analog of match_glob() in jsstr.c
 */
 private static void match_glob (GlobData mdata, Context cx, IScriptable scope, int count, RegExpImpl reImpl)
 {
     if (mdata.arrayobj == null) {
         IScriptable s = ScriptableObject.GetTopLevelScope (scope);
         mdata.arrayobj = ScriptRuntime.NewObject (cx, s, "Array", null);
     }
     SubString matchsub = reImpl.lastMatch;
     string matchstr = matchsub.ToString ();
     mdata.arrayobj.Put (count, mdata.arrayobj, matchstr);
 }
예제 #8
0
        /*
        * indexp is assumed to be an array of length 1
        */
        internal virtual object executeRegExp(Context cx, IScriptable scopeObj, RegExpImpl res, string str, int [] indexp, int matchType)
        {
            REGlobalData gData = new REGlobalData ();

            int start = indexp [0];
            char [] charArray = str.ToCharArray ();
            int end = charArray.Length;
            if (start > end)
                start = end;
            //
            // Call the recursive matcher to do the real work.
            //
            bool matches = matchRegExp (gData, re, charArray, start, end, res.multiline);
            if (!matches) {
                if (matchType != PREFIX)
                    return null;
                return Undefined.Value;
            }
            int index = gData.cp;
            int i = index;
            indexp [0] = i;
            int matchlen = i - (start + gData.skipped);
            int ep = index;
            index -= matchlen;
            object result;
            IScriptable obj;

            if (matchType == TEST) {
                /*
                * Testing for a match and updating cx.regExpImpl: don't allocate
                * an array object, do return true.
                */
                result = true;
                obj = null;
            }
            else {
                /*
                * The array returned on match has element 0 bound to the matched
                * string, elements 1 through re.parenCount bound to the paren
                * matches, an index property telling the length of the left context,
                * and an input property referring to the input string.
                */
                IScriptable scope = GetTopLevelScope (scopeObj);
                result = ScriptRuntime.NewObject (cx, scope, "Array", null);
                obj = (IScriptable)result;

                string matchstr = new string (charArray, index, matchlen);
                obj.Put (0, obj, matchstr);
            }

            if (re.parenCount == 0) {
                res.parens = null;
                res.lastParen = SubString.EmptySubString;
            }
            else {
                SubString parsub = null;
                int num;
                res.parens = new SubString [re.parenCount];
                for (num = 0; num < re.parenCount; num++) {
                    int cap_index = gData.parens_index (num);
                    string parstr;
                    if (cap_index != -1) {
                        int cap_length = gData.parens_length (num);
                        parsub = new SubString (charArray, cap_index, cap_length);
                        res.parens [num] = parsub;
                        if (matchType == TEST)
                            continue;
                        parstr = parsub.ToString ();
                        obj.Put (num + 1, obj, parstr);
                    }
                    else {
                        if (matchType != TEST)
                            obj.Put (num + 1, obj, Undefined.Value);
                    }
                }
                res.lastParen = parsub;
            }

            if (!(matchType == TEST)) {
                /*
                * Define the index and input properties last for better for/in loop
                * order (so they come after the elements).
                */
                obj.Put ("index", obj, (object)(start + gData.skipped));
                obj.Put ("input", obj, str);
            }

            if (res.lastMatch == null) {
                res.lastMatch = new SubString ();
                res.leftContext = new SubString ();
                res.rightContext = new SubString ();
            }
            res.lastMatch.charArray = charArray;
            res.lastMatch.index = index;
            res.lastMatch.length = matchlen;

            res.leftContext.charArray = charArray;
            if (cx.Version == Context.Versions.JS1_2) {
                /*
                * JS1.2 emulated Perl4.0.1.8 (patch level 36) for global regexps used
                * in scalar contexts, and unintentionally for the string.match "list"
                * psuedo-context.  On "hi there bye", the following would result:
                *
                * Language     while(/ /g){print("$`");}   s/ /$`/g
                * perl4.036    "hi", "there"               "hihitherehi therebye"
                * perl5        "hi", "hi there"            "hihitherehi therebye"
                * js1.2        "hi", "there"               "hihitheretherebye"
                *
                * Insofar as JS1.2 always defined $` as "left context from the last
                * match" for global regexps, it was more consistent than perl4.
                */
                res.leftContext.index = start;
                res.leftContext.length = gData.skipped;
            }
            else {
                /*
                * For JS1.3 and ECMAv2, emulate Perl5 exactly:
                *
                * js1.3        "hi", "hi there"            "hihitherehi therebye"
                */
                res.leftContext.index = 0;
                res.leftContext.length = start + gData.skipped;
            }

            res.rightContext.charArray = charArray;
            res.rightContext.index = ep;
            res.rightContext.length = end - ep;

            return result;
        }
예제 #9
0
        private static SubString interpretDollar(Context cx, RegExpImpl res, string da, int dp, int [] skip)
        {
            char dc;
            int  num, tmp;

            if (da [dp] != '$')
            {
                Context.CodeBug();
            }

            /* Allow a real backslash (literal "\\") to escape "$1" etc. */
            Context.Versions version = cx.Version;
            if (version != Context.Versions.Default && version <= Context.Versions.JS1_4)
            {
                if (dp > 0 && da [dp - 1] == '\\')
                {
                    return(null);
                }
            }
            int daL = da.Length;

            if (dp + 1 >= daL)
            {
                return(null);
            }
            /* Interpret all Perl match-induced dollar variables. */
            dc = da [dp + 1];
            if (BuiltinRegExp.isDigit(dc))
            {
                int cp;
                if (version != Context.Versions.Default && version <= Context.Versions.JS1_4)
                {
                    if (dc == '0')
                    {
                        return(null);
                    }
                    /* Check for overflow to avoid gobbling arbitrary decimal digits. */
                    num = 0;
                    cp  = dp;
                    while (++cp < daL && BuiltinRegExp.isDigit(dc = da [cp]))
                    {
                        tmp = 10 * num + (dc - '0');
                        if (tmp < num)
                        {
                            break;
                        }
                        num = tmp;
                    }
                }
                else
                {
                    /* ECMA 3, 1-9 or 01-99 */
                    int parenCount = (res.parens == null) ? 0 : res.parens.Length;
                    num = dc - '0';
                    if (num > parenCount)
                    {
                        return(null);
                    }
                    cp = dp + 2;
                    if ((dp + 2) < daL)
                    {
                        dc = da [dp + 2];
                        if (BuiltinRegExp.isDigit(dc))
                        {
                            tmp = 10 * num + (dc - '0');
                            if (tmp <= parenCount)
                            {
                                cp++;
                                num = tmp;
                            }
                        }
                    }
                    if (num == 0)
                    {
                        return(null); /* $0 or $00 is not valid */
                    }
                }
                /* Adjust num from 1 $n-origin to 0 array-index-origin. */
                num--;
                skip [0] = cp - dp;
                return(res.getParenSubString(num));
            }

            skip [0] = 2;
            switch (dc)
            {
            case '$':
                return(new SubString("$"));

            case '&':
                return(res.lastMatch);

            case '+':
                return(res.lastParen);

            case '`':
                if (version == Context.Versions.JS1_2)
                {
                    /*
                     * JS1.2 imitated the Perl4 bug where left context at each step
                     * in an iterative use of a global regexp started from last match,
                     * not from the start of the target string.  But Perl4 does start
                     * $` at the beginning of the target string when it is used in a
                     * substitution, so we emulate that special case here.
                     */
                    res.leftContext.index  = 0;
                    res.leftContext.length = res.lastMatch.index;
                }
                return(res.leftContext);

            case '\'':
                return(res.rightContext);
            }
            return(null);
        }
예제 #10
0
        /*
         * Analog of replace_glob() in jsstr.c
         */
        private static void replace_glob(GlobData rdata, Context cx, IScriptable scope, RegExpImpl reImpl, int leftIndex, int leftlen)
        {
            int    replen;
            string lambdaStr;

            if (rdata.lambda != null)
            {
                // invoke lambda function with args lastMatch, $1, $2, ... $n,
                // leftContext.length, whole string.
                SubString [] parens     = reImpl.parens;
                int          parenCount = (parens == null) ? 0 : parens.Length;
                object []    args       = new object [parenCount + 3];
                args [0] = reImpl.lastMatch.ToString();
                for (int i = 0; i < parenCount; i++)
                {
                    SubString sub = parens [i];
                    if (sub != null)
                    {
                        args [i + 1] = sub.ToString();
                    }
                    else
                    {
                        args [i + 1] = Undefined.Value;
                    }
                }
                args [parenCount + 1] = (int)reImpl.leftContext.length;
                args [parenCount + 2] = rdata.str;
                // This is a hack to prevent expose of reImpl data to
                // JS function which can run new regexps modifing
                // regexp that are used later by the engine.
                // TODO: redesign is necessary
                if (reImpl != cx.RegExpProxy)
                {
                    Context.CodeBug();
                }
                RegExpImpl re2 = new RegExpImpl();
                re2.multiline  = reImpl.multiline;
                re2.input      = reImpl.input;
                cx.RegExpProxy = re2;
                try {
                    IScriptable parent = ScriptableObject.GetTopLevelScope(scope);
                    object      result = rdata.lambda.Call(cx, parent, parent, args);
                    lambdaStr = ScriptConvert.ToString(result);
                }
                finally {
                    cx.RegExpProxy = reImpl;
                }
                replen = lambdaStr.Length;
            }
            else
            {
                lambdaStr = null;
                replen    = rdata.repstr.Length;
                if (rdata.dollar >= 0)
                {
                    int [] skip = new int [1];
                    int    dp   = rdata.dollar;
                    do
                    {
                        SubString sub = interpretDollar(cx, reImpl, rdata.repstr, dp, skip);
                        if (sub != null)
                        {
                            replen += sub.length - skip [0];
                            dp     += skip [0];
                        }
                        else
                        {
                            ++dp;
                        }
                        dp = rdata.repstr.IndexOf((char)'$', dp);
                    }while (dp >= 0);
                }
            }

            int growth = leftlen + replen + reImpl.rightContext.length;

            System.Text.StringBuilder charBuf = rdata.charBuf;
            if (charBuf == null)
            {
                charBuf       = new System.Text.StringBuilder(growth);
                rdata.charBuf = charBuf;
            }
            else
            {
                charBuf.EnsureCapacity(rdata.charBuf.Length + growth);
            }

            charBuf.Append(reImpl.leftContext.charArray, leftIndex, leftlen);
            if (rdata.lambda != null)
            {
                charBuf.Append(lambdaStr);
            }
            else
            {
                do_replace(rdata, cx, reImpl);
            }
        }
예제 #11
0
        /*
         * Analog of match_glob() in jsstr.c
         */
        private static void match_glob(GlobData mdata, Context cx, IScriptable scope, int count, RegExpImpl reImpl)
        {
            if (mdata.arrayobj == null)
            {
                IScriptable s = ScriptableObject.GetTopLevelScope(scope);
                mdata.arrayobj = ScriptRuntime.NewObject(cx, s, "Array", null);
            }
            SubString matchsub = reImpl.lastMatch;
            string    matchstr = matchsub.ToString();

            mdata.arrayobj.Put(count, mdata.arrayobj, matchstr);
        }
예제 #12
0
        /// <summary> Analog of C match_or_replace.</summary>
        private static object matchOrReplace(Context cx, IScriptable scope, IScriptable thisObj, object [] args, RegExpImpl reImpl, GlobData data, bool forceFlat)
        {
            BuiltinRegExp re;

            string str = ScriptConvert.ToString(thisObj);

            data.str = str;
            IScriptable topScope = ScriptableObject.GetTopLevelScope(scope);

            if (args.Length == 0)
            {
                object compiled = BuiltinRegExp.compileRE("", "", false);
                re = new BuiltinRegExp(topScope, compiled);
            }
            else if (args [0] is BuiltinRegExp)
            {
                re = (BuiltinRegExp)args [0];
            }
            else
            {
                string src = ScriptConvert.ToString(args [0]);
                string opt;
                if (data.optarg < args.Length)
                {
                    args [0] = src;
                    opt      = ScriptConvert.ToString(args [data.optarg]);
                }
                else
                {
                    opt = null;
                }
                object compiled = BuiltinRegExp.compileRE(src, opt, forceFlat);
                re = new BuiltinRegExp(topScope, compiled);
            }
            data.regexp = re;

            data.global = (re.Flags & BuiltinRegExp.JSREG_GLOB) != 0;
            int [] indexp = new int [] { 0 };
            object result = null;

            if (data.mode == EcmaScript.NET.RegExpActions.Search)
            {
                result = re.executeRegExp(cx, scope, reImpl, str, indexp, BuiltinRegExp.TEST);
                if (result != null && result.Equals(true))
                {
                    result = (int)reImpl.leftContext.length;
                }
                else
                {
                    result = -1;
                }
            }
            else if (data.global)
            {
                re.lastIndex = 0;
                for (int count = 0; indexp [0] <= str.Length; count++)
                {
                    result = re.executeRegExp(cx, scope, reImpl, str, indexp, BuiltinRegExp.TEST);
                    if (result == null || !result.Equals(true))
                    {
                        break;
                    }
                    if (data.mode == EcmaScript.NET.RegExpActions.Match)
                    {
                        match_glob(data, cx, scope, count, reImpl);
                    }
                    else
                    {
                        if (data.mode != EcmaScript.NET.RegExpActions.Replace)
                        {
                            Context.CodeBug();
                        }
                        SubString lastMatch = reImpl.lastMatch;
                        int       leftIndex = data.leftIndex;
                        int       leftlen   = lastMatch.index - leftIndex;
                        data.leftIndex = lastMatch.index + lastMatch.length;
                        replace_glob(data, cx, scope, reImpl, leftIndex, leftlen);
                    }
                    if (reImpl.lastMatch.length == 0)
                    {
                        if (indexp [0] == str.Length)
                        {
                            break;
                        }
                        indexp [0]++;
                    }
                }
            }
            else
            {
                result = re.executeRegExp(cx, scope, reImpl, str, indexp, ((data.mode == EcmaScript.NET.RegExpActions.Replace) ? BuiltinRegExp.TEST : BuiltinRegExp.MATCH));
            }

            return(result);
        }