Skip to content

Commit e62eafe

Browse files
committed
<@:(<&f) bug when f returns a pyx
1 parent 72e0ca6 commit e62eafe

File tree

6 files changed

+36
-21
lines changed

6 files changed

+36
-21
lines changed

jsrc/j.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ struct jtimespec jmtfclk(void); //'fast clock'; maybe less inaccurate; intended
738738

739739
// Use MEMAUDIT to sniff out errant memory alloc/free
740740
#ifndef MEMAUDIT
741-
#define MEMAUDIT 0x0 // Bitmask for memory audits:
741+
#define MEMAUDIT 0x00 // Bitmask for memory audits:
742742
// 1: make sure chains are valid (check headers)
743743
// 2: full audit of tpush/tpop
744744
// detect double-frees before they happen,

jsrc/m.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -216,17 +216,17 @@ B jtmeminitt(JJ jt){I k;
216216
R 1;}
217217

218218
// Audit all memory chains to detect overrun
219-
#if SY_64
220-
#define AUDITFILL ||((MEMAUDIT&0x4)?AC(Wx)!=(I)0xdeadbeefdeadbeefLL:0)
219+
#if SY_64 // define optional audits.
220+
#define AUDITFILL // obsolete ||((MEMAUDIT&0x4)?AM(Wx)!=(I)0xdeadbeefdeadbeefLL:0)
221221
#else
222-
#define AUDITFILL ||((MEMAUDIT&0x4)?AC(Wx)!=(I)0xdeadbeefL:0)
222+
#define AUDITFILL // obsolete ||((MEMAUDIT&0x4)?AM(Wx)!=(I)0xdeadbeefL:0)
223223
#endif
224224
// your code for which the warning gets suppressed
225225
void jtauditmemchains(J jt){
226226
#if MEMAUDIT&0x30
227227
F1PREFIP; I Wi,Wj;A Wx,prevWx=0; forcetomemory(&prevWx); if((MEMAUDITPCALLENABLE)&&((MEMAUDIT&0x20)||JT(jt,peekdata))){
228228
for(Wi=PMINL;Wi<=PLIML;++Wi){Wj=0; Wx=(jt->mempool[-PMINL+Wi]);
229-
NOUNROLL while(Wx){if(FHRHPOOLBIN(AFHRH(Wx))!=(Wi-PMINL)AUDITFILL||Wj>0x10000000)SEGFAULT; prevWx=Wx; Wx=AFCHAIN(Wx); ++Wj;}}
229+
NOUNROLL while(Wx){if(Wx->origin!=THREADID1(jt)||FHRHPOOLBIN(AFHRH(Wx))!=(Wi-PMINL)AUDITFILL||Wj>0x10000000)SEGFAULT; prevWx=Wx; Wx=AFCHAIN(Wx); ++Wj;}}
230230
}
231231
#endif
232232
}

