Creates a new state which is the merged combination of the two specified states.
196 {
197 if (s1._initialized == false)
198 return s2.Copy();
199
200 if (s1._stackLen != s2._stackLen || s1._stackEnd != s2._stackEnd)
201 throw new VerifyError($
"Inconsistent stack height: {s1._stackLen + s1._stack.Length - s1._stackEnd} != {s2._stackLen + s2._stack.Length - s2._stackEnd}");
202
203 var s = s1.Copy();
204 s._changed = s1._changed;
205
206 for (int i = 0; i < s._stackLen; i++)
207 {
208 var type1 = s._stack[i];
209 var type2 = s2._stack[i];
210 if (type1 == type2)
211 {
212
213 }
214 else if ((type1 == s1._context.VerifierJavaTypeFactory.ExtendedDouble && type2 == s1._context.PrimitiveJavaTypeFactory.DOUBLE) || (type2 == s1._context.VerifierJavaTypeFactory.ExtendedDouble && type1 == s1._context.PrimitiveJavaTypeFactory.DOUBLE))
215 {
216 if (type1 != s1._context.VerifierJavaTypeFactory.ExtendedDouble)
217 {
218 s.StackCopyOnWrite();
219 s._stack[i] = s1._context.VerifierJavaTypeFactory.ExtendedDouble;
220 s._changed = true;
221 }
222 }
223 else if ((type1 == s1._context.VerifierJavaTypeFactory.ExtendedFloat && type2 == s1._context.PrimitiveJavaTypeFactory.FLOAT) || (type2 == s1._context.VerifierJavaTypeFactory.ExtendedFloat && type1 == s1._context.PrimitiveJavaTypeFactory.FLOAT))
224 {
225 if (type1 != s1._context.VerifierJavaTypeFactory.ExtendedFloat)
226 {
227 s.StackCopyOnWrite();
228 s._stack[i] = s1._context.VerifierJavaTypeFactory.ExtendedFloat;
229 s._changed = true;
230 }
231 }
232 else if (!type1.IsPrimitive)
233 {
234 var baseType = FindCommonBaseType(s1._context, type1, type2);
235 if (baseType == s1._context.VerifierJavaTypeFactory.Invalid)
236 throw new VerifyError(
string.Format(
"cannot merge {0} and {1}", type1.Name, type2.Name));
237
238 if (type1 != baseType)
239 {
240 s.StackCopyOnWrite();
241 s._stack[i] = baseType;
242 s._changed = true;
243 }
244 }
245 else
246 {
247 throw new VerifyError(
string.Format(
"cannot merge {0} and {1}", type1.Name, type2.Name));
248 }
249 }
250
251 for (int i = 0; i < s._locals.Length; i++)
252 {
253 var type = s._locals[i];
254 var type2 = s2._locals[i];
255 var baseType = FindCommonBaseType(s1._context, type, type2);
256 if (type != baseType)
257 {
258 s.LocalsCopyOnWrite();
259 s._locals[i] = baseType;
260 s._changed = true;
261 }
262 }
263
264 if (!s._uninitializedThis && s2._uninitializedThis)
265 {
266 s._uninitializedThis = true;
267 s._changed = true;
268 }
269
270 return s;
271 }