diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2852764..ed8ec56 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -255,6 +255,34 @@ jobs: run: | make test + windows-msvc: + runs-on: windows-latest + strategy: + fail-fast: false + matrix: + buildType: [Debug, Release] + steps: + - uses: actions/checkout@v3 + - name: build + run: | + cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Visual Studio 17 2022" + cmake --build build --target qjs_exe + cmake --build build --target function_source + - name: stats + run: | + build\Debug\qjs.exe -qd + - name: test + run: | + build\Debug\qjs.exe tests\test_bigint.js + build\Debug\qjs.exe tests\test_closure.js + build\Debug\qjs.exe tests\test_language.js + build\Debug\qjs.exe tests\test_builtin.js + build\Debug\qjs.exe tests\test_loop.js + build\Debug\qjs.exe tests\test_std.js + build\Debug\qjs.exe tests\test_worker.js + build\Debug\qjs.exe tests\test_queue_microtask.js + build\Debug\function_source.exe + windows-clang: runs-on: windows-latest strategy: diff --git a/.gitignore b/.gitignore index a1aae71..fbeb98f 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ build/ unicode/ test262_*.txt +.idea +cmake-* \ No newline at end of file diff --git a/cutils.h b/cutils.h index 2fa6d8d..2b53dfb 100644 --- a/cutils.h +++ b/cutils.h @@ -46,11 +46,56 @@ #include #endif -#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(_MSC_VER) && !defined(__clang__) +# define likely(x) (x) +# define unlikely(x) (x) +# define force_inline __forceinline +# define no_inline __declspec(noinline) +# define __maybe_unused +# define __attribute__(x) +# define __attribute(x) +# include +static void *__builtin_frame_address(unsigned int level) { + return (void *)((char*)_AddressOfReturnAddress() - sizeof(int *) - level * sizeof(int *)); +} +#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)) +#endif + +// https://stackoverflow.com/a/6849629 +#undef FORMAT_STRING +#if _MSC_VER >= 1400 +# include +# if _MSC_VER > 1400 +# define FORMAT_STRING(p) _Printf_format_string_ p +# else +# define FORMAT_STRING(p) __format_string p +# endif /* FORMAT_STRING */ +#else +# define FORMAT_STRING(p) p +#endif /* _MSC_VER */ + +// https://stackoverflow.com/a/3312896 +// https://stackoverflow.com/a/3312896 +#if defined(__GNUC__) || defined(__clang__) // GCC, clang, clang-cl, and so on but not MSVC +# define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) +#elif defined(_MSC_VER) && !defined(__clang__) // MSVC +# define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop)) +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +#include +#define INF INFINITY +#define NEG_INF -INFINITY +#else +#define INF (1.0/0.0) +#define NEG_INF (-1.0/0.0) +#endif #define xglue(x, y) x ## y #define glue(x, y) xglue(x, y) @@ -136,38 +181,68 @@ static inline int64_t min_int64(int64_t a, int64_t b) /* WARNING: undefined if a = 0 */ static inline int clz32(unsigned int a) { +#if defined(_MSC_VER) && !defined(__clang__) + unsigned long index; + _BitScanReverse(&index, a); + return 31 - index; +#else return __builtin_clz(a); +#endif } /* WARNING: undefined if a = 0 */ static inline int clz64(uint64_t a) { +#if defined(_MSC_VER) && !defined(__clang__) + unsigned long index; + _BitScanReverse64(&index, a); + return 63 - index; +#else return __builtin_clzll(a); +#endif } /* WARNING: undefined if a = 0 */ static inline int ctz32(unsigned int a) { +#if defined(_MSC_VER) && !defined(__clang__) + unsigned long index; + _BitScanForward(&index, a); + return index; +#else return __builtin_ctz(a); +#endif } /* WARNING: undefined if a = 0 */ static inline int ctz64(uint64_t a) { +#if defined(_MSC_VER) && !defined(__clang__) + unsigned long index; + _BitScanForward64(&index, a); + return index; +#else return __builtin_ctzll(a); +#endif } -struct __attribute__((packed)) packed_u64 { - uint64_t v; -}; +PACK( + struct packed_u64 { + uint64_t v; + } +); -struct __attribute__((packed)) packed_u32 { - uint32_t v; -}; +PACK( + struct packed_u32 { + uint32_t v; + } +); -struct __attribute__((packed)) packed_u16 { - uint16_t v; -}; +PACK( + struct packed_u16 { + uint16_t v; + } +); static inline uint64_t get_u64(const uint8_t *tab) { @@ -299,7 +374,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, - const char *fmt, ...); + FORMAT_STRING(const char *fmt), ...); void dbuf_free(DynBuf *s); static inline BOOL dbuf_error(DynBuf *s) { return s->error; diff --git a/quickjs.c b/quickjs.c index 6540c2e..4d60a68 100644 --- a/quickjs.c +++ b/quickjs.c @@ -10153,7 +10153,7 @@ static JSValue js_atof2(JSContext *ctx, const char *str, const char **pp, if (!(flags & ATOD_INT_ONLY) && atod_type == ATOD_TYPE_FLOAT64 && strstart(p, "Infinity", &p)) { - double d = 1.0 / 0.0; + double d = INF; if (is_neg) d = -d; val = js_float64(d); @@ -22082,6 +22082,8 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg, int opcode, scope, tok1, skip_bits; BOOL has_initializer; + label_lvalue = -1; + if (has_ellipsis < 0) { /* pre-parse destructuration target for spread detection */ js_parse_skip_parens_token(s, &skip_bits, FALSE); @@ -40441,7 +40443,7 @@ static JSValue js_math_min_max(JSContext *ctx, JSValue this_val, uint32_t tag; if (unlikely(argc == 0)) { - return __JS_NewFloat64(is_max ? -1.0 / 0.0 : 1.0 / 0.0); + return __JS_NewFloat64(is_max ? NEG_INF : INF); } tag = JS_VALUE_GET_TAG(argv[0]);