Example #1
0
        private void ImportProcedure(string library, ProcedureNode proc)
        {
            string procName = proc.name;

            if (proc.isAutoGeneratedThisProc ||
                CoreUtils.IsSetter(procName) ||
                CoreUtils.IsDisposeMethod(procName) ||
                CoreUtils.StartsWithDoubleUnderscores(procName))
            {
                return;
            }

            string           obsoleteMessage = "";
            int              classScope      = proc.classScope;
            string           className       = string.Empty;
            MethodAttributes methodAttribute = proc.MethodAttribute;
            ClassAttributes  classAttribute  = null;

            if (classScope != Constants.kGlobalScope)
            {
                var classNode = LibraryManagementCore.ClassTable.ClassNodes[classScope];

                classAttribute = classNode.ClassAttributes;
                className      = classNode.name;
            }

            // MethodAttribute's HiddenInLibrary has higher priority than
            // ClassAttribute's HiddenInLibrary
            var isVisible             = true;
            var canUpdatePeriodically = false;

            if (methodAttribute != null)
            {
                isVisible             = !methodAttribute.HiddenInLibrary;
                canUpdatePeriodically = methodAttribute.CanUpdatePeriodically;
            }
            else
            {
                if (classAttribute != null)
                {
                    isVisible = !classAttribute.HiddenInLibrary;
                }
            }

            FunctionType type;

            if (classScope == Constants.kGlobalScope)
            {
                type = FunctionType.GenericFunction;
            }
            else
            {
                if (CoreUtils.IsGetter(procName))
                {
                    type = proc.isStatic
                        ? FunctionType.StaticProperty
                        : FunctionType.InstanceProperty;

                    string property;
                    if (CoreUtils.TryGetPropertyName(procName, out property))
                    {
                        procName = property;
                    }
                }
                else
                {
                    if (proc.isConstructor)
                    {
                        type = FunctionType.Constructor;
                    }
                    else if (proc.isStatic)
                    {
                        type = FunctionType.StaticMethod;
                    }
                    else
                    {
                        type = FunctionType.InstanceMethod;
                    }
                }
            }

            List <TypedParameter> arguments = proc.argInfoList.Zip(
                proc.argTypeList,
                (arg, argType) =>
            {
                AssociativeNode defaultArgumentNode;
                // Default argument specified by DefaultArgumentAttribute
                // takes higher priority
                if (!TryGetDefaultArgumentFromAttribute(arg, out defaultArgumentNode) &&
                    arg.IsDefault)
                {
                    var binaryExpr = arg.DefaultExpression as BinaryExpressionNode;
                    if (binaryExpr != null)
                    {
                        defaultArgumentNode = binaryExpr.RightNode;
                    }
                }

                return(new TypedParameter(arg.Name, argType, defaultArgumentNode));
            }).ToList();

            IEnumerable <string> returnKeys = null;

            if (proc.MethodAttribute != null)
            {
                if (proc.MethodAttribute.ReturnKeys != null)
                {
                    returnKeys = proc.MethodAttribute.ReturnKeys;
                }
                if (proc.MethodAttribute.IsObsolete)
                {
                    obsoleteMessage = proc.MethodAttribute.ObsoleteMessage;
                }
            }

            var function = new FunctionDescriptor(new FunctionDescriptorParams
            {
                Assembly              = library,
                ClassName             = className,
                FunctionName          = procName,
                Parameters            = arguments,
                ReturnType            = proc.returntype,
                FunctionType          = type,
                IsVisibleInLibrary    = isVisible,
                ReturnKeys            = returnKeys,
                PathManager           = pathManager,
                IsVarArg              = proc.isVarArg,
                ObsoleteMsg           = obsoleteMessage,
                CanUpdatePeriodically = canUpdatePeriodically,
                IsBuiltIn             = pathManager.PreloadedLibraries.Contains(library)
            });

            AddImportedFunctions(library, new[] { function });
        }
