Bug 615473 - Make ctypes.stdcall_abi and ctypes.winapi_abi aliases to the sole ABI on Win64. r=dwitte
authorSiddharth Agarwal <sid.bugzilla@gmail.com>
Thu, 11 Aug 2011 01:02:49 +0530
changeset 74217 d856045de3bcf09033fcd7fde1a94beb795d73c4
parent 74216 be91fb29d950eb712abcb26929423872de68ca42
child 74218 0e60623e36077a96a5f7e589baaf016f5b74c91a
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
reviewersdwitte
bugs615473
milestone8.0a1
Bug 615473 - Make ctypes.stdcall_abi and ctypes.winapi_abi aliases to the sole ABI on Win64. r=dwitte
js/src/ctypes/CTypes.cpp
toolkit/components/ctypes/tests/jsctypes-test.cpp
toolkit/components/ctypes/tests/jsctypes-test.h
toolkit/components/ctypes/tests/unit/test_jsctypes.js.in
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -4543,16 +4543,21 @@ GetABI(JSContext* cx, jsval abiType, ffi
   case ABI_DEFAULT:
     *result = FFI_DEFAULT_ABI;
     return true;
   case ABI_STDCALL:
   case ABI_WINAPI:
 #if (defined(_WIN32) && !defined(_WIN64)) || defined(_OS2)
     *result = FFI_STDCALL;
     return true;
+#elif (defined(_WIN64))
+    // We'd like the same code to work across Win32 and Win64, so stdcall_api
+    // and winapi_abi become aliases to the lone Win64 ABI.
+    *result = FFI_WIN64;
+    return true;
 #endif
   case INVALID_ABI:
     break;
   }
   return false;
 }
 
 static JSObject*
@@ -4687,32 +4692,38 @@ FunctionType::BuildSymbolName(JSContext*
   switch (GetABICode(cx, fninfo->mABI)) {
   case ABI_DEFAULT:
   case ABI_WINAPI:
     // For cdecl or WINAPI functions, no mangling is necessary.
     AppendString(result, name);
     break;
 
   case ABI_STDCALL: {
+#if (defined(_WIN32) && !defined(_WIN64)) || defined(_OS2)
     // On WIN32, stdcall functions look like:
     //   _foo@40
     // where 'foo' is the function name, and '40' is the aligned size of the
     // arguments.
     AppendString(result, "_");
     AppendString(result, name);
     AppendString(result, "@");
 
     // Compute the suffix by aligning each argument to sizeof(ffi_arg).
     size_t size = 0;
     for (size_t i = 0; i < fninfo->mArgTypes.length(); ++i) {
       JSObject* argType = fninfo->mArgTypes[i];
       size += Align(CType::GetSize(cx, argType), sizeof(ffi_arg));
     }
 
     IntegerToString(size, 10, result);
+#elif defined(_WIN64)
+    // On Win64, stdcall is an alias to the default ABI for compatibility, so no
+    // mangling is done.
+    AppendString(result, name);
+#endif
     break;
   }
 
   case INVALID_ABI:
     JS_NOT_REACHED("invalid abi");
     break;
   }
 }
--- a/toolkit/components/ctypes/tests/jsctypes-test.cpp
+++ b/toolkit/components/ctypes/tests/jsctypes-test.cpp
@@ -115,31 +115,31 @@ sum_many_##name##_##suffix(             
                                      j, k, l, m, n, o, p, q, r);               \
 }
 
 #define ABI /* cdecl */
 #define DEFINE_TYPE(x, y, z) FUNCTION_TESTS(x, y, z, cdecl)
 #include "typedefs.h"
 #undef ABI
 
-#if defined(_WIN32) && !defined(_WIN64)
+#if defined(_WIN32)
 
 void NS_STDCALL
 test_void_t_stdcall()
 {
   // do nothing
   return;
 }
 
 #define ABI NS_STDCALL
 #define DEFINE_TYPE(x, y, z) FUNCTION_TESTS(x, y, z, stdcall)
 #include "typedefs.h"
 #undef ABI
 
-#endif /* defined(_WIN32) && !defined(_WIN64) */
+#endif /* defined(_WIN32) */
 
 #define DEFINE_TYPE(name, type, ffiType)                                       \
 struct align_##name {                                                          \
   char x;                                                                      \
   type y;                                                                      \
 };                                                                             \
 struct nested_##name {                                                         \
   char a;                                                                      \
@@ -316,23 +316,23 @@ test_fnptr()
 }
 
 PRInt32
 test_closure_cdecl(PRInt8 i, test_func_ptr f)
 {
   return f(i);
 }
 
-#if defined(_WIN32) && !defined(_WIN64)
+#if defined(_WIN32)
 PRInt32
 test_closure_stdcall(PRInt8 i, test_func_ptr_stdcall f)
 {
   return f(i);
 }
