Ejemplo n.º 1
0
        /// <summary>
        /// Execute the data stored in core
        /// This is the entry point of all DS code to be executed
        /// </summary>
        /// <param name="core"></param>
        /// <returns></returns>
        public ProtoCore.RuntimeCore ExecuteVM(ProtoCore.Core core)
        {
            ProtoCore.RuntimeCore runtimeCore = CreateRuntimeCore(core);
            runtimeCore.StartTimer();
            try
            {
                foreach (ProtoCore.DSASM.CodeBlock codeblock in core.CodeBlockList)
                {
                    // Comment Jun:
                    // On first bounce, the stackframe depth is initialized to -1 in the Stackfame constructor.
                    // Passing it to bounce() increments it so the first depth is always 0
                    ProtoCore.DSASM.StackFrame stackFrame = new ProtoCore.DSASM.StackFrame(core.GlobOffset);
                    stackFrame.FramePointer = runtimeCore.RuntimeMemory.FramePointer;

                    // Comment Jun: Tell the new bounce stackframe that this is an implicit bounce
                    // Register TX is used for this.
                    StackValue svCallConvention = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.Implicit);
                    stackFrame.TX = svCallConvention;

                    // Initialize the entry point interpreter
                    int locals = 0; // This is the global scope, there are no locals
                    ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(runtimeCore);
                    runtimeCore.CurrentExecutive.CurrentDSASMExec = interpreter.runtime;
                    runtimeCore.CurrentExecutive.CurrentDSASMExec.Bounce(codeblock.codeBlockId, codeblock.instrStream.entrypoint, stackFrame, locals);
                }
                runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.ExecutionEnd);
            }
            catch
            {
                runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.ExecutionEnd);
                throw;
            }
            return(runtimeCore);
        }
Ejemplo n.º 2
0
        public void Execute(ProtoCore.Core core, ProtoCore.Runtime.Context context)
        {
            try
            {
                core.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.kExecutionBegin);
                foreach (ProtoCore.DSASM.CodeBlock codeblock in core.CodeBlockList)
                {
                    //ProtoCore.Runtime.Context context = new ProtoCore.Runtime.Context();

                    int locals = 0;


                    // Comment Jun:
                    // On first bounce, the stackframe depth is initialized to -1 in the Stackfame constructor.
                    // Passing it to bounce() increments it so the first depth is always 0
                    ProtoCore.DSASM.StackFrame stackFrame = new ProtoCore.DSASM.StackFrame(core.GlobOffset);

                    // Comment Jun: Tell the new bounce stackframe that this is an implicit bounce
                    // Register TX is used for this.
                    StackValue svCallConvention = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.kImplicit);
                    stackFrame.SetAt(ProtoCore.DSASM.StackFrame.AbsoluteIndex.kRegisterTX, svCallConvention);

                    core.Bounce(codeblock.codeBlockId, codeblock.instrStream.entrypoint, context, stackFrame, locals, EventSink);
                }
                core.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.kExecutionEnd);
            }
            catch
            {
                core.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.kExecutionEnd);
                throw;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// For a given list of formal parameters, get the function end points that resolve
        /// </summary>
        /// <param name="context"></param>
        /// <param name="formalParams"></param>
        /// <param name="replicationInstructions"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <param name="unresolvable">The number of argument sets that couldn't be resolved</param>
        /// <returns></returns>
        public Dictionary<FunctionEndPoint, int> GetExactMatchStatistics(
            Runtime.Context context,
            List<List<StackValue>> reducedFormalParams, StackFrame stackFrame, RuntimeCore runtimeCore, out int unresolvable)
        {
            List<ReplicationInstruction> replicationInstructions = new List<ReplicationInstruction>(); //We've already done the reduction before calling this

            unresolvable = 0;
            Dictionary<FunctionEndPoint, int> ret = new Dictionary<FunctionEndPoint, int>();

            foreach (List<StackValue> formalParamSet in reducedFormalParams)
            {
                List<FunctionEndPoint> feps = GetExactTypeMatches(context,
                                                                  formalParamSet, replicationInstructions, stackFrame,
                                                                  runtimeCore);
                if (feps.Count == 0)
                {
                    //We have an arugment set that couldn't be resolved
                    unresolvable++;
                }

                foreach (FunctionEndPoint fep in feps)
                {
                    if (ret.ContainsKey(fep))
                        ret[fep]++;
                    else
                        ret.Add(fep, 1);
                }
             }

             return ret;
        }
Ejemplo n.º 4
0
        public DebugProperties()
        {
            DebugStackFrame = new Stack <DebugFrame>();

            isResume           = false;
            executingGraphNode = null;
            ActiveBreakPoints  = new List <Instruction>();
            AllbreakPoints     = null;
            FRStack            = new Stack <bool>();
            FirstStackFrame    = new StackFrame(1);

            DebugEntryPC        = Constants.kInvalidIndex;
            CurrentBlockId      = Constants.kInvalidIndex;
            StepOutReturnPC     = Constants.kInvalidIndex;
            ReturnPCFromDispose = Constants.kInvalidIndex;
            IsPopmCall          = false;
        }
        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.º 6
0
        /// <summary>
        /// ExecuteLive is called by the liverunner where a persistent RuntimeCore is provided
        /// ExecuteLive assumes only a single global scope
        /// </summary>
        /// <param name="core"></param>
        /// <param name="runtimeCore"></param>
        /// <param name="runningBlock"></param>
        /// <param name="staticContext"></param>
        /// <param name="runtimeContext"></param>
        /// <returns></returns>
        public ProtoCore.RuntimeCore ExecuteLive(ProtoCore.Core core, ProtoCore.RuntimeCore runtimeCore)
        {
            try
            {
                Executable exe = runtimeCore.DSExecutable;
                Validity.Assert(exe.CodeBlocks.Count == 1);
                CodeBlock codeBlock   = runtimeCore.DSExecutable.CodeBlocks[0];
                int       codeBlockID = codeBlock.codeBlockId;

                // Comment Jun:
                // On first bounce, the stackframe depth is initialized to -1 in the Stackfame constructor.
                // Passing it to bounce() increments it so the first depth is always 0
                ProtoCore.DSASM.StackFrame stackFrame = new ProtoCore.DSASM.StackFrame(core.GlobOffset);
                stackFrame.FramePointer = runtimeCore.RuntimeMemory.FramePointer;

                // Comment Jun: Tell the new bounce stackframe that this is an implicit bounce
                // Register TX is used for this.
                StackValue svCallConvention = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.Implicit);
                stackFrame.TX = svCallConvention;

                // Initialize the entry point interpreter
                int locals = 0; // This is the global scope, there are no locals
                if (runtimeCore.CurrentExecutive.CurrentDSASMExec == null)
                {
                    ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(runtimeCore);
                    runtimeCore.CurrentExecutive.CurrentDSASMExec = interpreter.runtime;
                }

                runtimeCore.CurrentExecutive.CurrentDSASMExec.BounceUsingExecutive(
                    runtimeCore.CurrentExecutive.CurrentDSASMExec,
                    codeBlock.codeBlockId,
                    runtimeCore.StartPC,
                    stackFrame,
                    locals);

                runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.ExecutionEnd);
            }
            catch
            {
                runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.ExecutionEnd);
                throw;
            }
            return(runtimeCore);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Execute the data stored in core
        /// This is the entry point of all DS code to be executed
        /// </summary>
        /// <param name="core"></param>
        /// <param name="runningBlock"></param>
        /// <param name="staticContext"></param>
        /// <param name="runtimeContext"></param>
        public ProtoCore.RuntimeCore Execute(
            ProtoCore.Core core, int runningBlock, ProtoCore.CompileTime.Context staticContext, ProtoCore.Runtime.Context runtimeContext)
        {
            //========================Generate runtimecore here===============================//
            ProtoCore.RuntimeCore runtimeCore = core.__TempCoreHostForRefactoring;

            // Move these core setup to runtime core
            runtimeCore.RuntimeMemory.PushFrameForGlobals(core.GlobOffset);
            runtimeCore.RunningBlock = runningBlock;
            runtimeCore.RuntimeStatus.MessageHandler = core.BuildStatus.MessageHandler;

            try
            {
                runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.kExecutionBegin);
                foreach (ProtoCore.DSASM.CodeBlock codeblock in core.CodeBlockList)
                {
                    // Comment Jun:
                    // On first bounce, the stackframe depth is initialized to -1 in the Stackfame constructor.
                    // Passing it to bounce() increments it so the first depth is always 0
                    ProtoCore.DSASM.StackFrame stackFrame = new ProtoCore.DSASM.StackFrame(core.GlobOffset);
                    stackFrame.FramePointer = runtimeCore.RuntimeMemory.FramePointer;

                    // Comment Jun: Tell the new bounce stackframe that this is an implicit bounce
                    // Register TX is used for this.
                    StackValue svCallConvention = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.kImplicit);
                    stackFrame.TX = svCallConvention;

                    // Initialize the entry point interpreter
                    int locals = 0; // This is the global scope, there are no locals
                    ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(runtimeCore);
                    runtimeCore.CurrentExecutive.CurrentDSASMExec = interpreter.runtime;
                    runtimeCore.CurrentExecutive.CurrentDSASMExec.Bounce(codeblock.codeBlockId, codeblock.instrStream.entrypoint, runtimeContext, stackFrame, locals);
                }
                runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.kExecutionEnd);
            }
            catch
            {
                runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.kExecutionEnd);
                throw;
            }
            return(runtimeCore);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// For a given list of formal parameters, get the function end points that resolve
        /// </summary>
        /// <param name="context"></param>
        /// <param name="formalParams"></param>
        /// <param name="replicationInstructions"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <param name="unresolvable">The number of argument sets that couldn't be resolved</param>
        /// <returns></returns>
        public bool CanGetExactMatchStatics(
            Runtime.Context context,
            List<List<StackValue>> reducedFormalParams,
            StackFrame stackFrame,
            RuntimeCore runtimeCore,
            out HashSet<FunctionEndPoint> lookup)
        {
            lookup = new HashSet<FunctionEndPoint>();
            foreach (List<StackValue> formalParamSet in reducedFormalParams)
            {
                List<FunctionEndPoint> feps = GetExactTypeMatches(context, formalParamSet, new List<ReplicationInstruction>(), stackFrame, runtimeCore);
                if (feps.Count == 0)
                {
                    return false;
                }

                foreach (FunctionEndPoint fep in feps)
                {
                    lookup.Add(fep);
                }
             }

            return true;
        }
Ejemplo n.º 9
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, RuntimeCore runtimeCore)
        {
            List<FunctionEndPoint> ret = new List<FunctionEndPoint>();
            List<List<StackValue>> allReducedParamSVs = Replicator.ComputeAllReducedParams(formalParams, replicationInstructions, runtimeCore);
            
            //@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.ThisPtr;
            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.ClassID != Constants.kGlobalScope)
                {
                    continue;
                }

                bool typesOK = true;
                foreach (List<StackValue> reducedParamSVs in allReducedParamSVs)
                {
                    if (!fep.DoesTypeDeepMatch(reducedParamSVs, runtimeCore))
                    {
                        typesOK = false;
                        break;
                    }
                }

                if (typesOK)
                    ret.Add(fep);
            }

            return ret;
        }
Ejemplo n.º 10
0
        public void SetUpCallrForDebug(RuntimeCore runtimeCore, DSASM.Executive exec, ProcedureNode fNode, int pc, bool isBaseCall = false,
                                       CallSite callsite = null, List <StackValue> arguments         = null, List <List <ReplicationGuide> > replicationGuides = null, StackFrame stackFrame = null,
                                       List <StackValue> dotCallDimensions = null, bool hasDebugInfo = false, bool isMember = false, StackValue?thisPtr = null)
        {
            //ProtoCore.DSASM.Executive exec = core.CurrentExecutive.CurrentDSASMExec;

            DebugFrame debugFrame = new DebugFrame();

            debugFrame.IsBaseCall       = isBaseCall;
            debugFrame.Arguments        = arguments;
            debugFrame.IsMemberFunction = isMember;
            debugFrame.ThisPtr          = thisPtr;
            debugFrame.HasDebugInfo     = hasDebugInfo;

            if (CoreUtils.IsDisposeMethod(fNode.Name))
            {
                debugFrame.IsDisposeCall = true;
                ReturnPCFromDispose      = DebugEntryPC;
            }

            if (RunMode == Runmode.StepNext)
            {
                debugFrame.FunctionStepOver = true;
            }

            bool isReplicating      = false;
            bool isExternalFunction = false;

            // callsite is set to null for a base class constructor call in CALL
            if (callsite == null)
            {
                isReplicating      = false;
                isExternalFunction = false;

                SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec);
                DebugStackFrame.Push(debugFrame);

                return;
            }

            // Comment Jun: A dot call does not replicate and  must be handled immediately
            if (fNode.Name == Constants.kDotMethodName)
            {
                isReplicating                = false;
                isExternalFunction           = false;
                debugFrame.IsDotCall         = true;
                debugFrame.DotCallDimensions = dotCallDimensions;

                SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec);
                DebugStackFrame.Push(debugFrame);

                return;
            }

            List <List <ReplicationInstruction> > replicationTrials;
            bool willReplicate = callsite.WillCallReplicate(new Context(), arguments, replicationGuides, stackFrame, runtimeCore, out replicationTrials);

            // the inline conditional built-in is handled separately as 'WillCallReplicate' is always true in this case
            if (fNode.Name.Equals(Constants.kInlineConditionalMethodName))
            {
                // The inline conditional built-in is created only for associative blocks and needs to be handled separately as below
                InstructionStream istream = runtimeCore.DSExecutable.instrStreamList[CurrentBlockId];
                Validity.Assert(istream.language == Language.Associative);
                {
                    runtimeCore.DebugProps.InlineConditionOptions.isInlineConditional = true;
                    runtimeCore.DebugProps.InlineConditionOptions.startPc             = pc;

                    runtimeCore.DebugProps.InlineConditionOptions.endPc = FindEndPCForAssocGraphNode(pc, istream, fNode, exec.Properties.executingGraphNode, runtimeCore.Options.ExecuteSSA);


                    runtimeCore.DebugProps.InlineConditionOptions.instructionStream = runtimeCore.RunningBlock;
                    debugFrame.IsInlineConditional = true;
                }

                // no replication case
                if (willReplicate && replicationTrials.Count == 1)
                {
                    runtimeCore.DebugProps.InlineConditionOptions.ActiveBreakPoints.AddRange(runtimeCore.Breakpoints);

                    isReplicating      = false;
                    isExternalFunction = false;
                }
                else // an inline conditional call that replicates
                {
                    // Clear all breakpoints for outermost replicated call
                    if (!DebugStackFrameContains(StackFrameFlagOptions.IsReplicating))
                    {
                        ActiveBreakPoints.AddRange(runtimeCore.Breakpoints);
                        runtimeCore.Breakpoints.Clear();
                    }
                    isExternalFunction = false;
                    isReplicating      = true;
                }
                SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec, 0);

                DebugStackFrame.Push(debugFrame);

                return;
            }
            // Prevent breaking inside a function that is external except for dot calls
            // by clearing all breakpoints from outermost external function call
            // This check takes precedence over the replication check
            else if (fNode.IsExternal && fNode.Name != Constants.kDotMethodName)
            {
                // Clear all breakpoints
                if (!DebugStackFrameContains(StackFrameFlagOptions.IsExternalFunction) && fNode.Name != Constants.kFunctionRangeExpression)
                {
                    ActiveBreakPoints.AddRange(runtimeCore.Breakpoints);
                    runtimeCore.Breakpoints.Clear();
                }

                isExternalFunction = true;
                isReplicating      = false;
            }
            // Find if function call will replicate or not and if so
            // prevent stepping in by removing all breakpoints from outermost replicated call
            else if (willReplicate)
            {
                // Clear all breakpoints for outermost replicated call
                if (!DebugStackFrameContains(StackFrameFlagOptions.IsReplicating))
                {
                    ActiveBreakPoints.AddRange(runtimeCore.Breakpoints);
                    runtimeCore.Breakpoints.Clear();
                }

                isReplicating      = true;
                isExternalFunction = false;
            }
            // For all other function calls
            else
            {
                isReplicating      = false;
                isExternalFunction = false;
            }

            SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec);
            DebugStackFrame.Push(debugFrame);
        }
Ejemplo n.º 11
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.º 12
0
        public override StackValue Execute(ProtoCore.Runtime.Context c, List<StackValue> formalParameters, ProtoCore.DSASM.StackFrame stackFrame, RuntimeCore runtimeCore)
        {   //  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)
            {
                Interpreter interpreter = new Interpreter(runtimeCore, true);

                // Setup the stack frame data
                StackValue svThisPtr = stackFrame.ThisPtr;
                int ci = activation.JILRecord.classIndex;
                int fi = activation.JILRecord.funcIndex;
                int returnAddr = stackFrame.ReturnPC;
                int blockDecl = stackFrame.FunctionBlock;
                int blockCaller = stackFrame.FunctionCallerBlock;
                int framePointer = runtimeCore.RuntimeMemory.FramePointer;
                int locals = activation.JILRecord.locals;

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

                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].ProcTable.Procedures[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 == svThisPtr.Pointer;
                    if (isStaticCall)
                    {
                        stackFrame.ThisPtr = formalParameters[thisPtrIndex]; 
                    }
                    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)
                    {
                        runtimeCore.RuntimeStatus.LogWarning(ProtoCore.Runtime.WarningID.DereferencingNonPointer, Resources.kDeferencingNonPointer);
                        return StackValue.Null;
                    }

                    // These are the op types allowed. 
                    Validity.Assert(formalParameters[thisPtrIndex].IsPointer || 
                                    formalParameters[thisPtrIndex].IsDefaultArgument);
                    
                    svThisPtr = formalParameters[thisPtrIndex];
                    
                    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;
                }

                {

                    interpreter.runtime.executingBlock = runtimeCore.RunningBlock;
                    activation.JILRecord.globs = runtimeCore.DSExecutable.runtimeSymbols[runtimeCore.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 = stackFrame.CallerStackFrameType;

                    // FFI calls do not have execution states
                    runtimeCore.RuntimeMemory.PushFrameForLocals(locals);
                    StackFrame newStackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, StackFrameType.Function, depth, framePointer, registers, 0);
                    runtimeCore.RuntimeMemory.PushStackFrame(newStackFrame);

                    //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));
                    }

                    // Clear the FFI stack frame 
                    // FFI stack frames have no local variables
                    interpreter.runtime.rmem.FramePointer = (int)interpreter.runtime.rmem.GetAtRelative(StackFrame.FrameIndexFramePointer).IntegerValue;
                    interpreter.runtime.rmem.PopFrame(StackFrame.StackFrameSize + formalParameters.Count);

                    return op; 
                }
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        /// ExecuteLive is called by the liverunner where a persistent RuntimeCore is provided
        /// ExecuteLive assumes only a single global scope
        /// </summary>
        /// <param name="core"></param>
        /// <param name="runtimeCore"></param>
        /// <param name="runningBlock"></param>
        /// <param name="staticContext"></param>
        /// <param name="runtimeContext"></param>
        /// <returns></returns>
        public ProtoCore.RuntimeCore ExecuteLive(ProtoCore.Core core, ProtoCore.RuntimeCore runtimeCore)
        {
            try
            {
                Executable exe = runtimeCore.DSExecutable;
                Validity.Assert(exe.CodeBlocks.Count == 1);
                CodeBlock codeBlock = runtimeCore.DSExecutable.CodeBlocks[0];
                int codeBlockID = codeBlock.codeBlockId;

                // Comment Jun:
                // On first bounce, the stackframe depth is initialized to -1 in the Stackfame constructor.
                // Passing it to bounce() increments it so the first depth is always 0
                ProtoCore.DSASM.StackFrame stackFrame = new ProtoCore.DSASM.StackFrame(core.GlobOffset);
                stackFrame.FramePointer = runtimeCore.RuntimeMemory.FramePointer;

                // Comment Jun: Tell the new bounce stackframe that this is an implicit bounce
                // Register TX is used for this.
                StackValue svCallConvention = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.kImplicit);
                stackFrame.TX = svCallConvention;

                // Initialize the entry point interpreter
                int locals = 0; // This is the global scope, there are no locals
                if (runtimeCore.CurrentExecutive.CurrentDSASMExec == null)
                {
                    ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(runtimeCore);
                    runtimeCore.CurrentExecutive.CurrentDSASMExec = interpreter.runtime;
                }

                runtimeCore.CurrentExecutive.CurrentDSASMExec.BounceUsingExecutive(
                    runtimeCore.CurrentExecutive.CurrentDSASMExec,
                    codeBlock.codeBlockId,
                    runtimeCore.StartPC,
                    stackFrame,
                    locals);

                runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.kExecutionEnd);
            }
            catch
            {
                runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.kExecutionEnd);
                throw;
            }
            return runtimeCore;
        }
Ejemplo n.º 14
0
        private void BOUNCE_Handler(Instruction instruction)
        {
            // We disallow language blocks inside watch window currently - pratapa
            Validity.Assert(InterpreterMode.Expression != runtimeCore.Options.RunMode);

            int blockId = instruction.op1.BlockIndex;

            // Comment Jun: On a bounce, update the debug property to reflect this.
            // Before the explicit bounce, this was done in Execute() which is now no longer the case
            // as Execute is only called once during first bounce and succeeding bounce reuse the same interpreter
            runtimeCore.DebugProps.CurrentBlockId = blockId;

            // TODO(Jun/Jiong): Considering store the orig block id to stack frame
            runtimeCore.RunningBlock = blockId;

            runtimeCore.RuntimeMemory = rmem;
            if (runtimeCore.Options.RunMode != InterpreterMode.Expression)
            {
                runtimeCore.RuntimeMemory.PushConstructBlockId(blockId);
            }

            int ci = Constants.kInvalidIndex;
            int fi = Constants.kInvalidIndex;
            if (rmem.Stack.Count >= StackFrame.StackFrameSize)
            {
                StackValue sci = rmem.GetAtRelative(StackFrame.FrameIndexClassIndex);
                StackValue sfi = rmem.GetAtRelative(StackFrame.FrameIndexFunctionIndex);
                if (sci.IsClassIndex && sfi.IsFunctionIndex)
                {
                    ci = sci.ClassIndex;
                    fi = sfi.FunctionIndex;
                }
            }

            StackValue svThisPtr;
            if (rmem.CurrentStackFrame == null)
            {
                svThisPtr = StackValue.BuildPointer(Constants.kInvalidPointer);
            }
            else
            {
                svThisPtr = rmem.CurrentStackFrame.ThisPtr;
            }
            int returnAddr = pc + 1;

            Validity.Assert(Constants.kInvalidIndex != executingBlock);
            //int blockDecl = executingBlock;
            int blockDecl = rmem.GetAtRelative(StackFrame.FrameIndexFunctionBlockIndex).BlockIndex;
            int blockCaller = executingBlock;

            StackFrameType type = StackFrameType.LanguageBlock;
            int depth = (int)rmem.GetAtRelative(StackFrame.FrameIndexStackFrameDepth).IntegerValue;
            int framePointer = runtimeCore.RuntimeMemory.FramePointer;

            // Comment Jun: Use the register TX to store explicit/implicit bounce state
            bounceType = CallingConvention.BounceType.Explicit;
            TX = StackValue.BuildCallingConversion((int)CallingConvention.BounceType.Explicit);

            List<StackValue> registers = GetRegisters();

            StackFrameType callerType = (fepRun) ? StackFrameType.Function : StackFrameType.LanguageBlock;


            if (runtimeCore.Options.IDEDebugMode && runtimeCore.Options.RunMode != InterpreterMode.Expression)
            {
                // Comment Jun: Temporarily disable debug mode on bounce
                //Validity.Assert(false); 

                //Validity.Assert(runtimeCore.Breakpoints != null);
                //blockDecl = blockCaller = runtimeCore.DebugProps.CurrentBlockId;

                runtimeCore.DebugProps.SetUpBounce(this, blockCaller, returnAddr);

                StackFrame stackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, type, depth + 1, framePointer, 0, registers, 0);
                Language bounceLangauge = exe.instrStreamList[blockId].language;
                BounceExplicit(blockId, 0, bounceLangauge, stackFrame, runtimeCore.Breakpoints);
            }
            else //if (runtimeCore.Breakpoints == null)
            {
                StackFrame stackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, type, depth + 1, framePointer, 0, registers, 0);

                Language bounceLangauge = exe.instrStreamList[blockId].language;
                BounceExplicit(blockId, 0, bounceLangauge, stackFrame);
            }
        }