Example #2
0
        /// <summary>
        /// Sets the function to an inactive state where it can no longer be used by the front-end and backend
        /// </summary>
        /// <param name="functionDef"></param>
        public void SetFunctionInactive(FunctionDefinitionNode functionDef)
        {
            // DS language only supports function definition on the global and first language block scope
            // TODO Jun: Determine if it is still required to combine function tables in the codeblocks and callsite

            // Update the functiond definition in the codeblocks
            int hash = CoreUtils.GetFunctionHash(functionDef);

            ProcedureNode procNode = null;

            foreach (CodeBlock block in CodeBlockList)
            {
                // Update the current function definition in the current block
                procNode = block.procedureTable.Procedures.FirstOrDefault(p => p.HashID == hash);
                int index = procNode == null ? Constants.kInvalidIndex: procNode.ID;
                if (Constants.kInvalidIndex == index)
                {
                    continue;
                }

                procNode.IsActive = false;

                // Remove staled graph nodes
                var graph = block.instrStream.dependencyGraph;
                graph.GraphList.RemoveAll(g => g.classIndex == ClassIndex &&
                                          g.procIndex == index);
                graph.RemoveNodesFromScope(Constants.kGlobalScope, index);

                // Make a copy of all symbols defined in this function
                var localSymbols = block.symbolTable.symbolList.Values
                                   .Where(n =>
                                          n.classScope == Constants.kGlobalScope &&
                                          n.functionIndex == index)
                                   .ToList();

                foreach (var symbol in localSymbols)
                {
                    block.symbolTable.UndefineSymbol(symbol);
                }

                break;
            }

            if (null != procNode)
            {
                // Remove codeblock defined in procNode from CodeBlockList and CompleteCodeBlockList
                foreach (int cbID in procNode.ChildCodeBlocks)
                {
                    CompleteCodeBlockList.RemoveAll(x => x.codeBlockId == cbID);

                    foreach (CodeBlock cb in CodeBlockList)
                    {
                        cb.children.RemoveAll(x => x.codeBlockId == cbID);
                    }
                }
            }


            // Update the function definition in global function tables
            foreach (KeyValuePair <int, Dictionary <string, FunctionGroup> > functionGroupList in DSExecutable.FunctionTable.GlobalFuncTable)
            {
                foreach (KeyValuePair <string, FunctionGroup> functionGroup in functionGroupList.Value)
                {
                    functionGroup.Value.FunctionEndPoints.RemoveAll(func => func.procedureNode.HashID == hash);
                }
            }
        }
Example #3
0
        public void SetUpStepOverFunctionCalls(RuntimeCore runtimeCore, ProcedureNode fNode, GraphNode graphNode, bool hasDebugInfo)
        {
            int tempPC = DebugEntryPC;
            int limit  = 0; // end pc of current expression
            InstructionStream istream;

            int pc = tempPC;

            if (runtimeCore.DebugProps.InlineConditionOptions.isInlineConditional)
            {
                tempPC  = InlineConditionOptions.startPc;
                limit   = InlineConditionOptions.endPc;
                istream = runtimeCore.DSExecutable.instrStreamList[InlineConditionOptions.instructionStream];
            }
            else
            {
                pc      = tempPC;
                istream = runtimeCore.DSExecutable.instrStreamList[runtimeCore.RunningBlock];
                if (istream.language == Language.Associative)
                {
                    limit = FindEndPCForAssocGraphNode(pc, istream, fNode, graphNode, runtimeCore.Options.ExecuteSSA);
                    //Validity.Assert(limit != ProtoCore.DSASM.Constants.kInvalidIndex);
                }
                else if (istream.language == Language.Imperative)
                {
                    // Check for 'SETEXPUID' instruction to check for end of expression
                    while (++pc < istream.instrList.Count)
                    {
                        Instruction instr = istream.instrList[pc];
                        if (instr.opCode == OpCode.SETEXPUID)
                        {
                            limit = pc;
                            break;
                        }
                    }
                }
            }

            // Determine if this is outermost CALLR in the expression
            // until then do not restore any breakpoints
            // If outermost CALLR, restore breakpoints after end of expression
            pc = tempPC;
            int numNestedFunctionCalls = 0;

            while (++pc <= limit)
            {
                Instruction instr = istream.instrList[pc];
                if (instr.opCode == OpCode.CALLR && instr.debug != null)
                {
                    numNestedFunctionCalls++;
                }
            }
            if (numNestedFunctionCalls == 0)
            {
                // If this is the outermost function call
                runtimeCore.Breakpoints.Clear();
                runtimeCore.Breakpoints.AddRange(AllbreakPoints);

                pc = tempPC;
                while (++pc <= limit)
                {
                    Instruction instr = istream.instrList[pc];
                    // We still want to break at the closing brace of a function or ctor call or language block
                    if (instr.debug != null && instr.opCode != OpCode.RETURN && (instr.opCode != OpCode.RETB))
                    {
                        if (runtimeCore.Breakpoints.Contains(instr))
                        {
                            runtimeCore.Breakpoints.Remove(instr);
                        }
                    }
                }
            }
        }
