diff --git a/porting/debugutil.c b/porting/debugutil.c new file mode 100644 index 0000000..840bf5a --- /dev/null +++ b/porting/debugutil.c @@ -0,0 +1,139 @@ +#include +#include +#include + +static char hexDigits[16] ={ '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'A', 'B', + 'C', 'D', 'E', 'F'}; + +static char hexDigitsLower[16] = { '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f'}; + +int hexFill(char *buffer, int offset, int prePad, int formatWidth, int postPad, int value){ + int i; + + for (i=0; i>shift)&0xf]; + } + offset += formatWidth; + for (i=0; i>4]; + buffer[(2*i)+1] = hexDigits[(data[i]&0x0f)]; + } + buffer[(2*i)] = 0; + return buffer; +} + +char *simpleHexPrintLower(char *buffer, char *data, int len){ + int i; + for (i=0; i>4]; + buffer[(2*i)+1] = hexDigitsLower[(data[i]&0x0f)]; + } + buffer[(2*i)] = 0; + return buffer; +} + +static const unsigned char printableEBCDIC[256] = { /*ascii indexing good when compiling with qascii */ + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x20, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, + 0x26, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, + 0x2d, 0x2f, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x60, 0x3a, 0x23, 0x2e, 0x27, 0x3d, 0x22, + 0x2e, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x2e, 0x2e, 0x2e, 0x5b, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x5d, 0x2e, 0x2e, + 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x5c, 0x2e, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e +}; + +static const unsigned char printableASCII[256] = { + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x2e, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, + 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e +}; + + +static void hexdump(char *buffer, int length, int nominalStartAddress, int formatWidth, char *pad1, char *pad2){ + int i; + int index = 0; + int last_index = length-1; + char lineBuffer[256]; + const unsigned char *trans = printableASCII; + int pad1Len = strlen(pad1); + + while (index <= last_index){ + int pos; + int linePos = 8+pad1Len; + simpleHexFill(lineBuffer,8,index+nominalStartAddress); + memcpy(lineBuffer+8,pad1,pad1Len); + for (pos=0; pos +#include +#include +#include +#include +#include +#include +#include +#include "polyfill.h" + +size_t malloc_usable_size (const void *ptr){ + char *data = (char*)ptr; + int64_t address = (int64_t)ptr; + if (address > 0x100000000l){ + data -= 4; + return *((int*)data) - 0x10; /* that's the 64 bit malloc overhead */ + } else{ + return *((int*)data) - 0x10; /* that's the 31 bit malloc overhead */ + } +} + + +#if defined(__XPLINK__) +int32_t atomicIncrementI32(int32_t *place, int32_t increment){ + int32_t oldValue = 0; + int32_t newValue = 0; /* just to let compiler figure out a register */ + int pswMask = 0; + int64_t addr = (int64_t)place; + while (1){ + oldValue = *place; + newValue = oldValue+increment; + /* printf("old=%d new=%d\n",oldValue,newValue); */ + __asm(" L 9,%0 \n" + " L 10,%1 \n" + " LG 11,%2 \n" + " CS 9,10,0(11) \n" + " EPSW 10,0 note re-use of r10 \n" + " ST 10,%3 " + : + : + "m"(oldValue),"m"(newValue),"m"(addr),"m"(pswMask) + : + "r9","r10","r11"); + int cc = 0x3000 & pswMask; + /* printf("pswMask=0x%08X, old=%d\n",pswMask,oldValue); */ + if (cc == 0){ /* Pseudo JZ out of loop */ + break; + } + } + return oldValue; +} + +#else + +int32_t atomicIncrementI32(int32_t *place, int32_t increment){ + int old = *place; + /* printf("Ay caramba\n"); */ + *place = (old + increment); + return old; +} + +#endif + +/* +struct timespec { + time_t tv_sec; -- seconds + long tv_nsec; -- nanoseconds +}; +*/ + +#define STCK_MICRO_SHIFT 12 +static const uint64_t unixSecondsAfterZ = UINT64_C(2208988800); + +/* this ain't great, but it's better than nothing */ + +int clock_gettime(clockid_t clk_id, struct timespec *tp){ + uint64_t stck; + __asm(" STCK %0 " + : : "m"(stck): "r15"); + long micros = (long)(stck&0xFFF); + time_t unixSeconds = (time_t)((stck >> STCK_MICRO_SHIFT) - unixSecondsAfterZ); + + switch (clk_id){ + case CLOCK_REALTIME: + case CLOCK_MONOTONIC: + tp->tv_sec = unixSeconds; + tp->tv_nsec = (micros * 1000); + return 0; + default: + { + printf("*** PANIC *** unhandled clockid_t=%d\n",clk_id); + return EINVAL; /* 22 */ + } + } +} + +int convertOpenStream(int fd, unsigned short fileCCSID){ + struct f_cnvrt conversionArg; + conversionArg.cvtcmd = SETCVTON; /* SETCVTOFF; */ + conversionArg.pccsid = 0; + conversionArg.fccsid = fileCCSID; /* 1047; */ + int res = fcntl(fd, F_CONTROL_CVT, &conversionArg); + if (res != 0){ + printf("* internal error* convertOpenStream(), and ascii/ebcdic function, called fcntl failed errno=%d\n",errno); + } + return res; +} + +int tagFile(char *pathname, unsigned short ccsid){ +#ifdef _LP64 + attrib64_t attr; + memset(&attr,0,sizeof(attrib64_t)); + + attr.att_filetagchg = 1; + attr.att_filetag.ft_ccsid = ccsid; + attr.att_filetag.ft_txtflag = 1; + + int res = __chattr64(pathname, &attr, sizeof(attr)); +#else + attrib_t attr; + memset(&attr,0,sizeof(attrib_t)); + + attr.att_filetagchg = 1; + attr.att_filetag.ft_ccsid = ccsid; + attr.att_filetag.ft_txtflag = 1; + + int res = __chattr(pathname, &attr, sizeof(attr)); +#endif + if (res){ + printf("chattr failed with errno=%d\n",errno); + } + return res; +} + diff --git a/porting/polyfill.h b/porting/polyfill.h new file mode 100644 index 0000000..132cd5d --- /dev/null +++ b/porting/polyfill.h @@ -0,0 +1,42 @@ +#ifndef __CLANGBETA2_POLYFILL__ +#define __CLANGBETA2_POLYFILL__ + +#if __CHARSET_LIB == 1 +#define QASCII 1 +#endif + +#include + +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 +#define CLOCK_MONOTONIC 1 + +int clock_gettime(clockid_t clk_id, struct timespec *tp); + +/* + struct tm is short a few fields + + The glibc version of struct tm has additional fields + + long tm_gmtoff; -- Seconds east of UTC + const char *tm_zone; -- Timezone abbreviation + + + */ + +void dumpbuffer(void *buffer, int length); /* temp hack */ + +int convertOpenStream(int fd, unsigned short fileCCSID); + +#define CHARSET_ISO8859 819 + +int tagFile(char *pathname, unsigned short ccsid); + + +#endif diff --git a/porting_build.txt b/porting_build.txt new file mode 100644 index 0000000..f809aa0 --- /dev/null +++ b/porting_build.txt @@ -0,0 +1,37 @@ +QuickJS compiles well on many platorms using GCC or Clang. Linux and +BSD distros do this well with exactly the instructions in the primary +QuickJS repo. ZOS and Windows are OS's that are more challenging for +porting. This repo is a minor variant on QuickJS that uses Clang/LLVM +as its multiplatform compile/link tool. + +Building on Z + +Clang-13 is in beta on ZOS but works very on C11 sources. + +The primary issues on ZOS are accounting for the native character set +(EBCDIC) and filling gaps in the C11 standard libraries. The lattr +will probably vanish, but the former will persist indefinitely. + +Please set a Environment Variable for Clang + + export CLANG="/openxl_beta2" + +Git clone to quickjs to some repo and cd there. + +1) Make the compiler + +${CLANG}/bin/clang-13 -DCONFIG_VERSION=\"2021-03-27\" -D__SUSV3_THR=1 -D_OPEN_THREADS -D_XOPEN_SOURCE=600 -D_LARGE_TIME_API -D_OPEN_SYS_FILE_EXT=1 -fzos-le-char-mode=ascii -m64 -o qjsc qjsc.c quickjs.c cutils.c quickjs-libc.c libbf.c libregexp.c libunicode.c porting/polyfill.c porting/debugutil.c + +2) Compile repl +qjsc -c -o repl.c -m repl.js + +3) build the interpreter + +${CLANG}/bin/clang-13 -DCONFIG_VERSION=\"2021-03-27\" -D__SUSV3_THR=1 -D_OPEN_THREADS -D_XOPEN_SOURCE=600 -D_LARGE_TIME_API -D_OPEN_SYS_FILE_EXT=1 -fzos-le-char-mode=ascii -m64 -o qjs qjs.c repl.c quickjs.c cutils.c quickjs-libc.c libbf.c libregexp.c libunicode.c porting/polyfill.c porting/debugutil.c + +4) Test it by running qjs. + +5) Building libraries for embedding + + +