Ejemplo n.º 15
0
        public StackValue Callr(int blockDeclId,
                                int functionIndex, 
                                int classIndex, 
                                ref bool explicitCall, 
                                bool isDynamicCall = false, 
                                bool hasDebugInfo = false)
        {
            // This is curently unused but required for stack alignment
            var svDepth = rmem.Pop();
            int depth = (int)svDepth.IntegerValue;

            ProcedureNode fNode = null;

            bool isCallingMemberFunction = Constants.kInvalidIndex != classIndex;
            if (isCallingMemberFunction)
            {
                fNode = exe.classTable.ClassNodes[classIndex].ProcTable.Procedures[functionIndex];

                if (depth > 0 && fNode.IsConstructor)
                {
                    string message = String.Format(Resources.KCallingConstructorOnInstance, fNode.Name);
                    runtimeCore.RuntimeStatus.LogWarning(WarningID.CallingConstructorOnInstance, message);
                    return StackValue.Null;
                }
            }
            else
            {
                // Global function
                fNode = exe.procedureTable[blockDeclId].Procedures[functionIndex];
            }

            // Build the arg values list
            var arguments = new List<StackValue>();

            // Retrive the param values from the stack
            int stackindex = rmem.Stack.Count - 1;

            List<StackValue> dotCallDimensions = new List<StackValue>();
            if (fNode.Name.Equals(Constants.kDotMethodName))
            {
                int firstDotArgIndex = stackindex - (Constants.kDotCallArgCount - 1);
                StackValue svLHS = rmem.Stack[firstDotArgIndex];
                arguments.Add(svLHS);

                // Retrieve the indexed dimensions into the dot call
                int arrayDimIndex = stackindex - (Constants.kDotCallArgCount - Constants.kDotArgIndexArrayIndex - 1);
                StackValue svArrayPtrDimesions = rmem.Stack[arrayDimIndex];
                Validity.Assert(svArrayPtrDimesions.IsArray);

                int arrayCountIndex = stackindex - (Constants.kDotCallArgCount - Constants.kDotArgIndexDimCount - 1);
                StackValue svDimensionCount = rmem.Stack[arrayCountIndex];
                Validity.Assert(svDimensionCount.IsInteger);

                // If array dimension were provided then retrive the final pointer 
                if (svDimensionCount.IntegerValue > 0)
                {
                    var dimArray = rmem.Heap.ToHeapObject<DSArray>(svArrayPtrDimesions);
                    Validity.Assert(dimArray.Count == svDimensionCount.IntegerValue);
                    dotCallDimensions.AddRange(dimArray.Values);
                }
            }
            else
            {
                arguments = PopArgumentsFromStack(fNode.ArgumentTypes.Count);
                arguments.Reverse();
            }

            var replicationGuides = new List<List<ReplicationGuide>>();
            var atLevels = new List<AtLevel>();

            Runtime.Context runtimeContext = new Runtime.Context();

            // Comment Jun: These function do not require replication guides
            // TODO Jun: Move these conditions or refactor JIL code emission so these checks dont reside here (Post R1)
            if (Constants.kDotMethodName != fNode.Name
                && Constants.kFunctionRangeExpression != fNode.Name)
            {
                // Comment Jun: If this is a non-dot call, cache the guides first and retrieve them on the actual function call
                // TODO Jun: Ideally, cache the replication guides in the dynamic function node
                replicationGuides = GetCachedReplicationGuides(arguments.Count);
                atLevels = GetCachedAtLevels(arguments.Count);
            }

            // if is dynamic call, the final pointer has been resovled in the ProcessDynamicFunction function
            StackValue svThisPtr = StackValue.Null;

            if (depth > 0)
            {
                svThisPtr = rmem.Pop();
                if (!svThisPtr.IsPointer)
                {
                    string message = String.Format(Resources.kInvokeMethodOnInvalidObject, fNode.Name);
                    runtimeCore.RuntimeStatus.LogWarning(WarningID.DereferencingNonPointer, message);
                    return StackValue.Null;
                }
            }
            else
            {
                // There is no depth, but check if the function is a member function
                // If its a member function, the this pointer is required by the core to pass on to the FEP call
                if (isCallingMemberFunction && !fNode.IsConstructor && !fNode.IsStatic)
                {
                    // A member function
                    // Get the this pointer as this class instance would have already been cosntructed
                    svThisPtr = rmem.CurrentStackFrame.ThisPtr;
                }
                else if (fNode.Name.Equals(Constants.kInlineConditionalMethodName))
                {
                    // The built-in inlinecondition function is global but it is treated as a conditional execution rather than a normal function call
                    // This is why the class scope  needs to be preserved such that the auto-generated language blocks in an inline conditional can still refer to member functions and properties
                    svThisPtr = rmem.CurrentStackFrame.ThisPtr;
                }
                else
                {
                    // Global
                    svThisPtr = StackValue.BuildPointer(Constants.kInvalidPointer);
                }
            }

            if (svThisPtr.IsPointer &&
                svThisPtr.Pointer != Constants.kInvalidIndex &&
                svThisPtr.metaData.type != Constants.kInvalidIndex)
            {
                int runtimeClassIndex = svThisPtr.metaData.type;
                ClassNode runtimeClass = exe.classTable.ClassNodes[runtimeClassIndex];
                if (runtimeClass.IsMyBase(classIndex))
                {
                    classIndex = runtimeClassIndex;
                }
            }

            // Build the stackframe
            //int thisPtr = (int)svThisPtr.opdata;
            int ci = classIndex; // Constants.kInvalidIndex;   // Handled at FEP
            int fi = Constants.kInvalidIndex;   // Handled at FEP

            int returnAddr = pc + 1;

            int blockDecl = blockDeclId;

            if (null != Properties.executingGraphNode)
            {
                exe.ExecutingGraphnode = Properties.executingGraphNode;
            }

            // Get the cached callsite, creates a new one for a first-time call
            CallSite callsite = runtimeCore.RuntimeData.GetCallSite(
                exe.ExecutingGraphnode, 
                classIndex, 
                fNode.Name, 
                exe,
                runtimeCore.RunningBlock, 
                runtimeCore.Options, 
                runtimeCore.RuntimeStatus);
            Validity.Assert(null != callsite);

            List<StackValue> registers = GetRegisters();

            // Get the execution states of the current stackframe
            int currentScopeClass = Constants.kInvalidIndex;
            int currentScopeFunction = Constants.kInvalidIndex;
            GetCallerInformation(out currentScopeClass, out currentScopeFunction);

            // Handle execution states at the FEP
            var stackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, runtimeCore.RunningBlock, fepRun ? StackFrameType.Function : StackFrameType.LanguageBlock, StackFrameType.Function, 0, rmem.FramePointer, blockDeclId, registers, 0);
            StackValue sv = StackValue.Null;

            if (runtimeCore.Options.IDEDebugMode && runtimeCore.Options.RunMode != InterpreterMode.Expression)
            {
                if (runtimeCore.ContinuationStruct.IsFirstCall)
                {
                    runtimeCore.DebugProps.SetUpCallrForDebug(
                                                       runtimeCore,
                                                       this,
                                                       fNode,
                                                       pc,
                                                       false,
                                                       callsite,
                                                       arguments,
                                                       replicationGuides,
                                                       stackFrame,
                                                       dotCallDimensions,
                                                       hasDebugInfo);
                }
                else
                {
                    runtimeCore.DebugProps.SetUpCallrForDebug(
                                                       runtimeCore,
                                                       this,
                                                       fNode,
                                                       pc,
                                                       false,
                                                       callsite,
                                                       runtimeCore.ContinuationStruct.InitialArguments,
                                                       replicationGuides,
                                                       stackFrame,
                                                       runtimeCore.ContinuationStruct.InitialDotCallDimensions,
                                                       hasDebugInfo);
                }
            }

            //Dispatch without recursion tracking 
            explicitCall = false;
            IsExplicitCall = explicitCall;

            var argumentAtLevels = AtLevelHandler.GetArgumentAtLevelStructure(arguments, atLevels, runtimeCore);
            sv = callsite.JILDispatch(argumentAtLevels.Arguments, replicationGuides, argumentAtLevels.DominantStructure, stackFrame, runtimeCore, runtimeContext);
            if (sv.IsExplicitCall)
            {
                //
                // Set the interpreter properties for function calls
                // These are used when performing GC on return 
                // The GC occurs: 
                //      1. In this instruction for implicit calls
                //      2. In the return instruction
                //
                Properties.functionCallArguments = argumentAtLevels.Arguments;
                Properties.functionCallDotCallDimensions = dotCallDimensions;
                Properties.DominantStructure = argumentAtLevels.DominantStructure;

                explicitCall = true;
                IsExplicitCall = explicitCall;
                CallExplicit(sv.ExplicitCallEntry);
            }

            // If the function was called implicitly, The code below assumes this and must be executed
            if (!explicitCall)
            {
                // Restore debug properties after returning from a CALL/CALLR
                if (runtimeCore.Options.IDEDebugMode && runtimeCore.Options.RunMode != InterpreterMode.Expression)
                {
                    runtimeCore.DebugProps.RestoreCallrForNoBreak(runtimeCore, fNode);
                }

                if (CoreUtils.IsDotMethod(fNode.Name))
                {
                    sv = IndexIntoArray(sv, dotCallDimensions);
                    rmem.PopFrame(Constants.kDotCallArgCount);
                }
            }
            return sv;
        }
Ejemplo n.º 16
0
        public StackValue JILDispatch(
            List<StackValue> arguments, 
            List<List<ReplicationGuide>> replicationGuides,
            List<AtLevel> atLevels, 
            StackFrame stackFrame, 
            RuntimeCore runtimeCore, 
            Context context)
        {
#if DEBUG

            ArgumentSanityCheck(arguments);
#endif
            // Dispatch method
            return DispatchNew(context, arguments, replicationGuides, atLevels, stackFrame, runtimeCore);
        }
