@@ -1863,27 +1863,48 @@ bool InitPop(InterpState &S, CodePtr OpPC) {
18631863template <PrimType Name, class T = typename PrimConv<Name>::T>
18641864bool InitElem (InterpState &S, CodePtr OpPC, uint32_t Idx) {
18651865 const T &Value = S.Stk .pop <T>();
1866- const Pointer &Ptr = S.Stk .peek <Pointer>().atIndex (Idx);
1866+ const Pointer &Ptr = S.Stk .peek <Pointer>();
1867+
18671868 if (Ptr.isUnknownSizeArray ())
18681869 return false ;
1869- if (!CheckInit (S, OpPC, Ptr))
1870+
1871+ // In the unlikely event that we're initializing the first item of
1872+ // a non-array, skip the atIndex().
1873+ if (Idx == 0 && !Ptr.getFieldDesc ()->isArray ()) {
1874+ Ptr.initialize ();
1875+ new (&Ptr.deref <T>()) T (Value);
1876+ return true ;
1877+ }
1878+
1879+ const Pointer &ElemPtr = Ptr.atIndex (Idx);
1880+ if (!CheckInit (S, OpPC, ElemPtr))
18701881 return false ;
1871- Ptr .initialize ();
1872- new (&Ptr .deref <T>()) T (Value);
1882+ ElemPtr .initialize ();
1883+ new (&ElemPtr .deref <T>()) T (Value);
18731884 return true ;
18741885}
18751886
18761887// / The same as InitElem, but pops the pointer as well.
18771888template <PrimType Name, class T = typename PrimConv<Name>::T>
18781889bool InitElemPop (InterpState &S, CodePtr OpPC, uint32_t Idx) {
18791890 const T &Value = S.Stk .pop <T>();
1880- const Pointer &Ptr = S.Stk .pop <Pointer>(). atIndex (Idx) ;
1891+ const Pointer &Ptr = S.Stk .pop <Pointer>();
18811892 if (Ptr.isUnknownSizeArray ())
18821893 return false ;
1883- if (!CheckInit (S, OpPC, Ptr))
1894+
1895+ // In the unlikely event that we're initializing the first item of
1896+ // a non-array, skip the atIndex().
1897+ if (Idx == 0 && !Ptr.getFieldDesc ()->isArray ()) {
1898+ Ptr.initialize ();
1899+ new (&Ptr.deref <T>()) T (Value);
1900+ return true ;
1901+ }
1902+
1903+ const Pointer &ElemPtr = Ptr.atIndex (Idx);
1904+ if (!CheckInit (S, OpPC, ElemPtr))
18841905 return false ;
1885- Ptr .initialize ();
1886- new (&Ptr .deref <T>()) T (Value);
1906+ ElemPtr .initialize ();
1907+ new (&ElemPtr .deref <T>()) T (Value);
18871908 return true ;
18881909}
18891910
0 commit comments