LCOV - app.info - js/src/vm/RegExpStatics-inl.h

LCOV - code coverage report
| Current view: | directory - js/src/vm - RegExpStatics-inl.h (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 149 | 101 | 67.8 %
| Date: | 2012-04-07 | Functions: | 24 | 19 | 79.2 %

           1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
           2                 :  * vim: set ts=8 sw=4 et tw=99 ft=cpp:
           3                 :  *
           4                 :  * ***** BEGIN LICENSE BLOCK *****
           5                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           6                 :  *
           7                 :  * The contents of this file are subject to the Mozilla Public License Version
           8                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           9                 :  * the License. You may obtain a copy of the License at
          10                 :  * http://www.mozilla.org/MPL/
          11                 :  *
          12                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          13                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          14                 :  * for the specific language governing rights and limitations under the
          15                 :  * License.
          16                 :  *
          17                 :  * The Original Code is Mozilla SpiderMonkey JavaScript code.
          18                 :  *
          19                 :  * The Initial Developer of the Original Code is
          20                 :  * the Mozilla Foundation.
          21                 :  * Portions created by the Initial Developer are Copyright (C) 2011
          22                 :  * the Initial Developer. All Rights Reserved.
          23                 :  *
          24                 :  * Contributor(s):
          25                 :  *  Chris Leary <cdleary@mozilla.com>
          26                 :  *
          27                 :  * Alternatively, the contents of this file may be used under the terms of
          28                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          29                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          30                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          31                 :  * of those above. If you wish to allow use of your version of this file only
          32                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          33                 :  * use your version of this file under the terms of the MPL, indicate your
          34                 :  * decision by deleting the provisions above and replace them with the notice
          35                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          36                 :  * the provisions above, a recipient may use your version of this file under
          37                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          38                 :  *
          39                 :  * ***** END LICENSE BLOCK ***** */
          40                 :
          41                 : #ifndef RegExpStatics_inl_h__
          42                 : #define RegExpStatics_inl_h__
          43                 :
          44                 : #include "RegExpStatics.h"
          45                 :
          46                 : #include "vm/String-inl.h"
          47                 :
          48                 : namespace js {
          49                 :
          50                 : inline js::RegExpStatics *
          51         1593287 : js::GlobalObject::getRegExpStatics() const
          52                 : {
          53         1593287 :     JSObject &resObj = getSlot(REGEXP_STATICS).toObject();
          54         1593287 :     return static_cast<RegExpStatics *>(resObj.getPrivate());
          55                 : }
          56                 :
          57                 : inline size_t
          58                 : SizeOfRegExpStaticsData(const JSObject *obj, JSMallocSizeOfFun mallocSizeOf)
          59                 : {
          60                 :     return mallocSizeOf(obj->getPrivate());
          61                 : }
          62                 :
          63                 : inline
          64           23659 : RegExpStatics::RegExpStatics()
          65                 :   : bufferLink(NULL),
          66           23659 :     copied(false)
          67                 : {
          68           23659 :     clear();
          69           23659 : }
          70                 :
          71                 : inline bool
          72          786969 : RegExpStatics::createDependent(JSContext *cx, size_t start, size_t end, Value *out) const
          73                 : {
          74          786969 :     JS_ASSERT(start <= end);
          75          786969 :     JS_ASSERT(end <= matchPairsInput->length());
          76          786969 :     JSString *str = js_NewDependentString(cx, matchPairsInput, start, end - start);
          77          786969 :     if (!str)
          78               0 :         return false;
          79          786969 :     *out = StringValue(str);
          80          786969 :     return true;
          81                 : }
          82                 :
          83                 : inline bool
          84               0 : RegExpStatics::createPendingInput(JSContext *cx, Value *out) const
          85                 : {
          86               0 :     out->setString(pendingInput ? pendingInput.get() : cx->runtime->emptyString);
          87               0 :     return true;
          88                 : }
          89                 :
          90                 : inline bool
          91          786951 : RegExpStatics::makeMatch(JSContext *cx, size_t checkValidIndex, size_t pairNum, Value *out) const
          92                 : {
          93          786951 :     if (checkValidIndex / 2 >= pairCount() || matchPairs[checkValidIndex] < 0) {
          94               0 :         out->setString(cx->runtime->emptyString);
          95               0 :         return true;
          96                 :     }
          97          786951 :     return createDependent(cx, get(pairNum, 0), get(pairNum, 1), out);
          98                 : }
          99                 :
         100                 : inline bool
         101               9 : RegExpStatics::createLastParen(JSContext *cx, Value *out) const
         102                 : {
         103               9 :     if (pairCount() <= 1) {
         104               0 :         out->setString(cx->runtime->emptyString);
         105               0 :         return true;
         106                 :     }
         107               9 :     size_t num = pairCount() - 1;
         108               9 :     int start = get(num, 0);
         109               9 :     int end = get(num, 1);
         110               9 :     if (start == -1) {
         111               0 :         out->setString(cx->runtime->emptyString);
         112               0 :         return true;
         113                 :     }
         114               9 :     JS_ASSERT(start >= 0 && end >= 0);
         115               9 :     JS_ASSERT(end >= start);
         116               9 :     return createDependent(cx, start, end, out);
         117                 : }
         118                 :
         119                 : inline bool
         120               0 : RegExpStatics::createLeftContext(JSContext *cx, Value *out) const
         121                 : {
         122               0 :     if (!pairCount()) {
         123               0 :         out->setString(cx->runtime->emptyString);
         124               0 :         return true;
         125                 :     }
         126               0 :     if (matchPairs[0] < 0) {
         127               0 :         *out = UndefinedValue();
         128               0 :         return true;
         129                 :     }
         130               0 :     return createDependent(cx, 0, matchPairs[0], out);
         131                 : }
         132                 :
         133                 : inline bool
         134               9 : RegExpStatics::createRightContext(JSContext *cx, Value *out) const
         135                 : {
         136               9 :     if (!pairCount()) {
         137               0 :         out->setString(cx->runtime->emptyString);
         138               0 :         return true;
         139                 :     }
         140               9 :     if (matchPairs[1] < 0) {
         141               0 :         *out = UndefinedValue();
         142               0 :         return true;
         143                 :     }
         144               9 :     return createDependent(cx, matchPairs[1], matchPairsInput->length(), out);
         145                 : }
         146                 :
         147                 : inline void
         148            1458 : RegExpStatics::getParen(size_t pairNum, JSSubString *out) const
         149                 : {
         150            1458 :     checkParenNum(pairNum);
         151            1458 :     if (!pairIsPresent(pairNum)) {
         152              18 :         *out = js_EmptySubString;
         153              18 :         return;
         154                 :     }
         155            1440 :     out->chars = matchPairsInput->chars() + get(pairNum, 0);
         156            1440 :     out->length = getParenLength(pairNum);
         157                 : }
         158                 :
         159                 : inline void
         160           30501 : RegExpStatics::getLastMatch(JSSubString *out) const
         161                 : {
         162           30501 :     if (!pairCount()) {
         163               0 :         *out = js_EmptySubString;
         164               0 :         return;
         165                 :     }
         166           30501 :     JS_ASSERT(matchPairsInput);
         167           30501 :     out->chars = matchPairsInput->chars() + get(0, 0);
         168           30501 :     JS_ASSERT(get(0, 1) >= get(0, 0));
         169           30501 :     out->length = get(0, 1) - get(0, 0);
         170                 : }
         171                 :
         172                 : inline void
         173               0 : RegExpStatics::getLastParen(JSSubString *out) const
         174                 : {
         175               0 :     size_t pc = pairCount();
         176                 :     /* Note: the first pair is the whole match. */
         177               0 :     if (pc <= 1) {
         178               0 :         *out = js_EmptySubString;
         179               0 :         return;
         180                 :     }
         181               0 :     getParen(pc - 1, out);
         182                 : }
         183                 :
         184                 : inline void
         185               0 : RegExpStatics::getLeftContext(JSSubString *out) const
         186                 : {
         187               0 :     if (!pairCount()) {
         188               0 :         *out = js_EmptySubString;
         189               0 :         return;
         190                 :     }
         191               0 :     out->chars = matchPairsInput->chars();
         192               0 :     out->length = get(0, 0);
         193                 : }
         194                 :
         195                 : inline void
         196          155943 : RegExpStatics::getRightContext(JSSubString *out) const
         197                 : {
         198          155943 :     if (!pairCount()) {
         199               0 :         *out = js_EmptySubString;
         200               0 :         return;
         201                 :     }
         202          155943 :     out->chars = matchPairsInput->chars() + get(0, 1);
         203          155943 :     JS_ASSERT(get(0, 1) <= int(matchPairsInput->length()));
         204          155943 :     out->length = matchPairsInput->length() - get(0, 1);
         205                 : }
         206                 :
         207                 : inline void
         208              72 : RegExpStatics::copyTo(RegExpStatics &dst)
         209                 : {
         210              72 :     dst.matchPairs.clear();
         211                 :     /* 'save' has already reserved space in matchPairs */
         212              72 :     dst.matchPairs.infallibleAppend(matchPairs);
         213              72 :     dst.matchPairsInput = matchPairsInput;
         214              72 :     dst.pendingInput = pendingInput;
         215              72 :     dst.flags = flags;
         216              72 : }
         217                 :
         218                 : inline void
         219         2277611 : RegExpStatics::aboutToWrite()
         220                 : {
         221         2277611 :     if (bufferLink && !bufferLink->copied) {
         222              36 :         copyTo(*bufferLink);
         223              36 :         bufferLink->copied = true;
         224                 :     }
         225         2277611 : }
         226                 :
         227                 : inline void
         228           27909 : RegExpStatics::restore()
         229                 : {
         230           27909 :     if (bufferLink->copied)
         231              36 :         bufferLink->copyTo(*this);
         232           27909 :     bufferLink = bufferLink->bufferLink;
         233           27909 : }
         234                 :
         235                 : inline bool
         236         2253934 : RegExpStatics::updateFromMatchPairs(JSContext *cx, JSLinearString *input, MatchPairs *newPairs)
         237                 : {
         238         2253934 :     JS_ASSERT(input);
         239         2253934 :     aboutToWrite();
         240                 :     BarrieredSetPair<JSString, JSLinearString>(cx->compartment,
         241                 :                                                pendingInput, input,
         242         2253934 :                                                matchPairsInput, input);
         243                 :
         244         2253934 :     if (!matchPairs.resizeUninitialized(2 * newPairs->pairCount())) {
         245               0 :         js_ReportOutOfMemory(cx);
         246               0 :         return false;
         247                 :     }
         248                 :
         249         6335822 :     for (size_t i = 0; i < newPairs->pairCount(); ++i) {
         250         4081888 :         matchPairs[2 * i] = newPairs->pair(i).start;
         251         4081888 :         matchPairs[2 * i + 1] = newPairs->pair(i).limit;
         252                 :     }
         253                 :
         254         2253934 :     return true;
         255                 : }
         256                 :
         257                 : inline void
         258           23659 : RegExpStatics::clear()
         259                 : {
         260           23659 :     aboutToWrite();
         261           23659 :     flags = RegExpFlag(0);
         262           23659 :     pendingInput = NULL;
         263           23659 :     matchPairsInput = NULL;
         264           23659 :     matchPairs.clear();
         265           23659 : }
         266                 :
         267                 : inline void
         268               9 : RegExpStatics::setPendingInput(JSString *newInput)
         269                 : {
         270               9 :     aboutToWrite();
         271               9 :     pendingInput = newInput;
         272               9 : }
         273                 :
         274           55818 : PreserveRegExpStatics::~PreserveRegExpStatics()
         275                 : {
         276           27909 :     original->restore();
         277           27909 : }
         278                 :
         279                 : inline void
         280               9 : RegExpStatics::setMultiline(JSContext *cx, bool enabled)
         281                 : {
         282               9 :     aboutToWrite();
         283               9 :     if (enabled) {
         284               9 :         flags = RegExpFlag(flags | MultilineFlag);
         285               9 :         markFlagsSet(cx);
         286                 :     } else {
         287               0 :         flags = RegExpFlag(flags & ~MultilineFlag);
         288                 :     }
         289               9 : }
         290                 :
         291                 : inline void
         292               9 : RegExpStatics::markFlagsSet(JSContext *cx)
         293                 : {
         294                 :     /*
         295                 :      * Flags set on the RegExp function get propagated to constructed RegExp
         296                 :      * objects, which interferes with optimizations that inline RegExp cloning
         297                 :      * or avoid cloning entirely. Scripts making this assumption listen to
         298                 :      * type changes on RegExp.prototype, so mark a state change to trigger
         299                 :      * recompilation of all such code (when recompiling, a stub call will
         300                 :      * always be performed).
         301                 :      */
         302               9 :     GlobalObject *global = GetGlobalForScopeChain(cx);
         303               9 :     JS_ASSERT(this == global->getRegExpStatics());
         304                 :
         305               9 :     types::MarkTypeObjectFlags(cx, global, types::OBJECT_FLAG_REGEXP_FLAGS_SET);
         306               9 : }
         307                 :
         308                 : inline void
         309               0 : RegExpStatics::reset(JSContext *cx, JSString *newInput, bool newMultiline)
         310                 : {
         311               0 :     aboutToWrite();
         312               0 :     clear();
         313               0 :     pendingInput = newInput;
         314               0 :     setMultiline(cx, newMultiline);
         315               0 :     checkInvariants();
         316               0 : }
         317                 :
         318                 : } /* namespace js */
         319                 :
         320                 : inline js::RegExpStatics *
         321         1586961 : JSContext::regExpStatics()
         322                 : {
         323         1586961 :     return js::GetGlobalForScopeChain(this)->getRegExpStatics();
         324                 : }
         325                 :
         326                 : #endif

Generated by: LCOV version 1.7