Ejemplo n.º 17
0
        //Dispatch
        private StackValue DispatchNew(
            Context context, 
            List<StackValue> arguments, 
            List<List<ReplicationGuide>> partialReplicationGuides, 
            List<AtLevel> atLevels,
            StackFrame stackFrame, RuntimeCore runtimeCore)
        {
            // Update the CallsiteExecutionState with 
            // TODO: Replace this with the real data
            UpdateCallsiteExecutionState(null, runtimeCore);

            Stopwatch sw = new Stopwatch();
            sw.Start();

            StringBuilder log = new StringBuilder();

            log.AppendLine("Method name: " + methodName);

            #region Get Function Group

            //@PERF: Possible optimisation point here, to deal with static dispatches that don't need replication analysis
            //Handle resolution Pass 1: Name -> Method Group
            FunctionGroup funcGroup = GetFuncGroup(runtimeCore);
            if (funcGroup == null)
            {
                log.AppendLine("Function group not located");
                log.AppendLine("Resolution failed in: " + sw.ElapsedMilliseconds);

                if (runtimeCore.Options.DumpFunctionResolverLogic)
                    runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                return ReportFunctionGroupNotFound(runtimeCore, arguments);
            }

            //check accesibility of function group
            bool methodAccessible = IsFunctionGroupAccessible(runtimeCore, ref funcGroup);
            if (!methodAccessible)
            {
                return ReportMethodNotAccessible(runtimeCore);
            }

            //If we got here then the function group got resolved
            log.AppendLine("Function group resolved: " + funcGroup);

            #endregion

            arguments = GetArgumentsAtLevels(arguments, atLevels, runtimeCore).Select(a => a.Argument).ToList();

            partialReplicationGuides = PerformRepGuideDemotion(arguments, partialReplicationGuides, runtimeCore);

            //Replication Control is an ordered list of the elements that we have to replicate over
            //Ordering implies containment, so element 0 is the outer most forloop, element 1 is nested within it etc.
            //Take the explicit replication guides and build the replication structure
            //Turn the replication guides into a guide -> List args data structure
           var partialInstructions = Replicator.BuildPartialReplicationInstructions(partialReplicationGuides);

            //Get the fep that are resolved
            List<FunctionEndPoint> resolvesFeps;
            List<ReplicationInstruction> replicationInstructions;

            arguments = PerformRepGuideForcedPromotion(arguments, partialReplicationGuides, runtimeCore);
            ComputeFeps(log, context, arguments, funcGroup, partialInstructions, partialReplicationGuides, stackFrame, runtimeCore, out resolvesFeps, out replicationInstructions);

            if (resolvesFeps.Count == 0)
            {
                log.AppendLine("Resolution Failed");

                if (runtimeCore.Options.DumpFunctionResolverLogic)
                    runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                return ReportMethodNotFoundForArguments(runtimeCore, arguments);
            }

            arguments.ForEach(x => runtimeCore.AddCallSiteGCRoot(CallSiteID, x));
            StackValue ret = Execute(resolvesFeps, context, arguments, replicationInstructions, stackFrame, runtimeCore, funcGroup);
            runtimeCore.RemoveCallSiteGCRoot(CallSiteID);
            return ret;
        }
Ejemplo n.º 18
0
        private FunctionEndPoint SelectFinalFep(Context context,
                                                List<FunctionEndPoint> functionEndPoint,
                                                List<StackValue> formalParameters, StackFrame stackFrame, RuntimeCore runtimeCore)
        {
            List<ReplicationInstruction> replicationControl = new List<ReplicationInstruction>();
            //We're never going to replicate so create an empty structure to allow us to use
            //the existing utility methods

            //Filter for exact matches

            List<FunctionEndPoint> exactTypeMatchingCandindates = new List<FunctionEndPoint>();

            foreach (FunctionEndPoint possibleFep in functionEndPoint)
            {
                if (possibleFep.DoesTypeDeepMatch(formalParameters, runtimeCore))
                {
                    exactTypeMatchingCandindates.Add(possibleFep);
                }
            }


            //There was an exact match, so dispath to it
            if (exactTypeMatchingCandindates.Count > 0)
            {
                FunctionEndPoint fep = null;

                if (exactTypeMatchingCandindates.Count == 1)
                {
                    fep = exactTypeMatchingCandindates[0];
                }
                else
                {
                    fep = SelectFEPFromMultiple(stackFrame, runtimeCore,
                                                exactTypeMatchingCandindates, formalParameters);
                }

                return fep;
            }
            else
            {
                Dictionary<FunctionEndPoint, int> candidatesWithDistances = new Dictionary<FunctionEndPoint, int>();
                Dictionary<FunctionEndPoint, int> candidatesWithCastDistances = new Dictionary<FunctionEndPoint, int>();

                foreach (FunctionEndPoint fep in functionEndPoint)
                {
                    //@TODO(Luke): Is this value for allow array promotion correct?
                    int distance = fep.ComputeTypeDistance(formalParameters, runtimeCore.DSExecutable.classTable, runtimeCore, false);
                    if (distance !=
                        (int) ProcedureDistance.kInvalidDistance)
                        candidatesWithDistances.Add(fep, distance);
                }

                foreach (FunctionEndPoint fep in functionEndPoint)
                {
                    int dist = fep.ComputeCastDistance(formalParameters, runtimeCore.DSExecutable.classTable, runtimeCore);
                    candidatesWithCastDistances.Add(fep, dist);
                }

                List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances);

                if (candidateFunctions.Count == 0)
                {
                    runtimeCore.RuntimeStatus.LogWarning(WarningID.kAmbiguousMethodDispatch,
                                                  Resources.kAmbigousMethodDispatch);
                    return null;
                }


                FunctionEndPoint compliantTarget = GetCompliantTarget(context, formalParameters, replicationControl,
                                                                      stackFrame, runtimeCore, candidatesWithCastDistances,
                                                                      candidateFunctions, candidatesWithDistances);

                return compliantTarget;
            }
        }
Ejemplo n.º 19
0
        //Inbound methods

        public StackValue JILDispatchViaNewInterpreter(
            Context context, 
            List<StackValue> arguments, 
            List<List<ReplicationGuide>> replicationGuides,
            List<AtLevel> atLevels,
            StackFrame stackFrame, RuntimeCore runtimeCore)
        {
#if DEBUG
            ArgumentSanityCheck(arguments);
#endif
            // Dispatch method
            context.IsImplicitCall = true;
            return DispatchNew(context, arguments, replicationGuides, atLevels, stackFrame, runtimeCore);
        }
Ejemplo n.º 20
0
        private List<FunctionEndPoint> GetCandidateFunctions(StackFrame stackFrame,
                                                             Dictionary<FunctionEndPoint, int> candidatesWithDistances)
        {
            List<FunctionEndPoint> candidateFunctions = new List<FunctionEndPoint>();

            foreach (FunctionEndPoint fep in candidatesWithDistances.Keys)
            {
                if ((stackFrame.ThisPtr.IsPointer &&
                     stackFrame.ThisPtr.opdata == -1 && fep.procedureNode != null
                     && !fep.procedureNode.IsConstructor) && !fep.procedureNode.IsStatic
                    && (fep.procedureNode.ClassID != -1))
                {
                    continue;
                }

                candidateFunctions.Add(fep);
            }
            return candidateFunctions;
        }
Ejemplo n.º 21
0
        private FunctionEndPoint GetCompliantTarget(Context context, List<StackValue> formalParams,
                                                    List<ReplicationInstruction> replicationControl,
                                                    StackFrame stackFrame, RuntimeCore runtimeCore,
                                                    Dictionary<FunctionEndPoint, int> candidatesWithCastDistances,
                                                    List<FunctionEndPoint> candidateFunctions,
                                                    Dictionary<FunctionEndPoint, int> candidatesWithDistances)
        {
            FunctionEndPoint compliantTarget = null;
            //Produce an ordered list of the graph costs
            Dictionary<int, List<FunctionEndPoint>> conversionCostList = new Dictionary<int, List<FunctionEndPoint>>();

            foreach (FunctionEndPoint fep in candidateFunctions)
            {
                int cost = candidatesWithDistances[fep];
                if (conversionCostList.ContainsKey(cost))
                    conversionCostList[cost].Add(fep);
                else
                    conversionCostList.Add(cost, new List<FunctionEndPoint> {fep});
            }

            List<int> conversionCosts = new List<int>(conversionCostList.Keys);
            conversionCosts.Sort();

            List<FunctionEndPoint> fepsToSplit = new List<FunctionEndPoint>();

            foreach (int cost in conversionCosts)
            {
                foreach (FunctionEndPoint funcFep in conversionCostList[cost])
                {
                    if (funcFep.DoesPredicateMatch(context, formalParams, replicationControl))
                    {
                        compliantTarget = funcFep;
                        fepsToSplit.Add(funcFep);
                    }
                }

                if (compliantTarget != null)
                    break;
            }

            if (fepsToSplit.Count > 1)
            {
                int lowestCost = candidatesWithCastDistances[fepsToSplit[0]];
                compliantTarget = fepsToSplit[0];

                List<FunctionEndPoint> lowestCostFeps = new List<FunctionEndPoint>();

                foreach (FunctionEndPoint fep in fepsToSplit)
                {
                    if (candidatesWithCastDistances[fep] < lowestCost)
                    {
                        lowestCost = candidatesWithCastDistances[fep];
                        compliantTarget = fep;
                        lowestCostFeps = new List<FunctionEndPoint>() { fep };
                    }
                    else if (candidatesWithCastDistances[fep] == lowestCost)
                    {
                        lowestCostFeps.Add(fep);
                    }
                }

                //We have multiple feps, e.g. form overriding
                if (lowestCostFeps.Count > 0)
                    compliantTarget = SelectFEPFromMultiple(stackFrame, runtimeCore, lowestCostFeps, formalParams);
            }
            return compliantTarget;
        }
Ejemplo n.º 22
0
        private FunctionEndPoint SelectFEPFromMultiple(StackFrame stackFrame, RuntimeCore runtimeCore,
                                                       List<FunctionEndPoint> feps, List<StackValue> argumentsList)
        {
            StackValue svThisPtr = stackFrame.ThisPtr;
            Validity.Assert(svThisPtr.IsPointer,
                            "this pointer wasn't a pointer. {89635B06-AD53-4170-ADA5-065EB2AE5858}");

            int typeID = 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 (runtimeCore.DSExecutable.classTable.ClassNodes[typeID].Bases.Count > 0)
            {
                Validity.Assert(runtimeCore.DSExecutable.classTable.ClassNodes[typeID].Bases.Count == 1,
                                "Multiple inheritence not yet supported {B93D8D7F-AB4D-4412-8483-33DE739C0ADA}");

                typeID = runtimeCore.DSExecutable.classTable.ClassNodes[typeID].Bases[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 == Constants.kArbitraryRank)
                        noArbitraries++;

                    numberOfArbitraryRanks.Add(noArbitraries);
                }
            }

            int smallest = Int32.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(Resources.MultipleFunctionsFound);
                foreach (FunctionEndPoint fep in feps)
                    possibleFuncs.AppendLine("\t" + fep.ToString());


                possibleFuncs.AppendLine(string.Format(Resources.ErrorCode, "{DCE486C0-0975-49F9-BE2C-2E7D8CCD17DD}"));

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

            return feps[0];
        }
Ejemplo n.º 23
0
            public void PushStackFrame(StackFrame stackFrame, int localSize, int executionStates)
            {
                // TODO Jun: Performance
                // Push frame should only require adjusting the frame index instead of pushing dummy elements
                Validity.Assert(StackFrame.kStackFrameSize == stackFrame.Frame.Length);

                PushFrame(localSize);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kFramePointer]);

                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterTX]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterSX]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterRX]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterLX]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterFX]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterEX]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterDX]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterCX]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterBX]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kRegisterAX]);

                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kExecutionStates]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kLocalVariables]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kStackFrameDepth]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kStackFrameType]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kCallerStackFrameType]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kFunctionCallerBlock]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kFunctionBlock]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kReturnAddress]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kFunction]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kClass]);
                Push(stackFrame.Frame[(int)StackFrame.AbsoluteIndex.kThisPtr]);

                FramePointer = Stack.Count;
            }
