@@ -1863,27 +1863,48 @@ bool InitPop(InterpState &S, CodePtr OpPC) {
1863
1863
template <PrimType Name, class T = typename PrimConv<Name>::T>
1864
1864
bool InitElem (InterpState &S, CodePtr OpPC, uint32_t Idx) {
1865
1865
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
+
1867
1868
if (Ptr.isUnknownSizeArray ())
1868
1869
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))
1870
1881
return false ;
1871
- Ptr .initialize ();
1872
- new (&Ptr .deref <T>()) T (Value);
1882
+ ElemPtr .initialize ();
1883
+ new (&ElemPtr .deref <T>()) T (Value);
1873
1884
return true ;
1874
1885
}
1875
1886
1876
1887
// / The same as InitElem, but pops the pointer as well.
1877
1888
template <PrimType Name, class T = typename PrimConv<Name>::T>
1878
1889
bool InitElemPop (InterpState &S, CodePtr OpPC, uint32_t Idx) {
1879
1890
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>();
1881
1892
if (Ptr.isUnknownSizeArray ())
1882
1893
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))
1884
1905
return false ;
1885
- Ptr .initialize ();
1886
- new (&Ptr .deref <T>()) T (Value);
1906
+ ElemPtr .initialize ();
1907
+ new (&ElemPtr .deref <T>()) T (Value);
1887
1908
return true ;
1888
1909
}
1889
1910
0 commit comments