Example #4
0
        private void ImportProcedure(string library, ProcedureNode proc)
        {
            string procName = proc.Name;

            if (proc.IsAutoGeneratedThisProc ||
                // There could be DS functions that have private access
                // that shouldn't be imported into the Library
                proc.AccessModifier == AccessModifier.Private ||
                CoreUtils.IsSetter(procName) ||
                CoreUtils.IsDisposeMethod(procName) ||
                CoreUtils.StartsWithDoubleUnderscores(procName))
            {
                return;
            }

            string           obsoleteMessage = "";
            int              classScope      = proc.ClassID;
            string           className       = string.Empty;
            MethodAttributes methodAttribute = proc.MethodAttribute;
            ClassAttributes  classAttribute  = null;

            if (classScope != Constants.kGlobalScope)
            {
                var classNode = LibraryManagementCore.ClassTable.ClassNodes[classScope];

                classAttribute = classNode.ClassAttributes;
                className      = classNode.Name;
            }

            // MethodAttribute's HiddenInLibrary has higher priority than
            // ClassAttribute's HiddenInLibrary
            var isVisible             = true;
            var canUpdatePeriodically = false;

            if (methodAttribute != null)
            {
                isVisible             = !methodAttribute.HiddenInLibrary;
                canUpdatePeriodically = methodAttribute.CanUpdatePeriodically;
            }
            else
            {
                if (classAttribute != null)
                {
                    isVisible = !classAttribute.HiddenInLibrary;
                }
            }

            FunctionType type;

            if (classScope == Constants.kGlobalScope)
            {
                type = FunctionType.GenericFunction;
            }
            else
            {
                if (CoreUtils.IsGetter(procName))
                {
                    type = proc.IsStatic
                        ? FunctionType.StaticProperty
                        : FunctionType.InstanceProperty;

                    string property;
                    if (CoreUtils.TryGetPropertyName(procName, out property))
                    {
                        procName = property;
                    }
                }
                else
                {
                    if (proc.IsConstructor)
                    {
                        type = FunctionType.Constructor;
                    }
                    else if (proc.IsStatic)
                    {
                        type = FunctionType.StaticMethod;
                    }
                    else
                    {
                        type = FunctionType.InstanceMethod;
                    }
                }
            }

            List <TypedParameter> arguments = proc.ArgumentInfos.Zip(
                proc.ArgumentTypes,
                (arg, argType) =>
            {
                AssociativeNode defaultArgumentNode;
                // Default argument specified by DefaultArgumentAttribute
                // takes higher priority
                if (!TryGetDefaultArgumentFromAttribute(arg, out defaultArgumentNode) &&
                    arg.IsDefault)
                {
                    var binaryExpr = arg.DefaultExpression as BinaryExpressionNode;
                    if (binaryExpr != null)
                    {
                        defaultArgumentNode = binaryExpr.RightNode;
                    }
                }
                string shortName = null;
                if (defaultArgumentNode != null)
                {
                    shortName           = defaultArgumentNode.ToString();
                    var rewriter        = new ElementRewriter(LibraryManagementCore.ClassTable, LibraryManagementCore.BuildStatus.LogSymbolConflictWarning);
                    defaultArgumentNode = defaultArgumentNode.Accept(rewriter);
                }
                return(new TypedParameter(arg.Name, argType, defaultArgumentNode, shortName));
            }).ToList();

            bool isLacingDisabled           = false;
            IEnumerable <string> returnKeys = null;

            if (proc.MethodAttribute != null)
            {
                if (proc.MethodAttribute.ReturnKeys != null)
                {
                    returnKeys = proc.MethodAttribute.ReturnKeys;
                }
                if (proc.MethodAttribute.IsObsolete)
                {
                    obsoleteMessage = proc.MethodAttribute.ObsoleteMessage;
                }
                isLacingDisabled = proc.MethodAttribute.IsLacingDisabled;
            }

            var function = new FunctionDescriptor(new FunctionDescriptorParams
            {
                Assembly              = library,
                ClassName             = className,
                FunctionName          = procName,
                Parameters            = arguments,
                ReturnType            = proc.ReturnType,
                FunctionType          = type,
                IsVisibleInLibrary    = isVisible,
                ReturnKeys            = returnKeys,
                PathManager           = pathManager,
                IsVarArg              = proc.IsVarArg,
                ObsoleteMsg           = obsoleteMessage,
                CanUpdatePeriodically = canUpdatePeriodically,
                IsBuiltIn             = pathManager.PreloadedLibraries.Contains(library),
                IsPackageMember       = packagedLibraries.Contains(library),
                IsLacingDisabled      = isLacingDisabled
            });

            AddImportedFunctions(library, new[] { function });
        }
