Skip to content

Commit e278bd7

Browse files
dsuponitskiyYuriy Polyakovdsuponitskiy-dualitypascoec
authored
969 fix emscripten errors (2) (#985)
* initial emscripten fixes * Disabled some unit tests for Emscripten * Removed redundant __EMSCRIPTEN__ * Additional __EMSCRIPTEN__ removal * Correction for NATIVEINT * Clang-20 compiler error fix * Update utilities.h * Update UnitTestCKKSrns.cpp * Update UnitTestInteractiveBootstrap.cpp * Update UnitTestCKKSrnsSerialize.cpp * Update utilities.h --------- Co-authored-by: Yuriy Polyakov <ypolyakod@dualitytech.com> Co-authored-by: Dmitriy Suponitskiy <dsuponitskiy@dualitytech.com> Co-authored-by: pascoec <123595534+pascoec@users.noreply.github.com>
1 parent 1c15c51 commit e278bd7

36 files changed

+130
-133
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ cmake-build-debug
99
docs/doxygen
1010
docs/sphinx
1111
_build/
12+
embuild
1213
api/
1314
doxyoutput/
1415

CMakeLists.txt

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,9 @@ if(EMSCRIPTEN)
171171
set(CXX_COMPILE_FLAGS "${CXX_COMPILE_FLAGS} ${EMSCRIPTEN_IGNORE_WARNINGS}")
172172
add_compile_options(-fexceptions)
173173
add_link_options(
174+
-Wno-limited-postlink-optimizations
174175
-sINITIAL_MEMORY=2047MB -sMAXIMUM_MEMORY=4GB -sALLOW_MEMORY_GROWTH=1
175-
-sMALLOC=emmalloc -sNO_DISABLE_EXCEPTION_CATCHING)
176+
-sMALLOC=emmalloc -sDISABLE_EXCEPTION_CATCHING=0)
176177
endif()
177178

178179
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_COMPILE_FLAGS}")
@@ -267,6 +268,14 @@ include(CheckTypeSize)
267268
check_type_size("__int128" INT128)
268269
check_type_size("uint64_t" INT64)
269270

271+
### dsuponit: uncomment the following "if" block if HAVE_INT64 is false. It may happen when compiling with pthreads enabled.
272+
### Seems like I have disabled link with pthreads for Emscripten in all makefiles
273+
if(EMSCRIPTEN)
274+
# Emscripten always(!) supports uint64_t, but check_type_size() may not work correctly due to the way
275+
# Emscripten handles cross-compilation. Instead of checking, we can hardcode the result.
276+
set(HAVE_INT64 1)
277+
endif()
278+
270279
if(NOT(BUILD_SHARED OR BUILD_STATIC))
271280
message(SEND_ERROR "Either BUILD_SHARED or BUILD_STATIC neeed to be turned on.")
272281
endif()
@@ -282,9 +291,9 @@ if("${NATIVE_SIZE}" EQUAL 128)
282291
message(SEND_ERROR "Cannot support NATIVE_SIZE == 128")
283292
endif()
284293
elseif("${NATIVE_SIZE}" EQUAL 64)
285-
if(EMSCRIPTEN)
286-
set(HAVE_INT128 FALSE)
287-
endif()
294+
# if(EMSCRIPTEN)
295+
# set(HAVE_INT128 FALSE)
296+
# endif()
288297
if(${HAVE_INT64})
289298
set(NATIVEINT 64)
290299
message(STATUS "NATIVEINT is set to " ${NATIVEINT})
@@ -452,7 +461,9 @@ if(WITH_OPENMP)
452461
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
453462
endif()
454463
else() # WITH_OPENMP == OFF
455-
find_package(Threads REQUIRED)
464+
if(NOT EMSCRIPTEN)
465+
find_package(Threads REQUIRED)
466+
endif()
456467
# Disable unknown #pragma omp warning
457468
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unknown-pragmas")
458469
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas")

src/binfhe/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ if(BUILD_UNITTESTS)
5555
add_executable(binfhe_tests ${BINFHE_TEST_SRC_FILES} ${UNITTESTMAIN})
5656
set_property(TARGET binfhe_tests PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/unittest)
5757
target_link_libraries(binfhe_tests ${BINFHELIBS} ${ADDITIONAL_LIBS})
58-
if(NOT ${WITH_OPENMP})
58+
if(NOT ${WITH_OPENMP} AND NOT EMSCRIPTEN)
5959
target_link_libraries(binfhe_tests PRIVATE Threads::Threads)
6060
endif()
6161

