/work/obj-fuzz/dist/include/xptinfo.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | /** |
8 | | * Structures and methods with information about XPCOM interfaces for use by |
9 | | * XPConnect. The static backing data structures used by this file are generated |
10 | | * from xpidl interfaces by the jsonxpt.py and xptcodegen.py scripts. |
11 | | */ |
12 | | |
13 | | #ifndef xptinfo_h |
14 | | #define xptinfo_h |
15 | | |
16 | | #include <stdint.h> |
17 | | #include "nsID.h" |
18 | | #include "mozilla/Assertions.h" |
19 | | #include "jsapi.h" |
20 | | #include "js/Value.h" |
21 | | #include "nsString.h" |
22 | | #include "nsTArray.h" |
23 | | |
24 | | // Forward Declarations |
25 | | namespace mozilla { |
26 | | namespace dom { |
27 | | struct NativePropertyHooks; |
28 | | } // namespace dom |
29 | | } // namespace mozilla |
30 | | |
31 | | struct nsXPTInterfaceInfo; |
32 | | struct nsXPTType; |
33 | | struct nsXPTParamInfo; |
34 | | struct nsXPTMethodInfo; |
35 | | struct nsXPTConstantInfo; |
36 | | struct nsXPTDOMObjectInfo; |
37 | | |
38 | | // Internal helper methods. |
39 | | namespace xpt { |
40 | | namespace detail { |
41 | | |
42 | | inline const nsXPTInterfaceInfo* GetInterface(uint16_t aIndex); |
43 | | inline const nsXPTType& GetType(uint16_t aIndex); |
44 | | inline const nsXPTParamInfo& GetParam(uint16_t aIndex); |
45 | | inline const nsXPTMethodInfo& GetMethod(uint16_t aIndex); |
46 | | inline const nsXPTConstantInfo& GetConstant(uint16_t aIndex); |
47 | | inline const nsXPTDOMObjectInfo& GetDOMObjectInfo(uint16_t aIndex); |
48 | | inline const char* GetString(uint32_t aIndex); |
49 | | |
50 | | const nsXPTInterfaceInfo* InterfaceByIID(const nsIID& aIID); |
51 | | const nsXPTInterfaceInfo* InterfaceByName(const char* aName); |
52 | | |
53 | | extern const uint16_t sInterfacesSize; |
54 | | |
55 | | } // namespace detail |
56 | | } // namespace xpt |
57 | | |
58 | | |
59 | | /* |
60 | | * An Interface describes a single XPCOM interface, including all of its |
61 | | * methods. We don't record non-scriptable interfaces. |
62 | | */ |
63 | | struct nsXPTInterfaceInfo |
64 | | { |
65 | | // High efficiency getters for Interfaces based on perfect hashes. |
66 | 50 | static const nsXPTInterfaceInfo* ByIID(const nsIID& aIID) { |
67 | 50 | return xpt::detail::InterfaceByIID(aIID); |
68 | 50 | } |
69 | 6 | static const nsXPTInterfaceInfo* ByName(const char* aName) { |
70 | 6 | return xpt::detail::InterfaceByName(aName); |
71 | 6 | } |
72 | | |
73 | | // These are only needed for Components_interfaces's enumerator. |
74 | 0 | static const nsXPTInterfaceInfo* ByIndex(uint16_t aIndex) { |
75 | 0 | // NOTE: We add 1 here, as the internal index 0 is reserved for null. |
76 | 0 | return xpt::detail::GetInterface(aIndex + 1); |
77 | 0 | } |
78 | 0 | static uint16_t InterfaceCount() { return xpt::detail::sInterfacesSize; } |
79 | | |
80 | | |
81 | | // Interface flag getters |
82 | | bool IsScriptable() const { return true; } // XXX remove (bug 1480245) |
83 | | bool IsFunction() const { return mFunction; } |
84 | | bool IsBuiltinClass() const { return mBuiltinClass; } |
85 | | bool IsMainProcessScriptableOnly() const { return mMainProcessScriptableOnly; } |
86 | | |
87 | | const char* Name() const { return xpt::detail::GetString(mName); } |
88 | | const nsIID& IID() const { return mIID; } |
89 | | |
90 | | // Get the parent interface, or null if this interface doesn't have a parent. |
91 | | const nsXPTInterfaceInfo* GetParent() const { |
92 | | return xpt::detail::GetInterface(mParent); |
93 | | } |
94 | | |
95 | | // Do we have an ancestor interface with the given IID? |
96 | | bool HasAncestor(const nsIID& aIID) const; |
97 | | |
98 | | // Get methods & constants |
99 | | uint16_t ConstantCount() const { return mNumConsts; } |
100 | | const nsXPTConstantInfo& Constant(uint16_t aIndex) const; |
101 | | uint16_t MethodCount() const { return mNumMethods; } |
102 | | const nsXPTMethodInfo& Method(uint16_t aIndex) const; |
103 | | |
104 | | |
105 | | //////////////////////////////////////////////////////////// |
106 | | // nsIInterfaceInfo backwards compatibility (bug 1480245) // |
107 | | //////////////////////////////////////////////////////////// |
108 | | |
109 | | nsresult GetName(char** aName) const; |
110 | | nsresult IsScriptable(bool* aRes) const; |
111 | | nsresult IsBuiltinClass(bool* aRes) const; |
112 | | nsresult GetParent(const nsXPTInterfaceInfo** aParent) const; |
113 | | nsresult GetMethodCount(uint16_t* aMethodCount) const; |
114 | | nsresult GetConstantCount(uint16_t* aConstantCount) const; |
115 | | nsresult GetMethodInfo(uint16_t aIndex, const nsXPTMethodInfo** aInfo) const; |
116 | | nsresult GetConstant(uint16_t aIndex, |
117 | | JS::MutableHandleValue constant, |
118 | | char** aName) const; |
119 | | nsresult IsIID(const nsIID* aIID, bool* aIs) const; |
120 | | nsresult GetNameShared(const char** aName) const; |
121 | | nsresult GetIIDShared(const nsIID** aIID) const; |
122 | | nsresult IsFunction(bool* aRetval) const; |
123 | | nsresult HasAncestor(const nsIID* aIID, bool* aRetval) const; |
124 | | nsresult IsMainProcessScriptableOnly(bool* aRetval) const; |
125 | | |
126 | 3 | bool EnsureResolved() const { return true; } // XXX: Remove (bug 1480245) |
127 | | |
128 | | //////////////////////////////////////////////////////////////// |
129 | | // Ensure these fields are in the same order as xptcodegen.py // |
130 | | //////////////////////////////////////////////////////////////// |
131 | | |
132 | | nsID mIID; |
133 | | uint32_t mName; // Index into xpt::detail::sStrings |
134 | | |
135 | | uint16_t mParent : 14; |
136 | | uint16_t mBuiltinClass : 1; |
137 | | // XXX(nika): Do we need this if we don't have addons anymore? |
138 | | uint16_t mMainProcessScriptableOnly : 1; |
139 | | |
140 | | uint16_t mMethods; // Index into xpt::detail::sMethods |
141 | | |
142 | | uint16_t mConsts : 14; // Index into xpt::detail::sConsts |
143 | | uint16_t mFunction : 1; |
144 | | // uint16_t unused : 1; |
145 | | |
146 | | uint8_t mNumMethods; // NOTE(24/04/18): largest=nsIDocShell (193) |
147 | | uint8_t mNumConsts; // NOTE(24/04/18): largest=nsIAccessibleRole (175) |
148 | | }; |
149 | | |
150 | | // The fields in nsXPTInterfaceInfo were carefully ordered to minimize size. |
151 | | static_assert(sizeof(nsXPTInterfaceInfo) == 28, "wrong size?"); |
152 | | |
153 | | |
154 | | /* |
155 | | * The following enum represents contains the different tag types which |
156 | | * can be found in nsXPTTypeInfo::mTag. |
157 | | * |
158 | | * WARNING: mTag is 5 bits wide, supporting at most 32 tags. |
159 | | */ |
160 | | enum nsXPTTypeTag : uint8_t |
161 | | { |
162 | | // Arithmetic (POD) Types |
163 | | // - Do not require cleanup, |
164 | | // - All bit patterns are valid, |
165 | | // - Outparams may be uninitialized by caller, |
166 | | // - Directly supported in xptcall. |
167 | | // |
168 | | // NOTE: The name 'Arithmetic' comes from Harbison/Steele. Despite being a tad |
169 | | // unclear, it is used frequently in xptcall, so is unlikely to be changed. |
170 | | TD_INT8 = 0, |
171 | | TD_INT16 = 1, |
172 | | TD_INT32 = 2, |
173 | | TD_INT64 = 3, |
174 | | TD_UINT8 = 4, |
175 | | TD_UINT16 = 5, |
176 | | TD_UINT32 = 6, |
177 | | TD_UINT64 = 7, |
178 | | TD_FLOAT = 8, |
179 | | TD_DOUBLE = 9, |
180 | | TD_BOOL = 10, |
181 | | TD_CHAR = 11, |
182 | | TD_WCHAR = 12, |
183 | | _TD_LAST_ARITHMETIC = TD_WCHAR, |
184 | | |
185 | | // Pointer Types |
186 | | // - Require cleanup unless NULL, |
187 | | // - All-zeros (NULL) bit pattern is valid, |
188 | | // - Outparams may be uninitialized by caller, |
189 | | // - Supported in xptcall as raw pointer. |
190 | | TD_VOID = 13, |
191 | | TD_PNSIID = 14, |
192 | | TD_PSTRING = 15, |
193 | | TD_PWSTRING = 16, |
194 | | TD_INTERFACE_TYPE = 17, |
195 | | TD_INTERFACE_IS_TYPE = 18, |
196 | | TD_LEGACY_ARRAY = 19, |
197 | | TD_PSTRING_SIZE_IS = 20, |
198 | | TD_PWSTRING_SIZE_IS = 21, |
199 | | TD_DOMOBJECT = 22, |
200 | | TD_PROMISE = 23, |
201 | | _TD_LAST_POINTER = TD_PROMISE, |
202 | | |
203 | | // Complex Types |
204 | | // - Require cleanup, |
205 | | // - Always passed indirectly, |
206 | | // - Outparams must be initialized by caller, |
207 | | // - Supported in xptcall due to indirection. |
208 | | TD_DOMSTRING = 24, |
209 | | TD_UTF8STRING = 25, |
210 | | TD_CSTRING = 26, |
211 | | TD_ASTRING = 27, |
212 | | TD_JSVAL = 28, |
213 | | TD_ARRAY = 29, |
214 | | _TD_LAST_COMPLEX = TD_ARRAY |
215 | | }; |
216 | | |
217 | | static_assert(_TD_LAST_COMPLEX < 32, "nsXPTTypeTag must fit in 5 bits"); |
218 | | |
219 | | |
220 | | /* |
221 | | * A nsXPTType is a union used to identify the type of a method argument or |
222 | | * return value. The internal data is stored as an 5-bit tag, and two 8-bit |
223 | | * integers, to keep alignment requirements low. |
224 | | * |
225 | | * nsXPTType contains 3 extra bits, reserved for use by nsXPTParamInfo. |
226 | | */ |
227 | | struct nsXPTType |
228 | | { |
229 | 383M | nsXPTTypeTag Tag() const { return static_cast<nsXPTTypeTag>(mTag); } |
230 | | |
231 | | // The index in the function argument list which should be used when |
232 | | // determining the iid_is or size_is properties of this dependent type. |
233 | 2 | uint8_t ArgNum() const { |
234 | 2 | MOZ_ASSERT(Tag() == TD_INTERFACE_IS_TYPE || |
235 | 2 | Tag() == TD_PSTRING_SIZE_IS || |
236 | 2 | Tag() == TD_PWSTRING_SIZE_IS || |
237 | 2 | Tag() == TD_LEGACY_ARRAY); |
238 | 2 | return mData1; |
239 | 2 | } |
240 | | |
241 | | private: |
242 | | // Helper for reading 16-bit data values split between mData1 and mData2. |
243 | 12.9M | uint16_t Data16() const { return ((uint16_t)mData1 << 8) | mData2; } |
244 | | |
245 | | public: |
246 | | // Get the type of the element in the current array or sequence. Arrays only |
247 | | // fit 8 bits of type data, while sequences support up to 16 bits of type data |
248 | | // due to not needing to store an ArgNum. |
249 | 0 | const nsXPTType& ArrayElementType() const { |
250 | 0 | if (Tag() == TD_LEGACY_ARRAY) { |
251 | 0 | return xpt::detail::GetType(mData2); |
252 | 0 | } |
253 | 0 | MOZ_ASSERT(Tag() == TD_ARRAY); |
254 | 0 | return xpt::detail::GetType(Data16()); |
255 | 0 | } |
256 | | |
257 | | // We store the 16-bit iface value as two 8-bit values in order to |
258 | | // avoid 16-bit alignment requirements for XPTTypeDescriptor, which |
259 | | // reduces its size and also the size of XPTParamDescriptor. |
260 | 12.9M | const nsXPTInterfaceInfo* GetInterface() const { |
261 | 12.9M | MOZ_ASSERT(Tag() == TD_INTERFACE_TYPE); |
262 | 12.9M | return xpt::detail::GetInterface(Data16()); |
263 | 12.9M | } |
264 | | |
265 | 0 | const nsXPTDOMObjectInfo& GetDOMObjectInfo() const { |
266 | 0 | MOZ_ASSERT(Tag() == TD_DOMOBJECT); |
267 | 0 | return xpt::detail::GetDOMObjectInfo(Data16()); |
268 | 0 | } |
269 | | |
270 | | // See the comments in nsXPTTypeTag for an explanation as to what each of |
271 | | // these categories mean. |
272 | 32.4M | bool IsArithmetic() const { return Tag() <= _TD_LAST_ARITHMETIC; } |
273 | 12.9M | bool IsPointer() const { return !IsArithmetic() && Tag() <= _TD_LAST_POINTER; } |
274 | 35.7M | bool IsComplex() const { return Tag() > _TD_LAST_POINTER; } |
275 | | |
276 | 0 | bool IsInterfacePointer() const { |
277 | 0 | return Tag() == TD_INTERFACE_TYPE || Tag() == TD_INTERFACE_IS_TYPE; |
278 | 0 | } |
279 | | |
280 | 12.9M | bool IsDependent() const { |
281 | 12.9M | return (Tag() == TD_ARRAY && InnermostType().IsDependent()) || |
282 | 12.9M | Tag() == TD_INTERFACE_IS_TYPE || Tag() == TD_LEGACY_ARRAY || |
283 | 12.9M | Tag() == TD_PSTRING_SIZE_IS || Tag() == TD_PWSTRING_SIZE_IS; |
284 | 12.9M | } |
285 | | |
286 | | // Unwrap a nested type to its innermost value (e.g. through arrays). |
287 | 17.8M | const nsXPTType& InnermostType() const { |
288 | 17.8M | if (Tag() == TD_LEGACY_ARRAY || Tag() == TD_ARRAY) { |
289 | 0 | return ArrayElementType().InnermostType(); |
290 | 0 | } |
291 | 17.8M | return *this; |
292 | 17.8M | } |
293 | | |
294 | | // In-memory size of native type in bytes. |
295 | | inline size_t Stride() const; |
296 | | |
297 | | // Offset the given base pointer to reference the element at the given index. |
298 | 0 | void* ElementPtr(const void* aBase, uint32_t aIndex) const { |
299 | 0 | return (char*)aBase + (aIndex * Stride()); |
300 | 0 | } |
301 | | |
302 | | // Zero out a native value of the given type. The type must not be 'complex'. |
303 | 9.74M | void ZeroValue(void* aValue) const { |
304 | 9.74M | MOZ_RELEASE_ASSERT(!IsComplex(), "Cannot zero a complex value"); |
305 | 9.74M | memset(aValue, 0, Stride()); |
306 | 9.74M | } |
307 | | |
308 | | // Indexes into the extra types array of a small set of known types. |
309 | | enum class Idx : uint8_t |
310 | | { |
311 | | INT8 = 0, |
312 | | UINT8, |
313 | | INT16, |
314 | | UINT16, |
315 | | INT32, |
316 | | UINT32, |
317 | | INT64, |
318 | | UINT64, |
319 | | FLOAT, |
320 | | DOUBLE, |
321 | | BOOL, |
322 | | CHAR, |
323 | | WCHAR, |
324 | | PNSIID, |
325 | | PSTRING, |
326 | | PWSTRING, |
327 | | INTERFACE_IS_TYPE |
328 | | }; |
329 | | |
330 | | // Helper methods for fabricating nsXPTType values used by xpconnect. |
331 | 0 | static nsXPTType MkArrayType(Idx aInner) { |
332 | 0 | MOZ_ASSERT(aInner <= Idx::INTERFACE_IS_TYPE); |
333 | 0 | return { TD_LEGACY_ARRAY, false, false, false, 0, (uint8_t)aInner }; |
334 | 0 | } |
335 | 0 | static const nsXPTType& Get(Idx aInner) { |
336 | 0 | MOZ_ASSERT(aInner <= Idx::INTERFACE_IS_TYPE); |
337 | 0 | return xpt::detail::GetType((uint8_t)aInner); |
338 | 0 | } |
339 | | |
340 | | /////////////////////////////////////// |
341 | | // nsXPTType backwards compatibility // |
342 | | /////////////////////////////////////// |
343 | | |
344 | 17.8M | nsXPTType& operator=(nsXPTTypeTag aPrefix) { mTag = aPrefix; return *this; } |
345 | 19.4M | operator nsXPTTypeTag() const { return Tag(); } |
346 | | |
347 | | #define TD_ALIAS_(name_, value_) static constexpr nsXPTTypeTag name_ = value_ |
348 | | TD_ALIAS_(T_I8 , TD_INT8 ); |
349 | | TD_ALIAS_(T_I16 , TD_INT16 ); |
350 | | TD_ALIAS_(T_I32 , TD_INT32 ); |
351 | | TD_ALIAS_(T_I64 , TD_INT64 ); |
352 | | TD_ALIAS_(T_U8 , TD_UINT8 ); |
353 | | TD_ALIAS_(T_U16 , TD_UINT16 ); |
354 | | TD_ALIAS_(T_U32 , TD_UINT32 ); |
355 | | TD_ALIAS_(T_U64 , TD_UINT64 ); |
356 | | TD_ALIAS_(T_FLOAT , TD_FLOAT ); |
357 | | TD_ALIAS_(T_DOUBLE , TD_DOUBLE ); |
358 | | TD_ALIAS_(T_BOOL , TD_BOOL ); |
359 | | TD_ALIAS_(T_CHAR , TD_CHAR ); |
360 | | TD_ALIAS_(T_WCHAR , TD_WCHAR ); |
361 | | TD_ALIAS_(T_VOID , TD_VOID ); |
362 | | TD_ALIAS_(T_IID , TD_PNSIID ); |
363 | | TD_ALIAS_(T_DOMSTRING , TD_DOMSTRING ); |
364 | | TD_ALIAS_(T_CHAR_STR , TD_PSTRING ); |
365 | | TD_ALIAS_(T_WCHAR_STR , TD_PWSTRING ); |
366 | | TD_ALIAS_(T_INTERFACE , TD_INTERFACE_TYPE ); |
367 | | TD_ALIAS_(T_INTERFACE_IS , TD_INTERFACE_IS_TYPE); |
368 | | TD_ALIAS_(T_LEGACY_ARRAY , TD_LEGACY_ARRAY ); |
369 | | TD_ALIAS_(T_PSTRING_SIZE_IS , TD_PSTRING_SIZE_IS ); |
370 | | TD_ALIAS_(T_PWSTRING_SIZE_IS , TD_PWSTRING_SIZE_IS ); |
371 | | TD_ALIAS_(T_UTF8STRING , TD_UTF8STRING ); |
372 | | TD_ALIAS_(T_CSTRING , TD_CSTRING ); |
373 | | TD_ALIAS_(T_ASTRING , TD_ASTRING ); |
374 | | TD_ALIAS_(T_JSVAL , TD_JSVAL ); |
375 | | TD_ALIAS_(T_DOMOBJECT , TD_DOMOBJECT ); |
376 | | TD_ALIAS_(T_PROMISE , TD_PROMISE ); |
377 | | TD_ALIAS_(T_ARRAY , TD_ARRAY ); |
378 | | #undef TD_ALIAS_ |
379 | | |
380 | | //////////////////////////////////////////////////////////////// |
381 | | // Ensure these fields are in the same order as xptcodegen.py // |
382 | | //////////////////////////////////////////////////////////////// |
383 | | |
384 | | uint8_t mTag : 5; |
385 | | |
386 | | // Parameter bitflags are packed into the XPTTypeDescriptor to save space. |
387 | | // When the TypeDescriptor is not in a parameter, these flags are ignored. |
388 | | uint8_t mInParam : 1; |
389 | | uint8_t mOutParam : 1; |
390 | | uint8_t mOptionalParam : 1; |
391 | | |
392 | | // The data for the different variants is stored in these two data fields. |
393 | | // These should only be accessed via the getter methods above, which will |
394 | | // assert if the tag is invalid. |
395 | | uint8_t mData1; |
396 | | uint8_t mData2; |
397 | | }; |
398 | | |
399 | | // The fields in nsXPTType were carefully ordered to minimize size. |
400 | | static_assert(sizeof(nsXPTType) == 3, "wrong size"); |
401 | | |
402 | | |
403 | | /* |
404 | | * A nsXPTParamInfo is used to describe either a single argument to a method or |
405 | | * a method's result. It stores its flags in the type descriptor to save space. |
406 | | */ |
407 | | struct nsXPTParamInfo |
408 | | { |
409 | 17.8M | bool IsIn() const { return mType.mInParam; } |
410 | 86.0M | bool IsOut() const { return mType.mOutParam; } |
411 | 1.62M | bool IsOptional() const { return mType.mOptionalParam; } |
412 | 0 | bool IsShared() const { return false; } // XXX remove (backcompat) |
413 | | |
414 | | // Get the type of this parameter. |
415 | 68.1M | const nsXPTType& Type() const { return mType; } |
416 | 30.8M | const nsXPTType& GetType() const { return Type(); } // XXX remove (backcompat) |
417 | | |
418 | | // Whether this parameter is passed indirectly on the stack. All out/inout |
419 | | // params are passed indirectly, and complex types are always passed |
420 | | // indirectly. |
421 | 16.2M | bool IsIndirect() const { |
422 | 16.2M | return IsOut() || Type().IsComplex(); |
423 | 16.2M | } |
424 | | |
425 | | //////////////////////////////////////////////////////////////// |
426 | | // Ensure these fields are in the same order as xptcodegen.py // |
427 | | //////////////////////////////////////////////////////////////// |
428 | | |
429 | | nsXPTType mType; |
430 | | }; |
431 | | |
432 | | // The fields in nsXPTParamInfo were carefully ordered to minimize size. |
433 | | static_assert(sizeof(nsXPTParamInfo) == 3, "wrong size"); |
434 | | |
435 | | /* |
436 | | * A nsXPTMethodInfo is used to describe a single interface method. |
437 | | */ |
438 | | struct nsXPTMethodInfo |
439 | | { |
440 | 4.87M | bool IsGetter() const { return mGetter; } |
441 | 4.87M | bool IsSetter() const { return mSetter; } |
442 | 394 | bool IsNotXPCOM() const { return mNotXPCOM; } |
443 | 384 | bool IsHidden() const { return mHidden; } |
444 | 1.62M | bool IsSymbol() const { return mIsSymbol; } |
445 | 8.11M | bool WantsOptArgc() const { return mOptArgc; } |
446 | 14.6M | bool WantsContext() const { return mContext; } |
447 | 27.6M | uint8_t ParamCount() const { return mNumParams; } |
448 | | |
449 | 1.62M | const char* Name() const { |
450 | 1.62M | MOZ_ASSERT(!IsSymbol()); |
451 | 1.62M | return xpt::detail::GetString(mName); |
452 | 1.62M | } |
453 | 102M | const nsXPTParamInfo& Param(uint8_t aIndex) const { |
454 | 102M | MOZ_ASSERT(aIndex < mNumParams); |
455 | 102M | return xpt::detail::GetParam(mParams + aIndex); |
456 | 102M | } |
457 | | |
458 | 12.9M | bool HasRetval() const { return mHasRetval; } |
459 | 19.4M | const nsXPTParamInfo* GetRetval() const { |
460 | 19.4M | return mHasRetval ? &Param(mNumParams - 1) : nullptr; |
461 | 19.4M | } |
462 | | |
463 | | // If this is an [implicit_jscontext] method, returns the index of the |
464 | | // implicit JSContext* argument in the C++ method's argument list. |
465 | | // Otherwise returns UINT8_MAX. |
466 | 8.11M | uint8_t IndexOfJSContext() const { |
467 | 8.11M | if (!WantsContext()) { |
468 | 6.49M | return UINT8_MAX; |
469 | 6.49M | } |
470 | 1.62M | if (IsGetter() || IsSetter()) { |
471 | 0 | // Getters/setters always have the context as first argument. |
472 | 0 | return 0; |
473 | 0 | } |
474 | 1.62M | // The context comes before the return value, if there is one. |
475 | 1.62M | MOZ_ASSERT_IF(HasRetval(), ParamCount() > 0); |
476 | 1.62M | return ParamCount() - uint8_t(HasRetval()); |
477 | 1.62M | } |
478 | | |
479 | | ///////////////////////////////////////////// |
480 | | // nsXPTMethodInfo backwards compatibility // |
481 | | ///////////////////////////////////////////// |
482 | | |
483 | 1.62M | const char* GetName() const { return Name(); } |
484 | | |
485 | | JS::SymbolCode GetSymbolCode() const |
486 | | { |
487 | | MOZ_ASSERT(IsSymbol()); |
488 | | return JS::SymbolCode(mName); |
489 | | } |
490 | | |
491 | | JS::Symbol* GetSymbol(JSContext* aCx) const |
492 | | { |
493 | | return JS::GetWellKnownSymbol(aCx, GetSymbolCode()); |
494 | | } |
495 | | |
496 | | void GetSymbolDescription(JSContext* aCx, nsACString& aID) const; |
497 | | |
498 | 22.7M | uint8_t GetParamCount() const { return ParamCount(); } |
499 | 71.4M | const nsXPTParamInfo& GetParam(uint8_t aIndex) const { |
500 | 71.4M | return Param(aIndex); |
501 | 71.4M | } |
502 | | |
503 | | //////////////////////////////////////////////////////////////// |
504 | | // Ensure these fields are in the same order as xptcodegen.py // |
505 | | //////////////////////////////////////////////////////////////// |
506 | | |
507 | | uint32_t mName; // Index into xpt::detail::sStrings. |
508 | | uint16_t mParams; // Index into xpt::detail::sParams. |
509 | | uint8_t mNumParams; |
510 | | |
511 | | uint8_t mGetter : 1; |
512 | | uint8_t mSetter : 1; |
513 | | uint8_t mNotXPCOM : 1; |
514 | | uint8_t mHidden : 1; |
515 | | uint8_t mOptArgc : 1; |
516 | | uint8_t mContext : 1; |
517 | | uint8_t mHasRetval : 1; |
518 | | uint8_t mIsSymbol : 1; |
519 | | }; |
520 | | |
521 | | // The fields in nsXPTMethodInfo were carefully ordered to minimize size. |
522 | | static_assert(sizeof(nsXPTMethodInfo) == 8, "wrong size"); |
523 | | |
524 | | /** |
525 | | * A nsXPTConstantInfo is used to describe a single interface constant. |
526 | | */ |
527 | | struct nsXPTConstantInfo |
528 | | { |
529 | | const char* Name() const { |
530 | | return xpt::detail::GetString(mName); |
531 | | } |
532 | | |
533 | | JS::Value JSValue() const { |
534 | | if (mSigned || mValue <= uint32_t(INT32_MAX)) { |
535 | | return JS::Int32Value(int32_t(mValue)); |
536 | | } |
537 | | return JS::DoubleValue(mValue); |
538 | | } |
539 | | |
540 | | //////////////////////////////////////////////////////////////// |
541 | | // Ensure these fields are in the same order as xptcodegen.py // |
542 | | //////////////////////////////////////////////////////////////// |
543 | | |
544 | | uint32_t mName : 31; // Index into xpt::detail::mStrings. |
545 | | |
546 | | // Whether the value should be interpreted as a int32_t or uint32_t. |
547 | | uint32_t mSigned: 1; |
548 | | uint32_t mValue; // The value stored as a u32 |
549 | | }; |
550 | | |
551 | | // The fields in nsXPTConstantInfo were carefully ordered to minimize size. |
552 | | static_assert(sizeof(nsXPTConstantInfo) == 8, "wrong size"); |
553 | | |
554 | | /** |
555 | | * Object representing the information required to wrap and unwrap DOMObjects. |
556 | | * |
557 | | * This object will not live in rodata as it contains relocations. |
558 | | */ |
559 | | struct nsXPTDOMObjectInfo |
560 | | { |
561 | 0 | nsresult Unwrap(JS::HandleValue aHandle, void** aObj) const { |
562 | 0 | return mUnwrap(aHandle, aObj); |
563 | 0 | } |
564 | | |
565 | 0 | bool Wrap(JSContext* aCx, void* aObj, JS::MutableHandleValue aHandle) const { |
566 | 0 | return mWrap(aCx, aObj, aHandle); |
567 | 0 | } |
568 | | |
569 | 0 | void Cleanup(void* aObj) const { |
570 | 0 | return mCleanup(aObj); |
571 | 0 | } |
572 | | |
573 | | //////////////////////////////////////////////////////////////// |
574 | | // Ensure these fields are in the same order as xptcodegen.py // |
575 | | //////////////////////////////////////////////////////////////// |
576 | | |
577 | | nsresult (*mUnwrap) (JS::HandleValue aHandle, void** aObj); |
578 | | bool (*mWrap) (JSContext* aCx, void* aObj, JS::MutableHandleValue aHandle); |
579 | | void (*mCleanup) (void* aObj); |
580 | | }; |
581 | | |
582 | | |
583 | | namespace xpt { |
584 | | namespace detail { |
585 | | |
586 | | // The UntypedTArray type allows low-level access from XPConnect to nsTArray |
587 | | // internals without static knowledge of the array element type in question. |
588 | | class UntypedTArray |
589 | | : public nsTArray_base<nsTArrayFallibleAllocator, nsTArray_CopyWithMemutils> |
590 | | { |
591 | | public: |
592 | 0 | void* Elements() const { |
593 | 0 | return static_cast<void*>(Hdr() + 1); |
594 | 0 | } |
595 | | |
596 | | // Changes the length and capacity to be at least large enough for aTo elements. |
597 | 0 | bool SetLength(const nsXPTType& aEltTy, uint32_t aTo) { |
598 | 0 | if (!EnsureCapacity<nsTArrayFallibleAllocator>(aTo, aEltTy.Stride())) { |
599 | 0 | return false; |
600 | 0 | } |
601 | 0 | mHdr->mLength = aTo; |
602 | 0 | return true; |
603 | 0 | } |
604 | | |
605 | | // Free backing memory for the nsTArray object. |
606 | 0 | void Clear() { |
607 | 0 | if (mHdr != EmptyHdr() && !UsesAutoArrayBuffer()) { |
608 | 0 | nsTArrayFallibleAllocator::Free(mHdr); |
609 | 0 | } |
610 | 0 | mHdr = EmptyHdr(); |
611 | 0 | } |
612 | | }; |
613 | | |
614 | | |
615 | | ////////////////////////////////////////////// |
616 | | // Raw typelib data stored in const statics // |
617 | | ////////////////////////////////////////////// |
618 | | |
619 | | // XPIDL information |
620 | | extern const nsXPTInterfaceInfo sInterfaces[]; |
621 | | extern const nsXPTType sTypes[]; |
622 | | extern const nsXPTParamInfo sParams[]; |
623 | | extern const nsXPTMethodInfo sMethods[]; |
624 | | extern const nsXPTConstantInfo sConsts[]; |
625 | | extern const nsXPTDOMObjectInfo sDOMObjects[]; |
626 | | |
627 | | extern const char sStrings[]; |
628 | | |
629 | | |
630 | | ////////////////////////////////////// |
631 | | // Helper Methods for fetching data // |
632 | | ////////////////////////////////////// |
633 | | |
634 | | inline const nsXPTInterfaceInfo* |
635 | | GetInterface(uint16_t aIndex) |
636 | | { |
637 | | if (aIndex > 0 && aIndex <= sInterfacesSize) { |
638 | | return &sInterfaces[aIndex - 1]; // 1-based as 0 is a marker. |
639 | | } |
640 | | return nullptr; |
641 | | } |
642 | | |
643 | | inline const nsXPTType& |
644 | | GetType(uint16_t aIndex) |
645 | 0 | { |
646 | 0 | return sTypes[aIndex]; |
647 | 0 | } |
648 | | |
649 | | inline const nsXPTParamInfo& |
650 | | GetParam(uint16_t aIndex) |
651 | 102M | { |
652 | 102M | return sParams[aIndex]; |
653 | 102M | } |
654 | | |
655 | | inline const nsXPTMethodInfo& |
656 | | GetMethod(uint16_t aIndex) |
657 | | { |
658 | | return sMethods[aIndex]; |
659 | | } |
660 | | |
661 | | inline const nsXPTConstantInfo& |
662 | | GetConstant(uint16_t aIndex) |
663 | | { |
664 | | return sConsts[aIndex]; |
665 | | } |
666 | | |
667 | | inline const nsXPTDOMObjectInfo& |
668 | | GetDOMObjectInfo(uint16_t aIndex) |
669 | 0 | { |
670 | 0 | return sDOMObjects[aIndex]; |
671 | 0 | } |
672 | | |
673 | | inline const char* |
674 | | GetString(uint32_t aIndex) |
675 | | { |
676 | | return &sStrings[aIndex]; |
677 | | } |
678 | | |
679 | | } // namespace detail |
680 | | } // namespace xpt |
681 | | |
682 | | #define XPT_FOR_EACH_ARITHMETIC_TYPE(macro) \ |
683 | 0 | macro(TD_INT8, int8_t) \ |
684 | 0 | macro(TD_INT16, int16_t) \ |
685 | 0 | macro(TD_INT32, int32_t) \ |
686 | 0 | macro(TD_INT64, int64_t) \ |
687 | 0 | macro(TD_UINT8, uint8_t) \ |
688 | 0 | macro(TD_UINT16, uint16_t) \ |
689 | 0 | macro(TD_UINT32, uint32_t) \ |
690 | 0 | macro(TD_UINT64, uint64_t) \ |
691 | 0 | macro(TD_FLOAT, float) \ |
692 | 0 | macro(TD_DOUBLE, double) \ |
693 | 0 | macro(TD_BOOL, bool) \ |
694 | 0 | macro(TD_CHAR, char) \ |
695 | 0 | macro(TD_WCHAR, char16_t) |
696 | | |
697 | | #define XPT_FOR_EACH_POINTER_TYPE(macro) \ |
698 | 1.62M | macro(TD_VOID, void*) \ |
699 | 1.62M | macro(TD_PNSIID, nsID*) \ |
700 | 4 | macro(TD_PSTRING, char*) \ |
701 | 4 | macro(TD_PWSTRING, wchar_t*) \ |
702 | 8.11M | macro(TD_INTERFACE_TYPE, nsISupports*) \ |
703 | 8.11M | macro(TD_INTERFACE_IS_TYPE, nsISupports*) \ |
704 | 1 | macro(TD_LEGACY_ARRAY, void*) \ |
705 | 0 | macro(TD_PSTRING_SIZE_IS, char*) \ |
706 | 0 | macro(TD_PWSTRING_SIZE_IS, wchar_t*) \ |
707 | 0 | macro(TD_DOMOBJECT, void*) \ |
708 | 0 | macro(TD_PROMISE, mozilla::dom::Promise*) |
709 | | |
710 | | #define XPT_FOR_EACH_COMPLEX_TYPE(macro) \ |
711 | 0 | macro(TD_DOMSTRING, nsString) \ |
712 | 9.74M | macro(TD_UTF8STRING, nsCString) \ |
713 | 9.74M | macro(TD_CSTRING, nsCString) \ |
714 | 0 | macro(TD_ASTRING, nsString) \ |
715 | 6.49M | macro(TD_JSVAL, JS::Value) \ |
716 | 6.49M | macro(TD_ARRAY, xpt::detail::UntypedTArray) |
717 | | |
718 | | #define XPT_FOR_EACH_TYPE(macro) \ |
719 | 9.74M | XPT_FOR_EACH_ARITHMETIC_TYPE(macro) \ |
720 | 9.74M | XPT_FOR_EACH_POINTER_TYPE(macro) \ |
721 | 9.74M | XPT_FOR_EACH_COMPLEX_TYPE(macro) |
722 | | |
723 | | inline size_t |
724 | | nsXPTType::Stride() const |
725 | 9.74M | { |
726 | 9.74M | // Compute the stride to use when walking an array of the given type. |
727 | 9.74M | switch (Tag()) { |
728 | 9.74M | #define XPT_TYPE_STRIDE(tag, type) case tag: return sizeof(type); |
729 | 9.74M | XPT_FOR_EACH_TYPE(XPT_TYPE_STRIDE) |
730 | 9.74M | #undef XPT_TYPE_STRIDE |
731 | 9.74M | } |
732 | 9.74M | |
733 | 9.74M | MOZ_CRASH("Unknown type"); |
734 | 0 | } |
735 | | |
736 | | #endif /* xptinfo_h */ |