/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2; -*- * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "jsctypes-test.h" #include #include #include #include "typedefs.h" template struct ValueTraits { static T literal() { return static_cast(109.25); } static T sum(T a, T b) { return a + b; } static T sum_many(T a, T b, T c, T d, T e, T f, T g, T h, T i, T j, T k, T l, T m, T n, T o, T p, T q, T r) { return a + b + c + d + e + f + g + h + i + j + k + l + m + n + o + p + q + r; } }; template <> struct ValueTraits { typedef bool T; static T literal() { return true; } static T sum(T a, T b) { return a || b; } static T sum_many(T a, T b, T c, T d, T e, T f, T g, T h, T i, T j, T k, T l, T m, T n, T o, T p, T q, T r) { return a || b || c || d || e || f || g || h || i || j || k || l || m || n || o || p || q || r; } }; void test_void_t_cdecl() { // do nothing } // The "AndUnderscore" bit here is an unfortunate hack: the first argument to // DEFINE_CDECL_FUNCTIONS and DEFINE_STDCALL_FUNCTIONS, in addition to being a // type, may also be a *macro* on NetBSD -- #define int8_t __int8_t and so on. // See . // And unfortunately, passing that macro as an argument to this macro causes it // to be expanded -- producing get___int8_t_cdecl() and so on. Concatenating // int8_t with _ slightly muddies this code but inhibits expansion. See also // bug 1113379. #define FUNCTION_TESTS(nameAndUnderscore, type, ffiType, suffix) \ type ABI get_##nameAndUnderscore##suffix() { \ return ValueTraits::literal(); \ } \ \ type ABI set_##nameAndUnderscore##suffix(type x) { return x; } \ \ type ABI sum_##nameAndUnderscore##suffix(type x, type y) { \ return ValueTraits::sum(x, y); \ } \ \ type ABI sum_alignb_##nameAndUnderscore##suffix(char a, type x, char b, \ type y, char c) { \ return ValueTraits::sum(x, y); \ } \ \ type ABI sum_alignf_##nameAndUnderscore##suffix(float a, type x, float b, \ type y, float c) { \ return ValueTraits::sum(x, y); \ } \ \ type ABI sum_many_##nameAndUnderscore##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::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_CDECL_FUNCTIONS(x, y, z) FUNCTION_TESTS(x##_, y, z, cdecl) CTYPES_FOR_EACH_TYPE(DEFINE_CDECL_FUNCTIONS) #undef DEFINE_CDECL_FUNCTIONS #undef ABI #if defined(_WIN32) void NS_STDCALL test_void_t_stdcall() { // do nothing return; } # define ABI NS_STDCALL # define DEFINE_STDCALL_FUNCTIONS(x, y, z) FUNCTION_TESTS(x##_, y, z, stdcall) CTYPES_FOR_EACH_TYPE(DEFINE_STDCALL_FUNCTIONS) # undef DEFINE_STDCALL_FUNCTIONS # undef ABI #endif /* defined(_WIN32) */ #define DEFINE_CDECL_TYPE_STATS(name, type, ffiType) \ struct align_##name { \ char x; \ type y; \ }; \ struct nested_##name { \ char a; \ align_##name b; \ char c; \ }; \ \ void get_##name##_stats(size_t* align, size_t* size, size_t* nalign, \ size_t* nsize, size_t offsets[]) { \ *align = offsetof(align_##name, y); \ *size = sizeof(align_##name); \ *nalign = offsetof(nested_##name, b); \ *nsize = sizeof(nested_##name); \ offsets[0] = offsetof(align_##name, y); \ offsets[1] = offsetof(nested_##name, b); \ offsets[2] = offsetof(nested_##name, c); \ } CTYPES_FOR_EACH_TYPE(DEFINE_CDECL_TYPE_STATS) #undef DEFINE_CDECL_TYPE_STATS template int32_t StrLen(const T* string) { const T* end; for (end = string; *end; ++end) ; return end - string; } int32_t test_ansi_len(const char* string) { return StrLen(string); } int32_t test_wide_len(const char16_t* string) { return StrLen(string); } const char* test_ansi_ret() { return "success"; } const char16_t* test_wide_ret() { static const char16_t kSuccess[] = {'s', 'u', 'c', 'c', 'e', 's', 's', '\0'}; return kSuccess; } char* test_ansi_echo(const char* string) { return (char*)string; } int32_t test_pt_in_rect(myRECT rc, myPOINT pt) { if (pt.x < rc.left || pt.x > rc.right) return 0; if (pt.y < rc.bottom || pt.y > rc.top) return 0; return 1; } void test_init_pt(myPOINT* pt, int32_t x, int32_t y) { pt->x = x; pt->y = y; } int32_t test_nested_struct(NESTED n) { return int32_t(n.n1 + n.n2 + n.inner.i1 + n.inner.i2 + n.inner.i3 + n.n3 + n.n4); } myPOINT test_struct_return(myRECT r) { myPOINT p; p.x = r.left; p.y = r.top; return p; } myRECT test_large_struct_return(myRECT a, myRECT b) { myRECT r; r.left = a.left; r.right = a.right; r.top = b.top; r.bottom = b.bottom; return r; } ONE_BYTE test_1_byte_struct_return(myRECT r) { ONE_BYTE s; s.a = r.top; return s; } TWO_BYTE test_2_byte_struct_return(myRECT r) { TWO_BYTE s; s.a = r.top; s.b = r.left; return s; } THREE_BYTE test_3_byte_struct_return(myRECT r) { THREE_BYTE s; s.a = r.top; s.b = r.left; s.c = r.bottom; return s; } FOUR_BYTE test_4_byte_struct_return(myRECT r) { FOUR_BYTE s; s.a = r.top; s.b = r.left; s.c = r.bottom; s.d = r.right; return s; } FIVE_BYTE test_5_byte_struct_return(myRECT r) { FIVE_BYTE s; s.a = r.top; s.b = r.left; s.c = r.bottom; s.d = r.right; s.e = r.top; return s; } SIX_BYTE test_6_byte_struct_return(myRECT r) { SIX_BYTE s; s.a = r.top; s.b = r.left; s.c = r.bottom; s.d = r.right; s.e = r.top; s.f = r.left; return s; } SEVEN_BYTE test_7_byte_struct_return(myRECT r) { SEVEN_BYTE s; s.a = r.top; s.b = r.left; s.c = r.bottom; s.d = r.right; s.e = r.top; s.f = r.left; s.g = r.bottom; return s; } void* test_fnptr() { return (void*)(uintptr_t)test_ansi_len; } int32_t test_closure_cdecl(int8_t i, test_func_ptr f) { return f(i); } #if defined(_WIN32) int32_t test_closure_stdcall(int8_t i, test_func_ptr_stdcall f) { return f(i); } #endif /* defined(_WIN32) */ template struct PromotedTraits { typedef T type; }; #define DECL_PROMOTED(FROM, TO) \ template <> \ struct PromotedTraits { \ typedef TO type; \ } DECL_PROMOTED(bool, int); DECL_PROMOTED(char, int); DECL_PROMOTED(short, int); int32_t test_sum_va_cdecl(uint8_t n, ...) { va_list list; int32_t sum = 0; va_start(list, n); for (uint8_t i = 0; i < n; ++i) sum += va_arg(list, PromotedTraits::type); va_end(list); return sum; } uint8_t test_count_true_va_cdecl(uint8_t n, ...) { va_list list; uint8_t count = 0; va_start(list, n); for (uint8_t i = 0; i < n; ++i) if (va_arg(list, PromotedTraits::type)) count += 1; va_end(list); return count; } void test_add_char_short_int_va_cdecl(uint32_t* result, ...) { va_list list; va_start(list, result); *result += va_arg(list, PromotedTraits::type); *result += va_arg(list, PromotedTraits::type); *result += va_arg(list, PromotedTraits::type); va_end(list); } int32_t* test_vector_add_va_cdecl(uint8_t num_vecs, uint8_t vec_len, int32_t* result, ...) { va_list list; va_start(list, result); uint8_t i; for (i = 0; i < vec_len; ++i) result[i] = 0; for (i = 0; i < num_vecs; ++i) { int32_t* vec = va_arg(list, int32_t*); for (uint8_t j = 0; j < vec_len; ++j) result[j] += vec[j]; } va_end(list); return result; } myRECT data_rect = {-1, -2, 3, 4}; TestClass::TestClass(int32_t a) { mInt = a; } int32_t TestClass::Add(int32_t aOther) { mInt += aOther; return mInt; }