Merge mozilla-central to autoland. a=merge CLOSED TREE

This commit is contained in:
Gurzau Raul 2018-07-02 00:52:31 +03:00
Родитель 1f770d80e5 bdc12b755f
Коммит a5fae08102
96 изменённых файлов: 2990 добавлений и 2650 удалений

33
Cargo.lock сгенерированный
Просмотреть файл

@ -156,17 +156,18 @@ dependencies = [
[[package]]
name = "bindgen"
version = "0.33.2"
version = "0.37.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"clang-sys 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clang-sys 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)",
"clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"which 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -293,7 +294,7 @@ dependencies = [
[[package]]
name = "clang-sys"
version = "0.22.0"
version = "0.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -463,7 +464,7 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -547,7 +548,7 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -977,7 +978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "js"
version = "0.1.4"
dependencies = [
"bindgen 0.33.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.37.4 (registry+https://github.com/rust-lang/crates.io-index)",
"cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)",
"env_logger 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1592,7 +1593,7 @@ version = "0.0.1"
[[package]]
name = "proc-macro2"
version = "0.3.6"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1641,7 +1642,7 @@ name = "quote"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -1936,7 +1937,7 @@ dependencies = [
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.33.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.37.4 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2029,7 +2030,7 @@ name = "syn"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -2049,7 +2050,7 @@ name = "synstructure"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
"proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2533,7 +2534,7 @@ dependencies = [
"checksum base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "96434f987501f0ed4eb336a411e0631ecd1afa11574fe148587adc4ff96143c9"
"checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
"checksum bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bda13183df33055cbb84b847becce220d392df502ebe7a4a78d7021771ed94d0"
"checksum bindgen 0.33.2 (registry+https://github.com/rust-lang/crates.io-index)" = "603ed8d8392ace9581e834e26bd09799bf1e989a79bd1aedbb893e72962bdc6e"
"checksum bindgen 0.37.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1b25ab82877ea8fe6ce1ce1f8ac54361f0218bad900af9eb11803994bf67c221"
"checksum binjs_meta 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9fcfc86eecb125147e907529a5f1ac7978f6f26d20a52b82a7e053da5faefbc3"
"checksum bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9bf6104718e80d7b26a68fdbacff3481cfc05df670821affc7e9cbc1884400c"
"checksum bit-vec 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "02b4ff8b16e6076c3e14220b39fbc1fabb6737522281a388998046859400895f"
@ -2550,7 +2551,7 @@ dependencies = [
"checksum cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "393a5f0088efbe41f9d1fcd062f24e83c278608420e62109feb2c8abee07de7d"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum chrono 0.2.25 (registry+https://github.com/rust-lang/crates.io-index)" = "9213f7cd7c27e95c2b57c49f0e69b1ea65b27138da84a170133fd21b07659c00"
"checksum clang-sys 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "939a1a34310b120d26eba35c29475933128b0ec58e24b43327f8dbe6036fc538"
"checksum clang-sys 0.23.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d7f7c04e52c35222fffcc3a115b5daf5f7e2bfb71c13c4e2321afe1fc71859c2"
"checksum clap 2.31.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f0f16b89cbb9ee36d87483dc939fe9f1e13c05898d56d7b230a0d4dff033a536"
"checksum cmake 0.1.29 (registry+https://github.com/rust-lang/crates.io-index)" = "56d741ea7a69e577f6d06b36b7dff4738f680593dc27a701ffa8506b73ce28bb"
"checksum cookie 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "746858cae4eae40fff37e1998320068df317bc247dc91a67c6cfa053afdc2abb"
@ -2673,7 +2674,7 @@ dependencies = [
"checksum plane-split 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7079b8485b4f9d9560dee7a69ca8f6ca781f9f284ff9d2bf27255d440b03e4af"
"checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0"
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
"checksum proc-macro2 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4"
"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
"checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"

Просмотреть файл

@ -562,35 +562,6 @@ class SameOriginCheckerImpl final : public nsIChannelEventSink,
} // namespace
class nsContentUtils::nsContentUtilsReporter final : public nsIMemoryReporter
{
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf);
~nsContentUtilsReporter() = default;
public:
NS_DECL_ISUPPORTS
NS_IMETHOD
CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData, bool aAnonymize) override
{
int64_t amt = 0;
for (int32_t i = 0; i < PropertiesFile_COUNT; ++i) {
if (sStringBundles[i]) {
amt += sStringBundles[i]->SizeOfIncludingThisIfUnshared(MallocSizeOf);
}
}
MOZ_COLLECT_REPORT("explicit/dom/content-utils-string-bundles", KIND_HEAP, UNITS_BYTES,
amt, "string-bundles in ContentUtils");
return NS_OK;
}
};
NS_IMPL_ISUPPORTS(nsContentUtils::nsContentUtilsReporter, nsIMemoryReporter)
/**
* This class is used to determine whether or not the user is currently
* interacting with the browser. It listens to observer events to toggle the
@ -691,7 +662,6 @@ nsContentUtils::Init()
new PLDHashTable(&hash_table_ops, sizeof(EventListenerManagerMapEntry));
RegisterStrongMemoryReporter(new DOMEventListenerManagersHashReporter());
RegisterStrongMemoryReporter(new nsContentUtilsReporter());
}
sBlockedScriptRunners = new AutoTArray<nsCOMPtr<nsIRunnable>, 8>;
@ -3920,6 +3890,8 @@ nsContentUtils::GetEventArgNames(int32_t aNameSpaceID,
}
}
// Note: The list of content bundles in nsStringBundle.cpp should be updated
// whenever entries are added or removed from this list.
static const char gPropertiesFiles[nsContentUtils::PropertiesFile_COUNT][56] = {
// Must line up with the enum values in |PropertiesFile| enum.
"chrome://global/locale/css.properties",
@ -3960,6 +3932,18 @@ nsContentUtils::EnsureStringBundle(PropertiesFile aFile)
void
nsContentUtils::AsyncPrecreateStringBundles()
{
// We only ever want to pre-create bundles in the parent process.
//
// All nsContentUtils bundles are shared between the parent and child
// precesses, and the shared memory regions that back them *must* be created
// in the parent, and then sent to all children.
//
// If we attempt to create a bundle in the child before its memory region is
// available, we need to create a temporary non-shared bundle, and later
// replace that with the shared memory copy. So attempting to pre-load in the
// child is wasteful and unnecessary.
MOZ_ASSERT(XRE_IsParentProcess());
for (uint32_t bundleIndex = 0; bundleIndex < PropertiesFile_COUNT; ++bundleIndex) {
nsresult rv = NS_IdleDispatchToCurrentThread(
NS_NewRunnableFunction("AsyncPrecreateStringBundles",

Просмотреть файл

@ -85,6 +85,7 @@
#include "GMPServiceChild.h"
#include "NullPrincipal.h"
#include "nsISimpleEnumerator.h"
#include "nsIStringBundle.h"
#include "nsIWorkerDebuggerManager.h"
#if !defined(XP_WIN)
@ -2262,11 +2263,6 @@ ContentChild::RecvRegisterChrome(InfallibleTArray<ChromePackage>&& packages,
static_cast<nsChromeRegistryContent*>(registrySvc.get());
chromeRegistry->RegisterRemoteChrome(packages, resources, overrides,
locale, reset);
static bool preloadDone = false;
if (!preloadDone) {
preloadDone = true;
nsContentUtils::AsyncPrecreateStringBundles();
}
return IPC_OK();
}
@ -2536,6 +2532,20 @@ ContentChild::RecvAsyncMessage(const nsString& aMsg,
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentChild::RecvRegisterStringBundles(nsTArray<mozilla::dom::StringBundleDescriptor>&& aDescriptors)
{
nsCOMPtr<nsIStringBundleService> stringBundleService =
services::GetStringBundleService();
for (auto& descriptor : aDescriptors) {
stringBundleService->RegisterContentBundle(descriptor.bundleURL(), descriptor.mapFile(),
descriptor.mapSize());
}
return IPC_OK();
}
mozilla::ipc::IPCResult
ContentChild::RecvGeolocationUpdate(nsIDOMGeoPosition* aPosition)
{

Просмотреть файл

@ -394,6 +394,8 @@ public:
const IPC::Principal& aPrincipal,
const ClonedMessageData& aData) override;
mozilla::ipc::IPCResult RecvRegisterStringBundles(nsTArray<StringBundleDescriptor>&& stringBundles) override;
virtual mozilla::ipc::IPCResult RecvGeolocationUpdate(nsIDOMGeoPosition* aPosition) override;
virtual mozilla::ipc::IPCResult RecvGeolocationError(const uint16_t& errorCode) override;

Просмотреть файл

@ -146,6 +146,7 @@
#include "nsISiteSecurityService.h"
#include "nsISound.h"
#include "nsISpellChecker.h"
#include "nsIStringBundle.h"
#include "nsISupportsPrimitives.h"
#include "nsITimer.h"
#include "nsIURIFixup.h"
@ -1277,6 +1278,17 @@ ContentParent::GetAllEvenIfDead(nsTArray<ContentParent*>& aArray)
}
}
void
ContentParent::BroadcastStringBundle(const StringBundleDescriptor& aBundle)
{
AutoTArray<StringBundleDescriptor, 1> array;
array.AppendElement(aBundle);
for (auto* cp : AllProcesses(eLive)) {
Unused << cp->SendRegisterStringBundles(array);
}
}
const nsAString&
ContentParent::GetRemoteType() const
{
@ -2317,6 +2329,10 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority)
static_cast<nsChromeRegistryChrome*>(registrySvc.get());
chromeRegistry->SendRegisteredChrome(this);
nsCOMPtr<nsIStringBundleService> stringBundleService =
services::GetStringBundleService();
stringBundleService->SendContentBundles(this);
if (gAppData) {
nsCString version(gAppData->version);
nsCString buildID(gAppData->buildID);

Просмотреть файл

@ -204,6 +204,8 @@ public:
static void GetAllEvenIfDead(nsTArray<ContentParent*>& aArray);
static void BroadcastStringBundle(const StringBundleDescriptor&);
const nsAString& GetRemoteType() const;
virtual void DoGetRemoteType(nsAString& aRemoteType, ErrorResult& aError) const override

129
dom/ipc/MemMapSnapshot.cpp Normal file
Просмотреть файл

@ -0,0 +1,129 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "MemMapSnapshot.h"
#include "base/eintr_wrapper.h"
#include "base/file_util.h"
#include "mozilla/ResultExtensions.h"
#include "mozilla/ScopeExit.h"
#include "mozilla/ipc/FileDescriptorUtils.h"
#include "nsIFile.h"
#ifdef XP_UNIX
# include <sys/stat.h>
#endif
namespace mozilla {
using loader::AutoMemMap;
namespace ipc {
Result<Ok, nsresult>
MemMapSnapshot::Init(size_t aSize)
{
MOZ_ASSERT(!mInitialized);
MOZ_TRY(Create(aSize));
mInitialized = true;
return Ok();
}
Result<Ok, nsresult>
MemMapSnapshot::Finalize(AutoMemMap& aMem)
{
MOZ_ASSERT(mInitialized);
MOZ_TRY(Freeze(aMem));
mInitialized = false;
return Ok();
}
#if defined(XP_WIN)
Result<Ok, nsresult>
MemMapSnapshot::Create(size_t aSize)
{
HANDLE handle = CreateFileMapping(
INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE,
0, DWORD(aSize), nullptr);
if (!handle) {
return Err(NS_ERROR_FAILURE);
}
mFile.emplace(handle);
return mMem.initWithHandle(mFile.ref(), aSize, PR_PROT_READWRITE);
}
Result<Ok, nsresult>
MemMapSnapshot::Freeze(AutoMemMap& aMem)
{
auto orig = mFile.ref().ClonePlatformHandle();
mFile.reset();
HANDLE handle;
if (!::DuplicateHandle(GetCurrentProcess(), orig.release(), GetCurrentProcess(),
&handle, GENERIC_READ | FILE_MAP_READ,
false, DUPLICATE_CLOSE_SOURCE)) {
return Err(NS_ERROR_FAILURE);
}
return aMem.initWithHandle(FileDescriptor(handle), mMem.size());
}
#elif defined(XP_UNIX)
Result<Ok, nsresult>
MemMapSnapshot::Create(size_t aSize)
{
FilePath path;
ScopedCloseFile fd(file_util::CreateAndOpenTemporaryShmemFile(&path));
if (!fd) {
return Err(NS_ERROR_FAILURE);
}
if (HANDLE_EINTR(ftruncate(fileno(fd), aSize)) != 0) {
return Err(NS_ERROR_FAILURE);
}
MOZ_TRY(mMem.init(FILEToFileDescriptor(fd), PR_PROT_READWRITE));
mPath.Assign(path.value().data(), path.value().length());
return Ok();
}
Result<Ok, nsresult>
MemMapSnapshot::Freeze(AutoMemMap& aMem)
{
// Delete the shm file after we're done here, whether we succeed or not. The
// open file descriptor will keep it alive until all remaining references
// are closed, at which point it will be automatically freed.
auto cleanup = MakeScopeExit([&]() {
PR_Delete(mPath.get());
});
// Make the shm file readonly. This doesn't make a difference in practice,
// since we open and share a read-only file descriptor, and then delete the
// file. But it doesn't hurt, either.
chmod(mPath.get(), 0400);
nsCOMPtr<nsIFile> file;
MOZ_TRY(NS_NewNativeLocalFile(mPath, /* followLinks = */ false,
getter_AddRefs(file)));
return aMem.init(file);
}
#else
# error "Unsupported build configuration"
#endif
} // namespace ipc
} // namespace mozilla

64
dom/ipc/MemMapSnapshot.h Normal file
Просмотреть файл

@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_ipc_MemMapSnapshot_h
#define dom_ipc_MemMapSnapshot_h
#include "AutoMemMap.h"
#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
#include "mozilla/RangedPtr.h"
#include "mozilla/Result.h"
#ifdef XP_WIN
# include "mozilla/ipc/FileDescriptor.h"
#endif
namespace mozilla {
namespace ipc {
/**
* A helper class for creating a read-only snapshot of memory-mapped data.
*
* The Init() method initializes a read-write memory mapped region of the given
* size, which can be initialized with arbitrary data. The Finalize() method
* remaps that region as read-only (and backs it with a read-only file
* descriptor), and initializes an AutoMemMap with the new contents.
*
* The file descriptor for the resulting AutoMemMap can be shared among
* processes, to safely access a shared, read-only copy of the data snapshot.
*/
class MOZ_RAII MemMapSnapshot
{
public:
Result<Ok, nsresult> Init(size_t aSize);
Result<Ok, nsresult> Finalize(loader::AutoMemMap& aMap);
template<typename T = void>
RangedPtr<T> Get()
{
MOZ_ASSERT(mInitialized);
return mMem.get<T>();
}
private:
Result<Ok, nsresult> Create(size_t aSize);
Result<Ok, nsresult> Freeze(loader::AutoMemMap& aMem);
loader::AutoMemMap mMem;
bool mInitialized = false;
#ifdef XP_WIN
Maybe<FileDescriptor> mFile;
#else
nsCString mPath;
#endif
};
} // ipc
} // mozilla
#endif // dom_ipc_MemMapSnapshot_h

Просмотреть файл

@ -289,6 +289,13 @@ struct XPCOMInitData
DynamicScalarDefinition[] dynamicScalarDefs;
};
struct StringBundleDescriptor
{
nsCString bundleURL;
FileDescriptor mapFile;
uint32_t mapSize;
};
/**
* The PContent protocol is a top-level protocol between the UI process
* and a content process. There is exactly one PContentParent/PContentChild pair
@ -457,6 +464,8 @@ child:
async ClearSiteDataReloadNeeded(nsString origin);
async RegisterStringBundles(StringBundleDescriptor[] stringBundles);
// nsIPermissionManager messages
async AddPermission(Permission permission);

158
dom/ipc/SharedStringMap.cpp Normal file
Просмотреть файл

@ -0,0 +1,158 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "SharedStringMap.h"
#include "MemMapSnapshot.h"
#include "ScriptPreloader-inl.h"
#include "mozilla/BinarySearch.h"
#include "mozilla/ipc/FileDescriptor.h"
using namespace mozilla::loader;
namespace mozilla {
using namespace ipc;
namespace dom {
namespace ipc {
static inline size_t
GetAlignmentOffset(size_t aOffset, size_t aAlign)
{
auto mod = aOffset % aAlign;
return mod ? aAlign - mod : 0;
}
SharedStringMap::SharedStringMap(const FileDescriptor& aMapFile, size_t aMapSize)
{
auto result = mMap.initWithHandle(aMapFile, aMapSize);
MOZ_RELEASE_ASSERT(result.isOk());
// We return literal nsStrings and nsCStrings pointing to the mapped data,
// which means that we may still have references to the mapped data even
// after this instance is destroyed. That means that we need to keep the
// mapping alive until process shutdown, in order to be safe.
mMap.setPersistent();
}
SharedStringMap::SharedStringMap(SharedStringMapBuilder&& aBuilder)
{
auto result = aBuilder.Finalize(mMap);
MOZ_RELEASE_ASSERT(result.isOk());
mMap.setPersistent();
}
mozilla::ipc::FileDescriptor
SharedStringMap::CloneFileDescriptor() const
{
return mMap.cloneHandle();
}
bool
SharedStringMap::Has(const nsCString& aKey)
{
size_t index;
return Find(aKey, &index);
}
bool
SharedStringMap::Get(const nsCString& aKey, nsAString& aValue)
{
const auto& entries = Entries();
size_t index;
if (!Find(aKey, &index)) {
return false;
}
aValue.Assign(ValueTable().Get(entries[index].mValue));
return true;
}
bool
SharedStringMap::Find(const nsCString& aKey, size_t* aIndex)
{
const auto& keys = KeyTable();
return BinarySearchIf(Entries(), 0, EntryCount(),
[&] (const Entry& aEntry) {
return aKey.Compare(keys.GetBare(aEntry.mKey));
},
aIndex);
}
void
SharedStringMapBuilder::Add(const nsCString& aKey, const nsString& aValue)
{
mEntries.Put(aKey, {{mKeyTable.Add(aKey), aKey.Length()},
{mValueTable.Add(aValue), aValue.Length()}});
}
Result<Ok, nsresult>
SharedStringMapBuilder::Finalize(loader::AutoMemMap& aMap)
{
using Header = SharedStringMap::Header;
MOZ_ASSERT(mEntries.Count() == mKeyTable.Count());
nsTArray<nsCString> keys(mEntries.Count());
for (auto iter = mEntries.Iter(); !iter.Done(); iter.Next()) {
keys.AppendElement(iter.Key());
}
keys.Sort();
Header header = {uint32_t(keys.Length())};
size_t offset = sizeof(header);
offset += GetAlignmentOffset(offset, alignof(Header));
offset += keys.Length() * sizeof(SharedStringMap::Entry);
header.mKeyStringsOffset = offset;
header.mKeyStringsSize = mKeyTable.Size();
offset += header.mKeyStringsSize;
offset += GetAlignmentOffset(offset, alignof(decltype(mValueTable)::ElemType));
header.mValueStringsOffset = offset;
header.mValueStringsSize = mValueTable.Size();
offset += header.mValueStringsSize;
MemMapSnapshot mem;
MOZ_TRY(mem.Init(offset));
auto headerPtr = mem.Get<Header>();
headerPtr[0] = header;
auto* entry = reinterpret_cast<Entry*>(&headerPtr[1]);
for (auto& key : keys) {
*entry++ = mEntries.Get(key);
}
auto ptr = mem.Get<uint8_t>();
mKeyTable.Write({ &ptr[header.mKeyStringsOffset],
header.mKeyStringsSize });
mValueTable.Write({ &ptr[header.mValueStringsOffset],
header.mValueStringsSize });
mKeyTable.Clear();
mValueTable.Clear();
mEntries.Clear();
return mem.Finalize(aMap);
}
} // ipc
} // dom
} // mozilla

324
dom/ipc/SharedStringMap.h Normal file
Просмотреть файл

@ -0,0 +1,324 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: set ts=8 sts=4 et sw=4 tw=99: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef dom_ipc_SharedStringMap_h
#define dom_ipc_SharedStringMap_h
#include "mozilla/AutoMemMap.h"
#include "mozilla/Result.h"
#include "mozilla/TypeTraits.h"
#include "nsDataHashtable.h"
namespace mozilla {
namespace dom {
namespace ipc {
class SharedStringMapBuilder;
/**
* This class provides a simple, read-only key-value string store, with all
* data packed into a single segment of memory, which can be shared between
* processes.
*
* Look-ups are performed by binary search of a static table in the mapped
* memory region, and all returned strings are literals which reference the
* mapped data. No copies are performed on instantiation or look-up.
*
* Important: The mapped memory created by this class is persistent. Once an
* instance has been initialized, the memory that it allocates can never be
* freed before process shutdown. Do not use it for short-lived mappings.
*/
class SharedStringMap
{
using FileDescriptor = mozilla::ipc::FileDescriptor;
public:
/**
* The header at the beginning of the shared memory region describing its
* layout. The layout of the shared memory is as follows:
*
* - Header:
* A Header struct describing the contents of the rest of the memory region.
*
* - Optional alignment padding for Header[].
*
* - Entry[header.mEntryCount]:
* An array of Entry structs, one for each entry in the map. Entries are
* lexocographically sorted by key.
*
* - StringTable<nsCString>:
* A region of flat, null-terminated C strings. Entry key strings are
* encoded as character offsets into this region.
*
* - Optional alignment padding for char16_t[]
*
* - StringTable<nsString>:
* A region of flat, null-terminated UTF-16 strings. Entry value strings are
* encoded as character (*not* byte) offsets into this region.
*/
struct Header {
// The number of entries in this map.
uint32_t mEntryCount;
// The raw byte offset of the beginning of the key string table, from the
// start of the shared memory region, and its size in bytes.
size_t mKeyStringsOffset;
size_t mKeyStringsSize;
// The raw byte offset of the beginning of the value string table, from the
// start of the shared memory region, and its size in bytes (*not*
// characters).
size_t mValueStringsOffset;
size_t mValueStringsSize;
};
/**
* Contains the character offset and character length of an entry in a string
* table. This may be used for either 8-bit or 16-bit strings, and is required
* to retrieve an entry from a string table.
*/
struct StringEntry {
uint32_t mOffset;
uint32_t mLength;
};
/**
* Describes a value in the string map, as offsets into the key and value
* string tables.
*/
struct Entry {
// The offset and size of the entry's UTF-8 key in the key string table.
StringEntry mKey;
// The offset and size of the entry's UTF-16 value in the value string table.
StringEntry mValue;
};
NS_INLINE_DECL_REFCOUNTING(SharedStringMap)
// Note: These constructors are infallible on the premise that this class
// is used primarily in cases where it is critical to platform
// functionality.
explicit SharedStringMap(const FileDescriptor&, size_t);
explicit SharedStringMap(SharedStringMapBuilder&&);
/**
* Searches for the given value in the map, and returns true if it exists.
*/
bool Has(const nsCString& aKey);
/**
* Searches for the given value in the map, and, if it exists, returns true
* and places its value in aValue.
*
* The returned value is a literal string which references the mapped memory
* region.
*/
bool Get(const nsCString& aKey, nsAString& aValue);
private:
/**
* Searches for an entry for the given key. If found, returns true, and
* places its index in the entry array in aIndex.
*/
bool Find(const nsCString& aKey, size_t* aIndex);
public:
/**
* Returns the number of entries in the map.
*/
uint32_t Count() const { return EntryCount(); }
/**
* Returns the string entry at the given index. Keys are guaranteed to be
* sorted lexographically.
*
* The given index *must* be less than the value returned by Count().
*
* The returned value is a literal string which references the mapped memory
* region.
*/
nsCString GetKeyAt(uint32_t aIndex) const
{
MOZ_ASSERT(aIndex < Count());
return KeyTable().Get(Entries()[aIndex].mKey);
}
/**
* Returns the string value for the entry at the given index.
*
* The given index *must* be less than the value returned by Count().
*
* The returned value is a literal string which references the mapped memory
* region.
*/
nsString GetValueAt(uint32_t aIndex) const
{
MOZ_ASSERT(aIndex < Count());
return ValueTable().Get(Entries()[aIndex].mValue);
}
/**
* Returns a copy of the read-only file descriptor which backs the shared
* memory region for this map. The file descriptor may be passed between
* processes, and used to construct new instances of SharedStringMap with
* the same data as this instance.
*/
FileDescriptor CloneFileDescriptor() const;
size_t MapSize() const { return mMap.size(); }
protected:
~SharedStringMap() = default;
private:
template <typename StringType>
class StringTable
{
using ElemType = decltype(DeclVal<StringType>()[0]);
public:
MOZ_IMPLICIT StringTable(const RangedPtr<uint8_t>& aBuffer)
: mBuffer(aBuffer.ReinterpretCast<ElemType>())
{
MOZ_ASSERT(uintptr_t(aBuffer.get()) % alignof(ElemType) == 0,
"Got misalinged buffer");
}
StringType Get(const StringEntry& aEntry) const
{
StringType res;
res.AssignLiteral(GetBare(aEntry), aEntry.mLength);
return res;
}
const ElemType* GetBare(const StringEntry& aEntry) const
{
return &mBuffer[aEntry.mOffset];
}
private:
RangedPtr<ElemType> mBuffer;
};
// Type-safe getters for values in the shared memory region:
const Header& GetHeader() const
{
return mMap.get<Header>()[0];
}
RangedPtr<const Entry> Entries() const
{
return { reinterpret_cast<const Entry*>(&GetHeader() + 1),
EntryCount() };
}
uint32_t EntryCount() const
{
return GetHeader().mEntryCount;
}
StringTable<nsCString> KeyTable() const
{
auto& header = GetHeader();
return { { &mMap.get<uint8_t>()[header.mKeyStringsOffset],
header.mKeyStringsSize } };
}
StringTable<nsString> ValueTable() const
{
auto& header = GetHeader();
return { { &mMap.get<uint8_t>()[header.mValueStringsOffset],
header.mValueStringsSize } };
}
loader::AutoMemMap mMap;
};
/**
* A helper class which builds the contiguous look-up table used by
* SharedStringMap. Each key-value pair in the final map is added to the
* builder, before it is finalized and transformed into a snapshot.
*/
class MOZ_RAII SharedStringMapBuilder
{
public:
SharedStringMapBuilder() = default;
/**
* Adds a key-value pair to the map.
*/
void Add(const nsCString& aKey, const nsString& aValue);
/**
* Finalizes the binary representation of the map, writes it to a shared
* memory region, and then initializes the given AutoMemMap with a reference
* to the read-only copy of it.
*/
Result<Ok, nsresult> Finalize(loader::AutoMemMap& aMap);
private:
template <typename KeyType, typename StringType>
class StringTableBuilder
{
public:
using ElemType = typename StringType::char_type;
uint32_t Add(const StringType& aKey)
{
auto entry = mEntries.LookupForAdd(aKey).OrInsert([&] () {
Entry newEntry { mSize, aKey };
mSize += aKey.Length() + 1;
return newEntry;
});
return entry.mOffset;
}
void Write(const RangedPtr<uint8_t>& aBuffer)
{
auto buffer = aBuffer.ReinterpretCast<ElemType>();
for (auto iter = mEntries.Iter(); !iter.Done(); iter.Next()) {
auto& entry = iter.Data();
memcpy(&buffer[entry.mOffset], entry.mValue.BeginReading(),
sizeof(ElemType) * (entry.mValue.Length() + 1));
}
}
uint32_t Count() const { return mEntries.Count(); }
uint32_t Size() const { return mSize * sizeof(ElemType); }
void Clear() { mEntries.Clear(); }
private:
struct Entry
{
uint32_t mOffset;
StringType mValue;
};
nsDataHashtable<KeyType, Entry> mEntries;
uint32_t mSize = 0;
};
using Entry = SharedStringMap::Entry;
StringTableBuilder<nsCStringHashKey, nsCString> mKeyTable;
StringTableBuilder<nsStringHashKey, nsString> mValueTable;
nsDataHashtable<nsCStringHashKey, Entry> mEntries;
};
} // ipc
} // dom
} // mozilla
#endif // dom_ipc_SharedStringMap_h