Ejemplo n.º 24
0
        private StackValue Execute(
            List<FunctionEndPoint> functionEndPoint, 
            Context c, 
            List<StackValue> formalParameters, 
            List<ReplicationInstruction> replicationInstructions, 
            StackFrame stackFrame, 
            RuntimeCore runtimeCore, 
            FunctionGroup funcGroup)
        {
            SingleRunTraceData singleRunTraceData = (invokeCount < traceData.Count) ? traceData[invokeCount] : new SingleRunTraceData();
            SingleRunTraceData newTraceData = new SingleRunTraceData();
            StackValue ret;

            if (replicationInstructions.Count == 0)
            {
                c.IsReplicating = false;
                ret = ExecWithZeroRI(functionEndPoint, c, formalParameters, stackFrame, runtimeCore, funcGroup,
                    singleRunTraceData, newTraceData);
            }
            else //replicated call
            {
                c.IsReplicating = true;
                ret = ExecWithRISlowPath(functionEndPoint, c, formalParameters, replicationInstructions, stackFrame,
                                         runtimeCore, funcGroup, singleRunTraceData, newTraceData);
            }

            //Do a trace save here
            if (invokeCount < traceData.Count)
            {
                traceData[invokeCount] = newTraceData;
            }
            else
            {
                traceData.Add(newTraceData);
            }

            invokeCount++; //We've completed this invocation
            return ret;
        }
Ejemplo n.º 25
0
        private void BounceExplicit(int exeblock, int entry, Language language, StackFrame frame)
        {
            fepRun = false;
            rmem.PushStackFrame(frame);

            SetupExecutive(exeblock, entry);

            bool debugRun = (0 != (debugFlags & (int)DebugFlags.SPAWN_DEBUGGER));
            if (!fepRun || fepRun && debugRun)
            {
                logVMMessage("Start JIL Execution - " + CoreUtils.GetLanguageString(language));
            }
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Excecute an arbitrary depth replication using the full slow path algorithm
        /// </summary>
        /// <param name="functionEndPoint"> </param>
        /// <param name="c"></param>
        /// <param name="formalParameters"></param>
        /// <param name="replicationInstructions"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        private StackValue ExecWithRISlowPath(
            List<FunctionEndPoint> functionEndPoint, 
            Context c, 
            List<StackValue> formalParameters, 
            List<ReplicationInstruction> replicationInstructions, 
            StackFrame stackFrame, 
            RuntimeCore runtimeCore, 
            FunctionGroup funcGroup, 
            SingleRunTraceData previousTraceData, 
            SingleRunTraceData newTraceData)
        {
            if (runtimeCore.Options.ExecutionMode == ExecutionMode.Parallel)
                throw new NotImplementedException("Parallel mode disabled: {BF417AD5-9EA9-4292-ABBC-3526FC5A149E}");

            //Recursion base case
            if (replicationInstructions.Count == 0)
            {
                return ExecWithZeroRI(functionEndPoint, c, formalParameters, stackFrame, runtimeCore, funcGroup, previousTraceData, newTraceData);
            }

            //Get the replication instruction that this call will deal with
            ReplicationInstruction ri = replicationInstructions[0];

            if (ri.Zipped)
            {
                ZipAlgorithm algorithm = ri.ZipAlgorithm;

                //For each item in this plane, an array of the length of the minimum will be constructed

                //The size of the array will be the minimum size of the passed arrays
                List<int> repIndecies = ri.ZipIndecies;

                //this will hold the heap elements for all the arrays that are going to be replicated over
                List<StackValue[]> parameters = new List<StackValue[]>();

                int retSize;
                switch (algorithm)
                {
                    case ZipAlgorithm.Shortest:
                        retSize = Int32.MaxValue; //Search to find the smallest
                        break;

                    case ZipAlgorithm.Longest:
                        retSize = Int32.MinValue; //Search to find the largest
                        break;

                    default:
                        throw new ReplicationCaseNotCurrentlySupported(Resources.AlgorithmNotSupported);
                }


                bool hasEmptyArg = false;
                foreach (int repIndex in repIndecies)
                {

                    StackValue[] subParameters = null;
                    if (formalParameters[repIndex].IsArray)
                    {
                        subParameters = runtimeCore.Heap.ToHeapObject<DSArray>(formalParameters[repIndex]).Values.ToArray();
                    }
                    else
                    {
                        subParameters = new StackValue[] { formalParameters[repIndex] };
                    }
                    parameters.Add(subParameters);

                    if (subParameters.Length == 0)
                        hasEmptyArg = true;

                    switch (algorithm)
                    {
                        case ZipAlgorithm.Shortest:
                            retSize = Math.Min(retSize, subParameters.Length); //We need the smallest array
                            break;
                        case ZipAlgorithm.Longest:
                            retSize = Math.Max(retSize, subParameters.Length); //We need the longest array
                            break;
                    }

                }

                // If we're being asked to replicate across an empty list
                // then it's always going to be zero, as there will never be any
                // data to pass to that parameter.
                if (hasEmptyArg)
                    retSize = 0;

                StackValue[] retSVs = new StackValue[retSize];
                SingleRunTraceData retTrace = newTraceData;
                retTrace.NestedData = new List<SingleRunTraceData>(); //this will shadow the SVs as they are created

                //Populate out the size of the list with default values
                //@TODO:Luke perf optimisation here
                for (int i = 0; i < retSize; i++)
                    retTrace.NestedData.Add(new SingleRunTraceData());

                for (int i = 0; i < retSize; i++)
                {
                    SingleRunTraceData lastExecTrace = new SingleRunTraceData();

                    if (previousTraceData.HasNestedData && i < previousTraceData.NestedData.Count)
                    {
                        //There was previous data that needs loading into the cache
                        lastExecTrace = previousTraceData.NestedData[i];
                    }
                    else
                    {
                        //We're off the edge of the previous trace window
                        //So just pass in an empty block
                        lastExecTrace = new SingleRunTraceData();
                    }

                    //Build the call
                    List<StackValue> newFormalParams = new List<StackValue>();
                    newFormalParams.AddRange(formalParameters);

                    for (int repIi = 0; repIi < repIndecies.Count; repIi++)
                    {
                        switch (algorithm)
                        {
                            case ZipAlgorithm.Shortest:
                                //If the shortest algorithm is selected this would
                                newFormalParams[repIndecies[repIi]] = parameters[repIi][i];
                                break;
                            
                            case ZipAlgorithm.Longest:

                                int length = parameters[repIi].Length;
                                if (i < length)
                                {
                                    newFormalParams[repIndecies[repIi]] = parameters[repIi][i];
                                }
                                else
                                {
                                    newFormalParams[repIndecies[repIi]] = parameters[repIi].Last();
                                }
                                break;
                        }
                    }

                    List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                    newRIs.AddRange(replicationInstructions);
                    newRIs.RemoveAt(0);


                    SingleRunTraceData cleanRetTrace = new SingleRunTraceData();

                    retSVs[i] = ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, runtimeCore,
                                                    funcGroup, lastExecTrace, cleanRetTrace);

                    runtimeCore.AddCallSiteGCRoot(CallSiteID, retSVs[i]);

                    retTrace.NestedData[i] = cleanRetTrace;
                }

                StackValue ret = runtimeCore.RuntimeMemory.Heap.AllocateArray(retSVs);
                return ret;
            }
            else
            {
                //With a cartesian product over an array, we are going to create an array of n
                //where the n is the product of the next item

                //We will call the subsequent reductions n times
                int cartIndex = ri.CartesianIndex;

                //this will hold the heap elements for all the arrays that are going to be replicated over
                bool supressArray = false;
                int retSize;
                StackValue[] parameters = null; 
                
                if (formalParameters[cartIndex].IsArray)
                {
                    DSArray array = runtimeCore.Heap.ToHeapObject<DSArray>(formalParameters[cartIndex]);
                    parameters = array.Values.ToArray();
                    retSize = parameters.Length;
                }
                else
                {
                    retSize = 1;
                    supressArray = true;
                }

                StackValue[] retSVs = new StackValue[retSize];

                SingleRunTraceData retTrace = newTraceData;
                retTrace.NestedData = new List<SingleRunTraceData>(); //this will shadow the SVs as they are created

                //Populate out the size of the list with default values
                //@TODO:Luke perf optimisation here
                for (int i = 0; i < retSize; i++)
                {
                    retTrace.NestedData.Add(new SingleRunTraceData());
                }

                if (supressArray)
                {
                    List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                    newRIs.AddRange(replicationInstructions);
                    newRIs.RemoveAt(0);

                    List<StackValue> newFormalParams = new List<StackValue>();
                    newFormalParams.AddRange(formalParameters);

                    return ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, runtimeCore,
                                                funcGroup, previousTraceData, newTraceData);
                }

                //Now iterate over each of these options
                for (int i = 0; i < retSize; i++)
                {
                    //Build the call
                    List<StackValue> newFormalParams = new List<StackValue>();
                    newFormalParams.AddRange(formalParameters);

                    if (parameters != null)
                    {
                        //It was an array pack the arg with the current value
                        newFormalParams[cartIndex] = parameters[i];
                    }

                    List<ReplicationInstruction> newRIs = new List<ReplicationInstruction>();
                    newRIs.AddRange(replicationInstructions);
                    newRIs.RemoveAt(0);


                    SingleRunTraceData lastExecTrace;

                    if (previousTraceData.HasNestedData && i < previousTraceData.NestedData.Count)
                    {
                        //There was previous data that needs loading into the cache
                        lastExecTrace = previousTraceData.NestedData[i];
                    }
                    else if (previousTraceData.HasData && i == 0)
                    {
                        //We've moved up one dimension, and there was a previous run
                        lastExecTrace = new SingleRunTraceData();
                        lastExecTrace.Data = previousTraceData.GetLeftMostData();

                    }
                    else
                    {
                        //We're off the edge of the previous trace window
                        //So just pass in an empty block
                        lastExecTrace = new SingleRunTraceData();
                    }

                    //previousTraceData = lastExecTrace;
                    SingleRunTraceData cleanRetTrace = new SingleRunTraceData();

                    retSVs[i] = ExecWithRISlowPath(functionEndPoint, c, newFormalParams, newRIs, stackFrame, runtimeCore,
                                                    funcGroup, lastExecTrace, cleanRetTrace);

                    runtimeCore.AddCallSiteGCRoot(CallSiteID, retSVs[i]);

                    retTrace.NestedData[i] = cleanRetTrace;
                }


                StackValue ret = runtimeCore.RuntimeMemory.Heap.AllocateArray(retSVs);
                return ret;
            }
        }
