public StackValue Evaluate(List<StackValue> args, StackFrame stackFrame)
        {
            //
            // Build the stackframe
            int classScopeCaller = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kClass).opdata;
            int returnAddr = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kReturnAddress).opdata;
            int blockDecl = (int)mProcNode.runtimeIndex;
            int blockCaller = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionCallerBlock).opdata;
            int framePointer = mRunTime.runtime.Core.Rmem.FramePointer;
            StackValue thisPtr = StackUtils.BuildPointer(-1);

            // Comment Jun: the caller type is the current type in the stackframe
            StackFrameType callerType = (StackFrameType)stackFrame.GetAt(StackFrame.AbsoluteIndex.kStackFrameType).opdata;

            StackFrameType type = StackFrameType.kTypeFunction;
            int depth = 0;
            List<StackValue> registers = new List<StackValue>();

            // Comment Jun: Calling convention data is stored on the TX register
            StackValue svCallconvention = StackUtils.BuildNode(AddressType.CallingConvention, (long)ProtoCore.DSASM.CallingConvention.BounceType.kImplicit);
            mRunTime.runtime.TX = svCallconvention;

            StackValue svBlockDecl = StackUtils.BuildNode(AddressType.BlockIndex, blockDecl);
            mRunTime.runtime.SX = svBlockDecl;

            mRunTime.runtime.SaveRegisters(registers);
            ProtoCore.DSASM.StackFrame newStackFrame = new StackFrame(thisPtr, classScopeCaller, 1, returnAddr, blockDecl, blockCaller, callerType, type, depth, framePointer, registers);

            List<List<int>> replicationGuides = new List<List<int>>();
            if (mRunTime.runtime.Core.Options.IDEDebugMode && mRunTime.runtime.Core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                mRunTime.runtime.Core.DebugProps.SetUpCallrForDebug(mRunTime.runtime.Core, mRunTime.runtime, mProcNode, returnAddr - 1,
                    false, mCallSite, args, replicationGuides, newStackFrame);
            }

            StackValue rx = mCallSite.JILDispatchViaNewInterpreter(new Runtime.Context(), args, replicationGuides, newStackFrame, mRunTime.runtime.Core);

            if (mRunTime.runtime.Core.Options.IDEDebugMode && mRunTime.runtime.Core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                mRunTime.runtime.Core.DebugProps.RestoreCallrForNoBreak(mRunTime.runtime.Core, mProcNode);
            }

            return rx;
        }
