summaryrefslogtreecommitdiffstats
path: root/include/onlineupdate
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--include/onlineupdate/mar.h198
-rw-r--r--include/onlineupdate/mar_cmdline.h110
-rw-r--r--include/onlineupdate/mar_private.h79
-rw-r--r--include/onlineupdate/mozilla/Assertions.h503
-rw-r--r--include/onlineupdate/mozilla/Attributes.h481
-rw-r--r--include/onlineupdate/mozilla/Compiler.h110
-rw-r--r--include/onlineupdate/mozilla/Likely.h23
-rw-r--r--include/onlineupdate/mozilla/MacroArgs.h105
-rw-r--r--include/onlineupdate/mozilla/TypeTraits.h1116
-rw-r--r--include/onlineupdate/mozilla/Types.h134
-rw-r--r--include/onlineupdate/mozilla/nsTraceRefcnt.h67
11 files changed, 2926 insertions, 0 deletions
diff --git a/include/onlineupdate/mar.h b/include/onlineupdate/mar.h
new file mode 100644
index 000000000..0e21efb92
--- /dev/null
+++ b/include/onlineupdate/mar.h
@@ -0,0 +1,198 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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 MAR_H__
+#define MAR_H__
+
+#include "mozilla/Assertions.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* We have a MAX_SIGNATURES limit so that an invalid MAR will never
+ * waste too much of either updater's or signmar's time.
+ * It is also used at various places internally and will affect memory usage.
+ * If you want to increase this value above 9 then you need to adjust parsing
+ * code in tool/mar.c.
+*/
+#define MAX_SIGNATURES 8
+#ifdef __cplusplus
+static_assert(MAX_SIGNATURES <= 9, "too many signatures");
+#else
+MOZ_STATIC_ASSERT(MAX_SIGNATURES <= 9, "too many signatures");
+#endif
+
+struct ProductInformationBlock {
+ const char *MARChannelID;
+ const char *productVersion;
+};
+
+/**
+ * The MAR item data structure.
+ */
+typedef struct MarItem_ {
+ struct MarItem_ *next; /* private field */
+ uint32_t offset; /* offset into archive */
+ uint32_t length; /* length of data in bytes */
+ uint32_t flags; /* contains file mode bits */
+ char name[1]; /* file path */
+} MarItem;
+
+#define TABLESIZE 256
+
+struct MarFile_ {
+ FILE *fp;
+ MarItem *item_table[TABLESIZE];
+};
+
+typedef struct MarFile_ MarFile;
+
+/**
+ * Signature of callback function passed to mar_enum_items.
+ * @param mar The MAR file being visited.
+ * @param item The MAR item being visited.
+ * @param data The data parameter passed by the caller of mar_enum_items.
+ * @return A non-zero value to stop enumerating.
+ */
+typedef int (* MarItemCallback)(MarFile *mar, const MarItem *item, void *data);
+
+/**
+ * Open a MAR file for reading.
+ * @param path Specifies the path to the MAR file to open. This path must
+ * be compatible with fopen.
+ * @return NULL if an error occurs.
+ */
+MarFile *mar_open(const char *path);
+
+#ifdef _WIN32
+MarFile *mar_wopen(const wchar_t *path);
+#endif
+
+/**
+ * Close a MAR file that was opened using mar_open.
+ * @param mar The MarFile object to close.
+ */
+void mar_close(MarFile *mar);
+
+/**
+ * Find an item in the MAR file by name.
+ * @param mar The MarFile object to query.
+ * @param item The name of the item to query.
+ * @return A const reference to a MAR item or NULL if not found.
+ */
+const MarItem *mar_find_item(MarFile *mar, const char *item);
+
+/**
+ * Enumerate all MAR items via callback function.
+ * @param mar The MAR file to enumerate.
+ * @param callback The function to call for each MAR item.
+ * @param data A caller specified value that is passed along to the
+ * callback function.
+ * @return 0 if the enumeration ran to completion. Otherwise, any
+ * non-zero return value from the callback is returned.
+ */
+int mar_enum_items(MarFile *mar, MarItemCallback callback, void *data);
+
+/**
+ * Read from MAR item at given offset up to bufsize bytes.
+ * @param mar The MAR file to read.
+ * @param item The MAR item to read.
+ * @param offset The byte offset relative to the start of the item.
+ * @param buf A pointer to a buffer to copy the data into.
+ * @param bufsize The length of the buffer to copy the data into.
+ * @return The number of bytes written or a negative value if an
+ * error occurs.
+ */
+int mar_read(MarFile *mar, const MarItem *item, int offset, char *buf,
+ int bufsize);
+
+/**
+ * Create a MAR file from a set of files.
+ * @param dest The path to the file to create. This path must be
+ * compatible with fopen.
+ * @param numfiles The number of files to store in the archive.
+ * @param files The list of null-terminated file paths. Each file
+ * path must be compatible with fopen.
+ * @param infoBlock The information to store in the product information block.
+ * @return A non-zero value if an error occurs.
+ */
+int mar_create(const char *dest,
+ int numfiles,
+ char **files,
+ struct ProductInformationBlock *infoBlock);
+
+/**
+ * Extract a MAR file to the current working directory.
+ * @param path The path to the MAR file to extract. This path must be
+ * compatible with fopen.
+ * @return A non-zero value if an error occurs.
+ */
+int mar_extract(const char *path);
+
+#define MAR_MAX_CERT_SIZE (16*1024) // Way larger than necessary
+
+/* Read the entire file (not a MAR file) into a newly-allocated buffer.
+ * This function does not write to stderr. Instead, the caller should
+ * write whatever error messages it sees fit. The caller must free the returned
+ * buffer using free().
+ *
+ * @param filePath The path to the file that should be read.
+ * @param maxSize The maximum valid file size.
+ * @param data On success, *data will point to a newly-allocated buffer
+ * with the file's contents in it.
+ * @param size On success, *size will be the size of the created buffer.
+ *
+ * @return 0 on success, -1 on error
+ */
+int mar_read_entire_file(const char * filePath,
+ uint32_t maxSize,
+ /*out*/ const uint8_t * *data,
+ /*out*/ uint32_t *size);
+
+/**
+ * Verifies a MAR file by verifying each signature with the corresponding
+ * certificate. That is, the first signature will be verified using the first
+ * certificate given, the second signature will be verified using the second
+ * certificate given, etc. The signature count must exactly match the number of
+ * certificates given, and all signature verifications must succeed.
+ * We do not check that the certificate was issued by any trusted authority.
+ * We assume it to be self-signed. We do not check whether the certificate
+ * is valid for this usage.
+ *
+ * @param mar The already opened MAR file.
+ * @param certData Pointer to the first element in an array of certificate
+ * file data.
+ * @param certDataSizes Pointer to the first element in an array for size of
+ * the cert data.
+ * @param certCount The number of elements in certData and certDataSizes
+ * @return 0 on success
+ * a negative number if there was an error
+ * a positive number if the signature does not verify
+ */
+int mar_verify_signatures(MarFile *mar,
+ const uint8_t * const *certData,
+ const uint32_t *certDataSizes,
+ uint32_t certCount);
+
+/**
+ * Reads the product info block from the MAR file's additional block section.
+ * The caller is responsible for freeing the fields in infoBlock
+ * if the return is successful.
+ *
+ * @param infoBlock Out parameter for where to store the result to
+ * @return 0 on success, -1 on failure
+*/
+int
+mar_read_product_info_block(MarFile *mar,
+ struct ProductInformationBlock *infoBlock);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MAR_H__ */
diff --git a/include/onlineupdate/mar_cmdline.h b/include/onlineupdate/mar_cmdline.h
new file mode 100644
index 000000000..ef6867f06
--- /dev/null
+++ b/include/onlineupdate/mar_cmdline.h
@@ -0,0 +1,110 @@
+/* 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 MAR_CMDLINE_H__
+#define MAR_CMDLINE_H__
+
+/* We use NSPR here just to import the definition of uint32_t */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ProductInformationBlock;
+
+/**
+ * Determines MAR file information.
+ *
+ * @param path The path of the MAR file to check.
+ * @param hasSignatureBlock Optional out parameter specifying if the MAR
+ * file has a signature block or not.
+ * @param numSignatures Optional out parameter for storing the number
+ * of signatures in the MAR file.
+ * @param hasAdditionalBlocks Optional out parameter specifying if the MAR
+ * file has additional blocks or not.
+ * @param offsetAdditionalBlocks Optional out parameter for the offset to the
+ * first additional block. Value is only valid if
+ * hasAdditionalBlocks is not equal to 0.
+ * @param numAdditionalBlocks Optional out parameter for the number of
+ * additional blocks. Value is only valid if
+ * has_additional_blocks is not equal to 0.
+ * @return 0 on success and non-zero on failure.
+ */
+int get_mar_file_info(const char *path,
+ int *hasSignatureBlock,
+ uint32_t *numSignatures,
+ int *hasAdditionalBlocks,
+ uint32_t *offsetAdditionalBlocks,
+ uint32_t *numAdditionalBlocks);
+
+/**
+ * Reads the product info block from the MAR file's additional block section.
+ * The caller is responsible for freeing the fields in infoBlock
+ * if the return is successful.
+ *
+ * @param infoBlock Out parameter for where to store the result to
+ * @return 0 on success, -1 on failure
+*/
+int
+read_product_info_block(char *path,
+ struct ProductInformationBlock *infoBlock);
+
+/**
+ * Refreshes the product information block with the new information.
+ * The input MAR must not be signed or the function call will fail.
+ *
+ * @param path The path to the MAR file whose product info block
+ * should be refreshed.
+ * @param infoBlock Out parameter for where to store the result to
+ * @return 0 on success, -1 on failure
+*/
+int
+refresh_product_info_block(const char *path,
+ struct ProductInformationBlock *infoBlock);
+
+/**
+ * Writes out a copy of the MAR at src but with the signature block stripped.
+ *
+ * @param src The path of the source MAR file
+ * @param dest The path of the MAR file to write out that
+ has no signature block
+ * @return 0 on success
+ * -1 on error
+*/
+int
+strip_signature_block(const char *src, const char * dest);
+
+/**
+ * Extracts a signature from a MAR file, base64 encodes it, and writes it out
+ *
+ * @param src The path of the source MAR file
+ * @param sigIndex The index of the signature to extract
+ * @param dest The path of file to write the signature to
+ * @return 0 on success
+ * -1 on error
+*/
+int
+extract_signature(const char *src, uint32_t sigIndex, const char * dest);
+
+/**
+ * Imports a base64 encoded signature into a MAR file
+ *
+ * @param src The path of the source MAR file
+ * @param sigIndex The index of the signature to import
+ * @param base64SigFile A file which contains the signature to import
+ * @param dest The path of the destination MAR file with replaced signature
+ * @return 0 on success
+ * -1 on error
+*/
+int
+import_signature(const char *src,
+ uint32_t sigIndex,
+ const char * base64SigFile,
+ const char *dest);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MAR_CMDLINE_H__ */
diff --git a/include/onlineupdate/mar_private.h b/include/onlineupdate/mar_private.h
new file mode 100644
index 000000000..319564b74
--- /dev/null
+++ b/include/onlineupdate/mar_private.h
@@ -0,0 +1,79 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim:set ts=2 sw=2 sts=2 et cindent: */
+/* 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 MAR_PRIVATE_H__
+#define MAR_PRIVATE_H__
+
+#include "limits.h"
+#include "mozilla/Assertions.h"
+#include <stdint.h>
+
+#define BLOCKSIZE 4096
+#define ROUND_UP(n, incr) (((n) / (incr) + 1) * (incr))
+
+#define MAR_ID "MAR1"
+#define MAR_ID_SIZE 4
+
+/* The signature block comes directly after the header block
+ which is 16 bytes */
+#define SIGNATURE_BLOCK_OFFSET 16
+
+/* Make sure the file is less than 500MB. We do this to protect against
+ invalid MAR files. */
+#define MAX_SIZE_OF_MAR_FILE ((int64_t)1824288000)
+
+/* Existing code makes assumptions that the file size is
+ smaller than LONG_MAX. */
+MOZ_STATIC_ASSERT(MAX_SIZE_OF_MAR_FILE < ((int64_t)LONG_MAX),
+ "max mar file size is too big");
+
+/* We store at most the size up to the signature block + 4
+ bytes per BLOCKSIZE bytes */
+MOZ_STATIC_ASSERT(sizeof(BLOCKSIZE) <
+ (SIGNATURE_BLOCK_OFFSET + sizeof(uint32_t)),
+ "BLOCKSIZE is too big");
+
+/* The maximum size of any signature supported by current and future
+ implementations of the signmar program. */
+#define MAX_SIGNATURE_LENGTH 2048
+
+/* Each additional block has a unique ID.
+ The product information block has an ID of 1. */
+#define PRODUCT_INFO_BLOCK_ID 1
+
+#define MAR_ITEM_SIZE(namelen) (3*sizeof(uint32_t) + (namelen) + 1)
+
+/* Product Information Block (PIB) constants */
+#define PIB_MAX_MAR_CHANNEL_ID_SIZE 63
+#define PIB_MAX_PRODUCT_VERSION_SIZE 31
+
+/* The mar program is compiled as a host bin so we don't have access to NSPR at
+ runtime. For that reason we use ntohl, htonl, and define HOST_TO_NETWORK64
+ instead of the NSPR equivalents. */
+#ifdef _WIN32
+#include <winsock2.h>
+#define ftello _ftelli64
+#define fseeko _fseeki64
+#else
+#define _FILE_OFFSET_BITS 64
+#include <netinet/in.h>
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+
+#define HOST_TO_NETWORK64(x) ( \
+ ((((uint64_t) x) & 0xFF) << 56) | \
+ ((((uint64_t) x) >> 8) & 0xFF) << 48) | \
+ (((((uint64_t) x) >> 16) & 0xFF) << 40) | \
+ (((((uint64_t) x) >> 24) & 0xFF) << 32) | \
+ (((((uint64_t) x) >> 32) & 0xFF) << 24) | \
+ (((((uint64_t) x) >> 40) & 0xFF) << 16) | \
+ (((((uint64_t) x) >> 48) & 0xFF) << 8) | \
+ (((uint64_t) x) >> 56)
+#define NETWORK_TO_HOST64 HOST_TO_NETWORK64
+
+#endif /* MAR_PRIVATE_H__ */
diff --git a/include/onlineupdate/mozilla/Assertions.h b/include/onlineupdate/mozilla/Assertions.h
new file mode 100644
index 000000000..29b4588fd
--- /dev/null
+++ b/include/onlineupdate/mozilla/Assertions.h
@@ -0,0 +1,503 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* Implementations of runtime and static assertion macros for C and C++. */
+
+#ifndef mozilla_Assertions_h
+#define mozilla_Assertions_h
+
+#if defined(MOZILLA_INTERNAL_API) && defined(__cplusplus)
+#define MOZ_DUMP_ASSERTION_STACK
+#endif
+
+#include "Attributes.h"
+#include "Compiler.h"
+#include "Likely.h"
+#include "MacroArgs.h"
+#ifdef MOZ_DUMP_ASSERTION_STACK
+#include "nsTraceRefcnt.h"
+#endif
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef _WIN32
+ /*
+ * TerminateProcess and GetCurrentProcess are defined in <winbase.h>, which
+ * further depends on <windef.h>. We hardcode these few definitions manually
+ * because those headers clutter the global namespace with a significant
+ * number of undesired macros and symbols.
+ */
+# ifdef __cplusplus
+extern "C" {
+# endif
+__declspec(dllimport) int __stdcall
+TerminateProcess(void* hProcess, unsigned int uExitCode);
+__declspec(dllimport) void* __stdcall GetCurrentProcess(void);
+# ifdef __cplusplus
+}
+# endif
+#else
+# include <signal.h>
+#endif
+#ifdef ANDROID
+# include <android/log.h>
+#endif
+
+/*
+ * MOZ_STATIC_ASSERT may be used to assert a condition *at compile time* in C.
+ * In C++11, static_assert is provided by the compiler to the same effect.
+ * This can be useful when you make certain assumptions about what must hold for
+ * optimal, or even correct, behavior. For example, you might assert that the
+ * size of a struct is a multiple of the target architecture's word size:
+ *
+ * struct S { ... };
+ * // C
+ * MOZ_STATIC_ASSERT(sizeof(S) % sizeof(size_t) == 0,
+ * "S should be a multiple of word size for efficiency");
+ * // C++11
+ * static_assert(sizeof(S) % sizeof(size_t) == 0,
+ * "S should be a multiple of word size for efficiency");
+ *
+ * This macro can be used in any location where both an extern declaration and a
+ * typedef could be used.
+ */
+#ifndef __cplusplus
+ /*
+ * Some of the definitions below create an otherwise-unused typedef. This
+ * triggers compiler warnings with some versions of gcc, so mark the typedefs
+ * as permissibly-unused to disable the warnings.
+ */
+# if defined(__GNUC__)
+# define MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE __attribute__((unused))
+# else
+# define MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE /* nothing */
+# endif
+# define MOZ_STATIC_ASSERT_GLUE1(x, y) x##y
+# define MOZ_STATIC_ASSERT_GLUE(x, y) MOZ_STATIC_ASSERT_GLUE1(x, y)
+# if defined(__SUNPRO_CC)
+ /*
+ * The Sun Studio C++ compiler is buggy when declaring, inside a function,
+ * another extern'd function with an array argument whose length contains a
+ * sizeof, triggering the error message "sizeof expression not accepted as
+ * size of array parameter". This bug (6688515, not public yet) would hit
+ * defining moz_static_assert as a function, so we always define an extern
+ * array for Sun Studio.
+ *
+ * We include the line number in the symbol name in a best-effort attempt
+ * to avoid conflicts (see below).
+ */
+# define MOZ_STATIC_ASSERT(cond, reason) \
+ extern char MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)[(cond) ? 1 : -1]
+# elif defined(__COUNTER__)
+ /*
+ * If there was no preferred alternative, use a compiler-agnostic version.
+ *
+ * Note that the non-__COUNTER__ version has a bug in C++: it can't be used
+ * in both |extern "C"| and normal C++ in the same translation unit. (Alas
+ * |extern "C"| isn't allowed in a function.) The only affected compiler
+ * we really care about is gcc 4.2. For that compiler and others like it,
+ * we include the line number in the function name to do the best we can to
+ * avoid conflicts. These should be rare: a conflict would require use of
+ * MOZ_STATIC_ASSERT on the same line in separate files in the same
+ * translation unit, *and* the uses would have to be in code with
+ * different linkage, *and* the first observed use must be in C++-linkage
+ * code.
+ */
+# define MOZ_STATIC_ASSERT(cond, reason) \
+ typedef int MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __COUNTER__)[(cond) ? 1 : -1] MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE
+# else
+# define MOZ_STATIC_ASSERT(cond, reason) \
+ extern void MOZ_STATIC_ASSERT_GLUE(moz_static_assert, __LINE__)(int arg[(cond) ? 1 : -1]) MOZ_STATIC_ASSERT_UNUSED_ATTRIBUTE
+# endif
+
+#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) MOZ_STATIC_ASSERT(!(cond) || (expr), reason)
+#else
+#define MOZ_STATIC_ASSERT_IF(cond, expr, reason) static_assert(!(cond) || (expr), reason)
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Prints |aStr| as an assertion failure (using aFilename and aLine as the
+ * location of the assertion) to the standard debug-output channel.
+ *
+ * Usually you should use MOZ_ASSERT or MOZ_CRASH instead of this method. This
+ * method is primarily for internal use in this header, and only secondarily
+ * for use in implementing release-build assertions.
+ */
+static MOZ_COLD MOZ_ALWAYS_INLINE void
+MOZ_ReportAssertionFailure(const char* aStr, const char* aFilename, int aLine)
+ MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
+{
+#ifdef ANDROID
+ __android_log_print(ANDROID_LOG_FATAL, "MOZ_Assert",
+ "Assertion failure: %s, at %s:%d\n",
+ aStr, aFilename, aLine);
+#else
+ fprintf(stderr, "Assertion failure: %s, at %s:%d\n", aStr, aFilename, aLine);
+#if defined (MOZ_DUMP_ASSERTION_STACK) && !defined(MOZILLA_XPCOMRT_API)
+ nsTraceRefcnt::WalkTheStack(stderr);
+#endif
+ fflush(stderr);
+#endif
+}
+
+static MOZ_COLD MOZ_ALWAYS_INLINE void
+MOZ_ReportCrash(const char* aStr, const char* aFilename, int aLine)
+ MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
+{
+#ifdef ANDROID
+ __android_log_print(ANDROID_LOG_FATAL, "MOZ_CRASH",
+ "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine);
+#else
+ fprintf(stderr, "Hit MOZ_CRASH(%s) at %s:%d\n", aStr, aFilename, aLine);
+#if defined(MOZ_DUMP_ASSERTION_STACK) && !defined(MOZILLA_XPCOMRT_API)
+ nsTraceRefcnt::WalkTheStack(stderr);
+#endif
+ fflush(stderr);
+#endif
+}
+
+/**
+ * MOZ_REALLY_CRASH is used in the implementation of MOZ_CRASH(). You should
+ * call MOZ_CRASH instead.
+ */
+#if defined(_MSC_VER)
+ /*
+ * On MSVC use the __debugbreak compiler intrinsic, which produces an inline
+ * (not nested in a system function) breakpoint. This distinctively invokes
+ * Breakpad without requiring system library symbols on all stack-processing
+ * machines, as a nested breakpoint would require.
+ *
+ * We use TerminateProcess with the exit code aborting would generate
+ * because we don't want to invoke atexit handlers, destructors, library
+ * unload handlers, and so on when our process might be in a compromised
+ * state.
+ *
+ * We don't use abort() because it'd cause Windows to annoyingly pop up the
+ * process error dialog multiple times. See bug 345118 and bug 426163.
+ *
+ * We follow TerminateProcess() with a call to MOZ_NoReturn() so that the
+ * compiler doesn't hassle us to provide a return statement after a
+ * MOZ_REALLY_CRASH() call.
+ *
+ * (Technically these are Windows requirements, not MSVC requirements. But
+ * practically you need MSVC for debugging, and we only ship builds created
+ * by MSVC, so doing it this way reduces complexity.)
+ */
+
+__declspec(noreturn) __inline void MOZ_NoReturn() {}
+
+# ifdef __cplusplus
+# define MOZ_REALLY_CRASH() \
+ do { \
+ ::__debugbreak(); \
+ *((volatile int*) NULL) = __LINE__; \
+ ::TerminateProcess(::GetCurrentProcess(), 3); \
+ ::MOZ_NoReturn(); \
+ } while (0)
+# else
+# define MOZ_REALLY_CRASH() \
+ do { \
+ __debugbreak(); \
+ *((volatile int*) NULL) = __LINE__; \
+ TerminateProcess(GetCurrentProcess(), 3); \
+ MOZ_NoReturn(); \
+ } while (0)
+# endif
+#else
+# ifdef __cplusplus
+# define MOZ_REALLY_CRASH() \
+ do { \
+ *((volatile int*) NULL) = __LINE__; \
+ ::abort(); \
+ } while (0)
+# else
+# define MOZ_REALLY_CRASH() \
+ do { \
+ *((volatile int*) NULL) = __LINE__; \
+ abort(); \
+ } while (0)
+# endif
+#endif
+
+/*
+ * MOZ_CRASH([explanation-string]) crashes the program, plain and simple, in a
+ * Breakpad-compatible way, in both debug and release builds.
+ *
+ * MOZ_CRASH is a good solution for "handling" failure cases when you're
+ * unwilling or unable to handle them more cleanly -- for OOM, for likely memory
+ * corruption, and so on. It's also a good solution if you need safe behavior
+ * in release builds as well as debug builds. But if the failure is one that
+ * should be debugged and fixed, MOZ_ASSERT is generally preferable.
+ *
+ * The optional explanation-string, if provided, must be a string literal
+ * explaining why we're crashing. This argument is intended for use with
+ * MOZ_CRASH() calls whose rationale is non-obvious; don't use it if it's
+ * obvious why we're crashing.
+ *
+ * If we're a DEBUG build and we crash at a MOZ_CRASH which provides an
+ * explanation-string, we print the string to stderr. Otherwise, we don't
+ * print anything; this is because we want MOZ_CRASH to be 100% safe in release
+ * builds, and it's hard to print to stderr safely when memory might have been
+ * corrupted.
+ */
+#ifndef DEBUG
+# define MOZ_CRASH(...) MOZ_REALLY_CRASH()
+#else
+# define MOZ_CRASH(...) \
+ do { \
+ MOZ_ReportCrash("" __VA_ARGS__, __FILE__, __LINE__); \
+ MOZ_REALLY_CRASH(); \
+ } while (0)
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+/*
+ * MOZ_ASSERT(expr [, explanation-string]) asserts that |expr| must be truthy in
+ * debug builds. If it is, execution continues. Otherwise, an error message
+ * including the expression and the explanation-string (if provided) is printed,
+ * an attempt is made to invoke any existing debugger, and execution halts.
+ * MOZ_ASSERT is fatal: no recovery is possible. Do not assert a condition
+ * which can correctly be falsy.
+ *
+ * The optional explanation-string, if provided, must be a string literal
+ * explaining the assertion. It is intended for use with assertions whose
+ * correctness or rationale is non-obvious, and for assertions where the "real"
+ * condition being tested is best described prosaically. Don't provide an
+ * explanation if it's not actually helpful.
+ *
+ * // No explanation needed: pointer arguments often must not be NULL.
+ * MOZ_ASSERT(arg);
+ *
+ * // An explanation can be helpful to explain exactly how we know an
+ * // assertion is valid.
+ * MOZ_ASSERT(state == WAITING_FOR_RESPONSE,
+ * "given that <thingA> and <thingB>, we must have...");
+ *
+ * // Or it might disambiguate multiple identical (save for their location)
+ * // assertions of the same expression.
+ * MOZ_ASSERT(getSlot(PRIMITIVE_THIS_SLOT).isUndefined(),
+ * "we already set [[PrimitiveThis]] for this Boolean object");
+ * MOZ_ASSERT(getSlot(PRIMITIVE_THIS_SLOT).isUndefined(),
+ * "we already set [[PrimitiveThis]] for this String object");
+ *
+ * MOZ_ASSERT has no effect in non-debug builds. It is designed to catch bugs
+ * *only* during debugging, not "in the field". If you want the latter, use
+ * MOZ_RELEASE_ASSERT, which applies to non-debug builds as well.
+ *
+ * MOZ_DIAGNOSTIC_ASSERT works like MOZ_RELEASE_ASSERT in Nightly/Aurora and
+ * MOZ_ASSERT in Beta/Release - use this when a condition is potentially rare
+ * enough to require real user testing to hit, but is not security-sensitive.
+ * This can cause user pain, so use it sparingly. If a MOZ_DIAGNOSTIC_ASSERT
+ * is firing, it should promptly be converted to a MOZ_ASSERT while the failure
+ * is being investigated, rather than letting users suffer.
+ */
+
+/*
+ * Implement MOZ_VALIDATE_ASSERT_CONDITION_TYPE, which is used to guard against
+ * accidentally passing something unintended in lieu of an assertion condition.
+ */
+
+#ifdef __cplusplus
+# include "TypeTraits.h"
+namespace mozilla {
+namespace detail {
+
+template<typename T>
+struct IsFunction
+{
+ static const bool value = false;
+};
+
+template<typename R, typename... A>
+struct IsFunction<R(A...)>
+{
+ static const bool value = true;
+};
+
+template<typename T>
+struct AssertionConditionType
+{
+ typedef typename RemoveReference<T>::Type ValueT;
+ static_assert(!IsArray<ValueT>::value,
+ "Expected boolean assertion condition, got an array or a "
+ "string!");
+ static_assert(!IsFunction<ValueT>::value,
+ "Expected boolean assertion condition, got a function! Did "
+ "you intend to call that function?");
+ static_assert(!IsFloatingPoint<ValueT>::value,
+ "It's often a bad idea to assert that a floating-point number "
+ "is nonzero, because such assertions tend to intermittently "
+ "fail. Shouldn't your code gracefully handle this case instead "
+ "of asserting? Anyway, if you really want to do that, write an "
+ "explicit boolean condition, like !!x or x!=0.");
+
+ static const bool isValid = true;
+};
+
+} // namespace detail
+} // namespace mozilla
+# define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x) \
+ static_assert(mozilla::detail::AssertionConditionType<decltype(x)>::isValid, \
+ "invalid assertion condition")
+#else
+# define MOZ_VALIDATE_ASSERT_CONDITION_TYPE(x)
+#endif
+
+/* First the single-argument form. */
+#define MOZ_ASSERT_HELPER1(expr) \
+ do { \
+ MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \
+ if (MOZ_UNLIKELY(!(expr))) { \
+ MOZ_ReportAssertionFailure(#expr, __FILE__, __LINE__); \
+ MOZ_REALLY_CRASH(); \
+ } \
+ } while (0)
+/* Now the two-argument form. */
+#define MOZ_ASSERT_HELPER2(expr, explain) \
+ do { \
+ MOZ_VALIDATE_ASSERT_CONDITION_TYPE(expr); \
+ if (MOZ_UNLIKELY(!(expr))) { \
+ MOZ_ReportAssertionFailure(#expr " (" explain ")", __FILE__, __LINE__); \
+ MOZ_REALLY_CRASH(); \
+ } \
+ } while (0)
+
+#define MOZ_RELEASE_ASSERT_GLUE(a, b) a b
+#define MOZ_RELEASE_ASSERT(...) \
+ MOZ_RELEASE_ASSERT_GLUE( \
+ MOZ_PASTE_PREFIX_AND_ARG_COUNT(MOZ_ASSERT_HELPER, __VA_ARGS__), \
+ (__VA_ARGS__))
+
+#ifdef DEBUG
+# define MOZ_ASSERT(...) MOZ_RELEASE_ASSERT(__VA_ARGS__)
+#else
+# define MOZ_ASSERT(...) do { } while (0)
+#endif /* DEBUG */
+
+#ifdef RELEASE_BUILD
+# define MOZ_DIAGNOSTIC_ASSERT MOZ_ASSERT
+#else
+# define MOZ_DIAGNOSTIC_ASSERT MOZ_RELEASE_ASSERT
+#endif
+
+/*
+ * MOZ_ASSERT_IF(cond1, cond2) is equivalent to MOZ_ASSERT(cond2) if cond1 is
+ * true.
+ *
+ * MOZ_ASSERT_IF(isPrime(num), num == 2 || isOdd(num));
+ *
+ * As with MOZ_ASSERT, MOZ_ASSERT_IF has effect only in debug builds. It is
+ * designed to catch bugs during debugging, not "in the field".
+ */
+#ifdef DEBUG
+# define MOZ_ASSERT_IF(cond, expr) \
+ do { \
+ if (cond) { \
+ MOZ_ASSERT(expr); \
+ } \
+ } while (0)
+#else
+# define MOZ_ASSERT_IF(cond, expr) do { } while (0)
+#endif
+
+/*
+ * MOZ_ASSUME_UNREACHABLE_MARKER() expands to an expression which states that
+ * it is undefined behavior for execution to reach this point. No guarantees
+ * are made about what will happen if this is reached at runtime. Most code
+ * should use MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE because it has extra
+ * asserts.
+ */
+#if defined(__clang__) || defined(__GNUC__)
+# define MOZ_ASSUME_UNREACHABLE_MARKER() __builtin_unreachable()
+#elif defined(_MSC_VER)
+# define MOZ_ASSUME_UNREACHABLE_MARKER() __assume(0)
+#else
+# ifdef __cplusplus
+# define MOZ_ASSUME_UNREACHABLE_MARKER() ::abort()
+# else
+# define MOZ_ASSUME_UNREACHABLE_MARKER() abort()
+# endif
+#endif
+
+/*
+ * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE([reason]) tells the compiler that it
+ * can assume that the macro call cannot be reached during execution. This lets
+ * the compiler generate better-optimized code under some circumstances, at the
+ * expense of the program's behavior being undefined if control reaches the
+ * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE.
+ *
+ * In Gecko, you probably should not use this macro outside of performance- or
+ * size-critical code, because it's unsafe. If you don't care about code size
+ * or performance, you should probably use MOZ_ASSERT or MOZ_CRASH.
+ *
+ * SpiderMonkey is a different beast, and there it's acceptable to use
+ * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE more widely.
+ *
+ * Note that MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE is noreturn, so it's valid
+ * not to return a value following a MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE
+ * call.
+ *
+ * Example usage:
+ *
+ * enum ValueType {
+ * VALUE_STRING,
+ * VALUE_INT,
+ * VALUE_FLOAT
+ * };
+ *
+ * int ptrToInt(ValueType type, void* value) {
+ * {
+ * // We know for sure that type is either INT or FLOAT, and we want this
+ * // code to run as quickly as possible.
+ * switch (type) {
+ * case VALUE_INT:
+ * return *(int*) value;
+ * case VALUE_FLOAT:
+ * return (int) *(float*) value;
+ * default:
+ * MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE("Unexpected ValueType");
+ * }
+ * }
+ */
+
+/*
+ * Unconditional assert in debug builds for (assumed) unreachable code paths
+ * that have a safe return without crashing in release builds.
+ */
+#define MOZ_ASSERT_UNREACHABLE(reason) \
+ MOZ_ASSERT(false, "MOZ_ASSERT_UNREACHABLE: " reason)
+
+#define MOZ_MAKE_COMPILER_ASSUME_IS_UNREACHABLE(reason) \
+ do { \
+ MOZ_ASSERT_UNREACHABLE(reason); \
+ MOZ_ASSUME_UNREACHABLE_MARKER(); \
+ } while (0)
+
+/*
+ * MOZ_ALWAYS_TRUE(expr) and MOZ_ALWAYS_FALSE(expr) always evaluate the provided
+ * expression, in debug builds and in release builds both. Then, in debug
+ * builds only, the value of the expression is asserted either true or false
+ * using MOZ_ASSERT.
+ */
+#ifdef DEBUG
+# define MOZ_ALWAYS_TRUE(expr) MOZ_ASSERT((expr))
+# define MOZ_ALWAYS_FALSE(expr) MOZ_ASSERT(!(expr))
+#else
+# define MOZ_ALWAYS_TRUE(expr) ((void)(expr))
+# define MOZ_ALWAYS_FALSE(expr) ((void)(expr))
+#endif
+
+#undef MOZ_DUMP_ASSERTION_STACK
+
+#endif /* mozilla_Assertions_h */
diff --git a/include/onlineupdate/mozilla/Attributes.h b/include/onlineupdate/mozilla/Attributes.h
new file mode 100644
index 000000000..74b77a38d
--- /dev/null
+++ b/include/onlineupdate/mozilla/Attributes.h
@@ -0,0 +1,481 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* Implementations of various class and method modifier attributes. */
+
+#ifndef mozilla_Attributes_h
+#define mozilla_Attributes_h
+
+#include "Compiler.h"
+
+/*
+ * 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 inline hint:
+ * compilers are not guaranteed to respect it (although they're much more likely
+ * to do so).
+ *
+ * The MOZ_ALWAYS_INLINE_EVEN_DEBUG macro is yet stronger. It tells the
+ * compiler to inline even in DEBUG builds. It should be used very rarely.
+ */
+#if defined(_MSC_VER)
+# define MOZ_ALWAYS_INLINE_EVEN_DEBUG __forceinline
+#elif defined(__GNUC__)
+# define MOZ_ALWAYS_INLINE_EVEN_DEBUG __attribute__((always_inline)) inline
+#else
+# define MOZ_ALWAYS_INLINE_EVEN_DEBUG inline
+#endif
+
+#if !defined(DEBUG)
+# define MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE_EVEN_DEBUG
+#elif defined(_MSC_VER) && !defined(__cplusplus)
+# define MOZ_ALWAYS_INLINE __inline
+#else
+# define MOZ_ALWAYS_INLINE inline
+#endif
+
+#if defined(_MSC_VER)
+/*
+ * g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality
+ * without warnings (functionality used by the macros below). These modes are
+ * detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more
+ * standardly, by checking whether __cplusplus has a C++11 or greater value.
+ * Current versions of g++ do not correctly set __cplusplus, so we check both
+ * for forward compatibility.
+ *
+ * Even though some versions of MSVC support explicit conversion operators, we
+ * don't indicate support for them here, due to
+ * http://stackoverflow.com/questions/20498142/visual-studio-2013-explicit-keyword-bug
+ */
+# define MOZ_HAVE_NEVER_INLINE __declspec(noinline)
+# define MOZ_HAVE_NORETURN __declspec(noreturn)
+# ifdef __clang__
+ /* clang-cl probably supports constexpr and explicit conversions. */
+# if __has_extension(cxx_constexpr)
+# define MOZ_HAVE_CXX11_CONSTEXPR
+# endif
+# if __has_extension(cxx_explicit_conversions)
+# define MOZ_HAVE_EXPLICIT_CONVERSION
+# endif
+# endif
+#elif defined(__clang__)
+ /*
+ * Per Clang documentation, "Note that marketing version numbers should not
+ * be used to check for language features, as different vendors use different
+ * numbering schemes. Instead, use the feature checking macros."
+ */
+# ifndef __has_extension
+# define __has_extension __has_feature /* compatibility, for older versions of clang */
+# endif
+# if __has_extension(cxx_constexpr)
+# define MOZ_HAVE_CXX11_CONSTEXPR
+# endif
+# if __has_extension(cxx_explicit_conversions)
+# define MOZ_HAVE_EXPLICIT_CONVERSION
+# endif
+# if __has_attribute(noinline)
+# define MOZ_HAVE_NEVER_INLINE __attribute__((noinline))
+# endif
+# if __has_attribute(noreturn)
+# define MOZ_HAVE_NORETURN __attribute__((noreturn))
+# endif
+#elif defined(__GNUC__)
+# if defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(__cplusplus) && __cplusplus >= 201103L)
+# define MOZ_HAVE_CXX11_CONSTEXPR
+# if MOZ_GCC_VERSION_AT_LEAST(4, 8, 0)
+# define MOZ_HAVE_CXX11_CONSTEXPR_IN_TEMPLATES
+# endif
+# define MOZ_HAVE_EXPLICIT_CONVERSION
+# endif
+# define MOZ_HAVE_NEVER_INLINE __attribute__((noinline))
+# define MOZ_HAVE_NORETURN __attribute__((noreturn))
+#endif
+
+/*
+ * When built with clang analyzer (a.k.a scan-build), define MOZ_HAVE_NORETURN
+ * to mark some false positives
+ */
+#ifdef __clang_analyzer__
+# if __has_extension(attribute_analyzer_noreturn)
+# define MOZ_HAVE_ANALYZER_NORETURN __attribute__((analyzer_noreturn))
+# endif
+#endif
+
+/*
+ * The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a
+ * function at compile time. A constexpr function cannot examine any values
+ * except its arguments and can have no side effects except its return value.
+ * The MOZ_CONSTEXPR_VAR specifier tells a C++11 compiler that a variable's
+ * value may be computed at compile time. It should be preferred to just
+ * marking variables as MOZ_CONSTEXPR because if the compiler does not support
+ * constexpr it will fall back to making the variable const, and some compilers
+ * do not accept variables being marked both const and constexpr.
+ */
+#ifdef MOZ_HAVE_CXX11_CONSTEXPR
+# define MOZ_CONSTEXPR constexpr
+# define MOZ_CONSTEXPR_VAR constexpr
+# ifdef MOZ_HAVE_CXX11_CONSTEXPR_IN_TEMPLATES
+# define MOZ_CONSTEXPR_TMPL constexpr
+# else
+# define MOZ_CONSTEXPR_TMPL
+# endif
+#else
+# define MOZ_CONSTEXPR /* no support */
+# define MOZ_CONSTEXPR_VAR const
+# define MOZ_CONSTEXPR_TMPL
+#endif
+
+/*
+ * MOZ_EXPLICIT_CONVERSION is a specifier on a type conversion
+ * overloaded operator that declares that a C++11 compiler should restrict
+ * this operator to allow only explicit type conversions, disallowing
+ * implicit conversions.
+ *
+ * Example:
+ *
+ * template<typename T>
+ * class Ptr
+ * {
+ * T* mPtr;
+ * MOZ_EXPLICIT_CONVERSION operator bool() const
+ * {
+ * return mPtr != nullptr;
+ * }
+ * };
+ *
+ */
+#ifdef MOZ_HAVE_EXPLICIT_CONVERSION
+# define MOZ_EXPLICIT_CONVERSION explicit
+#else
+# define MOZ_EXPLICIT_CONVERSION /* no support */
+#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.
+ */
+#if defined(MOZ_HAVE_NEVER_INLINE)
+# define MOZ_NEVER_INLINE MOZ_HAVE_NEVER_INLINE
+#else
+# define MOZ_NEVER_INLINE /* no support */
+#endif
+
+/*
+ * MOZ_NORETURN, specified at the start of a function declaration, indicates
+ * that the given function does not return. (The function definition does not
+ * need to be annotated.)
+ *
+ * MOZ_NORETURN void abort(const char* msg);
+ *
+ * This modifier permits the compiler to optimize code assuming a call to such a
+ * function will never return. It also enables the compiler to avoid spurious
+ * warnings about not initializing variables, or about any other seemingly-dodgy
+ * operations performed after the function returns.
+ *
+ * This modifier does not affect the corresponding function's linking behavior.
+ */
+#if defined(MOZ_HAVE_NORETURN)
+# define MOZ_NORETURN MOZ_HAVE_NORETURN
+#else
+# define MOZ_NORETURN /* no support */
+#endif
+
+/**
+ * MOZ_COLD tells the compiler that a function is "cold", meaning infrequently
+ * executed. This may lead it to optimize for size more aggressively than speed,
+ * or to allocate the body of the function in a distant part of the text segment
+ * to help keep it from taking up unnecessary icache when it isn't in use.
+ *
+ * Place this attribute at the very beginning of a function definition. For
+ * example, write
+ *
+ * MOZ_COLD int foo();
+ *
+ * or
+ *
+ * MOZ_COLD int foo() { return 42; }
+ */
+#if defined(__GNUC__) || defined(__clang__)
+# define MOZ_COLD __attribute__ ((cold))
+#else
+# define MOZ_COLD
+#endif
+
+/**
+ * MOZ_NONNULL tells the compiler that some of the arguments to a function are
+ * known to be non-null. The arguments are a list of 1-based argument indexes
+ * identifying arguments which are known to be non-null.
+ *
+ * Place this attribute at the very beginning of a function definition. For
+ * example, write
+ *
+ * MOZ_NONNULL(1, 2) int foo(char *p, char *q);
+ */
+#if defined(__GNUC__) || defined(__clang__)
+# define MOZ_NONNULL(...) __attribute__ ((nonnull(__VA_ARGS__)))
+#else
+# define MOZ_NONNULL(...)
+#endif
+
+/*
+ * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS, specified at the end of a function
+ * declaration, indicates that for the purposes of static analysis, this
+ * function does not return. (The function definition does not need to be
+ * annotated.)
+ *
+ * MOZ_ReportCrash(const char* s, const char* file, int ln)
+ * MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS
+ *
+ * Some static analyzers, like scan-build from clang, can use this information
+ * to eliminate false positives. From the upstream documentation of scan-build:
+ * "This attribute is useful for annotating assertion handlers that actually
+ * can return, but for the purpose of using the analyzer we want to pretend
+ * that such functions do not return."
+ *
+ */
+#if defined(MOZ_HAVE_ANALYZER_NORETURN)
+# define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS MOZ_HAVE_ANALYZER_NORETURN
+#else
+# define MOZ_PRETEND_NORETURN_FOR_STATIC_ANALYSIS /* no support */
+#endif
+
+/*
+ * MOZ_ASAN_DENYLIST is a macro to tell AddressSanitizer (a compile-time
+ * instrumentation shipped with Clang and GCC) to not instrument the annotated
+ * function. Furthermore, it will prevent the compiler from inlining the
+ * function because inlining currently breaks the denylisting mechanism of
+ * AddressSanitizer.
+ */
+#if defined(__has_feature)
+# if __has_feature(address_sanitizer)
+# define MOZ_HAVE_ASAN_DENYLIST
+# endif
+#elif defined(__GNUC__)
+# if defined(__SANITIZE_ADDRESS__)
+# define MOZ_HAVE_ASAN_DENYLIST
+# endif
+#endif
+
+#if defined(MOZ_HAVE_ASAN_DENYLIST)
+# define MOZ_ASAN_DENYLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_address))
+#else
+# define MOZ_ASAN_DENYLIST /* nothing */
+#endif
+
+/*
+ * MOZ_TSAN_DENYLIST is a macro to tell ThreadSanitizer (a compile-time
+ * instrumentation shipped with Clang) to not instrument the annotated function.
+ * Furthermore, it will prevent the compiler from inlining the function because
+ * inlining currently breaks the denylisting mechanism of ThreadSanitizer.
+ */
+#if defined(__has_feature)
+# if __has_feature(thread_sanitizer)
+# define MOZ_TSAN_DENYLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_thread))
+# else
+# define MOZ_TSAN_DENYLIST /* nothing */
+# endif
+#else
+# define MOZ_TSAN_DENYLIST /* nothing */
+#endif
+
+/**
+ * MOZ_ALLOCATOR tells the compiler that the function it marks returns either a
+ * "fresh", "pointer-free" block of memory, or nullptr. "Fresh" means that the
+ * block is not pointed to by any other reachable pointer in the program.
+ * "Pointer-free" means that the block contains no pointers to any valid object
+ * in the program. It may be initialized with other (non-pointer) values.
+ *
+ * Placing this attribute on appropriate functions helps GCC analyze pointer
+ * aliasing more accurately in their callers.
+ *
+ * GCC warns if a caller ignores the value returned by a function marked with
+ * MOZ_ALLOCATOR: it is hard to imagine cases where dropping the value returned
+ * by a function that meets the criteria above would be intentional.
+ *
+ * Place this attribute after the argument list and 'this' qualifiers of a
+ * function definition. For example, write
+ *
+ * void *my_allocator(size_t) MOZ_ALLOCATOR;
+ *
+ * or
+ *
+ * void *my_allocator(size_t bytes) MOZ_ALLOCATOR { ... }
+ */
+#if defined(__GNUC__) || defined(__clang__)
+# define MOZ_ALLOCATOR __attribute__ ((malloc, warn_unused_result))
+#else
+# define MOZ_ALLOCATOR
+#endif
+
+/**
+ * MOZ_WARN_UNUSED_RESULT tells the compiler to emit a warning if a function's
+ * return value is not used by the caller.
+ *
+ * Place this attribute at the very beginning of a function definition. For
+ * example, write
+ *
+ * MOZ_WARN_UNUSED_RESULT int foo();
+ *
+ * or
+ *
+ * MOZ_WARN_UNUSED_RESULT int foo() { return 42; }
+ */
+#if defined(__GNUC__) || defined(__clang__)
+# define MOZ_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
+#else
+# define MOZ_WARN_UNUSED_RESULT
+#endif
+
+#ifdef __cplusplus
+
+/*
+ * The following macros are attributes that support the static analysis plugin
+ * included with Mozilla, and will be implemented (when such support is enabled)
+ * as C++11 attributes. Since such attributes are legal pretty much everywhere
+ * and have subtly different semantics depending on their placement, the
+ * following is a guide on where to place the attributes.
+ *
+ * Attributes that apply to a struct or class precede the name of the class:
+ * (Note that this is different from the placement of final for classes!)
+ *
+ * class MOZ_CLASS_ATTRIBUTE SomeClass {};
+ *
+ * Attributes that apply to functions follow the parentheses and const
+ * qualifiers but precede final, override and the function body:
+ *
+ * void DeclaredFunction() MOZ_FUNCTION_ATTRIBUTE;
+ * void SomeFunction() MOZ_FUNCTION_ATTRIBUTE {}
+ * void PureFunction() const MOZ_FUNCTION_ATTRIBUTE = 0;
+ * void OverriddenFunction() MOZ_FUNCTION_ATTRIBUTE override;
+ *
+ * Attributes that apply to variables or parameters follow the variable's name:
+ *
+ * int variable MOZ_VARIABLE_ATTRIBUTE;
+ *
+ * Attributes that apply to types follow the type name:
+ *
+ * typedef int MOZ_TYPE_ATTRIBUTE MagicInt;
+ * int MOZ_TYPE_ATTRIBUTE someVariable;
+ * int* MOZ_TYPE_ATTRIBUTE magicPtrInt;
+ * int MOZ_TYPE_ATTRIBUTE* ptrToMagicInt;
+ *
+ * Attributes that apply to statements precede the statement:
+ *
+ * MOZ_IF_ATTRIBUTE if (x == 0)
+ * MOZ_DO_ATTRIBUTE do { } while (0);
+ *
+ * Attributes that apply to labels precede the label:
+ *
+ * MOZ_LABEL_ATTRIBUTE target:
+ * goto target;
+ * MOZ_CASE_ATTRIBUTE case 5:
+ * MOZ_DEFAULT_ATTRIBUTE default:
+ *
+ * The static analyses that are performed by the plugin are as follows:
+ *
+ * MOZ_MUST_OVERRIDE: Applies to all C++ member functions. All immediate
+ * subclasses must provide an exact override of this method; if a subclass
+ * does not override this method, the compiler will emit an error. This
+ * attribute is not limited to virtual methods, so if it is applied to a
+ * nonvirtual method and the subclass does not provide an equivalent
+ * definition, the compiler will emit an error.
+ * MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is
+ * expected to live on the stack, so it is a compile-time error to use it, or
+ * an array of such objects, as a global or static variable, or as the type of
+ * a new expression (unless placement new is being used). If a member of
+ * another class uses this class, or if another class inherits from this
+ * class, then it is considered to be a stack class as well, although this
+ * attribute need not be provided in such cases.
+ * MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is
+ * expected to live on the stack or in static storage, so it is a compile-time
+ * error to use it, or an array of such objects, as the type of a new
+ * expression (unless placement new is being used). If a member of another
+ * class uses this class, or if another class inherits from this class, then
+ * it is considered to be a non-heap class as well, although this attribute
+ * need not be provided in such cases.
+ * MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS: Applies to all classes that are
+ * intended to prevent introducing static initializers. This attribute
+ * currently makes it a compile-time error to instantiate these classes
+ * anywhere other than at the global scope, or as a static member of a class.
+ * MOZ_TRIVIAL_CTOR_DTOR: Applies to all classes that must have both a trivial
+ * constructor and a trivial destructor. Setting this attribute on a class
+ * makes it a compile-time error for that class to get a non-trivial
+ * constructor or destructor for any reason.
+ * MOZ_HEAP_ALLOCATOR: Applies to any function. This indicates that the return
+ * value is allocated on the heap, and will as a result check such allocations
+ * during MOZ_STACK_CLASS and MOZ_NONHEAP_CLASS annotation checking.
+ * MOZ_IMPLICIT: Applies to constructors. Implicit conversion constructors
+ * are disallowed by default unless they are marked as MOZ_IMPLICIT. This
+ * attribute must be used for constructors which intend to provide implicit
+ * conversions.
+ * MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT: Applies to functions. Makes it a compile
+ * time error to pass arithmetic expressions on variables to the function.
+ * MOZ_OWNING_REF: Applies to declarations of pointer types. This attribute
+ * tells the compiler that the raw pointer is a strong reference, and that
+ * property is somehow enforced by the code. This can make the compiler
+ * ignore these pointers when validating the usage of pointers otherwise.
+ * MOZ_NON_OWNING_REF: Applies to declarations of pointer types. This attribute
+ * tells the compiler that the raw pointer is a weak reference, and that
+ * property is somehow enforced by the code. This can make the compiler
+ * ignore these pointers when validating the usage of pointers otherwise.
+ * MOZ_UNSAFE_REF: Applies to declarations of pointer types. This attribute
+ * should be used for non-owning references that can be unsafe, and their
+ * safety needs to be validated through code inspection. The string argument
+ * passed to this macro documents the safety conditions.
+ * MOZ_NO_ADDREF_RELEASE_ON_RETURN: Applies to function declarations. Makes it
+ * a compile time error to call AddRef or Release on the return value of a
+ * function. This is intended to be used with operator->() of our smart
+ * pointer classes to ensure that the refcount of an object wrapped in a
+ * smart pointer is not manipulated directly.
+ */
+#ifdef MOZ_CLANG_PLUGIN
+# define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override")))
+# define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class")))
+# define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class")))
+# define MOZ_TRIVIAL_CTOR_DTOR __attribute__((annotate("moz_trivial_ctor_dtor")))
+# ifdef DEBUG
+ /* in debug builds, these classes do have non-trivial constructors. */
+# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS __attribute__((annotate("moz_global_class")))
+# else
+# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS __attribute__((annotate("moz_global_class"))) \
+ MOZ_TRIVIAL_CTOR_DTOR
+# endif
+# define MOZ_IMPLICIT __attribute__((annotate("moz_implicit")))
+# define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT __attribute__((annotate("moz_no_arith_expr_in_arg")))
+# define MOZ_OWNING_REF __attribute__((annotate("moz_strong_ref")))
+# define MOZ_NON_OWNING_REF __attribute__((annotate("moz_weak_ref")))
+# define MOZ_UNSAFE_REF(reason) __attribute__((annotate("moz_strong_ref")))
+# define MOZ_NO_ADDREF_RELEASE_ON_RETURN __attribute__((annotate("moz_no_addref_release_on_return")))
+/*
+ * It turns out that clang doesn't like void func() __attribute__ {} without a
+ * warning, so use pragmas to disable the warning. This code won't work on GCC
+ * anyways, so the warning is safe to ignore.
+ */
+# define MOZ_HEAP_ALLOCATOR \
+ _Pragma("clang diagnostic push") \
+ _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \
+ __attribute__((annotate("moz_heap_allocator"))) \
+ _Pragma("clang diagnostic pop")
+#else
+# define MOZ_MUST_OVERRIDE /* nothing */
+# define MOZ_STACK_CLASS /* nothing */
+# define MOZ_NONHEAP_CLASS /* nothing */
+# define MOZ_TRIVIAL_CTOR_DTOR /* nothing */
+# define MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS /* nothing */
+# define MOZ_IMPLICIT /* nothing */
+# define MOZ_NO_ARITHMETIC_EXPR_IN_ARGUMENT /* nothing */
+# define MOZ_HEAP_ALLOCATOR /* nothing */
+# define MOZ_OWNING_REF /* nothing */
+# define MOZ_NON_OWNING_REF /* nothing */
+# define MOZ_UNSAFE_REF(reason) /* nothing */
+# define MOZ_NO_ADDREF_RELEASE_ON_RETURN /* nothing */
+#endif /* MOZ_CLANG_PLUGIN */
+
+#endif /* __cplusplus */
+
+#endif /* mozilla_Attributes_h */
diff --git a/include/onlineupdate/mozilla/Compiler.h b/include/onlineupdate/mozilla/Compiler.h
new file mode 100644
index 000000000..6d6fcbbb1
--- /dev/null
+++ b/include/onlineupdate/mozilla/Compiler.h
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* Various compiler checks. */
+
+#ifndef mozilla_Compiler_h
+#define mozilla_Compiler_h
+
+#define MOZ_IS_GCC 0
+#define MOS_IS_MSVC 0
+
+#if !defined(__clang__) && defined(__GNUC__)
+
+# undef MOZ_IS_GCC
+# define MOZ_IS_GCC 1
+ /*
+ * This macro should simplify gcc version checking. For example, to check
+ * for gcc 4.7.1 or later, check `#if MOZ_GCC_VERSION_AT_LEAST(4, 7, 1)`.
+ */
+# define MOZ_GCC_VERSION_AT_LEAST(major, minor, patchlevel) \
+ ((__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) \
+ >= ((major) * 10000 + (minor) * 100 + (patchlevel)))
+# if !MOZ_GCC_VERSION_AT_LEAST(4, 7, 0)
+# error "mfbt (and Gecko) require at least gcc 4.7 to build."
+# endif
+
+#elif defined(_MSC_VER)
+
+# undef MOZ_IS_MSVC
+# define MOZ_IS_MSVC 1
+
+#endif
+
+/*
+ * The situation with standard libraries is a lot worse than with compilers,
+ * particularly as clang and gcc could end up using one of three or so standard
+ * libraries, and they may not be up-to-snuff with newer C++11 versions. To
+ * detect the library, we're going to include cstddef (which is a small header
+ * which will be transitively included by everybody else at some point) to grab
+ * the version macros and deduce macros from there.
+ */
+#ifdef __cplusplus
+# include <cstddef>
+# ifdef _STLPORT_MAJOR
+# define MOZ_USING_STLPORT 1
+# define MOZ_STLPORT_VERSION_AT_LEAST(major, minor, patch) \
+ (_STLPORT_VERSION >= ((major) << 8 | (minor) << 4 | (patch)))
+# elif defined(_LIBCPP_VERSION)
+ /*
+ * libc++, unfortunately, doesn't appear to have useful versioning macros.
+ * Hopefully, the recommendations of N3694 with respect to standard libraries
+ * will get applied instead and we won't need to worry about version numbers
+ * here.
+ */
+# define MOZ_USING_LIBCXX 1
+# elif defined(__GLIBCXX__)
+# define MOZ_USING_LIBSTDCXX 1
+ /*
+ * libstdc++ is also annoying and doesn't give us useful versioning macros
+ * for the library. If we're using gcc, then assume that libstdc++ matches
+ * the compiler version. If we're using clang, we're going to have to fake
+ * major/minor combinations by looking for newly-defined config macros.
+ */
+# if MOZ_IS_GCC
+# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \
+ MOZ_GCC_VERSION_AT_LEAST(major, minor, patch)
+# elif defined(_GLIBCXX_THROW_OR_ABORT)
+# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \
+ ((major) < 4 || ((major) == 4 && (minor) <= 8))
+# elif defined(_GLIBCXX_NOEXCEPT)
+# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \
+ ((major) < 4 || ((major) == 4 && (minor) <= 7))
+# elif defined(_GLIBCXX_USE_DEPRECATED)
+# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \
+ ((major) < 4 || ((major) == 4 && (minor) <= 6))
+# elif defined(_GLIBCXX_PSEUDO_VISIBILITY)
+# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \
+ ((major) < 4 || ((major) == 4 && (minor) <= 5))
+# elif defined(_GLIBCXX_BEGIN_EXTERN_C)
+# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \
+ ((major) < 4 || ((major) == 4 && (minor) <= 4))
+# elif defined(_GLIBCXX_VISIBILITY_ATTR)
+# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \
+ ((major) < 4 || ((major) == 4 && (minor) <= 3))
+# elif defined(_GLIBCXX_VISIBILITY)
+# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) \
+ ((major) < 4 || ((major) == 4 && (minor) <= 2))
+# else
+# error "Your version of libstdc++ is unknown to us and is likely too old."
+# endif
+# endif
+
+ // Flesh out the defines for everyone else
+# ifndef MOZ_USING_STLPORT
+# define MOZ_USING_STLPORT 0
+# define MOZ_STLPORT_VERSION_AT_LEAST(major, minor, patch) 0
+# endif
+# ifndef MOZ_USING_LIBCXX
+# define MOZ_USING_LIBCXX 0
+# endif
+# ifndef MOZ_USING_LIBSTDCXX
+# define MOZ_USING_LIBSTDCXX 0
+# define MOZ_LIBSTDCXX_VERSION_AT_LEAST(major, minor, patch) 0
+# endif
+#endif /* __cplusplus */
+
+#endif /* mozilla_Compiler_h */
diff --git a/include/onlineupdate/mozilla/Likely.h b/include/onlineupdate/mozilla/Likely.h
new file mode 100644
index 000000000..5625bb226
--- /dev/null
+++ b/include/onlineupdate/mozilla/Likely.h
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/*
+ * MOZ_LIKELY and MOZ_UNLIKELY macros to hint to the compiler how a
+ * boolean predicate should be branch-predicted.
+ */
+
+#ifndef mozilla_Likely_h
+#define mozilla_Likely_h
+
+#if defined(__clang__) || defined(__GNUC__)
+#define MOZ_LIKELY(x) (__builtin_expect(!!(x), 1))
+#define MOZ_UNLIKELY(x) (__builtin_expect(!!(x), 0))
+#else
+#define MOZ_LIKELY(x) (!!(x))
+#define MOZ_UNLIKELY(x) (!!(x))
+#endif
+
+#endif /* mozilla_Likely_h */
diff --git a/include/onlineupdate/mozilla/MacroArgs.h b/include/onlineupdate/mozilla/MacroArgs.h
new file mode 100644
index 000000000..c8b733821
--- /dev/null
+++ b/include/onlineupdate/mozilla/MacroArgs.h
@@ -0,0 +1,105 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/*
+ * Implements various macros meant to ease the use of variadic macros.
+ */
+
+#ifndef mozilla_MacroArgs_h
+#define mozilla_MacroArgs_h
+
+/*
+ * MOZ_PASTE_PREFIX_AND_ARG_COUNT(aPrefix, ...) counts the number of variadic
+ * arguments and prefixes it with |aPrefix|. For example:
+ *
+ * MOZ_PASTE_PREFIX_AND_ARG_COUNT(, foo, 42) expands to 2
+ * MOZ_PASTE_PREFIX_AND_ARG_COUNT(A, foo, 42, bar) expands to A3
+ *
+ * You must pass in between 1 and 50 (inclusive) variadic arguments, past
+ * |aPrefix|. It is not legal to do
+ *
+ * MOZ_PASTE_PREFIX_AND_ARG_COUNT(prefix)
+ *
+ * (that is, pass in 0 variadic arguments). To ensure that a compile-time
+ * error occurs when these constraints are violated, use the
+ * MOZ_STATIC_ASSERT_VALID_ARG_COUNT macro with the same variaidc arguments
+ * wherever this macro is used.
+ *
+ * Passing (__VA_ARGS__, <rest of arguments>) rather than simply calling
+ * MOZ_MACROARGS_ARG_COUNT_HELPER2(__VA_ARGS__, <rest of arguments>) very
+ * carefully tiptoes around a MSVC bug where it improperly expands __VA_ARGS__
+ * as a single token in argument lists. For details, see:
+ *
+ * http://connect.microsoft.com/VisualStudio/feedback/details/380090/variadic-macro-replacement
+ * http://cplusplus.co.il/2010/07/17/variadic-macro-to-count-number-of-arguments/#comment-644
+ */
+#define MOZ_PASTE_PREFIX_AND_ARG_COUNT(aPrefix, ...) \
+ MOZ_MACROARGS_ARG_COUNT_HELPER((__VA_ARGS__, \
+ aPrefix##50, aPrefix##49, aPrefix##48, aPrefix##47, aPrefix##46, \
+ aPrefix##45, aPrefix##44, aPrefix##43, aPrefix##42, aPrefix##41, \
+ aPrefix##40, aPrefix##39, aPrefix##38, aPrefix##37, aPrefix##36, \
+ aPrefix##35, aPrefix##34, aPrefix##33, aPrefix##32, aPrefix##31, \
+ aPrefix##30, aPrefix##29, aPrefix##28, aPrefix##27, aPrefix##26, \
+ aPrefix##25, aPrefix##24, aPrefix##23, aPrefix##22, aPrefix##21, \
+ aPrefix##20, aPrefix##19, aPrefix##18, aPrefix##17, aPrefix##16, \
+ aPrefix##15, aPrefix##14, aPrefix##13, aPrefix##12, aPrefix##11, \
+ aPrefix##10, aPrefix##9, aPrefix##8, aPrefix##7, aPrefix##6, \
+ aPrefix##5, aPrefix##4, aPrefix##3, aPrefix##2, aPrefix##1, aPrefix##0))
+
+#define MOZ_MACROARGS_ARG_COUNT_HELPER(aArgs) \
+ MOZ_MACROARGS_ARG_COUNT_HELPER2 aArgs
+
+#define MOZ_MACROARGS_ARG_COUNT_HELPER2( \
+ a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, \
+ a11, a12, a13, a14, a15, a16, a17, a18, a19, a20, \
+ a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, \
+ a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, \
+ a41, a42, a43, a44, a45, a46, a47, a48, a49, a50, \
+ a51, ...) a51
+
+/*
+ * MOZ_STATIC_ASSERT_VALID_ARG_COUNT ensures that a compile-time error occurs
+ * when the argument count constraints of MOZ_PASTE_PREFIX_AND_ARG_COUNT are
+ * violated. Use this macro wherever MOZ_PASTE_PREFIX_AND_ARG_COUNT is used
+ * and pass it the same variadic arguments.
+ *
+ * This macro employs a few dirty tricks to function. To detect the zero
+ * argument case, |(__VA_ARGS__)| is stringified, sizeof-ed, and compared to
+ * what it should be in the absence of arguments.
+ *
+ * Detecting too many arguments is a little trickier. With a valid argument
+ * count and a prefix of 1, MOZ_PASTE_PREFIX_AND_ARG_COUNT expands to e.g. 14.
+ * With a prefix of 0.0, it expands to e.g. 0.04. If there are too many
+ * arguments, it expands to the first argument over the limit. If this
+ * exceeding argument is a number, the assertion will fail as there is no
+ * number than can simultaneously be both > 10 and == 0. If the exceeding
+ * argument is not a number, a compile-time error should still occur due to
+ * the operations performed on it.
+ */
+#define MOZ_MACROARGS_STRINGIFY_HELPER(x) #x
+#define MOZ_STATIC_ASSERT_VALID_ARG_COUNT(...) \
+ static_assert( \
+ sizeof(MOZ_MACROARGS_STRINGIFY_HELPER((__VA_ARGS__))) != sizeof("()") && \
+ (MOZ_PASTE_PREFIX_AND_ARG_COUNT(1, __VA_ARGS__)) > 10 && \
+ (int)(MOZ_PASTE_PREFIX_AND_ARG_COUNT(0.0, __VA_ARGS__)) == 0, \
+ "MOZ_STATIC_ASSERT_VALID_ARG_COUNT requires 1 to 50 arguments") /* ; */
+
+/*
+ * MOZ_ARGS_AFTER_N expands to its arguments excluding the first |N|
+ * arguments. For example:
+ *
+ * MOZ_ARGS_AFTER_2(a, b, c, d) expands to: c, d
+ */
+#define MOZ_ARGS_AFTER_1(a1, ...) __VA_ARGS__
+#define MOZ_ARGS_AFTER_2(a1, a2, ...) __VA_ARGS__
+
+/*
+ * MOZ_ARG_N expands to its |N|th argument.
+ */
+#define MOZ_ARG_1(a1, ...) a1
+#define MOZ_ARG_2(a1, a2, ...) a2
+
+#endif /* mozilla_MacroArgs_h */
diff --git a/include/onlineupdate/mozilla/TypeTraits.h b/include/onlineupdate/mozilla/TypeTraits.h
new file mode 100644
index 000000000..7ca9d3315
--- /dev/null
+++ b/include/onlineupdate/mozilla/TypeTraits.h
@@ -0,0 +1,1116 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* Template-based metaprogramming and type-testing facilities. */
+
+#ifndef mozilla_TypeTraits_h
+#define mozilla_TypeTraits_h
+
+#include "Types.h"
+
+/*
+ * These traits are approximate copies of the traits and semantics from C++11's
+ * <type_traits> header. Don't add traits not in that header! When all
+ * platforms provide that header, we can convert all users and remove this one.
+ */
+
+#include <wchar.h>
+
+namespace mozilla {
+
+/* Forward declarations. */
+
+template<typename> struct RemoveCV;
+
+/* 20.9.3 Helper classes [meta.help] */
+
+/**
+ * Helper class used as a base for various type traits, exposed publicly
+ * because <type_traits> exposes it as well.
+ */
+template<typename T, T Value>
+struct IntegralConstant
+{
+ static const T value = Value;
+ typedef T ValueType;
+ typedef IntegralConstant<T, Value> Type;
+};
+
+/** Convenient aliases. */
+typedef IntegralConstant<bool, true> TrueType;
+typedef IntegralConstant<bool, false> FalseType;
+
+/* 20.9.4 Unary type traits [meta.unary] */
+
+/* 20.9.4.1 Primary type categories [meta.unary.cat] */
+
+namespace detail {
+
+template<typename T>
+struct IsVoidHelper : FalseType {};
+
+template<>
+struct IsVoidHelper<void> : TrueType {};
+
+} // namespace detail
+
+/**
+ * IsVoid determines whether a type is void.
+ *
+ * mozilla::IsVoid<int>::value is false;
+ * mozilla::IsVoid<void>::value is true;
+ * mozilla::IsVoid<void*>::value is false;
+ * mozilla::IsVoid<volatile void>::value is true.
+ */
+template<typename T>
+struct IsVoid : detail::IsVoidHelper<typename RemoveCV<T>::Type> {};
+
+namespace detail {
+
+template <typename T>
+struct IsIntegralHelper : FalseType {};
+
+template<> struct IsIntegralHelper<char> : TrueType {};
+template<> struct IsIntegralHelper<signed char> : TrueType {};
+template<> struct IsIntegralHelper<unsigned char> : TrueType {};
+template<> struct IsIntegralHelper<short> : TrueType {};
+template<> struct IsIntegralHelper<unsigned short> : TrueType {};
+template<> struct IsIntegralHelper<int> : TrueType {};
+template<> struct IsIntegralHelper<unsigned int> : TrueType {};
+template<> struct IsIntegralHelper<long> : TrueType {};
+template<> struct IsIntegralHelper<unsigned long> : TrueType {};
+template<> struct IsIntegralHelper<long long> : TrueType {};
+template<> struct IsIntegralHelper<unsigned long long> : TrueType {};
+template<> struct IsIntegralHelper<bool> : TrueType {};
+template<> struct IsIntegralHelper<wchar_t> : TrueType {};
+#ifdef MOZ_CHAR16_IS_NOT_WCHAR
+template<> struct IsIntegralHelper<char16_t> : TrueType {};
+#endif
+
+} /* namespace detail */
+
+/**
+ * IsIntegral determines whether a type is an integral type.
+ *
+ * mozilla::IsIntegral<int>::value is true;
+ * mozilla::IsIntegral<unsigned short>::value is true;
+ * mozilla::IsIntegral<const long>::value is true;
+ * mozilla::IsIntegral<int*>::value is false;
+ * mozilla::IsIntegral<double>::value is false;
+ *
+ * Note that the behavior of IsIntegral on char16_t and char32_t is
+ * unspecified.
+ */
+template<typename T>
+struct IsIntegral : detail::IsIntegralHelper<typename RemoveCV<T>::Type>
+{};
+
+template<typename T, typename U>
+struct IsSame;
+
+namespace detail {
+
+template<typename T>
+struct IsFloatingPointHelper
+ : IntegralConstant<bool,
+ IsSame<T, float>::value ||
+ IsSame<T, double>::value ||
+ IsSame<T, long double>::value>
+{};
+
+} // namespace detail
+
+/**
+ * IsFloatingPoint determines whether a type is a floating point type (float,
+ * double, long double).
+ *
+ * mozilla::IsFloatingPoint<int>::value is false;
+ * mozilla::IsFloatingPoint<const float>::value is true;
+ * mozilla::IsFloatingPoint<long double>::value is true;
+ * mozilla::IsFloatingPoint<double*>::value is false.
+ */
+template<typename T>
+struct IsFloatingPoint
+ : detail::IsFloatingPointHelper<typename RemoveCV<T>::Type>
+{};
+
+namespace detail {
+
+template<typename T>
+struct IsArrayHelper : FalseType {};
+
+template<typename T, decltype(sizeof(1)) N>
+struct IsArrayHelper<T[N]> : TrueType {};
+
+template<typename T>
+struct IsArrayHelper<T[]> : TrueType {};
+
+} // namespace detail
+
+/**
+ * IsArray determines whether a type is an array type, of known or unknown
+ * length.
+ *
+ * mozilla::IsArray<int>::value is false;
+ * mozilla::IsArray<int[]>::value is true;
+ * mozilla::IsArray<int[5]>::value is true.
+ */
+template<typename T>
+struct IsArray : detail::IsArrayHelper<typename RemoveCV<T>::Type>
+{};
+
+namespace detail {
+
+template<typename T>
+struct IsPointerHelper : FalseType {};
+
+template<typename T>
+struct IsPointerHelper<T*> : TrueType {};
+
+} // namespace detail
+
+/**
+ * IsPointer determines whether a type is a possibly-CV-qualified pointer type
+ * (but not a pointer-to-member type).
+ *
+ * mozilla::IsPointer<struct S*>::value is true;
+ * mozilla::IsPointer<int*>::value is true;
+ * mozilla::IsPointer<int**>::value is true;
+ * mozilla::IsPointer<const int*>::value is true;
+ * mozilla::IsPointer<int* const>::value is true;
+ * mozilla::IsPointer<int* volatile>::value is true;
+ * mozilla::IsPointer<void (*)(void)>::value is true;
+ * mozilla::IsPointer<int>::value is false;
+ * mozilla::IsPointer<struct S>::value is false.
+ * mozilla::IsPointer<int(struct S::*)>::value is false
+ */
+template<typename T>
+struct IsPointer : detail::IsPointerHelper<typename RemoveCV<T>::Type>
+{};
+
+/**
+ * IsLvalueReference determines whether a type is an lvalue reference.
+ *
+ * mozilla::IsLvalueReference<struct S*>::value is false;
+ * mozilla::IsLvalueReference<int**>::value is false;
+ * mozilla::IsLvalueReference<void (*)(void)>::value is false;
+ * mozilla::IsLvalueReference<int>::value is false;
+ * mozilla::IsLvalueReference<struct S>::value is false;
+ * mozilla::IsLvalueReference<struct S*&>::value is true;
+ * mozilla::IsLvalueReference<struct S&&>::value is false.
+ */
+template<typename T>
+struct IsLvalueReference : FalseType {};
+
+template<typename T>
+struct IsLvalueReference<T&> : TrueType {};
+
+/**
+ * IsRvalueReference determines whether a type is an rvalue reference.
+ *
+ * mozilla::IsRvalueReference<struct S*>::value is false;
+ * mozilla::IsRvalueReference<int**>::value is false;
+ * mozilla::IsRvalueReference<void (*)(void)>::value is false;
+ * mozilla::IsRvalueReference<int>::value is false;
+ * mozilla::IsRvalueReference<struct S>::value is false;
+ * mozilla::IsRvalueReference<struct S*&>::value is false;
+ * mozilla::IsRvalueReference<struct S&&>::value is true.
+ */
+template<typename T>
+struct IsRvalueReference : FalseType {};
+
+template<typename T>
+struct IsRvalueReference<T&&> : TrueType {};
+
+namespace detail {
+
+// __is_enum is a supported extension across all of our supported compilers.
+template<typename T>
+struct IsEnumHelper
+ : IntegralConstant<bool, __is_enum(T)>
+{};
+
+} // namespace detail
+
+/**
+ * IsEnum determines whether a type is an enum type.
+ *
+ * mozilla::IsEnum<enum S>::value is true;
+ * mozilla::IsEnum<enum S*>::value is false;
+ * mozilla::IsEnum<int>::value is false;
+ */
+template<typename T>
+struct IsEnum
+ : detail::IsEnumHelper<typename RemoveCV<T>::Type>
+{};
+
+namespace detail {
+
+// __is_class is a supported extension across all of our supported compilers:
+// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html
+// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits
+// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx
+template<typename T>
+struct IsClassHelper
+ : IntegralConstant<bool, __is_class(T)>
+{};
+
+} // namespace detail
+
+/**
+ * IsClass determines whether a type is a class type (but not a union).
+ *
+ * struct S {};
+ * union U {};
+ * mozilla::IsClass<int>::value is false;
+ * mozilla::IsClass<const S>::value is true;
+ * mozilla::IsClass<U>::value is false;
+ */
+template<typename T>
+struct IsClass
+ : detail::IsClassHelper<typename RemoveCV<T>::Type>
+{};
+
+/* 20.9.4.2 Composite type traits [meta.unary.comp] */
+
+/**
+ * IsReference determines whether a type is an lvalue or rvalue reference.
+ *
+ * mozilla::IsReference<struct S*>::value is false;
+ * mozilla::IsReference<int**>::value is false;
+ * mozilla::IsReference<int&>::value is true;
+ * mozilla::IsReference<void (*)(void)>::value is false;
+ * mozilla::IsReference<const int&>::value is true;
+ * mozilla::IsReference<int>::value is false;
+ * mozilla::IsReference<struct S>::value is false;
+ * mozilla::IsReference<struct S&>::value is true;
+ * mozilla::IsReference<struct S*&>::value is true;
+ * mozilla::IsReference<struct S&&>::value is true.
+ */
+template<typename T>
+struct IsReference
+ : IntegralConstant<bool,
+ IsLvalueReference<T>::value || IsRvalueReference<T>::value>
+{};
+
+/**
+ * IsArithmetic determines whether a type is arithmetic. A type is arithmetic
+ * iff it is an integral type or a floating point type.
+ *
+ * mozilla::IsArithmetic<int>::value is true;
+ * mozilla::IsArithmetic<double>::value is true;
+ * mozilla::IsArithmetic<long double*>::value is false.
+ */
+template<typename T>
+struct IsArithmetic
+ : IntegralConstant<bool, IsIntegral<T>::value || IsFloatingPoint<T>::value>
+{};
+
+/* 20.9.4.3 Type properties [meta.unary.prop] */
+
+/**
+ * IsConst determines whether a type is const or not.
+ *
+ * mozilla::IsConst<int>::value is false;
+ * mozilla::IsConst<void* const>::value is true;
+ * mozilla::IsConst<const char*>::value is false.
+ */
+template<typename T>
+struct IsConst : FalseType {};
+
+template<typename T>
+struct IsConst<const T> : TrueType {};
+
+/**
+ * IsVolatile determines whether a type is volatile or not.
+ *
+ * mozilla::IsVolatile<int>::value is false;
+ * mozilla::IsVolatile<void* volatile>::value is true;
+ * mozilla::IsVolatile<volatile char*>::value is false.
+ */
+template<typename T>
+struct IsVolatile : FalseType {};
+
+template<typename T>
+struct IsVolatile<volatile T> : TrueType {};
+
+/**
+ * Traits class for identifying POD types. Until C++11 there's no automatic
+ * way to detect PODs, so for the moment this is done manually. Users may
+ * define specializations of this class that inherit from mozilla::TrueType and
+ * mozilla::FalseType (or equivalently mozilla::IntegralConstant<bool, true or
+ * false>, or conveniently from mozilla::IsPod for composite types) as needed to
+ * ensure correct IsPod behavior.
+ */
+template<typename T>
+struct IsPod : public FalseType {};
+
+template<> struct IsPod<char> : TrueType {};
+template<> struct IsPod<signed char> : TrueType {};
+template<> struct IsPod<unsigned char> : TrueType {};
+template<> struct IsPod<short> : TrueType {};
+template<> struct IsPod<unsigned short> : TrueType {};
+template<> struct IsPod<int> : TrueType {};
+template<> struct IsPod<unsigned int> : TrueType {};
+template<> struct IsPod<long> : TrueType {};
+template<> struct IsPod<unsigned long> : TrueType {};
+template<> struct IsPod<long long> : TrueType {};
+template<> struct IsPod<unsigned long long> : TrueType {};
+template<> struct IsPod<bool> : TrueType {};
+template<> struct IsPod<float> : TrueType {};
+template<> struct IsPod<double> : TrueType {};
+template<> struct IsPod<wchar_t> : TrueType {};
+#ifdef MOZ_CHAR16_IS_NOT_WCHAR
+template<> struct IsPod<char16_t> : TrueType {};
+#endif
+template<typename T> struct IsPod<T*> : TrueType {};
+
+namespace detail {
+
+// __is_empty is a supported extension across all of our supported compilers:
+// http://llvm.org/releases/3.0/docs/ClangReleaseNotes.html
+// http://gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Type-Traits.html#Type-Traits
+// http://msdn.microsoft.com/en-us/library/ms177194%28v=vs.100%29.aspx
+template<typename T>
+struct IsEmptyHelper
+ : IntegralConstant<bool, IsClass<T>::value && __is_empty(T)>
+{};
+
+} // namespace detail
+
+/**
+ * IsEmpty determines whether a type is a class (but not a union) that is empty.
+ *
+ * A class is empty iff it and all its base classes have no non-static data
+ * members (except bit-fields of length 0) and no virtual member functions, and
+ * no base class is empty or a virtual base class.
+ *
+ * Intuitively, empty classes don't have any data that has to be stored in
+ * instances of those classes. (The size of the class must still be non-zero,
+ * because distinct array elements of any type must have different addresses.
+ * However, if the Empty Base Optimization is implemented by the compiler [most
+ * compilers implement it, and in certain cases C++11 requires it], the size of
+ * a class inheriting from an empty |Base| class need not be inflated by
+ * |sizeof(Base)|.) And intuitively, non-empty classes have data members and/or
+ * vtable pointers that must be stored in each instance for proper behavior.
+ *
+ * static_assert(!mozilla::IsEmpty<int>::value, "not a class => not empty");
+ * union U1 { int x; };
+ * static_assert(!mozilla::IsEmpty<U1>::value, "not a class => not empty");
+ * struct E1 {};
+ * struct E2 { int : 0 };
+ * struct E3 : E1 {};
+ * struct E4 : E2 {};
+ * static_assert(mozilla::IsEmpty<E1>::value &&
+ * mozilla::IsEmpty<E2>::value &&
+ * mozilla::IsEmpty<E3>::value &&
+ * mozilla::IsEmpty<E4>::value,
+ * "all empty");
+ * union U2 { E1 e1; };
+ * static_assert(!mozilla::IsEmpty<U2>::value, "not a class => not empty");
+ * struct NE1 { int x; };
+ * struct NE2 : virtual E1 {};
+ * struct NE3 : E2 { virtual ~NE3() {} };
+ * struct NE4 { virtual void f() {} };
+ * static_assert(!mozilla::IsEmpty<NE1>::value &&
+ * !mozilla::IsEmpty<NE2>::value &&
+ * !mozilla::IsEmpty<NE3>::value &&
+ * !mozilla::IsEmpty<NE4>::value,
+ * "all empty");
+ */
+template<typename T>
+struct IsEmpty : detail::IsEmptyHelper<typename RemoveCV<T>::Type>
+{};
+
+
+namespace detail {
+
+template<typename T,
+ bool = IsFloatingPoint<T>::value,
+ bool = IsIntegral<T>::value,
+ typename NoCV = typename RemoveCV<T>::Type>
+struct IsSignedHelper;
+
+// Floating point is signed.
+template<typename T, typename NoCV>
+struct IsSignedHelper<T, true, false, NoCV> : TrueType {};
+
+// Integral is conditionally signed.
+template<typename T, typename NoCV>
+struct IsSignedHelper<T, false, true, NoCV>
+ : IntegralConstant<bool, bool(NoCV(-1) < NoCV(1))>
+{};
+
+// Non-floating point, non-integral is not signed.
+template<typename T, typename NoCV>
+struct IsSignedHelper<T, false, false, NoCV> : FalseType {};
+
+} // namespace detail
+
+/**
+ * IsSigned determines whether a type is a signed arithmetic type. |char| is
+ * considered a signed type if it has the same representation as |signed char|.
+ *
+ * mozilla::IsSigned<int>::value is true;
+ * mozilla::IsSigned<const unsigned int>::value is false;
+ * mozilla::IsSigned<unsigned char>::value is false;
+ * mozilla::IsSigned<float>::value is true.
+ */
+template<typename T>
+struct IsSigned : detail::IsSignedHelper<T> {};
+
+namespace detail {
+
+template<typename T,
+ bool = IsFloatingPoint<T>::value,
+ bool = IsIntegral<T>::value,
+ typename NoCV = typename RemoveCV<T>::Type>
+struct IsUnsignedHelper;
+
+// Floating point is not unsigned.
+template<typename T, typename NoCV>
+struct IsUnsignedHelper<T, true, false, NoCV> : FalseType {};
+
+// Integral is conditionally unsigned.
+template<typename T, typename NoCV>
+struct IsUnsignedHelper<T, false, true, NoCV>
+ : IntegralConstant<bool,
+ (IsSame<NoCV, bool>::value || bool(NoCV(1) < NoCV(-1)))>
+{};
+
+// Non-floating point, non-integral is not unsigned.
+template<typename T, typename NoCV>
+struct IsUnsignedHelper<T, false, false, NoCV> : FalseType {};
+
+} // namespace detail
+
+/**
+ * IsUnsigned determines whether a type is an unsigned arithmetic type.
+ *
+ * mozilla::IsUnsigned<int>::value is false;
+ * mozilla::IsUnsigned<const unsigned int>::value is true;
+ * mozilla::IsUnsigned<unsigned char>::value is true;
+ * mozilla::IsUnsigned<float>::value is false.
+ */
+template<typename T>
+struct IsUnsigned : detail::IsUnsignedHelper<T> {};
+
+/* 20.9.5 Type property queries [meta.unary.prop.query] */
+
+/* 20.9.6 Relationships between types [meta.rel] */
+
+/**
+ * IsSame tests whether two types are the same type.
+ *
+ * mozilla::IsSame<int, int>::value is true;
+ * mozilla::IsSame<int*, int*>::value is true;
+ * mozilla::IsSame<int, unsigned int>::value is false;
+ * mozilla::IsSame<void, void>::value is true;
+ * mozilla::IsSame<const int, int>::value is false;
+ * mozilla::IsSame<struct S, struct S>::value is true.
+ */
+template<typename T, typename U>
+struct IsSame : FalseType {};
+
+template<typename T>
+struct IsSame<T, T> : TrueType {};
+
+namespace detail {
+
+#if defined(__GNUC__) || defined(__clang__) || defined(_MSC_VER)
+
+template<class Base, class Derived>
+struct BaseOfTester : IntegralConstant<bool, __is_base_of(Base, Derived)> {};
+
+#else
+
+// The trickery used to implement IsBaseOf here makes it possible to use it for
+// the cases of private and multiple inheritance. This code was inspired by the
+// sample code here:
+//
+// http://stackoverflow.com/questions/2910979/how-is-base-of-works
+template<class Base, class Derived>
+struct BaseOfHelper
+{
+public:
+ operator Base*() const;
+ operator Derived*();
+};
+
+template<class Base, class Derived>
+struct BaseOfTester
+{
+private:
+ template<class T>
+ static char test(Derived*, T);
+ static int test(Base*, int);
+
+public:
+ static const bool value =
+ sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char);
+};
+
+template<class Base, class Derived>
+struct BaseOfTester<Base, const Derived>
+{
+private:
+ template<class T>
+ static char test(Derived*, T);
+ static int test(Base*, int);
+
+public:
+ static const bool value =
+ sizeof(test(BaseOfHelper<Base, Derived>(), int())) == sizeof(char);
+};
+
+template<class Base, class Derived>
+struct BaseOfTester<Base&, Derived&> : FalseType {};
+
+template<class Type>
+struct BaseOfTester<Type, Type> : TrueType {};
+
+template<class Type>
+struct BaseOfTester<Type, const Type> : TrueType {};
+
+#endif
+
+} /* namespace detail */
+
+/*
+ * IsBaseOf allows to know whether a given class is derived from another.
+ *
+ * Consider the following class definitions:
+ *
+ * class A {};
+ * class B : public A {};
+ * class C {};
+ *
+ * mozilla::IsBaseOf<A, B>::value is true;
+ * mozilla::IsBaseOf<A, C>::value is false;
+ */
+template<class Base, class Derived>
+struct IsBaseOf
+ : IntegralConstant<bool, detail::BaseOfTester<Base, Derived>::value>
+{};
+
+namespace detail {
+
+template<typename From, typename To>
+struct ConvertibleTester
+{
+private:
+ static From create();
+
+ template<typename From1, typename To1>
+ static char test(To to);
+
+ template<typename From1, typename To1>
+ static int test(...);
+
+public:
+ static const bool value =
+ sizeof(test<From, To>(create())) == sizeof(char);
+};
+
+} // namespace detail
+
+/**
+ * IsConvertible determines whether a value of type From will implicitly convert
+ * to a value of type To. For example:
+ *
+ * struct A {};
+ * struct B : public A {};
+ * struct C {};
+ *
+ * mozilla::IsConvertible<A, A>::value is true;
+ * mozilla::IsConvertible<A*, A*>::value is true;
+ * mozilla::IsConvertible<B, A>::value is true;
+ * mozilla::IsConvertible<B*, A*>::value is true;
+ * mozilla::IsConvertible<C, A>::value is false;
+ * mozilla::IsConvertible<A, C>::value is false;
+ * mozilla::IsConvertible<A*, C*>::value is false;
+ * mozilla::IsConvertible<C*, A*>::value is false.
+ *
+ * For obscure reasons, you can't use IsConvertible when the types being tested
+ * are related through private inheritance, and you'll get a compile error if
+ * you try. Just don't do it!
+ *
+ * Note - we need special handling for void, which ConvertibleTester doesn't
+ * handle. The void handling here doesn't handle const/volatile void correctly,
+ * which could be easily fixed if the need arises.
+ */
+template<typename From, typename To>
+struct IsConvertible
+ : IntegralConstant<bool, detail::ConvertibleTester<From, To>::value>
+{};
+
+template<typename B>
+struct IsConvertible<void, B>
+ : IntegralConstant<bool, IsVoid<B>::value>
+{};
+
+template<typename A>
+struct IsConvertible<A, void>
+ : IntegralConstant<bool, IsVoid<A>::value>
+{};
+
+template<>
+struct IsConvertible<void, void>
+ : TrueType
+{};
+
+/* 20.9.7 Transformations between types [meta.trans] */
+
+/* 20.9.7.1 Const-volatile modifications [meta.trans.cv] */
+
+/**
+ * RemoveConst removes top-level const qualifications on a type.
+ *
+ * mozilla::RemoveConst<int>::Type is int;
+ * mozilla::RemoveConst<const int>::Type is int;
+ * mozilla::RemoveConst<const int*>::Type is const int*;
+ * mozilla::RemoveConst<int* const>::Type is int*.
+ */
+template<typename T>
+struct RemoveConst
+{
+ typedef T Type;
+};
+
+template<typename T>
+struct RemoveConst<const T>
+{
+ typedef T Type;
+};
+
+/**
+ * RemoveVolatile removes top-level volatile qualifications on a type.
+ *
+ * mozilla::RemoveVolatile<int>::Type is int;
+ * mozilla::RemoveVolatile<volatile int>::Type is int;
+ * mozilla::RemoveVolatile<volatile int*>::Type is volatile int*;
+ * mozilla::RemoveVolatile<int* volatile>::Type is int*.
+ */
+template<typename T>
+struct RemoveVolatile
+{
+ typedef T Type;
+};
+
+template<typename T>
+struct RemoveVolatile<volatile T>
+{
+ typedef T Type;
+};
+
+/**
+ * RemoveCV removes top-level const and volatile qualifications on a type.
+ *
+ * mozilla::RemoveCV<int>::Type is int;
+ * mozilla::RemoveCV<const int>::Type is int;
+ * mozilla::RemoveCV<volatile int>::Type is int;
+ * mozilla::RemoveCV<int* const volatile>::Type is int*.
+ */
+template<typename T>
+struct RemoveCV
+{
+ typedef typename RemoveConst<typename RemoveVolatile<T>::Type>::Type Type;
+};
+
+/* 20.9.7.2 Reference modifications [meta.trans.ref] */
+
+/**
+ * Converts reference types to the underlying types.
+ *
+ * mozilla::RemoveReference<T>::Type is T;
+ * mozilla::RemoveReference<T&>::Type is T;
+ * mozilla::RemoveReference<T&&>::Type is T;
+ */
+
+template<typename T>
+struct RemoveReference
+{
+ typedef T Type;
+};
+
+template<typename T>
+struct RemoveReference<T&>
+{
+ typedef T Type;
+};
+
+template<typename T>
+struct RemoveReference<T&&>
+{
+ typedef T Type;
+};
+
+template<bool Condition, typename A, typename B>
+struct Conditional;
+
+namespace detail {
+
+enum Voidness { TIsVoid, TIsNotVoid };
+
+template<typename T, Voidness V = IsVoid<T>::value ? TIsVoid : TIsNotVoid>
+struct AddLvalueReferenceHelper;
+
+template<typename T>
+struct AddLvalueReferenceHelper<T, TIsVoid>
+{
+ typedef void Type;
+};
+
+template<typename T>
+struct AddLvalueReferenceHelper<T, TIsNotVoid>
+{
+ typedef T& Type;
+};
+
+} // namespace detail
+
+/**
+ * AddLvalueReference adds an lvalue & reference to T if one isn't already
+ * present. (Note: adding an lvalue reference to an rvalue && reference in
+ * essence replaces the && with a &&, per C+11 reference collapsing rules. For
+ * example, int&& would become int&.)
+ *
+ * The final computed type will only *not* be an lvalue reference if T is void.
+ *
+ * mozilla::AddLvalueReference<int>::Type is int&;
+ * mozilla::AddLvalueRference<volatile int&>::Type is volatile int&;
+ * mozilla::AddLvalueReference<void*>::Type is void*&;
+ * mozilla::AddLvalueReference<void>::Type is void;
+ * mozilla::AddLvalueReference<struct S&&>::Type is struct S&.
+ */
+template<typename T>
+struct AddLvalueReference
+ : detail::AddLvalueReferenceHelper<T>
+{};
+
+namespace detail {
+
+template<typename T, Voidness V = IsVoid<T>::value ? TIsVoid : TIsNotVoid>
+struct AddRvalueReferenceHelper;
+
+template<typename T>
+struct AddRvalueReferenceHelper<T, TIsVoid>
+{
+ typedef void Type;
+};
+
+template<typename T>
+struct AddRvalueReferenceHelper<T, TIsNotVoid>
+{
+ typedef T&& Type;
+};
+
+} // namespace detail
+
+/**
+ * AddRvalueReference adds an rvalue && reference to T if one isn't already
+ * present. (Note: adding an rvalue reference to an lvalue & reference in
+ * essence keeps the &, per C+11 reference collapsing rules. For example,
+ * int& would remain int&.)
+ *
+ * The final computed type will only *not* be a reference if T is void.
+ *
+ * mozilla::AddRvalueReference<int>::Type is int&&;
+ * mozilla::AddRvalueRference<volatile int&>::Type is volatile int&;
+ * mozilla::AddRvalueRference<const int&&>::Type is const int&&;
+ * mozilla::AddRvalueReference<void*>::Type is void*&&;
+ * mozilla::AddRvalueReference<void>::Type is void;
+ * mozilla::AddRvalueReference<struct S&>::Type is struct S&.
+ */
+template<typename T>
+struct AddRvalueReference
+ : detail::AddRvalueReferenceHelper<T>
+{};
+
+/* 20.2.4 Function template declval [declval] */
+
+/**
+ * DeclVal simplifies the definition of expressions which occur as unevaluated
+ * operands. It converts T to a reference type, making it possible to use in
+ * decltype expressions even if T does not have a default constructor, e.g.:
+ * decltype(DeclVal<TWithNoDefaultConstructor>().foo())
+ */
+template<typename T>
+typename AddRvalueReference<T>::Type DeclVal();
+
+/* 20.9.7.3 Sign modifications [meta.trans.sign] */
+
+template<bool B, typename T = void>
+struct EnableIf;
+
+namespace detail {
+
+template<bool MakeConst, typename T>
+struct WithC : Conditional<MakeConst, const T, T>
+{};
+
+template<bool MakeVolatile, typename T>
+struct WithV : Conditional<MakeVolatile, volatile T, T>
+{};
+
+
+template<bool MakeConst, bool MakeVolatile, typename T>
+struct WithCV : WithC<MakeConst, typename WithV<MakeVolatile, T>::Type>
+{};
+
+template<typename T>
+struct CorrespondingSigned;
+
+template<>
+struct CorrespondingSigned<char> { typedef signed char Type; };
+template<>
+struct CorrespondingSigned<unsigned char> { typedef signed char Type; };
+template<>
+struct CorrespondingSigned<unsigned short> { typedef short Type; };
+template<>
+struct CorrespondingSigned<unsigned int> { typedef int Type; };
+template<>
+struct CorrespondingSigned<unsigned long> { typedef long Type; };
+template<>
+struct CorrespondingSigned<unsigned long long> { typedef long long Type; };
+
+template<typename T,
+ typename CVRemoved = typename RemoveCV<T>::Type,
+ bool IsSignedIntegerType = IsSigned<CVRemoved>::value &&
+ !IsSame<char, CVRemoved>::value>
+struct MakeSigned;
+
+template<typename T, typename CVRemoved>
+struct MakeSigned<T, CVRemoved, true>
+{
+ typedef T Type;
+};
+
+template<typename T, typename CVRemoved>
+struct MakeSigned<T, CVRemoved, false>
+ : WithCV<IsConst<T>::value, IsVolatile<T>::value,
+ typename CorrespondingSigned<CVRemoved>::Type>
+{};
+
+} // namespace detail
+
+/**
+ * MakeSigned produces the corresponding signed integer type for a given
+ * integral type T, with the const/volatile qualifiers of T. T must be a
+ * possibly-const/volatile-qualified integral type that isn't bool.
+ *
+ * If T is already a signed integer type (not including char!), then T is
+ * produced.
+ *
+ * Otherwise, if T is an unsigned integer type, the signed variety of T, with
+ * T's const/volatile qualifiers, is produced.
+ *
+ * Otherwise, the integral type of the same size as T, with the lowest rank,
+ * with T's const/volatile qualifiers, is produced. (This basically only acts
+ * to produce signed char when T = char.)
+ *
+ * mozilla::MakeSigned<unsigned long>::Type is signed long;
+ * mozilla::MakeSigned<volatile int>::Type is volatile int;
+ * mozilla::MakeSigned<const unsigned short>::Type is const signed short;
+ * mozilla::MakeSigned<const char>::Type is const signed char;
+ * mozilla::MakeSigned<bool> is an error;
+ * mozilla::MakeSigned<void*> is an error.
+ */
+template<typename T>
+struct MakeSigned
+ : EnableIf<IsIntegral<T>::value &&
+ !IsSame<bool, typename RemoveCV<T>::Type>::value,
+ typename detail::MakeSigned<T>
+ >::Type
+{};
+
+namespace detail {
+
+template<typename T>
+struct CorrespondingUnsigned;
+
+template<>
+struct CorrespondingUnsigned<char> { typedef unsigned char Type; };
+template<>
+struct CorrespondingUnsigned<signed char> { typedef unsigned char Type; };
+template<>
+struct CorrespondingUnsigned<short> { typedef unsigned short Type; };
+template<>
+struct CorrespondingUnsigned<int> { typedef unsigned int Type; };
+template<>
+struct CorrespondingUnsigned<long> { typedef unsigned long Type; };
+template<>
+struct CorrespondingUnsigned<long long> { typedef unsigned long long Type; };
+
+
+template<typename T,
+ typename CVRemoved = typename RemoveCV<T>::Type,
+ bool IsUnsignedIntegerType = IsUnsigned<CVRemoved>::value &&
+ !IsSame<char, CVRemoved>::value>
+struct MakeUnsigned;
+
+template<typename T, typename CVRemoved>
+struct MakeUnsigned<T, CVRemoved, true>
+{
+ typedef T Type;
+};
+
+template<typename T, typename CVRemoved>
+struct MakeUnsigned<T, CVRemoved, false>
+ : WithCV<IsConst<T>::value, IsVolatile<T>::value,
+ typename CorrespondingUnsigned<CVRemoved>::Type>
+{};
+
+} // namespace detail
+
+/**
+ * MakeUnsigned produces the corresponding unsigned integer type for a given
+ * integral type T, with the const/volatile qualifiers of T. T must be a
+ * possibly-const/volatile-qualified integral type that isn't bool.
+ *
+ * If T is already an unsigned integer type (not including char!), then T is
+ * produced.
+ *
+ * Otherwise, if T is a signed integer type, the unsigned variety of T, with
+ * T's const/volatile qualifiers, is produced.
+ *
+ * Otherwise, the unsigned integral type of the same size as T, with the lowest
+ * rank, with T's const/volatile qualifiers, is produced. (This basically only
+ * acts to produce unsigned char when T = char.)
+ *
+ * mozilla::MakeUnsigned<signed long>::Type is unsigned long;
+ * mozilla::MakeUnsigned<volatile unsigned int>::Type is volatile unsigned int;
+ * mozilla::MakeUnsigned<const signed short>::Type is const unsigned short;
+ * mozilla::MakeUnsigned<const char>::Type is const unsigned char;
+ * mozilla::MakeUnsigned<bool> is an error;
+ * mozilla::MakeUnsigned<void*> is an error.
+ */
+template<typename T>
+struct MakeUnsigned
+ : EnableIf<IsIntegral<T>::value &&
+ !IsSame<bool, typename RemoveCV<T>::Type>::value,
+ typename detail::MakeUnsigned<T>
+ >::Type
+{};
+
+/* 20.9.7.4 Array modifications [meta.trans.arr] */
+
+/**
+ * RemoveExtent produces either the type of the elements of the array T, or T
+ * itself.
+ *
+ * mozilla::RemoveExtent<int>::Type is int;
+ * mozilla::RemoveExtent<const int[]>::Type is const int;
+ * mozilla::RemoveExtent<volatile int[5]>::Type is volatile int;
+ * mozilla::RemoveExtent<long[][17]>::Type is long[17].
+ */
+template<typename T>
+struct RemoveExtent
+{
+ typedef T Type;
+};
+
+template<typename T>
+struct RemoveExtent<T[]>
+{
+ typedef T Type;
+};
+
+template<typename T, decltype(sizeof(1)) N>
+struct RemoveExtent<T[N]>
+{
+ typedef T Type;
+};
+
+/* 20.9.7.5 Pointer modifications [meta.trans.ptr] */
+
+namespace detail {
+
+template<typename T, typename CVRemoved>
+struct RemovePointerHelper
+{
+ typedef T Type;
+};
+
+template<typename T, typename Pointee>
+struct RemovePointerHelper<T, Pointee*>
+{
+ typedef Pointee Type;
+};
+
+} // namespace detail
+
+/**
+ * Produces the pointed-to type if a pointer is provided, else returns the input
+ * type. Note that this does not dereference pointer-to-member pointers.
+ *
+ * struct S { bool m; void f(); };
+ * mozilla::RemovePointer<int>::Type is int;
+ * mozilla::RemovePointer<int*>::Type is int;
+ * mozilla::RemovePointer<int* const>::Type is int;
+ * mozilla::RemovePointer<int* volatile>::Type is int;
+ * mozilla::RemovePointer<const long*>::Type is const long;
+ * mozilla::RemovePointer<void* const>::Type is void;
+ * mozilla::RemovePointer<void (S::*)()>::Type is void (S::*)();
+ * mozilla::RemovePointer<void (*)()>::Type is void();
+ * mozilla::RemovePointer<bool S::*>::Type is bool S::*.
+ */
+template<typename T>
+struct RemovePointer
+ : detail::RemovePointerHelper<T, typename RemoveCV<T>::Type>
+{};
+
+/* 20.9.7.6 Other transformations [meta.trans.other] */
+
+/**
+ * EnableIf is a struct containing a typedef of T if and only if B is true.
+ *
+ * mozilla::EnableIf<true, int>::Type is int;
+ * mozilla::EnableIf<false, int>::Type is a compile-time error.
+ *
+ * Use this template to implement SFINAE-style (Substitution Failure Is not An
+ * Error) requirements. For example, you might use it to impose a restriction
+ * on a template parameter:
+ *
+ * template<typename T>
+ * class PodVector // vector optimized to store POD (memcpy-able) types
+ * {
+ * EnableIf<IsPod<T>::value, T>::Type* vector;
+ * size_t length;
+ * ...
+ * };
+ */
+template<bool B, typename T>
+struct EnableIf
+{};
+
+template<typename T>
+struct EnableIf<true, T>
+{
+ typedef T Type;
+};
+
+/**
+ * Conditional selects a class between two, depending on a given boolean value.
+ *
+ * mozilla::Conditional<true, A, B>::Type is A;
+ * mozilla::Conditional<false, A, B>::Type is B;
+ */
+template<bool Condition, typename A, typename B>
+struct Conditional
+{
+ typedef A Type;
+};
+
+template<class A, class B>
+struct Conditional<false, A, B>
+{
+ typedef B Type;
+};
+
+} /* namespace mozilla */
+
+#endif /* mozilla_TypeTraits_h */
diff --git a/include/onlineupdate/mozilla/Types.h b/include/onlineupdate/mozilla/Types.h
new file mode 100644
index 000000000..9d1e34b6d
--- /dev/null
+++ b/include/onlineupdate/mozilla/Types.h
@@ -0,0 +1,134 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+/* mfbt foundational types and macros. */
+
+#ifndef mozilla_Types_h
+#define mozilla_Types_h
+
+/*
+ * This header must be valid C and C++, includable by code embedding either
+ * SpiderMonkey or Gecko.
+ */
+
+/* Expose all <stdint.h> types and size_t. */
+#include <stddef.h>
+#include <stdint.h>
+
+/* Implement compiler and linker macros needed for APIs. */
+
+/*
+ * MOZ_EXPORT is used to declare and define a symbol or type which is externally
+ * visible to users of the current library. It encapsulates various decorations
+ * needed to properly export the method's symbol.
+ *
+ * api.h:
+ * extern MOZ_EXPORT int MeaningOfLife(void);
+ * extern MOZ_EXPORT int LuggageCombination;
+ *
+ * api.c:
+ * int MeaningOfLife(void) { return 42; }
+ * int LuggageCombination = 12345;
+ *
+ * If you are merely sharing a method across files, just use plain |extern|.
+ * These macros are designed for use by library interfaces -- not for normal
+ * methods or data used cross-file.
+ */
+#if defined(_WIN32)
+# define MOZ_EXPORT __declspec(dllexport)
+#else /* Unix */
+# ifdef HAVE_VISIBILITY_ATTRIBUTE
+# define MOZ_EXPORT __attribute__((visibility("default")))
+# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+# define MOZ_EXPORT __global
+# else
+# define MOZ_EXPORT /* nothing */
+# endif
+#endif
+
+
+/*
+ * Whereas implementers use MOZ_EXPORT to declare and define library symbols,
+ * users use MOZ_IMPORT_API and MOZ_IMPORT_DATA to access them. Most often the
+ * implementer of the library will expose an API macro which expands to either
+ * the export or import version of the macro, depending upon the compilation
+ * mode.
+ */
+#ifdef _WIN32
+# if defined(__MWERKS__)
+# define MOZ_IMPORT_API /* nothing */
+# else
+# define MOZ_IMPORT_API __declspec(dllimport)
+# endif
+#else
+# define MOZ_IMPORT_API MOZ_EXPORT
+#endif
+
+#if defined(_WIN32) && !defined(__MWERKS__)
+# define MOZ_IMPORT_DATA __declspec(dllimport)
+#else
+# define MOZ_IMPORT_DATA MOZ_EXPORT
+#endif
+
+/*
+ * Consistent with the above comment, the MFBT_API and MFBT_DATA macros expose
+ * export mfbt declarations when building mfbt, and they expose import mfbt
+ * declarations when using mfbt.
+ */
+#if defined(IMPL_MFBT)
+# define MFBT_API MOZ_EXPORT
+# define MFBT_DATA MOZ_EXPORT
+#else
+ /*
+ * On linux mozglue is linked in the program and we link libxul.so with
+ * -z,defs. Normally that causes the linker to reject undefined references in
+ * libxul.so, but as a loophole it allows undefined references to weak
+ * symbols. We add the weak attribute to the import version of the MFBT API
+ * macros to exploit this.
+ */
+# if defined(MOZ_GLUE_IN_PROGRAM) && !defined(MOZILLA_XPCOMRT_API)
+# define MFBT_API __attribute__((weak)) MOZ_IMPORT_API
+# define MFBT_DATA __attribute__((weak)) MOZ_IMPORT_DATA
+# else
+# define MFBT_API MOZ_IMPORT_API
+# define MFBT_DATA MOZ_IMPORT_DATA
+# endif
+#endif
+
+/*
+ * C symbols in C++ code must be declared immediately within |extern "C"|
+ * blocks. However, in C code, they need not be declared specially. This
+ * difference is abstracted behind the MOZ_BEGIN_EXTERN_C and MOZ_END_EXTERN_C
+ * macros, so that the user need not know whether he is being used in C or C++
+ * code.
+ *
+ * MOZ_BEGIN_EXTERN_C
+ *
+ * extern MOZ_EXPORT int MostRandomNumber(void);
+ * ...other declarations...
+ *
+ * MOZ_END_EXTERN_C
+ *
+ * This said, it is preferable to just use |extern "C"| in C++ header files for
+ * its greater clarity.
+ */
+#ifdef __cplusplus
+# define MOZ_BEGIN_EXTERN_C extern "C" {
+# define MOZ_END_EXTERN_C }
+#else
+# define MOZ_BEGIN_EXTERN_C
+# define MOZ_END_EXTERN_C
+#endif
+
+/*
+ * GCC's typeof is available when decltype is not.
+ */
+#if defined(__GNUC__) && defined(__cplusplus) && \
+ !defined(__GXX_EXPERIMENTAL_CXX0X__) && __cplusplus < 201103L
+# define decltype __typeof__
+#endif
+
+#endif /* mozilla_Types_h */
diff --git a/include/onlineupdate/mozilla/nsTraceRefcnt.h b/include/onlineupdate/mozilla/nsTraceRefcnt.h
new file mode 100644
index 000000000..c5b1de7e8
--- /dev/null
+++ b/include/onlineupdate/mozilla/nsTraceRefcnt.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 nsTraceRefcnt_h___
+#define nsTraceRefcnt_h___
+
+#include <stdio.h> // for FILE
+#include "nscore.h"
+
+class nsTraceRefcnt
+{
+public:
+ static void Shutdown();
+
+ enum StatisticsType {
+ ALL_STATS,
+ NEW_STATS
+ };
+
+ static nsresult DumpStatistics(StatisticsType aType = ALL_STATS,
+ FILE* aOut = 0);
+
+ static void ResetStatistics();
+
+ static void DemangleSymbol(const char* aSymbol, char* aBuffer, int aBufLen);
+
+ static void WalkTheStack(FILE* aStream);
+
+ /**
+ * This is a variant of |WalkTheStack| that uses |CodeAddressService| to cache
+ * the results of |NS_DescribeCodeAddress|. If |WalkTheStackCached| is being
+ * called frequently, it will be a few orders of magnitude faster than
+ * |WalkTheStack|. However, the cache uses a lot of memory, which can cause
+ * OOM crashes. Therefore, this should only be used for things like refcount
+ * logging which walk the stack extremely frequently.
+ */
+ static void WalkTheStackCached(FILE* aStream);
+
+ /**
+ * Tell nsTraceRefcnt whether refcounting, allocation, and destruction
+ * activity is legal. This is used to trigger assertions for any such
+ * activity that occurs because of static constructors or destructors.
+ */
+ static void SetActivityIsLegal(bool aLegal);
+};
+
+#define NS_TRACE_REFCNT_CONTRACTID "@mozilla.org/xpcom/trace-refcnt;1"
+#define NS_TRACE_REFCNT_CID \
+{ /* e3e7511e-a395-4924-94b1-d527861cded4 */ \
+ 0xe3e7511e, \
+ 0xa395, \
+ 0x4924, \
+ {0x94, 0xb1, 0xd5, 0x27, 0x86, 0x1c, 0xde, 0xd4} \
+} \
+
+////////////////////////////////////////////////////////////////////////////////
+// And now for that utility that you've all been asking for...
+
+extern "C" void
+NS_MeanAndStdDev(double aNumberOfValues,
+ double aSumOfValues, double aSumOfSquaredValues,
+ double* aMeanResult, double* aStdDevResult);
+
+////////////////////////////////////////////////////////////////////////////////
+#endif