Example #5
0
        private int FindEndPCForAssocGraphNode(int tempPC, InstructionStream istream, ProcedureNode fNode, GraphNode graphNode, bool handleSSATemps)
        {
            int       limit            = Constants.kInvalidIndex;
            GraphNode currentGraphNode = graphNode;

            if (currentGraphNode != null)
            {
                if (tempPC < currentGraphNode.updateBlock.startpc || tempPC > currentGraphNode.updateBlock.endpc)
                {
                    return(Constants.kInvalidIndex);
                }

                int       i             = currentGraphNode.dependencyGraphListID;
                GraphNode nextGraphNode = currentGraphNode;
                while (currentGraphNode.exprUID != Constants.kInvalidIndex &&
                       currentGraphNode.exprUID == nextGraphNode.exprUID)

                {
                    limit = nextGraphNode.updateBlock.endpc;
                    if (++i < istream.dependencyGraph.GraphList.Count)
                    {
                        nextGraphNode = istream.dependencyGraph.GraphList[i];
                    }
                    else
                    {
                        break;
                    }

                    // Is it the next statement
                    // This check will be deprecated on full SSA
                    if (handleSSATemps)
                    {
                        if (!nextGraphNode.IsSSANode())
                        {
                            // The next graphnode is nolonger part of the current statement
                            // This is the end pc needed to run until
                            nextGraphNode = istream.dependencyGraph.GraphList[i];
                            limit         = nextGraphNode.updateBlock.endpc;
                            break;
                        }
                    }
                }
            }
            // If graph node is null in associative lang block, it either is the very first property declaration or
            // it is the very first or only function call statement ("return = f();") inside the calling function
            // Here there's most likely a DEP or RETURN respectively after the function call
            // in which case, search for the instruction and set that as the new pc limit
            else if (!fNode.Name.Contains(Constants.kSetterPrefix))
            {
                while (++tempPC < istream.instrList.Count)
                {
                    Instruction instr = istream.instrList[tempPC];
                    if (instr.opCode == OpCode.DEP || instr.opCode == OpCode.RETURN)
                    {
                        limit = tempPC;
                        break;
                    }
                }
            }
            return(limit);
        }
Example #6
0
        public void SetUpCallrForDebug(RuntimeCore runtimeCore, DSASM.Executive exec, ProcedureNode fNode, int pc, bool isBaseCall = false,
                                       CallSite callsite = null, List <StackValue> arguments         = null, List <List <ReplicationGuide> > replicationGuides = null, StackFrame stackFrame = null,
                                       List <StackValue> dotCallDimensions = null, bool hasDebugInfo = false, bool isMember = false, StackValue?thisPtr = null)
        {
            //ProtoCore.DSASM.Executive exec = core.CurrentExecutive.CurrentDSASMExec;

            DebugFrame debugFrame = new DebugFrame();

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

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

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

            bool isReplicating      = false;
            bool isExternalFunction = false;

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

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

                return;
            }

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

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

                return;
            }

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

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

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


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

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

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

                DebugStackFrame.Push(debugFrame);

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

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

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

            SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec);
            DebugStackFrame.Push(debugFrame);
        }
