diff --git a/porting/polyfill.c b/porting/polyfill.c index 5a7ce80..23fb84c 100644 --- a/porting/polyfill.c +++ b/porting/polyfill.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "polyfill.h" @@ -107,7 +108,7 @@ int convertOpenStream(int fd, unsigned short fileCCSID){ } int tagFile(char *pathname, unsigned short ccsid){ -#ifdef _LP64 +#if defined(_LP64) && defined(ZCOMPILE_CLANG) attrib64_t attr; memset(&attr,0,sizeof(attrib64_t)); diff --git a/porting/polyfill.h b/porting/polyfill.h index 132cd5d..bc13fa7 100644 --- a/porting/polyfill.h +++ b/porting/polyfill.h @@ -1,5 +1,86 @@ -#ifndef __CLANGBETA2_POLYFILL__ -#define __CLANGBETA2_POLYFILL__ +#ifndef __CLANG_POLYFILL__ +#define __CLANG_POLYFILL__ + +#include + +#if defined(__GNUC__) && defined(__clang__) +#ifdef __IBMC__ +#define ZCOMPILE_XLCLANG +#else +#define ZCOMPILE_CLANG +#endif +#elif defined(__IBMC__) +#define ZCOMPILE_XLC +#else +#error Unknown_ZOS_C_Compiler +#endif + +#ifdef ZCOMPILE_XLCLANG + + +/* Notation from standard + + http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1548.pdf + + A - an atomic type + C - corresponding non-atomic + M - other arg for arithmetic, for atomic integer types, M is C + + atomic_fetch_add( volatile void* obj, memory_order mo ); + + The functions not ending in _explicit have the same semantics as the +corresponding _explicit function with memory_order_seq_cst for the +memory_order argument. + +*/ + +enum memory_order{ + memory_order_relaxed = __ATOMIC_RELAXED, + memory_order_consume = __ATOMIC_CONSUME, + memory_order_acquire = __ATOMIC_ACQUIRE, + memory_order_release = __ATOMIC_RELEASE, + memory_order_acq_rel = __ATOMIC_ACQ_REL, + memory_order_seq_cst = __ATOMIC_SEQ_CST, +}; + +typedef enum memory_order memory_order; + +#define atomic_fetch_add(ptr, val) __c11_atomic_fetch_add(ptr, val, memory_order_seq_cst) +#define atomic_fetch_sub(ptr, val) __c11_atomic_fetch_sub(ptr, val, memory_order_seq_cst) +#define atomic_fetch_and(ptr, val) __c11_atomic_fetch_and(ptr, val, memory_order_seq_cst) +#define atomic_fetch_or(ptr, val) __c11_atomic_fetch_or(ptr, val, memory_order_seq_cst) +#define atomic_fetch_xor(ptr, val) __c11_atomic_fetch_xor(ptr, val, memory_order_seq_cst) +#define atomic_load(ptr) __c11_atomic_load(ptr, memory_order_seq_cst) +#define atomic_store(ptr, val) __c11_atomic_store(ptr, val, memory_order_seq_cst) +#define atomic_exchange(ptr, val) __c11_atomic_exchange(ptr, val, memory_order_seq_cst) +#define atomic_compare_exchange_weak(ptr, exch, val) __c11_atomic_compare_exchange_weak(ptr, exch, val, memory_order_seq_cst, memory_order_seq_cst) +#define atomic_compare_exchange_strong(ptr, exch, val) __c11_atomic_compare_exchange_strong(ptr, exch, val, memory_order_seq_cst, memory_order_seq_cst) + +typedef _Atomic(int) atomic_int; +typedef _Atomic(uint8_t) atomic_uint8_t; +typedef _Atomic(uint16_t) atomic_uint16_t; +typedef _Atomic(uint32_t) atomic_uint32_t; +typedef _Atomic(uint64_t) atomic_uint64_t; + +typedef struct fake_uint128_tag{ + uint64_t hi; + uint64_t lo; +} fake_uint128_t; + +typedef struct fake_int128_tag{ + int64_t hi; + int64_t lo; +} fake_int128_t; + +#define joe_mul128(x,y) 0 +#define joe_castU128To64(x) (x)->lo + +#else + +#define joe_mul128(x,y) ((x) * (y)) +#define joe_castU128To64(x) (x) + +#endif #if __CHARSET_LIB == 1 #define QASCII 1 @@ -12,6 +93,8 @@ size_t malloc_usable_size (const void *ptr); int32_t atomicIncrementI32(int32_t *intPointer, int32_t increment); int64_t atomicIncrementI64(int64_t *intPointer, int64_t increment); + + typedef int clockid_t; #define CLOCK_REALTIME 0 diff --git a/porting_build.txt b/porting_build.txt index e690bb8..295a479 100644 --- a/porting_build.txt +++ b/porting_build.txt @@ -6,7 +6,7 @@ as its multiplatform compile/link tool. ---------------------------------------------------------------------- -Building on Z +Building on Z with Clang-13 Beta Clang-13 is in beta on ZOS but works very on C11 sources. @@ -37,6 +37,34 @@ ${CLANG}/bin/clang-13 -DCONFIG_VERSION=\"2021-03-27\" -D__SUSV3_THR=1 -D_OPEN_TH +-------------------------------------------------------------------------- + +Building on Z with xlclang 2.4.1 + +xlclang is the hybrid Clang-front-end-IBM-Toronto-backend +implementation of C/C++ that is currently GA on ZOS 2.4 and later. It +does not support 128 bit integers but otherwise seems provides what +QuickJS needs excluding BIGNUM support. Fortunately very little +JavaScript code uses the new bignum (e.g. 12345n) type numbers yet. + +xlclang also does not support stdatomic directly, however, the atomic +support for C++ seemed pretty good, so polyfill.h/c now expose a +subset of . A full implemention could probably be made +with a few more days effort. + +1) xlclang -q64 -qascii -DCONFIG_VERSION=\"2021-03-27\" -D_OPEN_SYS_FILE_EXT=1 -D_XOPEN_SOURCE=600 -D_OPEN_THREADS=1 -DSUBPOOL=132 "-Wc,float(ieee),longname,langlvl(extc99),gonum,goff,ASM,asmlib('CEE.SCEEMAC','SYS1.MACLIB','SYS1.MODGEN')" "-Wl,ac=1" -I ../h -Wbitwise-op-parentheses -o qjsc qjsc.c quickjs.c cutils.c quickjs-libc.c libregexp.c libunicode.c porting/polyfill.c + +2) Compile repl + +qjsc -c -o repl.c -m repl.js + +3) build the interpreter + +xlclang -q64 -qascii -DCONFIG_VERSION=\"2021-03-27\" -D_OPEN_SYS_FILE_EXT=1 -D_XOPEN_SOURCE=600 -D_OPEN_THREADS=1 -DSUBPOOL=132 "-Wc,float(ieee),longname,langlvl(extc99),gonum,goff,ASM,asmlib('CEE.SCEEMAC','SYS1.MACLIB','SYS1.MODGEN')" "-Wl,ac=1" -I ../h -Wbitwise-op-parentheses -o qjs qjs.c repl.c quickjs.c cutils.c quickjs-libc.c libregexp.c libunicode.c porting/polyfill.c porting/debugutil.c + +4,5) as above with Clang-13 build. + + -------------------------------------------------------------------------- Building on Windows diff --git a/quickjs.c b/quickjs.c index 58e1499..6737b7a 100644 --- a/quickjs.c +++ b/quickjs.c @@ -140,7 +140,11 @@ typedef int64_t ssize_t; /* JOENemo - I don't know where this comes from, but it #else #include #endif -#include + +#ifndef ZCOMPILE_XLCLANG /* XLCLANG hybrid thing does not have stdatomic, but clang-13 does */ +#include +#endif + #include #endif