示例#1
0
        private void Init(
            StackValue thisPtr, 
            int classIndex, 
            int functionIndex, 
            int returnAddress, 
            int functionBlockIndex,
            int callerBlockIndex,
            StackFrameType callerStackFrameType,
            StackFrameType stackFrameType,
            int depth,
            int framePointer,
            int blockIndex,
            List<StackValue> registers,
            int execStateSize)
        {
            Frame = new StackValue[StackFrameSize];

            Frame[AbsoluteIndex.ThisPtr] = thisPtr;
            Frame[AbsoluteIndex.ClassIndex] = StackValue.BuildClassIndex(classIndex);
            Frame[AbsoluteIndex.FunctionIndex] = StackValue.BuildFunctionIndex(functionIndex);
            Frame[AbsoluteIndex.ReturnAddress] = StackValue.BuildInt(returnAddress);
            Frame[AbsoluteIndex.FunctionBlockIndex] = StackValue.BuildBlockIndex(functionBlockIndex);
            Frame[AbsoluteIndex.CallerBlockIndex] = StackValue.BuildBlockIndex(callerBlockIndex);
            Frame[AbsoluteIndex.CallerStackFrameType] = StackValue.BuildFrameType((int)callerStackFrameType);
            Frame[AbsoluteIndex.StackFrameType] = StackValue.BuildFrameType((int)stackFrameType);
            Frame[AbsoluteIndex.StackFrameDepth] = StackValue.BuildInt(depth);
            Frame[AbsoluteIndex.LocalVariableCount] = StackValue.BuildInt(0);
            Frame[AbsoluteIndex.ExecutionStates] = StackValue.BuildInt(execStateSize);
            Frame[AbsoluteIndex.BlockIndex] = StackValue.BuildBlockIndex(blockIndex);
            Frame[AbsoluteIndex.RX] = registers[0];
            Frame[AbsoluteIndex.TX] = registers[1];
            Frame[AbsoluteIndex.FramePointer] = StackValue.BuildInt(framePointer);
        }
示例#2
0
        private void Init(
            StackValue thisPtr,
            int classIndex,
            int functionIndex,
            int returnAddress,
            int functionBlockIndex,
            int callerBlockIndex,
            StackFrameType callerStackFrameType,
            StackFrameType stackFrameType,
            int depth,
            int framePointer,
            int blockIndex,
            List <StackValue> registers,
            int execStateSize)
        {
            Frame = new StackValue[StackFrameSize];

            Frame[AbsoluteIndex.ThisPtr]              = thisPtr;
            Frame[AbsoluteIndex.ClassIndex]           = StackValue.BuildClassIndex(classIndex);
            Frame[AbsoluteIndex.FunctionIndex]        = StackValue.BuildFunctionIndex(functionIndex);
            Frame[AbsoluteIndex.ReturnAddress]        = StackValue.BuildInt(returnAddress);
            Frame[AbsoluteIndex.FunctionBlockIndex]   = StackValue.BuildBlockIndex(functionBlockIndex);
            Frame[AbsoluteIndex.CallerBlockIndex]     = StackValue.BuildBlockIndex(callerBlockIndex);
            Frame[AbsoluteIndex.CallerStackFrameType] = StackValue.BuildFrameType((int)callerStackFrameType);
            Frame[AbsoluteIndex.StackFrameType]       = StackValue.BuildFrameType((int)stackFrameType);
            Frame[AbsoluteIndex.StackFrameDepth]      = StackValue.BuildInt(depth);
            Frame[AbsoluteIndex.LocalVariableCount]   = StackValue.BuildInt(0);
            Frame[AbsoluteIndex.ExecutionStates]      = StackValue.BuildInt(execStateSize);
            Frame[AbsoluteIndex.BlockIndex]           = StackValue.BuildBlockIndex(blockIndex);
            Frame[AbsoluteIndex.RX]           = registers[0];
            Frame[AbsoluteIndex.TX]           = registers[1];
            Frame[AbsoluteIndex.FramePointer] = StackValue.BuildInt(framePointer);
        }
