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: |
|
||||
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
2
.gitignore
vendored
|
@ -5,3 +5,5 @@
|
|||
build/
|
||||
unicode/
|
||||
test262_*.txt
|
||||
.idea
|
||||
cmake-*
|
105
cutils.h
105
cutils.h
|
@ -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;
|
||||
|
|
|
@ -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]);
|
||||
|
|
Loading…
Reference in a new issue