Ejemplo n.º 2
0
        public override StackValue Execute(ProtoCore.Runtime.Context c, List <StackValue> formalParameters, ProtoCore.DSASM.StackFrame stackFrame, Core core)
        {
            ProtoCore.DSASM.Interpreter interpreter  = new ProtoCore.DSASM.Interpreter(core, true);
            ProtoCore.DSASM.Executive   oldDSASMExec = null;
            if (core.CurrentExecutive != null)
            {
                oldDSASMExec = core.CurrentExecutive.CurrentDSASMExec;
                core.CurrentExecutive.CurrentDSASMExec = interpreter.runtime;
            }

            // Assert for the block type
            activation.globs = core.DSExecutable.runtimeSymbols[core.RunningBlock].GetGlobalSize();

            // Push Execution states
            int execStateSize = 0;

            if (null != stackFrame.ExecutionStates)
            {
                execStateSize = stackFrame.ExecutionStates.Length;

                // ExecutionStates are in lexical order
                // Push them in reverse order (similar to args) so they can be retrieved in sequence
                // Retrieveing the executing states occur on function return
                for (int n = execStateSize - 1; n >= 0; --n)
                {
                    StackValue svState = stackFrame.ExecutionStates[n];
                    Validity.Assert(svState.IsBoolean);
                    interpreter.Push(svState);
                }
            }

            // Push Params
            formalParameters.Reverse();
            for (int i = 0; i < formalParameters.Count; i++)
            {
                interpreter.Push(formalParameters[i]);
            }

            StackValue svThisPtr   = stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kThisPtr);
            StackValue svBlockDecl = stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionBlock);

            // Jun: Make sure we have no empty or unaligned frame data
            Validity.Assert(DSASM.StackFrame.kStackFrameSize == stackFrame.Frame.Length);

            // Setup the stack frame data
            //int thisPtr = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kThisPtr).opdata;
            int ci           = activation.classIndex;
            int fi           = activation.funcIndex;
            int returnAddr   = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kReturnAddress).opdata;
            int blockDecl    = (int)svBlockDecl.opdata;
            int blockCaller  = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionCallerBlock).opdata;
            int framePointer = core.Rmem.FramePointer;
            int locals       = activation.locals;


            // Update the running block to tell the execution engine which set of instruction to execute
            // TODO(Jun/Jiong): Considering store the orig block id to stack frame
            int origRunningBlock = core.RunningBlock;

            core.RunningBlock = (int)svBlockDecl.opdata;

            // Set SX register
            interpreter.runtime.SX = svBlockDecl;

            DSASM.StackFrameType callerType = (DSASM.StackFrameType)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kCallerStackFrameType).opdata;

            List <StackValue> registers = new List <DSASM.StackValue>();

            StackValue svCallConvention;
            bool       isDispose = CoreUtils.IsDisposeMethod(procedureNode.name);

            bool explicitCall = !c.IsReplicating && !c.IsImplicitCall && !isDispose;

            if (explicitCall)
            {
                svCallConvention = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.CallType.kExplicit);
            }
            else
            {
                svCallConvention = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.CallType.kImplicit);
            }

            stackFrame.SetAt(DSASM.StackFrame.AbsoluteIndex.kRegisterTX, svCallConvention);
            interpreter.runtime.TX = svCallConvention;

            // Set SX register
            stackFrame.SetAt(DSASM.StackFrame.AbsoluteIndex.kRegisterSX, svBlockDecl);
            interpreter.runtime.SX = svBlockDecl;

            // TODO Jun:
            // The stackframe carries the current set of registers
            // Determine if this can be done even for the non explicit call implementation
            registers.AddRange(stackFrame.GetRegisters());


            // Comment Jun: the depth is always 0 for a function call as we are reseting this for each function call
            // This is only incremented for every language block bounce
            int depth = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kStackFrameDepth).opdata;

            DSASM.StackFrameType type = (DSASM.StackFrameType)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kStackFrameType).opdata;
            Validity.Assert(depth == 0);
            Validity.Assert(type == DSASM.StackFrameType.kTypeFunction);

            core.Rmem.PushStackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, type, depth, framePointer, registers, locals, execStateSize);


            StackValue svRet;

            if (explicitCall)
            {
                svRet = ProtoCore.DSASM.StackValue.BuildExplicitCall(activation.pc);
            }
            else
            {
                if (core.ExecMode != DSASM.InterpreterMode.kExpressionInterpreter && core.Options.IDEDebugMode)
                {
                    svRet = interpreter.Run(core.Breakpoints, core.RunningBlock, activation.pc, Language.kInvalid);
                }
                else
                {
                    svRet = interpreter.Run(core.RunningBlock, activation.pc, Language.kInvalid);
                }
                core.RunningBlock = origRunningBlock;
            }

            if (core.CurrentExecutive != null)
            {
                core.CurrentExecutive.CurrentDSASMExec = oldDSASMExec;
            }
            return(svRet); //DSASM.Mirror.ExecutionMirror.Unpack(svRet, core.heap, core);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Get a list of all the function end points that are type compliant, there maybe more than one due to pattern matches
        /// </summary>
        /// <returns></returns>
        public List<FunctionEndPoint> GetExactTypeMatches(ProtoCore.Runtime.Context context,
            List<StackValue> formalParams, List<ReplicationInstruction> replicationInstructions, StackFrame stackFrame, Core core)
        {
            List<FunctionEndPoint> ret = new List<FunctionEndPoint>();


            List<List<StackValue>> allReducedParamSVs = Replicator.ComputeAllReducedParams(formalParams, replicationInstructions, core);

            List<StackValue> reducedParamSVs = allReducedParamSVs[0];
            
            //@TODO(Luke): Need to add type statistics checks to the below if it is an array to stop int[] matching char[]
            


            //Now test the reduced Params over all of the available end points
            foreach (FunctionEndPoint fep in FunctionEndPoints)
            {
                if (fep.DoesTypeDeepMatch(reducedParamSVs, core))
                {
                    //// The first line checks if the lhs of a dot operation was a class name
                    //if (stackFrame.GetAt(StackFrame.AbsoluteIndex.kThisPtr).optype == AddressType.ClassIndex 
                    //    && !fep.procedureNode.isConstructor
                    //    && !fep.procedureNode.isStatic)

                    if ((stackFrame.GetAt(StackFrame.AbsoluteIndex.kThisPtr).optype == AddressType.Pointer &&
                        stackFrame.GetAt(StackFrame.AbsoluteIndex.kThisPtr).opdata == -1 && fep.procedureNode != null
                        && !fep.procedureNode.isConstructor) && !fep.procedureNode.isStatic
                        && (fep.procedureNode.classScope != -1))
                    {
                        continue;
                    }

                    ret.Add(fep);
                }

            }

            return ret;
        }