示例#3
0
        public static SDCombinedStackFrame ToSDModel(this ClrStackFrame frame)
        {
            StackFrameType type =
                (frame.Kind == ClrStackFrameType.ManagedMethod) ? StackFrameType.Managed :
                (frame.Kind == ClrStackFrameType.Runtime) ? StackFrameType.Special :
                /* here be dragons */ StackFrameType.Special;


            string methodName;
            string moduleName = string.Empty;

            if (frame.Method == null)
            {
                methodName = frame.DisplayString;                 //for example GCFrame
            }
            else
            {
                methodName = frame.Method.GetFullSignature();
                if (frame.Method.Type != null)
                {
                    moduleName = Path.GetFileNameWithoutExtension(frame.Method.Type.Module.Name);
                    if (string.IsNullOrEmpty(moduleName))
                    {
                        moduleName = "UNKNOWN";
                    }
                }
            }
            return(new SDCombinedStackFrame(type, frame.InstructionPointer, frame.StackPointer, methodName, moduleName, frame.Method.NativeCode));
        }
示例#4
0
        public SDCombinedStackFrame(StackFrameType type, ulong instructionPointer, ulong stackPointer, string methodName, string moduleName, ulong nativeCode)
        {
            Type = type;
            InstructionPointer = instructionPointer;
            StackPointer       = stackPointer;
            MethodName         = methodName;
            ModuleName         = moduleName;

            // calculate IL offset with instruction pointer of frame and instruction pointer
            // in the target dump file of the start of the method's assembly
            OffsetInMethod = InstructionPointer - nativeCode;
        }
示例#5
0
 public SDCombinedStackFrame(StackFrameType type, string moduleName, string methodName, ulong offsetInMethod, ulong ip, ulong sp, ulong returnOffset, ulong spOffset, SDFileAndLineNumber sourceInfo)
 {
     this.Type               = type;
     this.ModuleName         = moduleName;
     this.MethodName         = methodName;
     this.OffsetInMethod     = offsetInMethod;
     this.InstructionPointer = ip;
     this.StackPointer       = sp;
     this.ReturnOffset       = returnOffset;
     this.LinkedStackFrame   = null;
     this.StackPointerOffset = spOffset;
     this.SourceInfo         = sourceInfo;
 }
 public SDCombinedStackFrame(StackFrameType type, string moduleName, string methodName,
                             ulong offsetInMethod, ulong instructionPointer, ulong stackPointer,
                             ulong returnOffset, SDCombinedStackFrame linkedFrame)
 {
     this.Type               = type;
     this.ModuleName         = moduleName;
     this.MethodName         = methodName;
     this.OffsetInMethod     = offsetInMethod;
     this.InstructionPointer = instructionPointer;
     this.StackPointer       = stackPointer;
     this.ReturnOffset       = returnOffset;
     this.LinkedStackFrame   = linkedFrame;
 }
        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);
        }
示例#8
0
        public StackFrame(int globalOffset)
        {
            StackValue svThisPtr   = ProtoCore.DSASM.StackValue.BuildPointer(Constants.kInvalidPointer);
            int        ci          = Constants.kInvalidIndex;
            int        fi          = Constants.kInvalidIndex;
            int        returnAddr  = Constants.kInvalidIndex;
            int        blockDecl   = Constants.kInvalidIndex;
            int        blockCaller = 0;

            StackFrameType callerType   = DSASM.StackFrameType.kTypeLanguage;
            StackFrameType type         = DSASM.StackFrameType.kTypeLanguage;
            int            depth        = -1;
            int            framePointer = globalOffset;

            Init(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, type, depth, framePointer, StackValue.BuildInvalidRegisters(), new List <bool>());
        }
示例#9
0
 public StackFrame(
     StackValue thisPtr,
     int classIndex,
     int functionIndex,
     int returnAddress,
     int functionBlockIndex,
     int callerBlockIndex,
     StackFrameType callerStackFrameType,
     StackFrameType stackFrameType,
     int depth,
     int framePointer,
     int blockIndex,
     List <StackValue> registers,
     int executionStateSize)
 {
     Init(thisPtr, classIndex, functionIndex, returnAddress, functionBlockIndex, callerBlockIndex, callerStackFrameType, stackFrameType, depth, framePointer, blockIndex, registers, executionStateSize);
 }
