diff --git a/cutils.c b/cutils.c index c0aacef..c861f74 100644 --- a/cutils.c +++ b/cutils.c @@ -29,6 +29,32 @@ #include "cutils.h" +#ifdef _MSC_VER +#include +#include + +// From: https://stackoverflow.com/a/26085827 +int gettimeofday(struct timeval *tvp, void *tzp) +{ + (void)tzp; + static const uint64_t EPOCH = ((uint64_t)116444736000000000ULL); + + SYSTEMTIME system_time; + FILETIME file_time; + uint64_t time; + + GetSystemTime(&system_time); + SystemTimeToFileTime(&system_time, &file_time); + time = ((uint64_t)file_time.dwLowDateTime); + time += ((uint64_t)file_time.dwHighDateTime) << 32; + + tvp->tv_sec = (long)((time - EPOCH) / 10000000L); + tvp->tv_usec = (long)(system_time.wMilliseconds * 1000); + + return 0; +} +#endif + void pstrcpy(char *buf, int buf_size, const char *str) { int c; diff --git a/cutils.h b/cutils.h index f079e5c..612220c 100644 --- a/cutils.h +++ b/cutils.h @@ -28,12 +28,30 @@ #include #include #include +#ifdef _MSC_VER +#include +#include +int gettimeofday(struct timeval *tvp, void *tzp); +#else +#include +#endif +#ifndef __has_attribute +#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) +typedef size_t ssize_t; +#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 #define xglue(x, y) x ## y #define glue(x, y) xglue(x, y) @@ -128,27 +146,88 @@ static inline int64_t min_int64(int64_t a, int64_t b) /* WARNING: undefined if a = 0 */ static inline int clz32(unsigned int a) { +#ifdef _MSC_VER + unsigned long idx; + _BitScanReverse(&idx, a); + return 31 ^ idx; +#else return __builtin_clz(a); +#endif } /* WARNING: undefined if a = 0 */ static inline int clz64(uint64_t a) { +#ifdef _MSC_VER + unsigned long idx; + // BitScanReverse scans from MSB to LSB for first set bit. + // Returns 0 if no set bit is found. +# if INTPTR_MAX >= INT64_MAX // 64-bit + _BitScanReverse64(&idx, a); +# else + // Scan the high 32 bits. + if (_BitScanReverse(&idx, (uint32_t)(a >> 32))) + return 63 ^ (idx + 32); + // Scan the low 32 bits. + _BitScanReverse(&idx, (uint32_t)(a)); +# endif + return 63 ^ idx; +#else return __builtin_clzll(a); +#endif } /* WARNING: undefined if a = 0 */ static inline int ctz32(unsigned int a) { +#ifdef _MSC_VER + unsigned long idx; + _BitScanForward(&idx, a); + return idx; +#else return __builtin_ctz(a); +#endif } /* WARNING: undefined if a = 0 */ static inline int ctz64(uint64_t a) { +#ifdef _MSC_VER + unsigned long idx; + // Search from LSB to MSB for first set bit. + // Returns zero if no set bit is found. +# if INTPTR_MAX >= INT64_MAX // 64-bit + _BitScanForward64(&idx, a); + return idx; +# else + // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls. + // Scan the Low Word. + if (_BitScanForward(&idx, (uint32_t)(a))) + return idx; + // Scan the High Word. + _BitScanForward(&idx, (uint32_t)(a >> 32)); + return idx + 32; +# endif +#else return __builtin_ctzll(a); +#endif } +#ifdef _MSC_VER +#pragma pack(push, 1) +struct packed_u64 { + uint64_t v; +}; + +struct packed_u32 { + uint32_t v; +}; + +struct packed_u16 { + uint16_t v; +}; +#pragma pack(pop) +#else struct __attribute__((packed)) packed_u64 { uint64_t v; }; @@ -160,6 +239,7 @@ struct __attribute__((packed)) packed_u32 { struct __attribute__((packed)) packed_u16 { uint16_t v; }; +#endif static inline uint64_t get_u64(const uint8_t *tab) { diff --git a/libbf.h b/libbf.h index a1436ab..65e111c 100644 --- a/libbf.h +++ b/libbf.h @@ -27,7 +27,7 @@ #include #include -#if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX) +#if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX) && !defined(_MSC_VER) #define LIMB_LOG2_BITS 6 #else #define LIMB_LOG2_BITS 5 diff --git a/quickjs.c b/quickjs.c index e8fdd8a..828e70f 100644 --- a/quickjs.c +++ b/quickjs.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include @@ -48,7 +47,7 @@ #define OPTIMIZE 1 #define SHORT_OPCODES 1 -#if defined(EMSCRIPTEN) +#if defined(EMSCRIPTEN) || defined(_MSC_VER) #define DIRECT_DISPATCH 0 #else #define DIRECT_DISPATCH 1 @@ -67,11 +66,11 @@ /* define to include Atomics.* operations which depend on the OS threads */ -#if !defined(EMSCRIPTEN) +#if !defined(EMSCRIPTEN) && !defined(_MSC_VER) #define CONFIG_ATOMICS #endif -#if !defined(EMSCRIPTEN) +#if !defined(EMSCRIPTEN) && !defined(_MSC_VER) /* enable stack limitation */ #define CONFIG_STACK_CHECK #endif @@ -7302,7 +7301,7 @@ static int JS_DefinePrivateField(JSContext *ctx, JSValueConst obj, JS_ThrowTypeErrorNotASymbol(ctx); goto fail; } - prop = js_symbol_to_atom(ctx, (JSValue)name); + prop = js_symbol_to_atom(ctx, *(JSValue*)&name); p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (prs) { @@ -7333,7 +7332,7 @@ static JSValue JS_GetPrivateField(JSContext *ctx, JSValueConst obj, /* safety check */ if (unlikely(JS_VALUE_GET_TAG(name) != JS_TAG_SYMBOL)) return JS_ThrowTypeErrorNotASymbol(ctx); - prop = js_symbol_to_atom(ctx, (JSValue)name); + prop = js_symbol_to_atom(ctx, *(JSValue*)&name); p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (!prs) { @@ -7360,7 +7359,7 @@ static int JS_SetPrivateField(JSContext *ctx, JSValueConst obj, JS_ThrowTypeErrorNotASymbol(ctx); goto fail; } - prop = js_symbol_to_atom(ctx, (JSValue)name); + prop = js_symbol_to_atom(ctx, *(JSValue*)&name); p = JS_VALUE_GET_OBJ(obj); prs = find_own_property(&pr, p, prop); if (!prs) { @@ -7459,7 +7458,7 @@ static int JS_CheckBrand(JSContext *ctx, JSValueConst obj, JSValueConst func) return -1; } p = JS_VALUE_GET_OBJ(obj); - prs = find_own_property(&pr, p, js_symbol_to_atom(ctx, (JSValue)brand)); + prs = find_own_property(&pr, p, js_symbol_to_atom(ctx, *(JSValue*)&brand)); return (prs != NULL); } @@ -9079,7 +9078,7 @@ int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj, return -1; } /* this code relies on the fact that Uint32 are never allocated */ - val = (JSValueConst)JS_NewUint32(ctx, array_length); + val = JS_NewUint32(ctx, array_length); /* prs may have been modified */ prs = find_own_property(&pr, p, prop); assert(prs != NULL); @@ -15980,7 +15979,7 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, #else sf->js_mode = 0; #endif - sf->cur_func = (JSValue)func_obj; + sf->cur_func = *(JSValue*)&func_obj; sf->arg_count = argc; arg_buf = argv; @@ -15993,7 +15992,7 @@ static JSValue js_call_c_function(JSContext *ctx, JSValueConst func_obj, arg_buf[i] = JS_UNDEFINED; sf->arg_count = arg_count; } - sf->arg_buf = (JSValue*)arg_buf; + sf->arg_buf = (JSValueConst*)arg_buf; func = p->u.cfunc.c_function; switch(cproto) { @@ -16225,7 +16224,7 @@ static JSValue JS_CallInternal(JSContext *caller_ctx, JSValueConst func_obj, sf->js_mode = b->js_mode; arg_buf = argv; sf->arg_count = argc; - sf->cur_func = (JSValue)func_obj; + sf->cur_func = *(JSValue*)&func_obj; init_list_head(&sf->var_ref_list); var_refs = p->u.func.var_refs; @@ -40392,8 +40391,8 @@ static int64_t JS_FlattenIntoArray(JSContext *ctx, JSValueConst target, if (!JS_IsUndefined(mapperFunction)) { JSValueConst args[3] = { element, JS_NewInt64(ctx, sourceIndex), source }; element = JS_Call(ctx, mapperFunction, thisArg, 3, args); - JS_FreeValue(ctx, (JSValue)args[0]); - JS_FreeValue(ctx, (JSValue)args[1]); + JS_FreeValue(ctx, *(JSValue*)&args[0]); + JS_FreeValue(ctx, *(JSValue*)&args[1]); if (JS_IsException(element)) return -1; } @@ -41959,7 +41958,7 @@ static JSValue js_string_match(JSContext *ctx, JSValueConst this_val, str = JS_NewString(ctx, "g"); if (JS_IsException(str)) goto fail; - args[args_len++] = (JSValueConst)str; + args[args_len++] = *(JSValueConst*)&str; } rx = JS_CallConstructor(ctx, ctx->regexp_ctor, args_len, args); JS_FreeValue(ctx, str); @@ -43264,6 +43263,12 @@ static JSValue js_math_random(JSContext *ctx, JSValueConst this_val, return __JS_NewFloat64(ctx, u.d - 1.0); } +#ifdef _MSC_VER +#pragma function (ceil) +#pragma function (floor) +#pragma function (log2) +#endif + static const JSCFunctionListEntry js_math_funcs[] = { JS_CFUNC_MAGIC_DEF("min", 2, js_math_min_max, 0 ), JS_CFUNC_MAGIC_DEF("max", 2, js_math_min_max, 1 ), @@ -47158,7 +47163,7 @@ static JSMapRecord *map_add_record(JSContext *ctx, JSMapState *s, } else { JS_DupValue(ctx, key); } - mr->key = (JSValue)key; + mr->key = *(JSValue*)&key; h = map_hash_key(ctx, key) & (s->hash_size - 1); list_add_tail(&mr->hash_link, &s->hash_table[h]); list_add_tail(&mr->link, &s->records); @@ -47380,7 +47385,7 @@ static JSValue js_map_forEach(JSContext *ctx, JSValueConst this_val, args[0] = args[1]; else args[0] = JS_DupValue(ctx, mr->value); - args[2] = (JSValue)this_val; + args[2] = *(JSValue*)&this_val; ret = JS_Call(ctx, func, this_arg, 3, (JSValueConst *)args); JS_FreeValue(ctx, args[0]); if (!magic) @@ -48482,7 +48487,7 @@ static JSValue js_promise_all(JSContext *ctx, JSValueConst this_val, goto fail_reject; } resolve_element_data[0] = JS_NewBool(ctx, FALSE); - resolve_element_data[1] = (JSValueConst)JS_NewInt32(ctx, index); + resolve_element_data[1] = JS_NewInt32(ctx, index); resolve_element_data[2] = values; resolve_element_data[3] = resolving_funcs[is_promise_any]; resolve_element_data[4] = resolve_element_env; @@ -48841,7 +48846,7 @@ static JSValue js_async_from_sync_iterator_unwrap_func_create(JSContext *ctx, { JSValueConst func_data[1]; - func_data[0] = (JSValueConst)JS_NewBool(ctx, done); + func_data[0] = JS_NewBool(ctx, done); return JS_NewCFunctionData(ctx, js_async_from_sync_iterator_unwrap, 1, 0, 1, func_data); } @@ -54601,8 +54606,8 @@ static int js_TA_cmp_generic(const void *a, const void *b, void *opaque) { psc->exception = 2; } done: - JS_FreeValue(ctx, (JSValue)argv[0]); - JS_FreeValue(ctx, (JSValue)argv[1]); + JS_FreeValue(ctx, *(JSValue*)&argv[0]); + JS_FreeValue(ctx, *(JSValue*)&argv[1]); } return cmp; } diff --git a/quickjs.h b/quickjs.h index 7199936..30fdb2f 100644 --- a/quickjs.h +++ b/quickjs.h @@ -670,7 +670,7 @@ static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v) JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); p->ref_count++; } - return (JSValue)v; + return *(JSValue*)&v; } static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v) @@ -679,7 +679,7 @@ static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v) JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v); p->ref_count++; } - return (JSValue)v; + return *(JSValue*)&v; } int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */