StackMachine.java revision 1088:7e62d98d4625
1141104Sharti/*
294589Sobrien * Permission is hereby granted, free of charge, to any person obtaining a copy of
394589Sobrien * this software and associated documentation files (the "Software"), to deal in
45814Sjkh * the Software without restriction, including without limitation the rights to
51590Srgrimes * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
61590Srgrimes * of the Software, and to permit persons to whom the Software is furnished to do
71590Srgrimes * so, subject to the following conditions:
81590Srgrimes *
91590Srgrimes * The above copyright notice and this permission notice shall be included in all
101590Srgrimes * copies or substantial portions of the Software.
111590Srgrimes *
121590Srgrimes * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
131590Srgrimes * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
141590Srgrimes * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
151590Srgrimes * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
161590Srgrimes * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
171590Srgrimes * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
181590Srgrimes * SOFTWARE.
191590Srgrimes */
201590Srgrimespackage jdk.nashorn.internal.runtime.regexp.joni;
211590Srgrimes
221590Srgrimesimport static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
231590Srgrimesimport java.lang.ref.WeakReference;
241590Srgrimesimport jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel;
251590Srgrimesimport jdk.nashorn.internal.runtime.regexp.joni.constants.StackType;
261590Srgrimes
271590Srgrimesabstract class StackMachine extends Matcher implements StackType {
281590Srgrimes    protected static final int INVALID_INDEX = -1;
291590Srgrimes
301590Srgrimes    protected StackEntry[]stack;
311590Srgrimes    protected int stk;  // stkEnd
321590Srgrimes
331590Srgrimes    protected final int[]repeatStk;
341590Srgrimes    protected final int memStartStk, memEndStk;
351590Srgrimes
361590Srgrimes    protected StackMachine(final Regex regex, final char[] chars, final int p , final int end) {
371590Srgrimes        super(regex, chars, p, end);
3862833Swsanchez
3962833Swsanchez        this.stack = regex.stackNeeded ? fetchStack() : null;
401590Srgrimes        final int n = regex.numRepeat + (regex.numMem << 1);
411590Srgrimes        this.repeatStk = n > 0 ? new int[n] : null;
4262833Swsanchez
4394587Sobrien        memStartStk = regex.numRepeat - 1;
441590Srgrimes        memEndStk   = memStartStk + regex.numMem;
451590Srgrimes        /* for index start from 1, mem_start_stk[1]..mem_start_stk[num_mem] */
461590Srgrimes        /* for index start from 1, mem_end_stk[1]..mem_end_stk[num_mem] */
471590Srgrimes    }
481590Srgrimes
491590Srgrimes    private static StackEntry[] allocateStack() {
50144467Sharti        final StackEntry[]stack = new StackEntry[Config.INIT_MATCH_STACK_SIZE];
511590Srgrimes        stack[0] = new StackEntry();
52144467Sharti        return stack;
53144467Sharti    }
54144467Sharti
55144467Sharti    private void doubleStack() {
56144467Sharti        final StackEntry[] newStack = new StackEntry[stack.length << 1];
57144467Sharti        System.arraycopy(stack, 0, newStack, 0, stack.length);
58144467Sharti        stack = newStack;
591590Srgrimes    }
60144467Sharti
61144467Sharti    static final ThreadLocal<WeakReference<StackEntry[]>> stacks
62144467Sharti            = new ThreadLocal<WeakReference<StackEntry[]>>() {
63144467Sharti        @SuppressWarnings("unused")
64144467Sharti        @Override
651590Srgrimes        protected WeakReference<StackEntry[]> initialValue() {
66144467Sharti            return new WeakReference<StackEntry[]>(allocateStack());
67144467Sharti        }
68144467Sharti    };
69144467Sharti
701590Srgrimes    @SuppressWarnings("unused")
71144467Sharti    private static StackEntry[] fetchStack() {
721590Srgrimes        WeakReference<StackEntry[]> ref = stacks.get();
73144467Sharti        StackEntry[] stack = ref.get();
741590Srgrimes        if (stack == null) {
75144467Sharti            ref = new WeakReference<StackEntry[]>(stack = allocateStack());
76144467Sharti            stacks.set(ref);
77144467Sharti        }
78144467Sharti        return stack;
791590Srgrimes    }
80144467Sharti
81144467Sharti    protected final void init() {
82144467Sharti        if (stack != null) {
831590Srgrimes            pushEnsured(ALT, regex.codeLength - 1); /* bottom stack */
84144467Sharti        }
85144467Sharti        if (repeatStk != null) {
86144467Sharti            for (int i=1; i<=regex.numMem; i++) {
871590Srgrimes                repeatStk[i + memStartStk] = repeatStk[i + memEndStk] = INVALID_INDEX;
88144467Sharti            }
891590Srgrimes        }
90144467Sharti    }
91146132Sharti
92146132Sharti    protected final StackEntry ensure1() {
93146132Sharti        if (stk >= stack.length) {
94146132Sharti            doubleStack();
95146132Sharti        }
96146132Sharti        StackEntry e = stack[stk];
97146132Sharti        if (e == null) {
98146132Sharti            stack[stk] = e = new StackEntry();
99146132Sharti        }
100146132Sharti        return e;
101146132Sharti    }
1021590Srgrimes
1031590Srgrimes    protected final void pushType(final int type) {
104144494Sharti        ensure1().type = type;
1051590Srgrimes        stk++;
106141104Sharti    }
1071590Srgrimes
108107447Sru    private void push(final int type, final int pat, final int s, final int prev) {
109104475Sphk        final StackEntry e = ensure1();
110107447Sru        e.type = type;
1111590Srgrimes        e.setStatePCode(pat);
112141104Sharti        e.setStatePStr(s);
113146160Sjmallett        e.setStatePStrPrev(prev);
11494506Scharnier        stk++;
1155814Sjkh    }
116144665Sharti
1171590Srgrimes    protected final void pushEnsured(final int type, final int pat) {
1185814Sjkh        final StackEntry e = stack[stk];
119141104Sharti        e.type = type;
12080381Ssheldonh        e.setStatePCode(pat);
12194506Scharnier        stk++;
122141104Sharti    }
123141104Sharti
124142457Sharti    protected final void pushAlt(final int pat, final int s, final int prev) {
125146056Sharti        push(ALT, pat, s, prev);
1261590Srgrimes    }
127141104Sharti
128141104Sharti    protected final void pushPos(final int s, final int prev) {
1291590Srgrimes        push(POS, -1 /*NULL_UCHARP*/, s, prev);
130141104Sharti    }
131141104Sharti
132146574Sharti    protected final void pushPosNot(final int pat, final int s, final int prev) {
133146572Sharti        push(POS_NOT, pat, s, prev);
134141104Sharti    }
135146056Sharti
136141104Sharti    protected final void pushStopBT() {
137141104Sharti        pushType(STOP_BT);
138141104Sharti    }
1391590Srgrimes
140146057Sharti    protected final void pushLookBehindNot(final int pat, final int s, final int sprev) {
141146057Sharti        push(LOOK_BEHIND_NOT, pat, s, sprev);
142146057Sharti    }
1431590Srgrimes
144146057Sharti    protected final void pushRepeat(final int id, final int pat) {
145146057Sharti        final StackEntry e = ensure1();
146146057Sharti        e.type = REPEAT;
147146057Sharti        e.setRepeatNum(id);
148146057Sharti        e.setRepeatPCode(pat);
149146057Sharti        e.setRepeatCount(0);
150146057Sharti        stk++;
151146057Sharti    }
152146057Sharti
153144483Sharti    protected final void pushRepeatInc(final int sindex) {
154144483Sharti        final StackEntry e = ensure1();
155144483Sharti        e.type = REPEAT_INC;
156144483Sharti        e.setSi(sindex);
157144483Sharti        stk++;
158144483Sharti    }
159144483Sharti
160144483Sharti    protected final void pushMemStart(final int mnum, final int s) {
161144483Sharti        final StackEntry e = ensure1();
162144483Sharti        e.type = MEM_START;
163144483Sharti        e.setMemNum(mnum);
164144483Sharti        e.setMemPstr(s);
165144665Sharti        e.setMemStart(repeatStk[memStartStk + mnum]);
166144483Sharti        e.setMemEnd(repeatStk[memEndStk + mnum]);
167144483Sharti        repeatStk[memStartStk + mnum] = stk;
168144483Sharti        repeatStk[memEndStk + mnum] = INVALID_INDEX;
169144483Sharti        stk++;
170144483Sharti    }
171144483Sharti
172144483Sharti    protected final void pushMemEnd(final int mnum, final int s) {
173144483Sharti        final StackEntry e = ensure1();
174144483Sharti        e.type = MEM_END;
175144483Sharti        e.setMemNum(mnum);
176144483Sharti        e.setMemPstr(s);
177144483Sharti        e.setMemStart(repeatStk[memStartStk + mnum]);
178144483Sharti        e.setMemEnd(repeatStk[memEndStk + mnum]);
179144483Sharti        repeatStk[memEndStk + mnum] = stk;
180144483Sharti        stk++;
181144483Sharti    }
182144483Sharti
183144483Sharti    protected final void pushMemEndMark(final int mnum) {
184144483Sharti        final StackEntry e = ensure1();
185144483Sharti        e.type = MEM_END_MARK;
186144483Sharti        e.setMemNum(mnum);
187144483Sharti        stk++;
188144483Sharti    }
189144483Sharti
190146061Sharti    protected final int getMemStart(final int mnum) {
191144483Sharti        int level = 0;
192144483Sharti        int stkp = stk;
193144483Sharti
194144483Sharti        while (stkp > 0) {
195144483Sharti            stkp--;
196144483Sharti            final StackEntry e = stack[stkp];
197144483Sharti            if ((e.type & MASK_MEM_END_OR_MARK) != 0 && e.getMemNum() == mnum) {
198144483Sharti                level++;
199144483Sharti            } else if (e.type == MEM_START && e.getMemNum() == mnum) {
200144483Sharti                if (level == 0) {
201144483Sharti                    break;
202144483Sharti                }
203144483Sharti                level--;
204146061Sharti            }
205144483Sharti        }
206144483Sharti        return stkp;
207144483Sharti    }
208144483Sharti
209144483Sharti    protected final void pushNullCheckStart(final int cnum, final int s) {
210144483Sharti        final StackEntry e = ensure1();
211144483Sharti        e.type = NULL_CHECK_START;
212144483Sharti        e.setNullCheckNum(cnum);
213144483Sharti        e.setNullCheckPStr(s);
214144483Sharti        stk++;
215144483Sharti    }
216144483Sharti
217144483Sharti    protected final void pushNullCheckEnd(final int cnum) {
218144483Sharti        final StackEntry e = ensure1();
219144483Sharti        e.type = NULL_CHECK_END;
220144483Sharti        e.setNullCheckNum(cnum);
221144483Sharti        stk++;
222144483Sharti    }
223144483Sharti
224144483Sharti    // stack debug routines here
225144483Sharti    // ...
226144483Sharti
227144483Sharti    protected final void popOne() {
228144483Sharti        stk--;
229144483Sharti    }
230144483Sharti
231144483Sharti    protected final StackEntry pop() {
232144483Sharti        switch (regex.stackPopLevel) {
233144483Sharti        case StackPopLevel.FREE:
234144483Sharti            return popFree();
235144483Sharti        case StackPopLevel.MEM_START:
236144483Sharti            return popMemStart();
237144483Sharti        default:
238144483Sharti            return popDefault();
239144483Sharti        }
240144483Sharti    }
241144483Sharti
242144483Sharti    private StackEntry popFree() {
243144483Sharti        while (true) {
244144483Sharti            final StackEntry e = stack[--stk];
245144483Sharti
246144483Sharti            if ((e.type & MASK_POP_USED) != 0) {
247144483Sharti                return e;
248144483Sharti            }
249144483Sharti        }
250144494Sharti    }
251144494Sharti
252144483Sharti    private StackEntry popMemStart() {
253144483Sharti        while (true) {
254146061Sharti            final StackEntry e = stack[--stk];
255146061Sharti
256144483Sharti            if ((e.type & MASK_POP_USED) != 0) {
257144483Sharti                return e;
258144483Sharti            } else if (e.type == MEM_START) {
259146061Sharti                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
260144483Sharti                repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
261144494Sharti            }
262144494Sharti        }
263144483Sharti    }
2648874Srgrimes
2651590Srgrimes    private StackEntry popDefault() {
266144467Sharti        while (true) {
267144467Sharti            final StackEntry e = stack[--stk];
268144467Sharti
269144467Sharti            if ((e.type & MASK_POP_USED) != 0) {
270144467Sharti                return e;
2711590Srgrimes            } else if (e.type == MEM_START) {
27218730Ssteve                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
27318730Ssteve                repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
27418730Ssteve            } else if (e.type == REPEAT_INC) {
27518730Ssteve                //int si = stack[stk + IREPEAT_INC_SI];
276138232Sharti                //stack[si + IREPEAT_COUNT]--;
2771590Srgrimes                stack[e.getSi()].decreaseRepeatCount();
2781590Srgrimes            } else if (e.type == MEM_END) {
2791590Srgrimes                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
2801590Srgrimes                repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
2811590Srgrimes            }
2821590Srgrimes        }
283144467Sharti    }
2841590Srgrimes
2851590Srgrimes    protected final void popTilPosNot() {
286144467Sharti        while (true) {
287144467Sharti            stk--;
288144467Sharti            final StackEntry e = stack[stk];
289144467Sharti
290144467Sharti            if (e.type == POS_NOT) {
291144467Sharti                break;
2921590Srgrimes            } else if (e.type == MEM_START) {
2931590Srgrimes                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
294144467Sharti                repeatStk[memEndStk + e.getMemNum()] = e.getMemStart();
295146061Sharti            } else if (e.type == REPEAT_INC) {
296144467Sharti                //int si = stack[stk + IREPEAT_INC_SI];
297144467Sharti                //stack[si + IREPEAT_COUNT]--;
2981590Srgrimes                stack[e.getSi()].decreaseRepeatCount();
2991590Srgrimes            } else if (e.type == MEM_END){
300146140Sharti                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
301146140Sharti                repeatStk[memEndStk + e.getMemNum()] = e.getMemStart();
302146140Sharti            }
303146140Sharti        }
304146140Sharti    }
305144656Sharti
306138916Sharti    protected final void popTilLookBehindNot() {
307138916Sharti        while (true) {
308144494Sharti            stk--;
309138916Sharti            final StackEntry e = stack[stk];
310146061Sharti
3111590Srgrimes            if (e.type == LOOK_BEHIND_NOT) {
312137572Sphk                break;
313104475Sphk            } else if (e.type == MEM_START) {
314104475Sphk                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
315104475Sphk                repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
316146061Sharti            } else if (e.type == REPEAT_INC) {
3171590Srgrimes                //int si = stack[stk + IREPEAT_INC_SI];
3181590Srgrimes                //stack[si + IREPEAT_COUNT]--;
3191590Srgrimes                stack[e.getSi()].decreaseRepeatCount();
320146061Sharti            } else if (e.type == MEM_END) {
3211590Srgrimes                repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
322146061Sharti                repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
3231590Srgrimes            }
3241590Srgrimes        }
3251590Srgrimes    }
326137202Sharti
327137202Sharti    protected final int posEnd() {
328138232Sharti        int k = stk;
32918730Ssteve        while (true) {
3301590Srgrimes            k--;
331137252Sharti            final StackEntry e = stack[k];
332137252Sharti            if ((e.type & MASK_TO_VOID_TARGET) != 0) {
333137252Sharti                e.type = VOID;
3348874Srgrimes            } else if (e.type == POS) {
335138916Sharti                e.type = VOID;
336138916Sharti                break;
337138916Sharti            }
3381590Srgrimes        }
339144494Sharti        return k;
3401590Srgrimes    }
341144656Sharti
342144656Sharti    protected final void stopBtEnd() {
343144656Sharti        int k = stk;
3441590Srgrimes        while (true) {
345137605Sharti            k--;
346137605Sharti            final StackEntry e = stack[k];
347137605Sharti
3481590Srgrimes            if ((e.type & MASK_TO_VOID_TARGET) != 0) {
34918730Ssteve                e.type = VOID;
3501590Srgrimes            } else if (e.type == STOP_BT) {
3511590Srgrimes                e.type = VOID;
35218730Ssteve                break;
3531590Srgrimes            }
35418730Ssteve        }
3551590Srgrimes    }
3561590Srgrimes
3571590Srgrimes    // int for consistency with other null check routines
35818730Ssteve    protected final int nullCheck(final int id, final int s) {
35918730Ssteve        int k = stk;
36018730Ssteve        while (true) {
36118730Ssteve            k--;
36218730Ssteve            final StackEntry e = stack[k];
36318730Ssteve
364103503Sjmallett            if (e.type == NULL_CHECK_START) {
36518730Ssteve                if (e.getNullCheckNum() == id) {
366138232Sharti                    return e.getNullCheckPStr() == s ? 1 : 0;
36718730Ssteve                }
36818730Ssteve            }
36918730Ssteve        }
37018730Ssteve    }
37118730Ssteve
37218730Ssteve    protected final int nullCheckRec(final int id, final int s) {
37318730Ssteve        int level = 0;
374103503Sjmallett        int k = stk;
375103503Sjmallett        while (true) {
37618730Ssteve            k--;
37792921Simp            final StackEntry e = stack[k];
37892921Simp
37992921Simp            if (e.type == NULL_CHECK_START) {
38092921Simp                if (e.getNullCheckNum() == id) {
38192921Simp                    if (level == 0) {
382146142Sharti                        return e.getNullCheckPStr() == s ? 1 : 0;
3831590Srgrimes                    }
384146132Sharti                    level--;
385146132Sharti                }
386146132Sharti            } else if (e.type == NULL_CHECK_END) {
387146155Sharti                level++;
388146155Sharti            }
389146155Sharti        }
390146155Sharti    }
391146155Sharti
392146155Sharti    protected final int nullCheckMemSt(final int id, final int s) {
393146155Sharti        int k = stk;
394146155Sharti        int isNull;
395146155Sharti        while (true) {
396146155Sharti            k--;
397146155Sharti            StackEntry e = stack[k];
398146155Sharti
399146155Sharti            if (e.type == NULL_CHECK_START) {
400146155Sharti                if (e.getNullCheckNum() == id) {
401146155Sharti                    if (e.getNullCheckPStr() != s) {
402146155Sharti                        isNull = 0;
403146155Sharti                        break;
404146155Sharti                    }
405146155Sharti                    int endp;
406146155Sharti                    isNull = 1;
407146155Sharti                    while (k < stk) {
408146155Sharti                        if (e.type == MEM_START) {
409146155Sharti                            if (e.getMemEnd() == INVALID_INDEX) {
410146155Sharti                                isNull = 0;
411146155Sharti                                break;
412146155Sharti                            }
413146155Sharti                            if (bsAt(regex.btMemEnd, e.getMemNum())) {
414183465Sache                                endp = stack[e.getMemEnd()].getMemPStr();
415183465Sache                            } else {
416183465Sache                                endp = e.getMemEnd();
417183465Sache                            }
418183465Sache                            if (stack[e.getMemStart()].getMemPStr() != endp) {
419183465Sache                                isNull = 0;
420146155Sharti                                break;
421146155Sharti                            } else if (endp != s) {
422146155Sharti                                isNull = -1; /* empty, but position changed */
423146155Sharti                            }
424146155Sharti                        }
425146155Sharti                        k++;
426146155Sharti                        e = stack[k]; // !!
427146155Sharti                    }
428146155Sharti                    break;
429146155Sharti                }
430146155Sharti            }
431146155Sharti        }
432146155Sharti        return isNull;
433146155Sharti    }
434146155Sharti
435146155Sharti    protected final int nullCheckMemStRec(final int id, final int s) {
436146155Sharti        int level = 0;
437146155Sharti        int k = stk;
438146155Sharti        int isNull;
439146155Sharti        while (true) {
440146155Sharti            k--;
441146155Sharti            StackEntry e = stack[k];
442146155Sharti
443146155Sharti            if (e.type == NULL_CHECK_START) {
444146155Sharti                if (e.getNullCheckNum() == id) {
445146155Sharti                    if (level == 0) {
446146155Sharti                        if (e.getNullCheckPStr() != s) {
447146155Sharti                            isNull = 0;
448146155Sharti                            break;
449146155Sharti                        }
450146155Sharti                        int endp;
451146155Sharti                        isNull = 1;
452146155Sharti                        while (k < stk) {
453146155Sharti                            if (e.type == MEM_START) {
454146155Sharti                                if (e.getMemEnd() == INVALID_INDEX) {
455146155Sharti                                    isNull = 0;
456146155Sharti                                    break;
457146155Sharti                                }
458146155Sharti                                if (bsAt(regex.btMemEnd, e.getMemNum())) {
459146155Sharti                                    endp = stack[e.getMemEnd()].getMemPStr();
460146155Sharti                                } else {
461146155Sharti                                    endp = e.getMemEnd();
462146155Sharti                                }
463146155Sharti                                if (stack[e.getMemStart()].getMemPStr() != endp) {
464146155Sharti                                    isNull = 0;
465146155Sharti                                    break;
466146155Sharti                                } else if (endp != s) {
467146155Sharti                                    isNull = -1; /* empty, but position changed */
468146155Sharti                                }
469146155Sharti                            }
470146155Sharti                            k++;
471146155Sharti                            e = stack[k];
472146155Sharti                        }
473146155Sharti                        break;
474146155Sharti                    }
475146155Sharti                    level--;
476146155Sharti                }
477146155Sharti            } else if (e.type == NULL_CHECK_END) {
478146155Sharti                if (e.getNullCheckNum() == id) {
479146155Sharti                    level++;
480146144Sharti                }
481146144Sharti            }
482146144Sharti        }
483146144Sharti        return isNull;
484146144Sharti    }
485144467Sharti
486146144Sharti    protected final int getRepeat(final int id) {
487146144Sharti        int level = 0;
488146144Sharti        int k = stk;
489146144Sharti        while (true) {
490146144Sharti            k--;
491146144Sharti            final StackEntry e = stack[k];
492146144Sharti
493146144Sharti            if (e.type == REPEAT) {
494146144Sharti                if (level == 0) {
495146144Sharti                    if (e.getRepeatNum() == id) {
496146144Sharti                        return k;
497146144Sharti                    }
498146144Sharti                }
499146144Sharti            } else if (e.type == CALL_FRAME) {
500146144Sharti                level--;
501146144Sharti            } else if (e.type == RETURN) {
502146144Sharti                level++;
503146144Sharti            }
504146144Sharti        }
505146144Sharti    }
506146131Sharti
507146130Sharti    protected final int sreturn() {
508146130Sharti        int level = 0;
509146130Sharti        int k = stk;
510146130Sharti        while (true) {
511146130Sharti            k--;
512146130Sharti            final StackEntry e = stack[k];
513146130Sharti
514146130Sharti            if (e.type == CALL_FRAME) {
515146130Sharti                if (level == 0) {
516146130Sharti                    return e.getCallFrameRetAddr();
517146131Sharti                }
518146131Sharti                level--;
519146131Sharti            } else if (e.type == RETURN) {
520146131Sharti                level++;
521146131Sharti            }
522146131Sharti        }
523146131Sharti    }
524146131Sharti}
525146131Sharti