Ejemplo n.º 27
0
        private void CALL_Handler(Instruction instruction)
        {
            PushInterpreterProps(Properties);

            int fi = instruction.op1.FunctionIndex;
            int ci = instruction.op2.ClassIndex;

            rmem.Pop();

            StackValue svBlock = rmem.Pop();
            int blockId = svBlock.BlockIndex;
            if (runtimeCore.Options.RunMode != InterpreterMode.Expression)
            {
                rmem.PushConstructBlockId(blockId);
            }

            ProcedureNode fNode;
            if (ci != Constants.kInvalidIndex)
            {
                fNode = exe.classTable.ClassNodes[ci].ProcTable.Procedures[fi];
            }
            else
            {
                fNode = exe.procedureTable[blockId].Procedures[fi];
            }

            // Disabling support for stepping into replicating function calls temporarily 
            // This CALL instruction has a corresponding RETC instruction
            // and for debugger purposes for every RETURN/RETC where we restore the states,
            // we need a corresponding SetUpCallr to save the states. Therefore this call here - pratapa
            if (runtimeCore.Options.IDEDebugMode && runtimeCore.Options.RunMode != InterpreterMode.Expression)
            {
                runtimeCore.DebugProps.SetUpCallrForDebug(runtimeCore, this, fNode, pc, true);
            }

            StackValue svThisPointer = StackValue.BuildInvalid();
            int pcoffset = 0;

            // It is to specially handle calling base constructor 
            // from derive class and calling setter. 
            //
            // For the first case, we want to call base constructor 
            // but dont want to allocate memory from the heap again 
            // (instruction ALLOC), so we want to skip the first 
            // instruction in base constructor. Besides, at the end 
            // of base constructor instruction RETC doesnt actually 
            // returns from a function as here we just simulate 
            // function call.

            if (instruction.op3.IsInteger && instruction.op3.IntegerValue >= 0)
            {
                // thisptr should be the pointer to the instance of derive class
                svThisPointer = rmem.GetAtRelative(StackFrame.FrameIndexThisPtr);
                // how many instruction offset? basically it should be 1 to skip ALLOCC
                pcoffset = (int)instruction.op3.IntegerValue;

                // To simulate CALLR. We have to retrive the param values from the
                // stack and reverse these values and save back to the stack. Otherwise
                // in base constructor all params will be in reverse order
                List<StackValue> argvalues = new List<StackValue>();
                int stackindex = rmem.Stack.Count - 1;
                for (int idx = 0; idx < fNode.ArgumentTypes.Count; ++idx)
                {
                    StackValue value = rmem.Stack[stackindex--];
                    argvalues.Add(value);

                    // Probably it is useless in calling base constructor
                    bool hasGuide = rmem.Stack[stackindex].IsReplicationGuide;
                    if (hasGuide)
                    {
                        var replicationGuideList = new List<int>();

                        // Retrieve replication guides
                        value = rmem.Stack[stackindex--];
                        int guides = value.ReplicationGuide;
                        if (guides > 0)
                        {
                            for (int i = 0; i < guides; ++i)
                            {
                                value = rmem.Stack[stackindex--];
                                replicationGuideList.Add(value.ReplicationGuide);
                            }
                        }
                        replicationGuideList.Reverse();
                    }
                }
                rmem.PopFrame(fNode.ArgumentTypes.Count);
                for (int idx = 0; idx < fNode.ArgumentTypes.Count; ++idx)
                {
                    rmem.Push(argvalues[idx]);
                }
            }

            // TODO: Jun: To set these at compile time. They are being hardcoded to 0 temporarily as
            // class methods are always defined only at the global scope
            int blockDecl = 0;
            int blockCaller = 0;


            // Comment Jun: the caller type is the current type in the stackframe
            StackFrameType callerType = (fepRun) ? StackFrameType.Function : StackFrameType.LanguageBlock;

            StackValue svCallConvention = StackValue.BuildCallingConversion((int)CallingConvention.CallType.ExplicitBase);
            TX = svCallConvention;


            // On implicit call, the SX is set in JIL Fep
            // On explicit call, the SX should be directly set here

            List<StackValue> registers = 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 = 0;

            StackFrameType type = StackFrameType.Function;

            StackFrame stackFrame = new StackFrame(svThisPointer, ci, fi, pc + 1, blockDecl, blockCaller, callerType, type, depth, rmem.FramePointer, blockDecl, registers, 0);

            rmem.PushFrameForLocals(fNode.LocalCount);
            rmem.PushStackFrame(stackFrame);

            // Now let's go to the function
            pc = fNode.PC + pcoffset;
            fepRunStack.Push(false);

            // A standard call instruction must reset the graphnodes for associative
            if (Language.Associative == executingLanguage)
            {
                UpdateMethodDependencyGraph(pc, fi, ci);
            }

            if (runtimeCore.Options.RunMode != InterpreterMode.Expression)
            {
                rmem.PopConstructBlockId();
            }
            SetupGraphNodesInScope();
        }
Ejemplo n.º 28
0
        //Single function call
        /// <summary>
        /// Dispatch without replication
        /// </summary>
        private StackValue ExecWithZeroRI(List<FunctionEndPoint> functionEndPoint, Context c,
                                          List<StackValue> formalParameters, StackFrame stackFrame, RuntimeCore runtimeCore,
                                          FunctionGroup funcGroup, SingleRunTraceData previousTraceData, SingleRunTraceData newTraceData)
        {
            if (runtimeCore.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, runtimeCore);

            if (functionEndPoint == null)
            {
                runtimeCore.RuntimeStatus.LogWarning(WarningID.kMethodResolutionFailure, 
                    string.Format(Resources.FunctionDispatchFailed, "{2EB39E1B-557C-4819-94D8-CF7C9F933E8A}"));
                return StackValue.Null;
            }

            if (runtimeCore.Options.IDEDebugMode && runtimeCore.Options.RunMode != InterpreterMode.kExpressionInterpreter)
            {
                DebugFrame debugFrame = runtimeCore.DebugProps.DebugStackFrame.Peek();
                debugFrame.FinalFepChosen = finalFep;
            }

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

            // Correct block id where the function is defined. 
            stackFrame.FunctionBlock = finalFep.BlockScope;

            //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, runtimeCore);

            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, runtimeCore, ret);
            }
            return ret;
        }
Ejemplo n.º 29
0
        private StackValue CallrForMemberFunction(int blockIndex,
                                                  int classIndex,
                                                  int procIndex,
                                                  bool hasDebugInfo,
                                                  ref bool isExplicitCall)
        {
            var svDepth = rmem.Pop();
            Validity.Assert(svDepth.IsInteger);

            var arrayDim = rmem.Pop();
            Validity.Assert(arrayDim.IsArrayDimension);

            ClassNode classNode = exe.classTable.ClassNodes[classIndex];
            ProcedureNode procNode = classNode.ProcTable.Procedures[procIndex];

            // Get all arguments and replications 
            var arguments = PopArgumentsFromStack(procNode.ArgumentTypes.Count);
            arguments.Reverse();
            var repGuides = GetCachedReplicationGuides( arguments.Count + 1);
            var atLevels = GetCachedAtLevels(arguments.Count + 1);

            StackValue lhs = rmem.Pop();
            StackValue thisObject = lhs;
            bool isValidThisPointer = true;
            if (lhs.IsArray)
            {
                isValidThisPointer = ArrayUtils.GetFirstNonArrayStackValue(lhs, ref thisObject, runtimeCore);
                arguments.Insert(0, lhs);
            }

            if (!isValidThisPointer || (!thisObject.IsPointer && !thisObject.IsArray))
            {
                runtimeCore.RuntimeStatus.LogWarning(WarningID.DereferencingNonPointer,
                                              Resources.kDeferencingNonPointer);
                return StackValue.Null;
            }

            var registers = GetRegisters();

            var stackFrame = new StackFrame(thisObject, classIndex, procIndex, pc + 1, 0, runtimeCore.RunningBlock, fepRun ? StackFrameType.Function : StackFrameType.LanguageBlock, StackFrameType.Function, 0, rmem.FramePointer, 0, registers, 0);

            var callsite = runtimeCore.RuntimeData.GetCallSite(exe.ExecutingGraphnode,
                                            classIndex,
                                            procNode.Name,
                                            exe, runtimeCore.RunningBlock, runtimeCore.Options, runtimeCore.RuntimeStatus);

            Validity.Assert(null != callsite);

            bool setDebugProperty = runtimeCore.Options.IDEDebugMode &&
                                    runtimeCore.Options.RunMode != InterpreterMode.Expression &&
                                    procNode != null;

            if (setDebugProperty)
            {
                runtimeCore.DebugProps.SetUpCallrForDebug(
                                                   runtimeCore,
                                                   this,
                                                   procNode,
                                                   pc,
                                                   false,
                                                   callsite,
                                                   arguments,
                                                   repGuides,
                                                   stackFrame,
                                                   null,
                                                   hasDebugInfo);
            }

            var argumentAtLevels = AtLevelHandler.GetArgumentAtLevelStructure(arguments, atLevels, runtimeCore);

            StackValue sv = callsite.JILDispatch(argumentAtLevels.Arguments,
                                                 repGuides,
                                                 argumentAtLevels.DominantStructure,
                                                 stackFrame,
                                                 runtimeCore,
                                                 new Runtime.Context());

            isExplicitCall = sv.IsExplicitCall;
            if (isExplicitCall)
            {
                Properties.functionCallArguments = argumentAtLevels.Arguments;
                Properties.functionCallDotCallDimensions = new List<StackValue>();
                Properties.DominantStructure = argumentAtLevels.DominantStructure;
                CallExplicit(sv.ExplicitCallEntry);
            }

            return sv;
        }
Ejemplo n.º 30
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();

            //
            // Comment Jun:
            // Storing execution states is relevant only if the current scope is a function,
            // as this mechanism is used to keep track of maintining execution states of recursive calls
            // This mechanism should also be ignored if the function call is non-recursive as it does not need to maintains state in that case
            int execStateSize = procedureNode.GraphNodeList.Count;

            stackFrame.ExecutionStateSize = execStateSize;
            for (int n = execStateSize - 1; n >= 0; --n)
            {
                AssociativeGraph.GraphNode gnode = procedureNode.GraphNodeList[n];
                interpreter.Push(StackValue.BuildBoolean(gnode.isDirty));
            }

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

            StackValue svThisPtr   = stackFrame.ThisPtr;
            StackValue svBlockDecl = StackValue.BuildBlockIndex(stackFrame.FunctionBlock);

            // 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   = stackFrame.ReturnPC;
            int blockDecl    = stackFrame.FunctionBlock;
            int blockCaller  = stackFrame.FunctionCallerBlock;
            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;

            StackFrameType callerType = stackFrame.CallerStackFrameType;

            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.TX          = svCallConvention;
            interpreter.runtime.TX = svCallConvention;

            // Set SX register
            stackFrame.SX          = 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 = stackFrame.Depth;

            DSASM.StackFrameType type = stackFrame.StackFrameType;
            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
            {
                svRet             = interpreter.Run(core.RunningBlock, activation.pc, Language.kInvalid, core.Breakpoints);
                core.RunningBlock = origRunningBlock;
            }

            if (core.CurrentExecutive != null)
            {
                core.CurrentExecutive.CurrentDSASMExec = oldDSASMExec;
            }
            return(svRet); //DSASM.Mirror.ExecutionMirror.Unpack(svRet, core.heap, core);
        }
Ejemplo n.º 31
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.º 32
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.º 33
0
        /// <summary>
        /// Execute the data stored in core
        /// This is the entry point of all DS code to be executed
        /// </summary>
        /// <param name="core"></param>
        /// <returns></returns>
        public ProtoCore.RuntimeCore ExecuteVM(ProtoCore.Core core)
        {
            ProtoCore.RuntimeCore runtimeCore = CreateRuntimeCore(core);  
            runtimeCore.StartTimer();
            try
            {
                foreach (ProtoCore.DSASM.CodeBlock codeblock in core.CodeBlockList)
                {
                    // Comment Jun:
                    // On first bounce, the stackframe depth is initialized to -1 in the Stackfame constructor.
                    // Passing it to bounce() increments it so the first depth is always 0
                    ProtoCore.DSASM.StackFrame stackFrame = new ProtoCore.DSASM.StackFrame(core.GlobOffset);
                    stackFrame.FramePointer = runtimeCore.RuntimeMemory.FramePointer;

                    // Comment Jun: Tell the new bounce stackframe that this is an implicit bounce
                    // Register TX is used for this.
                    StackValue svCallConvention = StackValue.BuildCallingConversion((int)ProtoCore.DSASM.CallingConvention.BounceType.kImplicit);
                    stackFrame.TX = svCallConvention;

                    // Initialize the entry point interpreter
                    int locals = 0; // This is the global scope, there are no locals
                    ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(runtimeCore);
                    runtimeCore.CurrentExecutive.CurrentDSASMExec = interpreter.runtime;
                    runtimeCore.CurrentExecutive.CurrentDSASMExec.Bounce(codeblock.codeBlockId, codeblock.instrStream.entrypoint, stackFrame, locals);
                }
                runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.kExecutionEnd);
            }
            catch
            {
                runtimeCore.NotifyExecutionEvent(ProtoCore.ExecutionStateEventArgs.State.kExecutionEnd);
                throw;
            }
            return runtimeCore;
        }