Ejemplo n.º 4
0
        private List<FunctionEndPoint> GetCandidateFunctions(StackFrame stackFrame,
                                                             Dictionary<FunctionEndPoint, int> candidatesWithDistances)
        {
            List<FunctionEndPoint> candidateFunctions = new List<FunctionEndPoint>();

            foreach (FunctionEndPoint fep in candidatesWithDistances.Keys)
            {
                // The first line checks if the lhs of a dot operation was a class name
                //if (stackFrame.GetAt(StackFrame.AbsoluteIndex.kThisPtr).IsClassIndex
                //    && !fep.procedureNode.isConstructor
                //    && !fep.procedureNode.isStatic)

                if ((stackFrame.GetAt(StackFrame.AbsoluteIndex.kThisPtr).IsPointer &&
                     stackFrame.GetAt(StackFrame.AbsoluteIndex.kThisPtr).opdata == -1 && fep.procedureNode != null
                     && !fep.procedureNode.isConstructor) && !fep.procedureNode.isStatic
                    && (fep.procedureNode.classScope != -1))
                {
                    continue;
                }

                candidateFunctions.Add(fep);
            }
            return candidateFunctions;
        }
Ejemplo n.º 5
0
        public StackValue Evaluate(List<StackValue> args, StackFrame stackFrame)
        {
            // Build the stackframe
            var runtimeCore = interpreter.runtime.Core;

            int classScopeCaller = (int)stackFrame.GetAt(StackFrame.AbsoluteIndex.kClass).opdata;
            int returnAddr = (int)stackFrame.GetAt(StackFrame.AbsoluteIndex.kReturnAddress).opdata;
            int blockDecl = procNode.runtimeIndex;
            int blockCaller = (int)stackFrame.GetAt(StackFrame.AbsoluteIndex.kFunctionCallerBlock).opdata;
            int framePointer = runtimeCore.Rmem.FramePointer;
            StackValue thisPtr = StackValue.BuildPointer(-1);

            // Functoion has variable input parameter. This case only happen
            // for FFI functions whose last parameter's type is (params T[]).
            // In this case, we need to convert argument list from
            //
            //    {a1, a2, ..., am, v1, v2, ..., vn}
            // 
            // to
            // 
            //    {a1, a2, ..., am, {v1, v2, ..., vn}}
            if (procNode.isVarArg)
            {
                int paramCount = procNode.argInfoList.Count;
                Validity.Assert(paramCount >= 1);

                int varParamCount = args.Count - (paramCount - 1);
                var varParams = args.GetRange(paramCount - 1, varParamCount).ToArray();
                args.RemoveRange(paramCount - 1, varParamCount);

                var packedParams = HeapUtils.StoreArray(varParams, null, interpreter.runtime.Core);
                args.Add(packedParams);
            }

            bool isCallingMemberFunciton = procNode.classScope != Constants.kInvalidIndex 
                                           && !procNode.isConstructor 
                                           && !procNode.isStatic;

            bool isValidThisPointer = true;
            if (isCallingMemberFunciton)
            {
                Validity.Assert(args.Count >= 1);
                thisPtr = args[0];
                if (thisPtr.IsArray)
                {
                    isValidThisPointer = ArrayUtils.GetFirstNonArrayStackValue(thisPtr, ref thisPtr, runtimeCore);
                }
                else
                {
                    args.RemoveAt(0);
                }
            }

            if (!isValidThisPointer || (!thisPtr.IsPointer && !thisPtr.IsArray))
            {
                runtimeCore.RuntimeStatus.LogWarning(WarningID.kDereferencingNonPointer,
                                                     WarningMessage.kDeferencingNonPointer);
                return StackValue.Null;
            }

            var callerType = (StackFrameType)stackFrame.GetAt(StackFrame.AbsoluteIndex.kStackFrameType).opdata;
            interpreter.runtime.TX = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.kImplicit);

            StackValue svBlockDecl = StackValue.BuildBlockIndex(blockDecl);
            interpreter.runtime.SX = svBlockDecl;

            var repGuides = new List<List<ProtoCore.ReplicationGuide>>();

            List<StackValue> registers = new List<StackValue>();
            interpreter.runtime.SaveRegisters(registers);
            var newStackFrame = new StackFrame(thisPtr, 
                                               classScopeCaller, 
                                               1, 
                                               returnAddr, 
                                               blockDecl, 
                                               blockCaller, 
                                               callerType, 
                                               StackFrameType.kTypeFunction, 
                                               0,   // depth
                                               framePointer, 
                                               registers, 
                                               null);

            bool isInDebugMode = runtimeCore.Options.IDEDebugMode &&
                                 runtimeCore.ExecMode != InterpreterMode.kExpressionInterpreter;
            if (isInDebugMode)
            {
                runtimeCore.DebugProps.SetUpCallrForDebug(runtimeCore, 
                                                          interpreter.runtime, 
                                                          procNode, 
                                                          returnAddr - 1, 
                                                          false, 
                                                          callsite, 
                                                          args, 
                                                          repGuides, 
                                                          newStackFrame);
            }

            StackValue rx = callsite.JILDispatchViaNewInterpreter(
                                        new Runtime.Context(), 
                                        args, 
                                        repGuides, 
                                        newStackFrame, 
                                        runtimeCore);

            if (isInDebugMode)
            {
                runtimeCore.DebugProps.RestoreCallrForNoBreak(runtimeCore, procNode);
            }

            interpreter.runtime.DecRefCounter(rx);

            return rx;
        }