jsrc/result.h

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,15 @@ do{
252252
}while(1);
253253
}
254254
}else{
255-
// forced-boxed result. Must not be sparse. The result box is recursive to begin with, unless WILLBEOPENED is set
255+
// forced-boxed result. Must not be sparse. The result box is recursive to begin with, unless WILLBEOPENED is set. Wrecks are impossible
256256
ASSERT(!ISSPARSE(AT(z)),EVNONCE);
257257
// If z is DIRECT inplaceable, it must be unique and we can inherit them into a pristine result. Otherwise clear pristinity
258258
ZZFLAGWORD&=((AC(z)>>(BW-AFPRISTINEX))&(-(AT(z)&DIRECT)))|~ZZFLAGPRISTINE;
259259
if(likely(ZZWILLBEOPENEDNEVER||!(ZZFLAGWORD&ZZFLAGWILLBEOPENED))) {
260260
// normal case where we are creating the result box. Must incorp the result. Can't see an advantage is storing the virtual temporarily, and that would require testing for UNINCORP block
261261
realizeifvirtual(z); razaptstackend(z); // Since we are moving the result into a recursive box, we must ra() it. This plus rifv plus pristine flagging (above) =INCORPRA. We trouble to see if we can shorten tstack, since that is likely
262262
*zzboxp=z; // install the new box. zzboxp is ALWAYS a pointer to a box when force-boxed result
263-
} else {
263+
}else{
264264
// The result of this verb will be opened next, so we can take some liberties with it. We don't need to realize any virtual block EXCEPT one that we might
265265
// be reusing in this loop. The user flags those UNINCORPABLE. Rather than realize it we just make a virtual clone, since realizing might be expensive.
266266
// That is, if z is one of the virtual blocks we use to track subarrays, we mustn't incorporate it, so we clone it. These subarrays can be inputs to functions
@@ -273,21 +273,20 @@ do{
273273
// 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
274274
ACIPNO(z); *zzboxp=z; // install the new box. zzboxp is ALWAYS a pointer to a box when force-boxed result
275275
if(unlikely((ZZFLAGWORD&ZZFLAGCOUNTITEMS)!=0)){
276-
// if the result will be razed next, we will count the items and store that in AM. We will also ensure that the result boxes' contents have the same type
276+
// the result will be razed next. We will count the items and store that in AM. We will also ensure that the result boxes' contents have the same type
277277
// and item-shape. If one does not, we turn off special raze processing. It is safe to take over the AM field in this case, because we know this is WILLBEOPENED and
278278
// (1) will never assemble or epilog; (2) will feed directly into a verb that will discard it without doing any usecount modification
279-
I diff; // Will be set to 0 if we are unable to report the # items
279+
I diff; // Will be set to non0 if we are unable to report the # items
280280
#if PYXES
281281
// If the returned result is a pyx, we can't look into it to get its type/len. We could see if the pyx has been resolved, but we don't
282-
if(unlikely(diff=(AT(z)&PYX))){ZZFLAGWORD&=~ZZFLAGCOUNTITEMS; // if the result is a pyx, which can't be inspected, skip it, which makes the item count invalid
283-
}else{
284-
#else
285-
{
282+
if(likely((diff=(AT(z)&PYX))==0)) // if the result is a pyx, which can't be inspected, set diff to non0 (which makes the item count invalid) and skip the shape test
286283
#endif
284+
{ // this brace may be part of the previous line!
285+
// not a pyx - we can count the items
287286
#if !ZZSTARTATEND // going forwards
288-
A result0=AAV(zz)[0]; // fetch pointer to the first
287+
A result0=AAV(zz)[0]; // fetch pointer to the first
289288
#else
290-
A result0=AAV(zz)[AN(zz)-1]; // fetch pointer to first value stored, which is in the last position
289+
A result0=AAV(zz)[AN(zz)-1]; // fetch pointer to first value stored, which is in the last position
291290
#endif
292291
// see if the items of the new match the old, and increment the number of items
293292
I* zs=AS(z); I* ress=AS(result0); I zr=AR(z); I resr=AR(result0); //fetch info
@@ -296,7 +295,7 @@ do{
296295
I nitems=zs[0]; nitems=(zr==0)?1:nitems; zzcounteditems+=nitems; // add new items to count in zz. zs[0] will never segfault, even if z is empty
297296
#endif
298297
}
299-
ZZFLAGWORD^=(diff!=0)<<ZZFLAGCOUNTITEMSX; // turn off bit if we can't say the items are homogeneous
298+
ZZFLAGWORD^=(diff!=0)<<ZZFLAGCOUNTITEMSX; // turn off bit (which must be set now) if we can't say the items are homogeneous
300299
}
301300
// Note: by checking COUNTITEMS inside WILLBEOPENED we suppress support for COUNTITEMS in \. which sets WILLBEOPENEDNEVER. It would be safe to
302301
// count then, because no virtual contents would be allowed. But we are not sure that the EPILOG is safe, and this path is now off to the side
@@ -316,8 +315,9 @@ do{
316315
// Processing the first cell. Allocate the result area now that we know the shape/type of the result.
317316
// Get the rank/type to allocate for the presumed result
318317
// Get the type to allocate
319-
I natoms=AN(z); // number of atoms per result cell
320-
I zzt=AT(z); I zzr=AR(z); zzt=(ZZASSUMEBOXATOP||ZZFLAGWORD&ZZFLAGBOXATOP)?BOX:zzt; zzr=(ZZASSUMEBOXATOP||ZZFLAGWORD&ZZFLAGBOXATOP)?0:zzr; natoms=(ZZASSUMEBOXATOP||ZZFLAGWORD&ZZFLAGBOXATOP)?1:natoms;
318+
I natoms=AN(z); I zzt=AT(z); I zzr=AR(z); // number of atoms per result cell; type and rank of first result cell
319+
// Type of zz is that of z, except for BOXATOP: then it's BOX. The value can be a pyx only if BOXATOP is set, so we know zz can't itself be a pyx
320+
zzt=(ZZASSUMEBOXATOP||ZZFLAGWORD&ZZFLAGBOXATOP)?BOX:zzt; zzr=(ZZASSUMEBOXATOP||ZZFLAGWORD&ZZFLAGBOXATOP)?0:zzr; natoms=(ZZASSUMEBOXATOP||ZZFLAGWORD&ZZFLAGBOXATOP)?1:natoms;
321321
zzcelllen=natoms<<bplg(zzt); // number of bytes in one cell.
322322
JMCSETMASK(zzendmask,zzcelllen,ZZSTARTATEND) // set mask for JMCR
323323

jsrc/viavx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1128,7 +1128,7 @@ A jtindexofsub(J jt,I mode,A a,A w){F2PREFIP;PROLOG(0079);A h=0;fauxblockINT(zfa
11281128
RZ(z=EPILOGNORET(z));
11291129
// Since EPILOG may have rewritten AM, and IFORKEY never returns to the parser, we can store the FORKEY result in AM.
11301130
*((mode&IIOPMSK)==IFORKEY?(I*)&AM(z):(I*)&jt->shapesink)=forkeyresult;
1131-
RETF(z);
1131+
R z; // Not RETF, which may audit the AM field which we just modified
11321132
} /* a i."r w main control */
11331133

11341134
// verb to vector combine@e. compounds. The i. code is in the self

test/gtdot4.ijs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,22 @@ stime =: 6!:1''
3030
stime =: 6!:1''
3131
1 = > 6!:3 t. 1"0 ] 6 # 1
3232
(5-granularity) < stime -~ 6!:1''
33+
delth''
3334

35+
NB. Test mixtures of pyxes and non-pyxes
36+
1: 0 T. ''
37+
1: 0 T. ''
38+
1: 0 T. ''
39+
1: 0 T. '' NB. create threads
40+
41+
a =: i.&.> (20 ?@$ 10)
42+
(;a) -: ; (0.30 > (#a) ?@$ 0) >@] t.'worker'^:["0 a
43+
(;a) -: ; >@] t.'worker'"0 a
44+
(;a) -: ;@:((0.30 > (#a) ?@$ 0) >@] t.'worker'^:["0 ]) a
45+
(;a) -: ;@:(>@] t.'worker'"0) a
46+
47+
48+
delth''
3449
4!:55 ;:'delth granularity stime'
3550

3651
epilog''

test/tsu.ijs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ blacklist=: ((<testpath),each 'gmbx.ijs';'gfft.ijs';'glapack.ijs'),testfiles 'gm
5050
blacklist=: blacklist, (-. (<UNAME)e.<'Darwin')#(<testpath),each <'gcip1.ijs'
5151
blacklist=: blacklist, (IFRASPI<(IF64<UNAME-:'Linux')+.(IFWIN>IF64)+.IFIOS+.(UNAME-:'Wasm'))#(<testpath),each <'gregex.ijs' NB. require libjpcre2 binary
5252
blacklist=: blacklist, (-.IF64)#(<testpath),each <'g6x14.ijs' NB. require 64-bit
53-
blacklist=: blacklist, (1=1 { 8 T. '')#(<testpath),each 'gtdot.ijs';'gtdot1.ijs';'gtdot2.ijs';'gtdot3.ijs';'gtdot4.ijs' NB. require multithreading
53+
blacklist=: blacklist, (1=1 { 8 T. '')#(<testpath),each 'gtdot.ijs';'gtdot1.ijs';'gtdot2.ijs';'gtdot3.ijs';'gtdot4.ijs';'gtdot5.ijs' NB. require multithreading
5454
blacklist=: blacklist, (-.15!:23'')#(<testpath),each 'g15x.ijs';'g7x5.ijs';'gdll.ijs';'gdll_df.ijs';'gmmf.ijs';'gmmf1s.ijs';'gmmf1u.ijs';'gmmf1w.ijs' NB. 15!:0 unavailable
5555
blacklist=: blacklist, ('Wasm'-:UNAME)#(<testpath),each <'gstack.ijs' NB. crash
5656
blacklist=: blacklist, (IFQT*.'Wasm'-:UNAME)#(<testpath),each 'g331ps.ijs';'gsp422.ijs';'gsp432.ijs' NB. crash
@@ -475,7 +475,7 @@ allorcmdline=: 3 :0
475475
NB. fail
476476
end.
477477
else.
478-
ddall-.((testpath,'g') , ,&'.ijs')&.>;:'131 cip 520 sp 7x tdot1 3x tdot2 tdot3 tdot4 tdot t' NB. temporarily ignore threading
478+
ddall-.((testpath,'g') , ,&'.ijs')&.>;:'131 cip 520 sp 7x tdot1 3x tdot2 tdot3 tdot4 tdot5 tdot t' NB. temporarily ignore threading
479479
end.
480480
)
481481

0 commit comments

Comments
 (0)