Ejemplo n.º 34
0
        private void ComputeFeps(
            StringBuilder log, 
            Context context, 
            List<StackValue> arguments,
            FunctionGroup funcGroup,
            List<ReplicationInstruction> instructions, 
            List<List<ReplicationGuide>> partialReplicationGuides,
            StackFrame stackFrame,
            RuntimeCore runtimeCore,
            out List<FunctionEndPoint> resolvesFeps,
            out List<ReplicationInstruction> replicationInstructions)
        {
            //With replication guides only

            //Exact match
            //Match with single elements
            //Match with single elements with upcast

            //Try replication without type cast

            //Match with type conversion
            //Match with type conversion with upcast

            //Try replication + type casting

            //Try replication + type casting + Array promotion

            #region First Case: Replicate only according to the replication guides
            {
                log.AppendLine("Case 1: Exact Match");

                FunctionEndPoint fep = Case1GetCompleteMatchFEP(context, arguments, funcGroup, instructions,
                                                                stackFrame,
                                                                runtimeCore, log);
                if (fep != null)
                {
                    if (runtimeCore.Options.DumpFunctionResolverLogic)
                        runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                    resolvesFeps = new List<FunctionEndPoint>() { fep };
                    replicationInstructions = instructions;

                    return;
                }
            }

            #endregion

            #region Case 1a: Replicate only according to the replication guides, but with a sub-typing match
            {
                log.AppendLine("Case 1a: Replication guides + auto-replication + no cases");
                List<List<StackValue>> reducedParams = Replicator.ComputeAllReducedParams(arguments, instructions, runtimeCore);
                int resolutionFailures;

                Dictionary<FunctionEndPoint, int> lookups = funcGroup.GetExactMatchStatistics(
                    context, reducedParams, stackFrame, runtimeCore,
                    out resolutionFailures);

                if (resolutionFailures == 0)
                {
                    log.AppendLine("Resolution succeeded against FEP Cluster");
                    foreach (FunctionEndPoint fep in lookups.Keys)
                        log.AppendLine("\t - " + fep);

                    List<FunctionEndPoint> feps = new List<FunctionEndPoint>();
                    feps.AddRange(lookups.Keys);

                    if (runtimeCore.Options.DumpFunctionResolverLogic)
                        runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                    //Otherwise we have a cluster of FEPs that can be used to dispatch the array
                    resolvesFeps = feps;
                    replicationInstructions = instructions;

                    return;
                }
            }

            #endregion


            var replicationTrials = Replicator.BuildReplicationCombinations(instructions, arguments, runtimeCore);
            #region Case 2: Replication with no type cast

            {
                log.AppendLine("Case 2: Beginning Auto-replication, no casts");

                //Build the possible ways in which we might replicate
                foreach (List<ReplicationInstruction> repOption in replicationTrials)
                {
                    List<List<StackValue>> reducedParams = Replicator.ComputeAllReducedParams(arguments, repOption, runtimeCore);
                    int resolutionFailures;

                    Dictionary<FunctionEndPoint, int> lookups = funcGroup.GetExactMatchStatistics(
                        context, reducedParams, stackFrame, runtimeCore,
                        out resolutionFailures);

                    if (resolutionFailures > 0)
                        continue;

                    log.AppendLine("Resolution succeeded against FEP Cluster");
                    foreach (FunctionEndPoint fep in lookups.Keys)
                        log.AppendLine("\t - " + fep);

                    List<FunctionEndPoint> feps = new List<FunctionEndPoint>();
                    feps.AddRange(lookups.Keys);

                    if (runtimeCore.Options.DumpFunctionResolverLogic)
                        runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                    //Otherwise we have a cluster of FEPs that can be used to dispatch the array
                    resolvesFeps = feps;
                    replicationInstructions = repOption;

                    return;
                }
            }

            #endregion

            #region Case 3: Match with type conversion, but no array promotion
            {
                log.AppendLine("Case 3: Type conversion");

                FunctionEndPoint compliantTarget = GetCompliantFEP(context, arguments, funcGroup, instructions, stackFrame, runtimeCore);

                if (compliantTarget != null)
                {
                    log.AppendLine("Resolution Succeeded: " + compliantTarget);

                    if (runtimeCore.Options.DumpFunctionResolverLogic)
                        runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                    resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
                    replicationInstructions = instructions;
                    return;
                }
            }

            #endregion

            #region Case 4: Match with type conversion and replication

            log.AppendLine("Case 4: Replication + Type conversion");
            {
                if (arguments.Any(arg => arg.IsArray))
                {
                    foreach (List<ReplicationInstruction> replicationOption in replicationTrials)
                    {
                        //@TODO: THis should use the proper reducer?
                        FunctionEndPoint compliantTarget = GetCompliantFEP(context, arguments, funcGroup, replicationOption, stackFrame, runtimeCore);
                        if (compliantTarget != null)
                        {
                            log.AppendLine("Resolution Succeeded: " + compliantTarget);

                            if (runtimeCore.Options.DumpFunctionResolverLogic)
                                runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());

                            resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
                            replicationInstructions = replicationOption;
                            return;
                        }
                    }
                }
            }

            #endregion

            #region Case 5: Match with type conversion, replication and array promotion

            log.AppendLine("Case 5: Replication + Type conversion + Array promotion");
            {
                //Add as a first attempt a no-replication, but allowing up-promoting
                replicationTrials.Insert(0, new List<ReplicationInstruction>());

                foreach (List<ReplicationInstruction> replicationOption in replicationTrials)
                {
                    //@TODO: THis should use the proper reducer?
                    FunctionEndPoint compliantTarget = GetCompliantFEP(context, arguments, funcGroup, replicationOption, stackFrame, runtimeCore, true);
                    if (compliantTarget != null)
                    {
                        log.AppendLine("Resolution Succeeded: " + compliantTarget);

                        if (runtimeCore.Options.DumpFunctionResolverLogic)
                            runtimeCore.DSExecutable.EventSink.PrintMessage(log.ToString());
                        resolvesFeps = new List<FunctionEndPoint>() { compliantTarget };
                        replicationInstructions = replicationOption;
                        return;
                    }
                }
            }

            #endregion


            resolvesFeps = new List<FunctionEndPoint>();
            replicationInstructions = instructions;
        }
Ejemplo n.º 35
0
 public abstract StackValue Execute(ProtoCore.Runtime.Context c, List <StackValue> formalParameters, ProtoCore.DSASM.StackFrame stackFrame, RuntimeCore runtimeCore);
Ejemplo n.º 36
0
        /// <summary>
        /// Get complete match attempts to locate a function endpoint where 1 FEP matches all of the requirements for dispatch
        /// </summary>
        /// <param name="context"></param>
        /// <param name="arguments"></param>
        /// <param name="funcGroup"></param>
        /// <param name="replicationControl"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <param name="log"></param>
        /// <returns></returns>
        private FunctionEndPoint Case1GetCompleteMatchFEP(Context context, List<StackValue> arguments,
                                                          FunctionGroup funcGroup,
                                                          List<ReplicationInstruction> replicationInstructions, StackFrame stackFrame,
                                                          RuntimeCore runtimeCore, StringBuilder log)
        {
            //Exact match
            List<FunctionEndPoint> exactTypeMatchingCandindates =
                funcGroup.GetExactTypeMatches(context, arguments, replicationInstructions, stackFrame, runtimeCore);

            FunctionEndPoint fep = null;

            if (exactTypeMatchingCandindates.Count > 0)
            {
                if (exactTypeMatchingCandindates.Count == 1)
                {
                    //Exact match
                    fep = exactTypeMatchingCandindates[0];
                    log.AppendLine("1 exact match found - FEP selected" + fep);
                }
                else
                {
                    //Exact match with upcast
                    fep = SelectFEPFromMultiple(stackFrame,
                                                runtimeCore,
                                                exactTypeMatchingCandindates, arguments);

                    log.AppendLine(exactTypeMatchingCandindates.Count + "exact matches found - FEP selected" + fep);
                }
            }

            return fep;
        }
Ejemplo n.º 37
0
        public override StackValue Execute(ProtoCore.Runtime.Context c, List <StackValue> formalParameters, ProtoCore.DSASM.StackFrame stackFrame, RuntimeCore runtimeCore)
        {   //  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)
            {
                Interpreter interpreter = new Interpreter(runtimeCore, true);

                // Setup the stack frame data
                StackValue svThisPtr    = stackFrame.ThisPtr;
                int        ci           = activation.JILRecord.classIndex;
                int        fi           = activation.JILRecord.funcIndex;
                int        returnAddr   = stackFrame.ReturnPC;
                int        blockDecl    = stackFrame.FunctionBlock;
                int        blockCaller  = stackFrame.FunctionCallerBlock;
                int        framePointer = runtimeCore.RuntimeMemory.FramePointer;
                int        locals       = activation.JILRecord.locals;


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

                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].ProcTable.Procedures[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 == svThisPtr.Pointer;
                    if (isStaticCall)
                    {
                        stackFrame.ThisPtr = formalParameters[thisPtrIndex];
                    }
                    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)
                    {
                        runtimeCore.RuntimeStatus.LogWarning(ProtoCore.Runtime.WarningID.DereferencingNonPointer, Resources.kDeferencingNonPointer);
                        return(StackValue.Null);
                    }

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

                    svThisPtr = formalParameters[thisPtrIndex];

                    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);
                }

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

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

                    List <StackValue> registers = interpreter.runtime.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      = 0;
                    StackFrameType callerType = stackFrame.CallerStackFrameType;

                    // FFI calls do not have execution states
                    runtimeCore.RuntimeMemory.PushFrameForLocals(locals);
                    StackFrame newStackFrame = new StackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, StackFrameType.Function, depth, framePointer, 0, registers, 0);
                    runtimeCore.RuntimeMemory.PushStackFrame(newStackFrame);

                    //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));
                    }

                    // Clear the FFI stack frame
                    // FFI stack frames have no local variables
                    interpreter.runtime.rmem.FramePointer = (int)interpreter.runtime.rmem.GetAtRelative(StackFrame.FrameIndexFramePointer).IntegerValue;
                    interpreter.runtime.rmem.PopFrame(StackFrame.StackFrameSize + formalParameters.Count);

                    return(op);
                }
            }
        }
Ejemplo n.º 38
0
 /// <summary>
 /// Bounce to an existing executive
 /// </summary>
 /// <param name="exeblock"></param>
 /// <param name="entry"></param>
 /// <param name="context"></param>
 /// <param name="stackFrame"></param>
 /// <param name="locals"></param>
 /// <param name="fepRun"></param>
 /// <param name="exec"></param>
 /// <param name="breakpoints"></param>
 /// <returns></returns>
 public StackValue BounceUsingExecutive(
    DSASM.Executive executive,
    int exeblock,
    int entry,
    StackFrame stackFrame,
    int locals = 0,
    bool fepRun = false,
    DSASM.Executive exec = null,
    List<Instruction> breakpoints = null)
 {
     if (stackFrame != null)
     {
         rmem.PushFrameForLocals(locals);
         rmem.PushStackFrame(stackFrame);
         runtimeCore.DebugProps.SetUpBounce(exec, stackFrame.FunctionCallerBlock, stackFrame.ReturnPC);
     }
     executive.Execute(exeblock, entry, breakpoints);
     return executive.RX;
 }