src/binfhe/unittest/UnitTestFHEW.cpp

Lines changed: 18 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@
4141

4242
using namespace lbcrypto;
4343

44+
#if defined(__EMSCRIPTEN__)
45+
#define UNIT_TEST_EXCEPTION_TYPE_NAME_BINFHE "EMSCRIPTEN_UNKNOWN"
46+
#else
47+
#define UNIT_TEST_EXCEPTION_TYPE_NAME_BINFHE demangle(__cxxabiv1::__cxa_current_exception_type()->name())
48+
#endif
49+
// UNIT_TEST_HANDLE_ALL_EXCEPTIONS must always fail
50+
#define UNIT_TEST_HANDLE_ALL_EXCEPTIONS_BINFHE \
51+
std::string name(UNIT_TEST_EXCEPTION_TYPE_NAME_BINFHE); \
52+
std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl; \
53+
EXPECT_TRUE(0 == 1) << failmsg;
54+
55+
4456
//===========================================================================================================
4557
enum TEST_CASE_TYPE {
4658
FHEW_AND = 0,
@@ -272,14 +284,7 @@ class UTGENERAL_FHEW : public ::testing::TestWithParam<TEST_CASE_UTGENERAL_FHEW>
272284
EXPECT_TRUE(0 == 1) << failmsg;
273285
}
274286
catch (...) {
275-
#if defined EMSCRIPTEN
276-
std::string name("EMSCRIPTEN_UNKNOWN");
277-
#else
278-
std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name()));
279-
#endif
280-
std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl;
281-
// make it fail
282-
EXPECT_TRUE(0 == 1) << failmsg;
287+
UNIT_TEST_HANDLE_ALL_EXCEPTIONS_BINFHE;
283288
}
284289
}
285290

@@ -321,14 +326,7 @@ class UTGENERAL_FHEW : public ::testing::TestWithParam<TEST_CASE_UTGENERAL_FHEW>
321326
EXPECT_TRUE(0 == 1) << failmsg;
322327
}
323328
catch (...) {
324-
#if defined EMSCRIPTEN
325-
std::string name("EMSCRIPTEN_UNKNOWN");
326-
#else
327-
std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name()));
328-
#endif
329-
std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl;
330-
// make it fail
331-
EXPECT_TRUE(0 == 1) << failmsg;
329+
UNIT_TEST_HANDLE_ALL_EXCEPTIONS_BINFHE;
332330
}
333331
}
334332

@@ -362,14 +360,7 @@ class UTGENERAL_FHEW : public ::testing::TestWithParam<TEST_CASE_UTGENERAL_FHEW>
362360
EXPECT_TRUE(0 == 1) << failmsg;
363361
}
364362
catch (...) {
365-
#if defined EMSCRIPTEN
366-
std::string name("EMSCRIPTEN_UNKNOWN");
367-
#else
368-
std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name()));
369-
#endif
370-
std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl;
371-
// make it fail
372-
EXPECT_TRUE(0 == 1) << failmsg;
363+
UNIT_TEST_HANDLE_ALL_EXCEPTIONS_BINFHE;
373364
}
374365
}
375366

@@ -414,14 +405,7 @@ class UTGENERAL_FHEW : public ::testing::TestWithParam<TEST_CASE_UTGENERAL_FHEW>
414405
EXPECT_TRUE(0 == 1) << failmsg;
415406
}
416407
catch (...) {
417-
#if defined EMSCRIPTEN
418-
std::string name("EMSCRIPTEN_UNKNOWN");
419-
#else
420-
std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name()));
421-
#endif
422-
std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl;
423-
// make it fail
424-
EXPECT_TRUE(0 == 1) << failmsg;
408+
UNIT_TEST_HANDLE_ALL_EXCEPTIONS_BINFHE;
425409
}
426410
}
427411