Просмотреть файл

@ -12,8 +12,10 @@
#include "ipc/IPCMessageUtils.h"
#include "mozilla/dom/BindingUtils.h"
#include "mozilla/dom/BlobBinding.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/dom/DOMTypes.h"
#include "mozilla/dom/File.h"
#include "mozilla/dom/IPCBlobUtils.h"
#include "mozilla/ipc/BackgroundParent.h"
#include "mozilla/ipc/IPCStreamUtils.h"
#include "nsContentUtils.h"
#include "nsJSEnvironment.h"
@ -21,6 +23,8 @@
#include "StructuredCloneTags.h"
#include "jsapi.h"
using namespace mozilla::ipc;
namespace mozilla {
namespace dom {
namespace ipc {

Просмотреть файл

@ -15,6 +15,7 @@ XPIDL_MODULE = 'dom'
EXPORTS.mozilla.dom.ipc += [
'IdType.h',
'SharedStringMap.h',
'StructuredCloneData.h',
]
@ -61,12 +62,14 @@ UNIFIED_SOURCES += [
'ContentProcessHost.cpp',
'ContentProcessManager.cpp',
'FilePickerParent.cpp',
'MemMapSnapshot.cpp',
'MemoryReportRequest.cpp',
'nsIContentChild.cpp',
'nsIContentParent.cpp',
'PermissionMessageUtils.cpp',
'PreallocatedProcessManager.cpp',
'ProcessPriorityManager.cpp',
'SharedStringMap.cpp',
'StructuredCloneData.cpp',
'TabChild.cpp',
'TabContext.cpp',
@ -132,6 +135,7 @@ LOCAL_INCLUDES += [
'/extensions/spellcheck/src',
'/gfx/2d',
'/hal/sandbox',
'/js/xpconnect/loader',
'/layout/base',
'/media/webrtc',
'/netwerk/base',

Просмотреть файл

@ -48,8 +48,8 @@ SVGAngle::SetValue(float aValue, ErrorResult& rv)
return;
}
bool isBaseVal = mType == BaseValue;
mVal->SetBaseValue(aValue, isBaseVal ? mSVGElement.get() : nullptr,
isBaseVal);
mVal->SetBaseValue(aValue, mVal->mBaseValUnit,
isBaseVal ? mSVGElement.get() : nullptr, isBaseVal);
}
float

Просмотреть файл

@ -182,7 +182,7 @@ SVGMarkerElement::SetOrientToAngle(SVGAngle& angle, ErrorResult& rv)
return;
}
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE);
mAngleAttributes[ORIENT].SetBaseValue(f, this, true);
mAngleAttributes[ORIENT].SetBaseValue(f, angle.UnitType(), this, true);
}
//----------------------------------------------------------------------
@ -222,14 +222,16 @@ SVGMarkerElement::ParseAttribute(int32_t aNameSpaceID, nsAtom* aName,
if (aValue.EqualsLiteral("auto")) {
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_AUTO);
aResult.SetTo(aValue);
mAngleAttributes[ORIENT].SetBaseValue(0.f, this, false);
mAngleAttributes[ORIENT].SetBaseValue(0.f, SVG_ANGLETYPE_UNSPECIFIED,
this, false);
return true;
}
if (aValue.EqualsLiteral("auto-start-reverse") &&
MarkerImprovementsPrefEnabled()) {
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_AUTO_START_REVERSE);
aResult.SetTo(aValue);
mAngleAttributes[ORIENT].SetBaseValue(0.f, this, false);
mAngleAttributes[ORIENT].SetBaseValue(0.f, SVG_ANGLETYPE_UNSPECIFIED,
this, false);
return true;
}
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE);

Просмотреть файл

@ -163,10 +163,9 @@ nsSVGAngle::ConvertToSpecifiedUnits(uint16_t unitType,
}
float valueInUserUnits = mBaseVal * GetDegreesPerUnit(mBaseValUnit);
mBaseValUnit = uint8_t(unitType);
// Setting aDoSetAttr to false here will ensure we don't call
// Will/DidChangeAngle a second time (and dispatch duplicate notifications).
SetBaseValue(valueInUserUnits, aSVGElement, false);
SetBaseValue(valueInUserUnits, unitType, aSVGElement, false);
if (aSVGElement) {
aSVGElement->DidChangeAngle(mAttrEnum, emptyOrOldValue);
@ -294,10 +293,11 @@ nsSVGAngle::GetAnimValueString(nsAString & aValueAsString) const
}
void
nsSVGAngle::SetBaseValue(float aValue, nsSVGElement *aSVGElement,
bool aDoSetAttr)
nsSVGAngle::SetBaseValue(float aValue, uint8_t aUnit,
nsSVGElement *aSVGElement, bool aDoSetAttr)
{
if (mBaseVal == aValue * GetDegreesPerUnit(mBaseValUnit)) {
float valueInSpecifiedUnits = aValue / GetDegreesPerUnit(aUnit);
if (aUnit == mBaseValUnit && mBaseVal == valueInSpecifiedUnits) {
return;
}
nsAttrValue emptyOrOldValue;
@ -305,7 +305,8 @@ nsSVGAngle::SetBaseValue(float aValue, nsSVGElement *aSVGElement,
emptyOrOldValue = aSVGElement->WillChangeAngle(mAttrEnum);
}
mBaseVal = aValue / GetDegreesPerUnit(mBaseValUnit);
mBaseValUnit = aUnit;
mBaseVal = valueInSpecifiedUnits;
if (!mIsAnimated) {
mAnimVal = mBaseVal;
}

Просмотреть файл

@ -55,7 +55,8 @@ public:
float GetAnimValue() const
{ return mAnimVal * GetDegreesPerUnit(mAnimValUnit); }
void SetBaseValue(float aValue, nsSVGElement *aSVGElement, bool aDoSetAttr);
void SetBaseValue(float aValue, uint8_t aUnit, nsSVGElement *aSVGElement,
bool aDoSetAttr);
void SetAnimValue(float aValue, uint8_t aUnit, nsSVGElement *aSVGElement);
uint8_t GetBaseValueUnit() const { return mBaseValUnit; }

Просмотреть файл

@ -7,7 +7,6 @@
// string bundles (intl)
#include "nsStringBundleService.h"
#include "nsStringBundleTextOverride.h"
// locale
#include "nsLocaleConstructors.h"
@ -15,12 +14,10 @@
// uconv
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStringBundleService, Init)
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStringBundleTextOverride, Init)
NS_DEFINE_NAMED_CID(MOZ_LOCALESERVICE_CID);
NS_DEFINE_NAMED_CID(MOZ_OSPREFERENCES_CID);
NS_DEFINE_NAMED_CID(NS_STRINGBUNDLESERVICE_CID);
NS_DEFINE_NAMED_CID(NS_STRINGBUNDLETEXTOVERRIDE_CID);
NS_DEFINE_NAMED_CID(NS_COLLATIONFACTORY_CID);
NS_DEFINE_NAMED_CID(NS_COLLATION_CID);
@ -28,7 +25,6 @@ static const mozilla::Module::CIDEntry kIntlCIDs[] = {
{ &kMOZ_LOCALESERVICE_CID, false, nullptr, mozilla::intl::LocaleServiceConstructor },
{ &kMOZ_OSPREFERENCES_CID, false, nullptr, mozilla::intl::OSPreferencesConstructor },
{ &kNS_STRINGBUNDLESERVICE_CID, false, nullptr, nsStringBundleServiceConstructor },
{ &kNS_STRINGBUNDLETEXTOVERRIDE_CID, false, nullptr, nsStringBundleTextOverrideConstructor },
{ &kNS_COLLATIONFACTORY_CID, false, nullptr, nsCollationFactoryConstructor },
{ &kNS_COLLATION_CID, false, nullptr, nsCollationConstructor },
{ nullptr }
@ -38,7 +34,6 @@ static const mozilla::Module::ContractIDEntry kIntlContracts[] = {
{ MOZ_LOCALESERVICE_CONTRACTID, &kMOZ_LOCALESERVICE_CID },
{ MOZ_OSPREFERENCES_CONTRACTID, &kMOZ_OSPREFERENCES_CID },
{ NS_STRINGBUNDLE_CONTRACTID, &kNS_STRINGBUNDLESERVICE_CID },
{ NS_STRINGBUNDLETEXTOVERRIDE_CONTRACTID, &kNS_STRINGBUNDLETEXTOVERRIDE_CID },
{ NS_COLLATIONFACTORY_CONTRACTID, &kNS_COLLATIONFACTORY_CID },
{ NS_COLLATION_CONTRACTID, &kNS_COLLATION_CID },
{ nullptr }

Просмотреть файл

@ -8,16 +8,20 @@ XPCSHELL_TESTS_MANIFESTS += ['tests/unit/xpcshell.ini']
XPIDL_SOURCES += [
'nsIStringBundle.idl',
'nsIStringBundleOverride.idl',
]
XPIDL_MODULE = 'intl'
UNIFIED_SOURCES += [
'nsStringBundle.cpp',
'nsStringBundleTextOverride.cpp',
]
LOCAL_INCLUDES += [
'/xpcom/ds',
]
include('/ipc/chromium/chromium-config.mozbuild')
FINAL_LIBRARY = 'xul'
if CONFIG['CC_TYPE'] in ('clang', 'gcc'):

Просмотреть файл

@ -9,6 +9,15 @@
%{C++
#include "mozilla/MemoryReporting.h"
namespace mozilla {
namespace dom {
class ContentParent;
}
namespace ipc {
class FileDescriptor;
}
}
// Define Contractid and CID
// {D85A17C1-AA7C-11d2-9B8C-00805F8A16D9}
#define NS_STRINGBUNDLESERVICE_CID \
@ -74,7 +83,6 @@ interface nsIStringBundle : nsISupports
interface nsIStringBundleService : nsISupports
{
nsIStringBundle createBundle(in string aURLSpec);
nsIStringBundle createExtensibleBundle(in string aRegistryKey);
/**
* Formats a message string from a status code and status arguments.
@ -99,5 +107,11 @@ interface nsIStringBundleService : nsISupports
%{C++
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const = 0;
virtual void SendContentBundles(mozilla::dom::ContentParent* aContentParent) const = 0;
virtual void RegisterContentBundle(const nsCString& aBundleURL,
const mozilla::ipc::FileDescriptor& aMapFile,
size_t aMapSize) = 0;
%}
};

Просмотреть файл

@ -1,33 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* 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/. */
#include "nsISupports.idl"
interface nsISimpleEnumerator;
%{C++
#include "mozilla/MemoryReporting.h"
%}
// to be implemented by an embeddor that wants to override some strings
[scriptable, uuid(965eb278-5678-456b-82a7-20a0c86a803c)]
interface nsIStringBundleOverride : nsISupports
{
/**
* get the override value for a particular key in a particular
* string bundle
*/
AString getStringFromName(in AUTF8String url,
in ACString key);
/**
* get all override keys for a given string bundle
*/
nsISimpleEnumerator enumerateKeysInBundle(in AUTF8String url);
%{C++
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const = 0;
%}
};

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -8,73 +8,87 @@
#include "mozilla/ReentrantMonitor.h"
#include "nsIStringBundle.h"
#include "nsIMemoryReporter.h"
#include "nsCOMPtr.h"
#include "nsString.h"
#include "nsCOMArray.h"
class nsIPersistentProperties;
class nsIStringBundleOverride;
class nsStringBundle : public nsIStringBundle
class nsStringBundleBase : public nsIStringBundle
, public nsIMemoryReporter
{
public:
// init version
nsStringBundle(const char* aURLSpec, nsIStringBundleOverride*);
nsresult LoadProperties();
MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf)
nsresult ParseProperties(nsIPersistentProperties**);
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSISTRINGBUNDLE
NS_DECL_NSIMEMORYREPORTER
nsCOMPtr<nsIPersistentProperties> mProps;
virtual nsresult LoadProperties() = 0;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf) const override;
const nsCString& BundleURL() const { return mPropertiesURL; }
// Returns true if this bundle has more than one reference. If it has only
// a single reference, it is assumed to be held alive by the bundle cache.
bool IsShared() const { return mRefCnt > 1; }
static nsStringBundleBase* Cast(nsIStringBundle* aBundle)
{
return static_cast<nsStringBundleBase*>(aBundle);
}
template <typename T, typename... Args>
static already_AddRefed<T> Create(Args... args);
protected:
virtual ~nsStringBundle();
nsStringBundleBase(const char* aURLSpec);
virtual ~nsStringBundleBase();
virtual nsresult GetStringImpl(const nsACString& aName, nsAString& aResult) = 0;
virtual nsresult GetSimpleEnumerationImpl(nsISimpleEnumerator** elements) = 0;
void RegisterMemoryReporter();
nsresult GetCombinedEnumeration(nsIStringBundleOverride* aOverrideString,
nsISimpleEnumerator** aResult);
private:
nsCString mPropertiesURL;
nsCOMPtr<nsIStringBundleOverride> mOverrideStrings;
mozilla::ReentrantMonitor mReentrantMonitor;
bool mAttemptedLoad;
bool mLoaded;
size_t SizeOfIncludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf) const override;
public:
static nsresult FormatString(const char16_t *formatStr,
const char16_t **aParams, uint32_t aLength,
nsAString& aResult);
};
class nsExtensibleStringBundle;
/**
* An extensible implementation of the StringBundle interface.
*
* @created 28/Dec/1999
* @author Catalin Rotaru [CATA]
*/
class nsExtensibleStringBundle final : public nsIStringBundle
class nsStringBundle : public nsStringBundleBase
{
NS_DECL_ISUPPORTS
NS_DECL_NSISTRINGBUNDLE
nsresult Init(const char * aCategory, nsIStringBundleService *);
public:
nsExtensibleStringBundle();
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
size_t SizeOfIncludingThisIfUnshared(mozilla::MallocSizeOf aMallocSizeOf) const override;
NS_DECL_ISUPPORTS_INHERITED
private:
virtual ~nsExtensibleStringBundle();
nsCOMPtr<nsIPersistentProperties> mProps;
nsCOMArray<nsIStringBundle> mBundles;
bool mLoaded;
nsresult LoadProperties() override;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
protected:
friend class nsStringBundleBase;
explicit nsStringBundle(const char* aURLSpec);
virtual ~nsStringBundle();
nsresult GetStringImpl(const nsACString& aName, nsAString& aResult) override;
nsresult GetSimpleEnumerationImpl(nsISimpleEnumerator** elements) override;
};
#endif

Просмотреть файл

@ -14,10 +14,10 @@
#include "nsIObserver.h"
#include "nsWeakReference.h"
#include "nsIErrorService.h"
#include "nsIStringBundleOverride.h"
#include "nsIMemoryReporter.h"
#include "mozilla/LinkedList.h"
#include "mozilla/UniquePtr.h"
struct bundleCacheEntry_t;
@ -43,14 +43,20 @@ public:
size_t amt = SizeOfIncludingThis(MallocSizeOf);
MOZ_COLLECT_REPORT(
"explicit/string-bundle-service", KIND_HEAP, UNITS_BYTES,
"explicit/string-bundles/service", KIND_HEAP, UNITS_BYTES,
amt,
"Memory used for StringBundleService bundles");
"Memory used for StringBundleService overhead");
return NS_OK;
};
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
void SendContentBundles(mozilla::dom::ContentParent* aContentParent) const override;
void RegisterContentBundle(const nsCString& aBundleURL,
const mozilla::ipc::FileDescriptor& aMapFile,
size_t aMapSize) override;
private:
virtual ~nsStringBundleService();
@ -59,16 +65,20 @@ private:
uint32_t argCount, char16_t** argArray,
nsAString& result);
void flushBundleCache();
void flushBundleCache(bool ignoreShared = true);
bundleCacheEntry_t *insertIntoCache(already_AddRefed<nsIStringBundle> aBundle,
nsCString &aHashKey);
mozilla::UniquePtr<bundleCacheEntry_t> evictOneEntry();
bundleCacheEntry_t* insertIntoCache(already_AddRefed<nsIStringBundle> aBundle,
const nsACString &aHashKey);
nsDataHashtable<nsCStringHashKey, bundleCacheEntry_t*> mBundleMap;
// LRU list of cached entries, with the least-recently-used entry first.
mozilla::LinkedList<bundleCacheEntry_t> mBundleCache;
// List of cached shared-memory string bundles, in arbitrary order.
mozilla::AutoCleanLinkedList<bundleCacheEntry_t> mSharedBundles;
nsCOMPtr<nsIErrorService> mErrorService;
nsCOMPtr<nsIStringBundleOverride> mOverrideStrings;
};
#endif

Просмотреть файл

@ -1,292 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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/. */
#include "nsStringBundleTextOverride.h"
#include "nsString.h"
#include "nsNetUtil.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsContentUtils.h"
#include "nsDirectoryServiceUtils.h"
// first we need a simple class which wraps a nsIPropertyElement and
// cuts out the leading URL from the key
class URLPropertyElement : public nsIPropertyElement
{
public:
URLPropertyElement(nsIPropertyElement *aRealElement, uint32_t aURLLength) :
mRealElement(aRealElement),
mURLLength(aURLLength)
{ }
NS_DECL_ISUPPORTS
NS_DECL_NSIPROPERTYELEMENT
private:
nsCOMPtr<nsIPropertyElement> mRealElement;
uint32_t mURLLength;
virtual ~URLPropertyElement() {}
};
NS_IMPL_ISUPPORTS(URLPropertyElement, nsIPropertyElement)
// we'll tweak the key on the way through, and remove the url prefix
NS_IMETHODIMP
URLPropertyElement::GetKey(nsACString& aKey)
{
nsresult rv = mRealElement->GetKey(aKey);
if (NS_FAILED(rv)) return rv;
// chop off the url
aKey.Cut(0, mURLLength);
return NS_OK;
}
// values are unaffected
NS_IMETHODIMP
URLPropertyElement::GetValue(nsAString& aValue)
{
return mRealElement->GetValue(aValue);
}
// setters are kind of strange, hopefully we'll never be called
NS_IMETHODIMP
URLPropertyElement::SetKey(const nsACString& aKey)
{
// this is just wrong - ideally you'd take the key, append it to
// the url, and set that as the key. However, that would require
// us to hold onto a copy of the string, and that's a waste,
// considering nobody should ever be calling this.
NS_ERROR("This makes no sense!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
URLPropertyElement::SetValue(const nsAString& aValue)
{
return mRealElement->SetValue(aValue);
}
// this is a special enumerator which returns only the elements which
// are prefixed with a particular url
class nsPropertyEnumeratorByURL : public nsISimpleEnumerator
{
public:
nsPropertyEnumeratorByURL(const nsACString& aURL,
nsISimpleEnumerator* aOuter) :
mOuter(aOuter),
mURL(aURL)
{
// prepare the url once so we can use its value later
// persistent properties uses ":" as a delimiter, so escape
// that character
mURL.ReplaceSubstring(":", "%3A");
// there is always a # between the url and the real key
mURL.Append('#');
}
NS_DECL_ISUPPORTS
NS_DECL_NSISIMPLEENUMERATOR
private:
// actual enumerator of all strings from nsIProperties
nsCOMPtr<nsISimpleEnumerator> mOuter;
// the current element that is valid for this url
nsCOMPtr<nsIPropertyElement> mCurrent;
// the url in question, pre-escaped and with the # already in it
nsCString mURL;
virtual ~nsPropertyEnumeratorByURL() {}
};
//
// nsStringBundleTextOverride implementation
//
NS_IMPL_ISUPPORTS(nsStringBundleTextOverride,
nsIStringBundleOverride)
nsresult
nsStringBundleTextOverride::Init()
{
nsresult rv;
// check for existence of custom-strings.txt
nsCOMPtr<nsIFile> customStringsFile;
rv = NS_GetSpecialDirectory(NS_APP_CHROME_DIR,
getter_AddRefs(customStringsFile));
if (NS_FAILED(rv)) return rv;
// bail if not found - this will cause the service creation to
// bail as well, and cause this object to go away
customStringsFile->AppendNative(NS_LITERAL_CSTRING("custom-strings.txt"));
bool exists;
rv = customStringsFile->Exists(&exists);
if (NS_FAILED(rv) || !exists)
return NS_ERROR_FAILURE;
NS_WARNING("Using custom-strings.txt to override string bundles.");
// read in the custom bundle. Keys are in the form
// chrome://package/locale/foo.properties:keyname
nsAutoCString customStringsURLSpec;
rv = NS_GetURLSpecFromFile(customStringsFile, customStringsURLSpec);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), customStringsURLSpec);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIChannel> channel;
rv = NS_NewChannel(getter_AddRefs(channel),
uri,
nsContentUtils::GetSystemPrincipal(),
nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL,
nsIContentPolicy::TYPE_OTHER);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIInputStream> in;
rv = channel->Open2(getter_AddRefs(in));
NS_ENSURE_SUCCESS(rv, rv);
static NS_DEFINE_CID(kPersistentPropertiesCID, NS_IPERSISTENTPROPERTIES_CID);
mValues = do_CreateInstance(kPersistentPropertiesCID, &rv);
if (NS_FAILED(rv)) return rv;
rv = mValues->Load(in);
// turn this on to see the contents of custom-strings.txt
#ifdef DEBUG_alecf
nsCOMPtr<nsISimpleEnumerator> enumerator;
mValues->Enumerate(getter_AddRefs(enumerator));
NS_ASSERTION(enumerator, "no enumerator!\n");
printf("custom-strings.txt contains:\n");
printf("----------------------------\n");
bool hasMore;
enumerator->HasMoreElements(&hasMore);
do {
nsCOMPtr<nsISupports> sup;
enumerator->GetNext(getter_AddRefs(sup));
nsCOMPtr<nsIPropertyElement> prop = do_QueryInterface(sup);
nsAutoCString key;
nsAutoString value;
prop->GetKey(key);
prop->GetValue(value);
printf("%s = '%s'\n", key.get(), NS_ConvertUTF16toUTF8(value).get());
enumerator->HasMoreElements(&hasMore);
} while (hasMore);
#endif
return rv;
}
NS_IMETHODIMP
nsStringBundleTextOverride::GetStringFromName(const nsACString& aURL,
const nsACString& key,
nsAString& aResult)
{
// concatenate url#key to get the key to read
nsAutoCString combinedURL(aURL + NS_LITERAL_CSTRING("#") + key);
// persistent properties uses ":" as a delimiter, so escape that character
combinedURL.ReplaceSubstring(":", "%3A");
return mValues->GetStringProperty(combinedURL, aResult);
}
size_t
nsStringBundleTextOverride::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
{
return aMallocSizeOf(this) + (mValues ? mValues->SizeOfIncludingThis(aMallocSizeOf) : 0);
}
NS_IMETHODIMP
nsStringBundleTextOverride::EnumerateKeysInBundle(const nsACString& aURL,
nsISimpleEnumerator** aResult)
{
// enumerate all strings, and let the enumerator know
nsCOMPtr<nsISimpleEnumerator> enumerator;
mValues->Enumerate(getter_AddRefs(enumerator));
// make the enumerator wrapper and pass it off
nsPropertyEnumeratorByURL* propEnum =
new nsPropertyEnumeratorByURL(aURL, enumerator);
if (!propEnum) return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*aResult = propEnum);
return NS_OK;
}
//
// nsPropertyEnumeratorByURL implementation
//
NS_IMPL_ISUPPORTS(nsPropertyEnumeratorByURL, nsISimpleEnumerator)
NS_IMETHODIMP
nsPropertyEnumeratorByURL::GetNext(nsISupports **aResult)
{
if (!mCurrent) return NS_ERROR_UNEXPECTED;
// wrap mCurrent instead of returning it
*aResult = new URLPropertyElement(mCurrent, mURL.Length());
NS_ADDREF(*aResult);
// release it so we don't return it twice
mCurrent = nullptr;
return NS_OK;
}
NS_IMETHODIMP
nsPropertyEnumeratorByURL::HasMoreElements(bool * aResult)
{
bool hasMore;
mOuter->HasMoreElements(&hasMore);
while (hasMore) {
nsCOMPtr<nsISupports> supports;
mOuter->GetNext(getter_AddRefs(supports));
mCurrent = do_QueryInterface(supports);
if (mCurrent) {
nsAutoCString curKey;
mCurrent->GetKey(curKey);
if (StringBeginsWith(curKey, mURL))
break;
}
mOuter->HasMoreElements(&hasMore);
}
if (!hasMore)
mCurrent = nullptr;
*aResult = mCurrent ? true : false;
return NS_OK;
}

