Bug 711672 - Break mfbt's dependency on jstypes.h by moving various API macros out of JS and into mfbt. r=luke, r=cjones
authorJeff Walden <jwalden@mit.edu>
Tue, 13 Dec 2011 14:26:58 -0500
changeset 84583 38a35f0db9ff1bab21c7de76462fd06e50fa58cd
parent 84582 692d80735b7e90d94e595b20244891f85e73f7e0
child 84584 87be07cf8c10d4f8b9c0249529c6a4afa3983dac
push id519
push userakeybl@mozilla.com
push dateWed, 01 Feb 2012 00:38:35 +0000
treeherdermozilla-beta@788ea1ef610b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke, cjones
bugs711672
milestone11.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 711672 - Break mfbt's dependency on jstypes.h by moving various API macros out of JS and into mfbt. r=luke, r=cjones
js/public/TemplateLib.h
js/public/Utility.h
js/src/jstypes.h
js/src/jsutil.cpp
js/src/shell/js.cpp
js/xpconnect/shell/xpcshell.cpp
mfbt/Types.h
mfbt/Util.h
--- a/js/public/TemplateLib.h
+++ b/js/public/TemplateLib.h
@@ -36,18 +36,17 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef js_template_lib_h__
 #define js_template_lib_h__
 
-#include "mozilla/Types.h"
-#include "jsstdint.h"
+#include "jstypes.h"
 
 /*
  * Library of reusable template meta-functions (that is, functions on types and
  * compile-time values). Meta-functions are placed inside the 'tl' namespace to
  * avoid conflict with non-meta functions that logically have the same name
  * (e.g., js::tl::Min vs. js::Min).
  */
 
--- a/js/public/Utility.h
+++ b/js/public/Utility.h
@@ -38,17 +38,17 @@
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef js_utility_h__
 #define js_utility_h__
 
 #include <stdlib.h>
 #include <string.h>
 
-#include "mozilla/Util.h"
+#include "jstypes.h"
 
 #ifdef __cplusplus
 
 /* The public JS engine namespace. */
 namespace JS {}
 
 /* The mozilla-shared reusable template/utility namespace. */
 namespace mozilla {}
--- a/js/src/jstypes.h
+++ b/js/src/jstypes.h
@@ -49,19 +49,18 @@
 ** Instead of requiring these authors to find the dependent uses in their code
 ** and take the following steps only in those C files, we take steps once here
 ** for all C files.
 **/
 
 #ifndef jstypes_h___
 #define jstypes_h___
 
-#include "mozilla/StdInt.h"
+#include "mozilla/Util.h"
 
-#include <stddef.h>
 #include "js-config.h"
 
 /***********************************************************************
 ** MACROS:      JS_EXTERN_API
 **              JS_EXPORT_API
 ** DESCRIPTION:
 **      These are only for externally visible routines and globals.  For
 **      internal routines, just use "extern" for type checking and that
@@ -75,82 +74,37 @@
 **   in dowhim.h
 **     JS_EXTERN_API( void ) DoWhatIMean( void );
 **   in dowhim.c
 **     JS_EXPORT_API( void ) DoWhatIMean( void ) { return; }
 **
 **
 ***********************************************************************/
 
-#if defined(WIN32) || defined(XP_OS2)
-
-/* These also work for __MWERKS__ */
-# define JS_EXTERN_API(__type)  extern __declspec(dllexport) __type
-# define JS_EXPORT_API(__type)  __declspec(dllexport) __type
-# define JS_EXTERN_DATA(__type) extern __declspec(dllexport) __type
-# define JS_EXPORT_DATA(__type) __declspec(dllexport) __type
-
-#else /* Unix */
-
-# ifdef HAVE_VISIBILITY_ATTRIBUTE
-#  define JS_EXTERNAL_VIS __attribute__((visibility ("default")))
-# elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
-#  define JS_EXTERNAL_VIS __global
-# else
-#  define JS_EXTERNAL_VIS
-# endif
-
-# define JS_EXTERN_API(__type)  extern JS_EXTERNAL_VIS __type
-# define JS_EXPORT_API(__type)  JS_EXTERNAL_VIS __type
-# define JS_EXTERN_DATA(__type) extern JS_EXTERNAL_VIS __type
-# define JS_EXPORT_DATA(__type) JS_EXTERNAL_VIS __type
-
-#endif
-
-#ifdef _WIN32
-# if defined(__MWERKS__) || defined(__GNUC__)
-#  define JS_IMPORT_API(__x)    __x
-# else
-#  define JS_IMPORT_API(__x)    __declspec(dllimport) __x
-# endif
-#elif defined(XP_OS2)
-# define JS_IMPORT_API(__x)     __declspec(dllimport) __x
-#else
-# define JS_IMPORT_API(__x)     JS_EXPORT_API (__x)
-#endif
-
-#if defined(_WIN32) && !defined(__MWERKS__)
-# define JS_IMPORT_DATA(__x)      __declspec(dllimport) __x
-#elif defined(XP_OS2)
-# define JS_IMPORT_DATA(__x)      __declspec(dllimport) __x
-#else
-# define JS_IMPORT_DATA(__x)     JS_EXPORT_DATA (__x)
-#endif
+#define JS_EXTERN_API(type)  extern MOZ_EXPORT_API(type)
+#define JS_EXPORT_API(type)  MOZ_EXPORT_API(type)
+#define JS_EXPORT_DATA(type) MOZ_EXPORT_DATA(type)
+#define JS_IMPORT_API(type)  MOZ_IMPORT_API(type)
+#define JS_IMPORT_DATA(type) MOZ_IMPORT_DATA(type)
 
 /*
  * The linkage of JS API functions differs depending on whether the file is
  * used within the JS library or not. Any source file within the JS
  * interpreter should define EXPORT_JS_API whereas any client of the library
  * should not. STATIC_JS_API is used to build JS as a static library.
  */
 #if defined(STATIC_JS_API)
-
-# define JS_PUBLIC_API(t)   t
-# define JS_PUBLIC_DATA(t)  t
-
+#  define JS_PUBLIC_API(t)   t
+#  define JS_PUBLIC_DATA(t)  t
 #elif defined(EXPORT_JS_API) || defined(STATIC_EXPORTABLE_JS_API)
-
-# define JS_PUBLIC_API(t)   JS_EXPORT_API(t)
-# define JS_PUBLIC_DATA(t)  JS_EXPORT_DATA(t)
-
+#  define JS_PUBLIC_API(t)   MOZ_EXPORT_API(t)
+#  define JS_PUBLIC_DATA(t)  MOZ_EXPORT_DATA(t)
 #else
-
-# define JS_PUBLIC_API(t)   JS_IMPORT_API(t)
-# define JS_PUBLIC_DATA(t)  JS_IMPORT_DATA(t)
-
+#  define JS_PUBLIC_API(t)   MOZ_IMPORT_API(t)
+#  define JS_PUBLIC_DATA(t)  MOZ_IMPORT_DATA(t)
 #endif
 
 #define JS_FRIEND_API(t)    JS_PUBLIC_API(t)
 #define JS_FRIEND_DATA(t)   JS_PUBLIC_DATA(t)
 
 #if defined(_MSC_VER) && defined(_M_IX86)
 #define JS_FASTCALL __fastcall
 #elif defined(__GNUC__) && defined(__i386__) &&                         \
@@ -240,27 +194,18 @@
 #endif
 
 /***********************************************************************
 ** MACROS:      JS_BEGIN_EXTERN_C
 **              JS_END_EXTERN_C
 ** DESCRIPTION:
 **      Macro shorthands for conditional C++ extern block delimiters.
 ***********************************************************************/