Ejemplo n.º 6
0
        //Single function call

        /// <summary>
        /// Dispatch without replication
        /// </summary>
        private StackValue ExecWithZeroRI(List<FunctionEndPoint> functionEndPoint, ProtoCore.Runtime.Context c,
                                          List<StackValue> formalParameters, StackFrame stackFrame, Core core,
                                          FunctionGroup funcGroup, SingleRunTraceData previousTraceData, SingleRunTraceData newTraceData)
        {
            if(core.CancellationPending)
            {
                throw new ExecutionCancelledException();               
            }

            //@PERF: Todo add a fast path here for the case where we have a homogenious array so we can directly dispatch
            FunctionEndPoint finalFep = SelectFinalFep(c, functionEndPoint, formalParameters, stackFrame, core);

            if (functionEndPoint == null)
            {
                core.RuntimeStatus.LogWarning(ProtoCore.RuntimeData.WarningID.kMethodResolutionFailure,
                                              "Function dispatch could not be completed {2EB39E1B-557C-4819-94D8-CF7C9F933E8A}");
                return StackValue.Null;
            }

            if (core.Options.IDEDebugMode && core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                DebugFrame debugFrame = core.DebugProps.DebugStackFrame.Peek();
                debugFrame.FinalFepChosen = finalFep;
            }

            List<StackValue> coercedParameters = finalFep.CoerceParameters(formalParameters, core);

            // Correct block id where the function is defined. 
            StackValue funcBlock = stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionBlock);
            funcBlock.opdata = finalFep.BlockScope;
            stackFrame.SetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionBlock, funcBlock);


            //TraceCache -> TLS
            //Extract left most high-D pack
            ISerializable traceD = previousTraceData.GetLeftMostData();

            if (traceD != null)
            {
                //There was data associated with the previous execution, push this into the TLS

                Dictionary<string, ISerializable> dataDict = new Dictionary<string, ISerializable>();
                dataDict.Add(TRACE_KEY, traceD);

                TraceUtils.SetObjectToTLS(dataDict);
            }
            else
            {
                //There was no trace data for this run
                TraceUtils.ClearAllKnownTLSKeys();
            }

            //EXECUTE
            StackValue ret = finalFep.Execute(c, coercedParameters, stackFrame, core);

            if (ret.IsNull)
            {

                //wipe the trace cache
                TraceUtils.ClearTLSKey(TRACE_KEY);
            }

            //TLS -> TraceCache
            Dictionary<String, ISerializable> traceRet = TraceUtils.GetObjectFromTLS();

            if (traceRet.ContainsKey(TRACE_KEY))
            {
                var val = traceRet[TRACE_KEY];
                newTraceData.Data = val;
            }


            // An explicit call requires return coercion at the return instruction
            if (!ret.IsExplicitCall)
            {
                ret = PerformReturnTypeCoerce(finalFep, core, ret);
            }
            return ret;
        }
