Пример #1
0
        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);
        }