-#endif /* defined(_WIN32) && !defined(_WIN64) */
+#endif /* defined(_WIN32) */
 
 template <typename T> struct PromotedTraits {
   typedef T type;
 };
 #define DECL_PROMOTED(FROM, TO)                 \
   template <> struct PromotedTraits<FROM> {     \
     typedef TO type;                            \
   }
--- a/toolkit/components/ctypes/tests/jsctypes-test.h
+++ b/toolkit/components/ctypes/tests/jsctypes-test.h
@@ -64,17 +64,17 @@ NS_EXTERN_C
     type, type, type, type, type, type, type, type, type);                     \
                                                                                \
   EXPORT_CDECL(void) get_##name##_stats(size_t* align, size_t* size,           \
                                         size_t* nalign, size_t* nsize,         \
                                         size_t offsets[]);
 
 #include "typedefs.h"
 
-#if defined(_WIN32) && !defined(_WIN64)
+#if defined(_WIN32)
   EXPORT_STDCALL(void) test_void_t_stdcall();
 
   EXPORT_STDCALL(void*) get_voidptr_t_stdcall();
   EXPORT_STDCALL(void*) set_voidptr_t_stdcall(void*);
 
 #define DEFINE_TYPE(name, type, ffiType)                                       \
   EXPORT_STDCALL(type) get_##name##_stdcall();                                 \
   EXPORT_STDCALL(type) set_##name##_stdcall(type);                             \
@@ -84,17 +84,17 @@ NS_EXTERN_C
   EXPORT_STDCALL(type) sum_alignf_##name##_stdcall(                            \
     float, type, float, type, float);                                          \
   EXPORT_STDCALL(type) sum_many_##name##_stdcall(                              \
     type, type, type, type, type, type, type, type, type,                      \
     type, type, type, type, type, type, type, type, type);
 
 #include "typedefs.h"
 
