Skip to content

Commit 217f0e2

Browse files
JohnoKingMcDutchie
andcommitted
64-bit transition part 11: ksh93 nval (#964)
This is the eleventh of the thickfold patch series, which enables ksh93 to operate within a 64-bit address space. The parts of ksh93 affected by this commit are: - Various pieces of code wrongly assuming char is signed have been fixed (follow-up to #962). - The nval system, string.c, array handling and waitevent.c. This is probably one of the most consequential changes, the effect being that ksh is now capable of storing variables larger than UINT_MAX. Conspicuous changes of note: - With the expansion of np->nvsize to a size_t (which can be either 64-bit or 32-bit), the void* padding variable was a necessary addition for alignment purposes, so as to silence UBSan errors and prevent untimely memory faults. - (This part by Martijn Dekker) The NV_MINSZ and nv_namptr macros in nval.h have been corrected to properly align the value data that follows a static Namval_t header (minus its nvlink member) in a portable manner, i.e., according to max_align_t's alignment requirement (re: 01abbc6). This fixes longstanding incorrect alignment logic that happened to work on most platforms but broke if the layout of the Namval struct (Namval_t) was changed, causing undefined behaviour mainly in nvtype.c. This change should finally make it safe to apply future edits to Namval_t (except that nvlink and nvname must remain unchanged). - An -Wunreachable-code-return warning at the end of nv_create() has been fixed. - nv_setsize() as exposed in the public nval API now requires an argument of exactly (size_t)-1 to function like the nv_size() macro. - nv_create(): ported over an old fix from my expand-nvflags branch to allow usage of strlen without downcasting the result to an int. This fix adds a uint64_t nvflags variable for storing flags, which introduces some inconsequential warnings. Fixing/avoiding those is out of the scope of this project; that's better suited for a future revision of expand-nvflags. - Removed the unused and inessential attsize and attval struct members (these are remnants of the A__z botch, re: f215b10). Change in the number of warnings on Linux when compiling with clang using -Wsign-compare -Wshorten-64-to-32 -Wsign-conversion -Wimplicit-int-conversion: 802 => 481 => 37 (progression from part 10 => part 11 => part 13) Progresses #592 Co-authored-by: Martijn Dekker <martijn@inlv.org>
1 parent 1acaeae commit 217f0e2

19 files changed

Lines changed: 449 additions & 422 deletions

File tree

src/cmd/ksh93/include/defs.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ extern void *sh_arithcomp(char*);
112112
extern pid_t sh_fork(int,int*);
113113
extern pid_t _sh_fork(pid_t, int ,int*);
114114
extern void sh_invalidate_ifs(void);
115-
extern char *sh_mactrim(char*,int);
115+
extern char *sh_mactrim(char*,int8_t);
116116
extern int sh_macexpand(struct argnod*,struct argnod**,int);
117117
extern int sh_macfun(const char*,ptrdiff_t);
118118
extern void sh_machere(Sfio_t*, Sfio_t*, char*);

src/cmd/ksh93/include/name.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ struct Namref
5757
Dt_t *root;
5858
char *sub;
5959
#if SHOPT_FIXEDARRAY
60-
int curi;
60+
ssize_t curi;
6161
char dim;
6262
#endif /* SHOPT_FIXEDARRAY */
6363
};
@@ -143,12 +143,12 @@ struct Ufunction
143143
#define array_elem(ap) ((ap)->nelem&ARRAY_MASK)
144144
#define array_assoc(ap) ((ap)->fun)
145145

146-
extern int array_maxindex(Namval_t*);
146+
extern ssize_t array_maxindex(Namval_t*);
147147
extern char *nv_endsubscript(Namval_t*, char*, int);
148148
extern Namfun_t *nv_enforcedisc(Namval_t*);
149149
extern int nv_arrayisset(Namval_t*, Namarr_t*);
150150
extern int nv_arraysettype(Namval_t*, Namval_t*,const char*,int);
151-
extern int nv_aimax(Namval_t*);
151+
extern ssize_t nv_aimax(Namval_t*);
152152
extern int nv_atypeindex(Namval_t*, const char*);
153153
extern void nv_setlist(struct argnod*, int, Namval_t*);
154154
#if SHOPT_OPTIMIZE
@@ -162,7 +162,7 @@ extern void nv_setlist(struct argnod*, int, Namval_t*);
162162
# define nv_setoptimize(argaddr) /* no-op */
163163
# define nv_getoptimize() NULL
164164
#endif /* SHOPT_OPTIMIZE */
165-
extern void nv_outname(Sfio_t*,char*, int);
165+
extern void nv_outname(Sfio_t*,char*, ptrdiff_t);
166166
extern void nv_unref(Namval_t*);
167167
extern int nv_hasget(Namval_t*);
168168
extern void clone_all_disc(Namval_t*, Namval_t*, int);
@@ -186,7 +186,7 @@ extern int nv_istable(Namval_t*);
186186
extern size_t nv_datasize(Namval_t*, size_t*);
187187
extern Namfun_t *nv_mapchar(Namval_t*, const char*);
188188
#if SHOPT_FIXEDARRAY
189-
extern int nv_arrfixed(Namval_t*, Sfio_t*, int, char*);
189+
extern ssize_t nv_arrfixed(Namval_t*, Sfio_t*, int, char*);
190190
#endif /* SHOPT_FIXEDARRAY */
191191

192192
extern const Namdisc_t RESTRICTED_disc;

src/cmd/ksh93/include/national.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
# endif
3333
#endif /* SHOPT_MULTIBYTE */
3434

35-
extern int sh_strchr(const char*,const char*);
36-
extern int sh_strwidth(const char*);
35+
extern ptrdiff_t sh_strchr(const char*,const char*);
36+
extern size_t sh_strwidth(const char*);
3737

3838
#endif /* !_NATIONAL_H */

src/cmd/ksh93/include/nval.h

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ struct Namfun
6767
const Namdisc_t *disc;
6868
char nofree;
6969
unsigned int subshell;
70-
uint32_t dsize;
70+
size_t dsize;
7171
Namfun_t *next;
7272
char *last;
7373
Namval_t *type;
@@ -76,7 +76,7 @@ struct Namfun
7676
struct Nambfun
7777
{
7878
Namfun_t fun;
79-
int num;
79+
ssize_t num;
8080
const char **bnames;
8181
Namval_t *bltins[1];
8282
};
@@ -103,33 +103,35 @@ struct Namdecl
103103
/* attributes of name-value node attribute flags */
104104

105105
#define NV_DEFAULT 0
106-
/* This defines the attributes for an attributed name-value pair node */
106+
107+
/*
108+
* This defines the attributes for an attributed name-value pair node.
109+
*
110+
* NOTE: For NV_MINSZ and nv_namptr (below) to work correctly, nvlink
111+
* and nvname must be the first two members, in that order.
112+
*/
107113
struct Namval
108114
{
109115
Dtlink_t nvlink; /* space for cdt links */
110116
char *nvname; /* pointer to name of the node */
111-
#if _ast_sizeof_pointer == 8
112-
# if _ast_intswap > 0
113-
unsigned short nvflag; /* attributes */
114-
unsigned short pad1;
115-
# else
116-
unsigned short pad1;
117-
unsigned short nvflag; /* attributes */
118-
# endif
119-
uint32_t nvsize; /* size or base */
120-
#else
121-
unsigned short nvflag; /* attributes */
122-
unsigned short nvsize; /* size or base */
123-
#endif
117+
uint16_t nvflag; /* attributes */
118+
size_t nvsize; /* size or base */
124119
Namfun_t *nvfun; /* pointer to trap functions */
125120
void *nvalue; /* pointer to any kind of value */
126121
void *nvmeta; /* pointer to any of various kinds of type-dependent data */
127122
};
128123

129124
#define NV_CLASS ".sh.type"
130125
#define NV_DATA "_" /* special class or instance variable */
131-
#define NV_MINSZ (sizeof(struct Namval)-sizeof(Dtlink_t)-sizeof(char*))
132-
#define nv_namptr(p,n) ((Namval_t*)((char*)(p)+(n)*NV_MINSZ-sizeof(Dtlink_t)))
126+
127+
/* For aligning and addressing Namval_t data headers or array members with the nvlink member chopped off */
128+
struct _Namval_align_
129+
{
130+
char dummy;
131+
max_align_t probe;
132+
};
133+
#define NV_MINSZ roundof(sizeof(struct Namval) - offsetof(struct Namval, nvname), offsetof(struct _Namval_align_, probe))
134+
#define nv_namptr(p,n) ((Namval_t*)((char*)(p) + (n) * NV_MINSZ - offsetof(struct Namval, nvname)))
133135

134136
/* The following attributes are for internal use */
135137
#define NV_NOFREE 0x200 /* don't free the space when releasing value */
@@ -267,7 +269,7 @@ extern int nv_isnull(Namval_t*);
267269
extern Namfun_t *nv_isvtree(Namval_t*);
268270
extern Namval_t *nv_lastdict(void);
269271
extern Namval_t *nv_mkinttype(char*, size_t, int, const char*, Namdisc_t*);
270-
extern void nv_newattr(Namval_t*,unsigned,int);
272+
extern void nv_newattr(Namval_t*,unsigned,ssize_t);
271273
extern void nv_newtype(Namval_t*);
272274
extern Namval_t *nv_open(const char*,Dt_t*,int);
273275
extern void nv_putval(Namval_t*,const char*,int);
@@ -280,7 +282,7 @@ extern void nv_setref(Namval_t*, Dt_t*,int);
280282
extern int nv_settype(Namval_t*, Namval_t*, int);
281283
extern void nv_setvec(Namval_t*,int,int,char*[]);
282284
extern void nv_setvtree(Namval_t*);
283-
extern int nv_setsize(Namval_t*,int);
285+
extern size_t nv_setsize(Namval_t*,size_t);
284286
extern Namfun_t *nv_disc(Namval_t*,Namfun_t*,int);
285287
extern void nv_unset(Namval_t*,int);
286288
extern Namval_t *nv_search(const char *, Dt_t*, int);
@@ -289,7 +291,7 @@ extern Namval_t *nv_type(Namval_t*);
289291
extern void nv_addtype(Namval_t*,const char*, Optdisc_t*, size_t);
290292
extern const Namdisc_t *nv_discfun(int);
291293

292-
#define nv_size(np) nv_setsize((np),-1)
294+
#define nv_size(np) nv_setsize((np),(size_t)-1)
293295
#define nv_stack(np,nf) nv_disc(np,nf,0)
294296

295297
#endif /* !_NVAL_H */

src/cmd/ksh93/include/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#include <ast_release.h>
2222
#include "git.h"
2323

24-
#define SH_RELEASE_DATE "2026-04-02" /* must be in this format for $((.sh.version)) */
24+
#define SH_RELEASE_DATE "2026-04-05" /* must be in this format for $((.sh.version)) */
2525
/*
2626
* This comment keeps SH_RELEASE_DATE a few lines away from SH_RELEASE_SVER to avoid
2727
* merge conflicts when cherry-picking dev branch commits onto a release branch.

src/cmd/ksh93/nval.3

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Namdisc_t;
2525
.ft 5
2626
Namval_t *nv_open(const char *\fIname\fP, Dt_t *\fIdict\fP, int \fIflags\fP);
2727
Namval_t *nv_create(const char *\fIname\fP, Dt_t *\fIdict\fP, int \fIflags\fP, Namfun_t *\fIfp\fP);
28-
Namval_t *nv_namptr(void *\fIptr\fP, int \fIindx\fP);
28+
Namval_t *nv_namptr(void *\fIptr\fP, size_t \fIindx\fP);
2929
void nv_delete(Namval_t *\fInp\fP, Dt_t *\fIdict\fP, int \fInofree\fP);
3030
.ft R
3131
.fi
@@ -44,13 +44,13 @@ int nv_clone(Namval_t *\fIsrc\fP, Namval_t *\fIdest\fP, int \fIflags\fP);
4444
.nf
4545
.ft 5
4646
int nv_isnull(Namval_t *\fInp\fP);
47-
int nv_setsize(Namval_t *\fInp\fP, int \fIsize\fP);
48-
int nv_size(Namval_t *\fInp\fP);
47+
size_t nv_setsize(Namval_t *\fInp\fP, size_t \fIsize\fP);
48+
size_t nv_size(Namval_t *\fInp\fP);
4949
unsigned nv_isattr(Namval_t *\fInp\fP, unsigned \fIflags\fP);
5050
Namfun_t *nv_isvtree(Namval_t *\fInp\fP);
5151
unsigned nv_onattr(Namval_t *\fInp\fP, unsigned \fIflags\fP);
5252
unsigned nv_offattr(Namval_t *\fInp\fP, unsigned \fIflags\fP);
53-
void nv_newattr(Namval_t *\fInp\fP, unsigned \fIflags\fP, int \fIsize\fP);
53+
void nv_newattr(Namval_t *\fInp\fP, unsigned \fIflags\fP, ssize_t \fIsize\fP);
5454
.ft R
5555
.fi
5656

@@ -206,8 +206,8 @@ justified variables, the arithmetic base for integer variables,
206206
and the precision or number of places after the decimal point
207207
for floating point variables. If \fIsize\fP is greater than or
208208
equal to zero, the current size is changed to this value.
209-
The \f3nv_size()\fP function is equivalent to \f3nv_setsize()\fP
210-
with the second argument negative.
209+
The \f3nv_setsize()\fP function is equivalent to \f3nv_size()\fP
210+
when the second argument is equal to -1.
211211
.PP
212212
The \f3nv_getval()\fP function returns the value of the given
213213
name-value pair as a string. A \f3NULL\fP return value indicates

0 commit comments

Comments
 (0)