-#ifdef __cplusplus
-
-# define JS_BEGIN_EXTERN_C      extern "C" {
-# define JS_END_EXTERN_C        }
-
-#else
-
-# define JS_BEGIN_EXTERN_C
-# define JS_END_EXTERN_C
-
-#endif
+#define JS_BEGIN_EXTERN_C      MOZ_BEGIN_EXTERN_C
+#define JS_END_EXTERN_C        MOZ_END_EXTERN_C
 
 /***********************************************************************
 ** MACROS:      JS_BIT
 **              JS_BITMASK
 ** DESCRIPTION:
 ** Bit masking macros.  XXX n must be <= 31 to be portable
 ***********************************************************************/
 #define JS_BIT(n)       ((uint32_t)1 << (n))
--- a/js/src/jsutil.cpp
+++ b/js/src/jsutil.cpp
@@ -48,16 +48,18 @@
 #include "jsutil.h"
 
 #ifdef WIN32
 #    include "jswin.h"
 #else
 #    include <signal.h>
 #endif
 
+#include "js/TemplateLib.h"
+
 using namespace js;
 
 #ifdef DEBUG
 /* For JS_OOM_POSSIBLY_FAIL in jsutil.h. */
 JS_PUBLIC_DATA(uint32_t) OOM_maxAllocations = UINT32_MAX;
 JS_PUBLIC_DATA(uint32_t) OOM_counter = 0;
 #endif
 
@@ -91,17 +93,26 @@ CrashInJS()
      */
     *((volatile int *) NULL) = 123;  /* To continue from here in GDB: "return" then "continue". */
     raise(SIGABRT);  /* In case above statement gets nixed by the optimizer. */
 #else
     raise(SIGABRT);  /* To continue from here in GDB: "signal 0". */
 #endif
 }
 
-JS_PUBLIC_API(void) JS_Assert(const char *s, const char *file, JSIntn ln)
+/*
+ * |JS_Assert| historically took |JSIntn ln| as its last argument.  We've
+ * boiled |JSIntn ln| down to simply |int ln| so that mfbt may declare the
+ * function without depending on the |JSIntn| typedef, so we must manually
+ * verify that the |JSIntn| typedef is consistent.
+ */
+JS_STATIC_ASSERT((tl::IsSameType<JSIntn, int>::result));
+
+JS_PUBLIC_API(void)
+JS_Assert(const char *s, const char *file, int ln)
 {
     fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);
     fflush(stderr);
     CrashInJS();
 }
 
 #ifdef JS_BASIC_STATS
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -226,18 +226,18 @@ NewContext(JSRuntime *rt);
 static void
 DestroyContext(JSContext *cx, bool withGC);
 
 static const JSErrorFormatString *
 my_GetErrorMessage(void *userRef, const char *locale, const uintN errorNumber);
 
 #ifdef EDITLINE
 JS_BEGIN_EXTERN_C
-JS_EXTERN_API(char)    *readline(const char *prompt);
-JS_EXTERN_API(void)     add_history(char *line);
+extern JS_EXPORT_API(char *) readline(const char *prompt);
+extern JS_EXPORT_API(void)   add_history(char *line);
 JS_END_EXTERN_C
 #endif
 
 static void
 ReportException(JSContext *cx)
 {
     if (JS_IsExceptionPending(cx)) {
         if (!JS_ReportPendingException(cx))
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -241,17 +241,17 @@ GetLocationProperty(JSContext *cx, JSObj
     }
 
     return true;
 #endif
 }
 
 #ifdef EDITLINE
 extern "C" {
-extern JS_EXPORT_API(char)     *readline(const char *prompt);
+extern JS_EXPORT_API(char *)   readline(const char *prompt);
 extern JS_EXPORT_API(void)     add_history(char *line);
 }
 #endif
 
 static JSBool
 GetLine(JSContext *cx, char *bufp, FILE *file, const char *prompt) {
 #ifdef EDITLINE
     /*
--- a/mfbt/Types.h
+++ b/mfbt/Types.h
@@ -32,56 +32,130 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
-/*
- * NB: This header must be both valid C and C++.  It must be
- * include-able by code embedding SpiderMonkey *and* Gecko.
- */
+/* mfbt foundational types and macros. */
 
 #ifndef mozilla_Types_h_
 #define mozilla_Types_h_
 
 /*
- * Expose the standard integer types from <stdint.h> (and the integer type
- * limit and constant macros, if the right __STDC_*_MACRO has been defined for
- * each).  These are all usable throughout mfbt code, and throughout Mozilla
- * code more generally.
+ * This header must be valid C and C++, includable by code embedding either
+ * SpiderMonkey or Gecko.
+ */
+
+/*
+ * Expose all the integer types defined in C99's <stdint.h> (and the integer
+ * limit and constant macros, if compiling C code or if compiling C++ code and
+ * the right __STDC_*_MACRO has been defined for each).  These are all usable
+ * throughout mfbt code, and throughout Mozilla code more generally.
  */
 #include "mozilla/StdInt.h"
 
-/* 
- * mfbt is logically "lower level" than js/src, but needs basic
- * definitions of numerical types and macros for compiler/linker
- * directives.  js/src already goes through some pain to provide them
- * on numerous platforms, so instead of moving all that goop here,
- * this header makes use of the fact that for the foreseeable future
- * mfbt code will be part and parcel with libmozjs, static or not.
+/* Also expose size_t. */
+#include <stddef.h>
+
+/* Implement compiler and linker macros needed for APIs. */
+
+/*
+ * MOZ_EXPORT_API is used to declare and define a method which is externally
+ * visible to users of the current library.  It encapsulates various decorations
+ * needed to properly export the method's symbol.  MOZ_EXPORT_DATA serves the
+ * same purpose for data.
+ *
+ *   api.h:
+ *     extern MOZ_EXPORT_API(int) MeaningOfLife(void);
+ *     extern MOZ_EXPORT_DATA(int) LuggageCombination;
+ *
+ *   api.c:
+ *     MOZ_EXPORT_API(int) MeaningOfLife(void) { return 42; }
+ *     MOZ_EXPORT_DATA(int) LuggageCombination = 12345;
  *
- * For now, the policy is to use jstypes definitions but add a layer
- * of indirection on top of them in case a Great Refactoring ever
- * happens.
+ * If you are merely sharing a method across files, just use plain |extern|.
+ * These macros are designed for use by library interfaces -- not for normal
+ * methods or data used cross-file.
  */
-#include "jstypes.h"
-
-#define MOZ_EXPORT_API(type_)  JS_EXPORT_API(type_)
-#define MOZ_IMPORT_API(type_)  JS_IMPORT_API(type_)
+#if defined(WIN32) || defined(XP_OS2)
+#  define MOZ_EXPORT_API(type)    __declspec(dllexport) type
+#  define MOZ_EXPORT_DATA(type)   __declspec(dllexport) type
+#else /* Unix */
+#  ifdef HAVE_VISIBILITY_ATTRIBUTE
+#    define MOZ_EXTERNAL_VIS       __attribute__((visibility("default")))
+#  elif defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+#    define MOZ_EXTERNAL_VIS      __global
+#  else
+#    define MOZ_EXTERNAL_VIS
+#  endif
+#  define MOZ_EXPORT_API(type)    MOZ_EXTERNAL_VIS type
+#  define MOZ_EXPORT_DATA(type)   MOZ_EXTERNAL_VIS type
+#endif
 
 /*
- * mfbt definitions need to see export declarations when built, but
- * other code needs to see import declarations when using mfbt.
+ * Whereas implementers use MOZ_EXPORT_API and MOZ_EXPORT_DATA to declare and
+ * define library symbols, users use MOZ_IMPORT_API and MOZ_IMPORT_DATA to
+ * access them.  Most often the implementer of the library will expose an API
+ * macro which expands to either the export or import version of the macro,
+ * depending upon the compilation mode.
+ */
+#ifdef _WIN32
+#  if defined(__MWERKS__) || defined(__GNUC__)
+#    define MOZ_IMPORT_API(x)    x
+#  else
+#    define MOZ_IMPORT_API(x)    __declspec(dllimport) x
+#  endif
+#elif defined(XP_OS2)
+#  define MOZ_IMPORT_API(x)     __declspec(dllimport) x
+#else
+#  define MOZ_IMPORT_API(x)     MOZ_EXPORT_API(x)
+#endif
+
+#if defined(_WIN32) && !defined(__MWERKS__)
+#  define MOZ_IMPORT_DATA(x)     __declspec(dllimport) x
+#elif defined(XP_OS2)
+#  define MOZ_IMPORT_DATA(x)     __declspec(dllimport) x
+#else
+#  define MOZ_IMPORT_DATA(x)     MOZ_EXPORT_DATA(x)
+#endif
+
+/*
+ * Consistent with the above comment, the MFBT_API and MFBT_DATA macros expose
+ * export mfbt declarations when building mfbt, and they expose import mfbt
+ * declarations when using mfbt.
  */
 #if defined(IMPL_MFBT)
-#  define MFBT_API(type_)       MOZ_EXPORT_API(type_)
+#  define MFBT_API(type)        MOZ_EXPORT_API(type)
+#  define MFBT_DATA(type)       MOZ_EXPORT_DATA(type)
 #else
-#  define MFBT_API(type_)       MOZ_IMPORT_API(type_)
+#  define MFBT_API(type)        MOZ_IMPORT_API(type)
+#  define MFBT_DATA(type)       MOZ_IMPORT_DATA(type)
 #endif
 
-
-#define MOZ_BEGIN_EXTERN_C     JS_BEGIN_EXTERN_C
-#define MOZ_END_EXTERN_C       JS_END_EXTERN_C
+/*
+ * C symbols in C++ code must be declared immediately within |extern "C"|
+ * blocks.  However, in C code, they need not be declared specially.  This
+ * difference is abstracted behind the MOZ_BEGIN_EXTERN_C and MOZ_END_EXTERN_C
+ * macros, so that the user need not know whether he is being used in C or C++
+ * code.
+ *
+ *   MOZ_BEGIN_EXTERN_C
+ *
+ *   extern MOZ_EXPORT_API(int) MostRandomNumber(void);
+ *   ...other declarations...
+ *
+ *   MOZ_END_EXTERN_C
+ *
+ * This said, it is preferable to just use |extern "C"| in C++ header files for
+ * its greater clarity.
+ */
+#ifdef __cplusplus
+#  define MOZ_BEGIN_EXTERN_C    extern "C" {
+#  define MOZ_END_EXTERN_C      }
+#else
+#  define MOZ_BEGIN_EXTERN_C
+#  define MOZ_END_EXTERN_C
+#endif
 
 #endif  /* mozilla_Types_h_ */
--- a/mfbt/Util.h
+++ b/mfbt/Util.h
@@ -54,17 +54,17 @@
  * will be broken.
  *
  * JS_Assert is present even in release builds, for the benefit of applications
  * that build DEBUG and link against a non-DEBUG SpiderMonkey library.
  */
 MOZ_BEGIN_EXTERN_C
 
 extern MFBT_API(void)
-JS_Assert(const char *s, const char *file, JSIntn ln);
+JS_Assert(const char *s, const char *file, int ln);
 
 MOZ_END_EXTERN_C
 
 /*
  * MOZ_ASSERT() is a "strong" assertion of state, like libc's
  * assert().  If a MOZ_ASSERT() fails in a debug build, the process in
  * which it fails will stop running in a loud and dramatic way.
  */