Просмотреть файл

@ -1,43 +0,0 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* 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 nsStringBundleTextOverride_h__
#define nsStringBundleTextOverride_h__
#include "nsIStringBundleOverride.h"
#include "nsCOMPtr.h"
#include "nsIPersistentProperties2.h"
// {6316C6CE-12D3-479e-8F53-E289351412B8}
#define NS_STRINGBUNDLETEXTOVERRIDE_CID \
{ 0x6316c6ce, 0x12d3, 0x479e, \
{ 0x8f, 0x53, 0xe2, 0x89, 0x35, 0x14, 0x12, 0xb8 } }
#define NS_STRINGBUNDLETEXTOVERRIDE_CONTRACTID \
"@mozilla.org/intl/stringbundle/text-override;1"
// an implementation which does overrides from a text file
class nsStringBundleTextOverride : public nsIStringBundleOverride
{
public:
nsStringBundleTextOverride() { }
nsresult Init();
NS_DECL_ISUPPORTS
NS_DECL_NSISTRINGBUNDLEOVERRIDE
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const override;
private:
nsCOMPtr<nsIPersistentProperties> mValues;
virtual ~nsStringBundleTextOverride() {}
};
#endif

Просмотреть файл

@ -7,7 +7,7 @@ license = "MPL-2.0"
[build-dependencies]
env_logger = {version = "0.5", default-features = false} # disable `regex` to reduce code size
bindgen = {version = "0.33.1", default-features = false} # disable `logging` to reduce code size
bindgen = {version = "0.37", default-features = false} # disable `logging` to reduce code size
cmake = "0.1"
glob = "0.2.11"

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,8 @@
#!/bin/sh
cargo run -- \
../BinSource.webidl_ \
../BinSource.yaml \
--out-class ../BinSource-auto.h \
--out-impl ../BinSource-auto.cpp \
--out-token ../BinToken.h

Просмотреть файл

@ -19,6 +19,22 @@ use clap::{ App, Arg };
use itertools::Itertools;
/// A string or string-like construction that can be appended newline.
trait NewLineIfNotEmpty {
/// Append newline if the string is not empty.
fn newline_if_not_empty(&self) -> String;
}
impl<T> NewLineIfNotEmpty for T where T: ToStr {
fn newline_if_not_empty(&self) -> String {
let str = self.to_str();
if str.len() == 0 {
"".to_string()
} else {
format!("{}\n", str)
}
}
}
/// Rules for generating the code for parsing a single field
/// of a node.
///
@ -735,18 +751,18 @@ impl CPPExporter {
buffer_cases.push_str(&format!("
case BinKind::{variant_name}:
MOZ_TRY_VAR(result, parseInterface{class_name}(start, kind, fields));
{arm_after}
break;",
{arm_after} break;",
class_name = node.to_class_cases(),
variant_name = node.to_cpp_enum_case(),
arm_after = rules_for_this_sum.by_sum.get(&node)
.cloned()
.unwrap_or_default().after_arm.reindent(" ")));
.unwrap_or_default().after_arm.reindent(" ")
.newline_if_not_empty()));
}
buffer.push_str(&format!("\n{first_line}
{{
{type_ok} result;
switch(kind) {{{cases}
switch (kind) {{{cases}
default:
return raiseInvalidKind(\"{kind}\", kind);
}}
@ -888,9 +904,11 @@ impl CPPExporter {
{type_ok} result;
if (kind == BinKind::{null}) {{
result = {default_value};
}} else {{
}} else if (kind == BinKind::{kind}) {{
const auto start = tokenizer_->offset();
MOZ_TRY_VAR(result, parseInterface{contents}(start, kind, fields));
}} else {{
return raiseInvalidKind(\"{kind}\", kind);
}}
MOZ_TRY(guard.done());
@ -903,6 +921,7 @@ impl CPPExporter {
contents = parser.elements.to_class_cases(),
type_ok = type_ok,
default_value = default_value,
kind = parser.elements.to_cpp_enum_case(),
));
}
NamedType::Typedef(ref type_) => {
@ -988,7 +1007,6 @@ impl CPPExporter {
buffer.push_str(&comment);
// Generate public method
let kind = name.to_class_cases();
buffer.push_str(&format!("{first_line}
{{
BinKind kind;
@ -996,9 +1014,11 @@ impl CPPExporter {
AutoTaggedTuple guard(*tokenizer_);
MOZ_TRY(tokenizer_->enterTaggedTuple(kind, fields, guard));
if (kind != BinKind::{kind}) {{
return raiseInvalidKind(\"{kind}\", kind);
}}
const auto start = tokenizer_->offset();
BINJS_MOZ_TRY_DECL(result, parseInterface{kind}(start, kind, fields));
BINJS_MOZ_TRY_DECL(result, parseInterface{class_name}(start, kind, fields));
MOZ_TRY(guard.done());
return result;
@ -1006,7 +1026,8 @@ impl CPPExporter {
",
first_line = self.get_method_definition_start(name, "ParseNode*", "", ""),
kind = kind
kind = name.to_cpp_enum_case(),
class_name = name.to_class_cases(),
));
// Generate aux method
@ -1115,32 +1136,24 @@ impl CPPExporter {
};
if needs_block {
let parse_var = parse_var.reindent(" ");
format!("{before_field}
{decl_var}
{{
{block_before_field}
{parse_var}
{block_after_field}
format!("{before_field}{decl_var} {{
{block_before_field}{parse_var}{block_after_field}
}}
{after_field}",
before_field = before_field.reindent(" "),
decl_var = decl_var.reindent(" "),
parse_var = parse_var.reindent(" "),
after_field = after_field.reindent(" "),
block_before_field = rules_for_this_field.block_before_field.reindent(" "),
block_after_field = rules_for_this_field.block_after_field.reindent(" "))
before_field = before_field.reindent(" ").newline_if_not_empty(),
decl_var = decl_var.reindent(" ").newline_if_not_empty(),
block_before_field = rules_for_this_field.block_before_field.reindent(" ").newline_if_not_empty(),
parse_var = parse_var.reindent(" ").newline_if_not_empty(),
block_after_field = rules_for_this_field.block_after_field.reindent(" "),
after_field = after_field.reindent(" "))
} else {
// We have a before_field and an after_field. This will create newlines
// for them.
format!("
{before_field}
{decl_var}
{parse_var}
{after_field}
",
before_field = before_field.reindent(" "),
decl_var = decl_var.reindent(" "),
parse_var = parse_var.reindent(" "),
{before_field}{decl_var}{parse_var}{after_field}",
before_field = before_field.reindent(" ").newline_if_not_empty(),
decl_var = decl_var.reindent(" ").newline_if_not_empty(),
parse_var = parse_var.reindent(" ").newline_if_not_empty(),
after_field = after_field.reindent(" "))
}
}
@ -1154,11 +1167,11 @@ impl CPPExporter {
if build_result == "" {
buffer.push_str(&format!("{first_line}
{{
return raiseError(\"FIXME: Not implemented yet ({})\");
return raiseError(\"FIXME: Not implemented yet ({class_name})\");
}}
",
kind = kind.to_str(),
class_name = name.to_class_cases(),
first_line = first_line,
));
} else {
@ -1170,8 +1183,7 @@ impl CPPExporter {
#if defined(DEBUG)
const BinField expected_fields[{number_of_fields}] = {fields_type_list};
MOZ_TRY(tokenizer_->checkFields(kind, fields, expected_fields));
#endif // defined(DEBUG)
",
#endif // defined(DEBUG)",
fields_type_list = fields_type_list,
number_of_fields = number_of_fields)
};
@ -1179,18 +1191,16 @@ impl CPPExporter {
{{
MOZ_ASSERT(kind == BinKind::{kind});
BINJS_TRY(CheckRecursionLimit(cx_));
{check_fields}
{pre}{fields_implem}
{post}
return result;
{post} return result;
}}
",
check_fields = check_fields,
fields_implem = fields_implem,
pre = init,
post = build_result,
pre = init.newline_if_not_empty(),
post = build_result.newline_if_not_empty(),
kind = name.to_cpp_enum_case(),
first_line = first_line,
));

Просмотреть файл

@ -19,19 +19,11 @@ using namespace mozilla::ipc;
AutoMemMap::~AutoMemMap()
{
if (fileMap) {
if (addr) {
Unused << NS_WARN_IF(PR_MemUnmap(addr, size()) != PR_SUCCESS);
addr = nullptr;
}
Unused << NS_WARN_IF(PR_CloseFileMap(fileMap) != PR_SUCCESS);
fileMap = nullptr;
}
reset();
}
FileDescriptor
AutoMemMap::cloneFileDescriptor()
AutoMemMap::cloneFileDescriptor() const
{
if (fd.get()) {
auto handle = FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(fd.get()));
@ -51,7 +43,8 @@ AutoMemMap::init(nsIFile* file, int flags, int mode, PRFileMapProtect prot)
}
Result<Ok, nsresult>
AutoMemMap::init(const FileDescriptor& file)
AutoMemMap::init(const FileDescriptor& file, PRFileMapProtect prot,
size_t expectedSize)
{
MOZ_ASSERT(!fd);
if (!file.IsValid()) {
@ -66,11 +59,11 @@ AutoMemMap::init(const FileDescriptor& file)
}
Unused << handle.release();
return initInternal();
return initInternal(prot, expectedSize);
}
Result<Ok, nsresult>
AutoMemMap::initInternal(PRFileMapProtect prot)
AutoMemMap::initInternal(PRFileMapProtect prot, size_t expectedSize)
{
MOZ_ASSERT(!fileMap);
MOZ_ASSERT(!addr);
@ -86,6 +79,12 @@ AutoMemMap::initInternal(PRFileMapProtect prot)
return Err(NS_ERROR_FAILURE);
size_ = fileInfo.size;
// The memory region size passed in certain IPC messages isn't necessary on
// Unix-like systems, since we can always stat the file descriptor to
// determine it accurately. But since we have it, anyway, sanity check that
// it matches the size returned by the stat.
MOZ_ASSERT_IF(expectedSize > 0, size_ == expectedSize);
addr = PR_MemMap(fileMap, 0, size_);
if (!addr)
return Err(NS_ERROR_FAILURE);
@ -93,5 +92,73 @@ AutoMemMap::initInternal(PRFileMapProtect prot)
return Ok();
}
#ifdef XP_WIN
Result<Ok, nsresult>
AutoMemMap::initWithHandle(const FileDescriptor& file, size_t size, PRFileMapProtect prot)
{
MOZ_ASSERT(!fd);
MOZ_ASSERT(!handle_);
if (!file.IsValid()) {
return Err(NS_ERROR_INVALID_ARG);
}
handle_ = file.ClonePlatformHandle().release();
MOZ_ASSERT(!addr);
size_ = size;
addr = MapViewOfFile(
handle_,
prot == PR_PROT_READONLY ? FILE_MAP_READ : FILE_MAP_ALL_ACCESS,
0, 0, size);
return Ok();
}
FileDescriptor
AutoMemMap::cloneHandle() const
{
return FileDescriptor(handle_);
}
#else
Result<Ok, nsresult>
AutoMemMap::initWithHandle(const FileDescriptor& file, size_t size, PRFileMapProtect prot)
{
return init(file, prot);
}
FileDescriptor
AutoMemMap::cloneHandle() const
{
return cloneFileDescriptor();
}
#endif
void
AutoMemMap::reset()
{
if (fileMap) {
if (addr && !persistent_) {
Unused << NS_WARN_IF(PR_MemUnmap(addr, size()) != PR_SUCCESS);
addr = nullptr;
}
Unused << NS_WARN_IF(PR_CloseFileMap(fileMap) != PR_SUCCESS);
fileMap = nullptr;
}
#ifdef XP_WIN
if (handle_) {
CloseHandle(handle_);
handle_ = nullptr;
}
#endif
fd.dispose();
}
} // namespace loader
} // namespace mozilla

Просмотреть файл

@ -34,14 +34,26 @@ class AutoMemMap
PRFileMapProtect prot = PR_PROT_READONLY);
Result<Ok, nsresult>
init(const ipc::FileDescriptor& file);
init(const ipc::FileDescriptor& file,
PRFileMapProtect prot = PR_PROT_READONLY,
size_t expectedSize = 0);
// Initializes the mapped memory with a shared memory handle. On
// Unix-like systems, this is identical to the above init() method. On
// Windows, the FileDescriptor must be a handle for a file mapping,
// rather than a file descriptor.
Result<Ok, nsresult>
initWithHandle(const ipc::FileDescriptor& file, size_t size,
PRFileMapProtect prot = PR_PROT_READONLY);
void reset();
bool initialized() { return addr; }
uint32_t size() const { MOZ_ASSERT(fd); return size_; }
uint32_t size() const { return size_; }
template<typename T = void>
const RangedPtr<T> get()
RangedPtr<T> get()
{
MOZ_ASSERT(addr);
return { static_cast<T*>(addr), size_ };
@ -56,17 +68,32 @@ class AutoMemMap
size_t nonHeapSizeOfExcludingThis() { return size_; }
FileDescriptor cloneFileDescriptor();
FileDescriptor cloneFileDescriptor() const;
FileDescriptor cloneHandle() const;
// Makes this mapping persistent. After calling this, the mapped memory
// will remained mapped, even after this instance is destroyed.
void setPersistent() { persistent_ = true; }
private:
Result<Ok, nsresult> initInternal(PRFileMapProtect prot = PR_PROT_READONLY);
Result<Ok, nsresult> initInternal(PRFileMapProtect prot = PR_PROT_READONLY,
size_t expectedSize = 0);
AutoFDClose fd;
PRFileMap* fileMap = nullptr;
#ifdef XP_WIN
// We can't include windows.h in this header, since it gets included
// by some binding headers (which are explicitly incompatible with
// windows.h). So we can't use the HANDLE type here.
void* handle_ = nullptr;
#endif
uint32_t size_ = 0;
void* addr = nullptr;
bool persistent_ = 0;
AutoMemMap(const AutoMemMap&) = delete;
void operator=(const AutoMemMap&) = delete;
};

Просмотреть файл

@ -25,6 +25,7 @@ IPDL_SOURCES += [
]
EXPORTS.mozilla += [
'AutoMemMap.h',
'ScriptPreloader.h',
'URLPreloader.h',
]

Просмотреть файл

@ -0,0 +1,9 @@
<!DOCTYPE html>
<html style="width: 1px;">
<head>
<meta charset="UTF-8">
</head>
<body onload="x.style.color='red';">
<div id="x" style="overflow: scroll;"><input type="image" style="display: contents;"></div>
</body>
</html>

Просмотреть файл

@ -641,6 +641,7 @@ load text-overflow-form-elements.html
load text-overflow-iframe.html
asserts(1-4) load 1225005.html # bug 682647 and bug 448083
load 1233191.html
load 1233607.html
load 1234701-1.html
load 1234701-2.html
load 1271765.html

Просмотреть файл

@ -123,6 +123,19 @@ public:
MOZ_ASSERT(mRangeEnd == aOther.mRangeEnd);
}
template <typename U>
RangedPtr<U>
ReinterpretCast() const
{
#ifdef DEBUG
return { reinterpret_cast<U*>(mPtr),
reinterpret_cast<U*>(mRangeStart),
reinterpret_cast<U*>(mRangeEnd) };
#else
return { reinterpret_cast<U*>(mPtr), nullptr, nullptr };
#endif
}
/*
* You can only assign one RangedPtr into another if the two pointers have
* the same valid range:

Просмотреть файл

@ -807,8 +807,6 @@ malloc_size_of_is_0!(webrender_api::NormalBorder);
#[cfg(feature = "webrender_api")]
malloc_size_of_is_0!(webrender_api::RepeatMode);
#[cfg(feature = "webrender_api")]
malloc_size_of_is_0!(webrender_api::ScrollPolicy);
#[cfg(feature = "webrender_api")]
malloc_size_of_is_0!(webrender_api::ScrollSensitivity);
#[cfg(feature = "webrender_api")]
malloc_size_of_is_0!(webrender_api::StickyOffsetBounds);

Просмотреть файл

@ -78,7 +78,7 @@ kernel32-sys = "0.2"
[build-dependencies]
lazy_static = "1"
log = "0.4"
bindgen = { version = "0.33.2", optional = true, default-features = false }
bindgen = { version = "0.37", optional = true, default-features = false }
regex = {version = "0.2", optional = true}
walkdir = "2.1.4"
toml = {version = "0.4.5", optional = true, default-features = false}

Просмотреть файл

@ -71,7 +71,7 @@ bitflags! {
const IN_OPTIONAL_STATE = 1 << 22;
/// <https://html.spec.whatwg.org/multipage/#selector-read-write>
const IN_READ_WRITE_STATE = 1 << 22;
/// <https://html.spec.whatwg.org/multipage/semantics-other.html#selector-defined>
/// <https://html.spec.whatwg.org/multipage/#selector-defined>
const IN_DEFINED_STATE = 1 << 23;
/// <https://html.spec.whatwg.org/multipage/#selector-visited>
const IN_VISITED_STATE = 1 << 24;

Просмотреть файл

@ -6,17 +6,16 @@
//!
//! https://drafts.csswg.org/mediaqueries-4/#typedef-media-condition
use cssparser::{Parser, Token};
use context::QuirksMode;
use cssparser::{Parser, Token};
use parser::ParserContext;
use std::fmt::{self, Write};
use style_traits::{CssWriter, ParseError, StyleParseErrorKind, ToCss};
use super::{Device, MediaFeatureExpression};
/// A binary `and` or `or` operator.
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Parse, ToCss)]
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, Parse, PartialEq, ToCss)]
#[allow(missing_docs)]
pub enum Operator {
And,
@ -24,7 +23,7 @@ pub enum Operator {
}
/// Whether to allow an `or` condition or not during parsing.
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, Parse, ToCss)]
#[derive(Clone, Copy, Debug, Eq, MallocSizeOf, PartialEq, ToCss)]
enum AllowOr {
Yes,
No,

Просмотреть файл

@ -216,7 +216,7 @@ impl MediaFeatureExpression {
"width" => {
ExpressionKind::Width(Range::Eq(specified::Length::parse_non_negative(context, input)?))
},
_ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name)))
_ => return Err(input.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(name.clone())))
}))
}

Просмотреть файл

@ -27,12 +27,10 @@ mod attr;
mod custom_properties;
mod keyframes;
mod logical_geometry;
mod media_queries;
mod parsing;
mod properties;
mod rule_tree;
mod size_of;
#[path = "../../../ports/geckolib/tests/specified_values.rs"]
mod specified_values;
mod str;
mod stylesheets;

Просмотреть файл

@ -7,7 +7,7 @@ use style::computed_values::display::T as Display;
use style::properties::{PropertyDeclaration, Importance};
use style::properties::declaration_block::PropertyDeclarationBlock;
use style::properties::parse_property_declaration_list;
use style::values::{CustomIdent, RGBA};
use style::values::RGBA;
use style::values::specified::{BorderStyle, BorderSideWidth, Color};
use style::values::specified::{Length, LengthOrPercentage, LengthOrPercentageOrAuto};
use style::values::specified::NoCalcLength;
@ -75,39 +75,6 @@ mod shorthand_serialization {
block.to_css_string()
}
// Add Test to show error if a longhand property is missing!!!!!!
mod overflow {
pub use super::*;
use style::properties::longhands::overflow_x::SpecifiedValue as OverflowValue;
#[test]
fn equal_overflow_properties_should_serialize_to_single_value() {
let mut properties = Vec::new();
let overflow = OverflowValue::Auto;
properties.push(PropertyDeclaration::OverflowX(overflow));
properties.push(PropertyDeclaration::OverflowY(overflow));
let serialization = shorthand_properties_to_string(properties);
assert_eq!(serialization, "overflow: auto;");
}
#[test]
fn different_overflow_properties_should_serialize_to_two_values() {
let mut properties = Vec::new();
let overflow_x = OverflowValue::Scroll;
properties.push(PropertyDeclaration::OverflowX(overflow_x));
let overflow_y = OverflowValue::Auto;
properties.push(PropertyDeclaration::OverflowY(overflow_y));
let serialization = shorthand_properties_to_string(properties);
assert_eq!(serialization, "overflow-x: scroll; overflow-y: auto;");
}
}
mod four_sides_shorthands {
pub use super::*;

Просмотреть файл

@ -1 +1 @@
{"files":{"Cargo.toml":"d2d15d8518f87e50143184b13e14139095b0a6aa627d4d5d3a2d12893e765f50","build.rs":"032a1c51963894a421b0535f9227796d88768ac5f665a81d2edced69dc6d106a","src/callbacks.rs":"49f382ebdb94c8f0aba5496f5283ae3cdcf6666a5c41c604e6356e674f9a072b","src/clang.rs":"33d94fa699f052b52a2804b85f49fa5de3a2404ae05801ef9eae16016bc841f1","src/codegen/bitfield_unit.rs":"bd1a19701f1766d0bae3bcb97d7c3cb3881d4b182c56b8f4dfd24b7cc87b5338","src/codegen/bitfield_unit_tests.rs":"2073ac6a36e0bc9afaef5b1207966817c8fb7a1a9f6368c3b1b8f79822efbfba","src/codegen/error.rs":"2613af1d833377fd4a70719f4a09951d9d45dc9227827b9a2a938a1bcaaea2dd","src/codegen/helpers.rs":"bcb951f320fd0948e341d8eabdb58567296d77bf1ae5040c05d967e6435a15d5","src/codegen/impl_debug.rs":"e2ffd5b6ed936698aa4b9e7e3459d353383792707ad51f829a18a822f69cab0e","src/codegen/impl_partialeq.rs":"e86050b98f57fa4496dbde0beea319a89e46290309d274f626361779549b95bd","src/codegen/mod.rs":"74e818d857fb5147f623e9287632d23c4bd0cf87de840034809992b74ff88bdc","src/codegen/struct_layout.rs":"698ed7340242d1cbedd38d400c7c83c32e2fa043c35dbc9a2eea4022251ffdb0","src/extra_assertions.rs":"449549c4a7a50c3f0b06332452b2fb6c9b23f31ca8e5e1656fe6c7f21e8ef7fa","src/features.rs":"8c2148a6f922ca9cb0de2dd3ad77c4dd5734c4c219a5bea9d6b22c4367acb187","src/ir/analysis/derive_copy.rs":"14b53c53b337be00d59424371c07c6712d7cfc9a6735f9d913cda043fddce797","src/ir/analysis/derive_debug.rs":"1d6621c0fa5d899310cc175cb99703606ed34fd7f7ad77bb60f012f25ba504af","src/ir/analysis/derive_default.rs":"4fac04fc3019562cd213586680ecdcf8a3b3544ca3a5c5117f68e5c26e7ee0d9","src/ir/analysis/derive_hash.rs":"a50e849b4388115264c2d6afef5ab07e309d2469f4c3342fb683c799451e9e19","src/ir/analysis/derive_partialeq_or_partialord.rs":"46611c7f3caa0fe78243187742c4a36003dbc266de4c4390642e136bb889c43f","src/ir/analysis/has_destructor.rs":"d9aaaceba580b48eb0df4e5537b34b417c51ccdfeb8f6b72484f3bf4992317fe","src/ir/analysis/has_float.rs":"2a0465503d2c8247eaf916bd6a03594f3dc0370533d9a7c58cc5afb86693816c","src/ir/analysis/has_type_param_in_array.rs":"fcb1c78b6000f1f5eb8d8147e2afdaba9eb0e3a81b61e72537048dfdbeea7bcd","src/ir/analysis/has_vtable.rs":"37765e954ef792e369a58ccfe1d827a00fe9bce680466da1d6523671b94b6c92","src/ir/analysis/mod.rs":"ea5ace45c77e855674bb565ba0fef556f60e3293b0ddcf11d3a5a6ec15ab0648","src/ir/analysis/sizedness.rs":"3d3c8bde40604d53bb64273a3cbd8c55936a7dfe1de9b2ba92fc2c45572624b4","src/ir/analysis/template_params.rs":"5c6ee7a251a321ef5733e2e7ac3264621b4181268babcc008b69dbfc37691fb1","src/ir/annotations.rs":"ef106afcbe6084c18bd13a37ee3c1cdc9596bfb055db8c773d81f8f15fec3208","src/ir/comment.rs":"36f2a1d3970fdbf3d72c1f094043902747cde395215bdf7e9103926d9df011fd","src/ir/comp.rs":"b24e6ab76235b46bb5a262e3a3f2fc685c26bd7482aea113231a942eeffd0cf5","src/ir/context.rs":"ccd99c814f1a8ba1f3a30667a8d90db13a50adc26620be08f907283d1c5f08a3","src/ir/derive.rs":"1fd6ad621e3c60b950acbd51fbe386d1f0fadb7c1889c723245afff45e42e143","src/ir/dot.rs":"d01f1621ab67e368d854a82bd6bb0b8dd52f3c2c733de8eaf81aece9543818cb","src/ir/enum_ty.rs":"98a4aa58e598b31e4dc2c052c90029f37b53b5c5cfcbd216d4b0e8c73454813f","src/ir/function.rs":"cce97e7cd6ffb7d5ae40e6be1b82e7ae899d9ea9cf7c8f97380486ac7cc120e6","src/ir/int.rs":"1f61a472288afe489d9320bc8b13920333ece57891ae8570b4c4f25ab50688e6","src/ir/item.rs":"03477f4f4abfebc92ce4c9a202e33c86615dfffe3e6d1e0a201d2e85eecb9917","src/ir/item_kind.rs":"dbeae8c4fd0e5c9485d325aea040e056a1f2cd6d43fc927dee8fe1c0c59a7197","src/ir/layout.rs":"e3d1adf1ad2fa5bd96530cdd5097db3d9cc7b44d33ec23a04fcfccecd9cf4469","src/ir/mod.rs":"2eae90f207fad2e45957ec9287064992a419e3fc916aba84faff2ea25cbeb5ee","src/ir/module.rs":"c4d90bf38fe3672e01923734ccbdb7951ea929949d5f413a9c2aee12395a5094","src/ir/objc.rs":"05068c4fbf42429c4ac2a233c874f18ffcf7dc1744398e400a5a48d0e7a972f2","src/ir/template.rs":"bcd750450a4df0200a6e7958f9c96a09b91e3ccd29c60712f2b9d3458f1234aa","src/ir/traversal.rs":"da73d3fafa594fb12c13136f5c9d6e6ee0d6c7fa4b6e57863638d4ba5ef55dfa","src/ir/ty.rs":"7d16711a053f1b4e9d11d3c5665062a58278a869b196a24b7b2a62227eb3a38f","src/ir/var.rs":"57c8aa9f834c6f06418f7d471b1771bbb915821ef0d194b383be60092edca5f7","src/lib.rs":"99ed57a26e794ce724e434af0bf4f72b199bd0e1c42833324beb939acda9af33","src/log_stubs.rs":"6dfdd908b7c6453da416cf232893768f9480e551ca4add0858ef88bf71ee6ceb","src/main.rs":"e519053bcdde6bc88f60f955246a02d53b3db1cc5ccd1612e6675b790b7460b0","src/options.rs":"3df0214f428c221604420f8eb511b1c1e6d9326d1c6d3d2dea48278f833f9b77","src/parse.rs":"be7d13cc84fae79ec7b3aa9e77063fa475a48d74a854423e2c72d75006a25202","src/regex_set.rs":"a55241f2117f15729d174790f386e255fcb224b692325bbe6716dbb1d6874881","src/time.rs":"a02befb48d10dcc31e3f9571b2fa1c40f97fafe6f6ae7d7fc4f8fd01f1a169ba"},"package":"603ed8d8392ace9581e834e26bd09799bf1e989a79bd1aedbb893e72962bdc6e"}
{"files":{"Cargo.toml":"3080fa2631c58e35cb1b32642139d8c303a609f8b554bfe69cd659a5374f18b9","LICENSE":"1d2e4bdb9d94ab020e9550136cae9ec73fc699c3c96a9d98078c542e9b93d294","README.md":"630d1a1d123c131bad0fec23173e263ba8ecc064b5cd8446d4cab7ffd197db45","build.rs":"032a1c51963894a421b0535f9227796d88768ac5f665a81d2edced69dc6d106a","src/callbacks.rs":"9d41b7848cea37e8741fa7bc947ba58a83647824b1a0bbe7ff75012c412eab13","src/clang.rs":"5ce27d0772e66f9f2f94a55afd18c98d4a57aed4c1d57da53b025fbbbb81a287","src/codegen/bitfield_unit.rs":"88b0604322dc449fc9284850eadc1f5d14b42fa747d4258bae0b6b9535f52dfd","src/codegen/bitfield_unit_tests.rs":"2073ac6a36e0bc9afaef5b1207966817c8fb7a1a9f6368c3b1b8f79822efbfba","src/codegen/error.rs":"2613af1d833377fd4a70719f4a09951d9d45dc9227827b9a2a938a1bcaaea2dd","src/codegen/helpers.rs":"8badd4b5ba38b83477c3ee3fc6f9ca79059b5650f5b489b2723c335037e27d92","src/codegen/impl_debug.rs":"e2ffd5b6ed936698aa4b9e7e3459d353383792707ad51f829a18a822f69cab0e","src/codegen/impl_partialeq.rs":"d69e2a9cdf2fdea74a60532109c0a1a75791f5a5ef931b28c5d447fa2915e5d3","src/codegen/mod.rs":"c923594d8d27dede9192dd1081acdedf97d67430f780e3dc4db39b8928a55d71","src/codegen/struct_layout.rs":"9bd0e3455e55e2a1faa4f332a327c2529a21bdfdd0fcb3a45bc5cdd7801d288f","src/extra_assertions.rs":"449549c4a7a50c3f0b06332452b2fb6c9b23f31ca8e5e1656fe6c7f21e8ef7fa","src/features.rs":"a437e6f736c8fba81ff74d90e7ddd142192ae5ffb9240d8c885eb84be6f2fe45","src/ir/analysis/derive_copy.rs":"59c21e299af3a36c6c82d4d16454700238269abd5929ec2d67c8414aebf82c3b","src/ir/analysis/derive_debug.rs":"3530e27ab0e260ec013cee3ad78a81497970c656a8eed589b755cce8caf53040","src/ir/analysis/derive_default.rs":"20e9dac151fadc59a7926ed9276ee8ced47e59c3f0c43f69fdafb75706045aca","src/ir/analysis/derive_hash.rs":"85c73c5660dc311ab6c15a21b69c4c5d2aa380d740decaf59ad594a6728cbe1f","src/ir/analysis/derive_partialeq_or_partialord.rs":"fb9540c324fdfcc9b0ae816e7713af000b11f5e2768c512c22a3082f263bb6bc","src/ir/analysis/has_destructor.rs":"d9aaaceba580b48eb0df4e5537b34b417c51ccdfeb8f6b72484f3bf4992317fe","src/ir/analysis/has_float.rs":"2a0465503d2c8247eaf916bd6a03594f3dc0370533d9a7c58cc5afb86693816c","src/ir/analysis/has_type_param_in_array.rs":"fcb1c78b6000f1f5eb8d8147e2afdaba9eb0e3a81b61e72537048dfdbeea7bcd","src/ir/analysis/has_vtable.rs":"37765e954ef792e369a58ccfe1d827a00fe9bce680466da1d6523671b94b6c92","src/ir/analysis/mod.rs":"ea5ace45c77e855674bb565ba0fef556f60e3293b0ddcf11d3a5a6ec15ab0648","src/ir/analysis/sizedness.rs":"3d3c8bde40604d53bb64273a3cbd8c55936a7dfe1de9b2ba92fc2c45572624b4","src/ir/analysis/template_params.rs":"6554dd1240142ec0e7299e678b696725f5cba99243d1c3d1cbf58d4764082fd6","src/ir/annotations.rs":"ef106afcbe6084c18bd13a37ee3c1cdc9596bfb055db8c773d81f8f15fec3208","src/ir/comment.rs":"000481754e5433d7c0886b9ce8b93b64c7ab1ae52867d211c73c7c4b336649a2","src/ir/comp.rs":"7b22f3ff19ca45a6fbfe7ea015109d43f4ddf65b33b47b1c37829fcb87cdff9b","src/ir/context.rs":"80679859b4efa52d74b0c7501bb5951b58c9705a97b96c9fc05134d1abe401c6","src/ir/derive.rs":"9550d01731ca66be28124c91fd0211a618743a065bec7b00e27c934afff82a84","src/ir/dot.rs":"d01f1621ab67e368d854a82bd6bb0b8dd52f3c2c733de8eaf81aece9543818cb","src/ir/enum_ty.rs":"3611100df8ddf01b010d2eae1d26a67df022e47b6236b0ed9d1b9b42340ebafd","src/ir/function.rs":"b86e665c6659c32bce39194240e7da6221c5a2ec51b362ad9f6e34f1bc396a6f","src/ir/int.rs":"1f61a472288afe489d9320bc8b13920333ece57891ae8570b4c4f25ab50688e6","src/ir/item.rs":"6f0d13615c6883b5e64c75f6d18d79b978b47aa3599ae1f4c196903d2d2cda68","src/ir/item_kind.rs":"dbeae8c4fd0e5c9485d325aea040e056a1f2cd6d43fc927dee8fe1c0c59a7197","src/ir/layout.rs":"17daab0a80564006de1f6b6190e7d9e6c5eb96990242fe707f8dc676f7110c18","src/ir/mod.rs":"2eae90f207fad2e45957ec9287064992a419e3fc916aba84faff2ea25cbeb5ee","src/ir/module.rs":"c4d90bf38fe3672e01923734ccbdb7951ea929949d5f413a9c2aee12395a5094","src/ir/objc.rs":"828a890acdc8b10c44e69e2ed4a4f5d8c0e734606d3a8cc71658dcf43a49acf4","src/ir/template.rs":"21ba4cbacafce39b4a8013bc97e8054a906a8bc2f45a51aeef3b007caadde221","src/ir/traversal.rs":"eaca9aa6deb3eea9b8d7adc696781c70038796ff43e536bda47e90f84fe87d61","src/ir/ty.rs":"daa95f757288e4bfe84f9724c5f5df127b6f3a4452330691a24a94369db7d993","src/ir/var.rs":"57c8aa9f834c6f06418f7d471b1771bbb915821ef0d194b383be60092edca5f7","src/lib.rs":"d4217ac878659794c5990b1612f1de12f94f975257ea14307fb7dc63ac3a76da","src/log_stubs.rs":"6dfdd908b7c6453da416cf232893768f9480e551ca4add0858ef88bf71ee6ceb","src/main.rs":"e519053bcdde6bc88f60f955246a02d53b3db1cc5ccd1612e6675b790b7460b0","src/options.rs":"f1be872e418a96582b048c095ceeeba012b92ffed8a9658cd1fd9ae0e192372d","src/parse.rs":"be7d13cc84fae79ec7b3aa9e77063fa475a48d74a854423e2c72d75006a25202","src/regex_set.rs":"a55241f2117f15729d174790f386e255fcb224b692325bbe6716dbb1d6874881","src/time.rs":"3b763e6fee51d0eb01228dfe28bc28a9f692aff73b2a7b90a030902e0238fca6"},"package":"1b25ab82877ea8fe6ce1ce1f8ac54361f0218bad900af9eb11803994bf67c221"}

19
third_party/rust/bindgen/Cargo.toml поставляемый
Просмотреть файл

@ -12,11 +12,12 @@
[package]
name = "bindgen"
version = "0.33.2"
version = "0.37.4"
authors = ["Jyun-Yan You <jyyou.tw@gmail.com>", "Emilio Cobos Álvarez <emilio@crisal.io>", "Nick Fitzgerald <fitzgen@gmail.com>", "The Servo project developers"]
build = "build.rs"
include = ["Cargo.toml", "build.rs", "src/*.rs", "src/**/*.rs"]
include = ["LICENSE", "README.md", "Cargo.toml", "build.rs", "src/*.rs", "src/**/*.rs"]
description = "Automatically generates Rust FFI bindings to C and C++ libraries."
homepage = "https://rust-lang-nursery.github.io/rust-bindgen/"
documentation = "https://docs.rs/bindgen"
readme = "README.md"
keywords = ["bindings", "ffi", "code-generation"]
@ -38,8 +39,8 @@ version = "0.2"
version = "0.1.0"
[dependencies.clang-sys]
version = "0.22.0"
features = ["runtime", "clang_3_9"]
version = "0.23"
features = ["runtime", "clang_6_0"]
[dependencies.clap]
version = "2"
@ -58,11 +59,16 @@ optional = true
[dependencies.peeking_take_while]
version = "0.1.2"
[dependencies.proc-macro2]
version = "0.3.2, < 0.3.6"
default-features = false
[dependencies.quote]
version = "0.3.15"
version = "0.5"
default-features = false
[dependencies.regex]
version = "0.2"
version = "1.0"
[dependencies.which]
version = "1.0.2"
@ -84,5 +90,6 @@ testing_only_extra_assertions = []
testing_only_libclang_3_8 = []
testing_only_libclang_3_9 = []
testing_only_libclang_4 = []
testing_only_libclang_5 = []
[badges.travis-ci]
repository = "rust-lang-nursery/rust-bindgen"

28
third_party/rust/bindgen/LICENSE поставляемый Normal file
Просмотреть файл

@ -0,0 +1,28 @@
Copyright (c) 2013, Jyun-Yan You
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the author nor the names of his contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

45
third_party/rust/bindgen/README.md поставляемый Normal file
Просмотреть файл

@ -0,0 +1,45 @@
# `bindgen`
[`impl period`](https://blog.rust-lang.org/2017/09/18/impl-future-for-rust.html) has been started! Join us at [Gitter.im](https://gitter.im/rust-impl-period/WG-dev-tools-bindgen).
**`bindgen` automatically generates Rust FFI bindings to C (and some C++) libraries.**
For example, given the C header `doggo.h`:
```c
typedef struct Doggo {
int many;
char wow;
} Doggo;
void eleven_out_of_ten_majestic_af(Doggo* pupper);
```
`bindgen` produces Rust FFI code allowing you to call into the `doggo` library's
functions and use its types:
```rust
/* automatically generated by rust-bindgen */
#[repr(C)]
pub struct Doggo {
pub many: ::std::os::raw::c_int,
pub wow: ::std::os::raw::c_char,
}
extern "C" {
pub fn eleven_out_of_ten_majestic_af(pupper: *mut Doggo);
}
```
## Users Guide
[📚 Read the `bindgen` users guide here! 📚](https://rust-lang-nursery.github.io/rust-bindgen)
## API Reference
[API reference documentation is on docs.rs](https://docs.rs/bindgen)
## Contributing
[See `CONTRIBUTING.md` for hacking on `bindgen`!](./CONTRIBUTING.md)

2
third_party/rust/bindgen/src/callbacks.rs поставляемый
Просмотреть файл

@ -35,7 +35,7 @@ pub trait ParseCallbacks: fmt::Debug + UnwindSafe {
None
}
/// This function should return whether, given the a given enum variant
/// This function should return whether, given an enum variant
/// name, and value, this enum variant will forcibly be a constant.
fn enum_variant_behavior(
&self,

48
third_party/rust/bindgen/src/clang.rs поставляемый
Просмотреть файл

@ -911,6 +911,13 @@ impl Type {
/// Get the number of template arguments this type has, or `None` if it is
/// not some kind of template.
pub fn num_template_args(&self) -> Option<u32> {
// If an old libclang is loaded, we have no hope of answering this
// question correctly. However, that's no reason to panic when
// generating bindings for simple C headers with an old libclang.
if !clang_Type_getNumTemplateArguments::is_loaded() {
return None
}
let n = unsafe { clang_Type_getNumTemplateArguments(self.x) };
if n >= 0 {
Some(n as u32)
@ -975,7 +982,7 @@ impl Type {
}
}
/// Get the canonical version of this type. This sees through `typdef`s and
/// Get the canonical version of this type. This sees through `typedef`s and
/// aliases to get the underlying, canonical type.
pub fn canonical_type(&self) -> Type {
unsafe {
@ -1639,8 +1646,11 @@ pub fn ast_dump(c: &Cursor, depth: isize) -> CXChildVisitResult {
depth,
format!(" {}spelling = \"{}\"", prefix, ty.spelling()),
);
let num_template_args =
unsafe { clang_Type_getNumTemplateArguments(ty.x) };
let num_template_args = if clang_Type_getNumTemplateArguments::is_loaded() {
unsafe { clang_Type_getNumTemplateArguments(ty.x) }
} else {
-1
};
if num_template_args >= 0 {
print_indent(
depth,
@ -1812,3 +1822,35 @@ impl Drop for EvalResult {
unsafe { clang_EvalResult_dispose(self.x) };
}
}
/// Target information obtained from libclang.
#[derive(Debug)]
pub struct TargetInfo {
/// The target triple.
pub triple: String,
/// The width of the pointer _in bits_.
pub pointer_width: usize,
}
impl TargetInfo {
/// Tries to obtain target information from libclang.
pub fn new(tu: &TranslationUnit) -> Option<Self> {
if !clang_getTranslationUnitTargetInfo::is_loaded() {
return None;
}
let triple;
let pointer_width;
unsafe {
let ti = clang_getTranslationUnitTargetInfo(tu.x);
triple = cxstring_into_string(clang_TargetInfo_getTriple(ti));
pointer_width = clang_TargetInfo_getPointerWidth(ti);
clang_TargetInfo_dispose(ti);
}
assert!(pointer_width > 0);
assert_eq!(pointer_width % 8, 0);
Some(TargetInfo {
triple,
pointer_width: pointer_width as usize,
})
}
}

Просмотреть файл

@ -27,7 +27,13 @@ where
let byte_index = index / 8;
let byte = self.storage.as_ref()[byte_index];
let bit_index = index % 8;
let bit_index =
if cfg!(target_endian = "big") {
7 - (index % 8)
} else {
index % 8
};
let mask = 1 << bit_index;
byte & mask == mask
@ -40,9 +46,14 @@ where
let byte_index = index / 8;
let byte = &mut self.storage.as_mut()[byte_index];
let bit_index = index % 8;
let mask = 1 << bit_index;
let bit_index =
if cfg!(target_endian = "big") {
7 - (index % 8)
} else {
index % 8
};
let mask = 1 << bit_index;
if val {
*byte |= mask;
} else {
@ -60,7 +71,13 @@ where
for i in 0..(bit_width as usize) {
if self.get_bit(i + bit_offset) {
val |= 1 << i;
let index =
if cfg!(target_endian = "big") {
bit_width as usize - 1 - i
} else {
i
};
val |= 1 << index;
}
}
@ -76,7 +93,13 @@ where
for i in 0..(bit_width as usize) {
let mask = 1 << i;
let val_bit_is_set = val & mask == mask;
self.set_bit(i + bit_offset, val_bit_is_set);
let index =
if cfg!(target_endian = "big") {
bit_width as usize - 1 - i
} else {
i
};
self.set_bit(index + bit_offset, val_bit_is_set);
}
}
}

Просмотреть файл

@ -4,26 +4,28 @@ use ir::context::BindgenContext;
use ir::layout::Layout;
use quote;
use std::mem;
use proc_macro2::{Term, Span};
pub mod attributes {
use quote;
use proc_macro2::{Term, Span};
pub fn repr(which: &str) -> quote::Tokens {
let which = quote::Ident::new(which);
let which = Term::new(which, Span::call_site());
quote! {
#[repr( #which )]
}
}
pub fn repr_list(which_ones: &[&str]) -> quote::Tokens {
let which_ones = which_ones.iter().cloned().map(quote::Ident::new);
let which_ones = which_ones.iter().cloned().map(|one| Term::new(one, Span::call_site()));
quote! {
#[repr( #( #which_ones ),* )]
}
}
pub fn derives(which_ones: &[&str]) -> quote::Tokens {
let which_ones = which_ones.iter().cloned().map(quote::Ident::new);
let which_ones = which_ones.iter().cloned().map(|one| Term::new(one, Span::call_site()));
quote! {
#[derive( #( #which_ones ),* )]
}
@ -40,9 +42,9 @@ pub mod attributes {
// time they get here. Just make sure that we have newlines around it so
// that nothing else gets wrapped into the comment.
let mut tokens = quote! {};
tokens.append("\n");
tokens.append(comment);
tokens.append("\n");
tokens.append(Term::new("\n", Span::call_site()));
tokens.append(Term::new(&comment, Span::call_site()));
tokens.append(Term::new("\n", Span::call_site()));
tokens
}
@ -73,7 +75,7 @@ pub fn blob(layout: Layout) -> quote::Tokens {
}
};
let ty_name = quote::Ident::new(ty_name);
let ty_name = Term::new(ty_name, Span::call_site());
let data_len = opaque.array_size().unwrap_or(layout.size);
@ -103,7 +105,7 @@ pub fn bitfield_unit(ctx: &BindgenContext, layout: Layout) -> quote::Tokens {
let mut tokens = quote! {};
if ctx.options().enable_cxx_namespaces {
tokens.append(quote! { root:: });
tokens.append_all(quote! { root:: });
}
let align = match layout.align {
@ -114,7 +116,7 @@ pub fn bitfield_unit(ctx: &BindgenContext, layout: Layout) -> quote::Tokens {
};
let size = layout.size;
tokens.append(quote! {
tokens.append_all(quote! {
__BindgenBitfieldUnit<[u8; #size], #align>
});
@ -126,6 +128,7 @@ pub mod ast_ty {
use ir::function::FunctionSig;
use ir::ty::FloatKind;
use quote;
use proc_macro2;
pub fn raw_type(ctx: &BindgenContext, name: &str) -> quote::Tokens {
let ident = ctx.rust_ident_raw(name);
@ -166,29 +169,25 @@ pub mod ast_ty {
pub fn int_expr(val: i64) -> quote::Tokens {
// Don't use quote! { #val } because that adds the type suffix.
let mut tokens = quote! {};
tokens.append(val.to_string());
tokens
let val = proc_macro2::Literal::i64_unsuffixed(val);
quote!(#val)
}
pub fn uint_expr(val: u64) -> quote::Tokens {
// Don't use quote! { #val } because that adds the type suffix.
let mut tokens = quote! {};
tokens.append(val.to_string());
tokens
let val = proc_macro2::Literal::u64_unsuffixed(val);
quote!(#val)
}
pub fn byte_array_expr(bytes: &[u8]) -> quote::Tokens {
let mut bytes: Vec<_> = bytes.iter().cloned().collect();
bytes.push(0);
quote! {
#bytes
}
quote! { [ #(#bytes),* ] }
}
pub fn cstr_expr(mut string: String) -> quote::Tokens {
string.push('\0');
let b = quote::ByteStr(&string);
let b = proc_macro2::Literal::byte_string(&string.as_bytes());
quote! {
#b
}
@ -199,16 +198,9 @@ pub mod ast_ty {
f: f64,
) -> Result<quote::Tokens, ()> {
if f.is_finite() {
let mut string = f.to_string();
let val = proc_macro2::Literal::f64_unsuffixed(f);
// So it gets properly recognised as a floating point constant.
if !string.contains('.') {
string.push('.');
}
let mut tokens = quote! {};
tokens.append(string);
return Ok(tokens);
return Ok(quote!(#val));
}
let prefix = ctx.trait_prefix();

Просмотреть файл

@ -4,6 +4,7 @@ use ir::context::BindgenContext;
use ir::item::{IsOpaque, Item};
use ir::ty::{TypeKind, RUST_DERIVE_IN_ARRAY_LIMIT};
use quote;
use proc_macro2;
/// Generate a manual implementation of `PartialEq` trait for the
/// specified compound type.
@ -20,7 +21,7 @@ pub fn gen_partialeq_impl(
&self._bindgen_opaque_blob[..] == &other._bindgen_opaque_blob[..]
});
} else if comp_info.kind() == CompKind::Union {
assert!(!ctx.options().rust_features().untagged_union());
assert!(!ctx.options().rust_features().untagged_union);
tokens.push(quote! {
&self.bindgen_union_field[..] == &other.bindgen_union_field[..]
});
@ -71,7 +72,7 @@ pub fn gen_partialeq_impl(
}
fn gen_field(ctx: &BindgenContext, ty_item: &Item, name: &str) -> quote::Tokens {
fn quote_equals(name_ident: quote::Ident) -> quote::Tokens {
fn quote_equals(name_ident: proc_macro2::Term) -> quote::Tokens {
quote! { self.#name_ident == other.#name_ident }
}

368
third_party/rust/bindgen/src/codegen/mod.rs поставляемый
Просмотреть файл

@ -38,14 +38,15 @@ use ir::ty::{Type, TypeKind};
use ir::var::Var;
use quote;
use proc_macro2::{self, Term, Span};
use std;
use std::borrow::Cow;
use std::cell::Cell;
use std::collections::{HashSet, VecDeque};
use std::collections::hash_map::{Entry, HashMap};
use std::fmt::Write;
use std::iter;
use std::mem;
use std::ops;
// Name of type defined in constified enum module
@ -75,7 +76,7 @@ fn root_import(ctx: &BindgenContext, module: &Item) -> quote::Tokens {
let mut tokens = quote! {};
tokens.append_separated(path, "::");
tokens.append_separated(path, Term::new("::", Span::call_site()));
quote! {
#[allow(unused_imports)]
@ -299,17 +300,12 @@ impl AppendImplicitTemplateParams for quote::Tokens {
_ => {},
}
if let Some(params) = item.used_template_params(ctx) {
if params.is_empty() {
return;
}
let params = params.into_iter().map(|p| {
p.try_to_rust_ty(ctx, &())
.expect("template params cannot fail to be a rust type")
});
self.append(quote! {
let params: Vec<_> = item.used_template_params(ctx).iter().map(|p| {
p.try_to_rust_ty(ctx, &())
.expect("template params cannot fail to be a rust type")
}).collect();
if !params.is_empty() {
self.append_all(quote! {
< #( #params ),* >
});
}
@ -404,7 +400,7 @@ impl CodeGenerator for Module {
if result.saw_incomplete_array {
utils::prepend_incomplete_array_types(ctx, &mut *result);
}
if ctx.need_bindegen_complex_type() {
if ctx.need_bindgen_complex_type() {
utils::prepend_complex_type(&mut *result);
}
if result.saw_objc {
@ -427,6 +423,18 @@ impl CodeGenerator for Module {
let mut found_any = false;
let inner_items = result.inner(|result| {
result.push(root_import(ctx, item));
let path = item.namespace_aware_canonical_path(ctx).join("::");
if let Some(raw_lines) = ctx.options().module_lines.get(&path) {
for raw_line in raw_lines {
found_any = true;
// FIXME(emilio): The use of `Term` is an abuse, but we abuse it
// in a bunch more places.
let line = Term::new(raw_line, Span::call_site());
result.push(quote! { #line });
}
}
codegen_self(result, &mut found_any);
});
@ -436,16 +444,15 @@ impl CodeGenerator for Module {
}
let name = item.canonical_name(ctx);
result.push(if name == "root" {
let ident = ctx.rust_ident(name);
result.push(if item.id() == ctx.root_module() {
quote! {
#[allow(non_snake_case, non_camel_case_types, non_upper_case_globals)]
pub mod root {
pub mod #ident {
#( #inner_items )*
}
}
} else {
let ident = ctx.rust_ident(name);
quote! {
pub mod #ident {
#( #inner_items )*
@ -479,11 +486,8 @@ impl CodeGenerator for Var {
// We can't generate bindings to static variables of templates. The
// number of actual variables for a single declaration are open ended
// and we don't know what instantiations do or don't exist.
let type_params = item.all_template_params(ctx);
if let Some(params) = type_params {
if !params.is_empty() {
return;
}
if !item.all_template_params(ctx).is_empty() {
return;
}
let ty = self.ty().to_rust_ty_or_opaque(ctx, &());
@ -636,15 +640,10 @@ impl CodeGenerator for Type {
return;
}
let mut outer_params = item.used_template_params(ctx)
.and_then(|ps| if ps.is_empty() {
None
} else {
Some(ps)
});
let mut outer_params = item.used_template_params(ctx);
let inner_rust_type = if item.is_opaque(ctx, &()) {
outer_params = None;
outer_params = vec![];
self.to_opaque(ctx, item)
} else {
// Its possible that we have better layout information than
@ -691,7 +690,7 @@ impl CodeGenerator for Type {
// We prefer using `pub use` over `pub type` because of:
// https://github.com/rust-lang/rust/issues/26264
if inner_rust_type.as_str()
if inner_rust_type.to_string()
.chars()
.all(|c| match c {
// These are the only characters allowed in simple
@ -699,50 +698,48 @@ impl CodeGenerator for Type {
'A'...'Z' | 'a'...'z' | '0'...'9' | ':' | '_' | ' ' => true,
_ => false,
}) &&
outer_params.is_none() &&
outer_params.is_empty() &&
inner_item.expect_type().canonical_type(ctx).is_enum()
{
tokens.append(quote! {
tokens.append_all(quote! {
pub use
});
let path = top_level_path(ctx, item);
tokens.append_separated(path, "::");
tokens.append(quote! {
tokens.append_separated(path, Term::new("::", Span::call_site()));
tokens.append_all(quote! {
:: #inner_rust_type as #rust_name ;
});
result.push(tokens);
return;
}
tokens.append(quote! {
tokens.append_all(quote! {
pub type #rust_name
});
if let Some(params) = outer_params {
let params: Vec<_> = params.into_iter()
.filter_map(|p| p.as_template_param(ctx, &()))
.collect();
if params.iter().any(|p| ctx.resolve_type(*p).is_invalid_type_param()) {
warn!(
"Item contained invalid template \
parameter: {:?}",
item
);
return;
}
let params: Vec<_> = outer_params.into_iter()
.filter_map(|p| p.as_template_param(ctx, &()))
.collect();
if params.iter().any(|p| ctx.resolve_type(*p).is_invalid_type_param()) {
warn!(
"Item contained invalid template \
parameter: {:?}",
item
);
return;
}
let params: Vec<_> = params.iter().map(|p| {
p.try_to_rust_ty(ctx, &())
.expect("type parameters can always convert to rust ty OK")
}).collect();
let params = params.iter()
.map(|p| {
p.try_to_rust_ty(ctx, &())
.expect("type parameters can always convert to rust ty OK")
});
tokens.append(quote! {
if !params.is_empty() {
tokens.append_all(quote! {
< #( #params ),* >
});
}
tokens.append(quote! {
tokens.append_all(quote! {
= #inner_rust_type ;
});
@ -1059,11 +1056,11 @@ impl<'a> FieldCodegen<'a> for FieldData {
self.annotations().accessor_kind().unwrap_or(accessor_kind);
if is_private {
field.append(quote! {
field.append_all(quote! {
#field_ident : #ty ,
});
} else {
field.append(quote! {
field.append_all(quote! {
pub #field_ident : #ty ,
});
}
@ -1123,7 +1120,7 @@ impl<'a> FieldCodegen<'a> for FieldData {
impl BitfieldUnit {
/// Get the constructor name for this bitfield unit.
fn ctor_name(&self) -> quote::Tokens {
let ctor_name = quote::Ident::new(format!("new_bitfield_{}", self.nth()));
let ctor_name = Term::new(&format!("new_bitfield_{}", self.nth()), Span::call_site());
quote! {
#ctor_name
}
@ -1154,7 +1151,7 @@ impl Bitfield {
let width = self.width() as u8;
let prefix = ctx.trait_prefix();
ctor_impl.append(quote! {
ctor_impl.append_all(quote! {
__bindgen_bitfield_unit.set(
#offset,
#width,
@ -1322,7 +1319,7 @@ impl<'a> FieldCodegen<'a> for Bitfield {
let prefix = ctx.trait_prefix();
let getter_name = bitfield_getter_name(ctx, self);
let setter_name = bitfield_setter_name(ctx, self);
let unit_field_ident = quote::Ident::new(unit_field_name);
let unit_field_ident = Term::new(unit_field_name, Span::call_site());
let bitfield_ty_item = ctx.resolve_item(self.ty());
let bitfield_ty = bitfield_ty_item.expect_type();
@ -1418,8 +1415,6 @@ impl CodeGenerator for CompInfo {
return;
}
let used_template_params = item.used_template_params(ctx);
let ty = item.expect_type();
let layout = ty.layout(ctx);
let mut packed = self.is_packed(ctx, &layout);
@ -1527,6 +1522,7 @@ impl CodeGenerator for CompInfo {
});
}
let mut explicit_align = None;
if is_opaque {
// Opaque item should not have generated methods, fields.
debug_assert!(fields.is_empty());
@ -1534,6 +1530,8 @@ impl CodeGenerator for CompInfo {
match layout {
Some(l) => {
explicit_align = Some(l.align);
let ty = helpers::blob(l);
fields.push(quote! {
pub _bindgen_opaque_blob: #ty ,
@ -1555,6 +1553,7 @@ impl CodeGenerator for CompInfo {
if layout.align == 1 {
packed = true;
} else {
explicit_align = Some(layout.align);
let ty = helpers::blob(Layout::new(0, layout.align));
fields.push(quote! {
pub __bindgen_align: #ty ,
@ -1597,21 +1596,19 @@ impl CodeGenerator for CompInfo {
let mut generic_param_names = vec![];
if let Some(ref params) = used_template_params {
for (idx, ty) in params.iter().enumerate() {
let param = ctx.resolve_type(*ty);
let name = param.name().unwrap();
let ident = ctx.rust_ident(name);
generic_param_names.push(ident.clone());
for (idx, ty) in item.used_template_params(ctx).iter().enumerate() {
let param = ctx.resolve_type(*ty);
let name = param.name().unwrap();
let ident = ctx.rust_ident(name);
generic_param_names.push(ident.clone());
let prefix = ctx.trait_prefix();
let field_name = ctx.rust_ident(format!("_phantom_{}", idx));
fields.push(quote! {
pub #field_name : ::#prefix::marker::PhantomData<
::#prefix::cell::UnsafeCell<#ident>
> ,
});
}
let prefix = ctx.trait_prefix();
let field_name = ctx.rust_ident(format!("_phantom_{}", idx));
fields.push(quote! {
pub #field_name : ::#prefix::marker::PhantomData<
::#prefix::cell::UnsafeCell<#ident>
> ,
});
}
let generics = if !generic_param_names.is_empty() {
@ -1637,6 +1634,18 @@ impl CodeGenerator for CompInfo {
attributes.push(attributes::repr("C"));
}
if ctx.options().rust_features().repr_align {
if let Some(explicit) = explicit_align {
// Ensure that the struct has the correct alignment even in
// presence of alignas.
let explicit = helpers::ast_ty::int_expr(explicit as i64);
attributes.push(quote! {
#[repr(align(#explicit))]
});
}
}
let mut derives = vec![];
if item.can_derive_debug(ctx) {
derives.push("Debug");
@ -1652,11 +1661,13 @@ impl CodeGenerator for CompInfo {
ctx.options().derive_default && !self.is_forward_declaration();
}
let all_template_params = item.all_template_params(ctx);
if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() {
derives.push("Copy");
if ctx.options().rust_features().builtin_clone_impls() ||
used_template_params.is_some()
if ctx.options().rust_features().builtin_clone_impls ||
!all_template_params.is_empty()
{
// FIXME: This requires extra logic if you have a big array in a
// templated struct. The reason for this is that the magic:
@ -1711,7 +1722,7 @@ impl CodeGenerator for CompInfo {
}
};
tokens.append(quote! {
tokens.append_all(quote! {
#generics {
#( #fields )*
}
@ -1734,11 +1745,11 @@ impl CodeGenerator for CompInfo {
if self.found_unknown_attr() {
warn!(
"Type {} has an unkown attribute that may affect layout",
canonical_ident
canonical_ident.as_str()
);
}
if used_template_params.is_none() {
if all_template_params.is_empty() {
if !is_opaque {
for var in self.inner_vars() {
ctx.resolve_item(*var).codegen(ctx, result, &());
@ -1748,7 +1759,7 @@ impl CodeGenerator for CompInfo {
if ctx.options().layout_tests && !self.is_forward_declaration() {
if let Some(layout) = layout {
let fn_name =
format!("bindgen_test_layout_{}", canonical_ident);
format!("bindgen_test_layout_{}", canonical_ident.as_str());
let fn_name = ctx.rust_ident_raw(fn_name);
let prefix = ctx.trait_prefix();
let size_of_expr = quote! {
@ -1761,8 +1772,9 @@ impl CodeGenerator for CompInfo {
let align = layout.align;
let check_struct_align =
if align > mem::size_of::<*mut ()>() {
// FIXME when [RFC 1358](https://github.com/rust-lang/rust/issues/33626) ready
if align > ctx.target_pointer_size() &&
!ctx.options().rust_features().repr_align
{
None
} else {
Some(quote! {
@ -1996,7 +2008,7 @@ impl MethodCodegen for Method {
_ => panic!("How in the world?"),
};
if let (Abi::ThisCall, false) = (signature.abi(), ctx.options().rust_features().thiscall_abi()) {
if let (Abi::ThisCall, false) = (signature.abi(), ctx.options().rust_features().thiscall_abi) {
return;
}
@ -2092,11 +2104,15 @@ impl MethodCodegen for Method {
}
/// A helper type that represents different enum variations.
#[derive(Copy, Clone)]
enum EnumVariation {
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum EnumVariation {
/// The code for this enum will use a Rust enum
Rust,
/// The code for this enum will use a bitfield
Bitfield,
/// The code for this enum will use consts
Consts,
/// The code for this enum will use a module containing consts
ModuleConsts
}
@ -2110,7 +2126,7 @@ impl EnumVariation {
fn is_bitfield(&self) -> bool {
match *self {
EnumVariation::Bitfield => true,
EnumVariation::Bitfield {..} => true,
_ => false
}
}
@ -2125,12 +2141,37 @@ impl EnumVariation {
}
}
impl Default for EnumVariation {
fn default() -> EnumVariation {
EnumVariation::Consts
}
}
impl std::str::FromStr for EnumVariation {
type Err = std::io::Error;
/// Create a `EnumVariation` from a string.
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"rust" => Ok(EnumVariation::Rust),
"bitfield" => Ok(EnumVariation::Bitfield),
"consts" => Ok(EnumVariation::Consts),
"moduleconsts" => Ok(EnumVariation::ModuleConsts),
_ => Err(std::io::Error::new(std::io::ErrorKind::InvalidInput,
concat!("Got an invalid EnumVariation. Accepted values ",
"are 'rust', 'bitfield', 'consts', and ",
"'moduleconsts'."))),
}
}
}
/// A helper type to construct different enum variations.
enum EnumBuilder<'a> {
Rust {
codegen_depth: usize,
attrs: Vec<quote::Tokens>,
ident: quote::Ident,
ident: Term,
tokens: quote::Tokens,
emitted_any_variants: bool,
},
@ -2170,7 +2211,7 @@ impl<'a> EnumBuilder<'a> {
enum_variation: EnumVariation,
enum_codegen_depth: usize,
) -> Self {
let ident = quote::Ident::new(name);
let ident = Term::new(name, Span::call_site());
match enum_variation {
EnumVariation::Bitfield => {
@ -2185,7 +2226,7 @@ impl<'a> EnumBuilder<'a> {
}
EnumVariation::Rust => {
let tokens = quote!{};
let tokens = quote!();
EnumBuilder::Rust {
codegen_depth: enum_codegen_depth + 1,
attrs,
@ -2208,7 +2249,7 @@ impl<'a> EnumBuilder<'a> {
}
EnumVariation::ModuleConsts => {
let ident = quote::Ident::new(CONSTIFIED_ENUM_MODULE_REPR_NAME);
let ident = Term::new(CONSTIFIED_ENUM_MODULE_REPR_NAME, Span::call_site());
let type_definition = quote! {
#( #attrs )*
pub type #ident = #repr;
@ -2231,6 +2272,7 @@ impl<'a> EnumBuilder<'a> {
mangling_prefix: Option<&str>,
rust_ty: quote::Tokens,
result: &mut CodegenResult<'b>,
is_ty_named: bool,
) -> Self {
let variant_name = ctx.rust_mangle(variant.name());
let expr = match variant.val() {
@ -2262,19 +2304,28 @@ impl<'a> EnumBuilder<'a> {
}
}
EnumBuilder::Bitfield { .. } => {
let constant_name = match mangling_prefix {
Some(prefix) => {
Cow::Owned(format!("{}_{}", prefix, variant_name))
}
None => variant_name,
};
let ident = ctx.rust_ident(constant_name);
result.push(quote! {
#doc
pub const #ident : #rust_ty = #rust_ty ( #expr );
});
EnumBuilder::Bitfield { canonical_name, .. } => {
if ctx.options().rust_features().associated_const && is_ty_named {
let enum_ident = ctx.rust_ident(canonical_name);
let variant_ident = ctx.rust_ident(variant_name);
result.push(quote! {
impl #enum_ident {
#doc
pub const #variant_ident : #rust_ty = #rust_ty ( #expr );
}
});
} else {
let ident = ctx.rust_ident(match mangling_prefix {
Some(prefix) => {
Cow::Owned(format!("{}_{}", prefix, variant_name))
}
None => variant_name,
});
result.push(quote! {
#doc
pub const #ident : #rust_ty = #rust_ty ( #expr );
});
}
self
}
@ -2461,15 +2512,18 @@ impl CodeGenerator for Enum {
}
};
let variation = if self.is_bitfield(ctx, item) {
// ModuleConsts has higher precedence before Rust in order to avoid problems with
// overlapping match patterns
let variation = if self.is_constified_enum_module(ctx, item) {
EnumVariation::ModuleConsts
} else if self.is_bitfield(ctx, item) {
EnumVariation::Bitfield
} else if self.is_rustified_enum(ctx, item) {
EnumVariation::Rust
} else if self.is_constified_enum_module(ctx, item) {
EnumVariation::ModuleConsts
} else {
// We generate consts by default
} else if self.is_constified_enum(ctx, item) {
EnumVariation::Consts
} else {
ctx.options().default_enum_style
};
let mut attrs = vec![];
@ -2495,18 +2549,18 @@ impl CodeGenerator for Enum {
ctx: &BindgenContext,
enum_: &Type,
// Only to avoid recomputing every time.
enum_canonical_name: &quote::Ident,
enum_canonical_name: &Term,
// May be the same as "variant" if it's because the
// enum is unnamed and we still haven't seen the
// value.
variant_name: &str,
referenced_name: &quote::Ident,
referenced_name: &Term,
enum_rust_ty: quote::Tokens,
result: &mut CodegenResult<'a>,
) {
let constant_name = if enum_.name().is_some() {
if ctx.options().prepend_enum_name {
format!("{}_{}", enum_canonical_name, variant_name)
format!("{}_{}", enum_canonical_name.as_str(), variant_name)
} else {
variant_name.into()
}
@ -2535,7 +2589,7 @@ impl CodeGenerator for Enum {
);
// A map where we keep a value -> variant relation.
let mut seen_values = HashMap::<_, quote::Ident>::new();
let mut seen_values = HashMap::<_, Term>::new();
let enum_rust_ty = item.to_rust_ty_or_opaque(ctx, &());
let is_toplevel = item.is_toplevel(ctx);
@ -2607,6 +2661,7 @@ impl CodeGenerator for Enum {
constant_mangling_prefix,
enum_rust_ty.clone(),
result,
enum_ty.name().is_some(),
);
}
}
@ -2617,6 +2672,7 @@ impl CodeGenerator for Enum {
constant_mangling_prefix,
enum_rust_ty.clone(),
result,
enum_ty.name().is_some(),
);
let variant_name = ctx.rust_ident(variant.name());
@ -2633,12 +2689,13 @@ impl CodeGenerator for Enum {
let parent_name =
parent_canonical_name.as_ref().unwrap();
quote::Ident::new(
format!(
Term::new(
&format!(
"{}_{}",
parent_name,
variant_name
)
variant_name.as_str()
),
Span::call_site()
)
};
@ -2646,14 +2703,14 @@ impl CodeGenerator for Enum {
ctx,
enum_ty,
&ident,
mangled_name.as_ref(),
mangled_name.as_str(),
&variant_name,
enum_rust_ty.clone(),
result,
);
}
entry.insert(quote::Ident::new(variant_name));
entry.insert(variant_name);
}
}
}
@ -2702,9 +2759,8 @@ trait TryToOpaque {
/// leverage the blanket impl for this trait.
trait ToOpaque: TryToOpaque {
fn get_layout(&self, ctx: &BindgenContext, extra: &Self::Extra) -> Layout {
self.try_get_layout(ctx, extra).unwrap_or_else(
|_| Layout::for_size(1),
)
self.try_get_layout(ctx, extra)
.unwrap_or_else(|_| Layout::for_size(ctx, 1))
}
fn to_opaque(
@ -2951,7 +3007,7 @@ impl TryToRustTy for Type {
TypeKind::Complex(fk) => {
let float_path = float_kind_rust_type(ctx, fk);
ctx.generated_bindegen_complex();
ctx.generated_bindgen_complex();
Ok(if ctx.options().enable_cxx_namespaces {
quote! {
root::__BindgenComplex<#float_path>
@ -2981,10 +3037,9 @@ impl TryToRustTy for Type {
})
}
TypeKind::Enum(..) => {
let mut tokens = quote! {};
let path = item.namespace_aware_canonical_path(ctx);
tokens.append_separated(path.into_iter().map(quote::Ident::new), "::");
Ok(tokens)
let path = Term::new(&path.join("::"), Span::call_site());
Ok(quote!(#path))
}
TypeKind::TemplateInstantiation(ref inst) => {
inst.try_to_rust_ty(ctx, item)
@ -2993,7 +3048,6 @@ impl TryToRustTy for Type {
TypeKind::TemplateAlias(..) |
TypeKind::Alias(..) => {
let template_params = item.used_template_params(ctx)
.unwrap_or(vec![])
.into_iter()
.filter(|param| param.is_template_param(ctx, &()))
.collect::<Vec<_>>();
@ -3012,9 +3066,9 @@ impl TryToRustTy for Type {
}
}
TypeKind::Comp(ref info) => {
let template_params = item.used_template_params(ctx);
let template_params = item.all_template_params(ctx);
if info.has_non_type_template_params() ||
(item.is_opaque(ctx, &()) && template_params.is_some())
(item.is_opaque(ctx, &()) && !template_params.is_empty())
{
return self.try_to_opaque(ctx, item);
}
@ -3031,7 +3085,7 @@ impl TryToRustTy for Type {
}
TypeKind::Pointer(inner) |
TypeKind::Reference(inner) => {
let is_const = self.is_const() || ctx.resolve_type(inner).is_const();
let is_const = ctx.resolve_type(inner).is_const();
let inner = inner.into_resolver().through_type_refs().resolve(ctx);
let inner_ty = inner.expect_type();
@ -3106,20 +3160,18 @@ impl TryToRustTy for TemplateInstantiation {
let mut ty = quote! {};
let def_path = def.namespace_aware_canonical_path(ctx);
ty.append_separated(def_path.into_iter().map(|p| ctx.rust_ident(p)), "::");
ty.append_separated(def_path.into_iter().map(|p| ctx.rust_ident(p)), Term::new("::", Span::call_site()));
let def_params = match def.self_template_params(ctx) {
Some(params) => params,
None => {
// This can happen if we generated an opaque type for a partial
// template specialization, and we've hit an instantiation of
// that partial specialization.
extra_assert!(
def.is_opaque(ctx, &())
);
return Err(error::Error::InstantiationOfOpaqueType);
}
};
let def_params = def.self_template_params(ctx);
if def_params.is_empty() {
// This can happen if we generated an opaque type for a partial
// template specialization, and we've hit an instantiation of
// that partial specialization.
extra_assert!(
def.is_opaque(ctx, &())
);
return Err(error::Error::InstantiationOfOpaqueType);
}
// TODO: If the definition type is a template class/struct
// definition's member template definition, it could rely on
@ -3167,7 +3219,7 @@ impl TryToRustTy for FunctionSig {
let abi = self.abi();
match abi {
Abi::ThisCall if !ctx.options().rust_features().thiscall_abi() => {
Abi::ThisCall if !ctx.options().rust_features().thiscall_abi => {
warn!("Skipping function with thiscall ABI that isn't supported by the configured Rust target");
Ok(quote::Tokens::new())
}
@ -3212,11 +3264,8 @@ impl CodeGenerator for Function {
// generate bindings to template functions, because the set of
// instantiations is open ended and we have no way of knowing which
// monomorphizations actually exist.
let type_params = item.all_template_params(ctx);
if let Some(params) = type_params {
if !params.is_empty() {
return;
}
if !item.all_template_params(ctx).is_empty() {
return;
}
let name = self.name();
@ -3264,7 +3313,7 @@ impl CodeGenerator for Function {
}
let abi = match signature.abi() {
Abi::ThisCall if !ctx.options().rust_features().thiscall_abi() => {
Abi::ThisCall if !ctx.options().rust_features().thiscall_abi => {
warn!("Skipping function with thiscall ABI that isn't supported by the configured Rust target");
return;
}
@ -3319,7 +3368,7 @@ fn objc_method_codegen(
let class_name = class_name
.expect("Generating a class method without class name?")
.to_owned();
let expect_msg = format!("Couldn't find {}", class_name);
let expect_msg = proc_macro2::Literal::string(&format!("Couldn't find {}", class_name));
quote! {
msg_send!(objc::runtime::Class::get(#class_name).expect(#expect_msg), #methods_and_args)
}
@ -3445,11 +3494,12 @@ mod utils {
use ir::item::{Item, ItemCanonicalPath};
use ir::ty::TypeKind;
use quote;
use proc_macro2::{Term, Span};
use std::mem;
pub fn prepend_bitfield_unit_type(result: &mut Vec<quote::Tokens>) {
let mut bitfield_unit_type = quote! {};
bitfield_unit_type.append(include_str!("./bitfield_unit.rs"));
let bitfield_unit_type = Term::new(include_str!("./bitfield_unit.rs"), Span::call_site());
let bitfield_unit_type = quote!(#bitfield_unit_type);
let items = vec![bitfield_unit_type];
let old_items = mem::replace(result, items);
@ -3675,10 +3725,12 @@ mod utils {
item: &Item,
ctx: &BindgenContext,
) -> error::Result<quote::Tokens> {
let path = item.namespace_aware_canonical_path(ctx);
use proc_macro2::{Term, Span};
let mut tokens = quote! {};
tokens.append_separated(path.into_iter().map(quote::Ident::new), "::");
let path = item.namespace_aware_canonical_path(ctx);
let path = Term::new(&path.join("::"), Span::call_site());
let tokens = quote! {#path};
//tokens.append_separated(path, "::");
Ok(tokens)
}

Просмотреть файл

@ -7,8 +7,8 @@ use ir::context::BindgenContext;
use ir::layout::Layout;
use ir::ty::{Type, TypeKind};
use quote;
use proc_macro2::{Term, Span};
use std::cmp;
use std::mem;
/// Trace the layout of struct.
#[derive(Debug)]
@ -101,7 +101,7 @@ impl<'a> StructLayoutTracker<'a> {
pub fn saw_vtable(&mut self) {
debug!("saw vtable for {}", self.name);
let ptr_size = mem::size_of::<*mut ()>();
let ptr_size = self.ctx.target_pointer_size();
self.latest_offset += ptr_size;
self.latest_field_layout = Some(Layout::new(ptr_size, ptr_size));
self.max_field_align = ptr_size;
@ -165,15 +165,13 @@ impl<'a> StructLayoutTracker<'a> {
// can support.
//
// This means that the structs in the array are super-unsafe to
// access, since they won't be properly aligned, but *shrug*.
if let Some(layout) = self.ctx.resolve_type(inner).layout(
self.ctx,
)
{
if layout.align > mem::size_of::<*mut ()>() {
field_layout.size = align_to(layout.size, layout.align) *
len;
field_layout.align = mem::size_of::<*mut ()>();
// access, since they won't be properly aligned, but there's not too
// much we can do about it.
if let Some(layout) = self.ctx.resolve_type(inner).layout(self.ctx) {
if layout.align > self.ctx.target_pointer_size() {
field_layout.size =
align_to(layout.size, layout.align) * len;
field_layout.align = self.ctx.target_pointer_size();
}
}
}
@ -193,7 +191,7 @@ impl<'a> StructLayoutTracker<'a> {
// Otherwise the padding is useless.
let need_padding = padding_bytes >= field_layout.align ||
field_layout.align > mem::size_of::<*mut ()>();
field_layout.align > self.ctx.target_pointer_size();
self.latest_offset += padding_bytes;
@ -215,7 +213,7 @@ impl<'a> StructLayoutTracker<'a> {
if need_padding && padding_bytes != 0 {
Some(Layout::new(
padding_bytes,
cmp::min(field_layout.align, mem::size_of::<*mut ()>()),
cmp::min(field_layout.align, self.ctx.target_pointer_size())
))
} else {
None
@ -267,15 +265,15 @@ impl<'a> StructLayoutTracker<'a> {
(self.last_field_was_bitfield &&
padding_bytes >=
self.latest_field_layout.unwrap().align) ||
layout.align > mem::size_of::<*mut ()>())
layout.align > self.ctx.target_pointer_size())
{
let layout = if self.is_packed {
Layout::new(padding_bytes, 1)
} else if self.last_field_was_bitfield ||
layout.align > mem::size_of::<*mut ()>()
layout.align > self.ctx.target_pointer_size()
{
// We've already given up on alignment here.
Layout::for_size(padding_bytes)
Layout::for_size(self.ctx, padding_bytes)
} else {
Layout::new(padding_bytes, layout.align)
};
@ -289,8 +287,18 @@ impl<'a> StructLayoutTracker<'a> {
}
pub fn requires_explicit_align(&self, layout: Layout) -> bool {
self.max_field_align < layout.align &&
layout.align <= mem::size_of::<*mut ()>()
if self.max_field_align >= layout.align {
return false;
}
// At this point we require explicit alignment, but we may not be able
// to generate the right bits, let's double check.
if self.ctx.options().rust_features().repr_align {
return true;
}
// We can only generate up-to a word of alignment unless we support
// repr(align).
layout.align <= self.ctx.target_pointer_size()
}
fn padding_bytes(&self, layout: Layout) -> usize {
@ -303,7 +311,7 @@ impl<'a> StructLayoutTracker<'a> {
self.padding_count += 1;
let padding_field_name = quote::Ident::new(format!("__bindgen_padding_{}", padding_count));
let padding_field_name = Term::new(&format!("__bindgen_padding_{}", padding_count), Span::call_site());
self.max_field_align = cmp::max(self.max_field_align, layout.align);

31
third_party/rust/bindgen/src/features.rs поставляемый
Просмотреть файл

@ -90,8 +90,12 @@ macro_rules! rust_target_base {
=> Stable_1_0 => 1.0;
/// Rust stable 1.19
=> Stable_1_19 => 1.19;
/// Rust stable 1.20
=> Stable_1_20 => 1.20;
/// Rust stable 1.21
=> Stable_1_21 => 1.21;
/// Rust stable 1.25
=> Stable_1_25 => 1.25;
/// Nightly rust
=> Nightly => nightly;
);
@ -111,7 +115,10 @@ macro_rules! rust_feature_def {
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub struct RustFeatures {
$(
$feature: bool,
$(
#[$attr]
)*
pub $feature: bool,
)*
}
@ -124,15 +131,6 @@ macro_rules! rust_feature_def {
)*
}
}
$(
$(
#[$attr]
)*
pub fn $feature(&self) -> bool {
self.$feature
}
)*
}
}
}
@ -144,6 +142,10 @@ rust_feature_def!(
=> thiscall_abi;
/// builtin impls for `Clone` ([PR](https://github.com/rust-lang/rust/pull/43690))
=> builtin_clone_impls;
/// repr(align) https://github.com/rust-lang/rust/pull/47006
=> repr_align;
/// associated constants https://github.com/rust-lang/rust/issues/29646
=> associated_const;
);
impl From<RustTarget> for RustFeatures {
@ -154,10 +156,18 @@ impl From<RustTarget> for RustFeatures {
features.untagged_union = true;
}
if rust_target >= RustTarget::Stable_1_20 {
features.associated_const = true;
}
if rust_target >= RustTarget::Stable_1_21 {
features.builtin_clone_impls = true;
}
if rust_target >= RustTarget::Stable_1_25 {
features.repr_align = true;
}
if rust_target >= RustTarget::Nightly {
features.thiscall_abi = true;
}
@ -189,6 +199,7 @@ mod test {
test_target("1.0", RustTarget::Stable_1_0);
test_target("1.19", RustTarget::Stable_1_19);
test_target("1.21", RustTarget::Stable_1_21);
test_target("1.25", RustTarget::Stable_1_25);
test_target("nightly", RustTarget::Nightly);
}
}

Просмотреть файл

@ -234,7 +234,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
}
if info.kind() == CompKind::Union {
if !self.ctx.options().rust_features().untagged_union() {
if !self.ctx.options().rust_features().untagged_union {
// NOTE: If there's no template parameters we can derive
// copy unconditionally, since arrays are magical for
// rustc, and __BindgenUnionField always implements
@ -246,8 +246,8 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
}
// https://github.com/rust-lang/rust/issues/36640
if info.self_template_params(self.ctx).is_some() ||
item.used_template_params(self.ctx).is_some()
if !info.self_template_params(self.ctx).is_empty() ||
!item.all_template_params(self.ctx).is_empty()
{
trace!(
" comp cannot derive copy because issue 36640"

Просмотреть файл

@ -150,7 +150,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> {
});
return if layout_can_derive &&
!(ty.is_union() &&
self.ctx.options().rust_features().untagged_union()) {
self.ctx.options().rust_features().untagged_union) {
trace!(" we can trivially derive Debug for the layout");
ConstrainResult::Same
} else {
@ -235,7 +235,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDebug<'ctx> {
);
if info.kind() == CompKind::Union {
if self.ctx.options().rust_features().untagged_union() {
if self.ctx.options().rust_features().untagged_union {
trace!(" cannot derive Debug for Rust unions");
return self.insert(id);
}

Просмотреть файл

@ -177,7 +177,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> {
});
return if layout_can_derive &&
!(ty.is_union() &&
self.ctx.options().rust_features().untagged_union()) {
self.ctx.options().rust_features().untagged_union) {
trace!(" we can trivially derive Default for the layout");
ConstrainResult::Same
} else {
@ -271,7 +271,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> {
}
if info.kind() == CompKind::Union {
if self.ctx.options().rust_features().untagged_union() {
if self.ctx.options().rust_features().untagged_union {
trace!(" cannot derive Default for Rust unions");
return self.insert(id);
}

Просмотреть файл

@ -137,7 +137,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
});
return if layout_can_derive &&
!(ty.is_union() &&
self.ctx.options().rust_features().untagged_union()) {
self.ctx.options().rust_features().untagged_union) {
trace!(" we can trivially derive Hash for the layout");
ConstrainResult::Same
} else {
@ -257,7 +257,7 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
}
if info.kind() == CompKind::Union {
if self.ctx.options().rust_features().untagged_union() {
if self.ctx.options().rust_features().untagged_union {
trace!(" cannot derive Hash for Rust unions");
return self.insert(id);
}

Просмотреть файл

@ -119,7 +119,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
trace!("ty: {:?}", ty);
if item.is_opaque(self.ctx, &()) {
if ty.is_union()
&& self.ctx.options().rust_features().untagged_union()
&& self.ctx.options().rust_features().untagged_union
{
trace!(
" cannot derive `PartialEq`/`PartialOrd` for Rust unions"
@ -242,7 +242,7 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> {
}
if info.kind() == CompKind::Union {
if self.ctx.options().rust_features().untagged_union() {
if self.ctx.options().rust_features().untagged_union {
trace!(
" cannot derive `PartialEq`/`PartialOrd` for Rust unions"
);

Просмотреть файл

@ -275,7 +275,7 @@ impl<'ctx> UsedTemplateParameters<'ctx> {
let decl = self.ctx.resolve_type(instantiation.template_definition());
let args = instantiation.template_arguments();
let params = decl.self_template_params(self.ctx).unwrap_or(vec![]);
let params = decl.self_template_params(self.ctx);
debug_assert!(this_id != instantiation.template_definition());
let used_by_def = self.used
@ -419,7 +419,7 @@ impl<'ctx> MonotoneFramework for UsedTemplateParameters<'ctx> {
// template parameters, there is a single exception:
// opaque templates. Hence the unwrap_or.
let params =
decl.self_template_params(ctx).unwrap_or(vec![]);
decl.self_template_params(ctx);
for (arg, param) in args.iter().zip(params.iter()) {
let arg = arg.into_resolver()

2
third_party/rust/bindgen/src/ir/comment.rs поставляемый
Просмотреть файл

@ -39,7 +39,7 @@ fn make_indent(indent: usize) -> String {
iter::repeat(' ').take(indent * RUST_INDENTATION).collect()
}
/// Preprocesses mulitple single line comments.
/// Preprocesses multiple single line comments.
///
/// Handles lines starting with both `//` and `///`.
fn preprocess_single_lines(comment: &str, indent: usize) -> String {

18
third_party/rust/bindgen/src/ir/comp.rs поставляемый
Просмотреть файл

@ -1290,9 +1290,10 @@ impl CompInfo {
return CXChildVisit_Continue;
}
// Even if this is a definition, we may not be the semantic
// parent, see #1281.
let inner = Item::parse(cur, Some(potential_id), ctx)
.expect("Inner ClassDecl");
assert_eq!(ctx.resolve_item(inner).parent_id(), potential_id);
let inner = inner.expect_type_id(ctx);
@ -1355,7 +1356,7 @@ impl CompInfo {
// to be inserted in the map two times.
//
// I couldn't make a reduced test case, but anyway...
// Methods of template functions not only use to be inlined,
// Methods of template functions not only used to be inlined,
// but also instantiated, and we wouldn't be able to call
// them, so just bail out.
if !ci.template_params.is_empty() {
@ -1543,7 +1544,7 @@ impl CompInfo {
/// 1. Current RustTarget allows for `untagged_union`
/// 2. Each field can derive `Copy`
pub fn can_be_rust_union(&self, ctx: &BindgenContext) -> bool {
if !ctx.options().rust_features().untagged_union() {
if !ctx.options().rust_features().untagged_union {
return false;
}
@ -1668,12 +1669,8 @@ impl TemplateParameters for CompInfo {
fn self_template_params(
&self,
_ctx: &BindgenContext,
) -> Option<Vec<TypeId>> {
if self.template_params.is_empty() {
None
} else {
Some(self.template_params.clone())
}
) -> Vec<TypeId> {
self.template_params.clone()
}
}
@ -1684,8 +1681,7 @@ impl Trace for CompInfo {
where
T: Tracer,
{
let params = item.all_template_params(context).unwrap_or(vec![]);
for p in params {
for p in item.all_template_params(context) {
tracer.visit_kind(p.into(), EdgeKind::TemplateParameterDefinition);
}

184
third_party/rust/bindgen/src/ir/context.rs поставляемый
Просмотреть файл

@ -24,7 +24,7 @@ use cexpr;
use clang::{self, Cursor};
use clang_sys;
use parse::ClangItemParser;
use quote;
use proc_macro2::{Term, Span};
use std::borrow::Cow;
use std::cell::Cell;
use std::collections::{HashMap, HashSet, hash_map};
@ -366,11 +366,14 @@ pub struct BindgenContext {
/// The translation unit for parsing.
translation_unit: clang::TranslationUnit,
/// Target information that can be useful for some stuff.
target_info: Option<clang::TargetInfo>,
/// The options given by the user via cli or other medium.
options: BindgenOptions,
/// Whether a bindgen complex was generated
generated_bindegen_complex: Cell<bool>,
generated_bindgen_complex: Cell<bool>,
/// The set of `ItemId`s that are whitelisted. This the very first thing
/// computed after parsing our IR, and before running any of our analyses.
@ -503,6 +506,9 @@ impl<'ctx> WhitelistedItemsTraversal<'ctx> {
}
}
const HOST_TARGET: &'static str =
include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
/// Returns the effective target, and whether it was explicitly specified on the
/// clang flags.
fn find_effective_target(clang_args: &[String]) -> (String, bool) {
@ -521,8 +527,6 @@ fn find_effective_target(clang_args: &[String]) -> (String, bool) {
return (t, false)
}
const HOST_TARGET: &'static str =
include_str!(concat!(env!("OUT_DIR"), "/host-target.txt"));
(HOST_TARGET.to_owned(), false)
}
@ -561,6 +565,17 @@ impl BindgenContext {
).expect("TranslationUnit::parse failed")
};
let target_info = clang::TargetInfo::new(&translation_unit);
#[cfg(debug_assertions)]
{
if let Some(ref ti) = target_info {
if effective_target == HOST_TARGET {
assert_eq!(ti.pointer_width / 8, mem::size_of::<*mut ()>());
}
}
}
let root_module = Self::build_root_module(ItemId(0));
let root_module_id = root_module.id().as_module_id_unchecked();
@ -578,10 +593,11 @@ impl BindgenContext {
replacements: Default::default(),
collected_typerefs: false,
in_codegen: false,
index: index,
translation_unit: translation_unit,
options: options,
generated_bindegen_complex: Cell::new(false),
index,
translation_unit,
target_info,
options,
generated_bindgen_complex: Cell::new(false),
whitelisted: None,
codegen_items: None,
used_template_parameters: None,
@ -611,6 +627,15 @@ impl BindgenContext {
Timer::new(name).with_output(self.options.time_phases)
}
/// Returns the pointer width to use for the target for the current
/// translation.
pub fn target_pointer_size(&self) -> usize {
if let Some(ref ti) = self.target_info {
return ti.pointer_width / 8;
}
mem::size_of::<*mut ()>()
}
/// Get the stack of partially parsed types that we are in the middle of
/// parsing.
pub fn currently_parsed_types(&self) -> &[PartialType] {
@ -880,7 +905,7 @@ impl BindgenContext {
}
/// Returns a mangled name as a rust identifier.
pub fn rust_ident<S>(&self, name: S) -> quote::Ident
pub fn rust_ident<S>(&self, name: S) -> Term
where
S: AsRef<str>
{
@ -888,11 +913,11 @@ impl BindgenContext {
}
/// Returns a mangled name as a rust identifier.
pub fn rust_ident_raw<T>(&self, name: T) -> quote::Ident
pub fn rust_ident_raw<T>(&self, name: T) -> Term
where
T: Into<quote::Ident>
T: AsRef<str>
{
name.into()
Term::new(name.as_ref(), Span::call_site())
}
/// Iterate over all items that have been defined.
@ -1341,10 +1366,7 @@ impl BindgenContext {
let mut used_params = HashMap::new();
for &id in self.whitelisted_items() {
used_params.entry(id).or_insert(
id.self_template_params(self).map_or(
Default::default(),
|params| params.into_iter().map(|p| p.into()).collect(),
),
id.self_template_params(self).into_iter().map(|p| p.into()).collect()
);
}
self.used_template_parameters = Some(used_params);
@ -1516,7 +1538,7 @@ impl BindgenContext {
///
/// Note that `declaration_id` is not guaranteed to be in the context's item
/// set! It is possible that it is a partial type that we are still in the
/// middle of parsign.
/// middle of parsing.
fn get_declaration_info_for_template_instantiation(
&self,
instantiation: &Cursor,
@ -1527,15 +1549,16 @@ impl BindgenContext {
.and_then(|canon_decl| {
self.get_resolved_type(&canon_decl).and_then(
|template_decl_id| {
template_decl_id.num_self_template_params(self).map(
|num_params| {
(
*canon_decl.cursor(),
template_decl_id.into(),
num_params,
)
},
)
let num_params = template_decl_id.num_self_template_params(self);
if num_params == 0 {
None
} else {
Some((
*canon_decl.cursor(),
template_decl_id.into(),
num_params,
))
}
},
)
})
@ -1556,15 +1579,16 @@ impl BindgenContext {
.cloned()
})
.and_then(|template_decl| {
template_decl.num_self_template_params(self).map(
|num_template_params| {
(
*template_decl.decl(),
template_decl.id(),
num_template_params,
)
},
)
let num_template_params = template_decl.num_self_template_params(self);
if num_template_params == 0 {
None
} else {
Some((
*template_decl.decl(),
template_decl.id(),
num_template_params,
))
}
})
})
}
@ -1611,17 +1635,14 @@ impl BindgenContext {
) -> Option<TypeId> {
use clang_sys;
let num_expected_args = match self.resolve_type(template)
.num_self_template_params(self) {
Some(n) => n,
None => {
warn!(
"Tried to instantiate a template for which we could not \
determine any template parameters"
);
return None;
}
};
let num_expected_args = self.resolve_type(template).num_self_template_params(self);
if num_expected_args == 0 {
warn!(
"Tried to instantiate a template for which we could not \
determine any template parameters"
);
return None;
}
let mut args = vec![];
let mut found_const_arg = false;
@ -1893,7 +1914,7 @@ impl BindgenContext {
/// Make a new item that is a resolved type reference to the `wrapped_id`.
///
/// This is unfortunately a lot of bloat, but is needed to properly track
/// constness et. al.
/// constness et al.
///
/// We should probably make the constness tracking separate, so it doesn't
/// bloat that much, but hey, we already bloat the heck out of builtin
@ -1904,9 +1925,44 @@ impl BindgenContext {
wrapped_id: TypeId,
parent_id: Option<ItemId>,
ty: &clang::Type,
) -> TypeId {
self.build_wrapper(
with_id,
wrapped_id,
parent_id,
ty,
ty.is_const(),
)
}
/// A wrapper over a type that adds a const qualifier explicitly.
///
/// Needed to handle const methods in C++, wrapping the type .
pub fn build_const_wrapper(
&mut self,
with_id: ItemId,
wrapped_id: TypeId,
parent_id: Option<ItemId>,
ty: &clang::Type,
) -> TypeId {
self.build_wrapper(
with_id,
wrapped_id,
parent_id,
ty,
/* is_const = */ true,
)
}
fn build_wrapper(
&mut self,
with_id: ItemId,
wrapped_id: TypeId,
parent_id: Option<ItemId>,
ty: &clang::Type,
is_const: bool,
) -> TypeId {
let spelling = ty.spelling();
let is_const = ty.is_const();
let layout = ty.fallible_layout().ok();
let type_kind = TypeKind::ResolvedTypeRef(wrapped_id);
let ty = Type::new(Some(spelling), layout, type_kind, is_const);
@ -2291,7 +2347,11 @@ impl BindgenContext {
if self.options().whitelist_recursively {
traversal::all_edges
} else {
traversal::no_edges
// Only follow InnerType edges from the whitelisted roots.
// Such inner types (e.g. anonymous structs/unions) are
// always emitted by codegen, and they need to be whitelisted
// to make sure they are processed by e.g. the derive analysis.
traversal::only_inner_type_edges
};
let whitelisted = WhitelistedItemsTraversal::new(
@ -2316,7 +2376,7 @@ impl BindgenContext {
/// Convenient method for getting the prefix to use for most traits in
/// codegen depending on the `use_core` option.
pub fn trait_prefix(&self) -> quote::Ident {
pub fn trait_prefix(&self) -> Term {
if self.options().use_core {
self.rust_ident_raw("core")
} else {
@ -2324,14 +2384,14 @@ impl BindgenContext {
}
}
/// Call if a binden complex is generated
pub fn generated_bindegen_complex(&self) {
self.generated_bindegen_complex.set(true)
/// Call if a bindgen complex is generated
pub fn generated_bindgen_complex(&self) {
self.generated_bindgen_complex.set(true)
}
/// Whether we need to generate the binden complex type
pub fn need_bindegen_complex_type(&self) -> bool {
self.generated_bindegen_complex.get()
/// Whether we need to generate the bindgen complex type
pub fn need_bindgen_complex_type(&self) -> bool {
self.generated_bindgen_complex.get()
}
/// Compute whether we can derive debug.
@ -2503,7 +2563,7 @@ impl BindgenContext {
self.options().no_copy_types.matches(&name)
}
/// Chech if `--no-hash` flag is enabled for this item.
/// Check if `--no-hash` flag is enabled for this item.
pub fn no_hash_by_name(&self, item: &Item) -> bool {
let name = item.canonical_path(self)[1..].join("::");
self.options().no_hash_types.matches(&name)
@ -2618,13 +2678,13 @@ impl TemplateParameters for PartialType {
fn self_template_params(
&self,
_ctx: &BindgenContext,
) -> Option<Vec<TypeId>> {
) -> Vec<TypeId> {
// Maybe at some point we will eagerly parse named types, but for now we
// don't and this information is unavailable.
None
vec![]
}
fn num_self_template_params(&self, _ctx: &BindgenContext) -> Option<usize> {
fn num_self_template_params(&self, _ctx: &BindgenContext) -> usize {
// Wouldn't it be nice if libclang would reliably give us this
// information‽
match self.decl().kind() {
@ -2643,9 +2703,9 @@ impl TemplateParameters for PartialType {
};
clang_sys::CXChildVisit_Continue
});
Some(num_params)
num_params
}
_ => None,
_ => 0,
}
}
}

2
third_party/rust/bindgen/src/ir/derive.rs поставляемый
Просмотреть файл

@ -43,7 +43,7 @@ pub trait CanDeriveCopy<'a> {
/// A trait that encapsulates the logic for whether or not we can trivially
/// derive `Copy` without looking at any other types or results of fix point
/// analsyses. This is a helper trait for fix point analysis.
/// analyses. This is a helper trait for fix point analysis.
pub trait CanTriviallyDeriveCopy {
/// Return `true` if `Copy` can be trivially derived for this thing, `false`
/// otherwise.

47
third_party/rust/bindgen/src/ir/enum_ty.rs поставляемый
Просмотреть файл

@ -7,6 +7,7 @@ use clang;
use ir::annotations::Annotations;
use ir::item::ItemCanonicalPath;
use parse::{ClangItemParser, ParseError};
use regex_set::RegexSet;
/// An enum representing custom handling that can be given to a variant.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
@ -137,44 +138,36 @@ impl Enum {
Ok(Enum::new(repr, variants))
}
/// Whether the enum should be a bitfield
pub fn is_bitfield(&self, ctx: &BindgenContext, item: &Item) -> bool {
fn is_matching_enum(&self, ctx: &BindgenContext, enums: &RegexSet, item: &Item) -> bool {
let path = item.canonical_path(ctx);
let enum_ty = item.expect_type();
ctx.options().bitfield_enums.matches(&path[1..].join("::")) ||
(enum_ty.name().is_none() &&
self.variants().iter().any(|v| {
ctx.options().bitfield_enums.matches(&v.name())
}))
let path_matches = enums.matches(&path[1..].join("::"));
let enum_is_anon = enum_ty.name().is_none();
let a_variant_matches = self.variants().iter().any(|v| {
enums.matches(&v.name())
});
path_matches || (enum_is_anon && a_variant_matches)
}
/// Whether the enum should be a bitfield
pub fn is_bitfield(&self, ctx: &BindgenContext, item: &Item) -> bool {
self.is_matching_enum(ctx, &ctx.options().bitfield_enums, item)
}
/// Whether the enum should be an constified enum module
pub fn is_constified_enum_module(
&self,
ctx: &BindgenContext,
item: &Item,
) -> bool {
let path = item.canonical_path(ctx);
let enum_ty = item.expect_type();
pub fn is_constified_enum_module(&self, ctx: &BindgenContext, item: &Item) -> bool {
self.is_matching_enum(ctx, &ctx.options().constified_enum_modules, item)
}
ctx.options().constified_enum_modules.matches(&path[1..].join("::")) ||
(enum_ty.name().is_none() &&
self.variants().iter().any(|v| {
ctx.options().constified_enum_modules.matches(&v.name())
}))
/// Whether the enum should be an set of constants
pub fn is_constified_enum(&self, ctx: &BindgenContext, item: &Item) -> bool {
self.is_matching_enum(ctx, &ctx.options().constified_enums, item)
}
/// Whether the enum should be a Rust enum
pub fn is_rustified_enum(&self, ctx: &BindgenContext, item: &Item) -> bool {
let path = item.canonical_path(ctx);
let enum_ty = item.expect_type();
ctx.options().rustified_enums.matches(&path[1..].join("::")) ||
(enum_ty.name().is_none() &&
self.variants().iter().any(|v| {
ctx.options().rustified_enums.matches(&v.name())
}))
self.is_matching_enum(ctx, &ctx.options().rustified_enums, item)
}
}

19
third_party/rust/bindgen/src/ir/function.rs поставляемый
Просмотреть файл

@ -193,7 +193,7 @@ impl Abi {
impl quote::ToTokens for Abi {
fn to_tokens(&self, tokens: &mut quote::Tokens) {
tokens.append(match *self {
tokens.append_all(match *self {
Abi::C => quote! { "C" },
Abi::Stdcall => quote! { "stdcall" },
Abi::Fastcall => quote! { "fastcall" },
@ -402,14 +402,27 @@ impl FunctionSig {
let is_virtual = is_method && cursor.method_is_virtual();
let is_static = is_method && cursor.method_is_static();
if !is_static && !is_virtual {
let class = Item::parse(cursor.semantic_parent(), None, ctx)
let parent = cursor.semantic_parent();
let class = Item::parse(parent, None, ctx)
.expect("Expected to parse the class");
// The `class` most likely is not finished parsing yet, so use
// the unchecked variant.
let class = class.as_type_id_unchecked();
let class = if is_const {
let const_class_id = ctx.next_item_id();
ctx.build_const_wrapper(
const_class_id,
class,
None,
&parent.cur_type(),
)
} else {
class
};
let ptr =
Item::builtin_type(TypeKind::Pointer(class), is_const, ctx);
Item::builtin_type(TypeKind::Pointer(class), false, ctx);
args.insert(0, (Some("this".into()), ptr));
} else if is_virtual {
let void = Item::builtin_type(TypeKind::Void, false, ctx);

14
third_party/rust/bindgen/src/ir/item.rs поставляемый
Просмотреть файл

@ -1112,8 +1112,8 @@ where
fn self_template_params(
&self,
ctx: &BindgenContext,
) -> Option<Vec<TypeId>> {
ctx.resolve_item_fallible(*self).and_then(|item| {
) -> Vec<TypeId> {
ctx.resolve_item_fallible(*self).map_or(vec![], |item| {
item.self_template_params(ctx)
})
}
@ -1123,7 +1123,7 @@ impl TemplateParameters for Item {
fn self_template_params(
&self,
ctx: &BindgenContext,
) -> Option<Vec<TypeId>> {
) -> Vec<TypeId> {
self.kind.self_template_params(ctx)
}
}
@ -1132,7 +1132,7 @@ impl TemplateParameters for ItemKind {
fn self_template_params(
&self,
ctx: &BindgenContext,
) -> Option<Vec<TypeId>> {
) -> Vec<TypeId> {
match *self {
ItemKind::Type(ref ty) => ty.self_template_params(ctx),
// If we start emitting bindings to explicitly instantiated
@ -1140,7 +1140,7 @@ impl TemplateParameters for ItemKind {
// template params.
ItemKind::Function(_) |
ItemKind::Module(_) |
ItemKind::Var(_) => None,
ItemKind::Var(_) => vec![],
}
}
}
@ -1449,8 +1449,8 @@ impl ClangItemParser for Item {
return Ok(Item::new_opaque_type(id, ty, ctx));
}
if let Some(id) = Item::type_param(Some(id), location, ctx) {
return Ok(id);
if let Some(param_id) = Item::type_param(None, location, ctx) {
return Ok(ctx.build_ty_wrapper(id, param_id, None, ty));
}
}

29
third_party/rust/bindgen/src/ir/layout.rs поставляемый
Просмотреть файл

@ -4,8 +4,9 @@ use super::derive::{CanTriviallyDeriveCopy, CanTriviallyDeriveDebug,
CanTriviallyDeriveDefault, CanTriviallyDeriveHash,
CanTriviallyDerivePartialEqOrPartialOrd, CanDerive};
use super::ty::{RUST_DERIVE_IN_ARRAY_LIMIT, Type, TypeKind};
use ir::context::BindgenContext;
use clang;
use std::{cmp, mem};
use std::cmp;
/// A type that represents the struct layout of a type.
#[derive(Debug, Clone, Copy, PartialEq)]
@ -20,10 +21,15 @@ pub struct Layout {
#[test]
fn test_layout_for_size() {
use std::mem;
let ptr_size = mem::size_of::<*mut ()>();
assert_eq!(Layout::for_size(ptr_size), Layout::new(ptr_size, ptr_size));
assert_eq!(
Layout::for_size(3 * ptr_size),
Layout::for_size_internal(ptr_size, ptr_size),
Layout::new(ptr_size, ptr_size)
);
assert_eq!(
Layout::for_size_internal(ptr_size, 3 * ptr_size),
Layout::new(3 * ptr_size, ptr_size)
);
}
@ -39,13 +45,9 @@ impl Layout {
}
}
/// Creates a non-packed layout for a given size, trying to use the maximum
/// alignment possible.
pub fn for_size(size: usize) -> Self {
fn for_size_internal(ptr_size: usize, size: usize) -> Self {
let mut next_align = 2;
while size % next_align == 0 &&
next_align <= mem::size_of::<*mut ()>()
{
while size % next_align == 0 && next_align <= ptr_size {
next_align *= 2;
}
Layout {
@ -55,6 +57,12 @@ impl Layout {
}
}
/// Creates a non-packed layout for a given size, trying to use the maximum
/// alignment possible.
pub fn for_size(ctx: &BindgenContext, size: usize) -> Self {
Self::for_size_internal(ctx.target_pointer_size(), size)
}
/// Is this a zero-sized layout?
pub fn is_zero(&self) -> bool {
self.size == 0 && self.align == 0
@ -80,7 +88,8 @@ impl Opaque {
pub fn from_clang_ty(ty: &clang::Type) -> Type {
let layout = Layout::new(ty.size(), ty.align());
let ty_kind = TypeKind::Opaque;
Type::new(None, Some(layout), ty_kind, false)
let is_const = ty.is_const();
Type::new(None, Some(layout), ty_kind, is_const)
}
/// Return the known rust type we should use to create a correctly-aligned

8
third_party/rust/bindgen/src/ir/objc.rs поставляемый
Просмотреть файл

@ -13,6 +13,7 @@ use clang_sys::CXCursor_ObjCInstanceMethodDecl;
use clang_sys::CXCursor_ObjCProtocolDecl;
use clang_sys::CXCursor_ObjCProtocolRef;
use quote;
use proc_macro2::{Term, Span};
/// Objective C interface as used in TypeKind
///
@ -216,7 +217,7 @@ impl ObjCMethod {
let split_name: Vec<_> = self.name
.split(':')
.filter(|p| !p.is_empty())
.map(quote::Ident::new)
.map(|name| Term::new(name, Span::call_site()))
.collect();
// No arguments
@ -239,9 +240,10 @@ impl ObjCMethod {
// Get arguments without type signatures to pass to `msg_send!`
let mut args_without_types = vec![];
for arg in args.iter() {
let name_and_sig: Vec<&str> = arg.as_str().split(' ').collect();
let arg = arg.to_string();
let name_and_sig: Vec<&str> = arg.split(' ').collect();
let name = name_and_sig[0];
args_without_types.push(quote::Ident::new(name))
args_without_types.push(Term::new(name, Span::call_site()))
};
let args = split_name

63
third_party/rust/bindgen/src/ir/template.rs поставляемый
Просмотреть файл

@ -81,23 +81,23 @@ use parse::ClangItemParser;
/// +------+----------------------+--------------------------+------------------------+----
/// |Decl. | self_template_params | num_self_template_params | all_template_parameters| ...
/// +------+----------------------+--------------------------+------------------------+----
/// |Foo | Some([T, U]) | Some(2) | Some([T, U]) | ...
/// |Bar | Some([V]) | Some(1) | Some([T, U, V]) | ...
/// |Inner | None | None | Some([T, U]) | ...
/// |Lol | Some([W]) | Some(1) | Some([T, U, W]) | ...
/// |Wtf | Some([X]) | Some(1) | Some([T, U, X]) | ...
/// |Qux | None | None | None | ...
/// |Foo | [T, U] | 2 | [T, U] | ...
/// |Bar | [V] | 1 | [T, U, V] | ...
/// |Inner | [] | 0 | [T, U] | ...
/// |Lol | [W] | 1 | [T, U, W] | ...
/// |Wtf | [X] | 1 | [T, U, X] | ...
/// |Qux | [] | 0 | [] | ...
/// +------+----------------------+--------------------------+------------------------+----
///
/// ----+------+-----+----------------------+
/// ... |Decl. | ... | used_template_params |
/// ----+------+-----+----------------------+
/// ... |Foo | ... | Some([T, U]) |
/// ... |Bar | ... | Some([V]) |
/// ... |Inner | ... | None |
/// ... |Lol | ... | Some([T]) |
/// ... |Wtf | ... | Some([T]) |
/// ... |Qux | ... | None |
/// ... |Foo | ... | [T, U] |
/// ... |Bar | ... | [V] |
/// ... |Inner | ... | [] |
/// ... |Lol | ... | [T] |
/// ... |Wtf | ... | [T] |
/// ... |Qux | ... | [] |
/// ----+------+-----+----------------------+
pub trait TemplateParameters {
/// Get the set of `ItemId`s that make up this template declaration's free
@ -109,17 +109,12 @@ pub trait TemplateParameters {
/// anything but types, so we must treat them as opaque, and avoid
/// instantiating them.
fn self_template_params(&self, ctx: &BindgenContext)
-> Option<Vec<TypeId>>;
-> Vec<TypeId>;
/// Get the number of free template parameters this template declaration
/// has.
///
/// Implementations *may* return `Some` from this method when
/// `template_params` returns `None`. This is useful when we only have
/// partial information about the template declaration, such as when we are
/// in the middle of parsing it.
fn num_self_template_params(&self, ctx: &BindgenContext) -> Option<usize> {
self.self_template_params(ctx).map(|params| params.len())
fn num_self_template_params(&self, ctx: &BindgenContext) -> usize {
self.self_template_params(ctx).len()
}
/// Get the complete set of template parameters that can affect this
@ -136,30 +131,20 @@ pub trait TemplateParameters {
/// how we would fully reference such a member type in C++:
/// `Foo<int,char>::Inner`. `Foo` *must* be instantiated with template
/// arguments before we can gain access to the `Inner` member type.
fn all_template_params(&self, ctx: &BindgenContext) -> Option<Vec<TypeId>>
fn all_template_params(&self, ctx: &BindgenContext) -> Vec<TypeId>
where
Self: ItemAncestors,
{
let each_self_params: Vec<Vec<_>> = self.ancestors(ctx)
.filter_map(|id| id.self_template_params(ctx))
.collect();
if each_self_params.is_empty() {
None
} else {
Some(
each_self_params
.into_iter()
.rev()
.flat_map(|params| params)
.collect(),
)
}
let ancestors: Vec<_> = self.ancestors(ctx).collect();
ancestors.into_iter().rev().flat_map(|id| {
id.self_template_params(ctx).into_iter()
}).collect()
}
/// Get only the set of template parameters that this item uses. This is a
/// subset of `all_template_params` and does not necessarily contain any of
/// `self_template_params`.
fn used_template_params(&self, ctx: &BindgenContext) -> Option<Vec<TypeId>>
fn used_template_params(&self, ctx: &BindgenContext) -> Vec<TypeId>
where
Self: AsRef<ItemId>,
{
@ -169,14 +154,10 @@ pub trait TemplateParameters {
);
let id = *self.as_ref();
ctx.resolve_item(id).all_template_params(ctx).map(
|all_params| {
all_params
ctx.resolve_item(id).all_template_params(ctx)
.into_iter()
.filter(|p| ctx.uses_template_parameter(id, *p))
.collect()
},
)
}
}

12
third_party/rust/bindgen/src/ir/traversal.rs поставляемый
Просмотреть файл

@ -201,11 +201,13 @@ pub fn all_edges(_: &BindgenContext, _: Edge) -> bool {
true
}
/// A `TraversalPredicate` implementation that never follows any edges, and
/// therefore traversals using this predicate will only visit the traversal's
/// roots.
pub fn no_edges(_: &BindgenContext, _: Edge) -> bool {
false
/// A `TraversalPredicate` implementation that only follows
/// `EdgeKind::InnerType` edges, and therefore traversals using this predicate
/// will only visit the traversal's roots and their inner types. This is used
/// in no-recursive-whitelist mode, where inner types such as anonymous
/// structs/unions still need to be processed.
pub fn only_inner_type_edges(_: &BindgenContext, edge: Edge) -> bool {
edge.kind == EdgeKind::InnerType
}
/// A `TraversalPredicate` implementation that only follows edges to items that

27
third_party/rust/bindgen/src/ir/ty.rs поставляемый
Просмотреть файл

@ -16,7 +16,6 @@ use clang::{self, Cursor};
use parse::{ClangItemParser, ParseError, ParseResult};
use std::borrow::Cow;
use std::io;
use std::mem;
/// The base representation of a type in bindgen.
///
@ -232,8 +231,6 @@ impl Type {
/// What is the layout of this type?
pub fn layout(&self, ctx: &BindgenContext) -> Option<Layout> {
use std::mem;
self.layout.or_else(|| {
match self.kind {
TypeKind::Comp(ref ci) => ci.layout(ctx),
@ -242,8 +239,8 @@ impl Type {
TypeKind::Pointer(..) |
TypeKind::BlockPointer => {
Some(Layout::new(
mem::size_of::<*mut ()>(),
mem::align_of::<*mut ()>(),
ctx.target_pointer_size(),
ctx.target_pointer_size(),
))
}
TypeKind::ResolvedTypeRef(inner) => {
@ -543,7 +540,7 @@ impl TemplateParameters for Type {
fn self_template_params(
&self,
ctx: &BindgenContext,
) -> Option<Vec<TypeId>> {
) -> Vec<TypeId> {
self.kind.self_template_params(ctx)
}
}
@ -552,13 +549,13 @@ impl TemplateParameters for TypeKind {
fn self_template_params(
&self,
ctx: &BindgenContext,
) -> Option<Vec<TypeId>> {
) -> Vec<TypeId> {
match *self {
TypeKind::ResolvedTypeRef(id) => {
ctx.resolve_type(id).self_template_params(ctx)
}
TypeKind::Comp(ref comp) => comp.self_template_params(ctx),
TypeKind::TemplateAlias(_, ref args) => Some(args.clone()),
TypeKind::TemplateAlias(_, ref args) => args.clone(),
TypeKind::Opaque |
TypeKind::TemplateInstantiation(..) |
@ -578,7 +575,7 @@ impl TemplateParameters for TypeKind {
TypeKind::Alias(_) |
TypeKind::ObjCId |
TypeKind::ObjCSel |
TypeKind::ObjCInterface(_) => None,
TypeKind::ObjCInterface(_) => vec![],
}
}
}
@ -596,17 +593,6 @@ pub enum FloatKind {
Float128,
}
impl FloatKind {
/// If this type has a known size, return it (in bytes).
pub fn known_size(&self) -> usize {
match *self {
FloatKind::Float => mem::size_of::<f32>(),
FloatKind::Double | FloatKind::LongDouble => mem::size_of::<f64>(),
FloatKind::Float128 => mem::size_of::<f64>() * 2,
}
}
}
/// The different kinds of types that we can parse.
#[derive(Debug)]
pub enum TypeKind {
@ -1208,6 +1194,7 @@ impl Type {
};
let name = if name.is_empty() { None } else { Some(name) };
let is_const = ty.is_const();
let ty = Type::new(name, layout, kind, is_const);

208
third_party/rust/bindgen/src/lib.rs поставляемый
Просмотреть файл

@ -4,6 +4,9 @@
//! functions and use types defined in the header.
//!
//! See the [`Builder`](./struct.Builder.html) struct for usage.
//!
//! See the [Users Guide](https://rust-lang-nursery.github.io/rust-bindgen/) for
//! additional documentation.
#![deny(missing_docs)]
#![deny(warnings)]
#![deny(unused_extern_crates)]
@ -23,6 +26,7 @@ extern crate lazy_static;
extern crate peeking_take_while;
#[macro_use]
extern crate quote;
extern crate proc_macro2;
extern crate regex;
extern crate which;
@ -79,8 +83,10 @@ use ir::context::{BindgenContext, ItemId};
use ir::item::Item;
use parse::{ClangItemParser, ParseError};
use regex_set::RegexSet;
pub use codegen::EnumVariation;
use std::borrow::Cow;
use std::collections::HashMap;
use std::fs::{File, OpenOptions};
use std::io::{self, Write};
use std::iter;
@ -155,6 +161,23 @@ impl Default for CodegenConfig {
/// // Write the generated bindings to an output file.
/// bindings.write_to_file("path/to/output.rs")?;
/// ```
///
/// # Enums
///
/// Bindgen can map C/C++ enums into Rust in different ways. The way bindgen maps enums depends on
/// the pattern passed to several methods:
///
/// 1. [`constified_enum_module()`](#method.constified_enum_module)
/// 2. [`bitfield_enum()`](#method.bitfield_enum)
/// 3. [`rustified_enum()`](#method.rustified_enum)
///
/// For each C enum, bindgen tries to match the pattern in the following order:
///
/// 1. Constified enum module
/// 2. Bitfield enum
/// 3. Rustified enum
///
/// If none of the above patterns match, then bindgen will generate a set of Rust constants.
#[derive(Debug, Default)]
pub struct Builder {
options: BindgenOptions,
@ -181,6 +204,16 @@ impl Builder {
output_vector.push("--rust-target".into());
output_vector.push(self.options.rust_target.into());
if self.options.default_enum_style != Default::default() {
output_vector.push("--default-enum-variant=".into());
output_vector.push(match self.options.default_enum_style {
codegen::EnumVariation::Rust => "rust",
codegen::EnumVariation::Bitfield => "bitfield",
codegen::EnumVariation::Consts => "consts",
codegen::EnumVariation::ModuleConsts => "moduleconsts",
}.into())
}
self.options
.bitfield_enums
.get_items()
@ -223,6 +256,20 @@ impl Builder {
})
.count();
self.options
.constified_enums
.get_items()
.iter()
.map(|item| {
output_vector.push("--constified-enum".into());
output_vector.push(
item.trim_left_matches("^")
.trim_right_matches("$")
.into(),
);
})
.count();
self.options
.blacklisted_types
.get_items()
@ -326,19 +373,6 @@ impl Builder {
output_vector.push("--disable-name-namespacing".into());
}
self.options
.links
.iter()
.map(|&(ref item, _)| {
output_vector.push("--framework".into());
output_vector.push(
item.trim_left_matches("^")
.trim_right_matches("$")
.into(),
);
})
.count();
if !self.options.codegen_config.functions {
output_vector.push("--ignore-functions".into());
}
@ -372,19 +406,6 @@ impl Builder {
output_vector.push("--ignore-methods".into());
}
self.options
.links
.iter()
.map(|&(ref item, _)| {
output_vector.push("--clang-args".into());
output_vector.push(
item.trim_left_matches("^")
.trim_right_matches("$")
.into(),
);
})
.count();
if !self.options.convert_floats {
output_vector.push("--no-convert-floats".into());
}
@ -420,19 +441,6 @@ impl Builder {
})
.count();
self.options
.links
.iter()
.map(|&(ref item, _)| {
output_vector.push("--static".into());
output_vector.push(
item.trim_left_matches("^")
.trim_right_matches("$")
.into(),
);
})
.count();
if self.options.use_core {
output_vector.push("--use-core".into());
}
@ -600,6 +608,12 @@ impl Builder {
self
}
/// Disable support for native Rust unions, if supported.
pub fn disable_untagged_union(mut self) -> Self {
self.options.rust_features.untagged_union = false;
self
}
/// Set the output graphviz file.
pub fn emit_ir_graphviz<T: Into<String>>(mut self, path: T) -> Builder {
let path = path.into();
@ -642,7 +656,7 @@ impl Builder {
///
/// **Disabling this feature will almost certainly cause `bindgen` to emit
/// bindings that will not compile!** If you disable this feature, then it
/// is *your* responsiblity to provide definitions for every type that is
/// is *your* responsibility to provide definitions for every type that is
/// referenced from an explicitly whitelisted item. One way to provide the
/// definitions is by using the [`Builder::raw_line`](#method.raw_line)
/// method, another would be to define them in Rust and then `include!(...)`
@ -740,6 +754,11 @@ impl Builder {
self.whitelist_var(arg)
}
/// Set the default style of code to generate for enums
pub fn default_enum_style(mut self, arg: codegen::EnumVariation) -> Builder {
self.options.default_enum_style = arg;
self
}
/// Mark the given enum (or set of enums, if using a pattern) as being
/// bitfield-like. Regular expressions are supported.
@ -766,6 +785,13 @@ impl Builder {
self
}
/// Mark the given enum (or set of enums, if using a pattern) as a set of
/// constants that are not to be put into a module.
pub fn constified_enum<T: AsRef<str>>(mut self, arg: T) -> Builder {
self.options.constified_enums.insert(arg);
self
}
/// Mark the given enum (or set of enums, if using a pattern) as a set of
/// constants that should be put into a module.
///
@ -778,11 +804,40 @@ impl Builder {
/// Add a string to prepend to the generated bindings. The string is passed
/// through without any modification.
pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Builder {
pub fn raw_line<T: Into<String>>(mut self, arg: T) -> Self {
self.options.raw_lines.push(arg.into());
self
}
/// Add a given line to the beginning of module `mod`.
pub fn module_raw_line<T, U>(mut self, mod_: T, line: U) -> Self
where
T: Into<String>,
U: Into<String>,
{
self.options
.module_lines
.entry(mod_.into())
.or_insert_with(Vec::new)
.push(line.into());
self
}
/// Add a given set of lines to the beginning of module `mod`.
pub fn module_raw_lines<T, I>(mut self, mod_: T, lines: I) -> Self
where
T: Into<String>,
I: IntoIterator,
I::Item: Into<String>,
{
self.options
.module_lines
.entry(mod_.into())
.or_insert_with(Vec::new)
.extend(lines.into_iter().map(Into::into));
self
}
/// Add an argument to be passed straight through to clang.
pub fn clang_arg<T: Into<String>>(mut self, arg: T) -> Builder {
self.options.clang_args.push(arg.into());
@ -801,26 +856,6 @@ impl Builder {
self
}
/// Make the generated bindings link the given shared library.
pub fn link<T: Into<String>>(mut self, library: T) -> Builder {
self.options.links.push((library.into(), LinkType::Default));
self
}
/// Make the generated bindings link the given static library.
pub fn link_static<T: Into<String>>(mut self, library: T) -> Builder {
self.options.links.push((library.into(), LinkType::Static));
self
}
/// Make the generated bindings link the given framework.
pub fn link_framework<T: Into<String>>(mut self, library: T) -> Builder {
self.options.links.push(
(library.into(), LinkType::Framework),
);
self
}
/// Emit bindings for builtin definitions (for example `__builtin_va_list`)
/// in the generated Rust.
pub fn emit_builtins(mut self) -> Builder {
@ -1242,6 +1277,9 @@ struct BindgenOptions {
/// Whitelisted variables. See docs for `whitelisted_types` for more.
whitelisted_vars: RegexSet,
/// The default style of code to generate for enums
default_enum_style: codegen::EnumVariation,
/// The enum patterns to mark an enum as bitfield.
bitfield_enums: RegexSet,
@ -1251,12 +1289,12 @@ struct BindgenOptions {
/// The enum patterns to mark an enum as a module of constants.
constified_enum_modules: RegexSet,
/// The enum patterns to mark an enum as a set of constants.
constified_enums: RegexSet,
/// Whether we should generate builtins or not.
builtins: bool,
/// The set of libraries we should link in the generated Rust code.
links: Vec<(String, LinkType)>,
/// True if we should dump the Clang AST for debugging purposes.
emit_ast: bool,
@ -1281,7 +1319,7 @@ struct BindgenOptions {
impl_debug: bool,
/// True if we should implement the PartialEq trait for C/C++ structures and types
/// that do not support autoamically deriving PartialEq.
/// that do not support automatically deriving PartialEq.
impl_partialeq: bool,
/// True if we should derive Copy trait implementations for C/C++ structures
@ -1335,9 +1373,15 @@ struct BindgenOptions {
/// Whether we should convert float types to f32/f64 types.
convert_floats: bool,
/// The set of raw lines to prepend to the generated Rust code.
/// The set of raw lines to prepend to the top-level module of generated
/// Rust code.
raw_lines: Vec<String>,
/// The set of raw lines to prepend to each of the modules.
///
/// This only makes sense if the `enable_cxx_namespaces` option is set.
module_lines: HashMap<String, Vec<String>>,
/// The set of arguments to pass straight through to Clang.
clang_args: Vec<String>,
@ -1360,17 +1404,17 @@ struct BindgenOptions {
/// See the builder method description for more details.
conservative_inline_namespaces: bool,
/// Wether to keep documentation comments in the generated output. See the
/// Whether to keep documentation comments in the generated output. See the
/// documentation for more details.
generate_comments: bool,
/// Whether to generate inline functions. Defaults to false.
generate_inline_functions: bool,
/// Wether to whitelist types recursively. Defaults to true.
/// Whether to whitelist types recursively. Defaults to true.
whitelist_recursively: bool,
/// Intead of emitting 'use objc;' to files generated from objective c files,
/// Instead of emitting 'use objc;' to files generated from objective c files,
/// generate '#[macro_use] extern crate objc;'
objc_extern_crate: bool,
@ -1423,6 +1467,7 @@ impl BindgenOptions {
self.blacklisted_types.build();
self.opaque_types.build();
self.bitfield_enums.build();
self.constified_enums.build();
self.constified_enum_modules.build();
self.rustified_enums.build();
self.no_partialeq_types.build();
@ -1457,11 +1502,12 @@ impl Default for BindgenOptions {
whitelisted_types: Default::default(),
whitelisted_functions: Default::default(),
whitelisted_vars: Default::default(),
default_enum_style: Default::default(),
bitfield_enums: Default::default(),
rustified_enums: Default::default(),
constified_enums: Default::default(),
constified_enum_modules: Default::default(),
builtins: false,
links: vec![],
emit_ast: false,
emit_ir: false,
emit_ir_graphviz: None,
@ -1484,6 +1530,7 @@ impl Default for BindgenOptions {
msvc_mangling: false,
convert_floats: true,
raw_lines: vec![],
module_lines: HashMap::default(),
clang_args: vec![],
input_header: None,
input_unsaved_files: vec![],
@ -1506,19 +1553,6 @@ impl Default for BindgenOptions {
}
}
/// The linking type to use with a given library.
///
/// TODO: #104: This is ignored at the moment, but shouldn't be.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum LinkType {
/// Use shared library linking. This is the default.
Default,
/// Use static linking.
Static,
/// The library is an OSX framework.
Framework,
}
fn ensure_libclang_is_loaded() {
if clang_sys::is_loaded() {
return;
@ -1696,7 +1730,7 @@ impl Bindings {
writer.write("\n".as_bytes())?;
}
let bindings = self.module.as_str().to_string();
let bindings = self.module.to_string();
match self.rustfmt_generated_string(&bindings) {
Ok(rustfmt_bindings) => {
@ -1704,7 +1738,7 @@ impl Bindings {
},
Err(err) => {
eprintln!("{:?}", err);
writer.write(bindings.as_str().as_bytes())?;
writer.write(bindings.as_bytes())?;
},
}
Ok(())
@ -1865,13 +1899,13 @@ fn parse(context: &mut BindgenContext) -> Result<(), ()> {
/// Extracted Clang version data
#[derive(Debug)]
pub struct ClangVersion {
/// Major and minor semvar, if parsing was successful
/// Major and minor semver, if parsing was successful
pub parsed: Option<(u32, u32)>,
/// full version string
pub full: String,
}
/// Get the major and the minor semvar numbers of Clang's version
/// Get the major and the minor semver numbers of Clang's version
pub fn clang_version() -> ClangVersion {
if !clang_sys::is_loaded() {
// TODO(emilio): Return meaningful error (breaking).

71
third_party/rust/bindgen/src/options.rs поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
use bindgen::{Builder, CodegenConfig, RUST_TARGET_STRINGS, RustTarget, builder};
use bindgen::{Builder, CodegenConfig, RUST_TARGET_STRINGS, RustTarget, builder, EnumVariation};
use clap::{App, Arg};
use std::fs::File;
use std::io::{self, Error, ErrorKind, Write, stderr};
@ -26,18 +26,32 @@ where
Arg::with_name("header")
.help("C or C++ header file")
.required(true),
Arg::with_name("default-enum-style")
.long("default-enum-style")
.help("The default style of code used to generate enums.")
.value_name("variant")
.default_value("consts")
.possible_values(&["consts", "moduleconsts", "bitfield", "rust"])
.multiple(false),
Arg::with_name("bitfield-enum")
.long("bitfield-enum")
.help("Mark any enum whose name matches <regex> as a set of \
bitfield flags instead of an enumeration.")
bitfield flags.")
.value_name("regex")
.takes_value(true)
.multiple(true)
.number_of_values(1),
Arg::with_name("rustified-enum")
.long("rustified-enum")
.help("Mark any enum whose name matches <regex> as a Rust enum \
instead of a set of constants.")
.help("Mark any enum whose name matches <regex> as a Rust enum.")
.value_name("regex")
.takes_value(true)
.multiple(true)
.number_of_values(1),
Arg::with_name("constified-enum")
.long("constified-enum")
.help("Mark any enum whose name matches <regex> as a series of \
constants.")
.value_name("regex")
.takes_value(true)
.multiple(true)
@ -45,7 +59,7 @@ where
Arg::with_name("constified-enum-module")
.long("constified-enum-module")
.help("Mark any enum whose name matches <regex> as a module of \
constants instead of just constants.")
constants.")
.value_name("regex")
.takes_value(true)
.multiple(true)
@ -149,12 +163,6 @@ where
.help("Disable namespacing via mangling, causing bindgen to \
generate names like \"Baz\" instead of \"foo_bar_Baz\" \
for an input name \"foo::bar::Baz\"."),
Arg::with_name("framework")
.long("framework-link")
.help("Link to framework.")
.takes_value(true)
.multiple(true)
.number_of_values(1),
Arg::with_name("ignore-functions")
.long("ignore-functions")
.help("Do not generate bindings for functions or methods. This \
@ -168,13 +176,6 @@ where
Arg::with_name("ignore-methods")
.long("ignore-methods")
.help("Do not generate bindings for methods."),
Arg::with_name("dynamic")
.short("l")
.long("link")
.help("Link to dynamic library.")
.takes_value(true)
.multiple(true)
.number_of_values(1),
Arg::with_name("no-convert-floats")
.long("no-convert-floats")
.help("Do not automatically convert floats to f32/f64."),
@ -207,12 +208,6 @@ where
.long("rust-target")
.help(&rust_target_help)
.takes_value(true),
Arg::with_name("static")
.long("static-link")
.help("Link to static library.")
.takes_value(true)
.multiple(true)
.number_of_values(1),
Arg::with_name("use-core")
.long("use-core")
.help("Use types from Rust core instead of std."),
@ -322,6 +317,10 @@ where
builder = builder.rust_target(RustTarget::from_str(rust_target)?);
}
if let Some(variant) = matches.value_of("default-enum-style") {
builder = builder.default_enum_style(EnumVariation::from_str(variant)?)
}
if let Some(bitfields) = matches.values_of("bitfield-enum") {
for regex in bitfields {
builder = builder.bitfield_enum(regex);
@ -334,6 +333,12 @@ where
}
}
if let Some(bitfields) = matches.values_of("constified-enum") {
for regex in bitfields {
builder = builder.constified_enum(regex);
}
}
if let Some(constified_mods) = matches.values_of("constified-enum-module") {
for regex in constified_mods {
builder = builder.constified_enum_module(regex);
@ -409,12 +414,6 @@ where
builder = builder.ctypes_prefix(prefix);
}
if let Some(links) = matches.values_of("dynamic") {
for library in links {
builder = builder.link(library);
}
}
if let Some(what_to_generate) = matches.value_of("generate") {
let mut config = CodegenConfig::nothing();
for what in what_to_generate.split(",") {
@ -456,12 +455,6 @@ where
builder = builder.disable_name_namespacing();
}
if let Some(links) = matches.values_of("framework") {
for framework in links {
builder = builder.link_framework(framework);
}
}
if matches.is_present("ignore-functions") {
builder = builder.ignore_functions();
}
@ -498,12 +491,6 @@ where
}
}
if let Some(links) = matches.values_of("static") {
for library in links {
builder = builder.link_static(library);
}
}
if matches.is_present("use-core") {
builder = builder.use_core();
}

2
third_party/rust/bindgen/src/time.rs поставляемый
Просмотреть файл

@ -22,7 +22,7 @@ impl<'a> Timer<'a> {
}
}
/// Sets whether or not the Timer will print a mesage
/// Sets whether or not the Timer will print a message
/// when it is dropped.
pub fn with_output(mut self, output: bool) -> Self {
self.output = output;

Просмотреть файл

@ -1 +1 @@
{"files":{".travis.yml":"d5c89494c836e00ec8c3c02c9e228bf5dc34aabff203c37662a248e2da4bda05","CHANGELOG.md":"2d6ade5cd80d388392915d24f4712e8fd604579c7b26d48aa99908499e08817d","CONTRIBUTING.md":"4e2a45992604f07a37030bb1fc598c6f54a1785747c4f37a15a37481bbdecce8","Cargo.toml":"c2256b278d66bf80e6b62e58efa62a5fb98665c8c23dec68829b2c9fc2191962","LICENSE.txt":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"dff1b472fe1edbc6059ff5a96e595fa8dab9e9e133d10fd761cf5dfdcc80f4c6","appveyor.yml":"c9ab8ab1ab028b27d2be176e994a0d6a255cf8bcc36e15868472b6b8abf33fac","build.rs":"e6cf2ec64466b21f3e6eb8aaf7327ccdfcc77a2067e0e19ee5e2a6f57117c09b","ci/before_install.sh":"711c9d0539fa0372980c3a288d9482a0e46d3ba0fb8f7c7c110d6488a8ec4de5","ci/install.bat":"fb636c3511ba038ccf805755ef6542237cc595e905edcd61d56abd7163321f76","ci/script.sh":"1bb1cd29bd9635cc126cdcbd6c02f3500620a231a86726bf2165a4b74baaf433","ci/test_script.bat":"73462f51aaa9a1c14ce9f55c41dc3672df64faa9789725384ae4f28d8ba3c90b","clippy.toml":"acef14b9acffa18d1069ae08a4e8fe824a614f91b0bc71a6b1c68e4d885397e6","src/lib.rs":"a0410d2e23f808ba441e7bebe84785e85582c8130613e49c7b3b98e0aaf55b66","src/link.rs":"7323c3ddcd8038b899c21f7087666628f88e9cb430900549855ea78717824e6f","src/support.rs":"ecd0489662caad0a13ea468cbbbec3ca62ba9796a6e24aabb392978a3455ebfd","tests/header.h":"b1cf564b21d76db78529d1934e1481a5f0452fdedc6e32954608293c310498b6","tests/lib.rs":"e5e8a60bcaec3b5d043fde4a993d397adb56454d0b2a6adaa15df0535246f909"},"package":"939a1a34310b120d26eba35c29475933128b0ec58e24b43327f8dbe6036fc538"}
{"files":{".travis.yml":"d5c89494c836e00ec8c3c02c9e228bf5dc34aabff203c37662a248e2da4bda05","CHANGELOG.md":"62fd8ba43afbc4da3dba40d448a5af482794aaaa99071d40dc7abf8fc1a2195b","Cargo.toml":"1ada60cd29713d4386050d2b61a9eed430827885520816b0412ed0380fa3fa8f","LICENSE.txt":"cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30","README.md":"dff1b472fe1edbc6059ff5a96e595fa8dab9e9e133d10fd761cf5dfdcc80f4c6","appveyor.yml":"c9ab8ab1ab028b27d2be176e994a0d6a255cf8bcc36e15868472b6b8abf33fac","build.rs":"50be9c247e528ab0a354a7652fa9516906f79bbb4d128d54db7f5a9ee1ed2a86","ci/before_install.sh":"711c9d0539fa0372980c3a288d9482a0e46d3ba0fb8f7c7c110d6488a8ec4de5","ci/install.bat":"fb636c3511ba038ccf805755ef6542237cc595e905edcd61d56abd7163321f76","ci/script.sh":"1bb1cd29bd9635cc126cdcbd6c02f3500620a231a86726bf2165a4b74baaf433","ci/test_script.bat":"73462f51aaa9a1c14ce9f55c41dc3672df64faa9789725384ae4f28d8ba3c90b","clippy.toml":"acef14b9acffa18d1069ae08a4e8fe824a614f91b0bc71a6b1c68e4d885397e6","src/lib.rs":"d0a11284694f4f77448e72480addca613572d19c07fa92157e0fa717ed504abd","src/link.rs":"a0208e6b8e4840f1162b3b799b5e12dd559cc6f31a330b0eb1ba4ebe2385296d","src/support.rs":"70e77ea4337f740b13c394034c5705e962af6ee7ac4843fc7c9c7fe22ec2d074","tests/header.h":"b1cf564b21d76db78529d1934e1481a5f0452fdedc6e32954608293c310498b6","tests/lib.rs":"e5e8a60bcaec3b5d043fde4a993d397adb56454d0b2a6adaa15df0535246f909"},"package":"d7f7c04e52c35222fffcc3a115b5daf5f7e2bfb71c13c4e2321afe1fc71859c2"}

5
third_party/rust/clang-sys/CHANGELOG.md поставляемый
Просмотреть файл

@ -1,3 +1,8 @@
## [0.23.0] - 2018-06-16
### Changed
- Changed `Clang::find` to skip dynamic libraries for an incorrect architecture on Windows
## [0.22.0] - 2018-03-11
### Added

7
third_party/rust/clang-sys/CONTRIBUTING.md поставляемый
Просмотреть файл

@ -1,7 +0,0 @@
# Contributing to clang-sys
## Pull Requests
If you are intending to make a pull request, please make your changes in a branch that originated
from the `development` branch, not the `master` branch. Then, make your pull request against the
`development` branch.

10
third_party/rust/clang-sys/Cargo.toml поставляемый
Просмотреть файл

@ -12,7 +12,7 @@
[package]
name = "clang-sys"
version = "0.22.0"
version = "0.23.0"
authors = ["Kyle Mayes <kyle@mayeses.com>"]
build = "build.rs"
links = "clang"
@ -21,10 +21,6 @@ documentation = "https://kylemayes.github.io/clang-sys/3_5/clang_sys"
readme = "README.md"
license = "Apache-2.0"
repository = "https://github.com/KyleMayes/clang-sys"
[dependencies.clippy]
version = "0.0.*"
optional = true
[dependencies.glob]
version = "0.2.11"
@ -34,10 +30,6 @@ version = "0.2.39"
[dependencies.libloading]
version = "0.5.0"
optional = true
[build-dependencies.clippy]
version = "0.0.*"
optional = true
[build-dependencies.glob]
version = "0.2.11"

66
third_party/rust/clang-sys/build.rs поставляемый
Просмотреть файл

@ -25,15 +25,11 @@
#![allow(unused_attributes)]
#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![cfg_attr(feature="clippy", warn(clippy))]
extern crate glob;
use std::env;
use std::fs::{self, File};
use std::io::{Read};
use std::io::{Read, Seek, SeekFrom};
use std::path::{Path, PathBuf};
use std::process::{Command};
@ -128,6 +124,41 @@ const SEARCH_WINDOWS: &[&str] = &[
"C:\\MSYS*\\MinGW*\\lib",
];
/// Returns the ELF class from the ELF header in the supplied file.
fn parse_elf_header(file: &PathBuf) -> Result<u8, String> {
let mut file = try!(File::open(file).map_err(|e| e.to_string()));
let mut elf = [0; 5];
try!(file.read_exact(&mut elf).map_err(|e| e.to_string()));
if elf[..4] == [127, 69, 76, 70] {
Ok(elf[4])
} else {
Err("invalid ELF header".into())
}
}
/// Returns the magic number from the PE header in the supplied file.
fn parse_pe_header(file: &PathBuf) -> Result<u16, String> {
let mut file = try!(File::open(file).map_err(|e| e.to_string()));
let mut pe = [0; 4];
// Determine the header offset.
try!(file.seek(SeekFrom::Start(0x3C)).map_err(|e| e.to_string()));
try!(file.read_exact(&mut pe).map_err(|e| e.to_string()));
let offset = i32::from(pe[0]) + (i32::from(pe[1]) << 8) + (i32::from(pe[2]) << 16) + (i32::from(pe[3]) << 24);
// Determine the validity of the header.
try!(file.seek(SeekFrom::Start(offset as u64)).map_err(|e| e.to_string()));
try!(file.read_exact(&mut pe).map_err(|e| e.to_string()));
if pe != [80, 69, 0, 0] {
return Err("invalid PE header".into());
}
// Find the magic number.
try!(file.seek(SeekFrom::Current(20)).map_err(|e| e.to_string()));
try!(file.read_exact(&mut pe).map_err(|e| e.to_string()));
Ok(u16::from(pe[0]) + (u16::from(pe[1]) << 8))
}
/// Indicates the type of library being searched for.
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum Library {
@ -142,19 +173,26 @@ impl Library {
if *self == Library::Static {
return Ok(());
}
let mut file = try!(File::open(file).map_err(|e| e.to_string()));
let mut elf = [0; 5];
try!(file.read_exact(&mut elf).map_err(|e| e.to_string()));
if elf[..4] != [127, 69, 76, 70] {
return Err("invalid ELF header".into());
}
if cfg!(target_pointer_width="32") && elf[4] != 1 {
let class = try!(parse_elf_header(file));
if cfg!(target_pointer_width="32") && class != 1 {
return Err("invalid ELF class (64-bit)".into());
}
if cfg!(target_pointer_width="64") && elf[4] != 2 {
if cfg!(target_pointer_width="64") && class != 2 {
return Err("invalid ELF class (32-bit)".into());
}
Ok(())
} else if cfg!(target_os="windows") {
if *self == Library::Static {
return Ok(());
}
let magic = try!(parse_pe_header(file));
if cfg!(target_pointer_width="32") && magic != 267 {
return Err("invalid DLL (64-bit)".into());
}
if cfg!(target_pointer_width="64") && magic != 523 {
return Err("invalid DLL (32-bit)".into());
}
Ok(())
} else {
Ok(())
}
@ -216,7 +254,7 @@ fn find(library: Library, files: &[String], env: &str) -> Result<PathBuf, String
// Search the `LD_LIBRARY_PATH` directories.
if let Ok(path) = env::var("LD_LIBRARY_PATH") {
for directory in path.split(":").map(Path::new) {
for directory in path.split(':').map(Path::new) {
search_directory!(directory);
}
}

5
third_party/rust/clang-sys/src/lib.rs поставляемый
Просмотреть файл

@ -27,10 +27,7 @@
#![allow(non_camel_case_types, non_snake_case, non_upper_case_globals)]
#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![cfg_attr(feature="clippy", warn(clippy))]
#![cfg_attr(feature="clippy", allow(unreadable_literal))]
#![cfg_attr(feature="cargo-clippy", allow(unreadable_literal))]
extern crate glob;
extern crate libc;

2
third_party/rust/clang-sys/src/link.rs поставляемый
Просмотреть файл

@ -80,7 +80,7 @@ macro_rules! link {
}
$(
#[cfg_attr(feature="clippy", allow(too_many_arguments))]
#[cfg_attr(feature="cargo-clippy", allow(too_many_arguments))]
$(#[cfg($cfg)])*
pub unsafe fn $name($($pname: $pty), *) $(-> $ret)* {
let f = with_library(|l| {

7
third_party/rust/clang-sys/src/support.rs поставляемый
Просмотреть файл

@ -63,12 +63,7 @@ impl Clang {
let version = parse_version(&path);
let c_search_paths = parse_search_paths(&path, "c", args);
let cpp_search_paths = parse_search_paths(&path, "c++", args);
Clang {
path: path,
version: version,
c_search_paths: c_search_paths,
cpp_search_paths: cpp_search_paths,
}
Clang { path, version, c_search_paths, cpp_search_paths }
}
/// Returns a `clang` executable if one can be found.

1
third_party/rust/proc-macro2-0.3.5/.cargo-checksum.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1 @@
{"files":{".travis.yml":"872a0d195dcb1e84f28aa994f301c7139f70360bb42dee3954df5ee965efea15","Cargo.toml":"e71f764696d6998512da00a9ac309f2717d103707aeef81164f906c1588ede63","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"ce05336717e1e90724491a2f54487c41c752fa2d32396639439f7c6d0f1e6776","src/lib.rs":"3280d7e0b6043d8472f418aa5c8458c97aa2b5a572f9156a251b5672828468c2","src/stable.rs":"4b5a65bd5dc174dd027b9ee951844c3765450f9d45961a8d6cd7d5f85b4c25c8","src/strnom.rs":"129fe22f0b50e5a64fca82e731c959135381c910e19f3305ef35420e0aadde08","src/unstable.rs":"b43c713ac16d9de0ba0fa1b9bebe390122b4ad60ef2fc75408f721305fdcd46b","tests/test.rs":"b06713fd8bd93ab9f0156bd25152e08f68a71b35e064c53b584f7f7dbb9b60b8"},"package":"77997c53ae6edd6d187fec07ec41b207063b5ee6f33680e9fa86d405cdd313d4"}

Просмотреть файл

Просмотреть файл

@ -12,7 +12,7 @@
[package]
name = "proc-macro2"
version = "0.3.6"
version = "0.3.5"
authors = ["Alex Crichton <alex@alexcrichton.com>"]
description = "A stable implementation of the upcoming new `proc_macro` API. Comes with an\noption, off by default, to also reimplement itself in terms of the upstream\nunstable API.\n"
homepage = "https://github.com/alexcrichton/proc-macro2"

Просмотреть файл

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -24,7 +24,7 @@
//! [ts]: https://doc.rust-lang.org/proc_macro/struct.TokenStream.html
// Proc-macro2 types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/proc-macro2/0.3.6")]
#![doc(html_root_url = "https://docs.rs/proc-macro2/0.3.5")]
#![cfg_attr(feature = "nightly", feature(proc_macro))]
#[cfg(feature = "proc-macro")]

Просмотреть файл

@ -403,8 +403,6 @@ thread_local!(static SYMBOLS: RefCell<Interner> = RefCell::new(Interner::new()))
impl Term {
pub fn new(string: &str, span: Span) -> Term {
validate_term(string);
Term {
intern: SYMBOLS.with(|s| s.borrow_mut().intern(string)),
span: span,
@ -428,42 +426,6 @@ impl Term {
}
}
fn validate_term(string: &str) {
let validate = if string.starts_with('\'') {
&string[1..]
} else if string.starts_with("r#") {
&string[2..]
} else {
string
};
if validate.is_empty() {
panic!("Term is not allowed to be empty; use Option<Term>");
}
if validate.bytes().all(|digit| digit >= b'0' && digit <= b'9') {
panic!("Term cannot be a number; use Literal instead");
}
fn xid_ok(string: &str) -> bool {
let mut chars = string.chars();
let first = chars.next().unwrap();
if !(UnicodeXID::is_xid_start(first) || first == '_') {
return false;
}
for ch in chars {
if !UnicodeXID::is_xid_continue(ch) {
return false;
}
}
true
}
if !xid_ok(validate) {
panic!("{:?} is not a valid Term", string);
}
}
impl fmt::Debug for Term {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("Term").field(&self.as_str()).finish()

Просмотреть файл

Просмотреть файл

Просмотреть файл

@ -5,78 +5,9 @@ use std::str::{self, FromStr};
use proc_macro2::{Literal, Span, Term, TokenStream, TokenTree};
#[test]
fn terms() {
assert_eq!(Term::new("String", Span::call_site()).as_str(), "String");
assert_eq!(Term::new("fn", Span::call_site()).as_str(), "fn");
assert_eq!(Term::new("_", Span::call_site()).as_str(), "_");
}
#[test]
fn raw_terms() {
assert_eq!(Term::new("r#String", Span::call_site()).as_str(), "r#String");
assert_eq!(Term::new("r#fn", Span::call_site()).as_str(), "r#fn");
assert_eq!(Term::new("r#_", Span::call_site()).as_str(), "r#_");
}
#[test]
fn lifetimes() {
assert_eq!(Term::new("'a", Span::call_site()).as_str(), "'a");
assert_eq!(Term::new("'static", Span::call_site()).as_str(), "'static");
assert_eq!(Term::new("'_", Span::call_site()).as_str(), "'_");
}
#[test]
#[should_panic(expected = "Term is not allowed to be empty; use Option<Term>")]
fn term_empty() {
Term::new("", Span::call_site());
}
#[test]
#[should_panic(expected = "Term cannot be a number; use Literal instead")]
fn term_number() {
Term::new("255", Span::call_site());
}
#[test]
#[should_panic(expected = "\"a#\" is not a valid Term")]
fn term_invalid() {
Term::new("a#", Span::call_site());
}
#[test]
#[should_panic(expected = "Term is not allowed to be empty; use Option<Term>")]
fn raw_term_empty() {
Term::new("r#", Span::call_site());
}
#[test]
#[should_panic(expected = "Term cannot be a number; use Literal instead")]
fn raw_term_number() {
Term::new("r#255", Span::call_site());
}
#[test]
#[should_panic(expected = "\"r#a#\" is not a valid Term")]
fn raw_term_invalid() {
Term::new("r#a#", Span::call_site());
}
#[test]
#[should_panic(expected = "Term is not allowed to be empty; use Option<Term>")]
fn lifetime_empty() {
Term::new("'", Span::call_site());
}
#[test]
#[should_panic(expected = "Term cannot be a number; use Literal instead")]
fn lifetime_number() {
Term::new("'255", Span::call_site());
}
#[test]
#[should_panic(expected = r#""\'a#" is not a valid Term"#)]
fn lifetime_invalid() {
Term::new("'a#", Span::call_site());
fn symbols() {
assert_eq!(Term::new("foo", Span::call_site()).as_str(), "foo");
assert_eq!(Term::new("bar", Span::call_site()).as_str(), "bar");
}
#[test]

Просмотреть файл

@ -1 +0,0 @@
{"files":{".travis.yml":"872a0d195dcb1e84f28aa994f301c7139f70360bb42dee3954df5ee965efea15","Cargo.toml":"6ed5d7b9bf8805abd76f9e2a9be99b98e2cb70d9b97980b8aa09b6082d26a94d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"378f5840b258e2779c39418f3f2d7b2ba96f1c7917dd6be0713f88305dbda397","README.md":"ce05336717e1e90724491a2f54487c41c752fa2d32396639439f7c6d0f1e6776","src/lib.rs":"e99fedcb4b410c626fe1a3ab722c8b4f98baed2c64c2dff28c4eb62da354f2e2","src/stable.rs":"fd8d86f7542d211030056a7cdcc58b86131180d54f461910a4a067269eee9d4a","src/strnom.rs":"129fe22f0b50e5a64fca82e731c959135381c910e19f3305ef35420e0aadde08","src/unstable.rs":"b43c713ac16d9de0ba0fa1b9bebe390122b4ad60ef2fc75408f721305fdcd46b","tests/test.rs":"a8229931093cd6b39f759c60ef097e59bc43c98f1b0e5eea06ecc8d5d0879853"},"package":"49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"}