Skip to content

Commit

Permalink
Fix u&.>, which allowed a contents blocks to be marked inplaceable
Browse files Browse the repository at this point in the history
  • Loading branch information
HenryHRich committed Nov 5, 2020
1 parent 9761e26 commit 98b404c
Show file tree
Hide file tree
Showing 29 changed files with 78 additions and 75 deletions.
2 changes: 1 addition & 1 deletion jsrc/ab.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static AHDRR(bw1010insC,UC,UC){I k=d*(n-1);UC t=(UC)((n&1)-1); x+=k; DQ(m, DQ(d,

#define BITWISE(f,T,op) \
F2(f){A z;I *av,k=0,x;T*wv,y,*zv; \
ARGCHK2(a,w);F2PREFIP; /* kludge we allow inplace call but we don't honor it yet */ \
F2PREFIP;ARGCHK2(a,w); /* kludge we allow inplace call but we don't honor it yet */ \
if(!(INT&AT(a)))RZ(a=cvt(INT,a)); \
if(!(INT&AT(w)))RZ(w=cvt(INT,w)); \
av=(I*)AV(a); \
Expand Down
2 changes: 1 addition & 1 deletion jsrc/ao.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

// This is the derived verb for f/. y
static DF1(jtoblique){A x,y,z;I m,n,r;D rkblk[16];
ARGCHK1(w);F1PREFIP;
F1PREFIP;ARGCHK1(w);
r=AR(w); // r = rank of w
// create y= ,/ w - the _2-cells of w arranged in a list (virtual block)
RZ(y=redcat(w,self)); if(1>=r){m=AN(w); n=1;}else{m=AS(w)[0]; n=AS(w)[1];}
Expand Down
2 changes: 1 addition & 1 deletion jsrc/ap.c
Original file line number Diff line number Diff line change
Expand Up @@ -592,7 +592,7 @@ static DF1(jtinfixprefix1){F1PREFIP;

// f/\"r y w is y, fs is in self
static DF1(jtpscan){A z;I f,n,r,t,wn,wr,*ws,wt;
ARGCHK1(w);F1PREFIP;
F1PREFIP;ARGCHK1(w);
wt=AT(w); // get type of w
if(unlikely((SPARSE&wt)!=0))R scansp(w,self,jtpscan); // if sparse, go do it separately
// wn = #atoms in w, wr=rank of w, r=effective rank, f=length of frame, ws->shape of w
Expand Down
6 changes: 3 additions & 3 deletions jsrc/ar.c
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ static B jtreduce2(J jt,A w,C id,I f,I r,A*zz){A z=0;B b=0,btab[258],*zv;I c,d,m
} /* f/"r for dense w over an axis of length 2 */

static DF1(jtreduce){A z;I d,f,m,n,r,t,wr,*ws,zt;
ARGCHK1(w);F1PREFIP;
F1PREFIP;ARGCHK1(w);
if(unlikely((SPARSE&AT(w))!=0))R reducesp(w,self); // If sparse, go handle it
wr=AR(w); ws=AS(w);
// Create r: the effective rank; f: length of frame; n: # items in a CELL of w
Expand Down Expand Up @@ -606,7 +606,7 @@ static A jtredcatsp(J jt,A w,A z,I r){A a,q,x,y;B*b;I c,d,e,f,j,k,m,n,n1,p,*u,*v
// ,&.:(<"r) run together all axes above the last r. r must not exceed AR(w)-1
// w must not be sparse or empty
A jtredcatcell(J jt,A w,I r){A z;
ARGCHK1(w);F1PREFIP;
F1PREFIP;ARGCHK1(w);
I wr=AR(w); // get original rank, which may change if we inplace into the same block
if(r>=wr-1)R RETARG(w); // if only 1 axis left to run together, return the input
if((ASGNINPLACESGN(SGNIF((I)jtinplace,JTINPLACEWX)&(-r),w) && !(AFLAG(w)&AFUNINCORPABLE))){ // inplace allowed, usecount is right
Expand All @@ -624,7 +624,7 @@ A jtredcatcell(J jt,A w,I r){A z;


DF1(jtredcat){A z;B b;I f,r,*s,*v,wr;
ARGCHK1(w);F1PREFIP;
F1PREFIP;ARGCHK1(w);
wr=AR(w); r=(RANKT)jt->ranks; r=wr<r?wr:r; f=wr-r; s=AS(w); RESETRANK;
b=1==r&&1==s[f]; // special case: ,/ on last axis which has length 1: in that case, the rules say the axis disappears (because of the way ,/ works on length-1 lists)
if(2>r&&!b)RCA(w); // in all OTHER cases, result=input for ranks<2
Expand Down
2 changes: 1 addition & 1 deletion jsrc/as.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ A jtscansp(J jt,A w,A self,AF sf){A e,ee,x,z;B*b;I f,m,j,r,t,wr;P*wp,*zp;
} /* f/\"r or f/\."r on sparse w */

static DF1(jtsscan){A y,z;I d,f,m,n,r,t,wn,wr,*ws,wt;
ARGCHK1(w);F1PREFIP;
F1PREFIP;ARGCHK1(w);
wt=AT(w);
if(unlikely((SPARSE&wt)!=0))R scansp(w,self,jtsscan);
wn=AN(w); wr=AR(w); r=(RANKT)jt->ranks; r=wr<r?wr:r; f=wr-r; ws=AS(w); RESETRANK;
Expand Down
2 changes: 1 addition & 1 deletion jsrc/cc.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ DF2(jtspecialatoprestart){
// x <;.0 y and x (<;.0~ -~/"2)~ y where _2 { $x is 1 (i. e. 1 dimension of selection) localuse distinguishes the two cases (relative vs absolute length)
// We go for minimum overhead in the box allocation and copy
DF2(jtboxcut0){A z;
ARGCHK2(a,w);F2PREFIP;
F2PREFIP;ARGCHK2(a,w);
// NOTE: this routine is called from jtwords. In that case, self comes from jtwords and is set up with the parm for x (<;.0~ -~/"2)~ y but with no failover routine.
// Thus, the preliminary tests must not cause a failover. They don't, because the inputs from jtwords are known to be well-formed
// We require a have rank >=2, not sparse
Expand Down
13 changes: 5 additions & 8 deletions jsrc/cg.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
// passes inplacing through
static DF2(jtexeccyclicgerund){ // call is w,self or a,w,self
// find the real self, valence-dependent
ARGCHK1(w);
F2PREFIP;
F2PREFIP;ARGCHK1(w);
I ismonad=(AT(w)>>VERBX)&1; self=ismonad?w:self;
I nexttoexec=FAV(self)->localuse.lI; A vbtoexec=AAV(FAV(self)->fgh[2])[nexttoexec]; AF fntoexec=FAV(vbtoexec)->valencefns[1-ismonad]; ASSERT(fntoexec!=0,EVDOMAIN); // get fn to exec
++nexttoexec; nexttoexec=AN(FAV(self)->fgh[2])==nexttoexec?0:nexttoexec; FAV(self)->localuse.lI=nexttoexec; // cyclically advance exec pointer
Expand All @@ -32,8 +31,7 @@ static DF2(jtexeccyclicgerund){ // call is w,self or a,w,self
// similar, for executing [email protected]. This for I selectors
static DF2(jtexecgerundcellI){ // call is w,self or a,w,self
// find the real self, valence-dependent
ARGCHK1(w);
F2PREFIP;
F2PREFIP;ARGCHK1(w);
I ismonad=(AT(w)>>VERBX)&1; self=ismonad?w:self;
I nexttoexec=FAV(self)->localuse.lI;
I gerx=IAV(FAV(self)->fgh[1])[nexttoexec];
Expand All @@ -46,8 +44,7 @@ static DF2(jtexecgerundcellI){ // call is w,self or a,w,self
// This for B selectors
static DF2(jtexecgerundcellB){ // call is w,self or a,w,self
// find the real self, valence-dependent
ARGCHK1(w);
F2PREFIP;
F2PREFIP;ARGCHK1(w);
I ismonad=(AT(w)>>VERBX)&1; self=ismonad?w:self;
I nexttoexec=FAV(self)->localuse.lI;
I gerx=BAV(FAV(self)->fgh[1])[nexttoexec];
Expand Down Expand Up @@ -148,8 +145,8 @@ F2(jttie){ARGCHK2(a,w); R over(VERB&AT(a)?arep(a):a,VERB&AT(w)?arep(w):w);}
// m@.:v y. Execute the verbs at high rank if the operands are large
// Bivalent entry point: called as (jt,w,self) or (jt,a,w,self)
static DF2(jtcasei12){A vres,z;I gerit[128/SZI],ZZFLAGWORD;
ARGCHK2(a,w);
F1PREFIP; PROLOG(997);
F1PREFIP; ARGCHK2(a,w);
PROLOG(997);
// see if we were called as monad or dyad. If monad, fix up w and self
ZZFLAGWORD=AT(w)&VERB?ZZFLAGINITSTATE|ZZFLAGWILLBEOPENED|ZZFLAGCOUNTITEMS:ZZFLAGINITSTATE|ZZFLAGWILLBEOPENED|ZZFLAGCOUNTITEMS|ZZFLAGISDYAD; // we collect the results on the cells, but we don't assemble into a result. To signal this, we force BOXATOP and set WILLBEOPENED
jtinplace=(J)((I)jtinplace&(a==w?-4:-1)); // Don't allow inplacing if a==w dyad
Expand Down
3 changes: 1 addition & 2 deletions jsrc/cp.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ static DF1(jtpowseq){A fs,gs,x;I n=IMAX;V*sv;

// u^:n w where n is nonnegative finite integer atom (but never 0 or 1, which are handled as special cases)
static DF1(jtfpown){A fs,z;AF f1;I n;V*sv;A *old;
ARGCHK1(w);
F1PREFIP;
F1PREFIP;ARGCHK1(w);
sv=FAV(self);
n=AV(sv->fgh[2])[0];
fs=sv->fgh[0]; f1=FAV(fs)->valencefns[0];
Expand Down
8 changes: 4 additions & 4 deletions jsrc/cr.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,19 +640,19 @@ static DF2(cycr2){V*sv=FAV(self);I cger[128/SZI];


// Handle u"n y where u supports irs. Since the verb may support inplacing even with rank (,"n for example), pass that through.
static DF1(rank1i){ARGCHK1(w);F1PREFIP;DECLF; // this version when requested rank is positive
static DF1(rank1i){F1PREFIP;ARGCHK1(w);DECLF; // this version when requested rank is positive
I m=sv->localuse.lI4[0]; m=m>=AR(w)?~0:m; jt->ranks=(RANK2T)(m); // install rank for called routine
A z=CALL1IP(f1,w,fs);
jt->ranks=(RANK2T)~0; // reset rank to infinite
RETF(z);
}
static DF1(rank1in){ARGCHK1(w);F1PREFIP;DECLF; // this version when requested rank is negative
static DF1(rank1in){F1PREFIP;ARGCHK1(w);DECLF; // this version when requested rank is negative
I m=sv->localuse.lI4[0]+AR(w); m=m<0?0:m; jt->ranks=(RANK2T)(m); // install rank for called routine
A z=CALL1IP(f1,w,fs);
jt->ranks=(RANK2T)~0; // reset rank to infinite
RETF(z);
}
static DF2(rank2i){ARGCHK1(w);F2PREFIP;DECLF; // this version when requested rank is positive
static DF2(rank2i){F2PREFIP;ARGCHK1(w);DECLF; // this version when requested rank is positive
I ar=sv->localuse.lI4[1]; ar=ar>=AR(a)?(RANKT)~0:ar; I af=AR(a)-ar; // left rank
I wr=sv->localuse.lI4[2]; wr=wr>=AR(w)?(RANKT)~0:wr; I wf=AR(w)-wr; // right rank
af=wf<af?wf:af; af=af<0?0:af;
Expand All @@ -662,7 +662,7 @@ static DF2(rank2i){ARGCHK1(w);F2PREFIP;DECLF; // this version when requested ra
jt->ranks=(RANK2T)~0; // reset rank to infinite
RETF(z);
}
static DF2(rank2in){ARGCHK1(w);F2PREFIP;DECLF; // this version when a requested rank is negative
static DF2(rank2in){F2PREFIP;ARGCHK1(w);DECLF; // this version when a requested rank is negative
I wr=AR(w); I r=sv->localuse.lI4[2]; r=r>=wr?(RANKT)~0:r; wr+=r; wr=wr<0?0:wr; wr=r>=0?r:wr; I wf=AR(w)-wr; // right rank
I ar=AR(a); r=sv->localuse.lI4[1]; r=r>=ar?(RANKT)~0:r; ar+=r; ar=ar<0?0:ar; ar=r>=0?r:ar; I af=AR(a)-ar; // left rank
af=wf<af?wf:af; af=af<0?0:af;
Expand Down
14 changes: 10 additions & 4 deletions jsrc/cu.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static A jteverysp(J jt,A w,A fs){A*wv,x,z,*zv;P*wp,*zp;
DF1(jteveryself){R jtevery(jt,w,FAV(self)->fgh[0]);} // replace u&.> with u and process
// u&.>, but w may be a gerund, which makes the result a list of functions masquerading as an aray of boxes
A jtevery(J jt, A w, A fs){A * RESTRICT wv,x,z,* RESTRICT zv;
ARGCHK1(w);F1PREFIP;RESETRANK; // we claim to support IRS1 but really there's nothing to do for it
F1PREFIP;ARGCHK1(w);RESETRANK; // we claim to support IRS1 but really there's nothing to do for it
if(unlikely((SPARSE&AT(w))!=0))R everysp(w,fs);
AF f1=FAV(fs)->valencefns[0]; // pointer to function to call
A virtw; I flags; // flags are: ACINPLACE=pristine result; JTWILLBEOPENED=nonrecursive result; BOX=input was boxed; ACPERMANENT=input was inplaceable pristine, contents can be inplaced
Expand Down Expand Up @@ -90,7 +90,10 @@ A jtevery(J jt, A w, A fs){A * RESTRICT wv,x,z,* RESTRICT zv;
} else {
// result will be opened. It is nonrecursive. description in result.h. We don't have to realize or ra
if(AFLAG(x)&AFUNINCORPABLE){RZ(x=clonevirtual(x));}
// since we are adding the block to a NONrecursive boxed result, we DO NOT have to raise the usecount of the block. And we don't have to mark the usecount non-inplaceable
// since we are adding the block to a NONrecursive boxed result, we DO NOT have to raise the usecount of the block, but we do have to mark the block
// non-inplaceable, because the next thing to open it might be each: each will set the inplaceable flag if the parent is abandoned, so as to allow
// pristinity of lower results; thus we may not relax the rule that all contents must be non-inplaceable
ACIPNO(x); // can't ever have inplaceable contents
// We still have to see if virtw escaped, and on this leg we also have to see if the returned x was virtw
AFLAG(w)&=~(((AC(virtw)!=wcpre)|(x==virtw))<<AFPRISTINEX);
#if 0 // not clear this is worth doing
Expand Down Expand Up @@ -131,7 +134,7 @@ A jtevery(J jt, A w, A fs){A * RESTRICT wv,x,z,* RESTRICT zv;
DF2(jtevery2self){R jtevery2(jt,a,w,FAV(self)->fgh[0]);} // replace u&.> with u and process
// u&.>, but w may be a gerund, which makes the result a list of functions masquerading as an aray of boxes
A jtevery2(J jt, A a, A w, A fs){A*av,*wv,x,z,*zv;
ARGCHK2(a,w);F2PREFIP;
F2PREFIP;ARGCHK2(a,w);
AF f2=FAV(fs)->valencefns[1];
// Get the number of atoms, and the number of times to repeat the short side.
// The repetition is the count of the surplus frame.
Expand Down Expand Up @@ -232,7 +235,10 @@ A jtevery2(J jt, A a, A w, A fs){A*av,*wv,x,z,*zv;
} else {
// result will be opened. It is nonrecursive. description in result.h. We don't have to realize or ra
if(AFLAG(x)&AFUNINCORPABLE){RZ(x=clonevirtual(x));}
// since we are adding the block to a NONrecursive boxed result, we DO NOT have to raise the usecount of the block. And we don't have to mark the usecount non-inplaceable
// since we are adding the block to a NONrecursive boxed result, we DO NOT have to raise the usecount of the block, but we do have to mark the block
// non-inplaceable, because the next thing to open it might be each: each will set the inplaceable flag if the parent is abandoned, so as to allow
// pristinity of lower results; thus we may not relax the rule that all contents must be non-inplaceable
ACIPNO(x); // can't ever have inplaceable contents
// We still have to see if virtw escaped, and on this leg we also have to see if the returned x was virtw
AFLAG(w)&=~(((AC(virtw)!=wcpre)|(x==virtw))<<AFPRISTINEX);
AFLAG(a)&=~(((AC(virta)!=acpre)|(x==virta))<<AFPRISTINEX); flags&=~(((((AC(virtw)!=wcpre)|(x==virtw))&flags)|(((AC(virtw)!=wcpre)|(x==virtw))&(flags>>1)))<<ACINPLACEX);
Expand Down
17 changes: 8 additions & 9 deletions jsrc/j.h
Original file line number Diff line number Diff line change
Expand Up @@ -1297,7 +1297,7 @@ if(likely(z<3)){_zzt+=z; z=(I)&oneone; _zzt=_i&3?_zzt:(I*)z; z=_i&2?(I)_zzt:z; z
#define RNE(exp) {R jt->jerr?0:(exp);}
#define RZ(exp) {if(unlikely(!(exp)))R0}
#if MEMAUDIT&0xc
#define DEADARG(x) (x?(AFLAG(x)&CONW?SEGFAULT:0):0)
#define DEADARG(x) (x?(AFLAG(x)&CONW?SEGFAULT:0):0); if(MEMAUDIT&0x10)auditmemchains(); if(MEMAUDIT&0x2)audittstack(jt);
#define ARGCHK1D(x) ARGCHK1(x) // these not needed normally, but useful for debugging
#define ARGCHK2D(x,y) ARGCHK2(x,y)
#else
Expand Down Expand Up @@ -1447,6 +1447,13 @@ if(likely(z<3)){_zzt+=z; z=(I)&oneone; _zzt=_i&3?_zzt:(I*)z; z=_i&2?(I)_zzt:z; z
#define FLGWMINUSZX 6
#define FLGWMINUSZ ((I)1<<FLGWMINUSZX) // calculate z-x*y rather than x*y. Used by %.

#if !defined(C_CRC32C)
#define C_CRC32C 0
#endif
#if (C_AVX&&SY_64) || defined(__aarch64__) || defined(_M_ARM64) || EMU_AVX
#undef C_CRC32C
#define C_CRC32C 1
#endif


#include "ja.h"
Expand Down Expand Up @@ -1721,14 +1728,6 @@ static __forceinline void aligned_free(void *ptr) {
#define XANDY(x,y) ((I)((UI)(x)&(UI)(y)))
#endif

#if !defined(C_CRC32C)
#define C_CRC32C 0
#endif
#if (C_AVX&&SY_64) || defined(__aarch64__) || defined(_M_ARM64) || EMU_AVX
#undef C_CRC32C
#define C_CRC32C 1
#endif

// Supported in architecture ARMv8.1 and later
#if (C_CRC32C && (defined(__aarch64__)||defined(_M_ARM64)))
#define CRC32CW(crc, value) __asm__("crc32cw %w[c], %w[c], %w[v]":[c]"+r"(crc):[v]"r"(value))
Expand Down
4 changes: 2 additions & 2 deletions jsrc/jt.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ typedef struct {
A implocref[2]; // references to 'u.'~ and 'v.'~, marked as implicit locatives
I4 parsercalls; /* # times parser was called $ */
I4 nthreads; // number of threads to use, or 0 if we haven't checked $
A* tstacknext; // if not 0, points to the recently-used tstack buffer, whose chain field points to tstacknext
A* tstackcurr; // current allocation, holding NTSTACK bytes+1 block for alignment. First entry points to next-lower allocation
A* tstacknext; // if not 0, points to the recently-used tstack buffer, whose chain field points to tstacknext $
A* tstackcurr; // current allocation, holding NTSTACK bytes+1 block for alignment. First entry points to next-lower allocation $
D cctdefault; /* default complementary comparison tolerance */
#if !(C_CRC32C && SY_64)
UIL ctmask; /* 1 iff significant wrt ct; for i. and i: */
Expand Down
8 changes: 4 additions & 4 deletions jsrc/m.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ B jtmeminit(J jt){I k,m=MLEN;
#else
#define AUDITFILL
#endif
void jtauditmemchains(J jt){
void jtauditmemchains(J jt){F1PREFIP;
#if MEMAUDIT&16
I Wi,Wj;A Wx,prevWx=0; if(jt->peekdata){for(Wi=PMINL;Wi<=PLIML;++Wi){Wj=0; Wx=(jt->mfree[-PMINL+Wi].pool); while(Wx){if(FHRHPOOLBIN(AFHRH(Wx))!=(Wi-PMINL)AUDITFILL||Wj>0x10000000)SEGFAULT; prevWx=Wx; Wx=AFCHAIN(Wx); ++Wj;}}}
#endif
Expand Down Expand Up @@ -404,11 +404,11 @@ R num(0);

// Verify that block w does not appear on tstack more than lim times
// nextpushp might start out on a boundary
void audittstack(J jt){
void audittstack(J jt){F1PREFIP;
#if BW==64 && MEMAUDIT&2
if(jt->audittstackdisabled&1)R;
A *ttop;
A *nvrav=IAV1(jt->nvra);
A *nvrav=AAV1(jt->nvra);
// verify counts start clear
for(ttop=jt->tnextpushp-!!((I)jt->tnextpushp&(NTSTACKBLOCK-1));ttop;){
// loop through each entry, skipping the first which is a chain
Expand Down Expand Up @@ -689,7 +689,7 @@ I jtgc3(J jt,A *x,A *y,A *z,A* old){
}

// subroutine version of ra without rifv to save space
static A raonlys(AD * RESTRICT w) { ARGCHK1(w);
static A raonlys(AD * RESTRICT w) { RZ(w);
#if AUDITEXECRESULTS
if(AFLAG(w)&(AFVIRTUAL|AFUNINCORPABLE))SEGFAULT;
#endif
Expand Down
4 changes: 3 additions & 1 deletion jsrc/result.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,9 @@ do{
// but never an output from the block it is created in, since it changes during the loop. Thus, UNINCORPABLEs are found only in the loop that created them.
// It might be better to keep the result recursive and transfer ownership of the virtual block, but not by much.
if(AFLAG(z)&AFUNINCORPABLE){RZ(z=clonevirtual(z));}
// since we are adding the block to a NONrecursive boxed result, we DO NOT have to raise the usecount of the block. We set the usecount non-inplaceable because
// since we are adding the block to a NONrecursive boxed result, we DO NOT have to raise the usecount of the block, but we do have to mark the block
// non-inplaceable, because the next thing to open it might be each: each will set the inplaceable flag if the parent is abandoned, so as to allow
// pristinity of lower results; thus we may not relax the rule that all contents must be non-inplaceable
// box code all over assumes that contents are never inplaceable, and since we go through here only when we are going through box code next, we honor that
ACIPNO(z); *zzboxp=z; // install the new box. zzboxp is ALWAYS a pointer to a box when force-boxed result
if(unlikely((ZZFLAGWORD&ZZFLAGCOUNTITEMS)!=0)){
Expand Down
2 changes: 1 addition & 1 deletion jsrc/sn.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ F1(jtex){A*wv,y,z;B*zv;I i,n;L*v;I modifierchg=0;
AAV1(nvra)[jt->parserstackframe.nvrtop++] = v->val; // record the place where the value was protected; it will be freed when this sentence finishes
AFLAG(v->val) |= AFNVR|AFNVRUNFREED; // mark the value as protected
}
if(AFLAG(v->val)&AFNVRUNFREED){AFLAG(v->val)&=~AFNVRUNFREED; ras(v->val);} // indicate deferred free, and protect from the upcoming free; but if already deferred-free, reduce the usecount now
if(AFLAG(v->val)&AFNVRUNFREED){ras(v->val); AFLAG(v->val)&=~AFNVRUNFREED;} // indicate deferred free, and protect from the upcoming free; but if already deferred-free, reduce the usecount now
}
if(!(v->name->flag&NMDOT)&&v->val&&AT(v->val)&(VERB|ADV|CONJ))modifierchg=1; // if we delete a modifier, remember that fact
probedel(NAV(v->name)->m,NAV(v->name)->s,NAV(v->name)->hash,locfound); // delete the symbol (incl name and value) in the locale in which it is defined
Expand Down
2 changes: 1 addition & 1 deletion jsrc/v.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ F1(jtravel){A a,c,q,x,y,y0,z;B*b;I f,j,m,r,*u,*v,*yv;P*wp,*zp;
}

F1(jttable){A z,zz;I r,wr;
ARGCHK1(w);F1PREFIP;
F1PREFIP;ARGCHK1(w);
// We accept the pristine calculations from ravel
wr=AR(w); r=(RANKT)jt->ranks; r=wr<r?wr:r; // r=rank to use
RZ(IRSIP1(w,0L,r-1<0?0:r-1,jtravel,z)); // perform ravel on items
Expand Down
2 changes: 1 addition & 1 deletion jsrc/v1.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ static B eqvfl(I af,I wf,I m,I n,I k,D* RESTRICT av,D* RESTRICT wv,B* RESTRICT z

// Return 1 if a and w match, 0 if not
B jtequ(J jt,A a,A w){A x;
ARGCHK2(a,w);F2PREFIP; // allow inplace request - it has no effect
F2PREFIP;ARGCHK2(a,w); // allow inplace request - it has no effect
if(a==w)R 1;
if(unlikely((SPARSE&(AT(a)|AT(w)))!=0))if(AR(a)&&AR(w)){RZ(x=matchs(a,w)); R BAV(x)[0];}
R ((B (*)())jtmatchsub)(jt,a,w,0 MATCHSUBDEFAULTS); // don't check level - it takes too long for big arrays
Expand Down
7 changes: 3 additions & 4 deletions jsrc/va1.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ static A jtva1s(J jt,A w,A self,I cv,VA1F ado){A e,x,z,ze,zx;B c;I n,oprc,t,zt;P

static A jtva1(J jt,A w,A self){A z;I cv,n,t,wt,zt;VA1F ado;
UA *u=(UA *)FAV(self)->localuse.lvp[1];
ARGCHK1(w);F1PREFIP;
F1PREFIP;ARGCHK1(w);
wt=AT(w); n=AN(w); wt=(I)jtinplace&JTEMPTY?B01:wt;
#if SY_64
VA1 *p=&u->p1[(0x0321000054032100>>(CTTZ(wt)<<2))&7]; // from MSB, we need xxx 011 010 001 xxx 000 xxx xxx 101 100 xxx 011 010 001 xxx 000
Expand Down Expand Up @@ -204,8 +204,7 @@ static A jtva1(J jt,A w,A self){A z;I cv,n,t,wt,zt;VA1F ado;
// Consolidated entry point for ATOMIC1 verbs.
// This entry point supports inplacing
DF1(jtatomic1){A z;
ARGCHK1(w);
F1PREFIP;
F1PREFIP;ARGCHK1(w);
I awm1=AN(w)-1;
// check for singletons
if(!(awm1|(AT(w)&(NOUN&UNSAFE(~(B01+INT+FL)))))){ // len=1 andbool/int/float
Expand All @@ -224,4 +223,4 @@ DF1(jtatomic1){A z;
}
}

DF1(jtpix ){ARGCHK1(w); F1PREFIP; if(XNUM&AT(w)&&(jt->xmode==XMFLR||jt->xmode==XMCEIL))R jtatomic1(jtinplace,w,self); R jtatomic2(jtinplace,pie,w,ds(CSTAR));}
DF1(jtpix ){F1PREFIP; ARGCHK1(w); if(XNUM&AT(w)&&(jt->xmode==XMFLR||jt->xmode==XMCEIL))R jtatomic1(jtinplace,w,self); R jtatomic2(jtinplace,pie,w,ds(CSTAR));}
Loading

0 comments on commit 98b404c

Please sign in to comment.