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 and jsversion.h also should be included by every file.
30 // So include them here.
31 // XXX: including them in js/RequiredDefines.h should be a better option, since
32 // that is by definition the header file that should be included in all
33 // SpiderMonkey code.  However, Gecko doesn't do this!  See bug 909576.
34 #include "js-config.h"
35 #include "jsversion.h"
36 
37 /***********************************************************************
38 ** MACROS:      JS_EXTERN_API
39 **              JS_EXPORT_API
40 ** DESCRIPTION:
41 **      These are only for externally visible routines and globals.  For
42 **      internal routines, just use "extern" for type checking and that
43 **      will not export internal cross-file or forward-declared symbols.
44 **      Define a macro for declaring procedures return types. We use this to
45 **      deal with windoze specific type hackery for DLL definitions. Use
46 **      JS_EXTERN_API when the prototype for the method is declared. Use
47 **      JS_EXPORT_API for the implementation of the method.
48 **
49 ** Example:
50 **   in dowhim.h
51 **     JS_EXTERN_API( void ) DoWhatIMean( void );
52 **   in dowhim.c
53 **     JS_EXPORT_API( void ) DoWhatIMean( void ) { return; }
54 **
55 **
56 ***********************************************************************/
57 
58 #define JS_EXTERN_API(type)  extern MOZ_EXPORT type
59 #define JS_EXPORT_API(type)  MOZ_EXPORT type
60 #define JS_EXPORT_DATA(type) MOZ_EXPORT type
61 #define JS_IMPORT_API(type)  MOZ_IMPORT_API type
62 #define JS_IMPORT_DATA(type) MOZ_IMPORT_DATA type
63 
64 /*
65  * The linkage of JS API functions differs depending on whether the file is
66  * used within the JS library or not. Any source file within the JS
67  * interpreter should define EXPORT_JS_API whereas any client of the library
68  * should not. STATIC_JS_API is used to build JS as a static library.
69  */
70 #if defined(STATIC_JS_API)
71 #  define JS_PUBLIC_API(t)   t
72 #  define JS_PUBLIC_DATA(t)  t
73 #elif defined(EXPORT_JS_API) || defined(STATIC_EXPORTABLE_JS_API)
74 #  define JS_PUBLIC_API(t)   MOZ_EXPORT t
75 #  define JS_PUBLIC_DATA(t)  MOZ_EXPORT t
76 #else
77 #  define JS_PUBLIC_API(t)   MOZ_IMPORT_API t
78 #  define JS_PUBLIC_DATA(t)  MOZ_IMPORT_DATA t
79 #endif
80 
81 #if defined(STATIC_JS_API) || defined(EXPORT_JS_API) || defined(STATIC_EXPORTABLE_JS_API)
82 #  define JS_FRIEND_API(t)    MOZ_EXPORT t
83 #  define JS_FRIEND_DATA(t)   MOZ_EXPORT t
84 #else
85 #  define JS_FRIEND_API(t)   MOZ_IMPORT_API t
86 #  define JS_FRIEND_DATA(t)  MOZ_IMPORT_DATA t
87 #endif
88 
89 #if defined(_MSC_VER) && defined(_M_IX86)
90 #define JS_FASTCALL __fastcall
91 #elif defined(__GNUC__) && defined(__i386__)
92 #define JS_FASTCALL __attribute__((fastcall))
93 #else
94 #define JS_FASTCALL
95 #define JS_NO_FASTCALL
96 #endif
97 
98 /***********************************************************************
99 ** MACROS:      JS_BEGIN_MACRO
100 **              JS_END_MACRO
101 ** DESCRIPTION:
102 **      Macro body brackets so that macros with compound statement definitions
103 **      behave syntactically more like functions when called.
104 ***********************************************************************/
105 #define JS_BEGIN_MACRO  do {
106 
107 #if defined(_MSC_VER)
108 # define JS_END_MACRO                                                         \
109     } __pragma(warning(push)) __pragma(warning(disable:4127))                 \
110     while (0) __pragma(warning(pop))
111 #else
112 # define JS_END_MACRO   } while (0)
113 #endif
114 
115 /***********************************************************************
116 ** MACROS:      JS_BIT
117 **              JS_BITMASK
118 ** DESCRIPTION:
119 ** Bit masking macros.  XXX n must be <= 31 to be portable
120 ***********************************************************************/
121 #define JS_BIT(n)       ((uint32_t)1 << (n))
122 #define JS_BITMASK(n)   (JS_BIT(n) - 1)
123 
124 /***********************************************************************
125 ** MACROS:      JS_HOWMANY
126 **              JS_ROUNDUP
127 ** DESCRIPTION:
128 **      Commonly used macros for operations on compatible types.
129 ***********************************************************************/
130 #define JS_HOWMANY(x,y) (((x)+(y)-1)/(y))
131 #define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y))
132 
133 #include "jscpucfg.h"
134 
135 /*
136  * Define JS_64BIT iff we are building in an environment with 64-bit
137  * addresses.
138  */
139 #ifdef _MSC_VER
140 # if defined(_M_X64) || defined(_M_AMD64)
141 #  define JS_64BIT
142 # endif
143 #elif defined(__GNUC__)
144 /* Additional GCC defines are when running on Solaris, AIX, and HPUX */
145 # if defined(__x86_64__) || defined(__sparcv9) || \
146         defined(__64BIT__) || defined(__LP64__)
147 #  define JS_64BIT
148 # endif
149 #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Sun Studio C/C++ */
150 # if defined(__x86_64) || defined(__sparcv9)
151 #  define JS_64BIT
152 # endif
153 #elif defined(__xlc__) || defined(__xlC__)        /* IBM XL C/C++ */
154 # if defined(__64BIT__)
155 #  define JS_64BIT
156 # endif
157 #elif defined(__HP_cc) || defined(__HP_aCC)       /* HP-UX cc/aCC */
158 # if defined(__LP64__)
159 #  define JS_64BIT
160 # endif
161 #else
162 # error "Implement me"
163 #endif
164 
165 /***********************************************************************
166 ** MACROS:      JS_ARRAY_LENGTH
167 **              JS_ARRAY_END
168 ** DESCRIPTION:
169 **      Macros to get the number of elements and the pointer to one past the
170 **      last element of a C array. Use them like this:
171 **
172 **      char16_t buf[10];
173 **      JSString* str;
174 **      ...
175 **      for (char16_t* s = buf; s != JS_ARRAY_END(buf); ++s) *s = ...;
176 **      ...
177 **      str = JS_NewStringCopyN(cx, buf, JS_ARRAY_LENGTH(buf));
178 **      ...
179 **
180 ***********************************************************************/
181 
182 #define JS_ARRAY_LENGTH(array) (sizeof (array) / sizeof (array)[0])
183 #define JS_ARRAY_END(array)    ((array) + JS_ARRAY_LENGTH(array))
184 
185 #define JS_BITS_PER_BYTE 8
186 #define JS_BITS_PER_BYTE_LOG2 3
187 
188 #if defined(JS_64BIT)
189 # define JS_BITS_PER_WORD 64
190 #else
191 # define JS_BITS_PER_WORD 32
192 #endif
193 
194 /***********************************************************************
195 ** MACROS:      JS_FUNC_TO_DATA_PTR
196 **              JS_DATA_TO_FUNC_PTR
197 ** DESCRIPTION:
198 **      Macros to convert between function and data pointers of the same
199 **      size. Use them like this:
200 **
201 **      JSGetterOp nativeGetter;
202 **      JSObject* scriptedGetter;
203 **      ...
204 **      scriptedGetter = JS_FUNC_TO_DATA_PTR(JSObject*, nativeGetter);
205 **      ...
206 **      nativeGetter = JS_DATA_TO_FUNC_PTR(JSGetterOp, scriptedGetter);
207 **
208 ***********************************************************************/
209 
210 #define JS_FUNC_TO_DATA_PTR(type, fun)  (mozilla::BitwiseCast<type>(fun))
211 #define JS_DATA_TO_FUNC_PTR(type, ptr)  (mozilla::BitwiseCast<type>(ptr))
212 
213 #ifdef __GNUC__
214 # define JS_EXTENSION __extension__
215 # define JS_EXTENSION_(s) __extension__ ({ s; })
216 #else
217 # define JS_EXTENSION
218 # define JS_EXTENSION_(s) s
219 #endif
220 
221 #endif /* jstypes_h */
222