Add support for compiling with Microsoft Visual Studio C++ (MSVC) (#246)

This commit is contained in:
Jason 2024-01-16 19:42:05 +08:00 committed by GitHub
parent 5f6171c722
commit 48e4c63a0e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 124 additions and 17 deletions

View file

@ -255,6 +255,34 @@ jobs:
run: | run: |
make test 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: windows-clang:
runs-on: windows-latest runs-on: windows-latest
strategy: strategy:

2
.gitignore vendored
View file

@ -5,3 +5,5 @@
build/ build/
unicode/ unicode/
test262_*.txt test262_*.txt
.idea
cmake-*

105
cutils.h
View file

@ -46,11 +46,56 @@
#include <malloc_np.h> #include <malloc_np.h>
#endif #endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0) #if defined(_MSC_VER) && !defined(__clang__)
#define force_inline inline __attribute__((always_inline)) # define likely(x) (x)
#define no_inline __attribute__((noinline)) # define unlikely(x) (x)
#define __maybe_unused __attribute__((unused)) # define force_inline __forceinline
# define no_inline __declspec(noinline)
# define __maybe_unused
# define __attribute__(x)
# define __attribute(x)
# include <intrin.h>
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 <sal.h>
# 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 <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 xglue(x, y) x ## y
#define glue(x, y) xglue(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 */ /* WARNING: undefined if a = 0 */
static inline int clz32(unsigned int a) 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); return __builtin_clz(a);
#endif
} }
/* WARNING: undefined if a = 0 */ /* WARNING: undefined if a = 0 */
static inline int clz64(uint64_t a) 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); return __builtin_clzll(a);
#endif
} }
/* WARNING: undefined if a = 0 */ /* WARNING: undefined if a = 0 */
static inline int ctz32(unsigned int a) 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); return __builtin_ctz(a);
#endif
} }
/* WARNING: undefined if a = 0 */ /* WARNING: undefined if a = 0 */
static inline int ctz64(uint64_t a) 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); return __builtin_ctzll(a);
#endif
} }
struct __attribute__((packed)) packed_u64 { PACK(
uint64_t v; struct packed_u64 {
}; uint64_t v;
}
);
struct __attribute__((packed)) packed_u32 { PACK(
uint32_t v; struct packed_u32 {
}; uint32_t v;
}
);
struct __attribute__((packed)) packed_u16 { PACK(
uint16_t v; struct packed_u16 {
}; uint16_t v;
}
);
static inline uint64_t get_u64(const uint8_t *tab) 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); return dbuf_put(s, (uint8_t *)&val, 8);
} }
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s, int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
const char *fmt, ...); FORMAT_STRING(const char *fmt), ...);
void dbuf_free(DynBuf *s); void dbuf_free(DynBuf *s);
static inline BOOL dbuf_error(DynBuf *s) { static inline BOOL dbuf_error(DynBuf *s) {
return s->error; return s->error;

View file

@ -10153,7 +10153,7 @@ static JSValue js_atof2(JSContext *ctx, const char *str, const char **pp,
if (!(flags & ATOD_INT_ONLY) && if (!(flags & ATOD_INT_ONLY) &&
atod_type == ATOD_TYPE_FLOAT64 && atod_type == ATOD_TYPE_FLOAT64 &&
strstart(p, "Infinity", &p)) { strstart(p, "Infinity", &p)) {
double d = 1.0 / 0.0; double d = INF;
if (is_neg) if (is_neg)
d = -d; d = -d;
val = js_float64(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; int opcode, scope, tok1, skip_bits;
BOOL has_initializer; BOOL has_initializer;
label_lvalue = -1;
if (has_ellipsis < 0) { if (has_ellipsis < 0) {
/* pre-parse destructuration target for spread detection */ /* pre-parse destructuration target for spread detection */
js_parse_skip_parens_token(s, &skip_bits, FALSE); 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; uint32_t tag;
if (unlikely(argc == 0)) { 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]); tag = JS_VALUE_GET_TAG(argv[0]);