Skip to content

Commit

Permalink
platform specific porting code
Browse files Browse the repository at this point in the history
Signed-off-by: Joe Devlin <[email protected]>
  • Loading branch information
JoeNemo committed Feb 22, 2022
1 parent 0ec8ffd commit cd3c318
Show file tree
Hide file tree
Showing 4 changed files with 352 additions and 0 deletions.
139 changes: 139 additions & 0 deletions porting/debugutil.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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<prePad; i++){
buffer[offset+i] = ' ';
}
offset += prePad;

for (i=0; i<formatWidth; i++){
int shift = 4 * (formatWidth - i - 1);
buffer[offset+i] = hexDigits[(value>>shift)&0xf];
}
offset += formatWidth;
for (i=0; i<postPad; i++){
buffer[offset+i] = ' ';
}
return offset+postPad;
}

char *simpleHexFill(char *buffer, int formatWidth, int value){
int pos = hexFill(buffer,0,0,formatWidth,0,value);
buffer[pos] = 0;
return buffer;
}

char *simpleHexPrint(char *buffer, char *data, int len){
int i;
for (i=0; i<len; i++){
buffer[(2*i)] = hexDigits[(data[i]&0xf0)>>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<len; i++){
buffer[(2*i)] = hexDigitsLower[(data[i]&0xf0)>>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<formatWidth; pos++){
if ((index+pos)<length){
simpleHexFill(lineBuffer+linePos,2,(int)(0xFF&buffer[index+pos]));
linePos += 2;
/* linePos += sprintf(lineBuffer+linePos,"%0.2x",(int)(0xFF&buffer[index+pos])); */
} else{
linePos += sprintf(lineBuffer+linePos," ");
}
if ((pos % 4) == 3){
linePos += sprintf(lineBuffer+linePos," ");
}
}
linePos += sprintf(lineBuffer+linePos,"%s|",pad2);
for (pos=0; pos<formatWidth && (index+pos)<length; pos++){
int ch = trans[0xFF & buffer[index+pos]];
lineBuffer[linePos++] = ch;
}
lineBuffer[linePos++] = '|';
lineBuffer[linePos++] = 0;
printf("%s\n",lineBuffer);
index += formatWidth;
}
fflush(stdout);
}

void dumpbuffer(void *buffer, int length){
hexdump((char*)buffer,length,0,32," "," ");
}
134 changes: 134 additions & 0 deletions porting/polyfill.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#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;
}

42 changes: 42 additions & 0 deletions porting/polyfill.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#ifndef __CLANGBETA2_POLYFILL__
#define __CLANGBETA2_POLYFILL__

#if __CHARSET_LIB == 1
#define QASCII 1
#endif

#include <time.h>

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
37 changes: 37 additions & 0 deletions porting_build.txt
Original file line number Diff line number Diff line change
@@ -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="<somePath>/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

<TBD>

0 comments on commit cd3c318

Please sign in to comment.