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); }
public static StackValue PerformReturnTypeCoerce(FunctionEndPoint functionEndPoint, RuntimeCore runtimeCore, StackValue ret) { return PerformReturnTypeCoerce(functionEndPoint.procedureNode, runtimeCore, ret); }
public static bool CheckInvalidArrayCoersion(FunctionEndPoint fep, List<StackValue> reducedSVs, ClassTable classTable, RuntimeCore runtimeCore, 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(reducedSVs[i].IsArray, "This should be an array otherwise this shouldn't have passed previous tests"); if (!allowArrayPromotion) { if (typ.rank != ArrayUtils.GetMaxRankForArray(reducedSVs[i], runtimeCore) && typ.rank != DSASM.Constants.kArbitraryRank) return true; //Invalid co-ercsion } else { if (typ.rank < ArrayUtils.GetMaxRankForArray(reducedSVs[i], runtimeCore) && typ.rank != DSASM.Constants.kArbitraryRank) return true; //Invalid co-ercsion } Dictionary<ClassNode, int> arrayTypes = ArrayUtils.GetTypeStatisticsForArray(reducedSVs[i], runtimeCore); 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 = runtimeCore.DSExecutable.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], runtimeCore); if (commonBaseType == null) throw new ProtoCore.Exceptions.ReplicationCaseNotCurrentlySupported( string.Format(Resources.ArrayWithNotSupported, "{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 != runtimeCore.DSExecutable.classTable.ClassNodes[(int) PrimitiveType.kTypeNull]; bool recievingTypeNotAVar = argTypeNode != runtimeCore.DSExecutable.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; }
public StackValue ExecuteContinuation(FunctionEndPoint jilFep, StackFrame stackFrame, Core core) { // Pushing a dummy stackframe onto the Stack for the current fep int ci = -1; int fi = 0; // Hardcoded for Increment as member function if (jilFep.procedureNode == null) { ci = 14; jilFep.procedureNode = core.DSExecutable.classTable.ClassNodes[ci].vtable.procList[fi]; } Validity.Assert(jilFep.procedureNode != null); if (core.Options.IDEDebugMode) { DebugFrame debugFrame = core.DebugProps.DebugStackFrame.Peek(); debugFrame.FinalFepChosen = jilFep; } ProtoCore.DSASM.StackValue svThisPtr = stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kThisPtr); ProtoCore.DSASM.StackValue svBlockDecl = stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionBlock); int blockCaller = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionCallerBlock).opdata; int depth = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kStackFrameDepth).opdata; DSASM.StackFrameType type = (DSASM.StackFrameType)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kStackFrameType).opdata; int locals = 0; int returnAddr = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kReturnAddress).opdata; int framePointer = core.Rmem.FramePointer; DSASM.StackFrameType callerType = (DSASM.StackFrameType)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kCallerStackFrameType).opdata; StackValue svCallConvention = ProtoCore.DSASM.StackUtils.BuildNode(ProtoCore.DSASM.AddressType.CallingConvention, (long)ProtoCore.DSASM.CallingConvention.CallType.kExplicit); // Set TX register stackFrame.SetAt(DSASM.StackFrame.AbsoluteIndex.kRegisterTX, svCallConvention); // Set SX register stackFrame.SetAt(DSASM.StackFrame.AbsoluteIndex.kRegisterSX, svBlockDecl); List<ProtoCore.DSASM.StackValue> registers = new List<DSASM.StackValue>(); registers.AddRange(stackFrame.GetRegisters()); core.Rmem.PushStackFrame(svThisPtr, ci, fi, returnAddr, (int)svBlockDecl.opdata, blockCaller, callerType, type, depth, framePointer, registers, locals, 0); return StackUtils.BuildNode(AddressType.ExplicitCall, jilFep.procedureNode.pc); }