Ejemplo n.º 7
0
        private FunctionEndPoint SelectFEPFromMultiple(StackFrame stackFrame, Core core,
                                                       List<FunctionEndPoint> feps, List<StackValue> argumentsList)
        {
            StackValue svThisPtr = stackFrame.GetAt(StackFrame.AbsoluteIndex.kThisPtr);
            Validity.Assert(svThisPtr.IsPointer,
                            "this pointer wasn't a pointer. {89635B06-AD53-4170-ADA5-065EB2AE5858}");

            int typeID = (int) svThisPtr.metaData.type;

            //Test for exact match
            List<FunctionEndPoint> exactFeps = new List<FunctionEndPoint>();

            foreach (FunctionEndPoint fep in feps)
                if (fep.ClassOwnerIndex == typeID)
                    exactFeps.Add(fep);

            if (exactFeps.Count == 1)
            {
                return exactFeps[0];
            }


            //Walk the class tree structure to find the method

            while (core.ClassTable.ClassNodes[typeID].baseList.Count > 0)
            {
                Validity.Assert(core.ClassTable.ClassNodes[typeID].baseList.Count == 1,
                                "Multiple inheritence not yet supported {B93D8D7F-AB4D-4412-8483-33DE739C0ADA}");

                typeID = core.ClassTable.ClassNodes[typeID].baseList[0];

                foreach (FunctionEndPoint fep in feps)
                    if (fep.ClassOwnerIndex == typeID)
                        return fep;
            }

            //We weren't able to distinguish based on class hiearchy, try to sepearete based on array ranking
            List<int> numberOfArbitraryRanks = new List<int>();

            foreach (FunctionEndPoint fep in feps)
            {
                int noArbitraries = 0;

                for (int i = 0; i < argumentsList.Count; i++)
                {
                    if (fep.FormalParams[i].rank == DSASM.Constants.kArbitraryRank)
                        noArbitraries++;

                    numberOfArbitraryRanks.Add(noArbitraries);
                }
            }

            int smallest = int.MaxValue;
            List<int> indeciesOfSmallest = new List<int>();

            for (int i = 0; i < feps.Count; i++)
            {
                if (numberOfArbitraryRanks[i] < smallest)
                {
                    smallest = numberOfArbitraryRanks[i];
                    indeciesOfSmallest.Clear();
                    indeciesOfSmallest.Add(i);
                }
                else if (numberOfArbitraryRanks[i] == smallest)
                    indeciesOfSmallest.Add(i);
            }

            Validity.Assert(indeciesOfSmallest.Count > 0,
                            "Couldn't find a fep when there should have been multiple: {EB589F55-F36B-404A-91DC-8D0EDC527E72}");

            if (indeciesOfSmallest.Count == 1)
                return feps[indeciesOfSmallest[0]];


            if (!CoreUtils.IsInternalMethod(feps[0].procedureNode.name) || CoreUtils.IsGetterSetter(feps[0].procedureNode.name))
            {
                //If this has failed, we have multiple feps, which can't be distiquished by class hiearchy. Emit a warning and select one
                StringBuilder possibleFuncs = new StringBuilder();
                possibleFuncs.Append(
                    "Couldn't decide which function to execute. Please provide more specific type information. Possible functions were: ");
                foreach (FunctionEndPoint fep in feps)
                    possibleFuncs.AppendLine("\t" + fep.ToString());


                possibleFuncs.AppendLine("Error code: {DCE486C0-0975-49F9-BE2C-2E7D8CCD17DD}");

                core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kAmbiguousMethodDispatch, possibleFuncs.ToString());
            }

            return feps[0];

            //Validity.Assert(false, "We failed to find a single FEP when there should have been multiple. {CA6E1A93-4CF4-4030-AD94-3BF1C3CFC5AF}");

            //throw new Exceptions.CompilerInternalException("{CA6E1A93-4CF4-4030-AD94-3BF1C3CFC5AF}");
        }
