public void DSObjectPropertyChanged(ProtoCore.DSASM.Executive exe, int thisptr, String propertyName, object value)
 {
     /*
      * Validity.Assert(thisptr != Constants.kInvalidIndex);
      *
      * // It is a naive implementation, need to optimize it later on.
      * // At runtime we don't have mapping between a DS pointer and a
      * // symbol name, so we have to go through registered symbols to
      * // find out if some symbol's value is equal to thisptr.
      * //
      * // The other reason to do this is there is possible that two vars
      * // reference to the same object, so if the property of one of them
      * // is modified, the other one should be notified.
      * foreach (var varPropertyChangedHandler in mSubscribers)
      * {
      *  string symbolName = varPropertyChangedHandler.Key;
      *  SymbolNode symbolNode = exe.GetGlobalSymbolNode(symbolName);
      *  if (symbolNode == null)
      *  {
      *      continue;
      *  }
      *
      *  StackValue dsValue = exe.Core.Rmem.GetAtRelative(symbolNode);
      *  if (dsValue.optype != AddressType.Pointer && dsValue.opdata != thisptr)
      *  {
      *      continue;
      *  }
      *
      *  var propertyChangedHandler = varPropertyChangedHandler.Value;
      *  DSPropertyChangedHandler handler = null;
      *  if (propertyChangedHandler.TryGetValue(propertyName, out handler))
      *  {
      *      if (handler != null)
      *      {
      *          DSPropertyChangedEventArgs args = new DSPropertyChangedEventArgs(symbolName, propertyName, value);
      *          handler(args);
      *      }
      *  }
      * }
      */
 }
Example #2
0
 public Interpreter(RuntimeCore runtimeCore, bool isFEP = false)
 {
     runtime = runtimeCore.ExecutiveProvider.CreateExecutive(runtimeCore, isFEP);
 }
Example #3
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));
 }
Example #4
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);
        }
Example #5
0
        private void GCDisposeObject(ref StackValue svPtr, Executive exe)
        {
            int classIndex = (int)svPtr.metaData.type;
            ClassNode cn = exe.exe.classTable.ClassNodes[classIndex];
            ProcedureNode pn = null;

            while (pn == null)
            {
                pn = cn.GetDisposeMethod();
                if (pn == null && cn.baseList != null && cn.baseList.Count != 0) // search the base class
                {
                    // assume multiple inheritance is not allowed
                    // it will only has a single base class
                    classIndex = cn.baseList[0];
                    cn = exe.exe.classTable.ClassNodes[cn.baseList[0]];
                }
                else
                {
                    break;
                }
            }

            if (pn != null)
            {
                // TODO Jun/Jiong: Use build pointer utilities
                exe.rmem.Push(StackUtils.BuildNode(AddressType.ArrayDim, 0));
                exe.rmem.Push(StackUtils.BuildPointer(svPtr.opdata, svPtr.metaData));
                exe.rmem.Push(StackUtils.BuildNode(AddressType.BlockIndex, pn.runtimeIndex));
                exe.rmem.Push(StackUtils.BuildNode(AddressType.ArrayDim, 0));
                exe.rmem.Push(StackUtils.BuildStaticType((int)ProtoCore.PrimitiveType.kTypeVar));

                ++exe.Core.FunctionCallDepth;

                // TODO: Need to move isExplicitCall to DebugProps and come up with a more elegant solution for this
                // fix for IDE-963 - pratapa
                bool explicitCall = exe.isExplicitCall;
                bool tempFlag = explicitCall;
                exe.Callr(pn.procId, classIndex, 1, ref explicitCall);

                exe.isExplicitCall = tempFlag;

                --exe.Core.FunctionCallDepth;
            }
        }
Example #6
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);
        }
Example #7
0
        public void GCRelease(StackValue[] ptrList, Executive exe)
        {
            for (int n = 0; n < ptrList.Length; ++n)
            {
                StackValue svPtr = ptrList[n];
                if (svPtr.optype != AddressType.Pointer && svPtr.optype != AddressType.ArrayPointer)
                {
                    continue;
                }

                int ptr = (int)svPtr.opdata;
                if (ptr < 0 || ptr >= Heaplist.Count)
                {
                    continue;
                }
                HeapElement hs = Heaplist[ptr];

                if (!hs.Active)
                {
                    continue;
                }

                if (hs.Refcount > 0)
                {
                    hs.Refcount--;
                }

                // TODO Jun: If its a pointer to a primitive then dont decrease its refcount, just free it
                // Debug.Assert(hs.refcount >= 0);
                if (hs.Refcount == 0)
                {
                    // if it is of class type, first call its destructor before clean its members
                    if(svPtr.optype == AddressType.Pointer)
                        GCDisposeObject(ref svPtr, exe);

                    hs.Active = false;

                    GCRelease(hs.Stack, exe);
            #if _USE_FREE_LIST
                    freeList.Add(ptr);
            #endif
                }
            }
        }
Example #8
0
 /// <summary>
 /// Bounce instantiates a new Executive 
 /// Execution jumps to the new executive
 /// This iverload handles debugger properties when bouncing
 /// </summary>
 /// <param name="exeblock"></param>
 /// <param name="entry"></param>
 /// <param name="context"></param>
 /// <param name="stackFrame"></param>
 /// <param name="locals"></param>
 /// <param name="exec"></param>
 /// <param name="fepRun"></param>
 /// <param name="breakpoints"></param>
 /// <returns></returns>
 public StackValue Bounce(int exeblock, int entry, StackFrame stackFrame, int locals = 0, bool fepRun = false, Executive exec = null, List<Instruction> breakpoints = null)
 {
     if (stackFrame != null)
     {
         rmem.PushFrameForLocals(locals);
         rmem.PushStackFrame(stackFrame);
         runtimeCore.DebugProps.SetUpBounce(exec, stackFrame.FunctionCallerBlock, stackFrame.ReturnPC);
     }
     return runtimeCore.ExecutionInstance.Execute(exeblock, entry, fepRun, breakpoints);
 }
Example #9
0
 public Interpreter(Core core, bool isFEP = false)
 {
     //runtime = new Executive(core, isFEP);
     runtime = core.ExecutiveProvider.CreateExecutive(core, isFEP);
 }
Example #10
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);
 }
        /// <summary>
        /// If dsValue is a pointer (object), expand the size of this object and
        /// add references to referencedObjects; if dsValue is an array, then
        /// traverse recursively.
        ///
        /// Exception: ProtoCore.Exception.RunOutOfMemoryException if the engine
        /// fails to expand the size of object.
        /// </summary>
        /// <param name="dsValue"></param>
        /// <param name="referencedObjects"></param>
        /// <param name="exec"></param>
        private void SetReferenceObjects(StackValue dsValue, List<StackValue> referencedObjects, Executive exec)
        {
            if (dsValue.IsPointer)
            {
                var dsObject = exec.rmem.Heap.ToHeapObject<DSObject>(dsValue);
                if (dsObject != null)
                {
                    int startIndex = dsObject.Count;
                    dsObject.ExpandBySize(referencedObjects.Count);
                    Validity.Assert(dsObject.Count >= referencedObjects.Count);

                    for (int i = 0; i < referencedObjects.Count; i++)
                    {
                        dsObject.SetValueAtIndex(startIndex + i, referencedObjects[i], exec.RuntimeCore);
                    }
                }
            }
            else if (dsValue.IsArray)
            {
                var dsArray = exec.rmem.Heap.ToHeapObject<DSArray>(dsValue);
                if (dsArray != null)
                {
                    foreach (var element in dsArray.Values)
                    {
                        SetReferenceObjects(element, referencedObjects, exec);
                    }
                }
            }
        }