From b3d4e6fdf865486e41b895516a56188645a5a9e6 Mon Sep 17 00:00:00 2001 From: Andrew McCreight Date: Wed, 28 Feb 2018 12:51:39 -0800 Subject: [PATCH] Bug 1438688, part 2 - Load XPT information from a static variable instead of a file. r=njn This patch removes C++ code related to reading in XPT information from files. (Code related to packaging XPT files will be removed in the next patch.) This includes code in the manifest parser, in addition to the actual code for parsing files. XPT information is now loaded directly from a single static data structure, XPTHeader::kHeader, which will be automatically generated at compile time from .idl files (via .xpt files). Note that the script to do that is not added until part 6 of this patch series, so linking will fail on parts 2 through 5. I inlined XPTInterfaceInfoManager::RegisterXPTHeader into the ctor, because that is the only caller. It feels like the lock there should not be needed any more, but I left it alone for now. The forward declaration of XPTArena in xptiprivate.h is needed because it was being bootlegged via xpt_xdr.h. Some of the data structures in reflect/xptinfo/ (which wrap the xpt_struct.h data structures) are still allocated using XPTArena. Hopefully we can get rid of that in followup work. I also deleted a lot of comments in xpt_struct.h that talk about the on-disk format. I also deleted checking of the major version number, because that should not matter when the XPT information is baked into the executable. MozReview-Commit-ID: 6NJdaCWRBhU --- xpcom/components/ManifestParser.cpp | 4 - xpcom/components/nsComponentManager.cpp | 34 -- xpcom/components/nsComponentManager.h | 2 - .../reflect/xptinfo/XPTInterfaceInfoManager.h | 5 - .../xptinfo/xptiInterfaceInfoManager.cpp | 38 +- xpcom/reflect/xptinfo/xptiprivate.h | 2 +- xpcom/typelib/xpt/moz.build | 3 - xpcom/typelib/xpt/xpt_struct.cpp | 470 ------------------ xpcom/typelib/xpt/xpt_struct.h | 104 +--- xpcom/typelib/xpt/xpt_xdr.cpp | 238 --------- xpcom/typelib/xpt/xpt_xdr.h | 80 --- 11 files changed, 27 insertions(+), 953 deletions(-) delete mode 100644 xpcom/typelib/xpt/xpt_struct.cpp delete mode 100644 xpcom/typelib/xpt/xpt_xdr.cpp delete mode 100644 xpcom/typelib/xpt/xpt_xdr.h diff --git a/xpcom/components/ManifestParser.cpp b/xpcom/components/ManifestParser.cpp index 97acd78f28f32..5ed3889a80bb4 100644 --- a/xpcom/components/ManifestParser.cpp +++ b/xpcom/components/ManifestParser.cpp @@ -79,10 +79,6 @@ static const ManifestDirective kParsingTable[] = { "binary-component", 1, true, true, false, false, false, &nsComponentManagerImpl::ManifestBinaryComponent, nullptr, }, - { - "interfaces", 1, false, true, false, false, false, - &nsComponentManagerImpl::ManifestXPT, nullptr, - }, { "component", 2, false, true, false, false, false, &nsComponentManagerImpl::ManifestComponent, nullptr, diff --git a/xpcom/components/nsComponentManager.cpp b/xpcom/components/nsComponentManager.cpp index 227c806d46970..61eba1c1ee66e 100644 --- a/xpcom/components/nsComponentManager.cpp +++ b/xpcom/components/nsComponentManager.cpp @@ -17,9 +17,7 @@ #include "nsDirectoryServiceDefs.h" #include "nsCategoryManager.h" #include "nsCategoryManagerUtils.h" -#include "xptiprivate.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/XPTInterfaceInfoManager.h" #include "nsIConsoleService.h" #include "nsIObserverService.h" #include "nsISimpleEnumerator.h" @@ -32,7 +30,6 @@ #include "nsReadableUtils.h" #include "nsString.h" #include "prcmon.h" -#include "xptinfo.h" // this after nsISupports, to pick up IID so that xpt stuff doesn't try to define it itself... #include "nsThreadUtils.h" #include "prthread.h" #include "private/pprthred.h" @@ -575,37 +572,6 @@ nsComponentManagerImpl::ManifestBinaryComponent(ManifestProcessingContext& aCx, "Binary XPCOM components are no longer supported."); } -static void -DoRegisterXPT(FileLocation& aFile) -{ - uint32_t len; - FileLocation::Data data; - UniquePtr buf; - nsresult rv = aFile.GetData(data); - if (NS_SUCCEEDED(rv)) { - rv = data.GetSize(&len); - } - if (NS_SUCCEEDED(rv)) { - buf = MakeUnique(len); - rv = data.Copy(buf.get(), len); - } - if (NS_SUCCEEDED(rv)) { - XPTInterfaceInfoManager::GetSingleton()->RegisterBuffer(buf.get(), len); - } else { - nsCString uri; - aFile.GetURIString(uri); - LogMessage("Could not read '%s'.", uri.get()); - } -} - -void -nsComponentManagerImpl::ManifestXPT(ManifestProcessingContext& aCx, - int aLineNo, char* const* aArgv) -{ - FileLocation f(aCx.mFile, aArgv[0]); - DoRegisterXPT(f); -} - void nsComponentManagerImpl::ManifestComponent(ManifestProcessingContext& aCx, int aLineNo, char* const* aArgv) diff --git a/xpcom/components/nsComponentManager.h b/xpcom/components/nsComponentManager.h index 03e68206adb58..55e8f266a2250 100644 --- a/xpcom/components/nsComponentManager.h +++ b/xpcom/components/nsComponentManager.h @@ -290,8 +290,6 @@ class nsComponentManagerImpl final char* const* aArgv); void ManifestBinaryComponent(ManifestProcessingContext& aCx, int aLineNo, char* const* aArgv); - void ManifestXPT(ManifestProcessingContext& aCx, int aLineNo, - char* const* aArgv); void ManifestComponent(ManifestProcessingContext& aCx, int aLineNo, char* const* aArgv); void ManifestContract(ManifestProcessingContext& aCx, int aLineNo, diff --git a/xpcom/reflect/xptinfo/XPTInterfaceInfoManager.h b/xpcom/reflect/xptinfo/XPTInterfaceInfoManager.h index 58377d8a908ba..353afe260bfaf 100644 --- a/xpcom/reflect/xptinfo/XPTInterfaceInfoManager.h +++ b/xpcom/reflect/xptinfo/XPTInterfaceInfoManager.h @@ -17,7 +17,6 @@ template class nsCOMArray; class nsIMemoryReporter; -struct XPTHeader; struct XPTInterfaceDirectoryEntry; class xptiInterfaceEntry; class xptiInterfaceInfo; @@ -40,8 +39,6 @@ class XPTInterfaceInfoManager final void GetScriptableInterfaces(nsCOMArray& aInterfaces); - void RegisterBuffer(char *buf, uint32_t length); - static Mutex& GetResolveLock() { return GetSingleton()->mResolveLock; @@ -57,8 +54,6 @@ class XPTInterfaceInfoManager final void InitMemoryReporter(); - void RegisterXPTHeader(const XPTHeader* aHeader); - // idx is the index of this interface in the XPTHeader void VerifyAndAddEntryIfNew(const XPTInterfaceDirectoryEntry* iface, uint16_t idx, diff --git a/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp b/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp index 4c225621b4fe5..bb0a8ebac7f49 100644 --- a/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp +++ b/xpcom/reflect/xptinfo/xptiInterfaceInfoManager.cpp @@ -81,6 +81,12 @@ XPTInterfaceInfoManager::XPTInterfaceInfoManager() : mWorkingSet(), mResolveLock("XPTInterfaceInfoManager.mResolveLock") { + xptiTypelibGuts* typelib = xptiTypelibGuts::Create(&XPTHeader::kHeader); + + ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor); + for (uint16_t k = 0; k < XPTHeader::kHeader.mNumInterfaces; k++) { + VerifyAndAddEntryIfNew(XPTHeader::kHeader.mInterfaceDirectory + k, k, typelib); + } } XPTInterfaceInfoManager::~XPTInterfaceInfoManager() @@ -97,38 +103,6 @@ XPTInterfaceInfoManager::InitMemoryReporter() RegisterWeakMemoryReporter(this); } -void -XPTInterfaceInfoManager::RegisterBuffer(char *buf, uint32_t length) -{ - XPTState state; - XPT_InitXDRState(&state, buf, length); - - XPTCursor curs; - NotNull cursor = WrapNotNull(&curs); - if (!XPT_MakeCursor(&state, XPT_HEADER, 0, cursor)) { - return; - } - - XPTHeader *header = nullptr; - if (XPT_DoHeader(gXPTIStructArena, cursor, &header)) { - RegisterXPTHeader(header); - } -} - -void -XPTInterfaceInfoManager::RegisterXPTHeader(const XPTHeader* aHeader) -{ - if (aHeader->mMajorVersion >= XPT_MAJOR_INCOMPATIBLE_VERSION) { - MOZ_ASSERT(!aHeader->mNumInterfaces, "bad libxpt"); - } - - xptiTypelibGuts* typelib = xptiTypelibGuts::Create(aHeader); - - ReentrantMonitorAutoEnter monitor(mWorkingSet.mTableReentrantMonitor); - for(uint16_t k = 0; k < aHeader->mNumInterfaces; k++) - VerifyAndAddEntryIfNew(aHeader->mInterfaceDirectory + k, k, typelib); -} - void XPTInterfaceInfoManager::VerifyAndAddEntryIfNew(const XPTInterfaceDirectoryEntry* iface, uint16_t idx, diff --git a/xpcom/reflect/xptinfo/xptiprivate.h b/xpcom/reflect/xptinfo/xptiprivate.h index 283da1dbe3508..48590fb6c4dcf 100644 --- a/xpcom/reflect/xptinfo/xptiprivate.h +++ b/xpcom/reflect/xptinfo/xptiprivate.h @@ -15,7 +15,6 @@ // this after nsISupports, to pick up IID // so that xpt stuff doesn't try to define it itself... #include "xpt_struct.h" -#include "xpt_xdr.h" #include "nsIInterfaceInfo.h" #include "nsIInterfaceInfoManager.h" @@ -62,6 +61,7 @@ class xptiInterfaceInfo; class xptiInterfaceEntry; class xptiTypelibGuts; +struct XPTArena; extern XPTArena* gXPTIStructArena; /***************************************************************************/ diff --git a/xpcom/typelib/xpt/moz.build b/xpcom/typelib/xpt/moz.build index c6cf7e91cf04d..8ba7686ea79b1 100644 --- a/xpcom/typelib/xpt/moz.build +++ b/xpcom/typelib/xpt/moz.build @@ -10,14 +10,11 @@ DIRS += ['tools'] UNIFIED_SOURCES += [ 'xpt_arena.cpp', - 'xpt_struct.cpp', - 'xpt_xdr.cpp', ] EXPORTS += [ 'xpt_arena.h', 'xpt_struct.h', - 'xpt_xdr.h', ] FINAL_LIBRARY = 'xul' diff --git a/xpcom/typelib/xpt/xpt_struct.cpp b/xpcom/typelib/xpt/xpt_struct.cpp deleted file mode 100644 index 48b9efd45f58b..0000000000000 --- a/xpcom/typelib/xpt/xpt_struct.cpp +++ /dev/null @@ -1,470 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set ts=8 sts=4 et sw=4 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Implementation of XDR routines for typelib structures. */ - -#include "xpt_xdr.h" -#include "xpt_struct.h" -#include -#include -#include - -using mozilla::WrapNotNull; - -#define XPT_MAGIC "XPCOM\nTypeLib\r\n\032" -#define XPT_MAGIC_STRING "XPCOM\\nTypeLib\\r\\n\\032" - -/* - * Annotation records are variable-size records used to store secondary - * information about the typelib, e.g. such as the name of the tool that - * generated the typelib file, the date it was generated, etc. The - * information is stored with very loose format requirements so as to - * allow virtually any private data to be stored in the typelib. - * - * There are two types of Annotations: - * - * EmptyAnnotation - * PrivateAnnotation - * - * The tag field of the prefix discriminates among the variant record - * types for Annotation's. If the tag is 0, this record is an - * EmptyAnnotation. EmptyAnnotation's are ignored - they're only used to - * indicate an array of Annotation's that's completely empty. If the tag - * is 1, the record is a PrivateAnnotation. - * - * We don't actually store annotations; we just skip over them if they are - * present. - */ - -#define XPT_ANN_LAST 0x80 -#define XPT_ANN_PRIVATE 0x40 - -#define XPT_ANN_IS_LAST(flags) (flags & XPT_ANN_LAST) -#define XPT_ANN_IS_PRIVATE(flags)(flags & XPT_ANN_PRIVATE) - - -/***************************************************************************/ -/* Forward declarations. */ - -static bool -DoInterfaceDirectoryEntry(XPTArena *arena, NotNull cursor, - XPTInterfaceDirectoryEntry *ide); - -static bool -DoConstDescriptor(XPTArena *arena, NotNull cursor, - XPTConstDescriptor *cd, XPTInterfaceDescriptor *id); - -static bool -DoMethodDescriptor(XPTArena *arena, NotNull cursor, - XPTMethodDescriptor *md, XPTInterfaceDescriptor *id); - -static bool -SkipAnnotation(NotNull cursor, bool *isLast); - -static bool -DoInterfaceDescriptor(XPTArena *arena, NotNull outer, - const XPTInterfaceDescriptor **idp); - -static bool -DoTypeDescriptorPrefix(XPTArena *arena, NotNull cursor, - XPTTypeDescriptorPrefix *tdp); - -static bool -DoTypeDescriptor(XPTArena *arena, NotNull cursor, - XPTTypeDescriptor *td, XPTInterfaceDescriptor *id); - -static bool -DoParamDescriptor(XPTArena *arena, NotNull cursor, - XPTParamDescriptor *pd, XPTInterfaceDescriptor *id); - -/***************************************************************************/ - -bool -XPT_DoHeader(XPTArena *arena, NotNull cursor, XPTHeader **headerp) -{ - unsigned int i; - uint32_t file_length = 0; - uint32_t ide_offset; - - XPTHeader* header = XPT_NEWZAP(arena, XPTHeader); - if (!header) - return false; - *headerp = header; - - uint8_t magic[16]; - for (i = 0; i < sizeof(magic); i++) { - if (!XPT_Do8(cursor, &magic[i])) - return false; - } - - if (strncmp((const char*)magic, XPT_MAGIC, 16) != 0) { - /* Require that the header contain the proper magic */ - fprintf(stderr, - "libxpt: bad magic header in input file; " - "found '%s', expected '%s'\n", - magic, XPT_MAGIC_STRING); - return false; - } - - uint8_t minor_version; - if (!XPT_Do8(cursor, &header->mMajorVersion) || - !XPT_Do8(cursor, &minor_version)) { - return false; - } - - if (header->mMajorVersion >= XPT_MAJOR_INCOMPATIBLE_VERSION) { - /* This file is newer than we are and set to an incompatible version - * number. We must set the header state thusly and return. - */ - header->mNumInterfaces = 0; - return true; - } - - if (!XPT_Do16(cursor, &header->mNumInterfaces) || - !XPT_Do32(cursor, &file_length) || - !XPT_Do32(cursor, &ide_offset)) { - return false; - } - - /* - * Make sure the file length reported in the header is the same size as - * as our buffer unless it is zero (not set) - */ - if (file_length != 0 && - cursor->state->pool_allocated < file_length) { - fputs("libxpt: File length in header does not match actual length. File may be corrupt\n", - stderr); - return false; - } - - uint32_t data_pool; - if (!XPT_Do32(cursor, &data_pool)) - return false; - - XPT_SetDataOffset(cursor->state, data_pool); - - XPTInterfaceDirectoryEntry* interface_directory = nullptr; - - if (header->mNumInterfaces) { - size_t n = header->mNumInterfaces * sizeof(XPTInterfaceDirectoryEntry); - interface_directory = - static_cast(XPT_CALLOC8(arena, n)); - if (!interface_directory) - return false; - } - - /* - * Iterate through the annotations rather than recurring, to avoid blowing - * the stack on large xpt files. We don't actually store annotations, we - * just skip over them. - */ - bool isLast; - do { - if (!SkipAnnotation(cursor, &isLast)) - return false; - } while (!isLast); - - /* shouldn't be necessary now, but maybe later */ - XPT_SeekTo(cursor, ide_offset); - - for (i = 0; i < header->mNumInterfaces; i++) { - if (!DoInterfaceDirectoryEntry(arena, cursor, - &interface_directory[i])) - return false; - } - - header->mInterfaceDirectory = interface_directory; - - return true; -} - -/* InterfaceDirectoryEntry records go in the header */ -bool -DoInterfaceDirectoryEntry(XPTArena *arena, NotNull cursor, - XPTInterfaceDirectoryEntry *ide) -{ - const char* dummy_name_space; - - /* write the IID in our cursor space */ - if (!XPT_DoIID(cursor, &(ide->mIID)) || - - /* write the name string in the data pool, and the offset in our - cursor space */ - !XPT_DoCString(arena, cursor, &(ide->mName)) || - - /* don't write the name_space string in the data pool, because we don't - * need it. Do write the offset in our cursor space */ - !XPT_DoCString(arena, cursor, &dummy_name_space, /* ignore = */ true) || - - /* do InterfaceDescriptors */ - !DoInterfaceDescriptor(arena, cursor, &ide->mInterfaceDescriptor)) { - return false; - } - - return true; -} - -static bool -InterfaceDescriptorAddType(XPTArena *arena, - XPTInterfaceDescriptor *id, - XPTTypeDescriptor *td) -{ - const XPTTypeDescriptor *old = id->mAdditionalTypes; - XPTTypeDescriptor *new_; - size_t old_size = id->mNumAdditionalTypes * sizeof(XPTTypeDescriptor); - size_t new_size = old_size + sizeof(XPTTypeDescriptor); - - /* XXX should grow in chunks to minimize alloc overhead */ - new_ = static_cast(XPT_CALLOC8(arena, new_size)); - if (!new_) - return false; - if (old) { - memcpy(new_, old, old_size); - } - - new_[id->mNumAdditionalTypes] = *td; - id->mAdditionalTypes = new_; - - if (id->mNumAdditionalTypes == UINT8_MAX) - return false; - - id->mNumAdditionalTypes += 1; - return true; -} - -bool -DoInterfaceDescriptor(XPTArena *arena, NotNull outer, - const XPTInterfaceDescriptor **idp) -{ - XPTInterfaceDescriptor *id; - XPTCursor curs; - NotNull cursor = WrapNotNull(&curs); - uint32_t i, id_sz = 0; - - id = XPT_NEWZAP(arena, XPTInterfaceDescriptor); - if (!id) - return false; - *idp = id; - - if (!XPT_MakeCursor(outer->state, XPT_DATA, id_sz, cursor)) - return false; - - if (!XPT_Do32(outer, &cursor->offset)) - return false; - if (!cursor->offset) { - *idp = NULL; - return true; - } - if(!XPT_Do16(cursor, &id->mParentInterface) || - !XPT_Do16(cursor, &id->mNumMethods)) { - return false; - } - - XPTMethodDescriptor* method_descriptors = nullptr; - - if (id->mNumMethods) { - size_t n = id->mNumMethods * sizeof(XPTMethodDescriptor); - method_descriptors = - static_cast(XPT_CALLOC8(arena, n)); - if (!method_descriptors) - return false; - } - - for (i = 0; i < id->mNumMethods; i++) { - if (!DoMethodDescriptor(arena, cursor, &method_descriptors[i], id)) - return false; - } - - id->mMethodDescriptors = method_descriptors; - - if (!XPT_Do16(cursor, &id->mNumConstants)) { - return false; - } - - XPTConstDescriptor* const_descriptors = nullptr; - - if (id->mNumConstants) { - size_t n = id->mNumConstants * sizeof(XPTConstDescriptor); - const_descriptors = - static_cast(XPT_CALLOC8(arena, n)); - if (!const_descriptors) - return false; - } - - for (i = 0; i < id->mNumConstants; i++) { - if (!DoConstDescriptor(arena, cursor, &const_descriptors[i], id)) { - return false; - } - } - - id->mConstDescriptors = const_descriptors; - - if (!XPT_Do8(cursor, &id->mFlags)) { - return false; - } - - return true; -} - -bool -DoConstDescriptor(XPTArena *arena, NotNull cursor, - XPTConstDescriptor *cd, XPTInterfaceDescriptor *id) -{ - bool ok = false; - - if (!XPT_DoCString(arena, cursor, &cd->mName) || - !DoTypeDescriptor(arena, cursor, &cd->mType, id)) { - - return false; - } - - switch (cd->mType.Tag()) { - case TD_INT16: - ok = XPT_Do16(cursor, (uint16_t*) &cd->mValue.i16); - break; - case TD_INT32: - ok = XPT_Do32(cursor, (uint32_t*) &cd->mValue.i32); - break; - case TD_UINT16: - ok = XPT_Do16(cursor, &cd->mValue.ui16); - break; - case TD_UINT32: - ok = XPT_Do32(cursor, &cd->mValue.ui32); - break; - default: - MOZ_ASSERT(false, "illegal type"); - break; - } - - return ok; -} - -bool -DoMethodDescriptor(XPTArena *arena, NotNull cursor, - XPTMethodDescriptor *md, XPTInterfaceDescriptor *id) -{ - int i; - - if (!XPT_Do8(cursor, &md->mFlags) || - !XPT_DoCString(arena, cursor, &md->mName) || - !XPT_Do8(cursor, &md->mNumArgs)) - return false; - - XPTParamDescriptor* params = nullptr; - - if (md->mNumArgs) { - size_t n = md->mNumArgs * sizeof(XPTParamDescriptor); - params = static_cast(XPT_CALLOC8(arena, n)); - if (!params) - return false; - } - - for(i = 0; i < md->mNumArgs; i++) { - if (!DoParamDescriptor(arena, cursor, ¶ms[i], id)) - return false; - } - - md->mParams = params; - - // |result| appears in the on-disk format but it isn't used, - // because a method is either notxpcom, in which case it can't be - // called from script so the XPT information is irrelevant, or the - // result type is nsresult. - XPTParamDescriptor result; - if (!DoParamDescriptor(arena, cursor, &result, id)) - return false; - - return true; -} - -bool -DoParamDescriptor(XPTArena *arena, NotNull cursor, - XPTParamDescriptor *pd, XPTInterfaceDescriptor *id) -{ - if (!XPT_Do8(cursor, &pd->mFlags) || - !DoTypeDescriptor(arena, cursor, &pd->mType, id)) - return false; - - return true; -} - -bool -DoTypeDescriptorPrefix(XPTArena *arena, NotNull cursor, - XPTTypeDescriptorPrefix *tdp) -{ - return XPT_Do8(cursor, &tdp->mFlags); -} - -bool -DoTypeDescriptor(XPTArena *arena, NotNull cursor, - XPTTypeDescriptor *td, XPTInterfaceDescriptor *id) -{ - if (!DoTypeDescriptorPrefix(arena, cursor, &td->mPrefix)) { - return false; - } - - switch (td->Tag()) { - case TD_INTERFACE_TYPE: - uint16_t iface; - if (!XPT_Do16(cursor, &iface)) - return false; - td->mData1 = (iface >> 8) & 0xff; - td->mData2 = iface & 0xff; - break; - case TD_INTERFACE_IS_TYPE: - if (!XPT_Do8(cursor, &td->mData1)) - return false; - break; - case TD_ARRAY: { - // argnum2 appears in the on-disk format but it isn't used. - uint8_t argnum2 = 0; - if (!XPT_Do8(cursor, &td->mData1) || - !XPT_Do8(cursor, &argnum2)) - return false; - - XPTTypeDescriptor elementTypeDescriptor; - if (!DoTypeDescriptor(arena, cursor, &elementTypeDescriptor, id)) - return false; - if (!InterfaceDescriptorAddType(arena, id, &elementTypeDescriptor)) - return false; - td->mData2 = id->mNumAdditionalTypes - 1; - - break; - } - case TD_PSTRING_SIZE_IS: - case TD_PWSTRING_SIZE_IS: { - // argnum2 appears in the on-disk format but it isn't used. - uint8_t argnum2 = 0; - if (!XPT_Do8(cursor, &td->mData1) || - !XPT_Do8(cursor, &argnum2)) - return false; - break; - } - default: - /* nothing special */ - break; - } - return true; -} - -bool -SkipAnnotation(NotNull cursor, bool *isLast) -{ - uint8_t flags; - if (!XPT_Do8(cursor, &flags)) - return false; - - *isLast = XPT_ANN_IS_LAST(flags); - - if (XPT_ANN_IS_PRIVATE(flags)) { - if (!XPT_SkipStringInline(cursor) || - !XPT_SkipStringInline(cursor)) - return false; - } - - return true; -} - diff --git a/xpcom/typelib/xpt/xpt_struct.h b/xpcom/typelib/xpt/xpt_struct.h index d299b02dcf3a2..5b4a15aefc44d 100644 --- a/xpcom/typelib/xpt/xpt_struct.h +++ b/xpcom/typelib/xpt/xpt_struct.h @@ -5,7 +5,7 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ /* - * Structures matching the in-memory representation of typelib structures. + * Structures for representing typelib structures in memory. * http://www.mozilla.org/scriptable/typelib_file.html */ @@ -16,18 +16,6 @@ #include #include "mozilla/Assertions.h" -/* - * Originally, I was going to have structures that exactly matched the on-disk - * representation, but that proved difficult: different compilers can pack - * their structs differently, and that makes overlaying them atop a - * read-from-disk byte buffer troublesome. So now I just have some structures - * that are used in memory, and we're going to write a nice XDR library to - * write them to disk and stuff. It is pure joy. -- shaver - */ - -/* Structures for the typelib components */ - -struct XPTHeader; struct XPTInterfaceDirectoryEntry; struct XPTInterfaceDescriptor; struct XPTConstDescriptor; @@ -36,40 +24,17 @@ struct XPTParamDescriptor; struct XPTTypeDescriptor; struct XPTTypeDescriptorPrefix; -/* - * Every XPCOM typelib file begins with a header. - */ struct XPTHeader { - // Some of these fields exists in the on-disk format but don't need to be - // stored in memory (other than very briefly, which can be done with local - // variables). - - //uint8_t mMagic[16]; - uint8_t mMajorVersion; - //uint8_t mMinorVersion; uint16_t mNumInterfaces; - //uint32_t mFileLength; const XPTInterfaceDirectoryEntry* mInterfaceDirectory; - //uint32_t mDataPool; -}; -/* - * Any file with a major version number of XPT_MAJOR_INCOMPATIBLE_VERSION - * or higher is to be considered incompatible by this version of xpt and - * we will refuse to read it. We will return a header with magic, major and - * minor versions set from the file. num_interfaces will be set to zero to - * confirm our inability to read the file; i.e. even if some client of this - * library gets out of sync with us regarding the agreed upon value for - * XPT_MAJOR_INCOMPATIBLE_VERSION, anytime num_interfaces is zero we *know* - * that this library refused to read the file due to version incompatibility. - */ -#define XPT_MAJOR_INCOMPATIBLE_VERSION 0x02 + static const XPTHeader kHeader; +}; /* - * A contiguous array of fixed-size InterfaceDirectoryEntry records begins at - * the byte offset identified by the mInterfaceDirectory field in the file - * header. The array is used to quickly locate an interface description - * using its IID. No interface should appear more than once in the array. + * An array of directory entries is used to quickly locate an interface + * description using its IID. No interface should appear more than once in the + * array. */ struct XPTInterfaceDirectoryEntry { inline const XPTInterfaceDescriptor* InterfaceDescriptor() const; @@ -77,11 +42,6 @@ struct XPTInterfaceDirectoryEntry { nsID mIID; const char* mName; - - // This field exists in the on-disk format. But it isn't used so we don't - // allocate space for it in memory. - //const char* mNameSpace; - const XPTInterfaceDescriptor* mInterfaceDescriptor; }; @@ -105,8 +65,6 @@ struct XPTInterfaceDescriptor { /* * This field ordering minimizes the size of this struct. - * The fields are serialized on disk in a different order. - * See DoInterfaceDescriptor(). */ const XPTMethodDescriptor* mMethodDescriptors; const XPTConstDescriptor* mConstDescriptors; @@ -115,29 +73,12 @@ struct XPTInterfaceDescriptor { uint16_t mNumMethods; uint16_t mNumConstants; uint8_t mFlags; - - /* - * mAdditionalTypes are used for arrays where we may need multiple - * XPTTypeDescriptors for a single XPTMethodDescriptor. Since we still - * want to have a simple array of XPTMethodDescriptor (each with a single - * embedded XPTTypeDescriptor), a XPTTypeDescriptor can have a reference - * to an 'additional_type'. That reference is an index in this - * "mAdditionalTypes" array. So a given XPTMethodDescriptor might have - * a whole chain of these XPTTypeDescriptors to represent, say, a multi - * dimensional array. - * - * Note that in the typelib file these additional types are stored 'inline' - * in the MethodDescriptor. But, in the typelib MethodDescriptors can be - * of varying sizes, where in XPT's in memory mapping of the data we want - * them to be of fixed size. This mAdditionalTypes scheme is here to allow - * for that. - */ uint8_t mNumAdditionalTypes; }; /* - * A TypeDescriptor is a variable-size record used to identify the type of a - * method argument or return value. + * A TypeDescriptor is a union used to identify the type of a method + * argument or return value. * * There are three types of TypeDescriptors: * @@ -146,10 +87,9 @@ struct XPTInterfaceDescriptor { * InterfaceIsTypeDescriptor * * The tag field in the prefix indicates which of the variant TypeDescriptor - * records is being used, and hence the way any remaining fields should be - * parsed. Values from 0 to 17 refer to SimpleTypeDescriptors. The value 18 - * designates an InterfaceTypeDescriptor, while 19 represents an - * InterfaceIsTypeDescriptor. + * records is being used, and hence which union members are valid. Values from 0 + * to 17 refer to SimpleTypeDescriptors. The value 18 designates an + * InterfaceTypeDescriptor, while 19 represents an InterfaceIsTypeDescriptor. */ /* why bother with a struct? - other code relies on this being a struct */ @@ -234,21 +174,19 @@ struct XPTTypeDescriptor { }; /* - * A ConstDescriptor is a variable-size record that records the name and - * value of a scoped interface constant. This is allowed only for a subset - * of types. + * A ConstDescriptor records the name and value of a scoped interface constant. + * This is allowed only for a subset of types. * - * The type (and thus the size) of the value record is determined by the - * contents of the associated TypeDescriptor record. For instance, if type - * corresponds to int16_t, then value is a two-byte record consisting of a - * 16-bit signed integer. + * The type of the value record is determined by the contents of the associated + * TypeDescriptor record. For instance, if type corresponds to int16_t, then + * value is a 16-bit signed integer. */ union XPTConstValue { int16_t i16; uint16_t ui16; int32_t i32; uint32_t ui32; -}; /* varies according to type */ +}; struct XPTConstDescriptor { const char* Name() const { @@ -261,8 +199,8 @@ struct XPTConstDescriptor { }; /* - * A ParamDescriptor is a variable-size record used to describe either a - * single argument to a method or a method's result. + * A ParamDescriptor is used to describe either a single argument to a method or + * a method's result. */ struct XPTParamDescriptor { uint8_t mFlags; @@ -270,8 +208,7 @@ struct XPTParamDescriptor { }; /* - * A MethodDescriptor is a variable-size record used to describe a single - * interface method. + * A MethodDescriptor is used to describe a single interface method. */ struct XPTMethodDescriptor { const char* Name() const { @@ -283,7 +220,6 @@ struct XPTMethodDescriptor { const char* mName; const XPTParamDescriptor* mParams; - //XPTParamDescriptor mResult; // Present on disk, omitted here. uint8_t mFlags; uint8_t mNumArgs; }; diff --git a/xpcom/typelib/xpt/xpt_xdr.cpp b/xpcom/typelib/xpt/xpt_xdr.cpp deleted file mode 100644 index 5e199b5ec5188..0000000000000 --- a/xpcom/typelib/xpt/xpt_xdr.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set ts=8 sts=4 et sw=4 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* Implementation of XDR primitives. */ - -#include "xpt_xdr.h" -#include "nscore.h" -#include /* strchr */ -#include "mozilla/Assertions.h" -#include "mozilla/EndianUtils.h" - -static size_t -CursPoolOffsetRaw(NotNull cursor) -{ - if (cursor->pool == XPT_HEADER) { - return cursor->offset; - } - MOZ_ASSERT(cursor->state->data_offset); - return cursor->offset + cursor->state->data_offset; -} - -static size_t -CursPoolOffset(NotNull cursor) -{ - return CursPoolOffsetRaw(cursor) - 1; -} - -static char* -CursPoint(NotNull cursor) -{ - return &cursor->state->pool_data[CursPoolOffset(cursor)]; -} - -static bool -CheckCount(NotNull cursor, uint32_t space) -{ - // Fail if we're in the data area and about to exceed the allocation. - // XXX Also fail if we're in the data area and !state->data_offset - if (cursor->pool == XPT_DATA && - (CursPoolOffset(cursor) + space > cursor->state->pool_allocated)) { - MOZ_ASSERT(false); - fprintf(stderr, "FATAL: no room for %u in cursor\n", space); - return false; - } - - return true; -} - -void -XPT_InitXDRState(XPTState* state, char *data, uint32_t len) -{ - state->next_cursor[0] = state->next_cursor[1] = 1; - state->pool_data = data; - state->pool_allocated = len; -} - -/* All offsets are 1-based */ -void -XPT_SetDataOffset(XPTState *state, uint32_t data_offset) -{ - state->data_offset = data_offset; -} - -bool -XPT_MakeCursor(XPTState *state, XPTPool pool, uint32_t len, - NotNull cursor) -{ - cursor->state = state; - cursor->pool = pool; - cursor->bits = 0; - cursor->offset = state->next_cursor[pool]; - - if (!(CheckCount(cursor, len))) - return false; - - /* this check should be in CHECK_CURSOR */ - if (pool == XPT_DATA && !state->data_offset) { - fprintf(stderr, "no data offset for XPT_DATA cursor!\n"); - return false; - } - - state->next_cursor[pool] += len; - - return true; -} - -bool -XPT_SeekTo(NotNull cursor, uint32_t offset) -{ - /* XXX do some real checking and update len and stuff */ - cursor->offset = offset; - return true; -} - -bool -XPT_SkipStringInline(NotNull cursor) -{ - uint16_t length; - if (!XPT_Do16(cursor, &length)) - return false; - - uint8_t byte; - for (uint16_t i = 0; i < length; i++) - if (!XPT_Do8(cursor, &byte)) - return false; - - return true; -} - -bool -XPT_DoCString(XPTArena *arena, NotNull cursor, const char **identp, - bool ignore) -{ - uint32_t offset = 0; - if (!XPT_Do32(cursor, &offset)) - return false; - - if (!offset) { - *identp = NULL; - return true; - } - - XPTCursor my_cursor; - my_cursor.pool = XPT_DATA; - my_cursor.offset = offset; - my_cursor.state = cursor->state; - char* start = CursPoint(WrapNotNull(&my_cursor)); - - char* end = strchr(start, 0); /* find the end of the string */ - if (!end) { - fprintf(stderr, "didn't find end of string on decode!\n"); - return false; - } - int len = end - start; - MOZ_ASSERT(len > 0); - - if (!ignore) { - char *ident = (char*)XPT_CALLOC1(arena, len + 1u); - if (!ident) - return false; - - memcpy(ident, start, (size_t)len); - ident[len] = 0; - *identp = ident; - } - - return true; -} - -/* - * IIDs are written in struct order, in the usual big-endian way. From the - * typelib file spec: - * - * "For example, this IID: - * {00112233-4455-6677-8899-aabbccddeeff} - * is converted to the 128-bit value - * 0x00112233445566778899aabbccddeeff - * Note that the byte storage order corresponds to the layout of the nsIID - * C-struct on a big-endian architecture." - * - * (http://www.mozilla.org/scriptable/typelib_file.html#iid) - */ -bool -XPT_DoIID(NotNull cursor, nsID *iidp) -{ - int i; - - if (!XPT_Do32(cursor, &iidp->m0) || - !XPT_Do16(cursor, &iidp->m1) || - !XPT_Do16(cursor, &iidp->m2)) - return false; - - for (i = 0; i < 8; i++) - if (!XPT_Do8(cursor, (uint8_t *)&iidp->m3[i])) - return false; - - return true; -} - -// MSVC apparently cannot handle functions as template parameters very well, -// so we need to use a macro approach here. - -#define XPT_DOINT(T, func, valuep) \ - do { \ - const size_t sz = sizeof(T); \ - \ - if (!CheckCount(cursor, sz)) { \ - return false; \ - } \ - \ - *valuep = func(CursPoint(cursor)); \ - cursor->offset += sz; \ - return true; \ - } while(0) - -bool -XPT_Do64(NotNull cursor, int64_t *u64p) -{ - XPT_DOINT(int64_t, mozilla::BigEndian::readInt64, u64p); -} - -/* - * When we're handling 32- or 16-bit quantities, we handle a byte at a time to - * avoid alignment issues. Someone could come and optimize this to detect - * well-aligned cases and do a single store, if they cared. I might care - * later. - */ -bool -XPT_Do32(NotNull cursor, uint32_t *u32p) -{ - XPT_DOINT(uint32_t, mozilla::BigEndian::readUint32, u32p); -} - -bool -XPT_Do16(NotNull cursor, uint16_t *u16p) -{ - XPT_DOINT(uint16_t, mozilla::BigEndian::readUint16, u16p); -} - -#undef XPT_DOINT - -bool -XPT_Do8(NotNull cursor, uint8_t *u8p) -{ - if (!CheckCount(cursor, 1)) - return false; - - *u8p = *CursPoint(cursor); - - cursor->offset++; - - return true; -} - - diff --git a/xpcom/typelib/xpt/xpt_xdr.h b/xpcom/typelib/xpt/xpt_xdr.h deleted file mode 100644 index 80234e1f9d3e0..0000000000000 --- a/xpcom/typelib/xpt/xpt_xdr.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* vim: set ts=8 sts=4 et sw=4 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -/* - * Basic APIs for streaming typelib structures from disk. - */ - -#ifndef __xpt_xdr_h__ -#define __xpt_xdr_h__ - -#include "xpt_struct.h" -#include "mozilla/NotNull.h" - -using mozilla::NotNull; - -struct XPTArena; -struct XPTCursor; -struct XPTState; - -bool -XPT_SkipStringInline(NotNull cursor); - -bool -XPT_DoCString(XPTArena *arena, NotNull cursor, const char **strp, - bool ignore = false); - -bool -XPT_DoIID(NotNull cursor, nsID *iidp); - -bool -XPT_Do64(NotNull cursor, int64_t *u64p); - -bool -XPT_Do32(NotNull cursor, uint32_t *u32p); - -bool -XPT_Do16(NotNull cursor, uint16_t *u16p); - -bool -XPT_Do8(NotNull cursor, uint8_t *u8p); - -bool -XPT_DoHeader(XPTArena *arena, NotNull cursor, XPTHeader **headerp); - -enum XPTPool { - XPT_HEADER = 0, - XPT_DATA = 1 -}; - -struct XPTState { - uint32_t data_offset; - uint32_t next_cursor[2]; - char *pool_data; - uint32_t pool_allocated; -}; - -struct XPTCursor { - XPTState *state; - XPTPool pool; - uint32_t offset; - uint8_t bits; -}; - -void -XPT_InitXDRState(XPTState* state, char* data, uint32_t len); - -bool -XPT_MakeCursor(XPTState *state, XPTPool pool, uint32_t len, - NotNull cursor); - -bool -XPT_SeekTo(NotNull cursor, uint32_t offset); - -void -XPT_SetDataOffset(XPTState *state, uint32_t data_offset); - -#endif /* __xpt_xdr_h__ */