michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: ** File: jstypes.h michael@0: ** Description: Definitions of NSPR's basic types michael@0: ** michael@0: ** Prototypes and macros used to make up for deficiencies in ANSI environments michael@0: ** that we have found. michael@0: ** michael@0: ** Since we do not wrap and all the other standard headers, authors michael@0: ** of portable code will not know in general that they need these definitions. michael@0: ** Instead of requiring these authors to find the dependent uses in their code michael@0: ** and take the following steps only in those C files, we take steps once here michael@0: ** for all C files. michael@0: **/ michael@0: michael@0: #ifndef jstypes_h michael@0: #define jstypes_h michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "mozilla/Types.h" michael@0: michael@0: // jstypes.h is (or should be!) included by every file in SpiderMonkey. michael@0: // js-config.h and jsversion.h also should be included by every file. michael@0: // So include them here. michael@0: // XXX: including them in js/RequiredDefines.h should be a better option, since michael@0: // that is by definition the header file that should be included in all michael@0: // SpiderMonkey code. However, Gecko doesn't do this! See bug 909576. michael@0: #include "js-config.h" michael@0: #include "jsversion.h" michael@0: michael@0: /*********************************************************************** michael@0: ** MACROS: JS_EXTERN_API michael@0: ** JS_EXPORT_API michael@0: ** DESCRIPTION: michael@0: ** These are only for externally visible routines and globals. For michael@0: ** internal routines, just use "extern" for type checking and that michael@0: ** will not export internal cross-file or forward-declared symbols. michael@0: ** Define a macro for declaring procedures return types. We use this to michael@0: ** deal with windoze specific type hackery for DLL definitions. Use michael@0: ** JS_EXTERN_API when the prototype for the method is declared. Use michael@0: ** JS_EXPORT_API for the implementation of the method. michael@0: ** michael@0: ** Example: michael@0: ** in dowhim.h michael@0: ** JS_EXTERN_API( void ) DoWhatIMean( void ); michael@0: ** in dowhim.c michael@0: ** JS_EXPORT_API( void ) DoWhatIMean( void ) { return; } michael@0: ** michael@0: ** michael@0: ***********************************************************************/ michael@0: michael@0: #define JS_EXTERN_API(type) extern MOZ_EXPORT type michael@0: #define JS_EXPORT_API(type) MOZ_EXPORT type michael@0: #define JS_EXPORT_DATA(type) MOZ_EXPORT type michael@0: #define JS_IMPORT_API(type) MOZ_IMPORT_API type michael@0: #define JS_IMPORT_DATA(type) MOZ_IMPORT_DATA type michael@0: michael@0: /* michael@0: * The linkage of JS API functions differs depending on whether the file is michael@0: * used within the JS library or not. Any source file within the JS michael@0: * interpreter should define EXPORT_JS_API whereas any client of the library michael@0: * should not. STATIC_JS_API is used to build JS as a static library. michael@0: */ michael@0: #if defined(STATIC_JS_API) michael@0: # define JS_PUBLIC_API(t) t michael@0: # define JS_PUBLIC_DATA(t) t michael@0: #elif defined(EXPORT_JS_API) || defined(STATIC_EXPORTABLE_JS_API) michael@0: # define JS_PUBLIC_API(t) MOZ_EXPORT t michael@0: # define JS_PUBLIC_DATA(t) MOZ_EXPORT t michael@0: #else michael@0: # define JS_PUBLIC_API(t) MOZ_IMPORT_API t michael@0: # define JS_PUBLIC_DATA(t) MOZ_IMPORT_DATA t michael@0: #endif michael@0: michael@0: #if defined(STATIC_JS_API) || defined(EXPORT_JS_API) || defined(STATIC_EXPORTABLE_JS_API) michael@0: # define JS_FRIEND_API(t) MOZ_EXPORT t michael@0: # define JS_FRIEND_DATA(t) MOZ_EXPORT t michael@0: #else michael@0: # define JS_FRIEND_API(t) MOZ_IMPORT_API t michael@0: # define JS_FRIEND_DATA(t) MOZ_IMPORT_DATA t michael@0: #endif michael@0: michael@0: #if defined(_MSC_VER) && defined(_M_IX86) michael@0: #define JS_FASTCALL __fastcall michael@0: #elif defined(__GNUC__) && defined(__i386__) michael@0: #define JS_FASTCALL __attribute__((fastcall)) michael@0: #else michael@0: #define JS_FASTCALL michael@0: #define JS_NO_FASTCALL michael@0: #endif michael@0: michael@0: /*********************************************************************** michael@0: ** MACROS: JS_BEGIN_MACRO michael@0: ** JS_END_MACRO michael@0: ** DESCRIPTION: michael@0: ** Macro body brackets so that macros with compound statement definitions michael@0: ** behave syntactically more like functions when called. michael@0: ***********************************************************************/ michael@0: #define JS_BEGIN_MACRO do { michael@0: michael@0: #if defined(_MSC_VER) && _MSC_VER >= 1400 michael@0: # define JS_END_MACRO \ michael@0: } __pragma(warning(push)) __pragma(warning(disable:4127)) \ michael@0: while (0) __pragma(warning(pop)) michael@0: #else michael@0: # define JS_END_MACRO } while (0) michael@0: #endif michael@0: michael@0: /*********************************************************************** michael@0: ** MACROS: JS_BIT michael@0: ** JS_BITMASK michael@0: ** DESCRIPTION: michael@0: ** Bit masking macros. XXX n must be <= 31 to be portable michael@0: ***********************************************************************/ michael@0: #define JS_BIT(n) ((uint32_t)1 << (n)) michael@0: #define JS_BITMASK(n) (JS_BIT(n) - 1) michael@0: michael@0: /*********************************************************************** michael@0: ** MACROS: JS_HOWMANY michael@0: ** JS_ROUNDUP michael@0: ** DESCRIPTION: michael@0: ** Commonly used macros for operations on compatible types. michael@0: ***********************************************************************/ michael@0: #define JS_HOWMANY(x,y) (((x)+(y)-1)/(y)) michael@0: #define JS_ROUNDUP(x,y) (JS_HOWMANY(x,y)*(y)) michael@0: michael@0: #include "jscpucfg.h" michael@0: michael@0: /* michael@0: * Define JS_64BIT iff we are building in an environment with 64-bit michael@0: * addresses. michael@0: */ michael@0: #ifdef _MSC_VER michael@0: # if defined(_M_X64) || defined(_M_AMD64) michael@0: # define JS_64BIT michael@0: # endif michael@0: #elif defined(__GNUC__) michael@0: /* Additional GCC defines are when running on Solaris, AIX, and HPUX */ michael@0: # if defined(__x86_64__) || defined(__sparcv9) || \ michael@0: defined(__64BIT__) || defined(__LP64__) michael@0: # define JS_64BIT michael@0: # endif michael@0: #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) /* Sun Studio C/C++ */ michael@0: # if defined(__x86_64) || defined(__sparcv9) michael@0: # define JS_64BIT michael@0: # endif michael@0: #elif defined(__xlc__) || defined(__xlC__) /* IBM XL C/C++ */ michael@0: # if defined(__64BIT__) michael@0: # define JS_64BIT michael@0: # endif michael@0: #elif defined(__HP_cc) || defined(__HP_aCC) /* HP-UX cc/aCC */ michael@0: # if defined(__LP64__) michael@0: # define JS_64BIT michael@0: # endif michael@0: #else michael@0: # error "Implement me" michael@0: #endif michael@0: michael@0: /*********************************************************************** michael@0: ** MACROS: JS_ARRAY_LENGTH michael@0: ** JS_ARRAY_END michael@0: ** DESCRIPTION: michael@0: ** Macros to get the number of elements and the pointer to one past the michael@0: ** last element of a C array. Use them like this: michael@0: ** michael@0: ** jschar buf[10], *s; michael@0: ** JSString *str; michael@0: ** ... michael@0: ** for (s = buf; s != JS_ARRAY_END(buf); ++s) *s = ...; michael@0: ** ... michael@0: ** str = JS_NewStringCopyN(cx, buf, JS_ARRAY_LENGTH(buf)); michael@0: ** ... michael@0: ** michael@0: ***********************************************************************/ michael@0: michael@0: #define JS_ARRAY_LENGTH(array) (sizeof (array) / sizeof (array)[0]) michael@0: #define JS_ARRAY_END(array) ((array) + JS_ARRAY_LENGTH(array)) michael@0: michael@0: #define JS_BITS_PER_BYTE 8 michael@0: #define JS_BITS_PER_BYTE_LOG2 3 michael@0: michael@0: #if defined(JS_64BIT) michael@0: # define JS_BITS_PER_WORD 64 michael@0: #else michael@0: # define JS_BITS_PER_WORD 32 michael@0: #endif michael@0: michael@0: /*********************************************************************** michael@0: ** MACROS: JS_FUNC_TO_DATA_PTR michael@0: ** JS_DATA_TO_FUNC_PTR michael@0: ** DESCRIPTION: michael@0: ** Macros to convert between function and data pointers assuming that michael@0: ** they have the same size. Use them like this: michael@0: ** michael@0: ** JSPropertyOp nativeGetter; michael@0: ** JSObject *scriptedGetter; michael@0: ** ... michael@0: ** scriptedGetter = JS_FUNC_TO_DATA_PTR(JSObject *, nativeGetter); michael@0: ** ... michael@0: ** nativeGetter = JS_DATA_TO_FUNC_PTR(JSPropertyOp, scriptedGetter); michael@0: ** michael@0: ***********************************************************************/ michael@0: michael@0: #ifdef __GNUC__ michael@0: # define JS_FUNC_TO_DATA_PTR(type, fun) (__extension__ (type) (size_t) (fun)) michael@0: # define JS_DATA_TO_FUNC_PTR(type, ptr) (__extension__ (type) (size_t) (ptr)) michael@0: #else michael@0: /* Use an extra (void *) cast for MSVC. */ michael@0: # define JS_FUNC_TO_DATA_PTR(type, fun) ((type) (void *) (fun)) michael@0: # define JS_DATA_TO_FUNC_PTR(type, ptr) ((type) (void *) (ptr)) michael@0: #endif michael@0: michael@0: #ifdef __GNUC__ michael@0: # define JS_EXTENSION __extension__ michael@0: # define JS_EXTENSION_(s) __extension__ ({ s; }) michael@0: #else michael@0: # define JS_EXTENSION michael@0: # define JS_EXTENSION_(s) s michael@0: #endif michael@0: michael@0: #endif /* jstypes_h */