@@ -469,14 +453,7 @@ class UTGENERAL_FHEW : public ::testing::TestWithParam<TEST_CASE_UTGENERAL_FHEW>
469453
EXPECT_TRUE(0 == 1) << failmsg;
470454
}
471455
catch (...) {
472-
#if defined EMSCRIPTEN
473-
std::string name("EMSCRIPTEN_UNKNOWN");
474-
#else
475-
std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name()));
476-
#endif
477-
std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl;
478-
// make it fail
479-
EXPECT_TRUE(0 == 1) << failmsg;
456+
UNIT_TEST_HANDLE_ALL_EXCEPTIONS_BINFHE;
480457
}
481458
}
482459

@@ -528,14 +505,7 @@ class UTGENERAL_FHEW : public ::testing::TestWithParam<TEST_CASE_UTGENERAL_FHEW>
528505
EXPECT_TRUE(0 == 1) << failmsg;
529506
}
530507
catch (...) {
531-
#if defined EMSCRIPTEN
532-
std::string name("EMSCRIPTEN_UNKNOWN");
533-
#else
534-
std::string name(demangle(__cxxabiv1::__cxa_current_exception_type()->name()));
535-
#endif
536-
std::cerr << "Unknown exception of type \"" << name << "\" thrown from " << __func__ << "()" << std::endl;
537-
// make it fail
538-
EXPECT_TRUE(0 == 1) << failmsg;
508+
UNIT_TEST_HANDLE_ALL_EXCEPTIONS_BINFHE;
539509
}
540510
}
541511
};

src/core/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ if(BUILD_UNITTESTS)
6060
add_executable(core_tests ${CORE_TEST_SRC_FILES} ${UNITTESTMAIN})
6161
set_property(TARGET core_tests PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/unittest)
6262
target_link_libraries(core_tests ${CORELIBS} ${ADDITIONAL_LIBS})
63-
if(NOT ${WITH_OPENMP})
63+
if(NOT ${WITH_OPENMP} AND NOT EMSCRIPTEN)
6464
target_link_libraries(core_tests PRIVATE Threads::Threads)
6565
endif()
6666
add_dependencies(allcore core_tests)

src/core/include/utils/utilities.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ inline bool is64BitOverflow(double d) {
107107
return std::abs(d) > static_cast<double>(Max64BitValue());
108108
}
109109