示例#10
0
文件: Stack.cs 项目: qingemeng/Dynamo
        private void Init(StackValue svThisPtr, int classIndex, int funcIndex, int pc, int functionBlockDecl, int functionBlockCaller, StackFrameType callerType, StackFrameType type, int depth,
           int framePointer, List<StackValue> stack, List<bool> execStates)
        {
            Validity.Assert((int)StackFrame.AbsoluteIndex.kSize == kStackFrameSize);

            Frame = new StackValue[kStackFrameSize];

            Frame[(int)AbsoluteIndex.kFramePointer] = StackValue.BuildInt(framePointer);
            Frame[(int)AbsoluteIndex.kStackFrameType] = StackValue.BuildFrameType((int)type);
            Frame[(int)AbsoluteIndex.kCallerStackFrameType] = StackValue.BuildFrameType((int)callerType);
            Frame[(int)AbsoluteIndex.kStackFrameDepth] = StackValue.BuildInt(depth);
            Frame[(int)AbsoluteIndex.kFunctionCallerBlock] = StackValue.BuildBlockIndex(functionBlockCaller);
            Frame[(int)AbsoluteIndex.kFunctionBlock] = StackValue.BuildBlockIndex(functionBlockDecl);
            Frame[(int)AbsoluteIndex.kReturnAddress] = StackValue.BuildInt(pc);
            Frame[(int)AbsoluteIndex.kFunction] = StackValue.BuildInt(funcIndex);
            Frame[(int)AbsoluteIndex.kClass] = StackValue.BuildInt(classIndex);
            Frame[(int)AbsoluteIndex.kThisPtr] = svThisPtr;

            Frame[(int)AbsoluteIndex.kRegisterAX] = stack[0];
            Frame[(int)AbsoluteIndex.kRegisterBX] = stack[1];
            Frame[(int)AbsoluteIndex.kRegisterCX] = stack[2];
            Frame[(int)AbsoluteIndex.kRegisterDX] = stack[3];
            Frame[(int)AbsoluteIndex.kRegisterEX] = stack[4];
            Frame[(int)AbsoluteIndex.kRegisterFX] = stack[5];
            Frame[(int)AbsoluteIndex.kRegisterLX] = stack[6];
            Frame[(int)AbsoluteIndex.kRegisterRX] = stack[7];
            Frame[(int)AbsoluteIndex.kRegisterSX] = stack[8];
            Frame[(int)AbsoluteIndex.kRegisterTX] = stack[9];

            int execStateSize = 0;
            if (null != execStates)
            {
                execStateSize = execStates.Count;
                ExecutionStates = new StackValue[execStateSize];
                for (int n = 0; n < execStateSize; ++n)
                {
                    ExecutionStates[n] = StackValue.BuildBoolean(execStates[n]);
                }
            }

            Frame[(int)AbsoluteIndex.kExecutionStates] = StackValue.BuildInt(execStateSize);
            Frame[(int)AbsoluteIndex.kLocalVariables] = StackValue.BuildInt(0);
            
            Validity.Assert(kStackFrameSize == Frame.Length);
        }
示例#11
0
 public void PushStackFrame(StackValue svThisPtr, int classIndex, int funcIndex, int pc, int functionBlockDecl, int functionBlockCaller, StackFrameType callerType, StackFrameType type, int depth, int fp, List <StackValue> registers, int locsize, int executionStates)
 {
     // TODO Jun: Performance
     // Push frame should only require adjusting the frame index instead of pushing dummy elements
     PushFrame(locsize);
     Push(StackValue.BuildInt(fp));
     PushRegisters(registers);
     Push(StackValue.BuildInt(executionStates));
     Push(StackValue.BuildInt(0));
     Push(StackValue.BuildInt(depth));
     Push(StackValue.BuildFrameType((int)type));
     Push(StackValue.BuildFrameType((int)callerType));
     Push(StackValue.BuildBlockIndex(functionBlockCaller));
     Push(StackValue.BuildBlockIndex(functionBlockDecl));
     Push(StackValue.BuildInt(pc));
     Push(StackValue.BuildInt(funcIndex));
     Push(StackValue.BuildInt(classIndex));
     Push(svThisPtr);
     FramePointer = Stack.Count;
 }
示例#12
0
文件: Stack.cs 项目: qingemeng/Dynamo
 public StackFrame(StackValue svThisPtr, int classIndex, int funcIndex, int pc, int functionBlockDecl, int functionBlockCaller, StackFrameType callerType, StackFrameType type, int depth, int framePointer, List<StackValue> stack, List<bool> execStates) 
 {
     Init(svThisPtr, classIndex, funcIndex, pc, functionBlockDecl, functionBlockCaller, callerType, type, depth, framePointer, stack, execStates);
 }