Example #7
0
        private void ImportProcedure(string library, ProcedureNode proc)
        {
            string procName = proc.name;

            if (proc.isAutoGeneratedThisProc ||
                CoreUtils.IsSetter(procName) ||
                CoreUtils.IsDisposeMethod(procName) ||
                CoreUtils.StartsWithDoubleUnderscores(procName))
            {
                return;
            }

            int              classScope      = proc.classScope;
            string           className       = string.Empty;
            MethodAttributes methodAttribute = proc.MethodAttribute;
            ClassAttributes  classAttribute  = null;

            if (classScope != ProtoCore.DSASM.Constants.kGlobalScope)
            {
                var classNode = GraphUtilities.GetCore().ClassTable.ClassNodes[classScope];

                classAttribute = classNode.ClassAttributes;
                className      = classNode.name;
            }

            // MethodAttribute's HiddenInLibrary has higher priority than
            // ClassAttribute's HiddenInLibrary
            bool isVisible = true;

            if (methodAttribute != null)
            {
                isVisible = !methodAttribute.HiddenInLibrary;
            }
            else
            {
                if (classAttribute != null)
                {
                    isVisible = !classAttribute.HiddenInLibrary;
                }
            }

            FunctionType type;

            if (classScope == ProtoCore.DSASM.Constants.kGlobalScope)
            {
                type = FunctionType.GenericFunction;
            }
            else
            {
                if (CoreUtils.IsGetter(procName))
                {
                    type = proc.isStatic
                        ? FunctionType.StaticProperty
                        : FunctionType.InstanceProperty;

                    string property;
                    if (CoreUtils.TryGetPropertyName(procName, out property))
                    {
                        procName = property;
                    }
                }
                else
                {
                    if (proc.isConstructor)
                    {
                        type = FunctionType.Constructor;
                    }
                    else if (proc.isStatic)
                    {
                        type = FunctionType.StaticMethod;
                    }
                    else
                    {
                        type = FunctionType.InstanceMethod;
                    }
                }
            }

            IEnumerable <TypedParameter> arguments = proc.argInfoList.Zip(
                proc.argTypeList,
                (arg, argType) =>
            {
                object defaultValue = null;
                if (arg.IsDefault)
                {
                    var binaryExpr = arg.DefaultExpression as BinaryExpressionNode;
                    if (binaryExpr != null)
                    {
                        AssociativeNode vnode = binaryExpr.RightNode;
                        if (vnode is IntNode)
                        {
                            defaultValue = (vnode as IntNode).Value;
                        }
                        else if (vnode is DoubleNode)
                        {
                            defaultValue = (vnode as DoubleNode).Value;
                        }
                        else if (vnode is BooleanNode)
                        {
                            defaultValue = (vnode as BooleanNode).Value;
                        }
                        else if (vnode is StringNode)
                        {
                            defaultValue = (vnode as StringNode).value;
                        }
                    }
                }

                return(new TypedParameter(arg.Name, argType.ToString(), defaultValue));
            });

            IEnumerable <string> returnKeys = null;

            if (proc.MethodAttribute != null && proc.MethodAttribute.ReturnKeys != null)
            {
                returnKeys = proc.MethodAttribute.ReturnKeys;
            }

            var function = new FunctionDescriptor(
                library,
                className,
                procName,
                arguments,
                proc.returntype.ToString(),
                type,
                isVisible,
                returnKeys,
                proc.isVarArg);

            AddImportedFunctions(library, new[] { function });
        }
Example #8
0
 public static bool IsNonStaticPropertyLookupOnClass(ProcedureNode procCallNode, string className)
 {
     return(procCallNode.ArgumentInfos.Count == 1 &&
            procCallNode.ArgumentInfos[0].Name == Constants.kThisPointerArgName &&
            procCallNode.ArgumentTypes[0].Name == className);
 }
Example #9
0
        private void ImportProcedure(string library, ClassNode classNode, ProcedureNode proc)
        {
            if (proc.isAutoGeneratedThisProc)
            {
                return;
            }

            bool isVisibleInLibrary = !(null != proc.MethodAttribute && proc.MethodAttribute.HiddenInLibrary);

            //If the class is Hidden all methods are hidden.
            if (null != classNode.ClassAttributes && classNode.ClassAttributes.HiddenInLibrary)
            {
                isVisibleInLibrary = null != proc.MethodAttribute && !proc.MethodAttribute.HiddenInLibrary;
                //But if a particular method is not hidden, then this method is visible
            }

            string procName = proc.name;

            if (CoreUtils.IsSetter(procName) || CoreUtils.IsDisposeMethod(procName) ||
                CoreUtils.StartsWithDoubleUnderscores(procName))
            {
                return;
            }

            FunctionType type;

            if (CoreUtils.IsGetter(procName))
            {
                type = proc.isStatic ? FunctionType.StaticProperty : FunctionType.InstanceProperty;

                string property;
                if (CoreUtils.TryGetPropertyName(procName, out property))
                {
                    procName = property;
                }
            }
            else
            {
                if (proc.isConstructor)
                {
                    type = FunctionType.Constructor;
                }
                else if (proc.isStatic)
                {
                    type = FunctionType.StaticMethod;
                }
                else
                {
                    type = FunctionType.InstanceMethod;
                }
            }

            IEnumerable <TypedParameter> arguments = proc.argInfoList.Zip(
                proc.argTypeList,
                (arg, argType) =>
            {
                object defaultValue = null;
                if (arg.IsDefault)
                {
                    var binaryExpr = arg.DefaultExpression as BinaryExpressionNode;
                    if (binaryExpr != null)
                    {
                        AssociativeNode vnode = binaryExpr.RightNode;
                        if (vnode is IntNode)
                        {
                            defaultValue = (vnode as IntNode).Value;
                        }
                        else if (vnode is DoubleNode)
                        {
                            defaultValue = (vnode as DoubleNode).Value;
                        }
                        else if (vnode is BooleanNode)
                        {
                            defaultValue = (vnode as BooleanNode).Value;
                        }
                        else if (vnode is StringNode)
                        {
                            defaultValue = (vnode as StringNode).value;
                        }
                    }
                }

                return(new TypedParameter(arg.Name, argType.ToString(), defaultValue));
            });

            IEnumerable <string> returnKeys = null;

            if (proc.MethodAttribute != null && proc.MethodAttribute.ReturnKeys != null)
            {
                returnKeys = proc.MethodAttribute.ReturnKeys;
            }

            var function = new FunctionDescriptor(
                library,
                classNode.name,
                procName,
                arguments,
                proc.returntype.ToString(),
                type,
                isVisibleInLibrary,
                returnKeys,
                proc.isVarArg);

            AddImportedFunctions(library, new[] { function });
        }
        public override StackValue Execute(ProtoCore.Runtime.Context c, List <StackValue> formalParameters, ProtoCore.DSASM.StackFrame stackFrame, RuntimeCore runtimeCore)
        {   //  ensure there is no data race, function resolution and execution happens in parallel
            //  but for FFI we want it to be serial cause the code we are calling into may not cope
            //  with parallelism.
            //
            //  we are always looking and putting our function pointers in handler with each lang
            //  so better lock for FFIHandler (being static) it  will be good object to lock
            //
            lock (FFIHandlers)
            {
                Interpreter interpreter = new Interpreter(runtimeCore, true);

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


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

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

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

                // Check if this is a 'this' pointer function overload that was generated by the compiler
                if (null != fNode && fNode.IsAutoGeneratedThisProc)
                {
                    int  thisPtrIndex = 0;
                    bool isStaticCall = svThisPtr.IsPointer && Constants.kInvalidPointer == svThisPtr.Pointer;
                    if (isStaticCall)
                    {
                        stackFrame.ThisPtr = formalParameters[thisPtrIndex];
                    }
                    argTypes.RemoveAt(thisPtrIndex);

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

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

                    svThisPtr = formalParameters[thisPtrIndex];

                    formalParameters.RemoveAt(thisPtrIndex);
                }

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


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

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

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

                    List <StackValue> registers = interpreter.runtime.GetRegisters();

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

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

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

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

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

                    return(op);
                }
            }
        }
Example #11
0
 private void Visit(ProcedureNode node)
 {
 }
Example #12
0
            //private PropertyMirror(string name)
            //{
            //    PropertyName = name;
            //}
            internal PropertyMirror(ProcedureNode procNode, bool isSetter = false)
            {
                this.procNode = procNode;

                string getterPrefix = ProtoCore.DSASM.Constants.kGetterPrefix;
                int prefixLength = getterPrefix.Length;
                PropertyName = procNode.name.Substring(prefixLength);

                this.isSetter = isSetter;
            }
Example #13
0
            internal MethodMirror(ProcedureNode procNode)
            {
                MethodName = procNode.name;
                IsConstructor = procNode.isConstructor;
                IsStatic = procNode.isStatic;
                //IsAutoGenerated = procNode.isAutoGenerated;
                //IsAutoGeneratedThisProc = procNode.isAutoGeneratedThisProc;

                this.procNode = procNode;
            }
Example #14
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);
                }
            }
        }
        private void LoadObjects(DbObjectSearch search = null)
        {
            try
            {
                pbLoading.Visible = true;
                OperationStarted?.Invoke(this, "Loading objects...");

                tvwObjects.BeginUpdate();
                tvwObjects.Nodes.Clear();

                var schemas = _objects
                              .Where(obj => !string.IsNullOrEmpty(obj.Schema) && (search?.IsIncluded(obj) ?? true))
                              .GroupBy(obj => obj.Schema).OrderBy(grp => grp.Key);

                FolderNode folderNode = null;

                foreach (var schemaGrp in schemas)
                {
                    var schemaNode = new SchemaNode(schemaGrp.Key, schemaGrp.Count());
                    tvwObjects.Nodes.Add(schemaNode);

                    var tables = schemaGrp.OfType <Table>().OrderBy(obj => obj.Name);
                    if (tables.Any())
                    {
                        folderNode = new FolderNode("Tables", tables.Count());
                        schemaNode.Nodes.Add(folderNode);

                        foreach (var table in tables)
                        {
                            var tableNode = new TableNode(table);
                            if (_aliasManager.ContainsTable(table.ToString(), out string alias))
                            {
                                tableNode.Alias = alias;
                            }
                            folderNode.Nodes.Add(tableNode);

                            var foreignKeys = table.GetParentForeignKeys(_objects);
                            tableNode.Columns.AddRange(table.Columns.Select(col =>
                            {
                                var node = new ColumnNode(col, foreignKeys, table.IdentityColumn);
                                if (IsUniqueMultiColumn(table, col))
                                {
                                    node.NodeFont = new Font(tvwObjects.Font, FontStyle.Bold);
                                }
                                return(node);
                            }));

                            var childFKs = table.GetChildForeignKeys(_objects);
                            if (childFKs.Any())
                            {
                                var childFolderNode = new TreeNode($"Child Tables ({childFKs.Count()})")
                                {
                                    ImageKey = "join", SelectedImageKey = "join"
                                };
                                tableNode.Nodes.Add(childFolderNode);

                                foreach (var childFK in childFKs)
                                {
                                    var fkNode = new TableNode(childFK);
                                    childFolderNode.Nodes.Add(fkNode);
                                }
                            }
                        }
                        folderNode.Expand();
                    }

                    var views = schemaGrp.OfType <SqlSchema.Library.Models.View>().OrderBy(obj => obj.Name);
                    if (views.Any())
                    {
                        folderNode = new FolderNode("Views", views.Count());
                        schemaNode.Nodes.Add(folderNode);

                        foreach (var view in views)
                        {
                            var viewNode = new ViewNode(view);
                            folderNode.Nodes.Add(viewNode);
                        }
                    }

                    var functions = schemaGrp.OfType <TableFunction>().OrderBy(obj => obj.Name);
                    if (functions.Any())
                    {
                        folderNode = new FolderNode("Functions", functions.Count());
                        schemaNode.Nodes.Add(folderNode);

                        foreach (var func in functions)
                        {
                            var functionNode = new FunctionNode(func);
                            folderNode.Nodes.Add(functionNode);
                        }
                    }

                    var procs = schemaGrp.OfType <Procedure>().OrderBy(obj => obj.Name);
                    if (procs.Any())
                    {
                        folderNode = new FolderNode("Procedures", procs.Count());
                        schemaNode.Nodes.Add(folderNode);
                        foreach (var proc in procs)
                        {
                            var procNode = new ProcedureNode(proc);
                            folderNode.Nodes.Add(procNode);
                        }
                    }

                    schemaNode.Expand();
                }
            }
            finally
            {
                tvwObjects.EndUpdate();
                pbLoading.Visible = false;
                OperationEnded?.Invoke(this, new EventArgs());
            }
        }