diff --git a/cutils.c b/cutils.c index a02fb7688..3fe3317bc 100644 --- a/cutils.c +++ b/cutils.c @@ -50,7 +50,7 @@ void pstrcpy(char *buf, int buf_size, const char *str) char *pstrcat(char *buf, int buf_size, const char *s) { int len; - len = strlen(buf); + len = (int)strlen(buf); if (len < buf_size) pstrcpy(buf + len, buf_size - len, s); return buf; @@ -166,7 +166,7 @@ int dbuf_putstr(DynBuf *s, const char *str) return dbuf_put(s, (const uint8_t *)str, strlen(str)); } -int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s, +int util_format(printf, 2, 3) dbuf_printf(DynBuf *s, const char *fmt, ...) { va_list ap; @@ -235,7 +235,7 @@ int unicode_to_utf8(uint8_t *buf, unsigned int c) } *q++ = (c & 0x3f) | 0x80; } - return q - buf; + return (int)(q - buf); } static const unsigned int utf8_min_code[5] = { @@ -250,7 +250,8 @@ static const unsigned char utf8_first_code_mask[5] = { be >= 1. The maximum length for a UTF8 byte sequence is 6 bytes. */ int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp) { - int l, c, b, i; + int l, b, i; + uint8_t c; c = *p++; if (c < 0x80) { diff --git a/cutils.h b/cutils.h index 31f7cd84a..ad8661994 100644 --- a/cutils.h +++ b/cutils.h @@ -31,11 +31,160 @@ /* set if CPU is big endian */ #undef WORDS_BIGENDIAN -#define likely(x) __builtin_expect(!!(x), 1) -#define unlikely(x) __builtin_expect(!!(x), 0) -#define force_inline inline __attribute__((always_inline)) -#define no_inline __attribute__((noinline)) -#define __maybe_unused __attribute__((unused)) +#if defined(_WIN32) + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#include "win32/stdatomic.h" +#define _Atomic(x) x + +#include /* needed for timespec */ + +#define likely(x) (x) +#define unlikely(x) (x) +#define force_inline __forceinline +#define no_inline __declspec(noinline) +#define __maybe_unused +#define util_packed(_declaration) __pragma(pack(push, 1)) _declaration __pragma(pack(pop)) +#define util_format(...) + +#define js_popen _popen +#define js_pclose _pclose +#else + +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#define force_inline inline __attribute__((always_inline)) +#define no_inline __attribute__((noinline)) +#define __maybe_unused __attribute__((unused)) +#define util_packed(_declaration) _declaration __attribute__((packed)) +#define util_format(...) util_format(__VA_ARGS__)) + +#define js_popen popen +#define js_pclose pclose +#endif + +#if !defined(_SSIZE_T_DEFINED) +#if defined(_WIN64) +typedef unsigned __int64 ssize_t; +#elif defined(_WIN32) +typedef _W64 unsigned int ssize_t; +#endif +#define _SSIZE_T_DEFINED +#endif + +#if defined(_WIN32) +static int js_gettimeofday(struct timeval* tv, void* tz) +{ + (void)tz; + + // Note: some broken versions only have 8 trailing zero's, the correct epoch has 9 trailing zero's + // This magic number is the number of 100 nanosecond intervals since January 1, 1601 (UTC) + // until 00:00:00 January 1, 1970 + static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL); + + SYSTEMTIME system_time; + FILETIME file_time; + uint64_t time; + + GetSystemTime(&system_time); + SystemTimeToFileTime(&system_time, &file_time); + + time = ((uint64_t)file_time.dwLowDateTime); + time += ((uint64_t)file_time.dwHighDateTime) << 32; + + tv->tv_sec = (long)((time - EPOCH) / 10000000L); + tv->tv_usec = (long)(system_time.wMilliseconds * 1000); + + return 0; +} + +static int js_clock_getrealtime(struct timespec* ts) +{ + /* https://stackoverflow.com/a/5404467 */ + + LARGE_INTEGER t; + FILETIME f; + double microseconds; + static LARGE_INTEGER offset; + static double frequencyToMicroseconds; + static int initialized = 0; + static BOOL usePerformanceCounter = 0; + + if (!initialized) + { + LARGE_INTEGER performanceFrequency; + initialized = 1; + usePerformanceCounter = QueryPerformanceFrequency(&performanceFrequency); + if (usePerformanceCounter) + { + QueryPerformanceCounter(&offset); + frequencyToMicroseconds = (double)performanceFrequency.QuadPart / 1000000.; + } + else + { + SYSTEMTIME s; + s.wYear = 1970; + s.wMonth = 1; + s.wDay = 1; + s.wHour = 0; + s.wMinute = 0; + s.wSecond = 0; + s.wMilliseconds = 0; + SystemTimeToFileTime(&s, &f); + + offset.QuadPart = f.dwHighDateTime; + offset.QuadPart <<= 32; + offset.QuadPart |= f.dwLowDateTime; + + frequencyToMicroseconds = 10.0; + } + } + + if (usePerformanceCounter) + { + QueryPerformanceCounter(&t); + } + else + { + GetSystemTimeAsFileTime(&f); + t.QuadPart = f.dwHighDateTime; + t.QuadPart <<= 32; + t.QuadPart |= f.dwLowDateTime; + } + + t.QuadPart -= offset.QuadPart; + microseconds = (double)t.QuadPart / frequencyToMicroseconds; + t.QuadPart = microseconds; + + ts->tv_sec = t.QuadPart / 1000000; + ts->tv_nsec = t.QuadPart % 1000000; + + return 0; +} + +static int js_clock_getmonotonic(struct timespec* ts) +{ + return js_clock_getrealtime(ts); +} +#else +#define js_gettimeofday gettimeofday + +static int js_clock_getrealtime(struct timespec* ts) +{ + return clock_gettime(CLOCK_REALTIME, ts); +} + +static int js_clock_getmonotonic(struct timespec* ts) +{ + return clock_gettime(CLOCK_MONOTONIC, ts); +} + +#define js_popen popen +#endif #define xglue(x, y) x ## y #define glue(x, y) xglue(x, y) @@ -112,40 +261,64 @@ static inline int64_t min_int64(int64_t a, int64_t b) } /* WARNING: undefined if a = 0 */ -static inline int clz32(unsigned int a) +static force_inline int clz32(unsigned int a) { +#ifdef _WIN32 + uint32_t leading_zero = 0; + /* failing to bit scan is undefined, returning 32 instead */ + return (_BitScanReverse(&leading_zero, a)) ? (31 - leading_zero) : 32; +#else return __builtin_clz(a); +#endif } /* WARNING: undefined if a = 0 */ -static inline int clz64(uint64_t a) +static force_inline int clz64(uint64_t a) { +#ifdef _WIN32 + uint32_t leading_zero = 0; + /* failing to bit scan is undefined, returning 64 instead */ + return (_BitScanReverse64(&leading_zero, a)) ? (63 - leading_zero) : 32; +#else return __builtin_clzll(a); +#endif } /* WARNING: undefined if a = 0 */ static inline int ctz32(unsigned int a) { +#ifdef _WIN32 + uint32_t trailing_zero = 0; + /* failing to bit scan is undefined, returning 32 instead */ + return (_BitScanForward(&trailing_zero, a)) ? trailing_zero : 32; +#else return __builtin_ctz(a); +#endif } /* WARNING: undefined if a = 0 */ static inline int ctz64(uint64_t a) { +#ifdef _WIN32 + uint32_t trailing_zero = 0; + /* failing to bit scan is undefined, returning 64 instead */ + return (_BitScanForward64(&trailing_zero, a)) ? trailing_zero : 64; +#else return __builtin_ctzll(a); +#endif } -struct __attribute__((packed)) packed_u64 { +util_packed(struct packed_u64 { uint64_t v; -}; +}); -struct __attribute__((packed)) packed_u32 { +util_packed(struct packed_u32 { uint32_t v; -}; +}); -struct __attribute__((packed)) packed_u16 { +util_packed(struct packed_u16 { uint16_t v; -}; +}); static inline uint64_t get_u64(const uint8_t *tab) { @@ -262,7 +435,7 @@ static inline int dbuf_put_u64(DynBuf *s, uint64_t val) { return dbuf_put(s, (uint8_t *)&val, 8); } -int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s, +int util_format(printf, 2, 3) dbuf_printf(DynBuf *s, const char *fmt, ...); void dbuf_free(DynBuf *s); static inline BOOL dbuf_error(DynBuf *s) { diff --git a/libbf.c b/libbf.c index 3bf257a15..a481cc8c0 100644 --- a/libbf.c +++ b/libbf.c @@ -342,7 +342,7 @@ static inline limb_t get_bit(const limb_t *tab, limb_t len, slimb_t pos) { slimb_t i; i = pos >> LIMB_LOG2_BITS; - if (i < 0 || i >= len) + if (i < 0 || i >= (slimb_t)len) return 0; return (tab[i] >> (pos & (LIMB_BITS - 1))) & 1; } @@ -395,7 +395,7 @@ static inline limb_t scan_bit_nz(const bf_t *r, slimb_t bit_pos) static int bf_get_rnd_add(int *pret, const bf_t *r, limb_t l, slimb_t prec, int rnd_mode) { - int add_one, inexact; + limb_t add_one, inexact; limb_t bit1, bit0; if (rnd_mode == BF_RNDF) { @@ -420,7 +420,7 @@ static int bf_get_rnd_add(int *pret, const bf_t *r, limb_t l, } else { /* round to even */ add_one = - get_bit(r->tab, l, l * LIMB_BITS - 1 - (prec - 1)); + get_bit(r->tab, l, (slimb_t)(l * LIMB_BITS - 1 - (prec - 1))); } } break; @@ -442,7 +442,7 @@ static int bf_get_rnd_add(int *pret, const bf_t *r, limb_t l, if (inexact) *pret |= BF_ST_INEXACT; - return add_one; + return (int)add_one; } static int bf_set_overflow(bf_t *r, int sign, limb_t prec, bf_flags_t flags) @@ -5356,38 +5356,38 @@ int bf_acos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags) /* Note: we assume __int128 is available */ #define muldq(r1, r0, a, b) \ do { \ - unsigned __int128 __t; \ - __t = (unsigned __int128)(a) * (unsigned __int128)(b); \ + dlimb_t __t; \ + __t = (dlimb_t)(a) * (dlimb_t)(b); \ r0 = __t; \ r1 = __t >> 64; \ } while (0) #define divdq(q, r, a1, a0, b) \ do { \ - unsigned __int128 __t; \ + dlimb_t __t; \ limb_t __b = (b); \ - __t = ((unsigned __int128)(a1) << 64) | (a0); \ - q = __t / __b; \ - r = __t % __b; \ + __t = ((dlimb_t)(a1) << 64) | (a0); \ + q = __t / __b; \ + r = __t % __b; \ } while (0) #else #define muldq(r1, r0, a, b) \ do { \ - uint64_t __t; \ - __t = (uint64_t)(a) * (uint64_t)(b); \ + uint64_t __t; \ + __t = (uint64_t)(a) * (uint64_t)(b); \ r0 = __t; \ r1 = __t >> 32; \ } while (0) #define divdq(q, r, a1, a0, b) \ do { \ - uint64_t __t; \ + uint64_t __t; \ limb_t __b = (b); \ - __t = ((uint64_t)(a1) << 32) | (a0); \ - q = __t / __b; \ - r = __t % __b; \ + __t = ((uint64_t)(a1) << 32) | (a0); \ + q = __t / __b; \ + r = __t % __b; \ } while (0) #endif /* LIMB_BITS != 64 */ diff --git a/libbf.h b/libbf.h index 4576bf885..2c21f6f76 100644 --- a/libbf.h +++ b/libbf.h @@ -36,27 +36,41 @@ #define LIMB_BITS (1 << LIMB_LOG2_BITS) #if LIMB_BITS == 64 -typedef __int128 int128_t; -typedef unsigned __int128 uint128_t; -typedef int64_t slimb_t; -typedef uint64_t limb_t; -typedef uint128_t dlimb_t; -#define BF_RAW_EXP_MIN INT64_MIN -#define BF_RAW_EXP_MAX INT64_MAX -#define LIMB_DIGITS 19 -#define BF_DEC_BASE UINT64_C(10000000000000000000) +#ifdef _WIN32 + +/* NOTE: 128-bit integer types are not available on MSVC! */ + +typedef int64_t int128_t; +typedef uint64_t uint128_t; + +#else + +typedef __int128 int128_t; +typedef unsigned __int128 uint128_t; + +#endif + +typedef int64_t slimb_t; +typedef uint64_t limb_t; +typedef uint128_t dlimb_t; + +#define BF_RAW_EXP_MIN INT64_MIN +#define BF_RAW_EXP_MAX INT64_MAX + +#define LIMB_DIGITS 19 +#define BF_DEC_BASE UINT64_C(10000000000000000000) #else -typedef int32_t slimb_t; -typedef uint32_t limb_t; -typedef uint64_t dlimb_t; -#define BF_RAW_EXP_MIN INT32_MIN -#define BF_RAW_EXP_MAX INT32_MAX +typedef int32_t slimb_t; +typedef uint32_t limb_t; +typedef uint64_t dlimb_t; +#define BF_RAW_EXP_MIN INT32_MIN +#define BF_RAW_EXP_MAX INT32_MAX -#define LIMB_DIGITS 9 -#define BF_DEC_BASE 1000000000U +#define LIMB_DIGITS 9 +#define BF_DEC_BASE 1000000000U #endif diff --git a/libregexp.c b/libregexp.c index 379bfc7a9..78acb090d 100644 --- a/libregexp.c +++ b/libregexp.c @@ -401,7 +401,7 @@ static int re_emit_op_u32(REParseState *s, int op, uint32_t val) { int pos; dbuf_putc(&s->byte_code, op); - pos = s->byte_code.size; + pos = (int)s->byte_code.size; dbuf_put_u32(&s->byte_code, val); return pos; } @@ -410,7 +410,7 @@ static int re_emit_goto(REParseState *s, int op, uint32_t val) { int pos; dbuf_putc(&s->byte_code, op); - pos = s->byte_code.size; + pos = (int)s->byte_code.size; dbuf_put_u32(&s->byte_code, val - (pos + 4)); return pos; } @@ -427,7 +427,7 @@ static void re_emit_op_u16(REParseState *s, int op, uint32_t val) dbuf_put_u16(&s->byte_code, val); } -static int __attribute__((format(printf, 2, 3))) re_parse_error(REParseState *s, const char *fmt, ...) +static int util_format(printf, 2, 3) re_parse_error(REParseState *s, const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -465,7 +465,7 @@ static int parse_digits(const uint8_t **pp, BOOL allow_overflow) p++; } *pp = p; - return v; + return (int)v; } static int re_parse_expect(REParseState *s, const uint8_t **pp, int c) @@ -1234,7 +1234,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir) break; case '.': p++; - last_atom_start = s->byte_code.size; + last_atom_start = (int)s->byte_code.size; last_capture_count = s->capture_count; if (is_backward_dir) re_emit_op(s, REOP_prev); @@ -1272,7 +1272,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir) if (p[1] == '?') { if (p[2] == ':') { p += 3; - last_atom_start = s->byte_code.size; + last_atom_start = (int)s->byte_code.size; last_capture_count = s->capture_count; s->buf_ptr = p; if (re_parse_disjunction(s, is_backward_dir)) @@ -1296,7 +1296,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir) /* Annex B allows lookahead to be used as an atom for the quantifiers */ if (!s->is_utf16 && !is_backward_lookahead) { - last_atom_start = s->byte_code.size; + last_atom_start = (int)s->byte_code.size; last_capture_count = s->capture_count; } pos = re_emit_op_u32(s, REOP_lookahead + is_neg, 0); @@ -1336,7 +1336,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir) parse_capture: if (s->capture_count >= CAPTURE_COUNT_MAX) return re_parse_error(s, "too many captures"); - last_atom_start = s->byte_code.size; + last_atom_start = (int)s->byte_code.size; last_capture_count = s->capture_count; capture_index = s->capture_count++; re_emit_op_u8(s, REOP_save_start + is_backward_dir, @@ -1445,7 +1445,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir) return re_parse_error(s, "back reference out of range in regular expression"); } emit_back_reference: - last_atom_start = s->byte_code.size; + last_atom_start = (int)s->byte_code.size; last_capture_count = s->capture_count; re_emit_op_u8(s, REOP_back_reference + is_backward_dir, c); } @@ -1455,7 +1455,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir) } break; case '[': - last_atom_start = s->byte_code.size; + last_atom_start = (int)s->byte_code.size; last_capture_count = s->capture_count; if (is_backward_dir) re_emit_op(s, REOP_prev); @@ -1475,7 +1475,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir) if ((int)c < 0) return -1; normal_char: - last_atom_start = s->byte_code.size; + last_atom_start = (int)s->byte_code.size; last_capture_count = s->capture_count; if (is_backward_dir) re_emit_op(s, REOP_prev); diff --git a/qjs.c b/qjs.c index 4dd11f83b..ef23f979e 100644 --- a/qjs.c +++ b/qjs.c @@ -28,11 +28,15 @@ #include #include #include +#if !defined(_WIN32) #include +#endif #include #include #include -#if defined(__APPLE__) +#if defined(_WIN32) +#include +#elif defined(__APPLE__) #include #elif defined(__linux__) #include @@ -97,7 +101,7 @@ static int eval_file(JSContext *ctx, const char *filename, int module) eval_flags = JS_EVAL_TYPE_MODULE; else eval_flags = JS_EVAL_TYPE_GLOBAL; - ret = eval_buf(ctx, buf, buf_len, filename, eval_flags); + ret = eval_buf(ctx, buf, (int)buf_len, filename, eval_flags); js_free(ctx, buf); return ret; } @@ -156,7 +160,7 @@ static inline size_t js_trace_malloc_usable_size(void *ptr) #endif } -static void __attribute__((format(printf, 2, 3))) +static void util_format(printf, 2, 3) js_trace_malloc_printf(JSMallocState *s, const char *fmt, ...) { va_list ap; diff --git a/qjsc.c b/qjsc.c index f5bda57f6..e6c5fc1d2 100644 --- a/qjsc.c +++ b/qjsc.c @@ -27,9 +27,12 @@ #include #include #include -#include #include -#if !defined(_WIN32) +#if defined(_WIN32) +#include +#include "win32/getopt.h" +#else +#include #include #endif @@ -91,7 +94,7 @@ void namelist_add(namelist_t *lp, const char *name, const char *short_name, realloc(lp->array, sizeof(lp->array[0]) * newsize); /* XXX: check for realloc failure */ lp->array = a; - lp->size = newsize; + lp->size = (int)newsize; } e = &lp->array[lp->count++]; e->name = strdup(name); @@ -142,7 +145,7 @@ static void get_c_name(char *buf, size_t buf_size, const char *file) len = strlen(p); else len = r - p; - pstrcpy(buf, buf_size, c_ident_prefix); + pstrcpy(buf, (int)buf_size, c_ident_prefix); q = buf + strlen(buf); for(i = 0; i < len; i++) { c = p[i]; @@ -225,7 +228,7 @@ static void find_unique_cname(char *cname, size_t cname_size) break; suffix_num++; } - pstrcpy(cname, cname_size, cname1); + pstrcpy(cname, (int)cname_size, cname1); } JSModuleDef *jsc_module_loader(JSContext *ctx, diff --git a/quickjs-libc.c b/quickjs-libc.c index e8b81e910..4cbca2829 100644 --- a/quickjs-libc.c +++ b/quickjs-libc.c @@ -28,25 +28,32 @@ #include #include #include -#include #include #include -#include #include #include #include #include -#include + #if defined(_WIN32) #include #include -#include +#include +#include + +#define js_path_max _MAX_PATH #else +#include #include #include +#include +#include +#include #include #include +#define js_path_max PATH_MAX + #if defined(__APPLE__) typedef sig_t sighandler_t; #if !defined(environ) @@ -515,7 +522,7 @@ int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val, JS_BOOL use_realpath, JS_BOOL is_main) { JSModuleDef *m; - char buf[PATH_MAX + 16]; + char buf[js_path_max + 16]; JSValue meta_obj; JSAtom module_name_atom; const char *module_name; @@ -798,7 +805,7 @@ static void js_std_file_finalizer(JSRuntime *rt, JSValue val) if (s) { if (s->f && s->close_in_finalizer) { if (s->is_popen) - pclose(s->f); + js_pclose(s->f); else fclose(s->f); } @@ -919,7 +926,7 @@ static JSValue js_std_popen(JSContext *ctx, JSValueConst this_val, goto fail; } - f = popen(filename, mode); + f = js_popen(filename, mode); if (!f) err = errno; else @@ -1042,7 +1049,7 @@ static JSValue js_std_file_close(JSContext *ctx, JSValueConst this_val, if (!s->f) return JS_ThrowTypeError(ctx, "invalid file handle"); if (s->is_popen) - err = js_get_errno(pclose(s->f)); + err = js_get_errno(js_pclose(s->f)); else err = js_get_errno(fclose(s->f)); s->f = NULL; @@ -1363,7 +1370,7 @@ static JSValue js_std_urlGet(JSContext *ctx, JSValueConst this_val, return JS_EXCEPTION; } // printf("%s\n", (char *)cmd_buf.buf); - f = popen((char *)cmd_buf.buf, "r"); + f = js_popen((char *)cmd_buf.buf, "r"); dbuf_free(&cmd_buf); if (!f) { return JS_ThrowTypeError(ctx, "could not start curl"); @@ -1420,7 +1427,7 @@ static JSValue js_std_urlGet(JSContext *ctx, JSValueConst this_val, done: js_free(ctx, buf); buf = NULL; - pclose(f); + js_pclose(f); f = NULL; dbuf_free(data_buf); data_buf = NULL; @@ -1448,7 +1455,7 @@ static JSValue js_std_urlGet(JSContext *ctx, JSValueConst this_val, return ret_obj; fail: if (f) - pclose(f); + js_pclose(f); js_free(ctx, buf); if (data_buf) dbuf_free(data_buf); @@ -1947,7 +1954,7 @@ static JSValue js_os_signal(JSContext *ctx, JSValueConst this_val, static int64_t get_time_ms(void) { struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); + js_clock_getmonotonic(&ts); return (uint64_t)ts.tv_sec * 1000 + (ts.tv_nsec / 1000000); } #else @@ -1955,7 +1962,7 @@ static int64_t get_time_ms(void) static int64_t get_time_ms(void) { struct timeval tv; - gettimeofday(&tv, NULL); + js_gettimeofday(&tv, NULL); return (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000); } #endif @@ -2352,7 +2359,7 @@ static JSValue make_string_error(JSContext *ctx, static JSValue js_os_getcwd(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { - char buf[PATH_MAX]; + char buf[js_path_max]; int err; if (!getcwd(buf, sizeof(buf))) { @@ -2408,7 +2415,13 @@ static JSValue js_os_readdir(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { const char *path; +#if defined(_WIN32) + HANDLE hFind; + WIN32_FIND_DATA hData; + int f = 0; +#else DIR *f; +#endif struct dirent *d; JSValue obj; int err; @@ -2422,7 +2435,12 @@ static JSValue js_os_readdir(JSContext *ctx, JSValueConst this_val, JS_FreeCString(ctx, path); return JS_EXCEPTION; } +#if defined(_WIN32) + hFind = FindFirstFileA(path, &hData); + f = hFind != INVALID_HANDLE_VALUE; +#else f = opendir(path); +#endif if (!f) err = errno; else @@ -2431,6 +2449,16 @@ static JSValue js_os_readdir(JSContext *ctx, JSValueConst this_val, if (!f) goto done; len = 0; +#if defined(_WIN32) + do + { + JS_DefinePropertyValueUint32(ctx, obj, len++, + JS_NewString(ctx, hData.cFileName), + JS_PROP_C_W_E); + + } while (FindNextFileA(hFind, &hData)); + FindClose(hFind); +#else for(;;) { errno = 0; d = readdir(f); @@ -2443,6 +2471,7 @@ static JSValue js_os_readdir(JSContext *ctx, JSValueConst this_val, JS_PROP_C_W_E); } closedir(f); +#endif done: return make_obj_error(ctx, obj, err); } @@ -2595,7 +2624,7 @@ static JSValue js_os_realpath(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { const char *path; - char buf[PATH_MAX], *res; + char buf[js_path_max], *res; int err; path = JS_ToCString(ctx, argv[0]); @@ -2637,7 +2666,7 @@ static JSValue js_os_readlink(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { const char *path; - char buf[PATH_MAX]; + char buf[js_path_max]; int err; ssize_t res; @@ -2719,7 +2748,7 @@ static char **build_envp(JSContext *ctx, JSValueConst obj) static int my_execvpe(const char *filename, char **argv, char **envp) { char *path, *p, *p_next, *p1; - char buf[PATH_MAX]; + char buf[js_path_max]; size_t filename_len, path_len; BOOL eacces_error; @@ -2746,7 +2775,7 @@ static int my_execvpe(const char *filename, char **argv, char **envp) path_len = p1 - p; } /* path too long */ - if ((path_len + 1 + filename_len + 1) > PATH_MAX) + if ((path_len + 1 + filename_len + 1) > js_path_max) continue; memcpy(buf, p, path_len); buf[path_len] = '/'; @@ -3585,12 +3614,12 @@ static const JSCFunctionListEntry js_os_funcs[] = { JS_CFUNC_DEF("readdir", 1, js_os_readdir ), /* st_mode constants */ OS_FLAG(S_IFMT), - OS_FLAG(S_IFIFO), OS_FLAG(S_IFCHR), OS_FLAG(S_IFDIR), - OS_FLAG(S_IFBLK), OS_FLAG(S_IFREG), #if !defined(_WIN32) + OS_FLAG(S_IFIFO), + OS_FLAG(S_IFBLK), OS_FLAG(S_IFSOCK), OS_FLAG(S_IFLNK), OS_FLAG(S_ISGID), diff --git a/quickjs.c b/quickjs.c index a39ff8f66..2501417c1 100644 --- a/quickjs.c +++ b/quickjs.c @@ -28,15 +28,19 @@ #include #include #include -#include #include #include #include + +#if !defined(_WIN32) +#include + #if defined(__APPLE__) #include #elif defined(__linux__) #include #endif +#endif #include "cutils.h" #include "list.h" @@ -46,12 +50,16 @@ #include "libbf.h" #endif +#ifndef CONFIG_DIRECT_DISPATCH +#define CONFIG_DIRECT_DISPATCH 1 +#endif + #define OPTIMIZE 1 #define SHORT_OPCODES 1 #if defined(EMSCRIPTEN) #define DIRECT_DISPATCH 0 #else -#define DIRECT_DISPATCH 1 +#define DIRECT_DISPATCH CONFIG_DIRECT_DISPATCH #endif #if defined(__APPLE__) @@ -109,7 +117,9 @@ #ifdef CONFIG_ATOMICS #include +#if !defined(_WIN32) #include +#endif #include #endif @@ -202,7 +212,11 @@ typedef enum JSErrorEnum { #define JS_STACK_SIZE_MAX 65534 #define JS_STRING_LEN_MAX ((1 << 30) - 1) +#if defined(_WIN32) +#define __exception +#else #define __exception __attribute__((warn_unused_result)) +#endif typedef struct JSShape JSShape; typedef struct JSString JSString; @@ -1018,7 +1032,7 @@ static __exception int JS_ToArrayLengthFree(JSContext *ctx, uint32_t *plen, JSValue val, BOOL is_array_ctor); static JSValue JS_EvalObject(JSContext *ctx, JSValueConst this_obj, JSValueConst val, int flags, int scope_idx); -JSValue __attribute__((format(printf, 2, 3))) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...); +JSValue util_format(printf, 2, 3) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...); static __maybe_unused void JS_DumpAtoms(JSRuntime *rt); static __maybe_unused void JS_DumpString(JSRuntime *rt, const JSString *p); @@ -1567,7 +1581,7 @@ static void set_dummy_numeric_ops(JSNumericOperations *ops) #endif /* CONFIG_BIGNUM */ -#if !defined(CONFIG_STACK_CHECK) +#if defined(WIN32) || !defined(CONFIG_STACK_CHECK) /* no stack limitation */ static inline uint8_t *js_get_stack_pointer(void) { @@ -6582,7 +6596,7 @@ static JSValue JS_ThrowError(JSContext *ctx, JSErrorEnum error_num, return JS_ThrowError2(ctx, error_num, fmt, ap, add_backtrace); } -JSValue __attribute__((format(printf, 2, 3))) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...) +JSValue util_format(printf, 2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; @@ -6593,7 +6607,7 @@ JSValue __attribute__((format(printf, 2, 3))) JS_ThrowSyntaxError(JSContext *ctx return val; } -JSValue __attribute__((format(printf, 2, 3))) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...) +JSValue util_format(printf, 2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; @@ -6604,7 +6618,7 @@ JSValue __attribute__((format(printf, 2, 3))) JS_ThrowTypeError(JSContext *ctx, return val; } -static int __attribute__((format(printf, 3, 4))) JS_ThrowTypeErrorOrFalse(JSContext *ctx, int flags, const char *fmt, ...) +static int util_format(printf, 3, 4) JS_ThrowTypeErrorOrFalse(JSContext *ctx, int flags, const char *fmt, ...) { va_list ap; @@ -6620,7 +6634,7 @@ static int __attribute__((format(printf, 3, 4))) JS_ThrowTypeErrorOrFalse(JSCont } /* never use it directly */ -static JSValue __attribute__((format(printf, 3, 4))) __JS_ThrowTypeErrorAtom(JSContext *ctx, JSAtom atom, const char *fmt, ...) +static JSValue util_format(printf, 3, 4) __JS_ThrowTypeErrorAtom(JSContext *ctx, JSAtom atom, const char *fmt, ...) { char buf[ATOM_GET_STR_BUF_SIZE]; return JS_ThrowTypeError(ctx, fmt, @@ -6628,7 +6642,7 @@ static JSValue __attribute__((format(printf, 3, 4))) __JS_ThrowTypeErrorAtom(JSC } /* never use it directly */ -static JSValue __attribute__((format(printf, 3, 4))) __JS_ThrowSyntaxErrorAtom(JSContext *ctx, JSAtom atom, const char *fmt, ...) +static JSValue util_format(printf, 3, 4) __JS_ThrowSyntaxErrorAtom(JSContext *ctx, JSAtom atom, const char *fmt, ...) { char buf[ATOM_GET_STR_BUF_SIZE]; return JS_ThrowSyntaxError(ctx, fmt, @@ -6651,7 +6665,7 @@ static int JS_ThrowTypeErrorReadOnly(JSContext *ctx, int flags, JSAtom atom) } } -JSValue __attribute__((format(printf, 2, 3))) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...) +JSValue util_format(printf, 2, 3) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; @@ -6662,7 +6676,7 @@ JSValue __attribute__((format(printf, 2, 3))) JS_ThrowReferenceError(JSContext * return val; } -JSValue __attribute__((format(printf, 2, 3))) JS_ThrowRangeError(JSContext *ctx, const char *fmt, ...) +JSValue util_format(printf, 2, 3) JS_ThrowRangeError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; @@ -6673,7 +6687,7 @@ JSValue __attribute__((format(printf, 2, 3))) JS_ThrowRangeError(JSContext *ctx, return val; } -JSValue __attribute__((format(printf, 2, 3))) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...) +JSValue util_format(printf, 2, 3) JS_ThrowInternalError(JSContext *ctx, const char *fmt, ...) { JSValue val; va_list ap; @@ -7220,7 +7234,7 @@ static int JS_DefinePrivateField(JSContext *ctx, JSValueConst obj, JS_ThrowTypeErrorNotASymbol(ctx); goto fail; } - prop = js_symbol_to_atom(ctx, (JSValue)name); + prop = js_symbol_to_atom(ctx, name); p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (prs) { @@ -7251,7 +7265,7 @@ static JSValue JS_GetPrivateField(JSContext *ctx, JSValueConst obj, /* safety check */ if (unlikely(JS_VALUE_GET_TAG(name) != JS_TAG_SYMBOL)) return JS_ThrowTypeErrorNotASymbol(ctx); - prop = js_symbol_to_atom(ctx, (JSValue)name); + prop = js_symbol_to_atom(ctx, name); p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (!prs) { @@ -7278,7 +7292,7 @@ static int JS_SetPrivateField(JSContext *ctx, JSValueConst obj, JS_ThrowTypeErrorNotASymbol(ctx); goto fail; } - prop = js_symbol_to_atom(ctx, (JSValue)name); + prop = js_symbol_to_atom(ctx, name); p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (!prs) { @@ -7368,7 +7382,7 @@ static int JS_CheckBrand(JSContext *ctx, JSValueConst obj, JSValueConst func) if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT)) goto not_obj; p = JS_VALUE_GET_OBJ(obj); - prs = find_own_property(&pr, p, js_symbol_to_atom(ctx, (JSValue)brand)); + prs = find_own_property(&pr, p, js_symbol_to_atom(ctx, brand)); if (!prs) { JS_ThrowTypeError(ctx, "invalid brand on object"); return -1; @@ -8996,7 +9010,7 @@ int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj, return -1; } /* this code relies on the fact that Uint32 are never allocated */ - val = (JSValueConst)JS_NewUint32(ctx, array_length); + val = JS_NewUint32(ctx, array_length); /* prs may have been modified */ prs = find_own_property(&pr, p, prop); assert(prs != NULL); @@ -10191,7 +10205,7 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp, } else #endif { - double d = 1.0 / 0.0; + double d = NAN; if (is_neg) d = -d; val = JS_NewFloat64(ctx, d); @@ -15948,7 +15962,7 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, #else sf->js_mode = 0; #endif - sf->cur_func = (JSValue)func_obj; + sf->cur_func = func_obj; sf->arg_count = argc; arg_buf = argv; @@ -16192,7 +16206,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, sf->js_mode = b->js_mode; arg_buf = argv; sf->arg_count = argc; - sf->cur_func = (JSValue)func_obj; + sf->cur_func = func_obj; init_list_head(&sf->var_ref_list); var_refs = p->u.func.var_refs; @@ -20075,7 +20089,7 @@ static void free_token(JSParseState *s, JSToken *token) } } -static void __attribute((unused)) dump_token(JSParseState *s, +static void js_unused dump_token(JSParseState *s, const JSToken *token) { switch(token->val) { @@ -20136,7 +20150,7 @@ static void __attribute((unused)) dump_token(JSParseState *s, } } -int __attribute__((format(printf, 2, 3))) js_parse_error(JSParseState *s, const char *fmt, ...) +int util_format(printf, 2, 3) js_parse_error(JSParseState *s, const char *fmt, ...) { JSContext *ctx = s->ctx; va_list ap; @@ -34704,7 +34718,7 @@ typedef struct BCReaderState { } BCReaderState; #ifdef DUMP_READ_OBJECT -static void __attribute__((format(printf, 2, 3))) bc_read_trace(BCReaderState *s, const char *fmt, ...) { +static void util_format(printf, 2, 3) bc_read_trace(BCReaderState *s, const char *fmt, ...) { va_list ap; int i, n, n0; @@ -39088,8 +39102,8 @@ static int64_t JS_FlattenIntoArray(JSContext *ctx, JSValueConst target, if (!JS_IsUndefined(mapperFunction)) { JSValueConst args[3] = { element, JS_NewInt64(ctx, sourceIndex), source }; element = JS_Call(ctx, mapperFunction, thisArg, 3, args); - JS_FreeValue(ctx, (JSValue)args[0]); - JS_FreeValue(ctx, (JSValue)args[1]); + JS_FreeValue(ctx, args[0]); + JS_FreeValue(ctx, args[1]); if (JS_IsException(element)) return -1; } @@ -40506,7 +40520,7 @@ static JSValue js_string_match(JSContext *ctx, JSValueConst this_val, str = JS_NewString(ctx, "g"); if (JS_IsException(str)) goto fail; - args[args_len++] = (JSValueConst)str; + args[args_len++] = str; } rx = JS_CallConstructor(ctx, ctx->regexp_ctor, args_len, args); JS_FreeValue(ctx, str); @@ -41564,7 +41578,7 @@ static JSValue js_math_min_max(JSContext *ctx, JSValueConst this_val, uint32_t tag; if (unlikely(argc == 0)) { - return __JS_NewFloat64(ctx, is_max ? -1.0 / 0.0 : 1.0 / 0.0); + return __JS_NewFloat64(ctx, is_max ? -NAN : NAN); } tag = JS_VALUE_GET_TAG(argv[0]); @@ -41646,6 +41660,21 @@ static double js_math_round(double a) return u.d; } +static double js_math_abs(double a) +{ + return abs(a); +} + +static double js_math_ceil(double a) +{ + return ceil(a); +} + +static double js_math_floor(double a) +{ + return floor(a); +} + static JSValue js_math_hypot(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) { @@ -41717,8 +41746,8 @@ static uint64_t xorshift64star(uint64_t *pstate) static void js_random_init(JSContext *ctx) { struct timeval tv; - gettimeofday(&tv, NULL); - ctx->random_state = ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec; + js_gettimeofday(&tv, NULL); + ctx->random_state = ((uint64_t)tv.tv_sec * 1000000) + (uint64_t)tv.tv_usec; /* the state must be non zero */ if (ctx->random_state == 0) ctx->random_state = 1; @@ -41739,9 +41768,9 @@ static JSValue js_math_random(JSContext *ctx, JSValueConst this_val, static const JSCFunctionListEntry js_math_funcs[] = { JS_CFUNC_MAGIC_DEF("min", 2, js_math_min_max, 0 ), JS_CFUNC_MAGIC_DEF("max", 2, js_math_min_max, 1 ), - JS_CFUNC_SPECIAL_DEF("abs", 1, f_f, fabs ), - JS_CFUNC_SPECIAL_DEF("floor", 1, f_f, floor ), - JS_CFUNC_SPECIAL_DEF("ceil", 1, f_f, ceil ), + JS_CFUNC_SPECIAL_DEF("abs", 1, f_f, js_math_abs ), + JS_CFUNC_SPECIAL_DEF("floor", 1, f_f, js_math_floor ), + JS_CFUNC_SPECIAL_DEF("ceil", 1, f_f, js_math_ceil ), JS_CFUNC_SPECIAL_DEF("round", 1, f_f, js_math_round ), JS_CFUNC_SPECIAL_DEF("sqrt", 1, f_f, sqrt ), @@ -41798,7 +41827,7 @@ static JSValue js___date_now(JSContext *ctx, JSValueConst this_val, { int64_t d; struct timeval tv; - gettimeofday(&tv, NULL); + js_gettimeofday(&tv, NULL); d = (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000); return JS_NewInt64(ctx, d); } @@ -41810,7 +41839,7 @@ static JSValue js___date_clock(JSContext *ctx, JSValueConst this_val, { int64_t d; struct timeval tv; - gettimeofday(&tv, NULL); + js_gettimeofday(&tv, NULL); d = (int64_t)tv.tv_sec * 1000000 + tv.tv_usec; return JS_NewInt64(ctx, d); } @@ -45534,7 +45563,7 @@ static JSMapRecord *map_add_record(JSContext *ctx, JSMapState *s, } else { JS_DupValue(ctx, key); } - mr->key = (JSValue)key; + mr->key = key; h = map_hash_key(ctx, key) & (s->hash_size - 1); list_add_tail(&mr->hash_link, &s->hash_table[h]); list_add_tail(&mr->link, &s->records); @@ -45756,7 +45785,7 @@ static JSValue js_map_forEach(JSContext *ctx, JSValueConst this_val, args[0] = args[1]; else args[0] = JS_DupValue(ctx, mr->value); - args[2] = (JSValue)this_val; + args[2] = this_val; ret = JS_Call(ctx, func, this_arg, 3, (JSValueConst *)args); JS_FreeValue(ctx, args[0]); if (!magic) @@ -46734,7 +46763,7 @@ static JSValue js_promise_all(JSContext *ctx, JSValueConst this_val, goto fail_reject; } resolve_element_data[0] = JS_NewBool(ctx, FALSE); - resolve_element_data[1] = (JSValueConst)JS_NewInt32(ctx, index); + resolve_element_data[1] = JS_NewInt32(ctx, index); resolve_element_data[2] = values; resolve_element_data[3] = resolving_funcs[is_promise_any]; resolve_element_data[4] = resolve_element_env; @@ -47093,7 +47122,7 @@ static JSValue js_async_from_sync_iterator_unwrap_func_create(JSContext *ctx, { JSValueConst func_data[1]; - func_data[0] = (JSValueConst)JS_NewBool(ctx, done); + func_data[0] = JS_NewBool(ctx, done); return JS_NewCFunctionData(ctx, js_async_from_sync_iterator_unwrap, 1, 0, 1, func_data); } @@ -47398,7 +47427,7 @@ static int isURIReserved(int c) { return c < 0x100 && memchr(";/?:@&=+$,#", c, sizeof(";/?:@&=+$,#") - 1) != NULL; } -static int __attribute__((format(printf, 2, 3))) js_throw_URIError(JSContext *ctx, const char *fmt, ...) +static int util_format(printf, 2, 3) js_throw_URIError(JSContext *ctx, const char *fmt, ...) { va_list ap; @@ -48019,7 +48048,7 @@ static JSValue get_date_string(JSContext *ctx, JSValueConst this_val, /* OS dependent: return the UTC time in ms since 1970. */ static int64_t date_now(void) { struct timeval tv; - gettimeofday(&tv, NULL); + js_gettimeofday(&tv, NULL); return (int64_t)tv.tv_sec * 1000 + (tv.tv_usec / 1000); } @@ -52456,8 +52485,8 @@ static int js_TA_cmp_generic(const void *a, const void *b, void *opaque) { psc->exception = 1; } done: - JS_FreeValue(ctx, (JSValue)argv[0]); - JS_FreeValue(ctx, (JSValue)argv[1]); + JS_FreeValue(ctx, argv[0]); + JS_FreeValue(ctx, argv[1]); } return cmp; } @@ -53617,7 +53646,7 @@ static JSValue js_atomics_wait(JSContext *ctx, ret = 0; } else { /* XXX: use clock monotonic */ - clock_gettime(CLOCK_REALTIME, &ts); + js_clock_getrealtime(&ts); ts.tv_sec += timeout / 1000; ts.tv_nsec += (timeout % 1000) * 1000000; if (ts.tv_nsec >= 1000000000) { diff --git a/quickjs.h b/quickjs.h index 92457a2f5..590378da6 100644 --- a/quickjs.h +++ b/quickjs.h @@ -33,15 +33,17 @@ extern "C" { #endif #if defined(__GNUC__) || defined(__clang__) -#define js_likely(x) __builtin_expect(!!(x), 1) -#define js_unlikely(x) __builtin_expect(!!(x), 0) -#define js_force_inline inline __attribute__((always_inline)) +#define js_likely(x) __builtin_expect(!!(x), 1) +#define js_unlikely(x) __builtin_expect(!!(x), 0) +#define js_force_inline inline __attribute__((always_inline)) #define __js_printf_like(f, a) __attribute__((format(printf, f, a))) +#define js_unused __attribute((unused)) #else -#define js_likely(x) (x) -#define js_unlikely(x) (x) -#define js_force_inline inline +#define js_likely(x) (x) +#define js_unlikely(x) (x) +#define js_force_inline inline #define __js_printf_like(a, b) +#define js_unused #endif #define JS_BOOL int @@ -517,9 +519,9 @@ static js_force_inline JSValue JS_NewInt64(JSContext *ctx, int64_t val) { JSValue v; if (val == (int32_t)val) { - v = JS_NewInt32(ctx, val); + v = JS_NewInt32(ctx, (int32_t)val); } else { - v = __JS_NewFloat64(ctx, val); + v = __JS_NewFloat64(ctx, (double)val); } return v; } @@ -662,7 +664,7 @@ static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v) JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); p->ref_count++; } - return (JSValue)v; + return v; } static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v) @@ -671,7 +673,7 @@ static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v) JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); p->ref_count++; } - return (JSValue)v; + return v; } int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */ diff --git a/run-test262.c b/run-test262.c index c860dbbcc..7090b79de 100644 --- a/run-test262.c +++ b/run-test262.c @@ -29,11 +29,14 @@ #include #include #include -#include #include #include + +#if !defined(_WIN32) #include #include +#include +#endif #include "cutils.h" #include "list.h" @@ -85,8 +88,8 @@ int test_count, test_failed, test_index, test_skipped, test_excluded; int new_errors, changed_errors, fixed_errors; int async_done; -void warning(const char *, ...) __attribute__((__format__(__printf__, 1, 2))); -void fatal(int, const char *, ...) __attribute__((__format__(__printf__, 2, 3))); +void warning(const char *, ...) util_format(printf, 1, 2); +void fatal(int, const char *, ...) util_format(printf, 2, 3); void warning(const char *fmt, ...) { @@ -365,7 +368,34 @@ static void enumerate_tests(const char *path) { namelist_t *lp = &test_list; int start = lp->count; +#if defined(_WIN32) + HANDLE hFind; + WIN32_FIND_DATA hData; + char searchPath[_MAX_PATH]; + + memset(searchPath, 0, _MAX_PATH); + strncpy_s(searchPath, _MAX_PATH, path, strlen(path)); + strncat_s(searchPath, _MAX_PATH, "\\*", strlen("\\*")); + + hFind = FindFirstFileA(searchPath, &hData); + if (hFind != INVALID_HANDLE_VALUE) + { + do + { + char fullPath[_MAX_PATH]; + memset(fullPath, 0, _MAX_PATH); + strncpy_s(fullPath, _MAX_PATH, path, strlen(path)); + strncat_s(fullPath, _MAX_PATH, "\\", strlen("\\")); + strncat_s(fullPath, _MAX_PATH, hData.cFileName, strlen(hData.cFileName)); + + add_test_file(fullPath, NULL, 0); + + } while (FindNextFileA(hFind, &hData)); + FindClose(hFind); + } +#else ftw(path, add_test_file, 100); +#endif qsort(lp->array + start, lp->count - start, sizeof(*lp->array), namelist_cmp_indirect); } @@ -638,20 +668,32 @@ static JSValue js_agent_receiveBroadcast(JSContext *ctx, JSValue this_val, return JS_UNDEFINED; } +#if defined(WIN32) +void js_usleep(uint32_t us) +{ + Sleep(us / 1000); +} +#else +void js_usleep(uint32_t us) +{ + usleep(us); +} +#endif + static JSValue js_agent_sleep(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { uint32_t duration; if (JS_ToUint32(ctx, &duration, argv[0])) return JS_EXCEPTION; - usleep(duration * 1000); + js_usleep(duration * 1000); return JS_UNDEFINED; } static int64_t get_clock_ms(void) { struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); + js_clock_getmonotonic(&ts); return (uint64_t)ts.tv_sec * 1000 + (ts.tv_nsec / 1000000); } diff --git a/unicode_gen.c b/unicode_gen.c index f18aaa0ab..afda325e7 100644 --- a/unicode_gen.c +++ b/unicode_gen.c @@ -1827,7 +1827,7 @@ void check_case_conv(void) static int64_t get_time_ns(void) { struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); + js_clock_getmonotonic(&ts); return (int64_t)ts.tv_sec * 1000000000 + ts.tv_nsec; } #endif diff --git a/win32/getopt.c b/win32/getopt.c new file mode 100644 index 000000000..9ebe10af2 --- /dev/null +++ b/win32/getopt.c @@ -0,0 +1,104 @@ +/* +* Copyright (c) 1987, 1993, 1994 +* The Regents of the University of California. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. All advertising materials mentioning features or use of this software +* must display the following acknowledgement: +* This product includes software developed by the University of +* California, Berkeley and its contributors. +* 4. Neither the name of the University nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +*/ + +#include +#include + +int opterr = 1, /* if error message should be printed */ +optind = 1, /* index into parent argv vector */ +optopt, /* character checked for validity */ +optreset; /* reset getopt */ +char* optarg; /* argument associated with option */ + +#define BADCH (int)'?' +#define BADARG (int)':' +#define EMSG "" + +/* + * getopt -- + * Parse argc/argv argument vector. + */ +int getopt(int nargc, char* const nargv[], const char* ostr) +{ + static char* place = EMSG; /* option letter processing */ + const char* oli; /* option letter list index */ + + if (optreset || !*place) { /* update scanning pointer */ + optreset = 0; + if (optind >= nargc || *(place = nargv[optind]) != '-') { + place = EMSG; + return (-1); + } + if (place[1] && *++place == '-') { /* found "--" */ + ++optind; + place = EMSG; + return (-1); + } + } /* option letter okay? */ + if ((optopt = (int)*place++) == (int)':' || + !(oli = strchr(ostr, optopt))) { + /* + * if the user didn't specify '-' as an option, + * assume it means -1. + */ + if (optopt == (int)'-') + return (-1); + if (!*place) + ++optind; + if (opterr && *ostr != ':') + (void)printf("illegal option -- %c\n", optopt); + return (BADCH); + } + if (*++oli != ':') { /* don't need argument */ + optarg = NULL; + if (!*place) + ++optind; + } + else { /* need an argument */ + if (*place) /* no white space */ + optarg = place; + else if (nargc <= ++optind) { /* no arg */ + place = EMSG; + if (*ostr == ':') + return (BADARG); + if (opterr) + (void)printf("option requires an argument -- %c\n", optopt); + return (BADCH); + } + else /* white space */ + optarg = nargv[optind]; + place = EMSG; + ++optind; + } + return (optopt); /* dump back option letter */ +} \ No newline at end of file diff --git a/win32/getopt.h b/win32/getopt.h new file mode 100644 index 000000000..027468379 --- /dev/null +++ b/win32/getopt.h @@ -0,0 +1,45 @@ +/* +* Copyright (c) 1987, 1993, 1994 +* The Regents of the University of California. All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* 3. All advertising materials mentioning features or use of this software +* must display the following acknowledgement: +* This product includes software developed by the University of +* California, Berkeley and its contributors. +* 4. Neither the name of the University nor the names of its contributors +* may be used to endorse or promote products derived from this software +* without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +* SUCH DAMAGE. +*/ + +#ifndef GETOPT_H +#define GETOPT_H + +int getopt(int nargc, char* const nargv[], const char* ostr); + +extern int opterr = 1, /* if error message should be printed */ +optind = 1, /* index into parent argv vector */ +optopt, /* character checked for validity */ +optreset; /* reset getopt */ +extern char* optarg; /* argument associated with option */ + +#endif \ No newline at end of file diff --git a/win32/stdatomic.h b/win32/stdatomic.h new file mode 100644 index 000000000..dc38800bc --- /dev/null +++ b/win32/stdatomic.h @@ -0,0 +1,181 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef COMPAT_ATOMICS_WIN32_STDATOMIC_H +#define COMPAT_ATOMICS_WIN32_STDATOMIC_H + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include + +#define ATOMIC_FLAG_INIT 0 + +#define ATOMIC_VAR_INIT(value) (value) + +#define atomic_init(obj, value) \ +do { \ + *(obj) = (value); \ +} while(0) + +#define kill_dependency(y) ((void)0) + +#define atomic_thread_fence(order) \ + MemoryBarrier(); + +#define atomic_signal_fence(order) \ + ((void)0) + +#define atomic_is_lock_free(obj) 0 + +typedef intptr_t atomic_flag; +typedef intptr_t atomic_bool; +typedef intptr_t atomic_char; +typedef intptr_t atomic_schar; +typedef intptr_t atomic_uchar; +typedef intptr_t atomic_short; +typedef intptr_t atomic_ushort; +typedef intptr_t atomic_int; +typedef intptr_t atomic_uint; +typedef intptr_t atomic_long; +typedef intptr_t atomic_ulong; +typedef intptr_t atomic_llong; +typedef intptr_t atomic_ullong; +typedef intptr_t atomic_wchar_t; +typedef intptr_t atomic_int_least8_t; +typedef intptr_t atomic_uint_least8_t; +typedef intptr_t atomic_int_least16_t; +typedef intptr_t atomic_uint_least16_t; +typedef intptr_t atomic_int_least32_t; +typedef intptr_t atomic_uint_least32_t; +typedef intptr_t atomic_int_least64_t; +typedef intptr_t atomic_uint_least64_t; +typedef intptr_t atomic_int_fast8_t; +typedef intptr_t atomic_uint_fast8_t; +typedef intptr_t atomic_int_fast16_t; +typedef intptr_t atomic_uint_fast16_t; +typedef intptr_t atomic_int_fast32_t; +typedef intptr_t atomic_uint_fast32_t; +typedef intptr_t atomic_int_fast64_t; +typedef intptr_t atomic_uint_fast64_t; +typedef intptr_t atomic_intptr_t; +typedef intptr_t atomic_uintptr_t; +typedef intptr_t atomic_size_t; +typedef intptr_t atomic_ptrdiff_t; +typedef intptr_t atomic_intmax_t; +typedef intptr_t atomic_uintmax_t; + +#define atomic_store(object, desired) \ +do { \ + *(object) = (desired); \ + MemoryBarrier(); \ +} while (0) + +#define atomic_store_explicit(object, desired, order) \ + atomic_store(object, desired) + +#define atomic_load(object) \ + (MemoryBarrier(), *(object)) + +#define atomic_load_explicit(object, order) \ + atomic_load(object) + +#define atomic_exchange(object, desired) \ + InterlockedExchangePointer(object, desired); + +#define atomic_exchange_explicit(object, desired, order) \ + atomic_exchange(object, desired) + +static inline int atomic_compare_exchange_strong(intptr_t* object, intptr_t* expected, + intptr_t desired) +{ + intptr_t old = *expected; + *expected = (intptr_t)InterlockedCompareExchangePointer( + (PVOID*)object, (PVOID)desired, (PVOID)old); + return *expected == old; +} + +#define atomic_compare_exchange_strong_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak(object, expected, desired) \ + atomic_compare_exchange_strong(object, expected, desired) + +#define atomic_compare_exchange_weak_explicit(object, expected, desired, success, failure) \ + atomic_compare_exchange_weak(object, expected, desired) + +#ifdef _WIN64 +#define atomic_fetch_add(object, operand) \ + InterlockedExchangeAdd64(object, operand) + +#define atomic_fetch_sub(object, operand) \ + InterlockedExchangeAdd64(object, -(operand)) + +#define atomic_fetch_or(object, operand) \ + InterlockedOr64(object, operand) + +#define atomic_fetch_xor(object, operand) \ + InterlockedXor64(object, operand) + +#define atomic_fetch_and(object, operand) \ + InterlockedAnd64(object, operand) +#else +#define atomic_fetch_add(object, operand) \ + InterlockedExchangeAdd(object, operand) + +#define atomic_fetch_sub(object, operand) \ + InterlockedExchangeAdd(object, -(operand)) + +#define atomic_fetch_or(object, operand) \ + InterlockedOr(object, operand) + +#define atomic_fetch_xor(object, operand) \ + InterlockedXor(object, operand) + +#define atomic_fetch_and(object, operand) \ + InterlockedAnd(object, operand) +#endif /* _WIN64 */ + +#define atomic_fetch_add_explicit(object, operand, order) \ + atomic_fetch_add(object, operand) + +#define atomic_fetch_sub_explicit(object, operand, order) \ + atomic_fetch_sub(object, operand) + +#define atomic_fetch_or_explicit(object, operand, order) \ + atomic_fetch_or(object, operand) + +#define atomic_fetch_xor_explicit(object, operand, order) \ + atomic_fetch_xor(object, operand) + +#define atomic_fetch_and_explicit(object, operand, order) \ + atomic_fetch_and(object, operand) + +#define atomic_flag_test_and_set(object) \ + atomic_exchange(object, 1) + +#define atomic_flag_test_and_set_explicit(object, order) \ + atomic_flag_test_and_set(object) + +#define atomic_flag_clear(object) \ + atomic_store(object, 0) + +#define atomic_flag_clear_explicit(object, order) \ + atomic_flag_clear(object) + +#endif /* COMPAT_ATOMICS_WIN32_STDATOMIC_H */ \ No newline at end of file