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: |
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:

2
.gitignore vendored
View file

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

105
cutils.h
View file

@ -46,11 +46,56 @@
#include <malloc_np.h>
#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 <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 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;

View file

@ -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]);