-#endif /* defined(_WIN32) && !defined(_WIN64) */
+#endif /* defined(_WIN32) */
 
   NS_EXPORT PRInt32 test_ansi_len(const char*);
   NS_EXPORT PRInt32 test_wide_len(const PRUnichar*);
   NS_EXPORT const char* test_ansi_ret();
   NS_EXPORT const PRUnichar* test_wide_ret();
   NS_EXPORT char* test_ansi_echo(const char*);
 
   struct ONE_BYTE {
@@ -185,20 +185,20 @@ NS_EXTERN_C
   NS_EXPORT FIVE_BYTE test_5_byte_struct_return(RECT);
   NS_EXPORT SIX_BYTE test_6_byte_struct_return(RECT);
   NS_EXPORT SEVEN_BYTE test_7_byte_struct_return(RECT);
 
   NS_EXPORT void * test_fnptr();
 
   typedef PRInt32 (* test_func_ptr)(PRInt8);
   NS_EXPORT PRInt32 test_closure_cdecl(PRInt8, test_func_ptr);
-#if defined(_WIN32) && !defined(_WIN64)
+#if defined(_WIN32)
   typedef PRInt32 (NS_STDCALL * test_func_ptr_stdcall)(PRInt8);
   NS_EXPORT PRInt32 test_closure_stdcall(PRInt8, test_func_ptr_stdcall);
-#endif /* defined(_WIN32) && !defined(_WIN64) */
+#endif /* defined(_WIN32) */
 
   NS_EXPORT PRInt32 test_callme(PRInt8);
   NS_EXPORT void* test_getfn();
 
   EXPORT_CDECL(PRInt32) test_sum_va_cdecl(PRUint8 n, ...);
   EXPORT_CDECL(PRUint8) test_count_true_va_cdecl(PRUint8 n, ...);
   EXPORT_CDECL(void) test_add_char_short_int_va_cdecl(PRUint32* result, ...);
   EXPORT_CDECL(PRInt32*) test_vector_add_va_cdecl(PRUint8 num_vecs,
--- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js.in
+++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js.in
@@ -676,33 +676,31 @@ function run_basic_abi_tests(library, t,
   // Test the function call ABI for calls involving the type.
   function declare_fn_cdecl(fn_t, prefix) {
     return library.declare(prefix + name + "_cdecl", fn_t);
   }
   run_single_abi_tests(declare_fn_cdecl, ctypes.default_abi, t,
     toprimitive, get_test, set_tests, sum_tests, sum_many_tests);
 
 #ifdef WIN32
-#ifndef HAVE_64BIT_OS
   function declare_fn_stdcall(fn_t, prefix) {
     return library.declare(prefix + name + "_stdcall", fn_t);
   }
   run_single_abi_tests(declare_fn_stdcall, ctypes.stdcall_abi, t,
     toprimitive, get_test, set_tests, sum_tests, sum_many_tests);
 
   // Check that declaring a WINAPI function gets the right symbol name.
   let libuser32 = ctypes.open("user32.dll");
   let charupper = libuser32.declare("CharUpperA",
                                     ctypes.winapi_abi,
                                     ctypes.char.ptr,
                                     ctypes.char.ptr);
   let hello = ctypes.char.array()("hello!");
   do_check_eq(charupper(hello).readString(), "HELLO!");
 #endif
-#endif
 
   // Check the alignment of the type, and its behavior in a struct,
   // against what C says.
   check_struct_stats(library, t);
 }
 
 function run_single_abi_tests(decl, abi, t, toprimitive,
                               get_test, set_tests, sum_tests, sum_many_tests) {
@@ -1872,25 +1870,23 @@ function run_FunctionType_tests() {
   do_check_eq(fp_t.array().name, "g_t(*[])()");
   do_check_eq(fp_t.array().ptr.name, "g_t(*(*)[])()");
 
   let f3_t = ctypes.FunctionType(ctypes.default_abi,
     ctypes.char.ptr.array().ptr).ptr.ptr.array(8).array();
   do_check_eq(f3_t.name, "char*(*(**[][8])())[]");
 
 #ifdef WIN32
-#ifndef HAVE_64BIT_OS
   f3_t = ctypes.FunctionType(ctypes.stdcall_abi,
     ctypes.char.ptr.array().ptr).ptr.ptr.array(8).array();
   do_check_eq(f3_t.name, "char*(*(__stdcall **[][8])())[]");
   f3_t = ctypes.FunctionType(ctypes.winapi_abi,
     ctypes.char.ptr.array().ptr).ptr.ptr.array(8).array();
   do_check_eq(f3_t.name, "char*(*(WINAPI **[][8])())[]");
 #endif
-#endif
 
   let f4_t = ctypes.FunctionType(ctypes.default_abi,
     ctypes.char.ptr.array().ptr, [ ctypes.int32_t, fp_t ]);
   do_check_true(f4_t.argTypes.length == 2);
   do_check_true(f4_t.argTypes[0] === ctypes.int32_t);
   do_check_true(f4_t.argTypes[1] === fp_t);
 /* disabled temporarily per bug 598225.
   do_check_throws(function() { f4_t.argTypes.z = 0; }, Error);
@@ -2085,21 +2081,22 @@ function run_void_tests(library) {
   do_check_eq(test_void_t(), undefined);
 
   // Test that library.declare throws with void function args.
   do_check_throws(function() {
     library.declare("test_void_t_cdecl", ctypes.default_abi, ctypes.void_t, ctypes.void_t);
   }, Error);
 
 #ifdef WIN32
-#ifndef HAVE_64BIT_OS
   test_void_t = library.declare("test_void_t_stdcall", ctypes.stdcall_abi, ctypes.void_t);
   do_check_eq(test_void_t(), undefined);
 
-  // Check that WINAPI symbol lookup for a regular stdcall function fails.
+  // Check that WINAPI symbol lookup for a regular stdcall function fails on
+  // Win32 (it's all the same on Win64 though).
+#ifndef HAVE_64BIT_OS
   do_check_throws(function() {
     let test_winapi_t = library.declare("test_void_t_stdcall", ctypes.winapi_abi, ctypes.void_t);
   }, Error);
 #endif
 #endif
 }
 
 function run_string_tests(library) {
@@ -2248,28 +2245,26 @@ function run_function_tests(library)
   do_check_eq(ptrValue(test_ansi_len_2), ptrValue(ptr));
 */
 }
 
 function run_closure_tests(library)
 {
   run_single_closure_tests(library, ctypes.default_abi, "cdecl");
 #ifdef WIN32
-#ifndef HAVE_64BIT_OS
   run_single_closure_tests(library, ctypes.stdcall_abi, "stdcall");
 
   // Check that attempting to construct a ctypes.winapi_abi closure throws.
   function closure_fn()
   {
     return 1;
   }
   let fn_t = ctypes.FunctionType(ctypes.winapi_abi, ctypes.int32_t, []).ptr;
   do_check_throws(function() { fn_t(closure_fn) }, Error);
 #endif
-#endif
 }
 
 function run_single_closure_tests(library, abi, suffix)
 {
   let b = 23;
 
   function closure_fn(i)
   {
@@ -2319,27 +2314,25 @@ function run_variadic_tests(library) {
                         [ctypes.bool, "...", ctypes.bool]);
   }, Error);
 
   do_check_throws(function() {
     ctypes.FunctionType(ctypes.default_abi, ctypes.bool, ["..."]);
   }, Error);
 
 #ifdef WIN32
-#ifndef HAVE_64BIT_OS
   do_check_throws(function() {
       ctypes.FunctionType(ctypes.stdcall_abi, ctypes.bool,
                           [ctypes.bool, "..."]);
   }, Error);
   do_check_throws(function() {
       ctypes.FunctionType(ctypes.winapi_abi, ctypes.bool,
                           [ctypes.bool, "..."]);
   }, Error);
 #endif
-#endif
 
   do_check_throws(function() {
     // No variadic closure callbacks allowed.
     sum_va_type(function(){});
   }, Error);
 
   let count_true_va = library.declare("test_sum_va_cdecl", ctypes.default_abi, ctypes.uint8_t,
                                       ctypes.uint8_t, "...");