зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to cedar again to bring over the fix for the android talos perma-orange.
This commit is contained in:
Коммит
4cdcf5bdcb
|
@ -296,6 +296,7 @@ VPATH += \
|
|||
EXPORTS_NAMESPACES += mozilla
|
||||
|
||||
EXPORTS_mozilla = \
|
||||
RangedPtr.h \
|
||||
Types.h \
|
||||
Util.h \
|
||||
$(NULL)
|
||||
|
|
|
@ -81,14 +81,14 @@ JSONParser::readString()
|
|||
* Optimization: if the source contains no escaped characters, create the
|
||||
* string directly from the source text.
|
||||
*/
|
||||
RangeCheckedPointer<const jschar> start = current;
|
||||
RangedPtr<const jschar> start = current;
|
||||
for (; current < end; current++) {
|
||||
if (*current == '"') {
|
||||
size_t length = current - start;
|
||||
current++;
|
||||
JSFlatString *str = (ST == JSONParser::PropertyName)
|
||||
? js_AtomizeChars(cx, start, length)
|
||||
: js_NewStringCopyN(cx, start, length);
|
||||
? js_AtomizeChars(cx, start.get(), length)
|
||||
: js_NewStringCopyN(cx, start.get(), length);
|
||||
if (!str)
|
||||
return token(OOM);
|
||||
return stringToken(str);
|
||||
|
@ -110,7 +110,7 @@ JSONParser::readString()
|
|||
*/
|
||||
StringBuffer buffer(cx);
|
||||
do {
|
||||
if (start < current && !buffer.append(start, current))
|
||||
if (start < current && !buffer.append(start.get(), current.get()))
|
||||
return token(OOM);
|
||||
|
||||
if (current >= end)
|
||||
|
@ -200,7 +200,7 @@ JSONParser::readNumber()
|
|||
return token(Error);
|
||||
}
|
||||
|
||||
const RangeCheckedPointer<const jschar> digitStart = current;
|
||||
const RangedPtr<const jschar> digitStart = current;
|
||||
|
||||
/* 0|[1-9][0-9]+ */
|
||||
if (!JS7_ISDEC(*current)) {
|
||||
|
@ -218,7 +218,7 @@ JSONParser::readNumber()
|
|||
if (current == end || (*current != '.' && *current != 'e' && *current != 'E')) {
|
||||
const jschar *dummy;
|
||||
jsdouble d;
|
||||
if (!GetPrefixInteger(cx, digitStart, current, 10, &dummy, &d))
|
||||
if (!GetPrefixInteger(cx, digitStart.get(), current.get(), 10, &dummy, &d))
|
||||
return token(OOM);
|
||||
JS_ASSERT(current == dummy);
|
||||
return numberToken(negative ? -d : d);
|
||||
|
@ -264,7 +264,7 @@ JSONParser::readNumber()
|
|||
|
||||
jsdouble d;
|
||||
const jschar *finish;
|
||||
if (!js_strtod(cx, digitStart, current, &finish, &d))
|
||||
if (!js_strtod(cx, digitStart.get(), current.get(), &finish, &d))
|
||||
return token(OOM);
|
||||
JS_ASSERT(current == finish);
|
||||
return numberToken(negative ? -d : d);
|
||||
|
@ -382,7 +382,7 @@ JSONParser::advanceAfterObjectOpen()
|
|||
}
|
||||
|
||||
static inline void
|
||||
AssertPastValue(const RangeCheckedPointer<const jschar> current)
|
||||
AssertPastValue(const RangedPtr<const jschar> current)
|
||||
{
|
||||
/*
|
||||
* We're past an arbitrary JSON value, so the previous character is
|
||||
|
|
|
@ -41,9 +41,10 @@
|
|||
#ifndef jsonparser_h___
|
||||
#define jsonparser_h___
|
||||
|
||||
#include "mozilla/RangedPtr.h"
|
||||
|
||||
#include "jscntxt.h"
|
||||
#include "jsstr.h"
|
||||
#include "jstl.h"
|
||||
#include "jsvalue.h"
|
||||
|
||||
/*
|
||||
|
@ -59,8 +60,8 @@ class JSONParser
|
|||
/* Data members */
|
||||
|
||||
JSContext * const cx;
|
||||
js::RangeCheckedPointer<const jschar> current;
|
||||
const js::RangeCheckedPointer<const jschar> end;
|
||||
mozilla::RangedPtr<const jschar> current;
|
||||
const mozilla::RangedPtr<const jschar> end;
|
||||
|
||||
js::Value v;
|
||||
|
||||
|
@ -89,7 +90,7 @@ class JSONParser
|
|||
ParsingMode parsingMode = StrictJSON,
|
||||
ErrorHandling errorHandling = RaiseError)
|
||||
: cx(cx),
|
||||
current(data, data, length),
|
||||
current(data, length),
|
||||
end(data + length, data, length),
|
||||
parsingMode(parsingMode),
|
||||
errorHandling(errorHandling)
|
||||
|
|
174
js/src/jstl.h
174
js/src/jstl.h
|
@ -221,19 +221,6 @@ RoundUpPow2(size_t x)
|
|||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Safely subtract two pointers when it is known that end > begin. This avoids
|
||||
* the common compiler bug that if (size_t(end) - size_t(begin)) has the MSB
|
||||
* set, the unsigned subtraction followed by right shift will produce -1, or
|
||||
* size_t(-1), instead of the real difference.
|
||||
*/
|
||||
template <class T>
|
||||
JS_ALWAYS_INLINE size_t
|
||||
PointerRangeSize(T *begin, T *end)
|
||||
{
|
||||
return (size_t(end) - size_t(begin)) / sizeof(T);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class AlignedPtrAndFlag
|
||||
{
|
||||
|
@ -334,167 +321,6 @@ InitConst(const T &t)
|
|||
return const_cast<T &>(t);
|
||||
}
|
||||
|
||||
/* Smart pointer, restricted to a range defined at construction. */
|
||||
template <class T>
|
||||
class RangeCheckedPointer
|
||||
{
|
||||
T *ptr;
|
||||
|
||||
#ifdef DEBUG
|
||||
T * const rangeStart;
|
||||
T * const rangeEnd;
|
||||
#endif
|
||||
|
||||
void sanityChecks() {
|
||||
JS_ASSERT(rangeStart <= ptr);
|
||||
JS_ASSERT(ptr <= rangeEnd);
|
||||
}
|
||||
|
||||
/* Creates a new pointer for |ptr|, restricted to this pointer's range. */
|
||||
RangeCheckedPointer<T> create(T *ptr) const {
|
||||
#ifdef DEBUG
|
||||
return RangeCheckedPointer<T>(ptr, rangeStart, rangeEnd);
|
||||
#else
|
||||
return RangeCheckedPointer<T>(ptr, NULL, size_t(0));
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
RangeCheckedPointer(T *p, T *start, T *end)
|
||||
: ptr(p)
|
||||
#ifdef DEBUG
|
||||
, rangeStart(start), rangeEnd(end)
|
||||
#endif
|
||||
{
|
||||
JS_ASSERT(rangeStart <= rangeEnd);
|
||||
sanityChecks();
|
||||
}
|
||||
RangeCheckedPointer(T *p, T *start, size_t length)
|
||||
: ptr(p)
|
||||
#ifdef DEBUG
|
||||
, rangeStart(start), rangeEnd(start + length)
|
||||
#endif
|
||||
{
|
||||
JS_ASSERT(length <= size_t(-1) / sizeof(T));
|
||||
JS_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
|
||||
sanityChecks();
|
||||
}
|
||||
|
||||
RangeCheckedPointer<T> &operator=(const RangeCheckedPointer<T> &other) {
|
||||
JS_ASSERT(rangeStart == other.rangeStart);
|
||||
JS_ASSERT(rangeEnd == other.rangeEnd);
|
||||
ptr = other.ptr;
|
||||
sanityChecks();
|
||||
return *this;
|
||||
}
|
||||
|
||||
RangeCheckedPointer<T> operator+(size_t inc) {
|
||||
JS_ASSERT(inc <= size_t(-1) / sizeof(T));
|
||||
JS_ASSERT(ptr + inc > ptr);
|
||||
return create(ptr + inc);
|
||||
}
|
||||
|
||||
RangeCheckedPointer<T> operator-(size_t dec) {
|
||||
JS_ASSERT(dec <= size_t(-1) / sizeof(T));
|
||||
JS_ASSERT(ptr - dec < ptr);
|
||||
return create(ptr - dec);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
RangeCheckedPointer<T> &operator=(U *p) {
|
||||
*this = create(p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
RangeCheckedPointer<T> &operator=(const RangeCheckedPointer<U> &p) {
|
||||
JS_ASSERT(rangeStart <= p.ptr);
|
||||
JS_ASSERT(p.ptr <= rangeEnd);
|
||||
ptr = p.ptr;
|
||||
sanityChecks();
|
||||
return *this;
|
||||
}
|
||||
|
||||
RangeCheckedPointer<T> &operator++() {
|
||||
return (*this += 1);
|
||||
}
|
||||
|
||||
RangeCheckedPointer<T> operator++(int) {
|
||||
RangeCheckedPointer<T> rcp = *this;
|
||||
++*this;
|
||||
return rcp;
|
||||
}
|
||||
|
||||
RangeCheckedPointer<T> &operator--() {
|
||||
return (*this -= 1);
|
||||
}
|
||||
|
||||
RangeCheckedPointer<T> operator--(int) {
|
||||
RangeCheckedPointer<T> rcp = *this;
|
||||
--*this;
|
||||
return rcp;
|
||||
}
|
||||
|
||||
RangeCheckedPointer<T> &operator+=(size_t inc) {
|
||||
this->operator=<T>(*this + inc);
|
||||
return *this;
|
||||
}
|
||||
|
||||
RangeCheckedPointer<T> &operator-=(size_t dec) {
|
||||
this->operator=<T>(*this - dec);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T &operator[](int index) const {
|
||||
JS_ASSERT(size_t(index > 0 ? index : -index) <= size_t(-1) / sizeof(T));
|
||||
return *create(ptr + index);
|
||||
}
|
||||
|
||||
T &operator*() const {
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
operator T*() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
bool operator==(const RangeCheckedPointer<U> &other) const {
|
||||
return ptr == other.ptr;
|
||||
}
|
||||
template <class U>
|
||||
bool operator!=(const RangeCheckedPointer<U> &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template <class U>
|
||||
bool operator<(const RangeCheckedPointer<U> &other) const {
|
||||
return ptr < other.ptr;
|
||||
}
|
||||
template <class U>
|
||||
bool operator<=(const RangeCheckedPointer<U> &other) const {
|
||||
return ptr <= other.ptr;
|
||||
}
|
||||
|
||||
template <class U>
|
||||
bool operator>(const RangeCheckedPointer<U> &other) const {
|
||||
return ptr > other.ptr;
|
||||
}
|
||||
template <class U>
|
||||
bool operator>=(const RangeCheckedPointer<U> &other) const {
|
||||
return ptr >= other.ptr;
|
||||
}
|
||||
|
||||
size_t operator-(const RangeCheckedPointer<T> &other) const {
|
||||
JS_ASSERT(ptr >= other.ptr);
|
||||
return PointerRangeSize(other.ptr, ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
RangeCheckedPointer();
|
||||
T *operator&();
|
||||
};
|
||||
|
||||
template <class T, class U>
|
||||
JS_ALWAYS_INLINE T &
|
||||
ImplicitCast(U &u)
|
||||
|
|
|
@ -0,0 +1,280 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sw=4 et tw=99 ft=cpp:
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at:
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jeff Walden <jwalden+code@mit.edu> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef mozilla_RangedPtr_h_
|
||||
#define mozilla_RangedPtr_h_
|
||||
|
||||
#include "mozilla/Util.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/*
|
||||
* RangedPtr is a smart pointer restricted to an address range specified at
|
||||
* creation. The pointer (and any smart pointers derived from it) must remain
|
||||
* within the range [start, end] (inclusive of end to facilitate use as
|
||||
* sentinels). Dereferencing or indexing into the pointer (or pointers derived
|
||||
* from it) must remain within the range [start, end). All the standard pointer
|
||||
* operators are defined on it; in debug builds these operations assert that the
|
||||
* range specified at construction is respected.
|
||||
*
|
||||
* In theory passing a smart pointer instance as an argument can be slightly
|
||||
* slower than passing a T* (due to ABI requirements for passing structs versus
|
||||
* passing pointers), if the method being called isn't inlined. If you are in
|
||||
* extremely performance-critical code, you may want to be careful using this
|
||||
* smart pointer as an argument type.
|
||||
*
|
||||
* RangedPtr<T> intentionally does not implicitly convert to T*. Use get() to
|
||||
* explicitly convert to T*. Keep in mind that the raw pointer of course won't
|
||||
* implement bounds checking in debug builds.
|
||||
*/
|
||||
template <typename T>
|
||||
class RangedPtr
|
||||
{
|
||||
T* ptr;
|
||||
|
||||
#ifdef DEBUG
|
||||
T* const rangeStart;
|
||||
T* const rangeEnd;
|
||||
#endif
|
||||
|
||||
void checkSanity() {
|
||||
MOZ_ASSERT(rangeStart <= ptr);
|
||||
MOZ_ASSERT(ptr <= rangeEnd);
|
||||
}
|
||||
|
||||
/* Creates a new pointer for |ptr|, restricted to this pointer's range. */
|
||||
RangedPtr<T> create(T *ptr) const {
|
||||
#ifdef DEBUG
|
||||
return RangedPtr<T>(ptr, rangeStart, rangeEnd);
|
||||
#else
|
||||
return RangedPtr<T>(ptr, NULL, size_t(0));
|
||||
#endif
|
||||
}
|
||||
|
||||
public:
|
||||
RangedPtr(T* p, T* start, T* end)
|
||||
: ptr(p)
|
||||
#ifdef DEBUG
|
||||
, rangeStart(start), rangeEnd(end)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(rangeStart <= rangeEnd);
|
||||
checkSanity();
|
||||
}
|
||||
RangedPtr(T* p, T* start, size_t length)
|
||||
: ptr(p)
|
||||
#ifdef DEBUG
|
||||
, rangeStart(start), rangeEnd(start + length)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(length <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
/* Equivalent to RangedPtr(p, p, length). */
|
||||
RangedPtr(T* p, size_t length)
|
||||
: ptr(p)
|
||||
#ifdef DEBUG
|
||||
, rangeStart(p), rangeEnd(p + length)
|
||||
#endif
|
||||
{
|
||||
MOZ_ASSERT(length <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(uintptr_t(rangeStart) + length * sizeof(T) >= uintptr_t(rangeStart));
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
/* Equivalent to RangedPtr(arr, arr, N). */
|
||||
template<size_t N>
|
||||
RangedPtr(T arr[N])
|
||||
: ptr(arr)
|
||||
#ifdef DEBUG
|
||||
, rangeStart(arr), rangeEnd(arr + N)
|
||||
#endif
|
||||
{
|
||||
checkSanity();
|
||||
}
|
||||
|
||||
T* get() const {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* You can only assign one RangedPtr into another if the two pointers have
|
||||
* the same valid range:
|
||||
*
|
||||
* char arr1[] = "hi";
|
||||
* char arr2[] = "bye";
|
||||
* RangedPtr<char> p1(arr1, 2);
|
||||
* p1 = RangedPtr<char>(arr1 + 1, arr1, arr1 + 2); // works
|
||||
* p1 = RangedPtr<char>(arr2, 3); // asserts
|
||||
*/
|
||||
RangedPtr<T>& operator=(const RangedPtr<T>& other) {
|
||||
MOZ_ASSERT(rangeStart == other.rangeStart);
|
||||
MOZ_ASSERT(rangeEnd == other.rangeEnd);
|
||||
ptr = other.ptr;
|
||||
checkSanity();
|
||||
return *this;
|
||||
}
|
||||
|
||||
RangedPtr<T> operator+(size_t inc) {
|
||||
MOZ_ASSERT(inc <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(ptr + inc > ptr);
|
||||
return create(ptr + inc);
|
||||
}
|
||||
|
||||
RangedPtr<T> operator-(size_t dec) {
|
||||
MOZ_ASSERT(dec <= size_t(-1) / sizeof(T));
|
||||
MOZ_ASSERT(ptr - dec < ptr);
|
||||
return create(ptr - dec);
|
||||
}
|
||||
|
||||
/*
|
||||
* You can assign a raw pointer into a RangedPtr if the raw pointer is
|
||||
* within the range specified at creation.
|
||||
*/
|
||||
template <typename U>
|
||||
RangedPtr<T>& operator=(U* p) {
|
||||
*this = create(p);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
RangedPtr<T>& operator=(const RangedPtr<U>& p) {
|
||||
MOZ_ASSERT(rangeStart <= p.ptr);
|
||||
MOZ_ASSERT(p.ptr <= rangeEnd);
|
||||
ptr = p.ptr;
|
||||
checkSanity();
|
||||
return *this;
|
||||
}
|
||||
|
||||
RangedPtr<T>& operator++() {
|
||||
return (*this += 1);
|
||||
}
|
||||
|
||||
RangedPtr<T> operator++(int) {
|
||||
RangedPtr<T> rcp = *this;
|
||||
++*this;
|
||||
return rcp;
|
||||
}
|
||||
|
||||
RangedPtr<T>& operator--() {
|
||||
return (*this -= 1);
|
||||
}
|
||||
|
||||
RangedPtr<T> operator--(int) {
|
||||
RangedPtr<T> rcp = *this;
|
||||
--*this;
|
||||
return rcp;
|
||||
}
|
||||
|
||||
RangedPtr<T>& operator+=(size_t inc) {
|
||||
this->operator=<T>(*this + inc);
|
||||
return *this;
|
||||
}
|
||||
|
||||
RangedPtr<T>& operator-=(size_t dec) {
|
||||
this->operator=<T>(*this - dec);
|
||||
return *this;
|
||||
}
|
||||
|
||||
T& operator[](int index) const {
|
||||
MOZ_ASSERT(size_t(index > 0 ? index : -index) <= size_t(-1) / sizeof(T));
|
||||
return *create(ptr + index);
|
||||
}
|
||||
|
||||
T& operator*() const {
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool operator==(const RangedPtr<U>& other) const {
|
||||
return ptr == other.ptr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator!=(const RangedPtr<U>& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template<typename U>
|
||||
bool operator==(const U* u) const {
|
||||
return ptr == u;
|
||||
}
|
||||
template<typename U>
|
||||
bool operator!=(const U* u) const {
|
||||
return !(*this == u);
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool operator<(const RangedPtr<U>& other) const {
|
||||
return ptr < other.ptr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator<=(const RangedPtr<U>& other) const {
|
||||
return ptr <= other.ptr;
|
||||
}
|
||||
|
||||
template <typename U>
|
||||
bool operator>(const RangedPtr<U>& other) const {
|
||||
return ptr > other.ptr;
|
||||
}
|
||||
template <typename U>
|
||||
bool operator>=(const RangedPtr<U>& other) const {
|
||||
return ptr >= other.ptr;
|
||||
}
|
||||
|
||||
size_t operator-(const RangedPtr<T>& other) const {
|
||||
MOZ_ASSERT(ptr >= other.ptr);
|
||||
return PointerRangeSize(other.ptr, ptr);
|
||||
}
|
||||
|
||||
private:
|
||||
RangedPtr();
|
||||
T* operator&();
|
||||
operator T*() const;
|
||||
};
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* mozilla_RangedPtr_h_ */
|
|
@ -18,7 +18,7 @@
|
|||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyrigght (C) 2011
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
|
|
69
mfbt/Util.h
69
mfbt/Util.h
|
@ -18,7 +18,7 @@
|
|||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The Mozilla Foundation
|
||||
* Portions created by the Initial Developer are Copyrigght (C) 2011
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
|
@ -79,6 +79,59 @@ MOZ_END_EXTERN_C
|
|||
|
||||
#endif /* DEBUG */
|
||||
|
||||
/*
|
||||
* MOZ_INLINE is a macro which expands to tell the compiler that the method
|
||||
* decorated with it should be inlined. This macro is usable from C and C++
|
||||
* code, even though C89 does not support the |inline| keyword. The compiler
|
||||
* may ignore this directive if it chooses.
|
||||
*/
|
||||
#ifndef MOZ_INLINE
|
||||
# if defined __cplusplus
|
||||
# define MOZ_INLINE inline
|
||||
# elif defined _MSC_VER
|
||||
# define MOZ_INLINE __inline
|
||||
# elif defined __GNUC__
|
||||
# define MOZ_INLINE __inline__
|
||||
# else
|
||||
# define MOZ_INLINE inline
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MOZ_ALWAYS_INLINE is a macro which expands to tell the compiler that the
|
||||
* method decorated with it must be inlined, even if the compiler thinks
|
||||
* otherwise. This is only a (much) stronger version of the MOZ_INLINE hint:
|
||||
* compilers are not guaranteed to respect it (although they're much more likely
|
||||
* to do so).
|
||||
*/
|
||||
#ifndef MOZ_ALWAYS_INLINE
|
||||
# if defined DEBUG
|
||||
# define MOZ_ALWAYS_INLINE MOZ_INLINE
|
||||
# elif defined _MSC_VER
|
||||
# define MOZ_ALWAYS_INLINE __forceinline
|
||||
# elif defined __GNUC__
|
||||
# define MOZ_ALWAYS_INLINE __attribute__((always_inline)) MOZ_INLINE
|
||||
# else
|
||||
# define MOZ_ALWAYS_INLINE MOZ_INLINE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the
|
||||
* method decorated with it must never be inlined, even if the compiler would
|
||||
* otherwise choose to inline the method. Compilers aren't absolutely
|
||||
* guaranteed to support this, but most do.
|
||||
*/
|
||||
#ifndef MOZ_NEVER_INLINE
|
||||
# if defined _MSC_VER
|
||||
# define MOZ_NEVER_INLINE __declspec(noinline)
|
||||
# elif defined __GNUC__
|
||||
# define MOZ_NEVER_INLINE __attribute__((noinline))
|
||||
# else
|
||||
# define MOZ_NEVER_INLINE
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -250,6 +303,20 @@ class Maybe
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Safely subtract two pointers when it is known that end >= begin. This avoids
|
||||
* the common compiler bug that if (size_t(end) - size_t(begin)) has the MSB
|
||||
* set, the unsigned subtraction followed by right shift will produce -1, or
|
||||
* size_t(-1), instead of the real difference.
|
||||
*/
|
||||
template <class T>
|
||||
MOZ_ALWAYS_INLINE size_t
|
||||
PointerRangeSize(T* begin, T* end)
|
||||
{
|
||||
MOZ_ASSERT(end >= begin);
|
||||
return (size_t(end) - size_t(begin)) / sizeof(T);
|
||||
}
|
||||
|
||||
} /* namespace mozilla */
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
|
|
@ -648,7 +648,7 @@ pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.goog
|
|||
|
||||
// True if this is the first time we are showing about:firstrun
|
||||
pref("browser.firstrun.show.uidiscovery", true);
|
||||
pref("browser.firstrun.show.localepicker", true);
|
||||
pref("browser.firstrun.show.localepicker", false);
|
||||
|
||||
// initiated by a user
|
||||
pref("content.ime.strict_policy", true);
|
||||
|
|
|
@ -37,6 +37,9 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "mozilla/RangedPtr.h"
|
||||
|
||||
#include "nsURLParsers.h"
|
||||
#include "nsURLHelper.h"
|
||||
#include "nsIURI.h"
|
||||
|
@ -45,13 +48,16 @@
|
|||
#include "nsCRT.h"
|
||||
#include "netCore.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
static PRUint32
|
||||
CountConsecutiveSlashes(const char *str, PRInt32 len)
|
||||
{
|
||||
RangedPtr<const char> p(str, len);
|
||||
PRUint32 count = 0;
|
||||
while (len-- && *str++ == '/') ++count;
|
||||
while (len-- && *p++ == '/') ++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче