/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef vm_MatchPairs_h
#define vm_MatchPairs_h

#include "jsalloc.h"

#include "ds/LifoAlloc.h"
#include "js/Vector.h"

/*
 * RegExp match results are succinctly represented by pairs of integer
 * indices delimiting (start, limit] segments of the input string.
 *
 * The pair count for a given RegExp match is the capturing parentheses
 * count plus one for the "0 capturing paren" whole text match.
 */

namespace js {

struct MatchPair
{
    int32_t start;
    int32_t limit;

    MatchPair()
      : start(-1), limit(-1)
    { }

    MatchPair(int32_t start, int32_t limit)
      : start(start), limit(limit)
    { }

    size_t length()      const { MOZ_ASSERT(!isUndefined()); return limit - start; }
    bool isEmpty()       const { return length() == 0; }
    bool isUndefined()   const { return start < 0; }

    void displace(size_t amount) {
        start += (start < 0) ? 0 : amount;
        limit += (limit < 0) ? 0 : amount;
    }

    inline bool check() const {
        MOZ_ASSERT(limit >= start);
        MOZ_ASSERT_IF(start < 0, start == -1);
        MOZ_ASSERT_IF(limit < 0, limit == -1);
        return true;
    }
};

/* Base class for RegExp execution output. */
class MatchPairs
{
  protected:
    /* Length of pairs_. */
    uint32_t pairCount_;

    /* Raw pointer into an allocated MatchPair buffer. */
    MatchPair* pairs_;

  protected:
    /* Not used directly: use ScopedMatchPairs or VectorMatchPairs. */
    MatchPairs()
      : pairCount_(0), pairs_(nullptr)
    { }

  protected:
    /* Functions used by friend classes. */
    friend class RegExpShared;
    friend class RegExpStatics;

    /* MatchPair buffer allocator: set pairs_ and pairCount_. */
    virtual bool allocOrExpandArray(size_t pairCount) = 0;

    bool initArrayFrom(MatchPairs& copyFrom);
    void forgetArray() { pairs_ = nullptr; }

    void checkAgainst(size_t inputLength) {
#ifdef DEBUG
        for (size_t i = 0; i < pairCount_; i++) {
            const MatchPair& p = (*this)[i];
            MOZ_ASSERT(p.check());
            if (p.isUndefined())
                continue;
            MOZ_ASSERT(size_t(p.limit) <= inputLength);
        }
#endif
    }

  public:
    /* Querying functions in the style of RegExpStatics. */
    bool   empty() const           { return pairCount_ == 0; }
    size_t pairCount() const       { MOZ_ASSERT(pairCount_ > 0); return pairCount_; }
    size_t parenCount() const      { return pairCount_ - 1; }

    static size_t offsetOfPairs() { return offsetof(MatchPairs, pairs_); }
    static size_t offsetOfPairCount() { return offsetof(MatchPairs, pairCount_); }

    int32_t* pairsRaw() { return reinterpret_cast<int32_t*>(pairs_); }

  public:
    size_t length() const { return pairCount_; }

    const MatchPair& operator[](size_t i) const {
        MOZ_ASSERT(i < pairCount_);
        return pairs_[i];
    }
    MatchPair& operator[](size_t i) {
        MOZ_ASSERT(i < pairCount_);
        return pairs_[i];
    }
};

/* MatchPairs allocated into temporary storage, removed when out of scope. */
class ScopedMatchPairs : public MatchPairs
{
    LifoAllocScope lifoScope_;

  public:
    /* Constructs an implicit LifoAllocScope. */
    explicit ScopedMatchPairs(LifoAlloc* lifoAlloc)
      : lifoScope_(lifoAlloc)
    { }

  protected:
    bool allocOrExpandArray(size_t pairCount);
};

/*
 * MatchPairs allocated into permanent storage, for RegExpStatics.
 * The Vector of MatchPairs is reusable by Vector expansion.
 */
class VectorMatchPairs : public MatchPairs
{
    Vector<MatchPair, 10, SystemAllocPolicy> vec_;

  public:
    VectorMatchPairs() {
        vec_.clear();
    }

  protected:
    friend class RegExpStatics;
    bool allocOrExpandArray(size_t pairCount);
};

} /* namespace js */

#endif /* vm_MatchPairs_h */
