57 internal void Add(
int store)
59 for (
int i = 0; i <
count; i++)
65 var newarray =
new int[data.Length * 2];
66 Buffer.BlockCopy(
data, 0, newarray, 0,
data.Length * 4);
80 internal int this[
int index] =>
data[index];
82 internal int Count =>
count;
84 internal static void MarkShared(LocalStoreSites[] localStoreSites)
86 for (
int i = 0; i < localStoreSites.Length; i++)
87 localStoreSites[i].
shared =
true;
106 internal bool _changed =
true;
108 internal bool _initialized =
false;
122 _context = context ??
throw new ArgumentNullException(nameof(context));
141 _context = context ??
throw new ArgumentNullException(nameof(context));
143 _stack =
new RuntimeJavaType[maxStack];
145 _locals =
new RuntimeJavaType[maxLocals];
164 if (_initialized ==
false)
165 throw new InvalidOperationException();
173 target._changed =
true;
174 target._initialized = _initialized;
184 copy._flags &= ~ShareFlags.Stack;
197 if (s1._initialized ==
false)
201 throw new VerifyError($
"Inconsistent stack height: {s1._stackLen + s1._stack.Length - s1._stackEnd} != {s2._stackLen + s2._stack.Length - s2._stackEnd}");
204 s._changed = s1._changed;
206 for (
int i = 0; i < s._stackLen; i++)
208 var type1 = s._stack[i];
218 s.StackCopyOnWrite();
227 s.StackCopyOnWrite();
232 else if (!type1.IsPrimitive)
234 var baseType = FindCommonBaseType(s1.
_context, type1, type2);
236 throw new VerifyError(
string.Format(
"cannot merge {0} and {1}", type1.Name, type2.Name));
238 if (type1 != baseType)
240 s.StackCopyOnWrite();
241 s._stack[i] = baseType;
247 throw new VerifyError(
string.Format(
"cannot merge {0} and {1}", type1.Name, type2.Name));
251 for (
int i = 0; i < s._locals.Length; i++)
253 var type = s._locals[i];
255 var baseType = FindCommonBaseType(s1.
_context, type, type2);
256 if (type != baseType)
258 s.LocalsCopyOnWrite();
259 s._locals[i] = baseType;
266 s._uninitializedThis =
true;
273 internal void SetUnitializedThis(
bool state)
278 internal void CheckUninitializedThis()
281 throw new VerifyError(
"Base class constructor wasn't called");
284 internal static RuntimeJavaType FindCommonBaseType(RuntimeContext context, RuntimeJavaType type1, RuntimeJavaType type2)
291 if (type1 == context.JavaBase.TypeOfJavaLangObject || type2 == context.JavaBase.TypeOfJavaLangObject)
292 return context.JavaBase.TypeOfJavaLangObject;
295 if (type1 == context.VerifierJavaTypeFactory.Null)
299 if (type2 == context.VerifierJavaTypeFactory.Null)
303 if (type1 == context.VerifierJavaTypeFactory.Invalid || type2 == context.VerifierJavaTypeFactory.Invalid)
304 return context.VerifierJavaTypeFactory.Invalid;
306 if (RuntimeVerifierJavaType.IsFaultBlockException(type1))
308 RuntimeVerifierJavaType.ClearFaultBlockException(type1);
309 return FindCommonBaseType(context, context.JavaBase.TypeOfjavaLangThrowable, type2);
312 if (RuntimeVerifierJavaType.IsFaultBlockException(type2))
314 RuntimeVerifierJavaType.ClearFaultBlockException(type2);
315 return FindCommonBaseType(context, type1, context.JavaBase.TypeOfjavaLangThrowable);
319 if (type1.IsPrimitive || type2.IsPrimitive)
320 return context.VerifierJavaTypeFactory.Invalid;
323 if (type1 == context.VerifierJavaTypeFactory.UninitializedThis || type2 == context.VerifierJavaTypeFactory.UninitializedThis)
324 return context.VerifierJavaTypeFactory.Invalid;
327 if (RuntimeVerifierJavaType.IsNew(type1) || RuntimeVerifierJavaType.IsNew(type2))
328 return context.VerifierJavaTypeFactory.Invalid;
331 if (RuntimeVerifierJavaType.IsThis(type1))
332 type1 = ((RuntimeVerifierJavaType)type1).UnderlyingType;
335 if (RuntimeVerifierJavaType.IsThis(type2))
336 type2 = ((RuntimeVerifierJavaType)type2).UnderlyingType;
339 if (type1.IsUnloadable || type2.IsUnloadable)
340 return context.VerifierJavaTypeFactory.Unloadable;
343 if (type1.ArrayRank > 0 && type2.ArrayRank > 0)
346 int rank1 = type1.ArrayRank - 1;
347 int rank2 = type2.ArrayRank - 1;
348 var elem1 = type1.ElementTypeWrapper;
349 var elem2 = type2.ElementTypeWrapper;
350 while (rank1 != 0 && rank2 != 0)
352 elem1 = elem1.ElementTypeWrapper;
353 elem2 = elem2.ElementTypeWrapper;
363 RuntimeJavaType baseType;
364 if (elem1.IsPrimitive || elem2.IsPrimitive || elem1.IsNonPrimitiveValueType || elem2.IsNonPrimitiveValueType)
366 baseType = context.JavaBase.TypeOfJavaLangObject;
377 return baseType.MakeArrayType(rank);
396 if (type1.IsInterface && type2.IsInterface)
397 return context.
JavaBase.TypeOfJavaLangObject;
400 if (type1.IsInterface)
401 return type2.ImplementsInterface(type1) ? type1 : context.
JavaBase.TypeOfJavaLangObject;
404 if (type2.IsInterface)
405 return type1.ImplementsInterface(type2) ? type2 : context.
JavaBase.TypeOfJavaLangObject;
408 while (type1 !=
null)
411 type1 = type1.BaseTypeWrapper;
415 while (type2 !=
null)
418 type2 = type2.BaseTypeWrapper;
422 var type = context.
JavaBase.TypeOfJavaLangObject;
425 type1 = st1.Count > 0 ? st1.Pop() :
null;
426 type2 = st2.Count > 0 ? st2.Pop() :
null;
444 catch (IndexOutOfRangeException)
446 throw new VerifyError(
"Illegal local variable number");
461 catch (IndexOutOfRangeException)
463 throw new VerifyError(
"Illegal local variable number");
467 internal void GetLocalInt(
int index)
473 internal void SetLocalInt(
int index,
int instructionIndex)
478 internal void GetLocalLong(
int index)
481 throw new VerifyError(
"incorrect local type, not long");
484 internal void SetLocalLong(
int index,
int instructionIndex)
489 internal void GetLocalFloat(
int index)
492 throw new VerifyError(
"incorrect local type, not float");
495 internal void SetLocalFloat(
int index,
int instructionIndex)
500 internal void GetLocalDouble(
int index)
503 throw new VerifyError(
"incorrect local type, not double");
506 internal void SetLocalDouble(
int index,
int instructionIndex)
511 internal RuntimeJavaType GetLocalType(
int index)
517 catch (IndexOutOfRangeException)
519 throw new VerifyError(
"Illegal local variable number");
526 internal RuntimeJavaType GetLocalTypeEx(
int index)
531 internal void SetLocalType(
int index, RuntimeJavaType type,
int instructionIndex)
533 if (type.IsWidePrimitive)
539 internal void PushType(RuntimeJavaType type)
541 if (type.IsIntOnStackPrimitive)
547 internal void PushInt()
552 internal void PushLong()
557 internal void PushFloat()
562 internal void PushExtendedFloat()
567 internal void PushDouble()
572 internal void PushExtendedDouble()
577 internal void PopInt()
579 PopIntImpl(PopAnyType());
582 internal static void PopIntImpl(RuntimeJavaType type)
584 if (type != type.Context.PrimitiveJavaTypeFactory.INT)
588 internal bool PopFloat()
590 var tw = PopAnyType();
595 internal static void PopFloatImpl(RuntimeJavaType tw)
597 if (tw != tw.Context.PrimitiveJavaTypeFactory.FLOAT && tw != tw.Context.VerifierJavaTypeFactory.ExtendedFloat)
601 internal bool PopDouble()
603 var tw = PopAnyType();
608 internal static void PopDoubleImpl(RuntimeJavaType tw)
610 if (tw != tw.Context.PrimitiveJavaTypeFactory.DOUBLE && tw != tw.Context.VerifierJavaTypeFactory.ExtendedDouble)
614 internal void PopLong()
616 PopLongImpl(PopAnyType());
619 internal static void PopLongImpl(RuntimeJavaType tw)
621 if (tw != tw.Context.PrimitiveJavaTypeFactory.LONG)
627 internal RuntimeJavaType PopArrayType()
629 return PopArrayTypeImpl(PopAnyType());
632 internal static RuntimeJavaType PopArrayTypeImpl(RuntimeJavaType type)
634 if (!RuntimeVerifierJavaType.IsNullOrUnloadable(type) && type.ArrayRank == 0)
635 throw new VerifyError(
"Array reference expected on stack");
641 internal RuntimeJavaType PopObjectType()
643 return PopObjectTypeImpl(PopType());
646 internal static RuntimeJavaType PopObjectTypeImpl(RuntimeJavaType type)
648 if (type.IsPrimitive || RuntimeVerifierJavaType.IsNew(type) || type == type.Context.VerifierJavaTypeFactory.UninitializedThis)
649 throw new VerifyError(
"Expected object reference on stack");
655 internal RuntimeJavaType PopObjectType(RuntimeJavaType baseType)
657 return PopObjectTypeImpl(baseType, PopObjectType());
660 internal static RuntimeJavaType PopObjectTypeImpl(RuntimeJavaType baseType, RuntimeJavaType type)
664 if (!baseType.IsUnloadable && !baseType.IsInterfaceOrInterfaceArray && !(type.IsUnloadable || type.IsAssignableTo(baseType)))
665 throw new VerifyError(
"Unexpected type " + type.Name +
" where " + baseType.Name +
" was expected");
670 internal RuntimeJavaType PeekType()
673 throw new VerifyError(
"Unable to pop operand off an empty stack");
678 internal void MultiPopAnyType(
int count)
684 internal RuntimeJavaType PopFaultBlockException()
689 internal RuntimeJavaType PopAnyType()
692 throw new VerifyError(
"Unable to pop operand off an empty stack");
698 if (RuntimeVerifierJavaType.IsThis(type))
699 type = ((RuntimeVerifierJavaType)type).UnderlyingType;
701 if (RuntimeVerifierJavaType.IsFaultBlockException(type))
703 RuntimeVerifierJavaType.ClearFaultBlockException(type);
711 internal RuntimeJavaType PopType()
713 return PopTypeImpl(PopAnyType());
716 internal static RuntimeJavaType PopTypeImpl(RuntimeJavaType type)
718 if (type.IsWidePrimitive || type == type.Context.VerifierJavaTypeFactory.ExtendedDouble)
719 throw new VerifyError(
"Attempt to split long or double on the stack");
727 internal RuntimeJavaType PopType(RuntimeJavaType baseType)
729 return PopTypeImpl(baseType, PopAnyType());
732 internal static RuntimeJavaType PopTypeImpl(RuntimeJavaType baseType, RuntimeJavaType type)
734 if (baseType.IsIntOnStackPrimitive)
735 baseType = baseType.Context.PrimitiveJavaTypeFactory.INT;
737 if (RuntimeVerifierJavaType.IsNew(type) || type == type.Context.VerifierJavaTypeFactory.UninitializedThis)
738 throw new VerifyError(
"Expecting to find object/array on stack");
740 if (type == baseType)
743 if (type == baseType.Context.VerifierJavaTypeFactory.ExtendedDouble && baseType == baseType.Context.PrimitiveJavaTypeFactory.DOUBLE)
746 if (type == baseType.Context.VerifierJavaTypeFactory.ExtendedFloat && baseType == baseType.Context.PrimitiveJavaTypeFactory.FLOAT)
749 if (type.IsPrimitive ==
false && baseType.IsPrimitive ==
false)
751 if (baseType == baseType.Context.JavaBase.TypeOfJavaLangObject)
754 if (type.IsUnloadable || baseType.IsUnloadable)
759 if (baseType.IsInterfaceOrInterfaceArray)
762 if (type.IsAssignableTo(baseType))
769 throw new VerifyError(
"Unexpected type " + type.Name +
" where " + baseType.Name +
" was expected");
775 for (RuntimeJavaType baseTypeWrapper; (baseTypeWrapper = tw.BaseTypeWrapper) !=
null; tw = baseTypeWrapper)
777 if (baseTypeWrapper.IsUnloadable)
779 tw.Context.StaticCompiler.IssueMissingTypeMessage(tw.TypeAsBaseType.BaseType);
787 internal int GetStackHeight()
792 internal RuntimeJavaType GetStackSlot(
int pos)
803 internal RuntimeJavaType GetStackSlotEx(
int pos)
808 internal RuntimeJavaType GetStackByIndex(
int index)
825 internal void MarkInitialized(RuntimeJavaType type, RuntimeJavaType initType,
int instructionIndex)
827 System.Diagnostics.Debug.Assert(type !=
null && initType !=
null);
829 for (
int i = 0; i <
_locals.Length; i++)
872 internal void ClearFaultBlockException()
RuntimePrimitiveJavaTypeFactory PrimitiveJavaTypeFactory
Gets the RuntimePrimitiveJavaTypeFactory associated with this instance of the runtime.
RuntimeVerifierJavaTypeFactory VerifierJavaTypeFactory
Gets the RuntimeVerifierJavaTypeFactory associated with this instance of the runtime.