public static bool CheckInvalidArrayCoersion(FunctionEndPoint fep, List <StackValue> reducedSVs, ClassTable classTable, Core core, bool allowArrayPromotion) { for (int i = 0; i < reducedSVs.Count; i++) { Type typ = fep.FormalParams[i]; if (typ.UID == (int)ProtoCore.PrimitiveType.kInvalidType) { return(true); } if (!typ.IsIndexable) { continue; //It wasn't an array param, skip } //Compute the type of target param if (!allowArrayPromotion) { Validity.Assert(StackUtils.IsArray(reducedSVs[i]), "This should be an array otherwise this shouldn't have passed previous tests"); } if (!allowArrayPromotion) { if (typ.rank != ArrayUtils.GetMaxRankForArray(reducedSVs[i], core) && typ.rank != DSASM.Constants.kArbitraryRank) { return(true); //Invalid co-ercsion } } else { if (typ.rank < ArrayUtils.GetMaxRankForArray(reducedSVs[i], core) && typ.rank != DSASM.Constants.kArbitraryRank) { return(true); //Invalid co-ercsion } } Dictionary <ClassNode, int> arrayTypes = ArrayUtils.GetTypeStatisticsForArray(reducedSVs[i], core); ClassNode cn = null; if (arrayTypes.Count == 0) { //This was an empty array Validity.Assert(cn == null, "If it was an empty array, there shouldn't be a type node"); cn = core.ClassTable.ClassNodes[(int)PrimitiveType.kTypeNull]; } else if (arrayTypes.Count == 1) { //UGLY, get the key out of the array types, of which there is only one foreach (ClassNode key in arrayTypes.Keys) { cn = key; } } else if (arrayTypes.Count > 1) { ClassNode commonBaseType = ArrayUtils.GetGreatestCommonSubclassForArray(reducedSVs[i], core); if (commonBaseType == null) { throw new ProtoCore.Exceptions.ReplicationCaseNotCurrentlySupported("Array with no common superclass not yet supported: {0C644179-14F5-4172-8EF8-A2F3739901B2}"); } cn = commonBaseType; //From now on perform tests on the commmon base type } ClassNode argTypeNode = classTable.ClassNodes[typ.UID]; //cn now represents the class node of the argument //argTypeNode represents the class node of the argument bool isNotExactTypeMatch = cn != argTypeNode; bool argumentsNotNull = cn != core.ClassTable.ClassNodes[(int)PrimitiveType.kTypeNull]; bool recievingTypeNotAVar = argTypeNode != core.ClassTable.ClassNodes[(int)PrimitiveType.kTypeVar]; bool isNotConvertible = !cn.ConvertibleTo(typ.UID); //bool isCalleeVar = cn == core.classTable.list[(int) PrimitiveType.kTypeVar]; //Is it an invalid conversion? if (isNotExactTypeMatch && argumentsNotNull && recievingTypeNotAVar && isNotConvertible) // && !isCalleeVar) { return(true); //It's an invalid coersion } } return(false); }