Ejemplo n.º 8
0
        public StackValue Evaluate(List<StackValue> args, StackFrame stackFrame)
        {
            // Build the stackframe
            var runtimeCore = interpreter.runtime.Core;

            int classScopeCaller = (int)stackFrame.GetAt(StackFrame.AbsoluteIndex.kClass).opdata;
            int returnAddr = (int)stackFrame.GetAt(StackFrame.AbsoluteIndex.kReturnAddress).opdata;
            int blockDecl = (int)procNode.runtimeIndex;
            int blockCaller = (int)stackFrame.GetAt(StackFrame.AbsoluteIndex.kFunctionCallerBlock).opdata;
            int framePointer = runtimeCore.Rmem.FramePointer;
            StackValue thisPtr = StackValue.BuildPointer(-1);

            bool isCallingMemberFunciton = procNode.classScope != Constants.kInvalidIndex 
                                           && !procNode.isConstructor 
                                           && !procNode.isStatic;
            if (isCallingMemberFunciton)
            {
                Validity.Assert(args.Count >= 1);
                thisPtr = args[0];
                if (thisPtr.IsArray())
                {
                    ArrayUtils.GetFirstNonArrayStackValue(thisPtr, ref thisPtr, runtimeCore);
                }
                else
                {
                    args.RemoveAt(0);
                }
            }

            if (!thisPtr.IsObject() && !thisPtr.IsArray())
            {
                runtimeCore.RuntimeStatus.LogWarning(WarningID.kDereferencingNonPointer,
                                                     WarningMessage.kDeferencingNonPointer);
                return StackValue.Null;
            }

            var callerType = (StackFrameType)stackFrame.GetAt(StackFrame.AbsoluteIndex.kStackFrameType).opdata;
            interpreter.runtime.TX = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.kImplicit);

            StackValue svBlockDecl = StackValue.BuildBlockIndex(blockDecl);
            interpreter.runtime.SX = svBlockDecl;

            var repGuides = new List<List<ProtoCore.ReplicationGuide>>();

            List<StackValue> registers = new List<StackValue>();
            interpreter.runtime.SaveRegisters(registers);
            var newStackFrame = new StackFrame(thisPtr, 
                                               classScopeCaller, 
                                               1, 
                                               returnAddr, 
                                               blockDecl, 
                                               blockCaller, 
                                               callerType, 
                                               StackFrameType.kTypeFunction, 
                                               0,   // depth
                                               framePointer, 
                                               registers, 
                                               null);

            bool isInDebugMode = runtimeCore.Options.IDEDebugMode &&
                                 runtimeCore.ExecMode != InterpreterMode.kExpressionInterpreter;
            if (isInDebugMode)
            {
                runtimeCore.DebugProps.SetUpCallrForDebug(runtimeCore, 
                                                          interpreter.runtime, 
                                                          procNode, 
                                                          returnAddr - 1, 
                                                          false, 
                                                          callsite, 
                                                          args, 
                                                          repGuides, 
                                                          newStackFrame);
            }

            StackValue rx = callsite.JILDispatchViaNewInterpreter(
                                        new Runtime.Context(), 
                                        args, 
                                        repGuides, 
                                        newStackFrame, 
                                        runtimeCore);

            if (isInDebugMode)
            {
                runtimeCore.DebugProps.RestoreCallrForNoBreak(runtimeCore, procNode);
            }

            return rx;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Dispatch without replication
        /// </summary>
        private StackValue ExecWithZeroRI(List<FunctionEndPoint> functionEndPoint, ProtoCore.Runtime.Context c,
            List<StackValue> formalParameters, StackFrame stackFrame, Core core,
            FunctionGroup funcGroup)
        {
            //@PERF: Todo add a fast path here for the case where we have a homogenious array so we can directly dispatch

            FunctionEndPoint finalFep = SelectFinalFep(c, functionEndPoint, formalParameters, stackFrame, core);

            /*functionEndPoint = ResolveFunctionEndPointWithoutReplication(c,funcGroup, formalParameters,
                                                                         stackFrame, core);*/

            if (functionEndPoint == null)
            {
                core.RuntimeStatus.LogWarning(ProtoCore.RuntimeData.WarningID.kMethodResolutionFailure,
                                              "Function dispatch could not be completed {2EB39E1B-557C-4819-94D8-CF7C9F933E8A}");
                return StackUtils.BuildNull();
            }

            if (core.Options.IDEDebugMode && core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
            {
                DebugFrame debugFrame = core.DebugProps.DebugStackFrame.Peek();
                debugFrame.FinalFepChosen = finalFep;
            }

            //@TODO(Luke): Should this coerce?
            List<StackValue> coercedParameters = finalFep.CoerceParameters(formalParameters, core);

            // Correct block id where the function is defined.
            StackValue funcBlock = stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionBlock);
            funcBlock.opdata = finalFep.BlockScope;
            stackFrame.SetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionBlock, funcBlock);

            StackValue ret = finalFep.Execute(c, coercedParameters, stackFrame, core);

            // An explicit call requires return coercion at the return instruction
            if (ret.optype != AddressType.ExplicitCall)
            {
                ret = PerformReturnTypeCoerce(finalFep, core, ret);
            }
            return ret;
        }
Ejemplo n.º 10
0
        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);
        }
