From 776c326b34c5dd156d2cc3bded7de2286a61428b Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Mon, 15 Jan 2024 17:06:43 +0800 Subject: [PATCH 1/9] feat: Add support for compiling with Microsoft Visual Studio C++ (MSVC) --- .gitignore | 2 + cutils.h | 105 +++++++++++++++++++++++++++++++++++++++++++++-------- quickjs.c | 4 +- 3 files changed, 94 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index a1aae7192..fbeb98f3a 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 2fa6d8d07..4660ce55f 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) +# 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)) +#else +# 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 *)); +} +#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 +#ifdef __GNUC__ +#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) +#endif + +#ifdef _MSC_VER +#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop)) +#endif + +#ifdef _MSC_VER +#include "math.h" +#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) { +#ifndef _MSC_VER return __builtin_clz(a); +#else + unsigned long index; + _BitScanReverse(&index, a); + return 31 - index; +#endif } /* WARNING: undefined if a = 0 */ static inline int clz64(uint64_t a) { +#ifndef _MSC_VER return __builtin_clzll(a); +#else + unsigned long index; + _BitScanReverse64(&index, a); + return 63 - index; +#endif } /* WARNING: undefined if a = 0 */ static inline int ctz32(unsigned int a) { +#ifndef _MSC_VER return __builtin_ctz(a); +#else + unsigned long index; + _BitScanForward(&index, a); + return index; +#endif } /* WARNING: undefined if a = 0 */ static inline int ctz64(uint64_t a) { +#ifndef _MSC_VER return __builtin_ctzll(a); +#else + unsigned long index; + _BitScanForward64(&index, a); + return index; +#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 6540c2ebd..3695fbcb3 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); @@ -40441,7 +40441,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]); From 32894e63f47d255c1746e06dbc101beb2a95418c Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Tue, 16 Jan 2024 01:34:38 +0800 Subject: [PATCH 2/9] fix: Add checks for checking not in clang-cl which defines _MSC_VER as well --- cutils.h | 54 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/cutils.h b/cutils.h index 4660ce55f..4aab0b27b 100644 --- a/cutils.h +++ b/cutils.h @@ -46,7 +46,7 @@ #include #endif -#if !defined(_MSC_VER) +#if !defined(_MSC_VER) && !defined(__clang__) # define likely(x) __builtin_expect(!!(x), 1) # define unlikely(x) __builtin_expect(!!(x), 0) # define force_inline inline __attribute__((always_inline)) @@ -67,28 +67,30 @@ static void *__builtin_frame_address(unsigned int level) { #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 */ +#if defined(_MSC_VER) && !defined(__clang__) +# 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 */ +#endif // https://stackoverflow.com/a/3312896 #ifdef __GNUC__ #define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) #endif -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) #define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop)) #endif -#ifdef _MSC_VER +#if defined(_MSC_VER) && !defined(__clang__) #include "math.h" #define INF INFINITY #define NEG_INF -INFINITY @@ -181,48 +183,48 @@ static inline int64_t min_int64(int64_t a, int64_t b) /* WARNING: undefined if a = 0 */ static inline int clz32(unsigned int a) { -#ifndef _MSC_VER - return __builtin_clz(a); -#else +#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) { -#ifndef _MSC_VER - return __builtin_clzll(a); -#else +#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) { -#ifndef _MSC_VER - return __builtin_ctz(a); -#else +#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) { -#ifndef _MSC_VER - return __builtin_ctzll(a); -#else +#if defined(_MSC_VER) && !defined(__clang__) unsigned long index; _BitScanForward64(&index, a); return index; +#else + return __builtin_ctzll(a); #endif } From 8682c0afb607e32afdcddd74d9d2253d0f5e3d25 Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Tue, 16 Jan 2024 01:38:19 +0800 Subject: [PATCH 3/9] ci: Add windows-msvc target checking --- .github/workflows/ci.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2852764a3..ed8ec56ac 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: From 39c3bb3d6d415e0ff4584243bad13733cdec2647 Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Tue, 16 Jan 2024 02:10:05 +0800 Subject: [PATCH 4/9] fix: clang-cl build errors --- cutils.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/cutils.h b/cutils.h index 4aab0b27b..f69aa9fe7 100644 --- a/cutils.h +++ b/cutils.h @@ -46,13 +46,8 @@ #include #endif -#if !defined(_MSC_VER) && !defined(__clang__) -# 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)) -#else + +#if defined(_MSC_VER) && !defined(__clang__) # define likely(x) (x) # define unlikely(x) (x) # define force_inline __forceinline @@ -64,10 +59,16 @@ 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 -#if defined(_MSC_VER) && !defined(__clang__) +#if defined(_MSC_VER) // This should be applied even we are using clang-cl # undef FORMAT_STRING # if _MSC_VER >= 1400 # include @@ -82,7 +83,7 @@ static void *__builtin_frame_address(unsigned int level) { #endif // https://stackoverflow.com/a/3312896 -#ifdef __GNUC__ +#if defined(__GNUC__) || defined(__clang__) #define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) #endif From 01b6d68c7177567e063abde2110cddfc1c8917a7 Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Tue, 16 Jan 2024 02:57:07 +0800 Subject: [PATCH 5/9] revert: regret on FORMAT_STRING macro definition change --- cutils.h | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/cutils.h b/cutils.h index f69aa9fe7..200c97952 100644 --- a/cutils.h +++ b/cutils.h @@ -68,19 +68,17 @@ static void *__builtin_frame_address(unsigned int level) { #endif // https://stackoverflow.com/a/6849629 -#if defined(_MSC_VER) // This should be applied even we are using clang-cl -# 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 */ -#endif +#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 #if defined(__GNUC__) || defined(__clang__) From eb56e5cfd45b2c706d1ee93213a93df9185dd678 Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Tue, 16 Jan 2024 13:02:03 +0800 Subject: [PATCH 6/9] fix: label_lvalue sometimes read as uninitialized value --- quickjs.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quickjs.c b/quickjs.c index 3695fbcb3..4d60a6815 100644 --- a/quickjs.c +++ b/quickjs.c @@ -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); From 3322630754cf7205986d36fa2213f1e8d0dafc4a Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 16 Jan 2024 16:40:00 +0800 Subject: [PATCH 7/9] Update cutils.h "math.h" -> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Saúl Ibarra Corretgé --- cutils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cutils.h b/cutils.h index 200c97952..237a19ddb 100644 --- a/cutils.h +++ b/cutils.h @@ -90,7 +90,7 @@ static void *__builtin_frame_address(unsigned int level) { #endif #if defined(_MSC_VER) && !defined(__clang__) -#include "math.h" +#include "" #define INF INFINITY #define NEG_INF -INFINITY #else From b3bd339d1a71bf6c3570a34864a8aee5b9fd84a1 Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Tue, 16 Jan 2024 16:45:36 +0800 Subject: [PATCH 8/9] combine two cases --- cutils.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/cutils.h b/cutils.h index 237a19ddb..dde9d377d 100644 --- a/cutils.h +++ b/cutils.h @@ -81,12 +81,11 @@ static void *__builtin_frame_address(unsigned int level) { #endif /* _MSC_VER */ // https://stackoverflow.com/a/3312896 -#if defined(__GNUC__) || defined(__clang__) -#define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__)) -#endif - -#if defined(_MSC_VER) && !defined(__clang__) -#define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop)) +// 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__) From d6f71542a9c85cef5b2e07506878c9a7b87c650c Mon Sep 17 00:00:00 2001 From: CGQAQ Date: Tue, 16 Jan 2024 17:19:34 +0800 Subject: [PATCH 9/9] oops, github apply change it not quite right --- cutils.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cutils.h b/cutils.h index dde9d377d..2b53dfb66 100644 --- a/cutils.h +++ b/cutils.h @@ -89,7 +89,7 @@ static void *__builtin_frame_address(unsigned int level) { #endif #if defined(_MSC_VER) && !defined(__clang__) -#include "" +#include #define INF INFINITY #define NEG_INF -INFINITY #else