Example #1
0
bool
GeneratedSourceMap::searchLineByOffset(JSContext* cx, uint32_t offset, size_t* exprlocIndex)
{
    MOZ_ASSERT(!exprlocs_.empty());
    size_t exprlocsLength = exprlocs_.length();

    // Lazily build sorted array for fast log(n) lookup.
    if (!sortedByOffsetExprLocIndices_) {
        ExprLocIndexVector scratch;
        auto indices = MakeUnique<ExprLocIndexVector>();
        if (!indices || !indices->resize(exprlocsLength) || !scratch.resize(exprlocsLength)) {
            ReportOutOfMemory(cx);
            return false;
        }
        sortedByOffsetExprLocIndices_ = Move(indices);

        for (size_t i = 0; i < exprlocsLength; i++)
            (*sortedByOffsetExprLocIndices_)[i] = i;

        auto compareExprLocViaIndex = [&](uint32_t i, uint32_t j, bool* lessOrEqualp) -> bool {
            *lessOrEqualp = exprlocs_[i].offset <= exprlocs_[j].offset;
            return true;
        };
        MOZ_ALWAYS_TRUE(MergeSort(sortedByOffsetExprLocIndices_->begin(), exprlocsLength,
                                  scratch.begin(), compareExprLocViaIndex));
    }

    // Allowing non-exact search and if BinarySearchIf returns out-of-bound
    // index, moving the index to the last index.
    auto lookupFn = [&](uint32_t i) -> int {
        const ExprLoc& loc = exprlocs_[i];
        return offset == loc.offset ? 0 : offset < loc.offset ? -1 : 1;
    };
    size_t match;
    Unused << BinarySearchIf(sortedByOffsetExprLocIndices_->begin(), 0, exprlocsLength, lookupFn, &match);
    if (match >= exprlocsLength)
        match = exprlocsLength - 1;
    *exprlocIndex = (*sortedByOffsetExprLocIndices_)[match];
    return true;
}
Example #2
0
int32_t
gfxMathTable::GetCoverageIndex(const Coverage* aCoverage, uint32_t aGlyph)
{
  using mozilla::BinarySearch;
  using mozilla::BinarySearchIf;

  if (uint16_t(aCoverage->mFormat) == 1) {
    // Coverage Format 1: list of individual glyph indices in the glyph set.
    const CoverageFormat1* table =
      reinterpret_cast<const CoverageFormat1*>(aCoverage);
    const uint16_t count = table->mGlyphCount;
    const char* start = reinterpret_cast<const char*>(table + 1);
    if (ValidStructure(start, count * sizeof(GlyphID))) {
      const GlyphID* glyphArray = reinterpret_cast<const GlyphID*>(start);
      size_t index;

      if (BinarySearch(GlyphArrayWrapper(glyphArray), 0, count, aGlyph, &index)) {
        return index;
      }
    }
  } else if (uint16_t(aCoverage->mFormat) == 2) {
    // Coverage Format 2: ranges of consecutive indices.
    const CoverageFormat2* table =
      reinterpret_cast<const CoverageFormat2*>(aCoverage);
    const uint16_t count = table->mRangeCount;
    const char* start = reinterpret_cast<const char*>(table + 1);
    if (ValidStructure(start, count * sizeof(RangeRecord))) {
      const RangeRecord* rangeArray = reinterpret_cast<const RangeRecord*>(start);
      size_t index;

      if (BinarySearchIf(rangeArray, 0, count, RangeRecordComparator(aGlyph),
                         &index)) {
        uint16_t rStart = rangeArray[index].mStart;
        uint16_t startCoverageIndex = rangeArray[index].mStartCoverageIndex;
        return (startCoverageIndex + aGlyph - rStart);
      }
    }
  }
  return -1;
}
Example #3
0
bool
DebugState::getLineOffsets(JSContext* cx, size_t lineno, Vector<uint32_t>* offsets)
{
    if (!debugEnabled())
        return true;

    if (binarySource_) {
        const CallSite* callsite = SlowCallSiteSearchByOffset(metadata(Tier::Debug), lineno);
        if (callsite && !offsets->append(lineno))
            return false;
        return true;
    }

    if (!ensureSourceMap(cx))
        return false;

    if (!maybeSourceMap_)
        return true; // no source text available, keep offsets empty.

    ExprLocVector& exprlocs = maybeSourceMap_->exprlocs();

    // Binary search for the expression with the specified line number and
    // rewind to the first expression, if more than one expression on the same line.
    size_t match;
    if (!BinarySearchIf(exprlocs, 0, exprlocs.length(), LineComparator(lineno), &match))
        return true;

    while (match > 0 && exprlocs[match - 1].lineno == lineno)
        match--;

    // Return all expression offsets that were printed on the specified line.
    for (size_t i = match; i < exprlocs.length() && exprlocs[i].lineno == lineno; i++) {
        if (!offsets->append(exprlocs[i].offset))
            return false;
    }

    return true;
}