Add support for compiling with Microsoft Visual Studio C++ (MSVC) (#246)
This commit is contained in:
parent
5f6171c722
commit
48e4c63a0e
4 changed files with 124 additions and 17 deletions
28
.github/workflows/ci.yml
vendored
28
.github/workflows/ci.yml
vendored
|
@ -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
2
.gitignore
vendored
|
@ -5,3 +5,5 @@
|
||||||
build/
|
build/
|
||||||
unicode/
|
unicode/
|
||||||
test262_*.txt
|
test262_*.txt
|
||||||
|
.idea
|
||||||
|
cmake-*
|
89
cutils.h
89
cutils.h
|
@ -46,11 +46,56 @@
|
||||||
#include <malloc_np.h>
|
#include <malloc_np.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#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 likely(x) __builtin_expect(!!(x), 1)
|
||||||
# define unlikely(x) __builtin_expect(!!(x), 0)
|
# define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
# define force_inline inline __attribute__((always_inline))
|
# define force_inline inline __attribute__((always_inline))
|
||||||
# define no_inline __attribute__((noinline))
|
# define no_inline __attribute__((noinline))
|
||||||
# define __maybe_unused __attribute__((unused))
|
# 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(
|
||||||
|
struct packed_u64 {
|
||||||
uint64_t v;
|
uint64_t v;
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
struct __attribute__((packed)) packed_u32 {
|
PACK(
|
||||||
|
struct packed_u32 {
|
||||||
uint32_t v;
|
uint32_t v;
|
||||||
};
|
}
|
||||||
|
);
|
||||||
|
|
||||||
struct __attribute__((packed)) packed_u16 {
|
PACK(
|
||||||
|
struct packed_u16 {
|
||||||
uint16_t v;
|
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;
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
Loading…
Reference in a new issue