Abandon standard C conformance and require GNU extensions
Removed the use_gnu_ext option as well as fallback paths for compilers that don't support GNU extensions. To my knowledge, none of those compilers support C11 to a sufficient extent to compile Taisei anyway, and those fallbacks are very poorly tested. Pedantic warnings are now disabled, and extensions that are common to reasonably recent versions of GCC and clang are permitted to be relied on (list of allowed extensions TBA).
This commit is contained in:
parent
f3fcec70f6
commit
f73b1d6891
10 changed files with 112 additions and 164 deletions
|
@ -3,7 +3,6 @@ project('taisei', 'c',
|
|||
version : 'v1.4-dev',
|
||||
meson_version : '>=0.53.0',
|
||||
default_options : [
|
||||
# Should really be c11, but gnu11 is a safer default because everything is terrible.
|
||||
'c_std=gnu11',
|
||||
|
||||
'default_library=static',
|
||||
|
@ -60,7 +59,6 @@ config = configuration_data()
|
|||
|
||||
taisei_c_args = [
|
||||
'-Wall',
|
||||
'-Wpedantic',
|
||||
|
||||
'-Werror=assume',
|
||||
'-Werror=implicit-function-declaration',
|
||||
|
@ -81,10 +79,8 @@ taisei_c_args = [
|
|||
'-Wfloat-overflow-conversion',
|
||||
'-Wfloat-zero-conversion',
|
||||
'-Wfor-loop-analysis',
|
||||
'-Wformat-pedantic',
|
||||
'-Wformat-security',
|
||||
'-Wgcc-compat',
|
||||
'-Wgnu',
|
||||
'-Wignored-qualifiers',
|
||||
'-Winit-self',
|
||||
'-Wlogical-op',
|
||||
|
@ -272,7 +268,6 @@ else
|
|||
config.set('TAISEI_BUILDCONF_HAVE_MAX_ALIGN_T', malloc_alignment > 0)
|
||||
endif
|
||||
|
||||
config.set('TAISEI_BUILDCONF_USE_GNU_EXTENSIONS', get_option('use_gnu_ext'))
|
||||
config.set('TAISEI_BUILDCONF_HAVE_BUILTIN_POPCOUNTLL', cc.has_function('__builtin_popcountll'))
|
||||
config.set('TAISEI_BUILDCONF_HAVE_BUILTIN_POPCOUNT', cc.has_function('__builtin_popcount'))
|
||||
config.set('TAISEI_BUILDCONF_HAVE_BUILTIN_AVAILABLE', cc.has_function('__builtin_available'))
|
||||
|
|
|
@ -190,10 +190,3 @@ option(
|
|||
value : false,
|
||||
description : 'Build shaderc and spirv-cross CLI tools from subprojects even if system versions exist'
|
||||
)
|
||||
|
||||
option(
|
||||
'use_gnu_ext',
|
||||
type : 'boolean',
|
||||
value : true,
|
||||
description : 'Allow use of some GNU C extensions (if supported by compiler)'
|
||||
)
|
||||
|
|
135
src/dynarray.h
135
src/dynarray.h
|
@ -33,43 +33,26 @@ typedef DYNAMIC_ARRAY_BASE(void) DynamicArray;
|
|||
DynamicArray dyn_array; \
|
||||
}
|
||||
|
||||
#ifdef USE_GNU_EXTENSIONS
|
||||
#define DYNARRAY_ASSERT_VALID(darr) do { \
|
||||
static_assert( \
|
||||
__builtin_types_compatible_p(DynamicArray, __typeof__((darr)->dyn_array)), \
|
||||
"x->dyn_array must be of DynamicArray type"); \
|
||||
static_assert( \
|
||||
__builtin_offsetof(__typeof__(*(darr)), dyn_array) == 0, \
|
||||
"x->dyn_array must be the first member in struct"); \
|
||||
} while(0)
|
||||
#else
|
||||
#define DYNARRAY_ASSERT_VALID(darr) ((void)0)
|
||||
#endif
|
||||
#define DYNARRAY_ASSERT_VALID(darr) do { \
|
||||
static_assert( \
|
||||
__builtin_types_compatible_p(DynamicArray, __typeof__((darr)->dyn_array)), \
|
||||
"x->dyn_array must be of DynamicArray type"); \
|
||||
static_assert( \
|
||||
__builtin_offsetof(__typeof__(*(darr)), dyn_array) == 0, \
|
||||
"x->dyn_array must be the first member in struct"); \
|
||||
} while(0)
|
||||
|
||||
#ifdef USE_GNU_EXTENSIONS
|
||||
#define DYNARRAY_CAST_TO_BASE(darr) (__extension__ ({ \
|
||||
DYNARRAY_ASSERT_VALID(darr); \
|
||||
&NOT_NULL(darr)->dyn_array; \
|
||||
}))
|
||||
#else
|
||||
#define DYNARRAY_CAST_TO_BASE(darr) (&(darr)->dyn_array)
|
||||
#endif
|
||||
#define DYNARRAY_CAST_TO_BASE(darr) ({ \
|
||||
DYNARRAY_ASSERT_VALID(darr); \
|
||||
&NOT_NULL(darr)->dyn_array; \
|
||||
})
|
||||
|
||||
#ifdef USE_GNU_EXTENSIONS
|
||||
#define DYNARRAY_CHECK_ELEMENT_TYPE(darr, elem) do { \
|
||||
static_assert( \
|
||||
__builtin_types_compatible_p(__typeof__(elem), __typeof__(*(darr)->data)), \
|
||||
"Dynamic array element type mismatch" \
|
||||
); \
|
||||
} while(0)
|
||||
#else
|
||||
#define DYNARRAY_CHECK_ELEMENT_TYPE(darr, elem) do { \
|
||||
static_assert( \
|
||||
sizeof(elem) == sizeof(*(darr)->data), \
|
||||
"Dynamic array element size mismatch" \
|
||||
); \
|
||||
} while(0)
|
||||
#endif
|
||||
#define DYNARRAY_CHECK_ELEMENT_TYPE(darr, elem) do { \
|
||||
static_assert( \
|
||||
__builtin_types_compatible_p(__typeof__(elem), __typeof__(*(darr)->data)), \
|
||||
"Dynamic array element type mismatch" \
|
||||
); \
|
||||
} while(0)
|
||||
|
||||
#define DYNARRAY_ELEM_SIZE(darr) sizeof(*(darr)->data)
|
||||
|
||||
|
@ -97,15 +80,10 @@ dynarray_size_t _dynarray_prepare_append_with_min_capacity(dynarray_size_t sizeo
|
|||
#define _dynarray_append_with_min_capacity(darr, min_capacity) \
|
||||
dynarray_get_ptr(darr, _dynarray_dispatch_func(prepare_append_with_min_capacity, darr, min_capacity))
|
||||
|
||||
#ifdef USE_GNU_EXTENSIONS
|
||||
#define dynarray_append_with_min_capacity(darr, min_capacity) (__extension__ ({ \
|
||||
assume((darr) != NULL); \
|
||||
_dynarray_append_with_min_capacity((darr), min_capacity); \
|
||||
}))
|
||||
#else
|
||||
#define dynarray_append_with_min_capacity(darr, min_capacity) \
|
||||
_dynarray_append_with_min_capacity((darr), min_capacity)
|
||||
#endif
|
||||
#define dynarray_append_with_min_capacity(darr, min_capacity) ({ \
|
||||
__auto_type _darr2 = NOT_NULL(darr); \
|
||||
dynarray_get_ptr(_darr2, _dynarray_dispatch_func(prepare_append_with_min_capacity, _darr2, min_capacity)); \
|
||||
})
|
||||
|
||||
#define dynarray_append(darr) \
|
||||
dynarray_append_with_min_capacity(darr, 2)
|
||||
|
@ -121,23 +99,22 @@ void _dynarray_compact(dynarray_size_t sizeof_element, DynamicArray *darr) attr_
|
|||
} \
|
||||
} while(0)
|
||||
|
||||
#ifdef USE_GNU_EXTENSIONS
|
||||
#define dynarray_get_ptr(darr, idx) (__extension__ ({ \
|
||||
DYNARRAY_ASSERT_VALID(darr); \
|
||||
__auto_type _darr = NOT_NULL(darr); \
|
||||
dynarray_size_t _darr_idx = (idx); \
|
||||
assume(_darr_idx >= 0); \
|
||||
assume(_darr_idx < _darr->num_elements); \
|
||||
NOT_NULL((darr)->data + _darr_idx); \
|
||||
}))
|
||||
#else
|
||||
#define dynarray_get_ptr(darr, idx) ((darr)->data + (idx))
|
||||
#endif
|
||||
#define dynarray_get_ptr(darr, idx) ({ \
|
||||
DYNARRAY_ASSERT_VALID(darr); \
|
||||
__auto_type _darr = NOT_NULL(darr); \
|
||||
dynarray_size_t _darr_idx = (idx); \
|
||||
assume(_darr_idx >= 0); \
|
||||
assume(_darr_idx < _darr->num_elements); \
|
||||
NOT_NULL((darr)->data + _darr_idx); \
|
||||
})
|
||||
|
||||
#define dynarray_get(darr, idx) (*dynarray_get_ptr(darr, idx))
|
||||
#define dynarray_get(darr, idx) (*dynarray_get_ptr(darr, idx))
|
||||
#define dynarray_set(darr, idx, ...) ((*dynarray_get_ptr(darr, idx)) = (__VA_ARGS__))
|
||||
|
||||
void _dynarray_set_elements(dynarray_size_t sizeof_element, DynamicArray *darr, dynarray_size_t num_elements, void *elements) attr_nonnull_all;
|
||||
void _dynarray_set_elements(
|
||||
dynarray_size_t sizeof_element, DynamicArray *darr,
|
||||
dynarray_size_t num_elements, void *elements
|
||||
) attr_nonnull_all;
|
||||
#define dynarray_set_elements(darr, num_elements, elements) do { \
|
||||
DYNARRAY_ASSERT_VALID(darr); \
|
||||
DYNARRAY_CHECK_ELEMENT_TYPE(darr, *(elements)); \
|
||||
|
@ -145,24 +122,23 @@ void _dynarray_set_elements(dynarray_size_t sizeof_element, DynamicArray *darr,
|
|||
} while(0)
|
||||
|
||||
typedef bool (*dynarray_filter_predicate_t)(const void *pelem, void *userdata);
|
||||
void _dynarray_filter(dynarray_size_t sizeof_element, DynamicArray *darr, dynarray_filter_predicate_t predicate, void *userdata) attr_nonnull(2, 3);
|
||||
void _dynarray_filter(
|
||||
dynarray_size_t sizeof_element, DynamicArray *darr,
|
||||
dynarray_filter_predicate_t predicate, void *userdata
|
||||
) attr_nonnull(2, 3);
|
||||
#define dynarray_filter(darr, predicate, userdata) \
|
||||
_dynarray_dispatch_func(filter, darr, predicate, userdata)
|
||||
|
||||
#ifdef USE_GNU_EXTENSIONS
|
||||
#define dynarray_indexof(darr, pelem) (__extension__ ({ \
|
||||
DYNARRAY_ASSERT_VALID(darr); \
|
||||
__auto_type _darr = NOT_NULL(darr); \
|
||||
__auto_type _darr_pelem = NOT_NULL(pelem); \
|
||||
DYNARRAY_CHECK_ELEMENT_TYPE(_darr, *(_darr_pelem)); \
|
||||
intptr_t _darr_idx = (intptr_t)(_darr_pelem - _darr->data); \
|
||||
assume(_darr_idx >= 0); \
|
||||
assume(_darr_idx < _darr->num_elements); \
|
||||
(dynarray_size_t)_darr_idx; \
|
||||
}))
|
||||
#else
|
||||
#define dynarray_indexof(darr, pelem) ((intptr_t)((pelem) - (darr)->data))
|
||||
#endif
|
||||
#define dynarray_indexof(darr, pelem) ({ \
|
||||
DYNARRAY_ASSERT_VALID(darr); \
|
||||
__auto_type _darr = NOT_NULL(darr); \
|
||||
__auto_type _darr_pelem = NOT_NULL(pelem); \
|
||||
DYNARRAY_CHECK_ELEMENT_TYPE(_darr, *(_darr_pelem)); \
|
||||
intptr_t _darr_idx = (intptr_t)(_darr_pelem - _darr->data); \
|
||||
assume(_darr_idx >= 0); \
|
||||
assume(_darr_idx < _darr->num_elements); \
|
||||
(dynarray_size_t)_darr_idx; \
|
||||
})
|
||||
|
||||
#define _dynarray_foreach_iter MACROHAX_ADDLINENUM(_dynarray_foreach_iter)
|
||||
#define _dynarray_foreach_ignored MACROHAX_ADDLINENUM(_dynarray_foreach_ignored)
|
||||
|
@ -179,9 +155,18 @@ void _dynarray_filter(dynarray_size_t sizeof_element, DynamicArray *darr, dynarr
|
|||
} while(0)
|
||||
|
||||
#define dynarray_foreach_elem(_darr, _pelem_var, ...) \
|
||||
dynarray_foreach(_darr, attr_unused dynarray_size_t _dynarray_foreach_ignored, _pelem_var, __VA_ARGS__)
|
||||
dynarray_foreach( \
|
||||
_darr, \
|
||||
attr_unused dynarray_size_t _dynarray_foreach_ignored, \
|
||||
_pelem_var, \
|
||||
__VA_ARGS__ \
|
||||
)
|
||||
|
||||
#define dynarray_foreach_idx(_darr, _cntr_var, ...) \
|
||||
dynarray_foreach(_darr, _cntr_var, attr_unused void *_dynarray_foreach_ignored, __VA_ARGS__)
|
||||
dynarray_foreach(_darr, \
|
||||
_cntr_var, \
|
||||
attr_unused void *_dynarray_foreach_ignored, \
|
||||
__VA_ARGS__ \
|
||||
)
|
||||
|
||||
#endif // IGUARD_dynarray_h
|
||||
|
|
14
src/entity.h
14
src/entity.h
|
@ -125,15 +125,11 @@ INLINE const char *ent_type_name(EntityType type) {
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef USE_GNU_EXTENSIONS
|
||||
#define ENT_CAST(ent, typename) (__extension__ ({ \
|
||||
__auto_type _ent = ent; \
|
||||
assert(_ent->type == ENT_TYPE_ID(typename)); \
|
||||
UNION_CAST(EntityInterface*, typename*, _ent); \
|
||||
}))
|
||||
#else
|
||||
#define ENT_CAST(ent, typename) UNION_CAST(EntityInterface*, typename*, (ent));
|
||||
#endif
|
||||
#define ENT_CAST(ent, typename) ({ \
|
||||
__auto_type _ent = ent; \
|
||||
assert(_ent->type == ENT_TYPE_ID(typename)); \
|
||||
UNION_CAST(EntityInterface*, typename*, _ent); \
|
||||
})
|
||||
|
||||
void ent_init(void);
|
||||
void ent_shutdown(void);
|
||||
|
|
|
@ -79,7 +79,7 @@ void eventloop_run(void) {
|
|||
em_handle_resize_event, NULL, EPRIO_SYSTEM, MAKE_TAISEI_EVENT(TE_VIDEO_MODE_CHANGED)
|
||||
});
|
||||
|
||||
(__extension__ EM_ASM({
|
||||
EM_ASM({
|
||||
Module['onFirstFrame']();
|
||||
}));
|
||||
});
|
||||
}
|
||||
|
|
60
src/list.h
60
src/list.h
|
@ -101,42 +101,36 @@ ListContainer* list_wrap_container(void *data) attr_returns_allocated;
|
|||
|
||||
// type-generic macros
|
||||
|
||||
#ifdef USE_GNU_EXTENSIONS
|
||||
// thorough safeguard
|
||||
#define LIST_CAST(expr) ({ \
|
||||
static_assert(__builtin_types_compatible_p( \
|
||||
ListInterface, __typeof__((*(expr)).list_interface)), \
|
||||
"struct must implement ListInterface (use the LIST_INTERFACE macro)"); \
|
||||
static_assert(__builtin_offsetof(__typeof__(*(expr)), list_interface) == 0, \
|
||||
"list_interface must be the first member in struct"); \
|
||||
CASTPTR_ASSUME_ALIGNED((expr), List); \
|
||||
})
|
||||
|
||||
#define LIST_CAST(expr) (__extension__ ({ \
|
||||
static_assert(__builtin_types_compatible_p(ListInterface, __typeof__((*(expr)).list_interface)), \
|
||||
"struct must implement ListInterface (use the LIST_INTERFACE macro)"); \
|
||||
static_assert(__builtin_offsetof(__typeof__(*(expr)), list_interface) == 0, \
|
||||
"list_interface must be the first member in struct"); \
|
||||
CASTPTR_ASSUME_ALIGNED((expr), List); \
|
||||
}))
|
||||
#define LIST_CAST_2(expr) ({ \
|
||||
static_assert(__builtin_types_compatible_p(\
|
||||
ListInterface, __typeof__((**(expr)).list_interface)), \
|
||||
"struct must implement ListInterface (use the LIST_INTERFACE macro)"); \
|
||||
static_assert(__builtin_offsetof(__typeof__(**(expr)), list_interface) == 0, \
|
||||
"list_interface must be the first member in struct"); \
|
||||
(void)ASSUME_ALIGNED(*(expr), alignof(List)); \
|
||||
(List**)(expr); \
|
||||
})
|
||||
|
||||
#define LIST_CAST_2(expr) (__extension__ ({ \
|
||||
static_assert(__builtin_types_compatible_p(ListInterface, __typeof__((**(expr)).list_interface)), \
|
||||
"struct must implement ListInterface (use the LIST_INTERFACE macro)"); \
|
||||
static_assert(__builtin_offsetof(__typeof__(**(expr)), list_interface) == 0, \
|
||||
"list_interface must be the first member in struct"); \
|
||||
(void)ASSUME_ALIGNED(*(expr), alignof(List)); \
|
||||
(List**)(expr); \
|
||||
}))
|
||||
#define LIST_ANCHOR_CAST(expr) ({ \
|
||||
static_assert(__builtin_types_compatible_p(\
|
||||
ListAnchorInterface, __typeof__((*(expr)).list_anchor_interface)), \
|
||||
"struct must implement ListAnchorInterface (use the LIST_ANCHOR_INTERFACE macro)"); \
|
||||
static_assert(__builtin_offsetof(__typeof__(*(expr)), list_anchor_interface) == 0, \
|
||||
"list_anchor_interface must be the first member in struct"); \
|
||||
CASTPTR_ASSUME_ALIGNED((expr), ListAnchor); \
|
||||
})
|
||||
|
||||
#define LIST_ANCHOR_CAST(expr) (__extension__ ({ \
|
||||
static_assert(__builtin_types_compatible_p(ListAnchorInterface, __typeof__((*(expr)).list_anchor_interface)), \
|
||||
"struct must implement ListAnchorInterface (use the LIST_ANCHOR_INTERFACE macro)"); \
|
||||
static_assert(__builtin_offsetof(__typeof__(*(expr)), list_anchor_interface) == 0, \
|
||||
"list_anchor_interface must be the first member in struct"); \
|
||||
CASTPTR_ASSUME_ALIGNED((expr), ListAnchor); \
|
||||
}))
|
||||
|
||||
#define LIST_CAST_RETURN(e_typekey, e_return) CASTPTR_ASSUME_ALIGNED((e_return), __typeof__(*(e_typekey)))
|
||||
#else
|
||||
// basic safeguard
|
||||
#define LIST_CAST(expr) ((void)sizeof((*(expr)).list_interface), (List*)(expr))
|
||||
#define LIST_CAST_2(expr) ((void)sizeof((**(expr)).list_interface), (List**)(expr))
|
||||
#define LIST_ANCHOR_CAST(expr) ((void)sizeof((*(expr)).list_anchor_interface), (ListAnchor*)(expr))
|
||||
#define LIST_CAST_RETURN(e_typekey, e_return) (void*)(e_return)
|
||||
#endif
|
||||
#define LIST_CAST_RETURN(e_typekey, e_return) \
|
||||
CASTPTR_ASSUME_ALIGNED((e_return), __typeof__(*(e_typekey)))
|
||||
|
||||
#define list_insert(dest,elem) \
|
||||
(LIST_CAST_RETURN(elem, list_insert(LIST_CAST_2(dest), LIST_CAST(elem))))
|
||||
|
|
|
@ -26,8 +26,8 @@ void _ts_assert_fail(const char *cond, const char *func, const char *file, int l
|
|||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
void _emscripten_trap(void) {
|
||||
(__extension__ EM_ASM({
|
||||
EM_ASM({
|
||||
throw new Error("You just activated my trap card!");
|
||||
}));
|
||||
});
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -76,12 +76,9 @@
|
|||
|
||||
#define PRAGMA(p) _Pragma(#p)
|
||||
|
||||
#ifdef RNG_API_CHECK
|
||||
#undef TAISEI_BUILDCONF_USE_GNU_EXTENSIONS
|
||||
#undef USE_GNU_EXTENSIONS
|
||||
#endif
|
||||
|
||||
#ifndef __GNUC__ // clang defines this too
|
||||
#pragma Unsupported compiler, expect nothing to work
|
||||
|
||||
#define __attribute__(...)
|
||||
#define __extension__
|
||||
#define UNREACHABLE
|
||||
|
@ -91,9 +88,6 @@
|
|||
#define LIKELY(x) (bool)(x)
|
||||
#define UNLIKELY(x) (bool)(x)
|
||||
#else
|
||||
#ifdef TAISEI_BUILDCONF_USE_GNU_EXTENSIONS
|
||||
#define USE_GNU_EXTENSIONS
|
||||
#endif
|
||||
#define UNREACHABLE __builtin_unreachable()
|
||||
|
||||
#define DIAGNOSTIC(x) PRAGMA(GCC diagnostic x)
|
||||
|
@ -292,32 +286,23 @@ typedef _Complex double cmplx;
|
|||
|
||||
#define INLINE static inline attr_must_inline __attribute__((gnu_inline))
|
||||
|
||||
#ifdef USE_GNU_EXTENSIONS
|
||||
#define ASSUME_ALIGNED(expr, alignment) (__extension__ ({ \
|
||||
static_assert(__builtin_constant_p(alignment), ""); \
|
||||
__auto_type _assume_aligned_ptr = (expr); \
|
||||
assert(((uintptr_t)_assume_aligned_ptr & ((alignment) - 1)) == 0); \
|
||||
__builtin_assume_aligned(_assume_aligned_ptr, (alignment)); \
|
||||
}))
|
||||
#else
|
||||
#define ASSUME_ALIGNED(expr, alignment) (expr)
|
||||
#endif
|
||||
#define ASSUME_ALIGNED(expr, alignment) ({ \
|
||||
static_assert(__builtin_constant_p(alignment), ""); \
|
||||
__auto_type _assume_aligned_ptr = (expr); \
|
||||
assert(((uintptr_t)_assume_aligned_ptr & ((alignment) - 1)) == 0); \
|
||||
__builtin_assume_aligned(_assume_aligned_ptr, (alignment)); \
|
||||
})
|
||||
|
||||
#define UNION_CAST(_from_type, _to_type, _expr) \
|
||||
((union { _from_type f; _to_type t; }) { .f = (_expr) }).t
|
||||
|
||||
// #define CASTPTR_ASSUME_ALIGNED(expr, type) UNION_CAST(void*, type*, ASSUME_ALIGNED(expr, alignof(type)))
|
||||
#define CASTPTR_ASSUME_ALIGNED(expr, type) ((type*)ASSUME_ALIGNED((expr), alignof(type)))
|
||||
|
||||
#ifdef USE_GNU_EXTENSIONS
|
||||
#define NOT_NULL(expr) (__extension__ ({ \
|
||||
__auto_type _assume_not_null_ptr = (expr); \
|
||||
assume(_assume_not_null_ptr != NULL); \
|
||||
_assume_not_null_ptr; \
|
||||
}))
|
||||
#else
|
||||
#define NOT_NULL(expr) (expr)
|
||||
#endif
|
||||
#define NOT_NULL(expr) ({ \
|
||||
__auto_type _assume_not_null_ptr = (expr); \
|
||||
assume(_assume_not_null_ptr != NULL); \
|
||||
_assume_not_null_ptr; \
|
||||
})
|
||||
|
||||
#ifdef __SWITCH__
|
||||
#include "../arch_switch.h"
|
||||
|
|
|
@ -506,7 +506,7 @@ uint64_t _umuldiv64_slow(uint64_t x, uint64_t multiplier, uint64_t divisor) {
|
|||
INLINE
|
||||
uint64_t _umuldiv64(uint64_t x, uint64_t multiplier, uint64_t divisor) {
|
||||
#if defined(TAISEI_BUILDCONF_HAVE_INT128)
|
||||
__extension__ typedef unsigned __int128 uint128_t;
|
||||
typedef unsigned __int128 uint128_t;
|
||||
return ((uint128_t)x * (uint128_t)multiplier) / divisor;
|
||||
#elif defined(TAISEI_BUILDCONF_HAVE_LONG_DOUBLE)
|
||||
#define UMULDIV64_SANITY_CHECK
|
||||
|
|
|
@ -36,7 +36,7 @@ void vfs_sync_callback(bool is_load, char *error, CallChain *next) {
|
|||
|
||||
void vfs_sync(VFSSyncMode mode, CallChain next) {
|
||||
CallChain *cc = memdup(&next, sizeof(next));
|
||||
__extension__ (EM_ASM({
|
||||
EM_ASM({
|
||||
SyncFS($0, $1);
|
||||
}, (mode == VFS_SYNC_LOAD), cc));
|
||||
}, (mode == VFS_SYNC_LOAD), cc);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue