1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  * vim: set ts=8 sts=4 et sw=4 tw=99:
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 http://mozilla.org/MPL/2.0/. */
6 
7 /*
8 ** File:                jstypes.h
9 ** Description: Definitions of NSPR's basic types
10 **
11 ** Prototypes and macros used to make up for deficiencies in ANSI environments
12 ** that we have found.
13 **
14 ** Since we do not wrap <stdlib.h> and all the other standard headers, authors
15 ** of portable code will not know in general that they need these definitions.
16 ** Instead of requiring these authors to find the dependent uses in their code
17 ** and take the following steps only in those C files, we take steps once here
18 ** for all C files.
19 **/
20 
21 #ifndef jstypes_h
22 #define jstypes_h
23 
24 #include "mozilla/Attributes.h"
25 #include "mozilla/Casting.h"
26 #include "mozilla/Types.h"
27 
28 // jstypes.h is (or should be!) included by every file in SpiderMonkey.
29 // js-config.h also should be included by every file. So include it here.
30 // XXX: including it in js/RequiredDefines.h should be a better option, since
31 // that is by definition the header file that should be included in all
32 // SpiderMonkey code.  However, Gecko doesn't do this!  See bug 909576.
33 #include "js-config.h"
34 
35 /***********************************************************************
36 ** MACROS:      JS_EXTERN_API
37 **              JS_EXPORT_API
38 ** DESCRIPTION:
39 **      These are only for externally visible routines and globals.  For
40 **      internal routines, just use "extern" for type checking and that
41 **      will not export internal cross-file or forward-declared symbols.
42 **      Define a macro for declaring procedures return types. We use this to
43 **      deal with windoze specific type hackery for DLL definitions. Use
44 **      JS_EXTERN_API when the prototype for the method is declared. Use
45 **      JS_EXPORT_API for the implementation of the method.
46 **
47 ** Example:
48 **   in dowhim.h
49 **     JS_EXTERN_API( void ) DoWhatIMean( void );
50 **   in dowhim.c
51 **     JS_EXPORT_API( void ) DoWhatIMean( void ) { return; }
52 **
53 **
54 ***********************************************************************/
55 
56 #define JS_EXTERN_API(type) extern MOZ_EXPORT type
57 #define JS_EXPORT_API(type) MOZ_EXPORT type
58 #define JS_EXPORT_DATA(type) MOZ_EXPORT type
59 #define JS_IMPORT_API(type) MOZ_IMPORT_API type
60 #define JS_IMPORT_DATA(type) MOZ_IMPORT_DATA type
61 
62 /*
63  * The linkage of JS API functions differs depending on whether the file is
64  * used within the JS library or not. Any source file within the JS
65  * interpreter should define EXPORT_JS_API whereas any client of the library
66  * should not. STATIC_JS_API is used to build JS as a static library.
67  */
68 #if defined(STATIC_JS_API)
69 #define JS_PUBLIC_API
70 #define JS_PUBLIC_DATA
71 #define JS_FRIEND_API
72 #define JS_FRIEND_DATA
73 #elif defined(EXPORT_JS_API) || defined(STATIC_EXPORTABLE_JS_API)
74 #define JS_PUBLIC_API MOZ_EXPORT
75 #define JS_PUBLIC_DATA MOZ_EXPORT
76 #define JS_FRIEND_API MOZ_EXPORT
77 #define JS_FRIEND_DATA MOZ_EXPORT
78 #else
79 #define JS_PUBLIC_API MOZ_IMPORT_API
80 #define JS_PUBLIC_DATA MOZ_IMPORT_DATA
81 #define JS_FRIEND_API MOZ_IMPORT_API
82 #define JS_FRIEND_DATA MOZ_IMPORT_DATA
83 #endif
84 
85 #if defined(_MSC_VER) && defined(_M_IX86)
86 #define JS_FASTCALL __fastcall
87 #elif defined(__GNUC__) && defined(__i386__)
88 #define JS_FASTCALL __attribute__((fastcall))
89 #else
90 #define JS_FASTCALL
91 #define JS_NO_FASTCALL
92 #endif
93 
94 // gcc is buggy and warns on our attempts to JS_PUBLIC_API our
95 // forward-declarations or explicit template instantiations.  See
96 // <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=50044>.  Add a way to detect
97 // that so we can locally disable that warning.
98 #if MOZ_IS_GCC
99 #if MOZ_GCC_VERSION_AT_MOST(8, 0, 0)
100 #define JS_BROKEN_GCC_ATTRIBUTE_WARNING
101 #endif
102 #endif
103 
104 /***********************************************************************
105 ** MACROS:      JS_BEGIN_MACRO
106 **              JS_END_MACRO
107 ** DESCRIPTION:
108 **      Macro body brackets so that macros with compound statement definitions
109 **      behave syntactically more like functions when called.
110 ***********************************************************************/
111 #define JS_BEGIN_MACRO do {
112 #if defined(_MSC_VER)
113 #define JS_END_MACRO                                                  \
114   }                                                                   \
115   __pragma(warning(push)) __pragma(warning(disable : 4127)) while (0) \
116       __pragma(warning(pop))
117 #else
118 #define JS_END_MACRO \
119   }                  \
120   while (0)
121 #endif
122 
123 /***********************************************************************
124 ** MACROS:      JS_BIT
125 **              JS_BITMASK
126 ** DESCRIPTION:
127 ** Bit masking macros.  XXX n must be <= 31 to be portable
128 ***********************************************************************/
129 #define JS_BIT(n) ((uint32_t)1 << (n))
130 #define JS_BITMASK(n) (JS_BIT(n) - 1)
131 
132 /***********************************************************************
133 ** MACROS:      JS_HOWMANY
134 **              JS_ROUNDUP
135 ** DESCRIPTION:
136 **      Commonly used macros for operations on compatible types.
137 ***********************************************************************/
138 #define JS_HOWMANY(x, y) (((x) + (y)-1) / (y))
139 #define JS_ROUNDUP(x, y) (JS_HOWMANY(x, y) * (y))
140 
141 #define JS_BITS_PER_BYTE 8
142 #define JS_BITS_PER_BYTE_LOG2 3
143 
144 #if defined(JS_64BIT)
145 #define JS_BITS_PER_WORD 64
146 #else
147 #define JS_BITS_PER_WORD 32
148 #endif
149 
150 /***********************************************************************
151 ** MACROS:      JS_FUNC_TO_DATA_PTR
152 **              JS_DATA_TO_FUNC_PTR
153 ** DESCRIPTION:
154 **      Macros to convert between function and data pointers of the same
155 **      size. Use them like this:
156 **
157 **      JSGetterOp nativeGetter;
158 **      JSObject* scriptedGetter;
159 **      ...
160 **      scriptedGetter = JS_FUNC_TO_DATA_PTR(JSObject*, nativeGetter);
161 **      ...
162 **      nativeGetter = JS_DATA_TO_FUNC_PTR(JSGetterOp, scriptedGetter);
163 **
164 ***********************************************************************/
165 
166 #define JS_FUNC_TO_DATA_PTR(type, fun) (mozilla::BitwiseCast<type>(fun))
167 #define JS_DATA_TO_FUNC_PTR(type, ptr) (mozilla::BitwiseCast<type>(ptr))
168 
169 #ifdef __GNUC__
170 #define JS_EXTENSION __extension__
171 #define JS_EXTENSION_(s) __extension__({ s; })
172 #else
173 #define JS_EXTENSION
174 #define JS_EXTENSION_(s) s
175 #endif
176 
177 #endif /* jstypes_h */
178