Ejemplo n.º 39
0
        /// <summary>
        /// Conservative guess as to whether this call will replicate or not
        /// This may give inaccurate answers if the node cluster doesn't actually exist
        /// </summary>
        /// <param name="context"></param>
        /// <param name="arguments"></param>
        /// <param name="stackFrame"></param>
        /// <param name="core"></param>
        /// <returns></returns>
        public bool WillCallReplicate(Context context, List<StackValue> arguments,
                                      List<List<ReplicationGuide>> partialReplicationGuides, StackFrame stackFrame, RuntimeCore runtimeCore,
                                      out List<List<ReplicationInstruction>> replicationTrials)
        {
            replicationTrials = new List<List<ReplicationInstruction>>();

            if (partialReplicationGuides.Count > 0)
            {
                // Jun Comment: And at least one of them contains somthing
                for (int n = 0; n < partialReplicationGuides.Count; ++n)
                {
                    if (partialReplicationGuides[n].Count > 0)
                    {
                        return true;
                    }
                }
            }

            #region Get Function Group

            //@PERF: Possible optimisation point here, to deal with static dispatches that don't need replication analysis
            //Handle resolution Pass 1: Name -> Method Group
            FunctionGroup funcGroup;
            try
            {
                funcGroup = globalFunctionTable.GlobalFuncTable[classScope + 1][methodName];
            }
            catch (KeyNotFoundException)
            {
                return false;
            }

            #endregion

            //Replication Control is an ordered list of the elements that we have to replicate over
            //Ordering implies containment, so element 0 is the outer most forloop, element 1 is nested within it etc.
            //Take the explicit replication guides and build the replication structure
            //Turn the replication guides into a guide -> List args data structure
           var instructions = Replicator.BuildPartialReplicationInstructions(partialReplicationGuides);

            #region First Case: Replicate only according to the replication guides

            {
                FunctionEndPoint fep = Case1GetCompleteMatchFEP(context, arguments, funcGroup, instructions,
                                                                stackFrame,
                                                                runtimeCore, new StringBuilder());
                if (fep != null)
                {
                    //found an exact match
                    return false;
                }
            }

            #endregion

            #region Case 2: Replication with no type cast

            {
                //Build the possible ways in which we might replicate
                replicationTrials = Replicator.BuildReplicationCombinations(instructions, arguments, runtimeCore);

                foreach (List<ReplicationInstruction> replicationOption in replicationTrials)
                {
                    List<List<StackValue>> reducedParams = Replicator.ComputeAllReducedParams(arguments, replicationOption, runtimeCore);
                    int resolutionFailures;

                    funcGroup.GetExactMatchStatistics(context, reducedParams, stackFrame, runtimeCore, out resolutionFailures);

                    if (resolutionFailures > 0)
                        continue;

                    return true; //Replicates against cluster
                }
            }

            #endregion

            #region Case 3: Match with type conversion, but no array promotion

            {
                Dictionary<FunctionEndPoint, int> candidatesWithDistances =
                    funcGroup.GetConversionDistances(context, arguments, instructions,
                                                     runtimeCore.DSExecutable.classTable, runtimeCore);
                Dictionary<FunctionEndPoint, int> candidatesWithCastDistances =
                    funcGroup.GetCastDistances(context, arguments, instructions, runtimeCore.DSExecutable.classTable,
                                               runtimeCore);

                List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances);
                FunctionEndPoint compliantTarget = GetCompliantTarget(context, arguments,
                                                                      instructions, stackFrame, runtimeCore,
                                                                      candidatesWithCastDistances, candidateFunctions,
                                                                      candidatesWithDistances);

                if (compliantTarget != null)
                {
                    return false; //Type conversion but no replication
                }
            }

            #endregion

            #region Case 5: Match with type conversion, replication and array promotion

            {
                //Build the possible ways in which we might replicate
                replicationTrials =
                    Replicator.BuildReplicationCombinations(instructions, arguments, runtimeCore);

                //Add as a first attempt a no-replication, but allowing up-promoting
                replicationTrials.Insert(0,
                                         new List<ReplicationInstruction>()
                    );
            }

            #endregion

            return true; //It'll replicate if it suceeds
        }
Ejemplo n.º 40
0
        public ExecutionMirror Execute(string code)
        {
            code = string.Format("{0} = {1};", Constants.kWatchResultVar, code);

            // TODO Jun: Move this initaliztion of the exe into a unified function
            //Core.ExprInterpreterExe = new Executable();

            int blockId = ProtoCore.DSASM.Constants.kInvalidIndex;

            Core.Rmem.AlignStackForExprInterpreter();

            //Initialize the watch stack and watchBaseOffset
            //The watchBaseOffset is used to indexing the watch variables and related temporary variables
            Core.watchBaseOffset = 0;
            Core.watchStack.Clear();

            bool succeeded = Compile(code, out blockId);

            //Clear the warnings and errors so they will not continue impact the next compilation.
            //Fix IDE-662
            Core.BuildStatus.Errors.Clear();
            Core.BuildStatus.Warnings.Clear();

            for (int i = 0; i < Core.watchBaseOffset; ++i)
            {
                Core.watchStack.Add(StackUtils.BuildNull());
            }

            //Record the old function call depth
            //Fix IDE-523: part of error for watching non-existing member
            int oldFunctionCallDepth = Core.FunctionCallDepth;

            //Record the old start PC
            int oldStartPC = Core.startPC;

            if (succeeded)
            {
                //a2. Record the old start PC for restore instructions
                Core.startPC = Core.ExprInterpreterExe.instrStreamList[blockId].instrList.Count;
                Core.GenerateExprExeInstructions(blockId);

                //a3. Record the old running block
                int restoreBlock = Core.RunningBlock;
                Core.RunningBlock = blockId;

                //a4. Record the old debug entry PC and stack size of FileFepChosen
                int oldDebugEntryPC = Core.DebugProps.DebugEntryPC;

                //a5. Record the frame pointer for referencing to thisPtr
                Core.watchFramePointer = Core.Rmem.FramePointer;

                // The "Core.Bounce" below is gonna adjust the "FramePointer"
                // based on the current size of "Core.Rmem.Stack". All that is
                // good except that "Bounce" does not restore the previous value
                // of frame pointer after "bouncing back". Here we make a backup
                // of it and restore it right after the "Core.Bounce" call.
                //
                //Core.Executives[Core.CodeBlockList[Core.RunningBlock].language].
                ProtoCore.Runtime.Context context = new ProtoCore.Runtime.Context();

                try
                {
                    ProtoCore.DSASM.StackFrame stackFrame = null;
                    int locals = 0;

                    StackValue sv = Core.Bounce(blockId, Core.startPC, context, stackFrame, locals, EventSink);

                    // As Core.InterpreterProps stack member is pushed to every time the Expression Interpreter begins executing
                    // it needs to be popped off at the end for stack alignment - pratapa
                    Core.InterpreterProps.Pop();
                }
                catch
                { }

                //r5. Restore frame pointer.
                Core.Rmem.FramePointer = Core.watchFramePointer;

                //r4. Restore the debug entry PC and stack size of FileFepChosen
                Core.DebugProps.DebugEntryPC = oldDebugEntryPC;

                //r3. Restore the running block
                Core.RunningBlock = restoreBlock;

                //r2. Restore the instructions in Core.ExprInterpreterExe
                int from  = Core.startPC;
                int elems = Core.ExprInterpreterExe.iStreamCanvas.instrList.Count;
                Core.ExprInterpreterExe.instrStreamList[blockId].instrList.RemoveRange(from, elems);

                //Restore the start PC
                Core.startPC = oldStartPC;

                //Restore the function call depth
                //Fix IDE-523: part of error for watching non-existing member
                Core.FunctionCallDepth = oldFunctionCallDepth;


                //Clear the watchSymbolList
                foreach (SymbolNode node in Core.watchSymbolList)
                {
                    if (ProtoCore.DSASM.Constants.kInvalidIndex == node.classScope)
                    {
                        Core.DSExecutable.runtimeSymbols[node.runtimeTableIndex].Remove(node);
                    }
                    else
                    {
                        Core.ClassTable.ClassNodes[node.classScope].symbols.Remove(node);
                    }
                }
            }
            else
            {
                //Restore the start PC
                Core.startPC = oldStartPC;

                //Restore the function call depth
                //Fix IDE-523: part of error for watching non-existing member
                Core.FunctionCallDepth = oldFunctionCallDepth;

                //Clear the watchSymbolList
                foreach (SymbolNode node in Core.watchSymbolList)
                {
                    if (ProtoCore.DSASM.Constants.kInvalidIndex == node.classScope)
                    {
                        Core.DSExecutable.runtimeSymbols[node.runtimeTableIndex].Remove(node);
                    }
                    else
                    {
                        Core.ClassTable.ClassNodes[node.classScope].symbols.Remove(node);
                    }
                }

                // TODO: investigate why additional elements are added to the stack.
                Core.Rmem.RestoreStackForExprInterpreter();

                throw new ProtoCore.Exceptions.CompileErrorsOccured();
            }

            // TODO: investigate why additional elements are added to the stack.
            Core.Rmem.RestoreStackForExprInterpreter();

            return(new ExecutionMirror(Core.CurrentExecutive.CurrentDSASMExec, Core));
        }
        public StackValue Evaluate(List<StackValue> args, StackFrame stackFrame)
        {
            // Build the stackframe
            var runtimeCore = interpreter.runtime.RuntimeCore;

            int classScopeCaller = stackFrame.ClassScope;
            int returnAddr = stackFrame.ReturnPC;
            int blockDecl = procNode.RuntimeIndex;
            int blockCaller = stackFrame.FunctionCallerBlock;
            int framePointer = runtimeCore.RuntimeMemory.FramePointer;
            StackValue thisPtr = StackValue.BuildPointer(Constants.kInvalidIndex);

            // 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.ArgumentInfos.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 = interpreter.runtime.rmem.Heap.AllocateArray(varParams);
                args.Add(packedParams);
            }

            bool isCallingMemberFunciton = procNode.ClassID != 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,
                                              Resources.kDeferencingNonPointer);
                return StackValue.Null;
            }

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

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

            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.Options.RunMode != InterpreterMode.kExpressionInterpreter;
            if (isInDebugMode)
            {
                runtimeCore.DebugProps.SetUpCallrForDebug(
                                                          runtimeCore,
                                                          interpreter.runtime, 
                                                          procNode, 
                                                          returnAddr - 1, 
                                                          false, 
                                                          callsite, 
                                                          args,
                                                          new List<List<ProtoCore.ReplicationGuide>>(), 
                                                          newStackFrame);
            }

            StackValue rx = callsite.JILDispatchViaNewInterpreter(
                                        new Runtime.Context(), 
                                        args,
                                        new List<List<ProtoCore.ReplicationGuide>>(), 
                                        new List<AtLevel>(),
                                        newStackFrame,
                                        runtimeCore);

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

            return rx;
        }
Ejemplo n.º 42
0
        private FunctionEndPoint GetCompliantFEP(
            Context context, 
            List<StackValue> arguments, 
            FunctionGroup funcGroup, 
            List<ReplicationInstruction> replicationInstructions,
            StackFrame stackFrame, 
            RuntimeCore runtimeCore,
            bool allowArrayPromotion = false)
        {
            Dictionary<FunctionEndPoint, int> candidatesWithDistances = 
                funcGroup.GetConversionDistances(
                    context, 
                    arguments, 
                    replicationInstructions, 
                    runtimeCore.DSExecutable.classTable, 
                    runtimeCore,
                    allowArrayPromotion);

            Dictionary<FunctionEndPoint, int> candidatesWithCastDistances =
                funcGroup.GetCastDistances(
                    context, 
                    arguments, 
                    replicationInstructions, 
                    runtimeCore.DSExecutable.classTable, 
                    runtimeCore);

            List<FunctionEndPoint> candidateFunctions = GetCandidateFunctions(stackFrame, candidatesWithDistances);

            FunctionEndPoint compliantTarget = 
                GetCompliantTarget(
                    context, 
                    arguments, 
                    replicationInstructions, 
                    stackFrame,
                    runtimeCore, 
                    candidatesWithCastDistances, 
                    candidateFunctions, 
                    candidatesWithDistances);

            return compliantTarget;
        }