示例#13
0
        private void Init(StackValue svThisPtr, int classIndex, int funcIndex, int pc, int functionBlockDecl, int functionBlockCaller, StackFrameType callerType, StackFrameType type, int depth,
                          int framePointer, List <StackValue> stack, List <bool> execStates)
        {
            Validity.Assert((int)StackFrame.AbsoluteIndex.kSize == kStackFrameSize);

            Frame = new StackValue[kStackFrameSize];

            Frame[(int)AbsoluteIndex.kFramePointer]         = StackValue.BuildInt(framePointer);
            Frame[(int)AbsoluteIndex.kStackFrameType]       = StackValue.BuildFrameType((int)type);
            Frame[(int)AbsoluteIndex.kCallerStackFrameType] = StackValue.BuildFrameType((int)callerType);
            Frame[(int)AbsoluteIndex.kStackFrameDepth]      = StackValue.BuildInt(depth);
            Frame[(int)AbsoluteIndex.kFunctionCallerBlock]  = StackValue.BuildBlockIndex(functionBlockCaller);
            Frame[(int)AbsoluteIndex.kFunctionBlock]        = StackValue.BuildBlockIndex(functionBlockDecl);
            Frame[(int)AbsoluteIndex.kReturnAddress]        = StackValue.BuildInt(pc);
            Frame[(int)AbsoluteIndex.kFunction]             = StackValue.BuildInt(funcIndex);
            Frame[(int)AbsoluteIndex.kClass]   = StackValue.BuildInt(classIndex);
            Frame[(int)AbsoluteIndex.kThisPtr] = svThisPtr;

            Frame[(int)AbsoluteIndex.kRegisterAX] = stack[0];
            Frame[(int)AbsoluteIndex.kRegisterBX] = stack[1];
            Frame[(int)AbsoluteIndex.kRegisterCX] = stack[2];
            Frame[(int)AbsoluteIndex.kRegisterDX] = stack[3];
            Frame[(int)AbsoluteIndex.kRegisterEX] = stack[4];
            Frame[(int)AbsoluteIndex.kRegisterFX] = stack[5];
            Frame[(int)AbsoluteIndex.kRegisterLX] = stack[6];
            Frame[(int)AbsoluteIndex.kRegisterRX] = stack[7];
            Frame[(int)AbsoluteIndex.kRegisterSX] = stack[8];
            Frame[(int)AbsoluteIndex.kRegisterTX] = stack[9];

            int execStateSize = 0;

            if (null != execStates)
            {
                execStateSize   = execStates.Count;
                ExecutionStates = new StackValue[execStateSize];
                for (int n = 0; n < execStateSize; ++n)
                {
                    ExecutionStates[n] = StackValue.BuildBoolean(execStates[n]);
                }
            }

            Frame[(int)AbsoluteIndex.kExecutionStates] = StackValue.BuildInt(execStateSize);
            Frame[(int)AbsoluteIndex.kLocalVariables]  = StackValue.BuildInt(0);

            Validity.Assert(kStackFrameSize == Frame.Length);
        }
示例#14
0
 public void PushStackFrame(StackValue svThisPtr, int classIndex, int funcIndex, int pc, int functionBlockDecl, int functionBlockCaller, StackFrameType callerType, StackFrameType type, int depth, int fp, List<StackValue> registers, int locsize, int executionStates)
 {
     // TODO Jun: Performance
     // Push frame should only require adjusting the frame index instead of pushing dummy elements
     PushFrame(locsize);
     Push(StackValue.BuildInt(fp));
     PushRegisters(registers);
     Push(StackValue.BuildInt(executionStates));
     Push(StackValue.BuildInt(0));
     Push(StackValue.BuildInt(depth));
     Push(StackValue.BuildFrameType((int)type));
     Push(StackValue.BuildFrameType((int)callerType));
     Push(StackValue.BuildBlockIndex(functionBlockCaller));
     Push(StackValue.BuildBlockIndex(functionBlockDecl));
     Push(StackValue.BuildInt(pc));
     Push(StackValue.BuildInt(funcIndex));
     Push(StackValue.BuildInt(classIndex));
     Push(svThisPtr);
     FramePointer = Stack.Count;
 }
