--- a/toolkit/components/ctypes/tests/jsctypes-test.cpp
+++ b/toolkit/components/ctypes/tests/jsctypes-test.cpp
@@ -70,70 +70,72 @@ template <> struct ValueTraits<bool> {
void
test_void_t_cdecl()
{
// do nothing
return;
}
-#define DEFINE_TYPE(name, type, ffiType) \
+#define FUNCTION_TESTS(name, type, ffiType, suffix) \
type ABI \
-get_##name##_cdecl() \
+get_##name##_##suffix() \
{ \
return ValueTraits<type>::literal(); \
} \
\
type ABI \
-set_##name##_cdecl(type x) \
+set_##name##_##suffix(type x) \
{ \
return x; \
} \
\
type ABI \
-sum_##name##_cdecl(type x, type y) \
+sum_##name##_##suffix(type x, type y) \
{ \
return ValueTraits<type>::sum(x, y); \
} \
\
type ABI \
-sum_alignb_##name##_cdecl(char a, type x, char b, type y, char c) \
+sum_alignb_##name##_##suffix(char a, type x, char b, type y, char c) \
{ \
return ValueTraits<type>::sum(x, y); \
} \
\
type ABI \
-sum_alignf_##name##_cdecl(float a, type x, float b, type y, float c) \
+sum_alignf_##name##_##suffix(float a, type x, float b, type y, float c) \
{ \
return ValueTraits<type>::sum(x, y); \
} \
\
type ABI \
-sum_many_##name##_cdecl( \
+sum_many_##name##_##suffix( \
type a, type b, type c, type d, type e, type f, type g, type h, type i, \
type j, type k, type l, type m, type n, type o, type p, type q, type r) \
{ \
return ValueTraits<type>::sum_many(a, b, c, d, e, f, g, h, i, \
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)
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) */
#define DEFINE_TYPE(name, type, ffiType) \
struct align_##name { \
char x; \
@@ -316,17 +318,17 @@ test_fnptr()
PRInt32
test_closure_cdecl(PRInt8 i, PRInt32 (*f)(PRInt8))
{
return f(i);
}
#if defined(_WIN32) && !defined(_WIN64)
PRInt32
-test_closure_cdecl(PRInt8 i, PRInt32 (NS_STDCALL *f)(PRInt8))
+test_closure_stdcall(PRInt8 i, PRInt32 (NS_STDCALL *f)(PRInt8))
{
return f(i);
}
#endif /* defined(_WIN32) && !defined(_WIN64) */
template <typename T> struct PromotedTraits {
typedef T type;
};
--- a/toolkit/components/ctypes/tests/unit/test_jsctypes.js.in
+++ b/toolkit/components/ctypes/tests/unit/test_jsctypes.js.in
@@ -648,61 +648,87 @@ function run_UInt64_tests() {
do_check_throws(function() { ctypes.UInt64.join(0x100000000, 0); }, TypeError);
do_check_throws(function() { ctypes.UInt64.join(0, -0x1); }, TypeError);
do_check_throws(function() { ctypes.UInt64.join(0, 0x1000000000); }, TypeError);
}
function run_basic_abi_tests(library, t, name, toprimitive,
get_test, set_tests, sum_tests, sum_many_tests) {
// Test the function call ABI for calls involving the type.
- run_single_abi_tests(library, ctypes.default_abi, t, name + "_cdecl",
+ 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 _WIN64
- run_single_abi_tests(library, ctypes.stdcall_abi, t, name + "_stdcall",
+
+#ifdef WIN32
+#ifndef HAVE_64BIT_OS
+ function declare_fn_stdcall(fn_t, prefix) {
+ return library.declare(
+ // stdcall functions have the symbol name postfixed with the (aligned)
+ // size of the args.
+ "_" + prefix + name + "_stdcall" + "@" + argsize(fn_t.targetType.argTypes), fn_t);
+ }
+ function argsize(arglist) {
+ let size = 0;
+ for each (let a in arglist) {
+ if (a.size % 4 == 0)
+ size += a.size;
+ else
+ size += a.size + 4 - a.size % 4;
+ }
+ return size;
+ }
+ run_single_abi_tests(declare_fn_stdcall, ctypes.stdcall_abi, t,
toprimitive, get_test, set_tests, sum_tests, sum_many_tests);
#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(library, abi, t, name, toprimitive,
+function run_single_abi_tests(decl, abi, t, toprimitive,
get_test, set_tests, sum_tests, sum_many_tests) {
- let getter = library.declare("get_" + name, abi, t);
+ let getter_t = ctypes.FunctionType(abi, t).ptr;
+ let getter = decl(getter_t, "get_");
do_check_eq(toprimitive(getter()), get_test);
- let setter = library.declare("set_" + name, ctypes.default_abi, t, t);
+ let setter_t = ctypes.FunctionType(abi, t, [t]).ptr;
+ let setter = decl(setter_t, "set_");
for each (let i in set_tests)
do_check_eq(toprimitive(setter(i)), i);
- let sum = library.declare("sum_" + name, ctypes.default_abi, t, t, t);
+ let sum_t = ctypes.FunctionType(abi, t, [t, t]).ptr;
+ let sum = decl(sum_t, "sum_");
for each (let a in sum_tests)
do_check_eq(toprimitive(sum(a[0], a[1])), a[2]);
- let sum_alignb = library.declare("sum_alignb_" + name, ctypes.default_abi, t,
- ctypes.char, t, ctypes.char, t, ctypes.char);
- let sum_alignf = library.declare("sum_alignf_" + name, ctypes.default_abi, t,
- ctypes.float, t, ctypes.float, t, ctypes.float);
+ let sum_alignb_t = ctypes.FunctionType(abi, t,
+ [ctypes.char, t, ctypes.char, t, ctypes.char]).ptr;
+ let sum_alignb = decl(sum_alignb_t, "sum_alignb_");
+ let sum_alignf_t = ctypes.FunctionType(abi, t,
+ [ctypes.float, t, ctypes.float, t, ctypes.float]).ptr;
+ let sum_alignf = decl(sum_alignf_t, "sum_alignf_");
for each (let a in sum_tests) {
do_check_eq(toprimitive(sum_alignb(0, a[0], 0, a[1], 0)), a[2]);
do_check_eq(toprimitive(sum_alignb(1, a[0], 1, a[1], 1)), a[2]);
do_check_eq(toprimitive(sum_alignf(0, a[0], 0, a[1], 0)), a[2]);
do_check_eq(toprimitive(sum_alignf(1, a[0], 1, a[1], 1)), a[2]);
}
- let sum_many = library.declare("sum_many_" + name, ctypes.default_abi, t,
- t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t);
+ let sum_many_t = ctypes.FunctionType(abi, t,
+ [t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t]).ptr;
+ let sum_many = decl(sum_many_t, "sum_many_");
for each (let a in sum_many_tests)
- do_check_eq(toprimitive(
- sum_many(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
- a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
- a[16], a[17])), a[18]);
+ do_check_eq(
+ toprimitive(sum_many(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
+ a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
+ a[16], a[17])), a[18]);
}
function check_struct_stats(library, t) {
let s_t = ctypes.StructType("s_t", [{ x: ctypes.char }, { y: t }]);
let n_t = ctypes.StructType("n_t", [{ a: ctypes.char }, { b: s_t }, { c: ctypes.char }]);
let get_stats = library.declare("get_" + t.name + "_stats",
ctypes.default_abi, ctypes.void_t,
ctypes.size_t.ptr, ctypes.size_t.ptr, ctypes.size_t.ptr, ctypes.size_t.ptr,
@@ -1819,21 +1845,21 @@ function run_FunctionType_tests() {
// Test some more complex names.
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 _WIN64
+#ifdef WIN32
+#ifndef HAVE_64BIT_OS
f3_t = ctypes.FunctionType(ctypes.stdcall_abi,
- ctypes.char.ptr.array().ptr).ptr.array(8).array();
- do_check_eq(f3_t.ptr.name, "char*(__stdcall *(**[][8])())[]");
+ ctypes.char.ptr.array().ptr).ptr.ptr.array(8).array();
+ do_check_eq(f3_t.name, "char*(*(__stdcall **[][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);
@@ -2011,19 +2037,19 @@ function run_void_tests(library) {
let test_void_t = library.declare("test_void_t_cdecl", ctypes.default_abi, ctypes.void_t);
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 _WIN64
- test_void_t = library.declare("test_void_t_stdcall", ctypes.stdcall_abi, ctypes.void_t);
+#ifdef WIN32
+#ifndef HAVE_64BIT_OS
+ test_void_t = library.declare("_test_void_t_stdcall@0", ctypes.stdcall_abi, ctypes.void_t);
do_check_eq(test_void_t(), undefined);
#endif
#endif
}
function run_string_tests(library) {
let test_ansi_len = library.declare("test_ansi_len", ctypes.default_abi, ctypes.int32_t, ctypes.char.ptr);
do_check_eq(test_ansi_len(""), 0);
@@ -2165,19 +2191,20 @@ function run_function_tests(library)
do_check_eq(ptrValue(test_ansi_len), ptrValue(test_ansi_len_2));
do_check_throws(function() { test_ansi_len_2.value = null; }, Error);
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 _WIN64
- run_single_closure_tests(library, ctypes.stdcall_abi, "stdcall");
+#ifdef WIN32
+#ifndef HAVE_64BIT_OS
+ // stdcall closure tests are currently broken on windows. see bug 564966.
+ //run_single_closure_tests(library, ctypes.stdcall_abi, "stdcall");
#endif
#endif
}
function run_single_closure_tests(library, abi, suffix)
{
let b = 23;
@@ -2228,18 +2255,18 @@ function run_variadic_tests(library) {
ctypes.FunctionType(ctypes.default_abi, ctypes.bool,
[ctypes.bool, "...", ctypes.bool]);
}, Error);
do_check_throws(function() {
ctypes.FunctionType(ctypes.default_abi, ctypes.bool, ["..."]);
}, Error);
-#ifdef _WIN32
-#ifndef _WIN64
+#ifdef WIN32
+#ifndef HAVE_64BIT_OS
do_check_throws(function() {
ctypes.FunctionType(ctypes.stdcall_abi, ctypes.bool,
[ctypes.bool, "..."]);
}, Error);
#endif
#endif
do_check_throws(function() {