js/src/vm/RegExpStatics.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
     2  * vim: set ts=8 sts=4 et sw=4 tw=99:
     3  * This Source Code Form is subject to the terms of the Mozilla Public
     4  * License, v. 2.0. If a copy of the MPL was not distributed with this
     5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     7 #include "vm/RegExpStatics.h"
     9 #include "vm/RegExpStaticsObject.h"
    11 #include "jsobjinlines.h"
    13 using namespace js;
    15 /*
    16  * RegExpStatics allocates memory -- in order to keep the statics stored
    17  * per-global and not leak, we create a js::Class to wrap the C++ instance and
    18  * provide an appropriate finalizer. We store an instance of that js::Class in
    19  * a global reserved slot.
    20  */
    22 static void
    23 resc_finalize(FreeOp *fop, JSObject *obj)
    24 {
    25     RegExpStatics *res = static_cast<RegExpStatics *>(obj->getPrivate());
    26     fop->delete_(res);
    27 }
    29 static void
    30 resc_trace(JSTracer *trc, JSObject *obj)
    31 {
    32     void *pdata = obj->getPrivate();
    33     JS_ASSERT(pdata);
    34     RegExpStatics *res = static_cast<RegExpStatics *>(pdata);
    35     res->mark(trc);
    36 }
    38 const Class RegExpStaticsObject::class_ = {
    39     "RegExpStatics",
    40     JSCLASS_HAS_PRIVATE | JSCLASS_IMPLEMENTS_BARRIERS,
    41     JS_PropertyStub,         /* addProperty */
    42     JS_DeletePropertyStub,   /* delProperty */
    43     JS_PropertyStub,         /* getProperty */
    44     JS_StrictPropertyStub,   /* setProperty */
    45     JS_EnumerateStub,
    46     JS_ResolveStub,
    47     JS_ConvertStub,
    48     resc_finalize,
    49     nullptr,                 /* call        */
    50     nullptr,                 /* hasInstance */
    51     nullptr,                 /* construct   */
    52     resc_trace
    53 };
    55 JSObject *
    56 RegExpStatics::create(JSContext *cx, GlobalObject *parent)
    57 {
    58     JSObject *obj = NewObjectWithGivenProto(cx, &RegExpStaticsObject::class_, nullptr, parent);
    59     if (!obj)
    60         return nullptr;
    61     RegExpStatics *res = cx->new_<RegExpStatics>();
    62     if (!res)
    63         return nullptr;
    64     obj->setPrivate(static_cast<void *>(res));
    65     return obj;
    66 }
    68 void
    69 RegExpStatics::markFlagsSet(JSContext *cx)
    70 {
    71     // Flags set on the RegExp function get propagated to constructed RegExp
    72     // objects, which interferes with optimizations that inline RegExp cloning
    73     // or avoid cloning entirely. Scripts making this assumption listen to
    74     // type changes on RegExp.prototype, so mark a state change to trigger
    75     // recompilation of all such code (when recompiling, a stub call will
    76     // always be performed).
    77     JS_ASSERT(this == cx->global()->getRegExpStatics());
    79     types::MarkTypeObjectFlags(cx, cx->global(), types::OBJECT_FLAG_REGEXP_FLAGS_SET);
    80 }
    82 bool
    83 RegExpStatics::executeLazy(JSContext *cx)
    84 {
    85     if (!pendingLazyEvaluation)
    86         return true;
    88     JS_ASSERT(lazySource);
    89     JS_ASSERT(matchesInput);
    90     JS_ASSERT(lazyIndex != size_t(-1));
    92     /* Retrieve or create the RegExpShared in this compartment. */
    93     RegExpGuard g(cx);
    94     if (!cx->compartment()->regExps.get(cx, lazySource, lazyFlags, &g))
    95         return false;
    97     /*
    98      * It is not necessary to call aboutToWrite(): evaluation of
    99      * implicit copies is safe.
   100      */
   102     size_t length = matchesInput->length();
   103     const jschar *chars = matchesInput->chars();
   105     /* Execute the full regular expression. */
   106     RegExpRunStatus status = g->execute(cx, chars, length, &this->lazyIndex, this->matches);
   107     if (status == RegExpRunStatus_Error)
   108         return false;
   110     /*
   111      * RegExpStatics are only updated on successful (matching) execution.
   112      * Re-running the same expression must therefore produce a matching result.
   113      */
   114     JS_ASSERT(status == RegExpRunStatus_Success);
   116     /* Unset lazy state and remove rooted values that now have no use. */
   117     pendingLazyEvaluation = false;
   118     lazySource = nullptr;
   119     lazyIndex = size_t(-1);
   121     return true;
   122 }

mercurial