示例#15
0
 public StackFrame(StackValue svThisPtr, int classIndex, int funcIndex, int pc, int functionBlockDecl, int functionBlockCaller, StackFrameType callerType, StackFrameType type, int depth, int framePointer, List <StackValue> stack, List <bool> execStates)
 {
     Init(svThisPtr, classIndex, funcIndex, pc, functionBlockDecl, functionBlockCaller, callerType, type, depth, framePointer, stack, execStates);
 }
示例#16
0
        private void Init(StackValue svThisPtr, int classIndex, int funcIndex, int pc, int functionBlockDecl, int functionBlockCaller, StackFrameType callerType, StackFrameType type, int depth,
                          int framePointer, List <StackValue> stack)
        {
            Validity.Assert((int)StackFrame.AbsoluteIndex.kSize == kStackFrameSize);

            Frame = new StackValue[kStackFrameSize];

            Frame[(int)AbsoluteIndex.kFramePointer]         = StackUtils.BuildInt(framePointer);
            Frame[(int)AbsoluteIndex.kStackFrameType]       = StackUtils.BuildNode(AddressType.FrameType, (int)type);
            Frame[(int)AbsoluteIndex.kCallerStackFrameType] = StackUtils.BuildNode(AddressType.FrameType, (int)callerType);
            Frame[(int)AbsoluteIndex.kStackFrameDepth]      = StackUtils.BuildInt(depth);
            Frame[(int)AbsoluteIndex.kFunctionCallerBlock]  = StackUtils.BuildNode(AddressType.BlockIndex, functionBlockCaller);
            Frame[(int)AbsoluteIndex.kFunctionBlock]        = StackUtils.BuildNode(AddressType.BlockIndex, functionBlockDecl);
            Frame[(int)AbsoluteIndex.kReturnAddress]        = StackUtils.BuildInt(pc);
            Frame[(int)AbsoluteIndex.kFunction]             = StackUtils.BuildInt(funcIndex);
            Frame[(int)AbsoluteIndex.kClass]   = StackUtils.BuildInt(classIndex);
            Frame[(int)AbsoluteIndex.kThisPtr] = svThisPtr;

            Frame[(int)AbsoluteIndex.kRegisterAX] = stack[0];
            Frame[(int)AbsoluteIndex.kRegisterBX] = stack[1];
            Frame[(int)AbsoluteIndex.kRegisterCX] = stack[2];
            Frame[(int)AbsoluteIndex.kRegisterDX] = stack[3];
            Frame[(int)AbsoluteIndex.kRegisterEX] = stack[4];
            Frame[(int)AbsoluteIndex.kRegisterFX] = stack[5];
            Frame[(int)AbsoluteIndex.kRegisterLX] = stack[6];
            Frame[(int)AbsoluteIndex.kRegisterRX] = stack[7];
            Frame[(int)AbsoluteIndex.kRegisterSX] = stack[8];
            Frame[(int)AbsoluteIndex.kRegisterTX] = stack[9];

            Validity.Assert(kStackFrameSize == Frame.Length);
        }
        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);
                }
            }
        }
示例#18
0
        private void Init(StackValue svThisPtr, int classIndex, int funcIndex, int pc, int functionBlockDecl, int functionBlockCaller, StackFrameType callerType, StackFrameType type, int depth,
            int framePointer, List<StackValue> stack)
        {
            Validity.Assert((int)StackFrame.AbsoluteIndex.kSize == kStackFrameSize);

            Frame = new StackValue[kStackFrameSize];

            Frame[(int)AbsoluteIndex.kFramePointer] = StackUtils.BuildInt(framePointer);
            Frame[(int)AbsoluteIndex.kStackFrameType] = StackUtils.BuildNode(AddressType.FrameType, (int)type);
            Frame[(int)AbsoluteIndex.kCallerStackFrameType] = StackUtils.BuildNode(AddressType.FrameType, (int)callerType);
            Frame[(int)AbsoluteIndex.kStackFrameDepth] = StackUtils.BuildInt(depth);
            Frame[(int)AbsoluteIndex.kFunctionCallerBlock] = StackUtils.BuildNode(AddressType.BlockIndex, functionBlockCaller);
            Frame[(int)AbsoluteIndex.kFunctionBlock] = StackUtils.BuildNode(AddressType.BlockIndex, functionBlockDecl);
            Frame[(int)AbsoluteIndex.kReturnAddress] = StackUtils.BuildInt(pc);
            Frame[(int)AbsoluteIndex.kFunction] = StackUtils.BuildInt(funcIndex);
            Frame[(int)AbsoluteIndex.kClass] = StackUtils.BuildInt(classIndex);
            Frame[(int)AbsoluteIndex.kThisPtr] = svThisPtr;

            Frame[(int)AbsoluteIndex.kRegisterAX] = stack[0];
            Frame[(int)AbsoluteIndex.kRegisterBX] = stack[1];
            Frame[(int)AbsoluteIndex.kRegisterCX] = stack[2];
            Frame[(int)AbsoluteIndex.kRegisterDX] = stack[3];
            Frame[(int)AbsoluteIndex.kRegisterEX] = stack[4];
            Frame[(int)AbsoluteIndex.kRegisterFX] = stack[5];
            Frame[(int)AbsoluteIndex.kRegisterLX] = stack[6];
            Frame[(int)AbsoluteIndex.kRegisterRX] = stack[7];
            Frame[(int)AbsoluteIndex.kRegisterSX] = stack[8];
            Frame[(int)AbsoluteIndex.kRegisterTX] = stack[9];

            Validity.Assert(kStackFrameSize == Frame.Length);
        }
示例#19
0
 public void PushStackFrame(int ptr, int classIndex, int funcIndex, int pc, int functionBlockDecl, int functionBlockCaller, StackFrameType callerType, StackFrameType type, int depth, int fp, List <StackValue> registers, int locsize)
 {
     // TODO Jun: Performance
     // Push frame should only require adjusting the frame index instead of pushing dummy elements
     PushFrame(locsize);
     Push(StackUtils.BuildInt(fp));
     PushRegisters(registers);
     Push(StackUtils.BuildNode(AddressType.Int, depth));
     Push(StackUtils.BuildNode(AddressType.FrameType, (int)type));
     Push(StackUtils.BuildNode(AddressType.FrameType, (int)callerType));
     Push(StackUtils.BuildNode(AddressType.BlockIndex, functionBlockCaller));
     Push(StackUtils.BuildNode(AddressType.BlockIndex, functionBlockDecl));
     Push(StackUtils.BuildInt(pc));
     Push(StackUtils.BuildInt(funcIndex));
     Push(StackUtils.BuildInt(classIndex));
     Push(StackUtils.BuildPointer(ptr));
     FramePointer = Stack.Count;
 }
示例#20
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);
        }
示例#21
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);
                }
            }
        }
示例#22
0
文件: Stack.cs 项目: limrzx/Dynamo
 public StackFrame(
     StackValue thisPtr, 
     int classIndex,
     int functionIndex,
     int returnAddress,
     int functionBlockIndex,
     int callerBlockIndex,
     StackFrameType callerStackFrameType,
     StackFrameType stackFrameType,
     int depth,
     int framePointer,
     List<StackValue> registers,
     int executionStateSize) 
 {
     Init(thisPtr, classIndex, functionIndex, returnAddress, functionBlockIndex, callerBlockIndex, callerStackFrameType, stackFrameType, depth, framePointer, registers, executionStateSize);
 }
示例#23
0
 public void PushStackFrame(int ptr, int classIndex, int funcIndex, int pc, int functionBlockDecl, int functionBlockCaller, StackFrameType callerType, StackFrameType type, int depth, int fp, List<StackValue> registers, int locsize)
 {
     // TODO Jun: Performance
     // Push frame should only require adjusting the frame index instead of pushing dummy elements
     PushFrame(locsize);
     Push(StackUtils.BuildInt(fp));
     PushRegisters(registers);
     Push(StackUtils.BuildNode(AddressType.Int, depth));
     Push(StackUtils.BuildNode(AddressType.FrameType, (int)type));
     Push(StackUtils.BuildNode(AddressType.FrameType, (int)callerType));
     Push(StackUtils.BuildNode(AddressType.BlockIndex, functionBlockCaller));
     Push(StackUtils.BuildNode(AddressType.BlockIndex, functionBlockDecl));
     Push(StackUtils.BuildInt(pc));
     Push(StackUtils.BuildInt(funcIndex));
     Push(StackUtils.BuildInt(classIndex));
     Push(StackUtils.BuildPointer(ptr));
     FramePointer = Stack.Count;
 }