зеркало из https://github.com/mozilla/gecko-dev.git
720 строки
23 KiB
C++
720 строки
23 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
/**
|
|
* Structures and methods with information about XPCOM interfaces for use by
|
|
* XPConnect. The static backing data structures used by this file are generated
|
|
* from xpidl interfaces by the jsonxpt.py and xptcodegen.py scripts.
|
|
*/
|
|
|
|
#ifndef xptinfo_h
|
|
#define xptinfo_h
|
|
|
|
#include <stdint.h>
|
|
#include "nsID.h"
|
|
#include "mozilla/Assertions.h"
|
|
#include "js/Value.h"
|
|
#include "nsString.h"
|
|
#include "nsTArray.h"
|
|
|
|
// Forward Declarations
|
|
namespace mozilla {
|
|
namespace dom {
|
|
struct NativePropertyHooks;
|
|
} // namespace dom
|
|
} // namespace mozilla
|
|
|
|
struct nsXPTInterfaceInfo;
|
|
struct nsXPTType;
|
|
struct nsXPTParamInfo;
|
|
struct nsXPTMethodInfo;
|
|
struct nsXPTConstantInfo;
|
|
struct nsXPTDOMObjectInfo;
|
|
|
|
// Internal helper methods.
|
|
namespace xpt {
|
|
namespace detail {
|
|
|
|
inline const nsXPTInterfaceInfo* GetInterface(uint16_t aIndex);
|
|
inline const nsXPTType& GetType(uint16_t aIndex);
|
|
inline const nsXPTParamInfo& GetParam(uint16_t aIndex);
|
|
inline const nsXPTMethodInfo& GetMethod(uint16_t aIndex);
|
|
inline const nsXPTConstantInfo& GetConstant(uint16_t aIndex);
|
|
inline const nsXPTDOMObjectInfo& GetDOMObjectInfo(uint16_t aIndex);
|
|
inline const char* GetString(uint32_t aIndex);
|
|
|
|
const nsXPTInterfaceInfo* InterfaceByIID(const nsIID& aIID);
|
|
const nsXPTInterfaceInfo* InterfaceByName(const char* aName);
|
|
|
|
extern const uint16_t sInterfacesSize;
|
|
|
|
} // namespace detail
|
|
} // namespace xpt
|
|
|
|
|
|
/*
|
|
* An Interface describes a single XPCOM interface, including all of its
|
|
* methods. We don't record non-scriptable interfaces.
|
|
*/
|
|
struct nsXPTInterfaceInfo
|
|
{
|
|
// High efficiency getters for Interfaces based on perfect hashes.
|
|
static const nsXPTInterfaceInfo* ByIID(const nsIID& aIID) {
|
|
return xpt::detail::InterfaceByIID(aIID);
|
|
}
|
|
static const nsXPTInterfaceInfo* ByName(const char* aName) {
|
|
return xpt::detail::InterfaceByName(aName);
|
|
}
|
|
|
|
// These are only needed for Components_interfaces's enumerator.
|
|
static const nsXPTInterfaceInfo* ByIndex(uint16_t aIndex) {
|
|
// NOTE: We add 1 here, as the internal index 0 is reserved for null.
|
|
return xpt::detail::GetInterface(aIndex + 1);
|
|
}
|
|
static uint16_t InterfaceCount() { return xpt::detail::sInterfacesSize; }
|
|
|
|
|
|
// Interface flag getters
|
|
bool IsScriptable() const { return true; } // XXX remove (bug 1480245)
|
|
bool IsFunction() const { return mFunction; }
|
|
bool IsBuiltinClass() const { return mBuiltinClass; }
|
|
bool IsMainProcessScriptableOnly() const { return mMainProcessScriptableOnly; }
|
|
|
|
const char* Name() const { return xpt::detail::GetString(mName); }
|
|
const nsIID& IID() const { return mIID; }
|
|
|
|
// Get the parent interface, or null if this interface doesn't have a parent.
|
|
const nsXPTInterfaceInfo* GetParent() const {
|
|
return xpt::detail::GetInterface(mParent);
|
|
}
|
|
|
|
// Do we have an ancestor interface with the given IID?
|
|
bool HasAncestor(const nsIID& aIID) const;
|
|
|
|
// Get methods & constants
|
|
uint16_t ConstantCount() const { return mNumConsts; }
|
|
const nsXPTConstantInfo& Constant(uint16_t aIndex) const;
|
|
uint16_t MethodCount() const { return mNumMethods; }
|
|
const nsXPTMethodInfo& Method(uint16_t aIndex) const;
|
|
|
|
|
|
////////////////////////////////////////////////////////////
|
|
// nsIInterfaceInfo backwards compatibility (bug 1480245) //
|
|
////////////////////////////////////////////////////////////
|
|
|
|
nsresult GetName(char** aName) const;
|
|
nsresult IsScriptable(bool* aRes) const;
|
|
nsresult IsBuiltinClass(bool* aRes) const;
|
|
nsresult GetParent(const nsXPTInterfaceInfo** aParent) const;
|
|
nsresult GetMethodCount(uint16_t* aMethodCount) const;
|
|
nsresult GetConstantCount(uint16_t* aConstantCount) const;
|
|
nsresult GetMethodInfo(uint16_t aIndex, const nsXPTMethodInfo** aInfo) const;
|
|
nsresult GetConstant(uint16_t aIndex,
|
|
JS::MutableHandleValue constant,
|
|
char** aName) const;
|
|
nsresult IsIID(const nsIID* aIID, bool* aIs) const;
|
|
nsresult GetNameShared(const char** aName) const;
|
|
nsresult GetIIDShared(const nsIID** aIID) const;
|
|
nsresult IsFunction(bool* aRetval) const;
|
|
nsresult HasAncestor(const nsIID* aIID, bool* aRetval) const;
|
|
nsresult IsMainProcessScriptableOnly(bool* aRetval) const;
|
|
|
|
bool EnsureResolved() const { return true; } // XXX: Remove (bug 1480245)
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Ensure these fields are in the same order as xptcodegen.py //
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
nsID mIID;
|
|
uint32_t mName; // Index into xpt::detail::sStrings
|
|
|
|
uint16_t mParent : 14;
|
|
uint16_t mBuiltinClass : 1;
|
|
// XXX(nika): Do we need this if we don't have addons anymore?
|
|
uint16_t mMainProcessScriptableOnly : 1;
|
|
|
|
uint16_t mMethods; // Index into xpt::detail::sMethods
|
|
|
|
uint16_t mConsts : 14; // Index into xpt::detail::sConsts
|
|
uint16_t mFunction : 1;
|
|
// uint16_t unused : 1;
|
|
|
|
uint8_t mNumMethods; // NOTE(24/04/18): largest=nsIDocShell (193)
|
|
uint8_t mNumConsts; // NOTE(24/04/18): largest=nsIAccessibleRole (175)
|
|
};
|
|
|
|
// The fields in nsXPTInterfaceInfo were carefully ordered to minimize size.
|
|
static_assert(sizeof(nsXPTInterfaceInfo) == 28, "wrong size?");
|
|
|
|
|
|
/*
|
|
* The following enum represents contains the different tag types which
|
|
* can be found in nsXPTTypeInfo::mTag.
|
|
*
|
|
* WARNING: mTag is 5 bits wide, supporting at most 32 tags.
|
|
*/
|
|
enum nsXPTTypeTag : uint8_t
|
|
{
|
|
// Arithmetic (POD) Types
|
|
// - Do not require cleanup,
|
|
// - All bit patterns are valid,
|
|
// - Outparams may be uninitialized by caller,
|
|
// - Directly supported in xptcall.
|
|
//
|
|
// NOTE: The name 'Arithmetic' comes from Harbison/Steele. Despite being a tad
|
|
// unclear, it is used frequently in xptcall, so is unlikely to be changed.
|
|
TD_INT8 = 0,
|
|
TD_INT16 = 1,
|
|
TD_INT32 = 2,
|
|
TD_INT64 = 3,
|
|
TD_UINT8 = 4,
|
|
TD_UINT16 = 5,
|
|
TD_UINT32 = 6,
|
|
TD_UINT64 = 7,
|
|
TD_FLOAT = 8,
|
|
TD_DOUBLE = 9,
|
|
TD_BOOL = 10,
|
|
TD_CHAR = 11,
|
|
TD_WCHAR = 12,
|
|
_TD_LAST_ARITHMETIC = TD_WCHAR,
|
|
|
|
// Pointer Types
|
|
// - Require cleanup unless NULL,
|
|
// - All-zeros (NULL) bit pattern is valid,
|
|
// - Outparams may be uninitialized by caller,
|
|
// - Supported in xptcall as raw pointer.
|
|
TD_VOID = 13,
|
|
TD_PNSIID = 14,
|
|
TD_PSTRING = 15,
|
|
TD_PWSTRING = 16,
|
|
TD_INTERFACE_TYPE = 17,
|
|
TD_INTERFACE_IS_TYPE = 18,
|
|
TD_LEGACY_ARRAY = 19,
|
|
TD_PSTRING_SIZE_IS = 20,
|
|
TD_PWSTRING_SIZE_IS = 21,
|
|
TD_DOMOBJECT = 22,
|
|
TD_PROMISE = 23,
|
|
_TD_LAST_POINTER = TD_PROMISE,
|
|
|
|
// Complex Types
|
|
// - Require cleanup,
|
|
// - Always passed indirectly,
|
|
// - Outparams must be initialized by caller,
|
|
// - Supported in xptcall due to indirection.
|
|
TD_DOMSTRING = 24,
|
|
TD_UTF8STRING = 25,
|
|
TD_CSTRING = 26,
|
|
TD_ASTRING = 27,
|
|
TD_JSVAL = 28,
|
|
TD_ARRAY = 29,
|
|
_TD_LAST_COMPLEX = TD_ARRAY
|
|
};
|
|
|
|
static_assert(_TD_LAST_COMPLEX < 32, "nsXPTTypeTag must fit in 5 bits");
|
|
|
|
|
|
/*
|
|
* A nsXPTType is a union used to identify the type of a method argument or
|
|
* return value. The internal data is stored as an 5-bit tag, and two 8-bit
|
|
* integers, to keep alignment requirements low.
|
|
*
|
|
* nsXPTType contains 3 extra bits, reserved for use by nsXPTParamInfo.
|
|
*/
|
|
struct nsXPTType
|
|
{
|
|
nsXPTTypeTag Tag() const { return static_cast<nsXPTTypeTag>(mTag); }
|
|
|
|
// The index in the function argument list which should be used when
|
|
// determining the iid_is or size_is properties of this dependent type.
|
|
uint8_t ArgNum() const {
|
|
MOZ_ASSERT(Tag() == TD_INTERFACE_IS_TYPE ||
|
|
Tag() == TD_PSTRING_SIZE_IS ||
|
|
Tag() == TD_PWSTRING_SIZE_IS ||
|
|
Tag() == TD_LEGACY_ARRAY);
|
|
return mData1;
|
|
}
|
|
|
|
private:
|
|
// Helper for reading 16-bit data values split between mData1 and mData2.
|
|
uint16_t Data16() const { return ((uint16_t)mData1 << 8) | mData2; }
|
|
|
|
public:
|
|
// Get the type of the element in the current array or sequence. Arrays only
|
|
// fit 8 bits of type data, while sequences support up to 16 bits of type data
|
|
// due to not needing to store an ArgNum.
|
|
const nsXPTType& ArrayElementType() const {
|
|
if (Tag() == TD_LEGACY_ARRAY) {
|
|
return xpt::detail::GetType(mData2);
|
|
}
|
|
MOZ_ASSERT(Tag() == TD_ARRAY);
|
|
return xpt::detail::GetType(Data16());
|
|
}
|
|
|
|
// We store the 16-bit iface value as two 8-bit values in order to
|
|
// avoid 16-bit alignment requirements for XPTTypeDescriptor, which
|
|
// reduces its size and also the size of XPTParamDescriptor.
|
|
const nsXPTInterfaceInfo* GetInterface() const {
|
|
MOZ_ASSERT(Tag() == TD_INTERFACE_TYPE);
|
|
return xpt::detail::GetInterface(Data16());
|
|
}
|
|
|
|
const nsXPTDOMObjectInfo& GetDOMObjectInfo() const {
|
|
MOZ_ASSERT(Tag() == TD_DOMOBJECT);
|
|
return xpt::detail::GetDOMObjectInfo(Data16());
|
|
}
|
|
|
|
// See the comments in nsXPTTypeTag for an explanation as to what each of
|
|
// these categories mean.
|
|
bool IsArithmetic() const { return Tag() <= _TD_LAST_ARITHMETIC; }
|
|
bool IsPointer() const { return !IsArithmetic() && Tag() <= _TD_LAST_POINTER; }
|
|
bool IsComplex() const { return Tag() > _TD_LAST_POINTER; }
|
|
|
|
bool IsInterfacePointer() const {
|
|
return Tag() == TD_INTERFACE_TYPE || Tag() == TD_INTERFACE_IS_TYPE;
|
|
}
|
|
|
|
bool IsDependent() const {
|
|
return (Tag() == TD_ARRAY && InnermostType().IsDependent()) ||
|
|
Tag() == TD_INTERFACE_IS_TYPE || Tag() == TD_LEGACY_ARRAY ||
|
|
Tag() == TD_PSTRING_SIZE_IS || Tag() == TD_PWSTRING_SIZE_IS;
|
|
}
|
|
|
|
// Unwrap a nested type to its innermost value (e.g. through arrays).
|
|
const nsXPTType& InnermostType() const {
|
|
if (Tag() == TD_LEGACY_ARRAY || Tag() == TD_ARRAY) {
|
|
return ArrayElementType().InnermostType();
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
// In-memory size of native type in bytes.
|
|
inline size_t Stride() const;
|
|
|
|
// Offset the given base pointer to reference the element at the given index.
|
|
void* ElementPtr(const void* aBase, uint32_t aIndex) const {
|
|
return (char*)aBase + (aIndex * Stride());
|
|
}
|
|
|
|
// Zero out a native value of the given type. The type must not be 'complex'.
|
|
void ZeroValue(void* aValue) const {
|
|
MOZ_RELEASE_ASSERT(!IsComplex(), "Cannot zero a complex value");
|
|
memset(aValue, 0, Stride());
|
|
}
|
|
|
|
// Indexes into the extra types array of a small set of known types.
|
|
enum class Idx : uint8_t
|
|
{
|
|
INT8 = 0,
|
|
UINT8,
|
|
INT16,
|
|
UINT16,
|
|
INT32,
|
|
UINT32,
|
|
INT64,
|
|
UINT64,
|
|
FLOAT,
|
|
DOUBLE,
|
|
BOOL,
|
|
CHAR,
|
|
WCHAR,
|
|
PNSIID,
|
|
PSTRING,
|
|
PWSTRING,
|
|
INTERFACE_IS_TYPE
|
|
};
|
|
|
|
// Helper methods for fabricating nsXPTType values used by xpconnect.
|
|
static nsXPTType MkArrayType(Idx aInner) {
|
|
MOZ_ASSERT(aInner <= Idx::INTERFACE_IS_TYPE);
|
|
return { TD_LEGACY_ARRAY, false, false, false, 0, (uint8_t)aInner };
|
|
}
|
|
static const nsXPTType& Get(Idx aInner) {
|
|
MOZ_ASSERT(aInner <= Idx::INTERFACE_IS_TYPE);
|
|
return xpt::detail::GetType((uint8_t)aInner);
|
|
}
|
|
|
|
///////////////////////////////////////
|
|
// nsXPTType backwards compatibility //
|
|
///////////////////////////////////////
|
|
|
|
nsXPTType& operator=(nsXPTTypeTag aPrefix) { mTag = aPrefix; return *this; }
|
|
operator nsXPTTypeTag() const { return Tag(); }
|
|
|
|
#define TD_ALIAS_(name_, value_) static constexpr nsXPTTypeTag name_ = value_
|
|
TD_ALIAS_(T_I8 , TD_INT8 );
|
|
TD_ALIAS_(T_I16 , TD_INT16 );
|
|
TD_ALIAS_(T_I32 , TD_INT32 );
|
|
TD_ALIAS_(T_I64 , TD_INT64 );
|
|
TD_ALIAS_(T_U8 , TD_UINT8 );
|
|
TD_ALIAS_(T_U16 , TD_UINT16 );
|
|
TD_ALIAS_(T_U32 , TD_UINT32 );
|
|
TD_ALIAS_(T_U64 , TD_UINT64 );
|
|
TD_ALIAS_(T_FLOAT , TD_FLOAT );
|
|
TD_ALIAS_(T_DOUBLE , TD_DOUBLE );
|
|
TD_ALIAS_(T_BOOL , TD_BOOL );
|
|
TD_ALIAS_(T_CHAR , TD_CHAR );
|
|
TD_ALIAS_(T_WCHAR , TD_WCHAR );
|
|
TD_ALIAS_(T_VOID , TD_VOID );
|
|
TD_ALIAS_(T_IID , TD_PNSIID );
|
|
TD_ALIAS_(T_DOMSTRING , TD_DOMSTRING );
|
|
TD_ALIAS_(T_CHAR_STR , TD_PSTRING );
|
|
TD_ALIAS_(T_WCHAR_STR , TD_PWSTRING );
|
|
TD_ALIAS_(T_INTERFACE , TD_INTERFACE_TYPE );
|
|
TD_ALIAS_(T_INTERFACE_IS , TD_INTERFACE_IS_TYPE);
|
|
TD_ALIAS_(T_LEGACY_ARRAY , TD_LEGACY_ARRAY );
|
|
TD_ALIAS_(T_PSTRING_SIZE_IS , TD_PSTRING_SIZE_IS );
|
|
TD_ALIAS_(T_PWSTRING_SIZE_IS , TD_PWSTRING_SIZE_IS );
|
|
TD_ALIAS_(T_UTF8STRING , TD_UTF8STRING );
|
|
TD_ALIAS_(T_CSTRING , TD_CSTRING );
|
|
TD_ALIAS_(T_ASTRING , TD_ASTRING );
|
|
TD_ALIAS_(T_JSVAL , TD_JSVAL );
|
|
TD_ALIAS_(T_DOMOBJECT , TD_DOMOBJECT );
|
|
TD_ALIAS_(T_PROMISE , TD_PROMISE );
|
|
TD_ALIAS_(T_ARRAY , TD_ARRAY );
|
|
#undef TD_ALIAS_
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Ensure these fields are in the same order as xptcodegen.py //
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
uint8_t mTag : 5;
|
|
|
|
// Parameter bitflags are packed into the XPTTypeDescriptor to save space.
|
|
// When the TypeDescriptor is not in a parameter, these flags are ignored.
|
|
uint8_t mInParam : 1;
|
|
uint8_t mOutParam : 1;
|
|
uint8_t mOptionalParam : 1;
|
|
|
|
// The data for the different variants is stored in these two data fields.
|
|
// These should only be accessed via the getter methods above, which will
|
|
// assert if the tag is invalid.
|
|
uint8_t mData1;
|
|
uint8_t mData2;
|
|
};
|
|
|
|
// The fields in nsXPTType were carefully ordered to minimize size.
|
|
static_assert(sizeof(nsXPTType) == 3, "wrong size");
|
|
|
|
|
|
/*
|
|
* A nsXPTParamInfo is used to describe either a single argument to a method or
|
|
* a method's result. It stores its flags in the type descriptor to save space.
|
|
*/
|
|
struct nsXPTParamInfo
|
|
{
|
|
bool IsIn() const { return mType.mInParam; }
|
|
bool IsOut() const { return mType.mOutParam; }
|
|
bool IsOptional() const { return mType.mOptionalParam; }
|
|
bool IsShared() const { return false; } // XXX remove (backcompat)
|
|
|
|
// Get the type of this parameter.
|
|
const nsXPTType& Type() const { return mType; }
|
|
const nsXPTType& GetType() const { return Type(); } // XXX remove (backcompat)
|
|
|
|
// Whether this parameter is passed indirectly on the stack. All out/inout
|
|
// params are passed indirectly, and complex types are always passed
|
|
// indirectly.
|
|
bool IsIndirect() const {
|
|
return IsOut() || Type().IsComplex();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Ensure these fields are in the same order as xptcodegen.py //
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
nsXPTType mType;
|
|
};
|
|
|
|
// The fields in nsXPTParamInfo were carefully ordered to minimize size.
|
|
static_assert(sizeof(nsXPTParamInfo) == 3, "wrong size");
|
|
|
|
/*
|
|
* A nsXPTMethodInfo is used to describe a single interface method.
|
|
*/
|
|
struct nsXPTMethodInfo
|
|
{
|
|
bool IsGetter() const { return mGetter; }
|
|
bool IsSetter() const { return mSetter; }
|
|
bool IsNotXPCOM() const { return mNotXPCOM; }
|
|
bool IsHidden() const { return mHidden; }
|
|
bool WantsOptArgc() const { return mOptArgc; }
|
|
bool WantsContext() const { return mContext; }
|
|
uint8_t ParamCount() const { return mNumParams; }
|
|
|
|
const char* Name() const {
|
|
return xpt::detail::GetString(mName);
|
|
}
|
|
const nsXPTParamInfo& Param(uint8_t aIndex) const {
|
|
MOZ_ASSERT(aIndex < mNumParams);
|
|
return xpt::detail::GetParam(mParams + aIndex);
|
|
}
|
|
|
|
bool HasRetval() const { return mHasRetval; }
|
|
const nsXPTParamInfo* GetRetval() const {
|
|
return mHasRetval ? &Param(mNumParams - 1) : nullptr;
|
|
}
|
|
|
|
// If this is an [implicit_jscontext] method, returns the index of the
|
|
// implicit JSContext* argument in the C++ method's argument list.
|
|
// Otherwise returns UINT8_MAX.
|
|
uint8_t IndexOfJSContext() const {
|
|
if (!WantsContext()) {
|
|
return UINT8_MAX;
|
|
}
|
|
if (IsGetter() || IsSetter()) {
|
|
// Getters/setters always have the context as first argument.
|
|
return 0;
|
|
}
|
|
// The context comes before the return value, if there is one.
|
|
MOZ_ASSERT_IF(HasRetval(), ParamCount() > 0);
|
|
return ParamCount() - uint8_t(HasRetval());
|
|
}
|
|
|
|
/////////////////////////////////////////////
|
|
// nsXPTMethodInfo backwards compatibility //
|
|
/////////////////////////////////////////////
|
|
|
|
const char* GetName() const { return Name(); }
|
|
uint8_t GetParamCount() const { return ParamCount(); }
|
|
const nsXPTParamInfo& GetParam(uint8_t aIndex) const {
|
|
return Param(aIndex);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Ensure these fields are in the same order as xptcodegen.py //
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
uint32_t mName; // Index into xpt::detail::sStrings.
|
|
uint16_t mParams; // Index into xpt::detail::sParams.
|
|
uint8_t mNumParams;
|
|
|
|
uint8_t mGetter : 1;
|
|
uint8_t mSetter : 1;
|
|
uint8_t mNotXPCOM : 1;
|
|
uint8_t mHidden : 1;
|
|
uint8_t mOptArgc : 1;
|
|
uint8_t mContext : 1;
|
|
uint8_t mHasRetval : 1;
|
|
// uint8_t unused : 1;
|
|
};
|
|
|
|
// The fields in nsXPTMethodInfo were carefully ordered to minimize size.
|
|
static_assert(sizeof(nsXPTMethodInfo) == 8, "wrong size");
|
|
|
|
/**
|
|
* A nsXPTConstantInfo is used to describe a single interface constant.
|
|
*/
|
|
struct nsXPTConstantInfo
|
|
{
|
|
const char* Name() const {
|
|
return xpt::detail::GetString(mName);
|
|
}
|
|
|
|
JS::Value JSValue() const {
|
|
if (mSigned || mValue <= uint32_t(INT32_MAX)) {
|
|
return JS::Int32Value(int32_t(mValue));
|
|
}
|
|
return JS::DoubleValue(mValue);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Ensure these fields are in the same order as xptcodegen.py //
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
uint32_t mName : 31; // Index into xpt::detail::mStrings.
|
|
|
|
// Whether the value should be interpreted as a int32_t or uint32_t.
|
|
uint32_t mSigned: 1;
|
|
uint32_t mValue; // The value stored as a u32
|
|
};
|
|
|
|
// The fields in nsXPTConstantInfo were carefully ordered to minimize size.
|
|
static_assert(sizeof(nsXPTConstantInfo) == 8, "wrong size");
|
|
|
|
/**
|
|
* Object representing the information required to wrap and unwrap DOMObjects.
|
|
*
|
|
* This object will not live in rodata as it contains relocations.
|
|
*/
|
|
struct nsXPTDOMObjectInfo
|
|
{
|
|
nsresult Unwrap(JS::HandleValue aHandle, void** aObj) const {
|
|
return mUnwrap(aHandle, aObj);
|
|
}
|
|
|
|
bool Wrap(JSContext* aCx, void* aObj, JS::MutableHandleValue aHandle) const {
|
|
return mWrap(aCx, aObj, aHandle);
|
|
}
|
|
|
|
void Cleanup(void* aObj) const {
|
|
return mCleanup(aObj);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
// Ensure these fields are in the same order as xptcodegen.py //
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
nsresult (*mUnwrap) (JS::HandleValue aHandle, void** aObj);
|
|
bool (*mWrap) (JSContext* aCx, void* aObj, JS::MutableHandleValue aHandle);
|
|
void (*mCleanup) (void* aObj);
|
|
};
|
|
|
|
|
|
namespace xpt {
|
|
namespace detail {
|
|
|
|
// The UntypedTArray type allows low-level access from XPConnect to nsTArray
|
|
// internals without static knowledge of the array element type in question.
|
|
class UntypedTArray
|
|
: public nsTArray_base<nsTArrayFallibleAllocator, nsTArray_CopyWithMemutils>
|
|
{
|
|
public:
|
|
void* Elements() const {
|
|
return static_cast<void*>(Hdr() + 1);
|
|
}
|
|
|
|
// Changes the length and capacity to be at least large enough for aTo elements.
|
|
bool SetLength(const nsXPTType& aEltTy, uint32_t aTo) {
|
|
if (!EnsureCapacity<nsTArrayFallibleAllocator>(aTo, aEltTy.Stride())) {
|
|
return false;
|
|
}
|
|
mHdr->mLength = aTo;
|
|
return true;
|
|
}
|
|
|
|
// Free backing memory for the nsTArray object.
|
|
void Clear() {
|
|
if (mHdr != EmptyHdr() && !UsesAutoArrayBuffer()) {
|
|
nsTArrayFallibleAllocator::Free(mHdr);
|
|
}
|
|
mHdr = EmptyHdr();
|
|
}
|
|
};
|
|
|
|
|
|
//////////////////////////////////////////////
|
|
// Raw typelib data stored in const statics //
|
|
//////////////////////////////////////////////
|
|
|
|
// XPIDL information
|
|
extern const nsXPTInterfaceInfo sInterfaces[];
|
|
extern const nsXPTType sTypes[];
|
|
extern const nsXPTParamInfo sParams[];
|
|
extern const nsXPTMethodInfo sMethods[];
|
|
extern const nsXPTConstantInfo sConsts[];
|
|
extern const nsXPTDOMObjectInfo sDOMObjects[];
|
|
|
|
extern const char sStrings[];
|
|
|
|
|
|
//////////////////////////////////////
|
|
// Helper Methods for fetching data //
|
|
//////////////////////////////////////
|
|
|
|
inline const nsXPTInterfaceInfo*
|
|
GetInterface(uint16_t aIndex)
|
|
{
|
|
if (aIndex > 0 && aIndex <= sInterfacesSize) {
|
|
return &sInterfaces[aIndex - 1]; // 1-based as 0 is a marker.
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
inline const nsXPTType&
|
|
GetType(uint16_t aIndex)
|
|
{
|
|
return sTypes[aIndex];
|
|
}
|
|
|
|
inline const nsXPTParamInfo&
|
|
GetParam(uint16_t aIndex)
|
|
{
|
|
return sParams[aIndex];
|
|
}
|
|
|
|
inline const nsXPTMethodInfo&
|
|
GetMethod(uint16_t aIndex)
|
|
{
|
|
return sMethods[aIndex];
|
|
}
|
|
|
|
inline const nsXPTConstantInfo&
|
|
GetConstant(uint16_t aIndex)
|
|
{
|
|
return sConsts[aIndex];
|
|
}
|
|
|
|
inline const nsXPTDOMObjectInfo&
|
|
GetDOMObjectInfo(uint16_t aIndex)
|
|
{
|
|
return sDOMObjects[aIndex];
|
|
}
|
|
|
|
inline const char*
|
|
GetString(uint32_t aIndex)
|
|
{
|
|
return &sStrings[aIndex];
|
|
}
|
|
|
|
} // namespace detail
|
|
} // namespace xpt
|
|
|
|
#define XPT_FOR_EACH_ARITHMETIC_TYPE(macro) \
|
|
macro(TD_INT8, int8_t) \
|
|
macro(TD_INT16, int16_t) \
|
|
macro(TD_INT32, int32_t) \
|
|
macro(TD_INT64, int64_t) \
|
|
macro(TD_UINT8, uint8_t) \
|
|
macro(TD_UINT16, uint16_t) \
|
|
macro(TD_UINT32, uint32_t) \
|
|
macro(TD_UINT64, uint64_t) \
|
|
macro(TD_FLOAT, float) \
|
|
macro(TD_DOUBLE, double) \
|
|
macro(TD_BOOL, bool) \
|
|
macro(TD_CHAR, char) \
|
|
macro(TD_WCHAR, char16_t)
|
|
|
|
#define XPT_FOR_EACH_POINTER_TYPE(macro) \
|
|
macro(TD_VOID, void*) \
|
|
macro(TD_PNSIID, nsID*) \
|
|
macro(TD_PSTRING, char*) \
|
|
macro(TD_PWSTRING, wchar_t*) \
|
|
macro(TD_INTERFACE_TYPE, nsISupports*) \
|
|
macro(TD_INTERFACE_IS_TYPE, nsISupports*) \
|
|
macro(TD_LEGACY_ARRAY, void*) \
|
|
macro(TD_PSTRING_SIZE_IS, char*) \
|
|
macro(TD_PWSTRING_SIZE_IS, wchar_t*) \
|
|
macro(TD_DOMOBJECT, void*) \
|
|
macro(TD_PROMISE, mozilla::dom::Promise*)
|
|
|
|
#define XPT_FOR_EACH_COMPLEX_TYPE(macro) \
|
|
macro(TD_DOMSTRING, nsString) \
|
|
macro(TD_UTF8STRING, nsCString) \
|
|
macro(TD_CSTRING, nsCString) \
|
|
macro(TD_ASTRING, nsString) \
|
|
macro(TD_JSVAL, JS::Value) \
|
|
macro(TD_ARRAY, xpt::detail::UntypedTArray)
|
|
|
|
#define XPT_FOR_EACH_TYPE(macro) \
|
|
XPT_FOR_EACH_ARITHMETIC_TYPE(macro) \
|
|
XPT_FOR_EACH_POINTER_TYPE(macro) \
|
|
XPT_FOR_EACH_COMPLEX_TYPE(macro)
|
|
|
|
inline size_t
|
|
nsXPTType::Stride() const
|
|
{
|
|
// Compute the stride to use when walking an array of the given type.
|
|
switch (Tag()) {
|
|
#define XPT_TYPE_STRIDE(tag, type) case tag: return sizeof(type);
|
|
XPT_FOR_EACH_TYPE(XPT_TYPE_STRIDE)
|
|
#undef XPT_TYPE_STRIDE
|
|
}
|
|
|
|
MOZ_CRASH("Unknown type");
|
|
}
|
|
|
|
#endif /* xptinfo_h */
|