Ejemplo n.º 11
0
        public override StackValue Execute(ProtoCore.Runtime.Context c, List <StackValue> formalParameters, ProtoCore.DSASM.StackFrame stackFrame, Core core)
        {   //  ensure there is no data race, function resolution and execution happens in parallel
            //  but for FFI we want it to be serial cause the code we are calling into may not cope
            //  with parallelism.
            //
            //  we are always looking and putting our function pointers in handler with each lang
            //  so better lock for FFIHandler (being static) it  will be good object to lock
            //
            lock (FFIHandlers)
            {
                ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(core, true);

                StackValue svThisPtr   = stackFrame.GetAt(StackFrame.AbsoluteIndex.kThisPtr);
                StackValue svBlockDecl = stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionBlock);

                // Setup the stack frame data
                //int thisPtr = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kThisPtr).opdata;
                int ci           = activation.JILRecord.classIndex;
                int fi           = activation.JILRecord.funcIndex;
                int returnAddr   = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kReturnAddress).opdata;
                int blockDecl    = (int)svBlockDecl.opdata;
                int blockCaller  = (int)stackFrame.GetAt(DSASM.StackFrame.AbsoluteIndex.kFunctionCallerBlock).opdata;
                int framePointer = core.Rmem.FramePointer;
                int locals       = activation.JILRecord.locals;


                FFIHandler          handler = FFIHandlers[activation.ModuleType];
                FFIActivationRecord r       = activation;
                string className            = "";
                if (activation.JILRecord.classIndex > 0)
                {
                    className = core.DSExecutable.classTable.ClassNodes[activation.JILRecord.classIndex].name;
                }

                bool gcThisPtr = false;
                List <ProtoCore.Type> argTypes = new List <Type>(r.ParameterTypes);

                ProcedureNode fNode = null;
                if (ProtoCore.DSASM.Constants.kInvalidIndex != ci)
                {
                    fNode = interpreter.runtime.exe.classTable.ClassNodes[ci].vtable.procList[fi];
                }

                // Check if this is a 'this' pointer function overload that was generated by the compiler
                if (null != fNode && fNode.isAutoGeneratedThisProc)
                {
                    int  thisPtrIndex = 0;
                    bool isStaticCall = svThisPtr.IsPointer && Constants.kInvalidPointer == (int)svThisPtr.opdata;
                    if (isStaticCall)
                    {
                        thisPtrIndex = formalParameters.Count - 1;
                    }
                    argTypes.RemoveAt(thisPtrIndex);

                    // Comment Jun: Execute() can handle a null this pointer.
                    // But since we dont even need to to reach there if we dont have a valid this pointer, then just return null
                    if (formalParameters[thisPtrIndex].IsNull)
                    {
                        core.RuntimeStatus.LogWarning(ProtoCore.RuntimeData.WarningID.kDereferencingNonPointer, ProtoCore.RuntimeData.WarningMessage.kDeferencingNonPointer);
                        return(StackValue.Null);
                    }

                    // These are the op types allowed.
                    Validity.Assert(formalParameters[thisPtrIndex].IsPointer ||
                                    formalParameters[thisPtrIndex].IsDefaultArgument);

                    svThisPtr = formalParameters[thisPtrIndex];
                    gcThisPtr = true;

                    formalParameters.RemoveAt(thisPtrIndex);
                }

                FFIFunctionPointer functionPointer = handler.GetFunctionPointer(r.ModuleName, className, r.FunctionName, argTypes, r.ReturnType);
                mFunctionPointer       = Validate(functionPointer) ? functionPointer : null;
                mFunctionPointer.IsDNI = activation.IsDNI;


                if (mFunctionPointer == null)
                {
                    return(ProtoCore.DSASM.StackValue.Null);
                }

                List <object> ps = new List <object>(); //obsolete

                {
                    interpreter.runtime.executingBlock = core.RunningBlock;
                    activation.JILRecord.globs         = core.DSExecutable.runtimeSymbols[core.RunningBlock].GetGlobalSize();

                    // Params
                    formalParameters.Reverse();
                    for (int i = 0; i < formalParameters.Count; i++)
                    {
                        interpreter.Push(formalParameters[i]);
                    }

                    List <StackValue> registers = new List <DSASM.StackValue>();
                    interpreter.runtime.SaveRegisters(registers);

                    // Comment Jun: the depth is always 0 for a function call as we are reseting this for each function call
                    // This is only incremented for every language block bounce
                    int            depth      = 0;
                    StackFrameType callerType = (StackFrameType)stackFrame.GetAt(StackFrame.AbsoluteIndex.kCallerStackFrameType).opdata;

                    // FFI calls do not have execution states
                    core.Rmem.PushStackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, ProtoCore.DSASM.StackFrameType.kTypeFunction, depth, framePointer, registers, locals, 0);

                    //is there a way the current stack be passed across and back into the managed runtime by FFI calling back into the language?
                    //e.g. DCEnv* carrying all the stack information? look at how vmkit does this.
                    // = jilMain.Run(ActivationRecord.JILRecord.pc, null, true);

                    //double[] tempArray = GetUnderlyingArray<double>(jilMain.runtime.rmem.stack);
                    Object     ret = mFunctionPointer.Execute(c, interpreter);
                    StackValue op;
                    if (ret == null)
                    {
                        op = StackValue.Null;
                    }
                    else if (ret is StackValue)
                    {
                        op = (StackValue)ret;
                    }
                    else if (ret is Int64 || ret is int)
                    {
                        op = StackValue.BuildInt((Int64)ret);
                    }
                    else if (ret is double)
                    {
                        op = StackValue.BuildDouble((double)ret);
                    }
                    else
                    {
                        throw new ArgumentException(string.Format("FFI: incorrect return type {0} from external function {1}:{2}", activation.ReturnType.Name,
                                                                  activation.ModuleName, activation.FunctionName));
                    }

                    // gc the parameters
                    if (gcThisPtr)// && core.Options.EnableThisPointerFunctionOverload)
                    {
                        // thisptr is sent as parameter, so need to gc it.
                        // but when running in expression interpreter mode, do not GC because in DSASM.Executive.DecRefCounter() related GC functions,
                        // the reference count will not be changed in expression interpreter mode.
                        if (core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
                        {
                            interpreter.runtime.Core.Rmem.Heap.GCRelease(new StackValue[] { svThisPtr }, interpreter.runtime);
                        }
                    }
                    interpreter.runtime.Core.Rmem.Heap.GCRelease(formalParameters.ToArray(), interpreter.runtime);

                    // increment the reference counter of the return value
                    interpreter.runtime.GCRetain(op);
                    // Clear the FFI stack frame
                    // FFI stack frames have no local variables
                    interpreter.runtime.rmem.FramePointer = (int)interpreter.runtime.rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFramePointer).opdata;
                    interpreter.runtime.rmem.PopFrame(ProtoCore.DSASM.StackFrame.kStackFrameSize + formalParameters.Count);

                    return(op); //DSASM.Mirror.ExecutionMirror.Unpack(op, core.heap, core);
                }
            }
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Get a list of all the function end points that are type compliant, there maybe more than one due to pattern matches
        /// </summary>
        /// <returns></returns>
        public List<FunctionEndPoint> GetExactTypeMatches(ProtoCore.Runtime.Context context,
            List<StackValue> formalParams, List<ReplicationInstruction> replicationInstructions, StackFrame stackFrame, Core core)
        {
            List<FunctionEndPoint> ret = new List<FunctionEndPoint>();


            List<List<StackValue>> allReducedParamSVs = Replicator.ComputeAllReducedParams(formalParams, replicationInstructions, core);

            List<StackValue> reducedParamSVs = allReducedParamSVs[0];
            
            //@TODO(Luke): Need to add type statistics checks to the below if it is an array to stop int[] matching char[]
            
            //Now test the reduced Params over all of the available end points
            StackValue thisptr = stackFrame.GetAt(StackFrame.AbsoluteIndex.kThisPtr);
            bool isInstance = thisptr.IsPointer && thisptr.opdata != Constants.kInvalidIndex;
            bool isGlobal = thisptr.IsPointer && thisptr.opdata == Constants.kInvalidIndex;
                                  
            foreach (FunctionEndPoint fep in FunctionEndPoints)
            {
                var proc = fep.procedureNode;

                // Member functions are overloaded with thisptr as the first
                // parameter, so if member function replicates on the left hand
                // side, the type matching should only be applied to overloaded
                // member functions, otherwise should only be applied to original
                // member functions.
                if (isInstance && context.IsReplicating != proc.isAutoGeneratedThisProc)
                {
                    continue;
                }
                else if (isGlobal && !proc.isConstructor && !proc.isStatic && proc.classScope != Constants.kGlobalScope)
                {
                    continue;
                }

                if (fep.DoesTypeDeepMatch(reducedParamSVs, core))
                {
                    ret.Add(fep);
                }
            }

            return ret;
        }