Skip to content

Commit 48e4c63

Browse files
authoredJan 16, 2024
Add support for compiling with Microsoft Visual Studio C++ (MSVC) (#246)
1 parent 5f6171c commit 48e4c63

File tree

4 files changed

+124
-17
lines changed

4 files changed

+124
-17
lines changed
 

‎.github/workflows/ci.yml

+28
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,34 @@ jobs:
255255
run: |
256256
make test
257257
258+
windows-msvc:
259+
runs-on: windows-latest
260+
strategy:
261+
fail-fast: false
262+
matrix:
263+
buildType: [Debug, Release]
264+
steps:
265+
- uses: actions/checkout@v3
266+
- name: build
267+
run: |
268+
cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Visual Studio 17 2022"
269+
cmake --build build --target qjs_exe
270+
cmake --build build --target function_source
271+
- name: stats
272+
run: |
273+
build\Debug\qjs.exe -qd
274+
- name: test
275+
run: |
276+
build\Debug\qjs.exe tests\test_bigint.js
277+
build\Debug\qjs.exe tests\test_closure.js
278+
build\Debug\qjs.exe tests\test_language.js
279+
build\Debug\qjs.exe tests\test_builtin.js
280+
build\Debug\qjs.exe tests\test_loop.js
281+
build\Debug\qjs.exe tests\test_std.js
282+
build\Debug\qjs.exe tests\test_worker.js
283+
build\Debug\qjs.exe tests\test_queue_microtask.js
284+
build\Debug\function_source.exe
285+
258286
windows-clang:
259287
runs-on: windows-latest
260288
strategy:

‎.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@
55
build/
66
unicode/
77
test262_*.txt
8+
.idea
9+
cmake-*

‎cutils.h

+90-15
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,56 @@
4646
#include <malloc_np.h>
4747
#endif
4848

49-
#define likely(x) __builtin_expect(!!(x), 1)
50-
#define unlikely(x) __builtin_expect(!!(x), 0)
51-
#define force_inline inline __attribute__((always_inline))
52-
#define no_inline __attribute__((noinline))
53-
#define __maybe_unused __attribute__((unused))
49+
50+
#if defined(_MSC_VER) && !defined(__clang__)
51+
# define likely(x) (x)
52+
# define unlikely(x) (x)
53+
# define force_inline __forceinline
54+
# define no_inline __declspec(noinline)
55+
# define __maybe_unused
56+
# define __attribute__(x)
57+
# define __attribute(x)
58+
# include <intrin.h>
59+
static void *__builtin_frame_address(unsigned int level) {
60+
return (void *)((char*)_AddressOfReturnAddress() - sizeof(int *) - level * sizeof(int *));
61+
}
62+
#else
63+
# define likely(x) __builtin_expect(!!(x), 1)
64+
# define unlikely(x) __builtin_expect(!!(x), 0)
65+
# define force_inline inline __attribute__((always_inline))
66+
# define no_inline __attribute__((noinline))
67+
# define __maybe_unused __attribute__((unused))
68+
#endif
69+
70+
// https://stackoverflow.com/a/6849629
71+
#undef FORMAT_STRING
72+
#if _MSC_VER >= 1400
73+
# include <sal.h>
74+
# if _MSC_VER > 1400
75+
# define FORMAT_STRING(p) _Printf_format_string_ p
76+
# else
77+
# define FORMAT_STRING(p) __format_string p
78+
# endif /* FORMAT_STRING */
79+
#else
80+
# define FORMAT_STRING(p) p
81+
#endif /* _MSC_VER */
82+
83+
// https://stackoverflow.com/a/3312896
84+
// https://stackoverflow.com/a/3312896
85+
#if defined(__GNUC__) || defined(__clang__) // GCC, clang, clang-cl, and so on but not MSVC
86+
# define PACK( __Declaration__ ) __Declaration__ __attribute__((__packed__))
87+
#elif defined(_MSC_VER) && !defined(__clang__) // MSVC
88+
# define PACK( __Declaration__ ) __pragma( pack(push, 1) ) __Declaration__ __pragma( pack(pop))
89+
#endif
90+
91+
#if defined(_MSC_VER) && !defined(__clang__)
92+
#include <math.h>
93+
#define INF INFINITY
94+
#define NEG_INF -INFINITY
95+
#else
96+
#define INF (1.0/0.0)
97+
#define NEG_INF (-1.0/0.0)
98+
#endif
5499

55100
#define xglue(x, y) x ## y
56101
#define glue(x, y) xglue(x, y)
@@ -136,38 +181,68 @@ static inline int64_t min_int64(int64_t a, int64_t b)
136181
/* WARNING: undefined if a = 0 */
137182
static inline int clz32(unsigned int a)
138183
{
184+
#if defined(_MSC_VER) && !defined(__clang__)
185+
unsigned long index;
186+
_BitScanReverse(&index, a);
187+
return 31 - index;
188+
#else
139189
return __builtin_clz(a);
190+
#endif
140191
}
141192

142193
/* WARNING: undefined if a = 0 */
143194
static inline int clz64(uint64_t a)
144195
{
196+
#if defined(_MSC_VER) && !defined(__clang__)
197+
unsigned long index;
198+
_BitScanReverse64(&index, a);
199+
return 63 - index;
200+
#else
145201
return __builtin_clzll(a);
202+
#endif
146203
}
147204

148205
/* WARNING: undefined if a = 0 */
149206
static inline int ctz32(unsigned int a)
150207
{
208+
#if defined(_MSC_VER) && !defined(__clang__)
209+
unsigned long index;
210+
_BitScanForward(&index, a);
211+
return index;
212+
#else
151213
return __builtin_ctz(a);
214+
#endif
152215
}
153216

154217
/* WARNING: undefined if a = 0 */
155218
static inline int ctz64(uint64_t a)
156219
{
220+
#if defined(_MSC_VER) && !defined(__clang__)
221+
unsigned long index;
222+
_BitScanForward64(&index, a);
223+
return index;
224+
#else
157225
return __builtin_ctzll(a);
226+
#endif
158227
}
159228

160-
struct __attribute__((packed)) packed_u64 {
161-
uint64_t v;
162-
};
229+
PACK(
230+
struct packed_u64 {
231+
uint64_t v;
232+
}
233+
);
163234

164-
struct __attribute__((packed)) packed_u32 {
165-
uint32_t v;
166-
};
235+
PACK(
236+
struct packed_u32 {
237+
uint32_t v;
238+
}
239+
);
167240

168-
struct __attribute__((packed)) packed_u16 {
169-
uint16_t v;
170-
};
241+
PACK(
242+
struct packed_u16 {
243+
uint16_t v;
244+
}
245+
);
171246

172247
static inline uint64_t get_u64(const uint8_t *tab)
173248
{
@@ -299,7 +374,7 @@ static inline int dbuf_put_u64(DynBuf *s, uint64_t val)
299374
return dbuf_put(s, (uint8_t *)&val, 8);
300375
}
301376
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
302-
const char *fmt, ...);
377+
FORMAT_STRING(const char *fmt), ...);
303378
void dbuf_free(DynBuf *s);
304379
static inline BOOL dbuf_error(DynBuf *s) {
305380
return s->error;

‎quickjs.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -10153,7 +10153,7 @@ static JSValue js_atof2(JSContext *ctx, const char *str, const char **pp,
1015310153
if (!(flags & ATOD_INT_ONLY) &&
1015410154
atod_type == ATOD_TYPE_FLOAT64 &&
1015510155
strstart(p, "Infinity", &p)) {
10156-
double d = 1.0 / 0.0;
10156+
double d = INF;
1015710157
if (is_neg)
1015810158
d = -d;
1015910159
val = js_float64(d);
@@ -22082,6 +22082,8 @@ static int js_parse_destructuring_element(JSParseState *s, int tok, int is_arg,
2208222082
int opcode, scope, tok1, skip_bits;
2208322083
BOOL has_initializer;
2208422084

22085+
label_lvalue = -1;
22086+
2208522087
if (has_ellipsis < 0) {
2208622088
/* pre-parse destructuration target for spread detection */
2208722089
js_parse_skip_parens_token(s, &skip_bits, FALSE);
@@ -40441,7 +40443,7 @@ static JSValue js_math_min_max(JSContext *ctx, JSValue this_val,
4044140443
uint32_t tag;
4044240444

4044340445
if (unlikely(argc == 0)) {
40444-
return __JS_NewFloat64(is_max ? -1.0 / 0.0 : 1.0 / 0.0);
40446+
return __JS_NewFloat64(is_max ? NEG_INF : INF);
4044540447
}
4044640448

4044740449
tag = JS_VALUE_GET_TAG(argv[0]);

0 commit comments

Comments
 (0)