Add Windows and Switch build support

This commit is contained in:
2026-06-08 22:33:06 +08:00
parent 7a925c3736
commit 5525343656
11 changed files with 610 additions and 70 deletions
+63
View File
@@ -27,15 +27,32 @@
#include <stdlib.h>
#include <inttypes.h>
#if defined(_MSC_VER)
#include <intrin.h>
#endif
/* set if CPU is big endian */
#undef WORDS_BIGENDIAN
#if defined(_MSC_VER)
#define likely(x) (x)
#define unlikely(x) (x)
#define force_inline __forceinline
#define no_inline __declspec(noinline)
#define __maybe_unused
#ifndef __attribute__
#define __attribute__(x)
#endif
#ifndef __attribute
#define __attribute(x)
#endif
#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)
@@ -114,27 +131,69 @@ 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)
unsigned long r;
_BitScanReverse(&r, a);
return 31 - (int)r;
#else
return __builtin_clz(a);
#endif
}
/* WARNING: undefined if a = 0 */
static inline int clz64(uint64_t a)
{
#if defined(_MSC_VER)
#if defined(_M_X64) || defined(_M_ARM64)
unsigned long r;
_BitScanReverse64(&r, a);
return 63 - (int)r;
#else
uint32_t h = (uint32_t)(a >> 32);
if (h != 0)
return clz32(h);
return 32 + clz32((uint32_t)a);
#endif
#else
return __builtin_clzll(a);
#endif
}
/* WARNING: undefined if a = 0 */
static inline int ctz32(unsigned int a)
{
#if defined(_MSC_VER)
unsigned long r;
_BitScanForward(&r, a);
return (int)r;
#else
return __builtin_ctz(a);
#endif
}
/* WARNING: undefined if a = 0 */
static inline int ctz64(uint64_t a)
{
#if defined(_MSC_VER)
#if defined(_M_X64) || defined(_M_ARM64)
unsigned long r;
_BitScanForward64(&r, a);
return (int)r;
#else
uint32_t l = (uint32_t)a;
if (l != 0)
return ctz32(l);
return 32 + ctz32((uint32_t)(a >> 32));
#endif
#else
return __builtin_ctzll(a);
#endif
}
#if defined(_MSC_VER)
#pragma pack(push, 1)
#endif
struct __attribute__((packed)) packed_u64 {
uint64_t v;
};
@@ -147,6 +206,10 @@ struct __attribute__((packed)) packed_u16 {
uint16_t v;
};
#if defined(_MSC_VER)
#pragma pack(pop)
#endif
static inline uint64_t get_u64(const uint8_t *tab)
{
return ((const struct packed_u64 *)tab)->v;
+117 -50
View File
@@ -28,7 +28,11 @@
#include <inttypes.h>
#include <string.h>
#include <assert.h>
#if defined(_WIN32)
#include <windows.h>
#else
#include <sys/time.h>
#endif
#include <time.h>
#include <fenv.h>
#include <math.h>
@@ -50,7 +54,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
@@ -69,11 +73,11 @@
/* define to include Atomics.* operations which depend on the OS
threads */
#if !defined(EMSCRIPTEN)
#if !defined(EMSCRIPTEN) && !defined(_WIN32)
#define CONFIG_ATOMICS
#endif
#if !defined(EMSCRIPTEN)
#if !defined(EMSCRIPTEN) && !defined(_WIN32)
/* enable stack limitation */
#define CONFIG_STACK_CHECK
#endif
@@ -115,6 +119,43 @@
#include <errno.h>
#endif
#if defined(_WIN32)
static int gettimeofday(struct timeval *tv, void *tz)
{
FILETIME ft;
uint64_t t;
(void)tz;
GetSystemTimeAsFileTime(&ft);
t = ((uint64_t)ft.dwHighDateTime << 32) | ft.dwLowDateTime;
t -= UINT64_C(116444736000000000);
tv->tv_sec = (long)(t / 10000000);
tv->tv_usec = (long)((t % 10000000) / 10);
return 0;
}
#ifndef ssize_t
typedef intptr_t ssize_t;
#endif
static struct tm *localtime_r(const time_t *timep, struct tm *result)
{
return localtime_s(result, timep) == 0 ? result : NULL;
}
static double js_get_infinity(int sign)
{
volatile double zero = 0.0;
double inf = 1.0 / zero;
return sign < 0 ? -inf : inf;
}
#else
static double js_get_infinity(int sign)
{
return sign < 0 ? -1.0 / 0.0 : 1.0 / 0.0;
}
#endif
enum {
/* classid tag */ /* union usage | properties */
JS_CLASS_OBJECT = 1, /* must be first */
@@ -7249,7 +7290,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, name);
p = JS_VALUE_GET_OBJ(obj);
prs = find_own_property(&pr, p, prop);
if (prs) {
@@ -7280,7 +7321,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, name);
p = JS_VALUE_GET_OBJ(obj);
prs = find_own_property(&pr, p, prop);
if (!prs) {
@@ -7307,7 +7348,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, name);
p = JS_VALUE_GET_OBJ(obj);
prs = find_own_property(&pr, p, prop);
if (!prs) {
@@ -7397,7 +7438,7 @@ static int JS_CheckBrand(JSContext *ctx, JSValueConst obj, JSValueConst func)
if (unlikely(JS_VALUE_GET_TAG(obj) != JS_TAG_OBJECT))
goto not_obj;
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, brand));
if (!prs) {
JS_ThrowTypeError(ctx, "invalid brand on object");
return -1;
@@ -9051,7 +9092,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);
@@ -10246,7 +10287,7 @@ static JSValue js_atof(JSContext *ctx, const char *str, const char **pp,
} else
#endif
{
double d = 1.0 / 0.0;
double d = js_get_infinity(1);
if (is_neg)
d = -d;
val = JS_NewFloat64(ctx, d);
@@ -16052,7 +16093,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 = func_obj;
sf->arg_count = argc;
arg_buf = argv;
@@ -16296,7 +16337,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 = func_obj;
init_list_head(&sf->var_ref_list);
var_refs = p->u.func.var_refs;
@@ -39292,8 +39333,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, args[0]);
JS_FreeValue(ctx, args[1]);
if (JS_IsException(element))
return -1;
}
@@ -39839,9 +39880,9 @@ static const JSCFunctionListEntry js_number_funcs[] = {
JS_CFUNC_DEF("isSafeInteger", 1, js_number_isSafeInteger ),
JS_PROP_DOUBLE_DEF("MAX_VALUE", 1.7976931348623157e+308, 0 ),
JS_PROP_DOUBLE_DEF("MIN_VALUE", 5e-324, 0 ),
JS_PROP_DOUBLE_DEF("NaN", NAN, 0 ),
JS_PROP_DOUBLE_DEF("NEGATIVE_INFINITY", -INFINITY, 0 ),
JS_PROP_DOUBLE_DEF("POSITIVE_INFINITY", INFINITY, 0 ),
JS_PROP_DOUBLE_DEF("NaN", JS_FLOAT64_NAN, 0 ),
JS_PROP_DOUBLE_DEF("NEGATIVE_INFINITY", -1.0 / 0.0, 0 ),
JS_PROP_DOUBLE_DEF("POSITIVE_INFINITY", 1.0 / 0.0, 0 ),
JS_PROP_DOUBLE_DEF("EPSILON", 2.220446049250313e-16, 0 ), /* ES6 */
JS_PROP_DOUBLE_DEF("MAX_SAFE_INTEGER", 9007199254740991.0, 0 ), /* ES6 */
JS_PROP_DOUBLE_DEF("MIN_SAFE_INTEGER", -9007199254740991.0, 0 ), /* ES6 */
@@ -40710,7 +40751,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++] = str;
}
rx = JS_CallConstructor(ctx, ctx->regexp_ctor, args_len, args);
JS_FreeValue(ctx, str);
@@ -41759,6 +41800,32 @@ static double js_fmax(double a, double b)
}
}
static double js_math_fabs_wrap(double x) { return fabs(x); }
static double js_math_floor_wrap(double x) { return floor(x); }
static double js_math_ceil_wrap(double x) { return ceil(x); }
static double js_math_sqrt_wrap(double x) { return sqrt(x); }
static double js_math_acos_wrap(double x) { return acos(x); }
static double js_math_asin_wrap(double x) { return asin(x); }
static double js_math_atan_wrap(double x) { return atan(x); }
static double js_math_atan2_wrap(double x, double y) { return atan2(x, y); }
static double js_math_cos_wrap(double x) { return cos(x); }
static double js_math_exp_wrap(double x) { return exp(x); }
static double js_math_log_wrap(double x) { return log(x); }
static double js_math_sin_wrap(double x) { return sin(x); }
static double js_math_tan_wrap(double x) { return tan(x); }
static double js_math_trunc_wrap(double x) { return trunc(x); }
static double js_math_cosh_wrap(double x) { return cosh(x); }
static double js_math_sinh_wrap(double x) { return sinh(x); }
static double js_math_tanh_wrap(double x) { return tanh(x); }
static double js_math_acosh_wrap(double x) { return acosh(x); }
static double js_math_asinh_wrap(double x) { return asinh(x); }
static double js_math_atanh_wrap(double x) { return atanh(x); }
static double js_math_expm1_wrap(double x) { return expm1(x); }
static double js_math_log1p_wrap(double x) { return log1p(x); }
static double js_math_log2_wrap(double x) { return log2(x); }
static double js_math_log10_wrap(double x) { return log10(x); }
static double js_math_cbrt_wrap(double x) { return cbrt(x); }
static JSValue js_math_min_max(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv, int magic)
{
@@ -41768,7 +41835,7 @@ static JSValue js_math_min_max(JSContext *ctx, JSValueConst this_val,
uint32_t tag;
if (unlikely(argc == 0)) {
return __JS_NewFloat64(ctx, is_max ? -1.0 / 0.0 : 1.0 / 0.0);
return __JS_NewFloat64(ctx, js_get_infinity(is_max ? -1 : 1));
}
tag = JS_VALUE_GET_TAG(argv[0]);
@@ -41943,36 +42010,36 @@ static JSValue js_math_random(JSContext *ctx, JSValueConst this_val,
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 ),
JS_CFUNC_SPECIAL_DEF("abs", 1, f_f, fabs ),
JS_CFUNC_SPECIAL_DEF("floor", 1, f_f, floor ),
JS_CFUNC_SPECIAL_DEF("ceil", 1, f_f, ceil ),
JS_CFUNC_SPECIAL_DEF("abs", 1, f_f, js_math_fabs_wrap ),
JS_CFUNC_SPECIAL_DEF("floor", 1, f_f, js_math_floor_wrap ),
JS_CFUNC_SPECIAL_DEF("ceil", 1, f_f, js_math_ceil_wrap ),
JS_CFUNC_SPECIAL_DEF("round", 1, f_f, js_math_round ),
JS_CFUNC_SPECIAL_DEF("sqrt", 1, f_f, sqrt ),
JS_CFUNC_SPECIAL_DEF("sqrt", 1, f_f, js_math_sqrt_wrap ),
JS_CFUNC_SPECIAL_DEF("acos", 1, f_f, acos ),
JS_CFUNC_SPECIAL_DEF("asin", 1, f_f, asin ),
JS_CFUNC_SPECIAL_DEF("atan", 1, f_f, atan ),
JS_CFUNC_SPECIAL_DEF("atan2", 2, f_f_f, atan2 ),
JS_CFUNC_SPECIAL_DEF("cos", 1, f_f, cos ),
JS_CFUNC_SPECIAL_DEF("exp", 1, f_f, exp ),
JS_CFUNC_SPECIAL_DEF("log", 1, f_f, log ),
JS_CFUNC_SPECIAL_DEF("acos", 1, f_f, js_math_acos_wrap ),
JS_CFUNC_SPECIAL_DEF("asin", 1, f_f, js_math_asin_wrap ),
JS_CFUNC_SPECIAL_DEF("atan", 1, f_f, js_math_atan_wrap ),
JS_CFUNC_SPECIAL_DEF("atan2", 2, f_f_f, js_math_atan2_wrap ),
JS_CFUNC_SPECIAL_DEF("cos", 1, f_f, js_math_cos_wrap ),
JS_CFUNC_SPECIAL_DEF("exp", 1, f_f, js_math_exp_wrap ),
JS_CFUNC_SPECIAL_DEF("log", 1, f_f, js_math_log_wrap ),
JS_CFUNC_SPECIAL_DEF("pow", 2, f_f_f, js_pow ),
JS_CFUNC_SPECIAL_DEF("sin", 1, f_f, sin ),
JS_CFUNC_SPECIAL_DEF("tan", 1, f_f, tan ),
JS_CFUNC_SPECIAL_DEF("sin", 1, f_f, js_math_sin_wrap ),
JS_CFUNC_SPECIAL_DEF("tan", 1, f_f, js_math_tan_wrap ),
/* ES6 */
JS_CFUNC_SPECIAL_DEF("trunc", 1, f_f, trunc ),
JS_CFUNC_SPECIAL_DEF("trunc", 1, f_f, js_math_trunc_wrap ),
JS_CFUNC_SPECIAL_DEF("sign", 1, f_f, js_math_sign ),
JS_CFUNC_SPECIAL_DEF("cosh", 1, f_f, cosh ),
JS_CFUNC_SPECIAL_DEF("sinh", 1, f_f, sinh ),
JS_CFUNC_SPECIAL_DEF("tanh", 1, f_f, tanh ),
JS_CFUNC_SPECIAL_DEF("acosh", 1, f_f, acosh ),
JS_CFUNC_SPECIAL_DEF("asinh", 1, f_f, asinh ),
JS_CFUNC_SPECIAL_DEF("atanh", 1, f_f, atanh ),
JS_CFUNC_SPECIAL_DEF("expm1", 1, f_f, expm1 ),
JS_CFUNC_SPECIAL_DEF("log1p", 1, f_f, log1p ),
JS_CFUNC_SPECIAL_DEF("log2", 1, f_f, log2 ),
JS_CFUNC_SPECIAL_DEF("log10", 1, f_f, log10 ),
JS_CFUNC_SPECIAL_DEF("cbrt", 1, f_f, cbrt ),
JS_CFUNC_SPECIAL_DEF("cosh", 1, f_f, js_math_cosh_wrap ),
JS_CFUNC_SPECIAL_DEF("sinh", 1, f_f, js_math_sinh_wrap ),
JS_CFUNC_SPECIAL_DEF("tanh", 1, f_f, js_math_tanh_wrap ),
JS_CFUNC_SPECIAL_DEF("acosh", 1, f_f, js_math_acosh_wrap ),
JS_CFUNC_SPECIAL_DEF("asinh", 1, f_f, js_math_asinh_wrap ),
JS_CFUNC_SPECIAL_DEF("atanh", 1, f_f, js_math_atanh_wrap ),
JS_CFUNC_SPECIAL_DEF("expm1", 1, f_f, js_math_expm1_wrap ),
JS_CFUNC_SPECIAL_DEF("log1p", 1, f_f, js_math_log1p_wrap ),
JS_CFUNC_SPECIAL_DEF("log2", 1, f_f, js_math_log2_wrap ),
JS_CFUNC_SPECIAL_DEF("log10", 1, f_f, js_math_log10_wrap ),
JS_CFUNC_SPECIAL_DEF("cbrt", 1, f_f, js_math_cbrt_wrap ),
JS_CFUNC_DEF("hypot", 2, js_math_hypot ),
JS_CFUNC_DEF("random", 0, js_math_random ),
JS_CFUNC_SPECIAL_DEF("fround", 1, f_f, js_math_fround ),
@@ -45738,7 +45805,7 @@ static JSMapRecord *map_add_record(JSContext *ctx, JSMapState *s,
} else {
JS_DupValue(ctx, key);
}
mr->key = (JSValue)key;
mr->key = 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);
@@ -45960,7 +46027,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] = this_val;
ret = JS_Call(ctx, func, this_arg, 3, (JSValueConst *)args);
JS_FreeValue(ctx, args[0]);
if (!magic)
@@ -46956,7 +47023,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;
@@ -47315,7 +47382,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);
}
@@ -47894,7 +47961,7 @@ static const JSCFunctionListEntry js_global_funcs[] = {
JS_CFUNC_DEF("escape", 1, js_global_escape ),
JS_CFUNC_DEF("unescape", 1, js_global_unescape ),
JS_PROP_DOUBLE_DEF("Infinity", 1.0 / 0.0, 0 ),
JS_PROP_DOUBLE_DEF("NaN", NAN, 0 ),
JS_PROP_DOUBLE_DEF("NaN", JS_FLOAT64_NAN, 0 ),
JS_PROP_UNDEFINED_DEF("undefined", 0 ),
/* for the 'Date' implementation */
@@ -52744,8 +52811,8 @@ static int js_TA_cmp_generic(const void *a, const void *b, void *opaque) {
psc->exception = 1;
}
done:
JS_FreeValue(ctx, (JSValue)argv[0]);
JS_FreeValue(ctx, (JSValue)argv[1]);
JS_FreeValue(ctx, argv[0]);
JS_FreeValue(ctx, argv[1]);
}
return cmp;
}
+26 -5
View File
@@ -215,12 +215,33 @@ typedef struct JSValue {
#define JS_VALUE_GET_FLOAT64(v) ((v).u.float64)
#define JS_VALUE_GET_PTR(v) ((v).u.ptr)
#define JS_MKVAL(tag, val) (JSValue){ (JSValueUnion){ .int32 = val }, tag }
#define JS_MKPTR(tag, p) (JSValue){ (JSValueUnion){ .ptr = p }, tag }
static inline JSValue JS_MKVAL(int tag, int32_t val)
{
JSValue v;
v.tag = tag;
v.u.int32 = val;
return v;
}
static inline JSValue JS_MKPTR(int tag, void *ptr)
{
JSValue v;
v.tag = tag;
v.u.ptr = ptr;
return v;
}
#define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64)
#define JS_NAN (JSValue){ .u.float64 = JS_FLOAT64_NAN, JS_TAG_FLOAT64 }
static inline JSValue JS_MKFLOAT64_NAN(void)
{
JSValue v;
v.tag = JS_TAG_FLOAT64;
v.u.float64 = JS_FLOAT64_NAN;
return v;
}
#define JS_NAN JS_MKFLOAT64_NAN()
static inline JSValue __JS_NewFloat64(JSContext *ctx, double d)
{
@@ -667,7 +688,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 v;
}
static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v)
@@ -676,7 +697,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 v;
}
int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */