Beispiel #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);
        }
Beispiel #2
0
        internal object GetCLRObject(StackValue svData, Core core)
        {
            if (null == core.DSExecutable.classTable)
            {
                return(null);
            }

            IList <ClassNode> classNodes = core.DSExecutable.classTable.ClassNodes;

            if (null == classNodes || (classNodes.Count <= 0))
            {
                return(null);
            }

            ClassNode classnode = core.DSExecutable.classTable.ClassNodes[(int)svData.metaData.type];

            if (!classnode.IsImportedClass) //TODO: look at properties to see if it contains any FFI objects.
            {
                return(null);
            }

            try
            {
                ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(core, false);
                var helper    = ProtoFFI.DLLFFIHandler.GetModuleHelper(ProtoFFI.FFILanguage.CSharp);
                var marshaler = helper.GetMarshaller(core);
                return(marshaler.UnMarshal(svData, null, interpreter, typeof(object)));
            }
            catch (System.Exception)
            {
                return(null);
            }
        }
Beispiel #3
0
        private ExecutionMirror Execute(int programCounterToExecuteFrom, List <Instruction> breakpoints, bool fepRun = false)
        {
            runtimeCore.Breakpoints = breakpoints;
            resumeBlockID           = runtimeCore.RunningBlock;


            if (runtimeCore.DebugProps.FirstStackFrame != null)
            {
                runtimeCore.DebugProps.FirstStackFrame.FramePointer = 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);
                runtimeCore.DebugProps.FirstStackFrame.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(
                resumeBlockID,
                programCounterToExecuteFrom,
                runtimeCore.DebugProps.FirstStackFrame,
                locals,
                fepRun,
                null,
                breakpoints);

            return(new ExecutionMirror(runtimeCore.CurrentExecutive.CurrentDSASMExec, runtimeCore));
        }
        public override StackValue Execute(int codeblock, int entry, ProtoCore.Runtime.Context callContext, System.Collections.Generic.List <Instruction> breakpoints, ProtoCore.DebugServices.EventSink sink = null, bool fepRun = false)
        {
            ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(core, fepRun);
            CurrentDSASMExec = interpreter.runtime;
            StackValue sv = interpreter.Run(breakpoints, codeblock, entry, Language.kAssociative);

            return(sv);
        }
Beispiel #5
0
        public override object Execute(ProtoCore.Runtime.Context context, ProtoCore.DSASM.Interpreter dsi)
        {
            int paramCount      = mArgTypes.Count;
            int envSize         = IsDNI ? 2 : 0;
            int totalParamCount = paramCount + envSize;

            List <Object>     parameters = new List <object>();
            List <StackValue> s          = dsi.runtime.rmem.Stack;

            if (IsDNI)
            {
                parameters.Add(DLLFFIHandler.Env);
                parameters.Add((Int64)0);
            }
            for (int i = 0; i < mArgTypes.Count; ++i)
            {
                // Comment Jun: FFI function stack frames do not contain locals
                int        locals   = 0;
                int        relative = 0 - ProtoCore.DSASM.StackFrame.kStackFrameSize - locals - i - 1;
                StackValue o        = dsi.runtime.rmem.GetAtRelative(relative);

                if (o.optype == ProtoCore.DSASM.AddressType.Int)
                {
                    if (mArgTypes[i].Name == "double")
                    {
                        //  if the function expects a double and we have passed an int
                        //  in an int then promote it to be a double!
                        //
                        parameters.Add(o.opdata_d);
                    }
                    else
                    {
                        parameters.Add(o.opdata);
                    }
                }
                else if (o.optype == ProtoCore.DSASM.AddressType.Double)
                {
                    parameters.Add(o.opdata_d);
                }
                else if (o.optype == ProtoCore.DSASM.AddressType.ArrayPointer)
                {
                    int    size  = 0;
                    object array = GetArray(o, dsi, out size);
                    parameters.Add(array);
                    parameters.Add(size);
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
            //object ret = mFunction.Invoke(parameters);
            object ret = mFunction.Execute(parameters.ToArray());

            return(ConvertReturnValue(ret, context, dsi));
        }
Beispiel #6
0
        private object ConvertCSArrayToDSArray(double[] csArray, ProtoCore.DSASM.Interpreter dsi)
        {
            var    runtimeCore = dsi.runtime.RuntimeCore;
            object retVal      = null;

            var values = csArray.Select(x => StackValue.BuildDouble(x)).ToArray();

            retVal = runtimeCore.RuntimeMemory.Heap.AllocateArray(values);
            return(retVal);
        }
 public override StackValue Execute(int codeblock, int entry, ProtoCore.Runtime.Context callContext, ProtoCore.DebugServices.EventSink sink)
 {
     if (!core.Options.CompileToLib)
     {
         ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(core);
         CurrentDSASMExec = interpreter.runtime;
         StackValue sv = interpreter.Run(codeblock, entry, Language.kAssociative);
         return(sv);
     }
     else
     {
         return(StackValue.Null);
     }
 }
Beispiel #8
0
 public override StackValue Execute(int codeblock, int entry, ProtoCore.Runtime.Context callContext, ProtoCore.DebugServices.EventSink sink)
 {
     if (!core.Options.CompileToLib)
     {
         ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(core);
         CurrentDSASMExec = interpreter.runtime;
         var sv = interpreter.Run(codeblock, entry, ProtoCore.Language.kImperative);
         return sv;
     }
     else
     {
         return StackValue.Null;
     }
 }
        public FunctionPointerEvaluator(StackValue pointer, Interpreter dsi)
        {
            Validity.Assert(pointer.optype == AddressType.FunctionPointer);
            mRunTime = dsi;
            Core core = dsi.runtime.Core;

            int fptr = (int)pointer.opdata;
            ProtoCore.DSASM.FunctionPointerNode fptrNode;
            if (core.FunctionPointerTable.functionPointerDictionary.TryGetByFirst(fptr, out fptrNode))
            {
                int blockId = fptrNode.blockId;
                int procId = fptrNode.procId;
                mProcNode = dsi.runtime.exe.procedureTable[blockId].procList[procId];
            }

            mCallSite = new ProtoCore.CallSite(ProtoCore.DSASM.Constants.kGlobalScope, Name, core.FunctionTable, core.Options.ExecutionMode);
        }
Beispiel #10
0
        private object ConvertCSArrayToDSArray(double[] csArray, ProtoCore.DSASM.Interpreter dsi)
        {
            var    runtimeCore = dsi.runtime.RuntimeCore;
            object retVal      = null;

            var values = csArray.Select(x => StackValue.BuildDouble(x)).ToArray();

            try
            {
                retVal = runtimeCore.RuntimeMemory.Heap.AllocateArray(values);
                return(retVal);
            }
            catch (RunOutOfMemoryException)
            {
                dsi.runtime.RuntimeCore.RuntimeStatus.LogWarning(ProtoCore.Runtime.WarningID.RunOutOfMemory, ProtoCore.Properties.Resources.RunOutOfMemory);
                return(StackValue.Null);
            }
        }
Beispiel #11
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);
        }
Beispiel #12
0
        private object ConvertCSArrayToDSArray(double[] csArray, ProtoCore.DSASM.Interpreter dsi)
        {
            var    core   = dsi.runtime.Core;
            object retVal = null;

            lock (core.Heap.cslock)
            {
                var numElems = csArray.Length;
                int ptr      = core.Heap.Allocate(numElems);
                for (int n = numElems - 1; n >= 0; --n)
                {
                    core.Heap.Heaplist[ptr].Stack[n] = StackValue.BuildDouble(csArray[n]);
                }
                retVal = StackValue.BuildArrayPointer(ptr);
                //dsi.runtime.rmem.Push(StackValue.BuildArrayPointer(ptr));
            }

            return(retVal);
        }
Beispiel #13
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);
        }
        public FunctionPointerEvaluator(StackValue pointer, Interpreter dsi)
        {
            Validity.Assert(pointer.IsFunctionPointer);
            interpreter = dsi;
            RuntimeCore runtimeCore = dsi.runtime.RuntimeCore;

            int fptr = (int)pointer.opdata;
            FunctionPointerNode fptrNode;
            int classScope = Constants.kGlobalScope;

            if (runtimeCore.DSExecutable.FuncPointerTable.functionPointerDictionary.TryGetByFirst(fptr, out fptrNode))
            {
                int blockId = fptrNode.blockId;
                int procId = fptrNode.procId;
                classScope = fptrNode.classScope;
                procNode = dsi.runtime.GetProcedureNode(blockId, classScope, procId);
            }

            callsite = new ProtoCore.CallSite(classScope, Name, interpreter.runtime.exe.FunctionTable, runtimeCore.Options.ExecutionMode);
        }
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            Object retVal = base.Execute(c, dsi);
            if (retVal == null)
            {
                return null;
            }

            StackValue propValue = (StackValue)retVal;
            StackValue thisObject = dsi.runtime.rmem.Stack.Last();
            if (StackUtils.IsValidPointer(thisObject) && StackUtils.IsReferenceType(propValue))
            {
                int classIndex = (int)thisObject.metaData.type;
                if (classIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    var core = dsi.runtime.Core;
                    int thisptr = (int)thisObject.opdata;

                    int idx = core.DSExecutable.classTable.ClassNodes[classIndex].symbols.IndexOf(PropertyName);
                    StackValue oldValue = core.Heap.Heaplist[(int)thisObject.opdata].GetValue(idx, core);
                    if (!StackUtils.Equals(oldValue, propValue))
                    {
                        GCUtils.GCRetain(propValue, core);
                        core.Heap.Heaplist[thisptr].SetValue(idx, propValue);
                    }
                }
            }

            return retVal;
        }
Beispiel #16
0
        private object GetArray(StackValue o,
                                ProtoCore.DSASM.Interpreter dsi,
                                out int size)
        {
            size = 0;
            var array = dsi.runtime.rmem.Heap.ToHeapObject <DSArray>(o);

            if (!array.VisibleItems.Any())
            {
                return(null);
            }

            IList elements = null;
            var   opType   = array.GetValueFromIndex(0, dsi.runtime.RuntimeCore).optype;

            if (opType == AddressType.Boolean)
            {
                elements = new List <bool>();
            }
            else if (opType == AddressType.Double)
            {
                elements = new List <double>();
            }
            else if (opType == AddressType.Int)
            {
                elements = new List <int>();
            }
            else if (opType == AddressType.ArrayPointer)
            {
                throw new ArgumentException("FFI does not support nested arrays");
            }
            else
            {
                throw new ArgumentException(string.Format("Argument of type {0} is not supported for FFI Marshalling", opType.ToString()));
            }

            foreach (var op in array.VisibleItems)
            {
                if (opType == AddressType.Double)
                {
                    elements.Add(op.RawDoubleValue);
                }
                else if (opType == AddressType.Int)
                {
                    elements.Add(op.RawIntValue);
                }
                else if (opType == AddressType.Boolean)
                {
                    elements.Add(op.RawIntValue == 0 ? true : false);
                }
            }


            //  now based on the type of element in ds-array
            //  create a new array and return it
            //
            if (opType == AddressType.Double)
            {
                double[] arr = new double[size];
                elements.CopyTo(arr, 0);
                return(arr);
            }
            else if (opType == AddressType.Int)
            {
                int[] arr = new int[size];
                elements.CopyTo(arr, 0);
                return(arr);
            }
            else if (opType == AddressType.Boolean)
            {
                bool[] arr = new bool[size];
                elements.CopyTo(arr, 0);
                return(arr);
            }
            else
            {
                size = 0;
                return(null);
            }
        }
Beispiel #17
0
 public StackValue Execute(int codeblock, int entry, ProtoCore.Runtime.Context callContext, bool fepRun = false, System.Collections.Generic.List <Instruction> breakpoints = null)
 {
     ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(core, fepRun);
     CurrentDSASMExec = interpreter.runtime;
     return(interpreter.Run(codeblock, entry, CurrentDSASMExec.executingLanguage, breakpoints));
 }
 public static string GetMethodName(StackValue pointer, Interpreter dsi)
 {
     Validity.Assert(pointer.optype == AddressType.FunctionPointer);
     return dsi.runtime.exe.procedureTable[0].procList[(int)pointer.opdata].name;
 }
        /// <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;
        }
Beispiel #20
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);
                }
            }
        }
 public static string GetMethodName(StackValue pointer, Interpreter dsi)
 {
     Validity.Assert(pointer.IsFunctionPointer);
     return dsi.runtime.exe.procedureTable[0].Procedures[(int)pointer.opdata].Name;
 }
Beispiel #22
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);
        }
        protected object InvokeFunctionPointerNoThrow(ProtoCore.Runtime.Context c, Interpreter dsi, object thisObject, object[] parameters)
        {
            object ret = null;
            StackValue dsRetValue = StackValue.Null;
            try
            {
                FFIObjectMarshler marshaller = Module.GetMarshaller(dsi.runtime.RuntimeCore);
                ret = InvokeFunctionPointer(thisObject, parameters);
                //Reduce to singleton if the attribute is specified.
                ret = ReflectionInfo.ReduceReturnedCollectionToSingleton(ret);
                dsRetValue = marshaller.Marshal(ret, c, dsi, mReturnType);
            }
            catch (DllNotFoundException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogSemanticError(ex.InnerException.Message);
                }
                dsi.LogSemanticError(ex.Message);
            }
            catch (System.Reflection.TargetException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.Reflection.TargetInvocationException ex)
            {
                if (ex.InnerException != null)
                {
                    System.Exception exc = ex.InnerException;
                    var exception = exc as ArgumentNullException;
                    if (exception != null)
                    {
                        var innerMessage = string.Format(Resources.ArgumentNullException, exception.ParamName);
                        var msg = string.Format(Resources.OperationFailType2, 
                            ReflectionInfo.DeclaringType.Name, 
                            ReflectionInfo.Name, 
                            innerMessage);

                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, msg);
                    }
                    else if (exc is System.ArgumentException)
                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, ErrorString(exc));
                    else if (exc is System.NullReferenceException)
                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ErrorString(null));
                    else
                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ErrorString(exc));
                }
                else
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ErrorString(ex));
            }
            catch (System.Reflection.TargetParameterCountException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.MethodAccessException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.InvalidOperationException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.NotSupportedException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
            }
            catch (ArgumentNullException ex)
            {
                var innerMessage = string.Format(Resources.ArgumentNullException, ex.ParamName);
                var msg = string.Format(Resources.OperationFailType2,
                    ReflectionInfo.DeclaringType.Name,
                    ReflectionInfo.Name,
                    innerMessage);

                dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, msg);
            }
            catch (System.ArgumentException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, ErrorString(ex.InnerException));
                }
                else
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kInvalidArguments, ErrorString(ex));
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kDefault, ErrorString(ex.InnerException));
                }
                dsi.LogWarning(ProtoCore.Runtime.WarningID.kDefault, ErrorString(ex));
            }

            return dsRetValue;
        }
        internal object GetCLRObject(StackValue svData, Core core)
        {
            if (null == core.DSExecutable.classTable)
                return null;

            IList<ClassNode> classNodes = core.DSExecutable.classTable.ClassNodes;
            if (null == classNodes || (classNodes.Count <= 0))
                return null;

            ClassNode classnode = core.DSExecutable.classTable.ClassNodes[(int)svData.metaData.type];
            if (!classnode.IsImportedClass) //TODO: look at properties to see if it contains any FFI objects.
                return null;

            try
            {
                ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(core, false);
                var helper = ProtoFFI.DLLFFIHandler.GetModuleHelper(ProtoFFI.FFILanguage.CSharp);
                var marshaler = helper.GetMarshaller(core);
                return marshaler.UnMarshal(svData, null, interpreter, typeof(object));
            }
            catch (System.Exception)
            {
                return null;
            }
        }
Beispiel #25
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;
                }

                {

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

                }
            }
        }
Beispiel #26
0
 public override StackValue Execute(int codeblock, int entry, ProtoCore.Runtime.Context callContext, List <Instruction> breakpoints, ProtoCore.DebugServices.EventSink sink, bool fepRun = false)
 {
     ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(core);
     CurrentDSASMExec = interpreter.runtime;
     return(interpreter.Run(breakpoints, codeblock, entry, ProtoCore.Language.kImperative));
 }
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            int nParamCount = mArgTypes.Length;
            int paramCount = mArgTypes.Length;
            int envSize = IsDNI ? 2 : 0;
            int totalParamCount = paramCount + envSize;

            List<Object> parameters = new List<object>();
            List<ProtoCore.DSASM.StackValue> s = dsi.runtime.rmem.Stack;
            Object thisObject = null;
            FFIObjectMarshler marshaller = Module.GetMarshaller(dsi.runtime.Core);
            if (!ReflectionInfo.IsStatic)
            {
                try
                {
                    thisObject = marshaller.UnMarshal(s.Last(), c, dsi, ReflectionInfo.DeclaringType);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(ProtoCore.RuntimeData.WarningMessage.kFFIFailedToObtainThisObject, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, message);
                    return null;
                }

                if (thisObject == null)
                    return null; //Can't call a method on null object.
            }

            ParameterInfo[] paraminfos = ReflectionInfo.GetParameters();
            for (int i = 0; i < mArgTypes.Length; ++i)
            {
                // Comment Jun: FFI function stack frames do not contain locals
                int locals = 0;
                int relative = 0 - ProtoCore.DSASM.StackFrame.kStackFrameSize - locals - i - 1;
                ProtoCore.DSASM.StackValue opArg = dsi.runtime.rmem.GetAtRelative(relative);
                try
                {
                    Type paramType = paraminfos[i].ParameterType;
                    object param = marshaller.UnMarshal(opArg, c, dsi, paramType);

                    //null is passed for a value type, so we must return null
                    //rather than interpreting any value from null. fix defect 1462014
                    if (!paramType.IsGenericType && paramType.IsValueType && param == null)
                        throw new System.InvalidCastException(string.Format("Null value cannot be cast to {0}", paraminfos[i].ParameterType.Name));

                    parameters.Add(param);
                }
                catch (System.InvalidCastException ex)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
                    return null;
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(ProtoCore.RuntimeData.WarningMessage.kFFIFailedToObtainObject, paraminfos[i].ParameterType.Name, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, message);
                    return null;
                }
            }

            object ret = null;
            StackValue dsRetValue = StackUtils.BuildNull();
            try
            {
                ret = InvokeFunctionPointer(thisObject, parameters.Count > 0 ? parameters.ToArray() : null);
                //Reduce to singleton if the attribute is specified.
                ret = ReflectionInfo.ReduceReturnedCollectionToSingleton(ret);
                dsRetValue = marshaller.Marshal(ret, c, dsi, mReturnType);
            }
            catch (DllNotFoundException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogSemanticError(ex.InnerException.Message);
                }
                dsi.LogSemanticError(ex.Message);
            }
            catch (System.Reflection.TargetException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.Reflection.TargetInvocationException ex)
            {
                if (ex.InnerException != null)
                {
                    System.Exception exc = ex.InnerException;
                    if (exc is System.ArgumentException)
                        dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kInvalidArguments, ErrorString(exc));
                    else if (exc is System.NullReferenceException)
                        dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ErrorString(null));
                    else
                        dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ErrorString(exc));
                }
                else
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ErrorString(ex));
            }
            catch (System.Reflection.TargetParameterCountException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.MethodAccessException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.InvalidOperationException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.NotSupportedException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.InnerException.Message);
                }
                dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kAccessViolation, ex.Message);
            }
            catch (System.ArgumentException ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kInvalidArguments, ErrorString(ex.InnerException));
                }
                else
                    dsi.LogWarning(ProtoCore.RuntimeData.WarningID.kInvalidArguments, ErrorString(ex));
            }
            catch (Exception ex)
            {
                if (ex.InnerException != null)
                {
                    dsi.LogSemanticError(ErrorString(ex.InnerException));
                }
                dsi.LogSemanticError(ErrorString(ex));
            }

            return dsRetValue;
        }
Beispiel #28
0
        private ExecutionMirror Execute(int programCounterToExecuteFrom, List<Instruction> breakpoints, bool fepRun = false)
        {
            runtimeCore.Breakpoints = breakpoints;
            resumeBlockID = runtimeCore.RunningBlock;


            if (runtimeCore.DebugProps.FirstStackFrame != null)
            {
                runtimeCore.DebugProps.FirstStackFrame.FramePointer = 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);
                runtimeCore.DebugProps.FirstStackFrame.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(
                resumeBlockID, 
                programCounterToExecuteFrom,
                runtimeCore.DebugProps.FirstStackFrame, 
                locals, 
                fepRun,
                null,
                breakpoints);

            return new ExecutionMirror(runtimeCore.CurrentExecutive.CurrentDSASMExec, runtimeCore);

        }
        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.optype == DSASM.AddressType.Boolean);
                    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);
        }
Beispiel #30
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; 
                }
            }
        }
Beispiel #31
0
 public abstract Object Execute(ProtoCore.Runtime.Context c, ProtoCore.DSASM.Interpreter dsi);
        /// <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;
        }
        public override StackValue Execute(ProtoCore.Runtime.Context c, List<StackValue> formalParameters, ProtoCore.DSASM.StackFrame stackFrame, RuntimeCore runtimeCore)
        {
            ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(runtimeCore, true);
            ProtoCore.DSASM.Executive oldDSASMExec = null;
            if (runtimeCore.CurrentExecutive != null)
            {
                oldDSASMExec = runtimeCore.CurrentExecutive.CurrentDSASMExec;
                runtimeCore.CurrentExecutive.CurrentDSASMExec = interpreter.runtime;
            }

            // Assert for the block type
            activation.globs = runtimeCore.DSExecutable.runtimeSymbols[runtimeCore.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 = runtimeCore.RuntimeMemory.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 = runtimeCore.RunningBlock;
            runtimeCore.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);

            runtimeCore.RuntimeMemory.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(runtimeCore.RunningBlock, activation.pc, Language.kInvalid, runtimeCore.Breakpoints);
                runtimeCore.RunningBlock = origRunningBlock;
            }

            if (runtimeCore.CurrentExecutive != null)
            {
                runtimeCore.CurrentExecutive.CurrentDSASMExec = oldDSASMExec;
            }
            return svRet; //DSASM.Mirror.ExecutionMirror.Unpack(svRet, core.heap, core);
        }
Beispiel #34
0
 public override StackValue Execute(int codeblock, int entry, ProtoCore.Runtime.Context callContext, List<Instruction> breakpoints, ProtoCore.DebugServices.EventSink sink, bool fepRun = false)
 {
     ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(core);
     CurrentDSASMExec = interpreter.runtime;
     return interpreter.Run(breakpoints, codeblock, entry, ProtoCore.Language.kImperative);
 }
Beispiel #35
0
        private object GetArray(StackValue o,
                                ProtoCore.DSASM.Interpreter dsi,
                                out int size)
        {
            size = 0;
            int         ptr = (int)o.opdata;
            HeapElement hs  = dsi.runtime.rmem.Heap.Heaplist[ptr];

            size = hs.VisibleSize;

            if (size == 0)
            {
                return(null);
            }

            IList elements = null;
            var   opType   = hs.Stack[0].optype;

            if (opType == AddressType.Boolean)
            {
                elements = new List <bool>();
            }
            else if (opType == AddressType.Double)
            {
                elements = new List <double>();
            }
            else if (opType == AddressType.Int)
            {
                elements = new List <int>();
            }
            else if (opType == AddressType.ArrayPointer)
            {
                throw new ArgumentException("FFI does not support nested arrays");
            }
            else
            {
                throw new ArgumentException(string.Format("Argument of type {0} is not supported for FFI Marshalling", opType.ToString()));
            }

            for (int idx = 0; idx < size; ++idx)
            {
                var op = hs.Stack[idx];
                if (opType == AddressType.Double)
                {
                    elements.Add(op.opdata_d);
                }
                else if (opType == AddressType.Int)
                {
                    elements.Add((int)op.opdata);
                }
                else if (opType == AddressType.Boolean)
                {
                    elements.Add(op.opdata == 0 ? true : false);
                }
            }


            //  now based on the type of element in ds-array
            //  create a new array and return it
            //
            if (opType == AddressType.Double)
            {
                double[] arr = new double[size];
                elements.CopyTo(arr, 0);
                return(arr);
            }
            else if (opType == AddressType.Int)
            {
                int[] arr = new int[size];
                elements.CopyTo(arr, 0);
                return(arr);
            }
            else if (opType == AddressType.Boolean)
            {
                bool[] arr = new bool[size];
                elements.CopyTo(arr, 0);
                return(arr);
            }
            else
            {
                size = 0;
                return(null);
            }
        }
Beispiel #36
0
 public abstract Object Execute(ProtoCore.Runtime.Context c, ProtoCore.DSASM.Interpreter dsi, List <StackValue> stack);
Beispiel #37
0
 public override StackValue Execute(int codeblock, int entry, ProtoCore.Runtime.Context callContext, System.Collections.Generic.List<Instruction> breakpoints, ProtoCore.DebugServices.EventSink sink = null, bool fepRun = false)
 {
     ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(core, fepRun);
     CurrentDSASMExec = interpreter.runtime;
     StackValue sv = interpreter.Run(breakpoints, codeblock, entry, Language.kAssociative);
     return sv;
 }
Beispiel #38
0
 public StackValue Execute(int codeblock, int entry, bool fepRun = false, System.Collections.Generic.List<Instruction> breakpoints = null)
 {
     ProtoCore.DSASM.Interpreter interpreter = new ProtoCore.DSASM.Interpreter(runtimeCore, fepRun);
     CurrentDSASMExec = interpreter.runtime;
     return interpreter.Run(codeblock, entry, CurrentDSASMExec.executingLanguage, breakpoints);
 }
Beispiel #39
0
        private object ConvertReturnValue(object retVal, ProtoCore.Runtime.Context context, ProtoCore.DSASM.Interpreter dsi)
        {
            object returnValue = retVal;

            //  these are arrays!
            if (mReturnType.IsIndexable)
            {
                //  we have already asserted that these can be of rank 1 only, for now
                //
                IntPtr arrPtr = (IntPtr)retVal;
                if (arrPtr == IntPtr.Zero)
                {
                    return(StackValue.Null);
                }

                _Array arr = (_Array)Marshal.PtrToStructure(arrPtr, typeof(_Array));

                if (mReturnType.Name == "double")
                {
                    double[] elements = new double[arr.numElems];
                    Marshal.Copy(arr.elements, elements, 0, arr.numElems);

                    //  free up the memory
                    Marshal.FreeCoTaskMem(arr.elements);
                    Marshal.FreeCoTaskMem(arrPtr);

                    returnValue = ConvertCSArrayToDSArray(elements, dsi);
                }
                else if (mReturnType.Name == "int")
                {
                    int[] elements = new int[arr.numElems];
                    Marshal.Copy(arr.elements, elements, 0, arr.numElems);
                    return(elements);
                }
                else
                {
                    throw new ArgumentException(string.Format("FFI: unknown type {0} to marshall", mReturnType.Name));
                }
            }

            return(returnValue);
        }
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            List<Object> parameters = new List<object>();
            List<StackValue> s = dsi.runtime.rmem.Stack;
            Object thisObject = null;
            FFIObjectMarshler marshaller = Module.GetMarshaller(dsi.runtime.RuntimeCore);
            if (!ReflectionInfo.IsStatic)
            {
                try
                {
                    thisObject = marshaller.UnMarshal(s.Last(), c, dsi, ReflectionInfo.DeclaringType);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(Resources.kFFIFailedToObtainThisObject, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, message);
                    return null;
                }

                if (thisObject == null)
                    return null; //Can't call a method on null object.
            }

            ParameterInfo[] paraminfos = ReflectionInfo.GetParameters();
            for (int i = 0; i < mArgTypes.Length; ++i)
            {
                // Comment Jun: FFI function stack frames do not contain locals
                int locals = 0;
                int relative = 0 - ProtoCore.DSASM.StackFrame.kStackFrameSize - locals - i - 1;
                StackValue opArg = dsi.runtime.rmem.GetAtRelative(relative);
                try
                {
                    Type paramType = paraminfos[i].ParameterType;
                    object param = null;
                    if (opArg.IsDefaultArgument)
                        param = Type.Missing;
                    else 
                        param = marshaller.UnMarshal(opArg, c, dsi, paramType);

                    //null is passed for a value type, so we must return null 
                    //rather than interpreting any value from null. fix defect 1462014 
                    if (!paramType.IsGenericType && paramType.IsValueType && param == null)
                    {
                        //This is going to cause a cast exception. This is a very frequently called problem, so we want to short-cut the execution

                        dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation,
                            string.Format(Resources.FailedToCastFromNull, paraminfos[i].ParameterType.Name));
                        
                            return null;
                        //throw new System.InvalidCastException(string.Format("Null value cannot be cast to {0}", paraminfos[i].ParameterType.Name));
                        
                    }

                    parameters.Add(param);
                }
                catch (System.InvalidCastException ex)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, ex.Message);
                    return null;
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(Resources.kFFIFailedToObtainObject, paraminfos[i].ParameterType.Name, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.kAccessViolation, message);
                    return null;
                }
            }

            return InvokeFunctionPointerNoThrow(c, dsi, thisObject, parameters.Count > 0 ? parameters.ToArray() : null);
        }
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            Object retVal = base.Execute(c, dsi);
            List<ProtoCore.DSASM.StackValue> s = dsi.runtime.rmem.Stack;
            FFIObjectMarshler marshaller = Module.GetMarshaller(dsi.runtime.Core);
            marshaller.OnDispose(s.Last(), c, dsi); //Notify marshler for dispose.

            return retVal;
        }
Beispiel #42
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);
        }
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            List<StackValue> s = dsi.runtime.rmem.Stack;
            FFIObjectMarshler marshaller = Module.GetMarshaller(dsi.runtime.RuntimeCore);

            var thisObject = marshaller.UnMarshal(s.Last(), c, dsi, ReflectionInfo.DeclaringType);
            //Notify marshler for dispose.
            marshaller.OnDispose(s.Last(), c, dsi);

            Object retVal = null;
            if (ReflectionInfo.IsWrapperOf(CLRModuleType.DisposeMethod))
            {
                // For those FFI objects that are disposable but don't provide 
                // Dispose() method in their classes, they will share a same
                // Dispose() method from CLRModuleType.DisposeMethod. We need
                // to manually dispose them.

                if (thisObject != null && thisObject is IDisposable)
                {
                    var disposable = thisObject as IDisposable;
                    disposable.Dispose();
                }
            }
            else
            {
                retVal = InvokeFunctionPointerNoThrow(c, dsi, thisObject, null);
            }

            return retVal;
        }
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            Object retVal = base.Execute(c, dsi);
            if (retVal == null)
            {
                return null;
            }

            StackValue propValue = (StackValue)retVal;
            StackValue thisObject = dsi.runtime.rmem.Stack.Last();

            bool isValidPointer = thisObject.IsPointer && thisObject.opdata != Constants.kInvalidIndex;
            if (isValidPointer && propValue.IsReferenceType)
            {
                int classIndex = thisObject.metaData.type;
                if (classIndex != ProtoCore.DSASM.Constants.kInvalidIndex)
                {
                    var runtimeCore = dsi.runtime.RuntimeCore;
                    int idx = runtimeCore.DSExecutable.classTable.ClassNodes[classIndex].symbols.IndexOf(PropertyName);

                    var obj = runtimeCore.Heap.ToHeapObject<DSObject>(thisObject);
                    StackValue oldValue = obj.GetValueFromIndex(idx, runtimeCore);
                    if (!StackUtils.Equals(oldValue, propValue))
                    {
                        obj.SetValueAtIndex(idx, propValue, runtimeCore);
                    }
                }
            }

            return retVal;
        }
        public override object Execute(ProtoCore.Runtime.Context c, Interpreter dsi)
        {
            List<Object> parameters = new List<object>();
            List<StackValue> s = dsi.runtime.rmem.Stack;
            Object thisObject = null;
            FFIObjectMarshler marshaller = Module.GetMarshaller(dsi.runtime.RuntimeCore);
            if (!ReflectionInfo.IsStatic)
            {
                try
                {
                    thisObject = marshaller.UnMarshal(s.Last(), c, dsi, ReflectionInfo.DeclaringType);
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(Resources.kFFIFailedToObtainThisObject, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, message);
                    return null;
                }

                if (thisObject == null)
                    return null; //Can't call a method on null object.
            }

            FFIParameterInfo[] paraminfos = ReflectionInfo.GetParameters();
            List<StackValue> referencedParameters = new List<StackValue>();

            for (int i = 0; i < mArgTypes.Length; ++i)
            {
                // Comment Jun: FFI function stack frames do not contain locals
                int locals = 0;
                int relative = 0 - ProtoCore.DSASM.StackFrame.StackFrameSize - locals - i - 1;
                StackValue opArg = dsi.runtime.rmem.GetAtRelative(relative);
                try
                {
                    Type paramType = paraminfos[i].Info.ParameterType;
                    object param = null;
                    if (opArg.IsDefaultArgument)
                        param = Type.Missing;
                    else 
                        param = marshaller.UnMarshal(opArg, c, dsi, paramType);

                    if (paraminfos[i].KeepReference && opArg.IsReferenceType)
                    {
                        referencedParameters.Add(opArg);
                    }

                    //null is passed for a value type, so we must return null 
                    //rather than interpreting any value from null. fix defect 1462014 
                    if (!paramType.IsGenericType && paramType.IsValueType && param == null)
                    {
                        //This is going to cause a cast exception. This is a very frequently called problem, so we want to short-cut the execution

                        dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation,
                            string.Format(Resources.FailedToCastFromNull, paraminfos[i].Info.ParameterType.Name));
                        
                            return null;
                        //throw new System.InvalidCastException(string.Format("Null value cannot be cast to {0}", paraminfos[i].ParameterType.Name));
                        
                    }

                    parameters.Add(param);
                }
                catch (System.InvalidCastException ex)
                {
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, ex.Message);
                    return null;
                }
                catch (InvalidOperationException)
                {
                    string message = String.Format(Resources.kFFIFailedToObtainObject, paraminfos[i].Info.ParameterType.Name, ReflectionInfo.DeclaringType.Name, ReflectionInfo.Name);
                    dsi.LogWarning(ProtoCore.Runtime.WarningID.AccessViolation, message);
                    return null;
                }
            }

            var ret =  InvokeFunctionPointerNoThrow(c, dsi, thisObject, parameters.Count > 0 ? parameters.ToArray() : null);
            if (ReflectionInfo.KeepReferenceThis && thisObject != null)
            {
                referencedParameters.Add(s.Last());
            }

            int count = referencedParameters.Count;
            if (count > 0 && (ret is StackValue))
            {
                // If there is a parameter who has attribute [KeepReference],
                // it means this parameter will cross the DesignScript boundary
                // and be referenced by C# object. Therefore, when its DS
                // wrapper object is out of scope, we shouldn't dispose it;
                // otherwise that C# object will reference to an invalid object.
                //
                // Similarly, if the method has attribute [KeepReferenceThis],
                // it means the return object will reference to this object
                // internally, so we shouldn't dispose this object.
                //
                // The hack here is to treat them like properties in the return
                // object. Note all DS wrapper objects are dummy objects who
                // haven't any members. By allocating extra space on the heap,
                // we store the reference in the return object so that the
                // parameter will have the same lifecycle as the return object.
                //
                // One case need to consider about is the type of return value.
                // If the return value is an array, we have to recursively go 
                // into the array and expand the element, instead of setting
                // these hidden information directly on the array.
                try
                {
                    SetReferenceObjects((StackValue)ret, referencedParameters, dsi.runtime);
                }
                catch (RunOutOfMemoryException)
                {
                    dsi.runtime.RuntimeCore.RuntimeStatus.LogWarning(ProtoCore.Runtime.WarningID.RunOutOfMemory, Resources.RunOutOfMemory);
                    return StackValue.Null;
                }
            }

            return ret;
        }