Add cross-platform Atomics support
Fixes: https://github.com/quickjs-ng/quickjs/issues/1
This commit is contained in:
parent
0de570988a
commit
569b238ec4
11 changed files with 1331 additions and 1075 deletions
|
@ -51,7 +51,7 @@ if(MSVC)
|
|||
xcheck_add_c_compiler_flag(-Wno-reserved-macro-identifier)
|
||||
xcheck_add_c_compiler_flag(-Wno-reserved-identifier)
|
||||
xcheck_add_c_compiler_flag(-Wdeprecated-declarations)
|
||||
add_compile_definitions(WIN32_LEAN_AND_MEAN)
|
||||
xcheck_add_c_compiler_flag(/experimental:c11atomics)
|
||||
endif()
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "WASI")
|
||||
|
@ -153,10 +153,16 @@ if(BUILD_QJS_LIBC)
|
|||
list(APPEND qjs_sources quickjs-libc.c)
|
||||
endif()
|
||||
list(APPEND qjs_defines _GNU_SOURCE)
|
||||
if(WIN32)
|
||||
list(APPEND qjs_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0602)
|
||||
endif()
|
||||
list(APPEND qjs_libs qjs ${CMAKE_DL_LIBS})
|
||||
find_package(Threads)
|
||||
if(NOT CMAKE_SYSTEM_NAME STREQUAL "WASI")
|
||||
list(APPEND qjs_libs ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif()
|
||||
if(NOT MSVC)
|
||||
find_package(Threads)
|
||||
list(APPEND qjs_libs ${CMAKE_THREAD_LIBS_INIT} m)
|
||||
list(APPEND qjs_libs m)
|
||||
endif()
|
||||
|
||||
add_library(qjs ${qjs_sources})
|
||||
|
|
222
cutils.c
222
cutils.c
|
@ -34,6 +34,9 @@
|
|||
|
||||
#include "cutils.h"
|
||||
|
||||
#undef NANOSEC
|
||||
#define NANOSEC ((uint64_t) 1e9)
|
||||
|
||||
#pragma GCC visibility push(default)
|
||||
|
||||
void pstrcpy(char *buf, int buf_size, const char *str)
|
||||
|
@ -649,7 +652,7 @@ uint64_t js__hrtime_ns(void) {
|
|||
* performance counter interval, integer math could cause this computation
|
||||
* to overflow. Therefore we resort to floating point math.
|
||||
*/
|
||||
scaled_freq = (double) frequency.QuadPart / 1e9;
|
||||
scaled_freq = (double) frequency.QuadPart / NANOSEC;
|
||||
result = (double) counter.QuadPart / scaled_freq;
|
||||
return (uint64_t) result;
|
||||
}
|
||||
|
@ -660,7 +663,7 @@ uint64_t js__hrtime_ns(void) {
|
|||
if (clock_gettime(CLOCK_MONOTONIC, &t))
|
||||
abort();
|
||||
|
||||
return t.tv_sec * (uint64_t) 1e9 + t.tv_nsec;
|
||||
return t.tv_sec * NANOSEC + t.tv_nsec;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -674,4 +677,219 @@ int64_t js__gettimeofday_us(void) {
|
|||
return ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
}
|
||||
|
||||
/* Cross-platform threading APIs. */
|
||||
|
||||
#if !defined(EMSCRIPTEN) && !defined(__wasi__)
|
||||
|
||||
#if defined(_WIN32)
|
||||
typedef void (*js__once_cb)(void);
|
||||
|
||||
typedef struct {
|
||||
js__once_cb callback;
|
||||
} js__once_data_t;
|
||||
|
||||
static BOOL WINAPI js__once_inner(INIT_ONCE *once, void *param, void **context) {
|
||||
js__once_data_t *data = param;
|
||||
|
||||
data->callback();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void js_once(js_once_t *guard, js__once_cb callback) {
|
||||
js__once_data_t data = { .callback = callback };
|
||||
InitOnceExecuteOnce(guard, js__once_inner, (void*) &data, NULL);
|
||||
}
|
||||
|
||||
void js_mutex_init(js_mutex_t *mutex) {
|
||||
InitializeCriticalSection(mutex);
|
||||
}
|
||||
|
||||
void js_mutex_destroy(js_mutex_t *mutex) {
|
||||
DeleteCriticalSection(mutex);
|
||||
}
|
||||
|
||||
void js_mutex_lock(js_mutex_t *mutex) {
|
||||
EnterCriticalSection(mutex);
|
||||
}
|
||||
|
||||
void js_mutex_unlock(js_mutex_t *mutex) {
|
||||
LeaveCriticalSection(mutex);
|
||||
}
|
||||
|
||||
void js_cond_init(js_cond_t *cond) {
|
||||
InitializeConditionVariable(cond);
|
||||
}
|
||||
|
||||
void js_cond_destroy(js_cond_t *cond) {
|
||||
/* nothing to do */
|
||||
(void) cond;
|
||||
}
|
||||
|
||||
void js_cond_signal(js_cond_t *cond) {
|
||||
WakeConditionVariable(cond);
|
||||
}
|
||||
|
||||
void js_cond_broadcast(js_cond_t *cond) {
|
||||
WakeAllConditionVariable(cond);
|
||||
}
|
||||
|
||||
void js_cond_wait(js_cond_t *cond, js_mutex_t *mutex) {
|
||||
if (!SleepConditionVariableCS(cond, mutex, INFINITE))
|
||||
abort();
|
||||
}
|
||||
|
||||
int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout) {
|
||||
if (SleepConditionVariableCS(cond, mutex, (DWORD)(timeout / 1e6)))
|
||||
return 0;
|
||||
if (GetLastError() != ERROR_TIMEOUT)
|
||||
abort();
|
||||
return -1;
|
||||
}
|
||||
|
||||
#else /* !defined(_WIN32) */
|
||||
|
||||
void js_once(js_once_t *guard, void (*callback)(void)) {
|
||||
if (pthread_once(guard, callback))
|
||||
abort();
|
||||
}
|
||||
|
||||
void js_mutex_init(js_mutex_t *mutex) {
|
||||
if (pthread_mutex_init(mutex, NULL))
|
||||
abort();
|
||||
}
|
||||
|
||||
void js_mutex_destroy(js_mutex_t *mutex) {
|
||||
if (pthread_mutex_destroy(mutex))
|
||||
abort();
|
||||
}
|
||||
|
||||
void js_mutex_lock(js_mutex_t *mutex) {
|
||||
if (pthread_mutex_lock(mutex))
|
||||
abort();
|
||||
}
|
||||
|
||||
void js_mutex_unlock(js_mutex_t *mutex) {
|
||||
if (pthread_mutex_unlock(mutex))
|
||||
abort();
|
||||
}
|
||||
|
||||
void js_cond_init(js_cond_t *cond) {
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
if (pthread_cond_init(cond, NULL))
|
||||
abort();
|
||||
#else
|
||||
pthread_condattr_t attr;
|
||||
int err;
|
||||
|
||||
if (pthread_condattr_init(&attr))
|
||||
abort();
|
||||
|
||||
if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
|
||||
abort();
|
||||
|
||||
if (pthread_cond_init(cond, &attr))
|
||||
abort();
|
||||
|
||||
if (pthread_condattr_destroy(&attr))
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
void js_cond_destroy(js_cond_t *cond) {
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
/* It has been reported that destroying condition variables that have been
|
||||
* signalled but not waited on can sometimes result in application crashes.
|
||||
* See https://codereview.chromium.org/1323293005.
|
||||
*/
|
||||
pthread_mutex_t mutex;
|
||||
struct timespec ts;
|
||||
int err;
|
||||
|
||||
if (pthread_mutex_init(&mutex, NULL))
|
||||
abort();
|
||||
|
||||
if (pthread_mutex_lock(&mutex))
|
||||
abort();
|
||||
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 1;
|
||||
|
||||
err = pthread_cond_timedwait_relative_np(cond, &mutex, &ts);
|
||||
if (err != 0 && err != ETIMEDOUT)
|
||||
abort();
|
||||
|
||||
if (pthread_mutex_unlock(&mutex))
|
||||
abort();
|
||||
|
||||
if (pthread_mutex_destroy(&mutex))
|
||||
abort();
|
||||
#endif /* defined(__APPLE__) && defined(__MACH__) */
|
||||
|
||||
if (pthread_cond_destroy(cond))
|
||||
abort();
|
||||
}
|
||||
|
||||
void js_cond_signal(js_cond_t *cond) {
|
||||
if (pthread_cond_signal(cond))
|
||||
abort();
|
||||
}
|
||||
|
||||
void js_cond_broadcast(js_cond_t *cond) {
|
||||
if (pthread_cond_broadcast(cond))
|
||||
abort();
|
||||
}
|
||||
|
||||
void js_cond_wait(js_cond_t *cond, js_mutex_t *mutex) {
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
int r;
|
||||
|
||||
errno = 0;
|
||||
r = pthread_cond_wait(cond, mutex);
|
||||
|
||||
/* Workaround for a bug in OS X at least up to 13.6
|
||||
* See https://github.com/libuv/libuv/issues/4165
|
||||
*/
|
||||
if (r == EINVAL && errno == EBUSY)
|
||||
return;
|
||||
if (r)
|
||||
abort();
|
||||
#else
|
||||
if (pthread_cond_wait(cond, mutex))
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
|
||||
int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout) {
|
||||
int r;
|
||||
struct timespec ts;
|
||||
|
||||
#if !defined(__APPLE__)
|
||||
timeout += js__hrtime_ns();
|
||||
#endif
|
||||
|
||||
ts.tv_sec = timeout / NANOSEC;
|
||||
ts.tv_nsec = timeout % NANOSEC;
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
r = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
|
||||
#else
|
||||
r = pthread_cond_timedwait(cond, mutex, &ts);
|
||||
#endif
|
||||
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
if (r == ETIMEDOUT)
|
||||
return -1;
|
||||
|
||||
abort();
|
||||
|
||||
/* Pacify some compilers. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* !defined(EMSCRIPTEN) && !defined(__wasi__) */
|
||||
|
||||
#pragma GCC visibility pop
|
||||
|
|
41
cutils.h
41
cutils.h
|
@ -29,8 +29,10 @@
|
|||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#if defined(_MSC_VER)
|
||||
#include <winsock2.h>
|
||||
#include <malloc.h>
|
||||
#define alloca _alloca
|
||||
|
@ -43,7 +45,10 @@
|
|||
#elif defined(__FreeBSD__)
|
||||
#include <malloc_np.h>
|
||||
#endif
|
||||
|
||||
#if !defined(_WIN32)
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
# define likely(x) (x)
|
||||
|
@ -426,4 +431,36 @@ static inline size_t js__malloc_usable_size(const void *ptr)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Cross-platform threading APIs. */
|
||||
|
||||
#if !defined(EMSCRIPTEN) && !defined(__wasi__)
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define JS_ONCE_INIT INIT_ONCE_STATIC_INIT
|
||||
typedef INIT_ONCE js_once_t;
|
||||
typedef CRITICAL_SECTION js_mutex_t;
|
||||
typedef CONDITION_VARIABLE js_cond_t;
|
||||
#else
|
||||
#define JS_ONCE_INIT PTHREAD_ONCE_INIT
|
||||
typedef pthread_once_t js_once_t;
|
||||
typedef pthread_mutex_t js_mutex_t;
|
||||
typedef pthread_cond_t js_cond_t;
|
||||
#endif
|
||||
|
||||
void js_once(js_once_t *guard, void (*callback)(void));
|
||||
|
||||
void js_mutex_init(js_mutex_t *mutex);
|
||||
void js_mutex_destroy(js_mutex_t *mutex);
|
||||
void js_mutex_lock(js_mutex_t *mutex);
|
||||
void js_mutex_unlock(js_mutex_t *mutex);
|
||||
|
||||
void js_cond_init(js_cond_t *cond);
|
||||
void js_cond_destroy(js_cond_t *cond);
|
||||
void js_cond_signal(js_cond_t *cond);
|
||||
void js_cond_broadcast(js_cond_t *cond);
|
||||
void js_cond_wait(js_cond_t *cond, js_mutex_t *mutex);
|
||||
int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout);
|
||||
|
||||
#endif /* !defined(EMSCRIPTEN) && !defined(__wasi__) */
|
||||
|
||||
#endif /* CUTILS_H */
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
const uint32_t qjsc_function_source_size = 384;
|
||||
|
||||
const uint8_t qjsc_function_source[384] = {
|
||||
0x09, 0x06, 0x0c, 0x61, 0x63, 0x74, 0x75, 0x61,
|
||||
0x0a, 0x06, 0x0c, 0x61, 0x63, 0x74, 0x75, 0x61,
|
||||
0x6c, 0x02, 0x66, 0x0c, 0x65, 0x78, 0x70, 0x65,
|
||||
0x63, 0x74, 0x14, 0x75, 0x73, 0x65, 0x20, 0x73,
|
||||
0x74, 0x72, 0x69, 0x63, 0x74, 0x34, 0x66, 0x75,
|
||||
|
@ -17,38 +17,38 @@ const uint8_t qjsc_function_source[384] = {
|
|||
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x6a,
|
||||
0x73, 0x0c, 0x00, 0x02, 0x01, 0x9e, 0x01, 0x00,
|
||||
0x06, 0x00, 0x03, 0x00, 0x01, 0xa0, 0x01, 0x06,
|
||||
0xa0, 0x01, 0x00, 0x00, 0x00, 0xac, 0x03, 0x02,
|
||||
0x00, 0x30, 0xae, 0x03, 0x04, 0x00, 0x70, 0xac,
|
||||
0xa0, 0x01, 0x00, 0x00, 0x00, 0xb2, 0x03, 0x02,
|
||||
0x00, 0x30, 0xb4, 0x03, 0x04, 0x00, 0x70, 0xb2,
|
||||
0x03, 0x04, 0x03, 0x70, 0x10, 0x00, 0x01, 0x00,
|
||||
0xe0, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x03, 0xc1,
|
||||
0x05, 0x08, 0xc1, 0x04, 0x3f, 0xd8, 0x00, 0x00,
|
||||
0x00, 0x80, 0x3f, 0xd7, 0x00, 0x00, 0x00, 0x40,
|
||||
0x3e, 0xd8, 0x00, 0x00, 0x00, 0x80, 0xbe, 0x00,
|
||||
0x40, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd9,
|
||||
0x00, 0x00, 0x00, 0xc8, 0x04, 0xda, 0x00, 0x00,
|
||||
0x00, 0x3a, 0xd8, 0x00, 0x00, 0x00, 0x61, 0x01,
|
||||
0x00, 0x38, 0xd7, 0x00, 0x00, 0x00, 0x42, 0x36,
|
||||
0x05, 0x08, 0xc1, 0x04, 0x3f, 0xdb, 0x00, 0x00,
|
||||
0x00, 0x80, 0x3f, 0xda, 0x00, 0x00, 0x00, 0x40,
|
||||
0x3e, 0xdb, 0x00, 0x00, 0x00, 0x80, 0xbe, 0x00,
|
||||
0x40, 0xda, 0x00, 0x00, 0x00, 0x00, 0x04, 0xdc,
|
||||
0x00, 0x00, 0x00, 0xc8, 0x04, 0xdd, 0x00, 0x00,
|
||||
0x00, 0x3a, 0xdb, 0x00, 0x00, 0x00, 0x61, 0x01,
|
||||
0x00, 0x38, 0xda, 0x00, 0x00, 0x00, 0x42, 0x36,
|
||||
0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0xc9, 0x06,
|
||||
0xc8, 0x62, 0x01, 0x00, 0x38, 0xd8, 0x00, 0x00,
|
||||
0x00, 0xaf, 0xe9, 0x0b, 0x38, 0x8f, 0x00, 0x00,
|
||||
0xc8, 0x62, 0x01, 0x00, 0x38, 0xdb, 0x00, 0x00,
|
||||
0x00, 0xaf, 0xe9, 0x0b, 0x38, 0x92, 0x00, 0x00,
|
||||
0x00, 0x62, 0x01, 0x00, 0xee, 0x2f, 0x61, 0x03,
|
||||
0x00, 0x61, 0x02, 0x00, 0x38, 0x39, 0x00, 0x00,
|
||||
0x00, 0x38, 0xd8, 0x00, 0x00, 0x00, 0x04, 0xd7,
|
||||
0x00, 0x38, 0xdb, 0x00, 0x00, 0x00, 0x04, 0xda,
|
||||
0x00, 0x00, 0x00, 0x9d, 0x31, 0x01, 0x00, 0x04,
|
||||
0x00, 0xca, 0x62, 0x02, 0x00, 0x42, 0x36, 0x00,
|
||||
0x00, 0x00, 0x24, 0x00, 0x00, 0xcb, 0x06, 0xc8,
|
||||
0x62, 0x03, 0x00, 0x38, 0xd8, 0x00, 0x00, 0x00,
|
||||
0xaf, 0xe9, 0x0b, 0x38, 0x8f, 0x00, 0x00, 0x00,
|
||||
0x62, 0x03, 0x00, 0x38, 0xdb, 0x00, 0x00, 0x00,
|
||||
0xaf, 0xe9, 0x0b, 0x38, 0x92, 0x00, 0x00, 0x00,
|
||||
0x62, 0x03, 0x00, 0xee, 0x2f, 0x68, 0x03, 0x00,
|
||||
0x68, 0x02, 0x00, 0xc4, 0x28, 0xb6, 0x03, 0x01,
|
||||
0x68, 0x02, 0x00, 0xc4, 0x28, 0xbc, 0x03, 0x01,
|
||||
0x01, 0x28, 0x60, 0x01, 0x49, 0x02, 0x21, 0x1a,
|
||||
0x1b, 0x04, 0x1e, 0x1d, 0x12, 0x26, 0x49, 0x1d,
|
||||
0x0c, 0x06, 0x11, 0x18, 0x2a, 0x1c, 0x37, 0x41,
|
||||
0x21, 0x1c, 0x34, 0x18, 0x1b, 0x04, 0x26, 0x11,
|
||||
0x3f, 0x1d, 0x0c, 0x06, 0x11, 0x18, 0x2a, 0x1c,
|
||||
0x53, 0x41, 0x00, 0x0c, 0x43, 0x02, 0x01, 0xae,
|
||||
0x53, 0x41, 0x00, 0x0c, 0x43, 0x02, 0x01, 0xb4,
|
||||
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x03,
|
||||
0x00, 0xbb, 0x2a, 0x28, 0xb6, 0x03, 0x03, 0x01,
|
||||
0x00, 0xbb, 0x2a, 0x28, 0xbc, 0x03, 0x03, 0x01,
|
||||
0x04, 0x02, 0x1e, 0x0c, 0x0e, 0x1a, 0x66, 0x75,
|
||||
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66,
|
||||
0x28, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
const uint32_t qjsc_hello_size = 89;
|
||||
|
||||
const uint8_t qjsc_hello[89] = {
|
||||
0x09, 0x04, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
|
||||
0x0a, 0x04, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
|
||||
0x6c, 0x65, 0x06, 0x6c, 0x6f, 0x67, 0x16, 0x48,
|
||||
0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72,
|
||||
0x6c, 0x64, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
|
@ -13,9 +13,9 @@ const uint8_t qjsc_hello[89] = {
|
|||
0x6f, 0x2e, 0x6a, 0x73, 0x0c, 0x00, 0x02, 0x00,
|
||||
0x9e, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00,
|
||||
0x14, 0x01, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x38,
|
||||
0xd6, 0x00, 0x00, 0x00, 0x42, 0xd7, 0x00, 0x00,
|
||||
0x00, 0x04, 0xd8, 0x00, 0x00, 0x00, 0x24, 0x01,
|
||||
0x00, 0xcc, 0x28, 0xb2, 0x03, 0x01, 0x01, 0x00,
|
||||
0xd9, 0x00, 0x00, 0x00, 0x42, 0xda, 0x00, 0x00,
|
||||
0x00, 0x04, 0xdb, 0x00, 0x00, 0x00, 0x24, 0x01,
|
||||
0x00, 0xcc, 0x28, 0xb8, 0x03, 0x01, 0x01, 0x00,
|
||||
0x00,
|
||||
};
|
||||
|
||||
|
|
|
@ -5,23 +5,23 @@
|
|||
const uint32_t qjsc_fib_module_size = 310;
|
||||
|
||||
const uint8_t qjsc_fib_module[310] = {
|
||||
0x09, 0x03, 0x2c, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x0a, 0x03, 0x2c, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x73, 0x2f, 0x66, 0x69, 0x62, 0x5f,
|
||||
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x6a,
|
||||
0x73, 0x06, 0x66, 0x69, 0x62, 0x02, 0x6e, 0x0d,
|
||||
0xac, 0x03, 0x00, 0x01, 0x00, 0x00, 0xae, 0x03,
|
||||
0xb2, 0x03, 0x00, 0x01, 0x00, 0x00, 0xb4, 0x03,
|
||||
0x00, 0x00, 0x0c, 0x20, 0x02, 0x01, 0x9e, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x09, 0x00,
|
||||
0xae, 0x03, 0x00, 0x01, 0x08, 0xe9, 0x05, 0xbe,
|
||||
0x00, 0xe0, 0x29, 0x06, 0x2e, 0xac, 0x03, 0x01,
|
||||
0xb4, 0x03, 0x00, 0x01, 0x08, 0xe9, 0x05, 0xbe,
|
||||
0x00, 0xe0, 0x29, 0x06, 0x2e, 0xb2, 0x03, 0x01,
|
||||
0x01, 0x06, 0x01, 0x01, 0x00, 0x07, 0x14, 0x02,
|
||||
0x00, 0x0c, 0x43, 0x02, 0x01, 0xae, 0x03, 0x01,
|
||||
0x00, 0x01, 0x04, 0x01, 0x00, 0x1a, 0x01, 0xb0,
|
||||
0x03, 0x00, 0x01, 0x00, 0xae, 0x03, 0x00, 0x00,
|
||||
0x00, 0x0c, 0x43, 0x02, 0x01, 0xb4, 0x03, 0x01,
|
||||
0x00, 0x01, 0x04, 0x01, 0x00, 0x1a, 0x01, 0xb6,
|
||||
0x03, 0x00, 0x01, 0x00, 0xb4, 0x03, 0x00, 0x00,
|
||||
0xd0, 0xb3, 0xa7, 0xe9, 0x03, 0xb3, 0x28, 0xd0,
|
||||
0xb4, 0xac, 0xe9, 0x03, 0xb4, 0x28, 0xdc, 0xd0,
|
||||
0xb4, 0x9e, 0xee, 0xdc, 0xd0, 0xb5, 0x9e, 0xee,
|
||||
0x9d, 0x28, 0xac, 0x03, 0x02, 0x08, 0x20, 0x04,
|
||||
0x9d, 0x28, 0xb2, 0x03, 0x02, 0x08, 0x20, 0x04,
|
||||
0x00, 0x07, 0x06, 0x07, 0x06, 0x12, 0x09, 0x08,
|
||||
0x07, 0x07, 0x10, 0x07, 0x06, 0x07, 0x06, 0x12,
|
||||
0x13, 0x08, 0x07, 0x08, 0x16, 0x0c, 0x0c, 0x07,
|
||||
|
@ -49,7 +49,7 @@ const uint8_t qjsc_fib_module[310] = {
|
|||
const uint32_t qjsc_hello_module_size = 177;
|
||||
|
||||
const uint8_t qjsc_hello_module[177] = {
|
||||
0x09, 0x07, 0x30, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x0a, 0x07, 0x30, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 0x6c,
|
||||
0x6f, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
|
||||
0x2e, 0x6a, 0x73, 0x1e, 0x2e, 0x2f, 0x66, 0x69,
|
||||
|
@ -59,17 +59,17 @@ const uint8_t qjsc_hello_module[177] = {
|
|||
0x6c, 0x6f, 0x67, 0x16, 0x48, 0x65, 0x6c, 0x6c,
|
||||
0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x10,
|
||||
0x66, 0x69, 0x62, 0x28, 0x31, 0x30, 0x29, 0x3d,
|
||||
0x0d, 0xac, 0x03, 0x01, 0xae, 0x03, 0x00, 0x00,
|
||||
0x01, 0x00, 0xb0, 0x03, 0x00, 0x0c, 0x20, 0x02,
|
||||
0x0d, 0xb2, 0x03, 0x01, 0xb4, 0x03, 0x00, 0x00,
|
||||
0x01, 0x00, 0xb6, 0x03, 0x00, 0x0c, 0x20, 0x02,
|
||||
0x01, 0x9e, 0x01, 0x00, 0x00, 0x00, 0x05, 0x01,
|
||||
0x00, 0x32, 0x00, 0xb0, 0x03, 0x00, 0x0c, 0x08,
|
||||
0xe9, 0x02, 0x29, 0x38, 0xd9, 0x00, 0x00, 0x00,
|
||||
0x42, 0xda, 0x00, 0x00, 0x00, 0x04, 0xdb, 0x00,
|
||||
0x00, 0x00, 0x24, 0x01, 0x00, 0x0e, 0x38, 0xd9,
|
||||
0x00, 0x00, 0x00, 0x42, 0xda, 0x00, 0x00, 0x00,
|
||||
0x04, 0xdc, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00,
|
||||
0x00, 0x32, 0x00, 0xb6, 0x03, 0x00, 0x0c, 0x08,
|
||||
0xe9, 0x02, 0x29, 0x38, 0xdc, 0x00, 0x00, 0x00,
|
||||
0x42, 0xdd, 0x00, 0x00, 0x00, 0x04, 0xde, 0x00,
|
||||
0x00, 0x00, 0x24, 0x01, 0x00, 0x0e, 0x38, 0xdc,
|
||||
0x00, 0x00, 0x00, 0x42, 0xdd, 0x00, 0x00, 0x00,
|
||||
0x04, 0xdf, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00,
|
||||
0xbb, 0x0a, 0xee, 0x24, 0x02, 0x00, 0x0e, 0x06,
|
||||
0x2e, 0xac, 0x03, 0x01, 0x01, 0x0a, 0x01, 0x01,
|
||||
0x2e, 0xb2, 0x03, 0x01, 0x01, 0x0a, 0x01, 0x01,
|
||||
0x00, 0x04, 0x0a, 0x02, 0x62, 0x00, 0x4d, 0x30,
|
||||
0x00,
|
||||
};
|
||||
|
|
1972
gen/repl.c
1972
gen/repl.c
File diff suppressed because it is too large
Load diff
|
@ -5,7 +5,7 @@
|
|||
const uint32_t qjsc_test_fib_size = 166;
|
||||
|
||||
const uint8_t qjsc_test_fib[166] = {
|
||||
0x09, 0x07, 0x28, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x0a, 0x07, 0x28, 0x65, 0x78, 0x61, 0x6d, 0x70,
|
||||
0x6c, 0x65, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74,
|
||||
0x5f, 0x66, 0x69, 0x62, 0x2e, 0x6a, 0x73, 0x10,
|
||||
0x2e, 0x2f, 0x66, 0x69, 0x62, 0x2e, 0x73, 0x6f,
|
||||
|
@ -13,17 +13,17 @@ const uint8_t qjsc_test_fib[166] = {
|
|||
0x73, 0x6f, 0x6c, 0x65, 0x06, 0x6c, 0x6f, 0x67,
|
||||
0x16, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57,
|
||||
0x6f, 0x72, 0x6c, 0x64, 0x10, 0x66, 0x69, 0x62,
|
||||
0x28, 0x31, 0x30, 0x29, 0x3d, 0x0d, 0xac, 0x03,
|
||||
0x01, 0xae, 0x03, 0x00, 0x00, 0x01, 0x00, 0xb0,
|
||||
0x28, 0x31, 0x30, 0x29, 0x3d, 0x0d, 0xb2, 0x03,
|
||||
0x01, 0xb4, 0x03, 0x00, 0x00, 0x01, 0x00, 0xb6,
|
||||
0x03, 0x00, 0x0c, 0x20, 0x02, 0x01, 0x9e, 0x01,
|
||||
0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x32, 0x00,
|
||||
0xb0, 0x03, 0x00, 0x0c, 0x08, 0xe9, 0x02, 0x29,
|
||||
0x38, 0xd9, 0x00, 0x00, 0x00, 0x42, 0xda, 0x00,
|
||||
0x00, 0x00, 0x04, 0xdb, 0x00, 0x00, 0x00, 0x24,
|
||||
0x01, 0x00, 0x0e, 0x38, 0xd9, 0x00, 0x00, 0x00,
|
||||
0x42, 0xda, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00,
|
||||
0xb6, 0x03, 0x00, 0x0c, 0x08, 0xe9, 0x02, 0x29,
|
||||
0x38, 0xdc, 0x00, 0x00, 0x00, 0x42, 0xdd, 0x00,
|
||||
0x00, 0x00, 0x04, 0xde, 0x00, 0x00, 0x00, 0x24,
|
||||
0x01, 0x00, 0x0e, 0x38, 0xdc, 0x00, 0x00, 0x00,
|
||||
0x42, 0xdd, 0x00, 0x00, 0x00, 0x04, 0xdf, 0x00,
|
||||
0x00, 0x00, 0x65, 0x00, 0x00, 0xbb, 0x0a, 0xee,
|
||||
0x24, 0x02, 0x00, 0x0e, 0x06, 0x2e, 0xac, 0x03,
|
||||
0x24, 0x02, 0x00, 0x0e, 0x06, 0x2e, 0xb2, 0x03,
|
||||
0x01, 0x01, 0x0a, 0x01, 0x01, 0x00, 0x04, 0x0a,
|
||||
0x02, 0x62, 0x00, 0x4d, 0x30, 0x00,
|
||||
};
|
||||
|
|
|
@ -170,11 +170,9 @@ DEF(status, "status")
|
|||
DEF(reason, "reason")
|
||||
DEF(globalThis, "globalThis")
|
||||
DEF(bigint, "bigint")
|
||||
#ifdef CONFIG_ATOMICS
|
||||
DEF(not_equal, "not-equal")
|
||||
DEF(timed_out, "timed-out")
|
||||
DEF(ok, "ok")
|
||||
#endif
|
||||
DEF(toJSON, "toJSON")
|
||||
/* class names */
|
||||
DEF(Object, "Object")
|
||||
|
|
57
quickjs.c
57
quickjs.c
|
@ -67,6 +67,11 @@
|
|||
#define NO_TM_GMTOFF
|
||||
#endif
|
||||
|
||||
#if !defined(EMSCRIPTEN) && !defined(__wasi__)
|
||||
#include "quickjs-c-atomics.h"
|
||||
#define CONFIG_ATOMICS
|
||||
#endif
|
||||
|
||||
/* dump object free */
|
||||
//#define DUMP_FREE
|
||||
//#define DUMP_CLOSURE
|
||||
|
@ -99,12 +104,6 @@
|
|||
/* test the GC by forcing it before each object allocation */
|
||||
//#define FORCE_GC_AT_MALLOC
|
||||
|
||||
#ifdef CONFIG_ATOMICS
|
||||
#include <pthread.h>
|
||||
#include "quickjs-c-atomics.h"
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
#define STRINGIFY_(x) #x
|
||||
#define STRINGIFY(x) STRINGIFY_(x)
|
||||
|
||||
|
@ -32561,7 +32560,7 @@ typedef enum BCTagEnum {
|
|||
BC_TAG_OBJECT_REFERENCE,
|
||||
} BCTagEnum;
|
||||
|
||||
#define BC_VERSION 9
|
||||
#define BC_VERSION 10
|
||||
|
||||
typedef struct BCWriterState {
|
||||
JSContext *ctx;
|
||||
|
@ -51497,11 +51496,12 @@ static JSValue js_atomics_isLockFree(JSContext *ctx,
|
|||
typedef struct JSAtomicsWaiter {
|
||||
struct list_head link;
|
||||
BOOL linked;
|
||||
pthread_cond_t cond;
|
||||
js_cond_t cond;
|
||||
int32_t *ptr;
|
||||
} JSAtomicsWaiter;
|
||||
|
||||
static pthread_mutex_t js_atomics_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static js_once_t js_atomics_once = JS_ONCE_INIT;
|
||||
static js_mutex_t js_atomics_mutex;
|
||||
static struct list_head js_atomics_waiter_list =
|
||||
LIST_HEAD_INIT(js_atomics_waiter_list);
|
||||
|
||||
|
@ -51543,44 +51543,34 @@ static JSValue js_atomics_wait(JSContext *ctx,
|
|||
|
||||
/* XXX: inefficient if large number of waiters, should hash on
|
||||
'ptr' value */
|
||||
/* XXX: use Linux futexes when available ? */
|
||||
pthread_mutex_lock(&js_atomics_mutex);
|
||||
js_mutex_lock(&js_atomics_mutex);
|
||||
if (size_log2 == 3) {
|
||||
res = *(int64_t *)ptr != v;
|
||||
} else {
|
||||
res = *(int32_t *)ptr != v;
|
||||
}
|
||||
if (res) {
|
||||
pthread_mutex_unlock(&js_atomics_mutex);
|
||||
js_mutex_unlock(&js_atomics_mutex);
|
||||
return JS_AtomToString(ctx, JS_ATOM_not_equal);
|
||||
}
|
||||
|
||||
waiter = &waiter_s;
|
||||
waiter->ptr = ptr;
|
||||
pthread_cond_init(&waiter->cond, NULL);
|
||||
js_cond_init(&waiter->cond);
|
||||
waiter->linked = TRUE;
|
||||
list_add_tail(&waiter->link, &js_atomics_waiter_list);
|
||||
|
||||
if (timeout == INT64_MAX) {
|
||||
pthread_cond_wait(&waiter->cond, &js_atomics_mutex);
|
||||
js_cond_wait(&waiter->cond, &js_atomics_mutex);
|
||||
ret = 0;
|
||||
} else {
|
||||
/* XXX: use clock monotonic */
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
ts.tv_sec += timeout / 1000;
|
||||
ts.tv_nsec += (timeout % 1000) * 1000000;
|
||||
if (ts.tv_nsec >= 1000000000) {
|
||||
ts.tv_nsec -= 1000000000;
|
||||
ts.tv_sec++;
|
||||
}
|
||||
ret = pthread_cond_timedwait(&waiter->cond, &js_atomics_mutex,
|
||||
&ts);
|
||||
ret = js_cond_timedwait(&waiter->cond, &js_atomics_mutex, timeout * 1e6 /* to ns */);
|
||||
}
|
||||
if (waiter->linked)
|
||||
list_del(&waiter->link);
|
||||
pthread_mutex_unlock(&js_atomics_mutex);
|
||||
pthread_cond_destroy(&waiter->cond);
|
||||
if (ret == ETIMEDOUT) {
|
||||
js_mutex_unlock(&js_atomics_mutex);
|
||||
js_cond_destroy(&waiter->cond);
|
||||
if (ret == -1) {
|
||||
return JS_AtomToString(ctx, JS_ATOM_timed_out);
|
||||
} else {
|
||||
return JS_AtomToString(ctx, JS_ATOM_ok);
|
||||
|
@ -51612,7 +51602,7 @@ static JSValue js_atomics_notify(JSContext *ctx,
|
|||
|
||||
n = 0;
|
||||
if (abuf->shared && count > 0) {
|
||||
pthread_mutex_lock(&js_atomics_mutex);
|
||||
js_mutex_lock(&js_atomics_mutex);
|
||||
init_list_head(&waiter_list);
|
||||
list_for_each_safe(el, el1, &js_atomics_waiter_list) {
|
||||
waiter = list_entry(el, JSAtomicsWaiter, link);
|
||||
|
@ -51627,9 +51617,9 @@ static JSValue js_atomics_notify(JSContext *ctx,
|
|||
}
|
||||
list_for_each(el, &waiter_list) {
|
||||
waiter = list_entry(el, JSAtomicsWaiter, link);
|
||||
pthread_cond_signal(&waiter->cond);
|
||||
js_cond_signal(&waiter->cond);
|
||||
}
|
||||
pthread_mutex_unlock(&js_atomics_mutex);
|
||||
js_mutex_unlock(&js_atomics_mutex);
|
||||
}
|
||||
return js_int32(n);
|
||||
}
|
||||
|
@ -51654,8 +51644,15 @@ static const JSCFunctionListEntry js_atomics_obj[] = {
|
|||
JS_OBJECT_DEF("Atomics", js_atomics_funcs, countof(js_atomics_funcs), JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE ),
|
||||
};
|
||||
|
||||
static void js__atomics_init(void) {
|
||||
js_mutex_init(&js_atomics_mutex);
|
||||
}
|
||||
|
||||
/* TODO(saghul) make this public and not dependent on typed arrays? */
|
||||
void JS_AddIntrinsicAtomics(JSContext *ctx)
|
||||
{
|
||||
js_once(&js_atomics_once, js__atomics_init);
|
||||
|
||||
/* add Atomics as autoinit object */
|
||||
JS_SetPropertyFunctionList(ctx, ctx->global_obj, js_atomics_obj, countof(js_atomics_obj));
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ arraybuffer-transfer
|
|||
arrow-function
|
||||
async-functions
|
||||
async-iteration
|
||||
Atomics=skip # disabled because of Windows <-> pthreads
|
||||
Atomics
|
||||
Atomics.waitAsync=skip
|
||||
BigInt
|
||||
caller
|
||||
|
|
Loading…
Reference in a new issue