110-
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
110+
#if NATIVEINT == 128
111111
inline constexpr __int128 Max128BitValue() {
112112
return static_cast<__int128>(((unsigned __int128)1 << 127) - ((unsigned __int128)1 << 73) - (unsigned __int128)1);
113113
}
@@ -124,7 +124,7 @@ inline bool isConvertableToNativeInt(double d) {
124124
return std::abs(d) <= static_cast<double>(std::numeric_limits<int32_t>::max());
125125
if constexpr (NATIVEINT == 64)
126126
return std::abs(d) <= static_cast<double>(Max64BitValue());
127-
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
127+
#if NATIVEINT == 128
128128
if constexpr (NATIVEINT == 128)
129129
return std::abs(d) <= static_cast<double>(Max128BitValue());
130130
#endif

src/core/lib/utils/prng/blake2engine.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ Blake2Engine::~Blake2Engine() {
4848
void Blake2Engine::Generate() {
4949
// m_counter is the input to the hash function
5050
// m_buffer is the output
51-
if (blake2xb(m_buffer.begin(), m_buffer.size() * sizeof(PRNG::result_type), &m_counter, sizeof(m_counter),
52-
m_seed.cbegin(), m_seed.size() * sizeof(PRNG::result_type)) != 0) {
51+
if (blake2xb(static_cast<void*>(m_buffer.data()), m_buffer.size() * sizeof(PRNG::result_type), &m_counter, sizeof(m_counter),
52+
static_cast<const void*>(m_seed.data()), m_seed.size() * sizeof(PRNG::result_type)) != 0) {
5353
OPENFHE_THROW("PRNG: blake2xb failed");
5454
}
5555
m_counter++;
@@ -96,7 +96,7 @@ static void Blake2SeedGenerator(Blake2Engine::blake2_seed_array_t& seed) {
9696
// On a 64-bit machine, the thread id is 64 bits long
9797
// skip on 32-bit arm architectures
9898
#if !defined(__arm__) && !defined(__EMSCRIPTEN__)
99-
if (sizeof(size_t) == 8)
99+
if constexpr (sizeof(size_t) == 8)
100100
initKey[2] = (std::hash<std::thread::id>{}(std::this_thread::get_id()) >> 32);
101101
#endif
102102
// heap variable; we are going to use up to 64 bits of its memory location as the counter.

src/core/unittest/UnitTest128.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ using namespace lbcrypto;
5050
/************************************************
5151
* TESTING Modular operations for 128-bit backend
5252
************************************************/
53-
#if (NATIVEINT == 128) && !defined(__EMSCRIPTEN__)
53+
#if NATIVEINT == 128
5454
TEST(UT128, modular_operations) {
5555
intnat::NativeInteger modulus = ((intnat::NativeInteger(1) << 120) + intnat::NativeInteger(123456789));
5656
intnat::NativeInteger mu = modulus.ComputeMu();

src/core/unittest/UnitTestXallocate.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@
4848
#include "utils/inttypes.h"
4949
#include "utils/utilities.h"
5050

51+
// this test does not work correctly in the web assembly configuration
52+
#if !defined(__EMSCRIPTEN__)
53+
5154
using namespace lbcrypto;
5255

5356
class UnitTestBinInt : public ::testing::Test {
@@ -86,21 +89,21 @@ static MyClassStatic myClassStatic;
8689
static void out_of_memory() {
8790
// new-handler function called by Allocator when pool is out of memory
8891
xalloc_stats();
89-
#if 0
92+
#if 0
9093
std::bad_alloc exception;
9194
throw(exception);
92-
#else
95+
#else
9396
assert(0);
94-
#endif
97+
#endif
9598
}
9699

97100
static const int MAX_BLOCK_SIZE = 4000;
98-
// static const int MAX_ALLOCATIONS = 10000;
99-
#ifdef __ANDROID__
101+
// static const int MAX_ALLOCATIONS = 10000;
102+
#ifdef __ANDROID__
100103
static const int MAX_ALLOCATIONS = 512; // reduce size of pool for limited memory
101-
#else
104+
#else
102105
static const int MAX_ALLOCATIONS = 2048;
103-
#endif
106+
#endif
104107
static void* memoryPtrs[MAX_ALLOCATIONS];
105108
static void* memoryPtrs2[MAX_ALLOCATIONS];
106109

@@ -115,11 +118,11 @@ void Benchmark(const char* name, AllocFunc allocFunc, DeallocFunc deallocFunc) {
115118
TimeVar t1, t_total;
116119

117120
float ElapsedMicroseconds = 0;
118-
#if defined(__clang__)
121+
#if defined(__clang__)
119122
[[maybe_unused]] float TotalElapsedMicroseconds = 0;
120-
#else
123+
#else
121124
float TotalElapsedMicroseconds = 0;
122-
#endif
125+
#endif
123126
// Allocate MAX_ALLOCATIONS blocks MAX_BLOCK_SIZE / 2 sized blocks
124127
TIC(t_total);
125128
TIC(t1);
@@ -192,12 +195,13 @@ TEST(UTBlockAllocate, xalloc_test) {
192195
Benchmark("xmalloc/xfree (Run 2)", xmalloc, xfree);
193196
Benchmark("xmalloc/xfree (Run 3)", xmalloc, xfree);
194197

195-
#ifdef PROFILE
198+
#ifdef PROFILE
196199
xalloc_stats();
197-
#endif
200+
#endif
198201

199202
// If AUTOMATIC_XALLOCATOR_INIT_DESTROY is defined, ~XallocDestroy() will call
200203
// xalloc_destroy() automatically. Never call xalloc_destroy() manually except
201204
// if using xallocator in a C-only application.
202205
// xalloc_destroy();
203206
}
207+
#endif

src/pke/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ if(BUILD_UNITTESTS)
6161
set_property(TARGET pke_tests PROPERTY RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/unittest)
6262
target_include_directories(pke_tests PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/unittest/utils")
6363
target_link_libraries(pke_tests ${PKELIBS} ${ADDITIONAL_LIBS})
64-
if(NOT ${WITH_OPENMP})
64+
if(NOT ${WITH_OPENMP} AND NOT EMSCRIPTEN)
6565
target_link_libraries(pke_tests PRIVATE Threads::Threads)
6666
endif()
6767
add_dependencies(allpke pke_tests)

src/pke/examples/advanced-ckks-bootstrapping.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ void BootstrapExample(uint32_t numSlots) {
8888
* to obtain a good precision and performance tradeoff. We recommend keeping the parameters
8989
* below unless you are an FHE expert.
9090
*/
91-
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
91+
#if NATIVEINT == 128
9292
// Currently, only FIXEDMANUAL and FIXEDAUTO modes are supported for 128-bit CKKS bootstrapping.
9393
ScalingTechnique rescaleTech = FIXEDAUTO;
9494
usint dcrtBits = 78;

src/pke/examples/advanced-real-numbers-128.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ int main(int argc, char* argv[]) {
9494
*
9595
*/
9696

97-
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
97+
#if NATIVEINT == 128
9898
AutomaticRescaleDemo(FIXEDAUTO);
9999
// Note that FLEXIBLEAUTO is not supported for 128-bit CKKS
100100

src/pke/examples/iterative-ckks-bootstrapping.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ void IterativeBootstrapExample() {
8181
parameters.SetSecurityLevel(HEStd_NotSet);
8282
parameters.SetRingDim(1 << 12);
8383

84-
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
84+
#if NATIVEINT == 128
8585
// Currently, only FIXEDMANUAL and FIXEDAUTO modes are supported for 128-bit CKKS bootstrapping.
8686
ScalingTechnique rescaleTech = FIXEDAUTO;
8787
usint dcrtBits = 78;

src/pke/examples/simple-ckks-bootstrapping.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ void SimpleBootstrapExample() {
7676
* to obtain a good precision and performance tradeoff. We recommend keeping the parameters
7777
* below unless you are an FHE expert.
7878
*/
79-
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
79+
#if NATIVEINT == 128
8080
ScalingTechnique rescaleTech = FIXEDAUTO;
8181
usint dcrtBits = 78;
8282
usint firstMod = 89;

src/pke/examples/simple-complex-numbers.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ void SimpleBootstrappingComplex() {
361361
* to obtain a good precision and performance tradeoff. We recommend keeping the parameters
362362
* below unless you are an FHE expert.
363363
*/
364-
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
364+
#if NATIVEINT == 128
365365
ScalingTechnique rescaleTech = FIXEDAUTO;
366366
usint dcrtBits = 78;
367367
usint firstMod = 89;

src/pke/extras/ckks-bootstrap.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ void BootstrapExample(SecretKeyDist secretKeyDist, uint32_t n, uint32_t slots, u
8585
std::vector<uint32_t> levelBudget5 = {1, 2};
8686
std::vector<uint32_t> levelBudget6 = {3, 1};
8787

88-
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
88+
#if NATIVEINT == 128
8989
ScalingTechnique rescaleTech = FIXEDMANUAL;
9090
usint dcrtBits = 78;
9191
usint firstMod = 89; /*firstMod*/
@@ -123,7 +123,7 @@ void BootstrapExample(SecretKeyDist secretKeyDist, uint32_t n, uint32_t slots, u
123123
HYBRID,
124124
3, /*numLargeDigits*/
125125
2, /*maxRelinSkDeg*/
126-
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
126+
#if NATIVEINT == 128
127127
89, /*firstMod*/
128128
#else
129129
60, /*firstMod*/
@@ -253,7 +253,7 @@ void BootstrapExampleClean(SecretKeyDist secretKeyDist, uint32_t n, uint32_t slo
253253
// Choose a number smaller than ceil(log2(slots))
254254
std::vector<uint32_t> levelBudget = {4, 4};
255255

256-
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
256+
#if NATIVEINT == 128
257257
ScalingTechnique rescaleTech = FIXEDMANUAL;
258258
usint dcrtBits = 78;
259259
usint firstMod = 89; /*firstMod*/
@@ -291,7 +291,7 @@ void BootstrapExampleClean(SecretKeyDist secretKeyDist, uint32_t n, uint32_t slo
291291
HYBRID,
292292
3, /*numLargeDigits*/
293293
2, /*maxRelinSkDeg*/
294-
#if NATIVEINT == 128 && !defined(__EMSCRIPTEN__)
294+
#if NATIVEINT == 128
295295
89, /*firstMod*/
296296
#else
297297
60, /*firstMod*/

0 commit comments

Comments
 (0)