Ejemplo n.º 1
0
        /// <summary>
        /// Create BinaryExpressionNode
        /// </summary>
        /// <param name="node"></param>
        /// <param name="outnode"></param>
        private void EmitBlockNode(Block node, out AssociativeNode outnode)
        {
            Validity.Assert(node != null);

            // TODO: Confirm that these children are returned in the order that they
            // appear in the code
            Dictionary <int, Node> childNodes = node.GetChildrenWithIndices();

            // Parse program statement in node.Name
            string code = node.Name + ";";

            ProtoCore.AST.AssociativeAST.CodeBlockNode commentNode   = null;
            ProtoCore.AST.AssociativeAST.CodeBlockNode codeBlockNode = (ProtoCore.AST.AssociativeAST.CodeBlockNode)GraphUtilities.Parse(code, out commentNode);
            Validity.Assert(codeBlockNode != null);

            List <ProtoCore.AST.AssociativeAST.AssociativeNode> astList = codeBlockNode.Body;

            Validity.Assert(astList.Count == 1);

            if (astList[0] is ProtoCore.AST.AssociativeAST.IdentifierNode)
            {
                ProtoCore.AST.AssociativeAST.BinaryExpressionNode ben = new ProtoCore.AST.AssociativeAST.BinaryExpressionNode();
                ben.LeftNode = astList[0];
                ben.Optr     = ProtoCore.DSASM.Operator.assign;
                ProtoCore.AST.AssociativeAST.AssociativeNode statement = null;
                foreach (KeyValuePair <int, Node> kvp in childNodes)
                {
                    DFSTraverse(kvp.Value, out statement);
                }
                ben.RightNode = statement;
                astList[0]    = ben;
            }

            //I don't know what I am doing
            if (astList[0] is BinaryExpressionNode)
            {
                BinaryExpressionNode tempBen = astList[0] as BinaryExpressionNode;
                if (tempBen.LeftNode is IdentifierNode)
                {
                    IdentifierNode identitiferNode = tempBen.LeftNode as IdentifierNode;
                    if (identitiferNode.ArrayDimensions != null)
                    {
                        ArrayIndexerNode arrIndex = new ArrayIndexerNode();
                        arrIndex.ArrayDimensions = identitiferNode.ArrayDimensions;
                        arrIndex.Array           = identitiferNode;
                        tempBen.LeftNode         = arrIndex;
                    }
                }
                if (tempBen.RightNode is IdentifierNode)
                {
                    IdentifierNode identitiferNode = tempBen.RightNode as IdentifierNode;
                    if (identitiferNode.ArrayDimensions != null)
                    {
                        ArrayIndexerNode arrIndex = new ArrayIndexerNode();
                        arrIndex.ArrayDimensions = identitiferNode.ArrayDimensions;
                        arrIndex.Array           = identitiferNode;
                        tempBen.RightNode        = arrIndex;
                    }
                }
                astList[0] = tempBen;
            }
            //it should be correct, if not, debug?

            ProtoCore.AST.AssociativeAST.BinaryExpressionNode bNode = astList[0] as ProtoCore.AST.AssociativeAST.BinaryExpressionNode;
            Validity.Assert(bNode != null);
            bNode.Guid = node.Guid;
            //bNode.SplitFromUID = node.splitFomUint;

            // Child nodes are arguments to expression in bNode.RightNode.
            // Match child nodes with IdentifierNode's in bNode.RightNode - pratapa
            foreach (Node n in childNodes.Values)
            {
                AssociativeNode argNode = null;
                DFSTraverse(n, out argNode);

                // DFS traverse the bNode.RightNode and check for IdentifierNode's
                // and if their names match with the names of argNode, then replace
                // the IdentifierNode in bNode.RightNode with argNode
                BinaryExpressionNode ben = argNode as BinaryExpressionNode;
                Validity.Assert(ben != null);
                //ProtoCore.CodeGenDS codeGen = new ProtoCore.CodeGenDS(ben);
                AstCodeBlockTraverse sourceGen = new AstCodeBlockTraverse(ben);
                ProtoCore.AST.AssociativeAST.AssociativeNode right = bNode.RightNode;
                sourceGen.DFSTraverse(ref right);
                bNode.RightNode = right;
            }

            //(AstRootNode as CodeBlockNode).Body.Add(expressionNode);

            Validity.Assert(gc != null);
            gc.HandleNewNode(bNode);

            outnode = bNode;
        }
Ejemplo n.º 2
0
        private void EmitFunctionNode(Func node, out AssociativeNode outnode)
        {
            Validity.Assert(node != null);

            AssociativeNode fNode         = new NullNode();
            string          funcQualifier = node.Name;

            if (node.isRange)
            {
                EmitRangeExpNode(node, out fNode);
            }
            else if (!funcQualifier.Contains("."))
            {
                if (node.isProperty)
                {
                    Dictionary <int, Node> nodes = node.GetChildrenWithIndices();
                    Validity.Assert(nodes.Count == 1);
                    for (int i = 0; i < nodes.Count; ++i)
                    {
                        AssociativeNode instanceNode = null;
                        DFSTraverse(nodes[i], out instanceNode);

                        EmitFunctionCallNode(node, out fNode);
                        ((fNode as FunctionCallNode).Function as IdentifierNode).Value = ProtoCore.DSASM.Constants.kGetterPrefix + ((fNode as FunctionCallNode).Function as IdentifierNode).Value;
                        //string className = (node.Name.Split('.'))[0];
                        //IdentifierNode inode = new IdentifierNode(className);

                        fNode = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(instanceNode, fNode as FunctionCallNode);
                    }
                }
                else if (node.isMemberFunction)
                {
                    Dictionary <int, Node> nodes = node.GetChildrenWithIndices();

                    AssociativeNode instanceNode = null;
                    DFSTraverse(nodes[0], out instanceNode);

                    EmitFunctionCallNode(node, out fNode);
                    //string className = (node.Name.Split('.'))[0];
                    //IdentifierNode inode = new IdentifierNode(className);

                    fNode = ProtoCore.Utils.CoreUtils.GenerateCallDotNode(instanceNode, fNode as FunctionCallNode);
                }
                else
                {
                    // Create AssociativeAST.FunctionCallNode for global and built-in functions
                    EmitFunctionCallNode(node, out fNode);
                }
            }
            else
            {
                // Create FunctionDotCallNode for ctors, static and instance methods
                EmitFunctionDotCallNode(node, out fNode);
            }

            BinaryExpressionNode assignmentNode = new BinaryExpressionNode();

            assignmentNode.LeftNode  = new IdentifierNode(node.tempName);
            assignmentNode.Optr      = ProtoCore.DSASM.Operator.assign;
            assignmentNode.RightNode = fNode;
            assignmentNode.Guid      = node.Guid;

            Validity.Assert(gc != null);
            gc.HandleNewNode(assignmentNode);

            outnode = assignmentNode;
        }
Ejemplo n.º 3
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 = AddressType.Pointer == svThisPtr.optype && ProtoCore.DSASM.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 (AddressType.Null == formalParameters[thisPtrIndex].optype)
                    {
                        core.RuntimeStatus.LogWarning(ProtoCore.RuntimeData.WarningID.kDereferencingNonPointer, ProtoCore.RuntimeData.WarningMessage.kDeferencingNonPointer);
                        return(StackUtils.BuildNull());
                    }

                    // These are the op types allowed.
                    Validity.Assert(AddressType.Pointer == formalParameters[thisPtrIndex].optype || AddressType.DefaultArg == formalParameters[thisPtrIndex].optype);

                    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.StackUtils.BuildNull());
                }

                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 <ProtoCore.DSASM.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;
                    core.Rmem.PushStackFrame(svThisPtr, ci, fi, returnAddr, blockDecl, blockCaller, callerType, ProtoCore.DSASM.StackFrameType.kTypeFunction, depth, framePointer, registers, locals);

                    //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 = StackUtils.BuildNull();
                    }
                    else if (ret is StackValue)
                    {
                        op = (StackValue)ret;
                    }
                    else if (ret is Int64 || ret is int)
                    {
                        op        = new StackValue();
                        op.optype = AddressType.Int;
                        op.opdata = (Int64)ret;
                    }
                    else if (ret is double)
                    {
                        op          = new StackValue();
                        op.optype   = AddressType.Double;
                        op.opdata_d = (double)ret;
                    }
                    else
                    {
                        throw new ArgumentException(string.Format("FFI: incorrect return type {0} from external function {1}:{2}", activation.ReturnType.Name,
                                                                  activation.ModuleName, activation.FunctionName));
                    }

                    // gc the parameters
                    if (gcThisPtr)// && core.Options.EnableThisPointerFunctionOverload)
                    {
                        // thisptr is sent as parameter, so need to gc it.
                        // but when running in expression interpreter mode, do not GC because in DSASM.Executive.DecRefCounter() related GC functions,
                        // the reference count will not be changed in expression interpreter mode.
                        if (core.ExecMode != ProtoCore.DSASM.InterpreterMode.kExpressionInterpreter)
                        {
                            interpreter.runtime.Core.Rmem.Heap.GCRelease(new StackValue[] { svThisPtr }, interpreter.runtime);
                        }
                    }
                    interpreter.runtime.Core.Rmem.Heap.GCRelease(formalParameters.ToArray(), interpreter.runtime);

                    // increment the reference counter of the return value
                    interpreter.runtime.GCRetain(op);
                    // Clear the FFI stack frame
                    // FFI stack frames have no local variables
                    interpreter.runtime.rmem.FramePointer = (int)interpreter.runtime.rmem.GetAtRelative(ProtoCore.DSASM.StackFrame.kFrameIndexFramePointer).opdata;
                    interpreter.runtime.rmem.PopFrame(ProtoCore.DSASM.StackFrame.kStackFrameSize + formalParameters.Count);

                    return(op); //DSASM.Mirror.ExecutionMirror.Unpack(op, core.heap, core);
                }
            }
        }
Ejemplo n.º 4
0
        private void EmitBinaryExpNode(Operator node, out AssociativeNode outnode)
        {
            Validity.Assert(node != null);

            Dictionary <int, Node> nodes = node.GetChildrenWithIndices();

            Validity.Assert(nodes.Count <= 2);

            BinaryExpressionNode expressionNode = new BinaryExpressionNode();

            // Create operator from input node
            switch (node.Name)
            {
            case "=":
                expressionNode.Optr = ProtoCore.DSASM.Operator.assign;
                break;

            case "+":
                expressionNode.Optr = ProtoCore.DSASM.Operator.add;
                break;

            case "-":
                expressionNode.Optr = ProtoCore.DSASM.Operator.sub;
                break;

            case "*":
                expressionNode.Optr = ProtoCore.DSASM.Operator.mul;
                break;

            case "/":
                expressionNode.Optr = ProtoCore.DSASM.Operator.div;
                break;

            case "%":
                expressionNode.Optr = ProtoCore.DSASM.Operator.mod;
                break;

            case "==":
                expressionNode.Optr = ProtoCore.DSASM.Operator.eq;
                break;

            case "!=":
                expressionNode.Optr = ProtoCore.DSASM.Operator.nq;
                break;

            case ">=":
                expressionNode.Optr = ProtoCore.DSASM.Operator.ge;
                break;

            case ">":
                expressionNode.Optr = ProtoCore.DSASM.Operator.gt;
                break;

            case "<=":
                expressionNode.Optr = ProtoCore.DSASM.Operator.le;
                break;

            case "<":
                expressionNode.Optr = ProtoCore.DSASM.Operator.lt;
                break;

            case "&&":
                expressionNode.Optr = ProtoCore.DSASM.Operator.and;
                break;

            case "||":
                expressionNode.Optr = ProtoCore.DSASM.Operator.or;
                break;

            case "&":
                expressionNode.Optr = ProtoCore.DSASM.Operator.bitwiseand;
                break;

            case "|":
                expressionNode.Optr = ProtoCore.DSASM.Operator.bitwiseor;
                break;

            case "^":
                expressionNode.Optr = ProtoCore.DSASM.Operator.bitwisexor;
                break;

            default: break;
            }

            AssociativeNode identNode1 = new NullNode();
            AssociativeNode identNode2 = new NullNode();

            if (nodes.Count == 2)
            {
                // Create BinaryExpressionNode from identNode1, identNode2 and operator
                DFSTraverse(nodes[0], out identNode1);
                DFSTraverse(nodes[1], out identNode2);
            }
            else if (nodes.Count == 1)
            {
                // Create BinaryExpressionNode from identNode1, null
                DFSTraverse(nodes[0], out identNode1);
            }
            expressionNode.LeftNode  = identNode1;
            expressionNode.RightNode = identNode2;

            //(AstRootNode as CodeBlockNode).Body.Add(expressionNode);
            BinaryExpressionNode assignmentNode = new BinaryExpressionNode();

            assignmentNode.LeftNode  = new IdentifierNode(node.tempName);
            assignmentNode.Optr      = ProtoCore.DSASM.Operator.assign;
            assignmentNode.RightNode = expressionNode;
            assignmentNode.Guid      = node.Guid;

            Validity.Assert(gc != null);
            gc.HandleNewNode(assignmentNode);

            outnode = assignmentNode;
        }
Ejemplo n.º 5
0
 public int GetType(string ident)
 {
     Validity.Assert(null != classTable);
     return(classTable.IndexOf(ident));
 }
Ejemplo n.º 6
0
        public static StackValue Coerce(StackValue sv, Type targetType, Core core)
        {
            //@TODO(Jun): FIX ME - abort coersion for default args
            if (sv.IsDefaultArgument)
            {
                return(sv);
            }

            if (!(
                    sv.metaData.type == targetType.UID ||
                    (core.ClassTable.ClassNodes[sv.metaData.type].ConvertibleTo(targetType.UID)) ||
                    sv.IsArray))
            {
                core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kConversionNotPossible, ProtoCore.RuntimeData.WarningMessage.kConvertNonConvertibleTypes);
                return(StackValue.Null);
            }

            //if it's an array
            if (sv.IsArray && !targetType.IsIndexable)
            {
                //This is an array rank reduction
                //this may only be performed in recursion and is illegal here
                string errorMessage = String.Format(ProtoCore.RuntimeData.WarningMessage.kConvertArrayToNonArray, core.TypeSystem.GetType(targetType.UID));
                core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kConversionNotPossible, errorMessage);
                return(StackValue.Null);
            }


            if (sv.IsArray &&
                targetType.IsIndexable)
            {
                Validity.Assert(sv.IsArray);

                //We're being asked to convert an array into an array
                //walk over the structure converting each othe elements

                if (targetType.UID == (int)PrimitiveType.kTypeVar && targetType.rank == DSASM.Constants.kArbitraryRank && core.Heap.IsTemporaryPointer(sv))
                {
                    return(sv);
                }

                //Validity.Assert(targetType.rank != -1, "Arbitrary rank array conversion not yet implemented {2EAF557F-62DE-48F0-9BFA-F750BBCDF2CB}");

                //Decrease level of reductions by one
                Type newTargetType = new Type();
                newTargetType.UID = targetType.UID;
                if (targetType.rank != Constants.kArbitraryRank)
                {
                    newTargetType.rank = targetType.rank - 1;
                }
                else
                {
                    if (ArrayUtils.GetMaxRankForArray(sv, core) == 1)
                    {
                        //Last unpacking
                        newTargetType.rank = 0;
                    }
                    else
                    {
                        newTargetType.rank = Constants.kArbitraryRank;
                    }
                }

                return(ArrayUtils.CopyArray(sv, newTargetType, core));
            }

            if (!sv.IsArray && !sv.IsNull &&
                targetType.IsIndexable &&
                targetType.rank != DSASM.Constants.kArbitraryRank)
            {
                //We're being asked to promote the value into an array
                if (targetType.rank == 1)
                {
                    Type newTargetType = new Type();
                    newTargetType.UID  = targetType.UID;
                    newTargetType.Name = targetType.Name;
                    newTargetType.rank = 0;

                    //Upcast once
                    StackValue coercedValue = Coerce(sv, newTargetType, core);
                    GCUtils.GCRetain(coercedValue, core);
                    StackValue newSv = core.Heap.AllocateArray(new StackValue[] { coercedValue }, null);
                    return(newSv);
                }
                else
                {
                    Validity.Assert(targetType.rank > 1, "Target rank should be greater than one for this clause");

                    Type newTargetType = new Type();
                    newTargetType.UID  = targetType.UID;
                    newTargetType.Name = targetType.Name;
                    newTargetType.rank = targetType.rank - 1;

                    //Upcast once
                    StackValue coercedValue = Coerce(sv, newTargetType, core);
                    GCUtils.GCRetain(coercedValue, core);
                    StackValue newSv = core.Heap.AllocateArray(new StackValue[] { coercedValue }, null);
                    return(newSv);
                }
            }

            if (sv.IsPointer)
            {
                StackValue ret = ClassCoerece(sv, targetType, core);
                return(ret);
            }

            //If it's anything other than array, just create a new copy
            switch (targetType.UID)
            {
            case (int)PrimitiveType.kInvalidType:
                Validity.Assert(false, "Can't convert invalid type");
                break;

            case (int)PrimitiveType.kTypeBool:
                return(sv.ToBoolean(core));

            case (int)PrimitiveType.kTypeChar:
            {
                StackValue newSV = sv.ShallowClone();
                newSV.metaData = new MetaData {
                    type = (int)PrimitiveType.kTypeChar
                };
                return(newSV);
            }

            case (int)PrimitiveType.kTypeDouble:
                return(sv.ToDouble());

            case (int)PrimitiveType.kTypeFunctionPointer:
                if (sv.metaData.type != (int)PrimitiveType.kTypeFunctionPointer)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, ProtoCore.RuntimeData.WarningMessage.kFailToConverToFunction);
                    return(StackValue.Null);
                }
                return(sv);

            case (int)PrimitiveType.kTypeHostEntityID:
            {
                StackValue newSV = sv.ShallowClone();
                newSV.metaData = new MetaData {
                    type = (int)PrimitiveType.kTypeHostEntityID
                };
                return(newSV);
            }

            case (int)PrimitiveType.kTypeInt:
            {
                if (sv.metaData.type == (int)PrimitiveType.kTypeDouble)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeConvertionCauseInfoLoss, ProtoCore.RuntimeData.WarningMessage.kConvertDoubleToInt);
                }
                return(sv.ToInteger());
            }

            case (int)PrimitiveType.kTypeNull:
            {
                if (sv.metaData.type != (int)PrimitiveType.kTypeNull)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, ProtoCore.RuntimeData.WarningMessage.kFailToConverToNull);
                    return(StackValue.Null);
                }
                return(sv);
            }

            case (int)PrimitiveType.kTypePointer:
            {
                if (sv.metaData.type != (int)PrimitiveType.kTypeNull)
                {
                    core.RuntimeStatus.LogWarning(RuntimeData.WarningID.kTypeMismatch, ProtoCore.RuntimeData.WarningMessage.kFailToConverToPointer);
                    return(StackValue.Null);
                }
                return(sv);
            }

            case (int)PrimitiveType.kTypeString:
            {
                StackValue newSV = sv.ShallowClone();
                newSV.metaData = new MetaData {
                    type = (int)PrimitiveType.kTypeString
                };
                if (sv.metaData.type == (int)PrimitiveType.kTypeChar)
                {
                    char ch = EncodingUtils.ConvertInt64ToCharacter(newSV.opdata);
                    newSV = StackValue.BuildString(ch.ToString(), core.Heap);
                }
                return(newSV);
            }

            case (int)PrimitiveType.kTypeVar:
            {
                return(sv);
            }

            case (int)PrimitiveType.kTypeArray:
            {
                return(ArrayUtils.CopyArray(sv, targetType, core));
            }

            default:
                if (sv.IsNull)
                {
                    return(StackValue.Null);
                }
                else
                {
                    throw new NotImplementedException("Requested coercion not implemented");
                }
            }

            throw new NotImplementedException("Requested coercion not implemented");
        }
Ejemplo n.º 7
0
 public string GetType(int UID)
 {
     Validity.Assert(null != classTable);
     return(classTable.GetTypeName(UID));
 }
Ejemplo n.º 8
0
 public static string GetMethodName(StackValue pointer, Interpreter dsi)
 {
     Validity.Assert(pointer.IsFunctionPointer);
     return(dsi.runtime.exe.procedureTable[0].procList[(int)pointer.opdata].name);
 }
Ejemplo n.º 9
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.kAssociative);
                {
                    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);

                    /*if (core.DebugProps.RunMode == Runmode.StepNext)
                     * {
                     *  core.Breakpoints.Clear();
                     * }*/

                    isReplicating      = false;
                    isExternalFunction = false;
                }
                else // an inline conditional call that replicates
                {
#if !__DEBUG_REPLICATE
                    // Clear all breakpoints for outermost replicated call
                    if (!DebugStackFrameContains(StackFrameFlagOptions.IsReplicating))
                    {
                        ActiveBreakPoints.AddRange(runtimeCore.Breakpoints);
                        runtimeCore.Breakpoints.Clear();
                    }
#endif
                    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)
            {
#if !__DEBUG_REPLICATE
                // Clear all breakpoints for outermost replicated call
                if (!DebugStackFrameContains(StackFrameFlagOptions.IsReplicating))
                {
                    ActiveBreakPoints.AddRange(runtimeCore.Breakpoints);
                    runtimeCore.Breakpoints.Clear();
                }
#endif

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

            SetUpCallr(ref debugFrame, isReplicating, isExternalFunction, exec);
            DebugStackFrame.Push(debugFrame);
        }
Ejemplo n.º 10
0
        public void SetTypeSystem()
        {
            Validity.Assert(null == classTable);
            if (null != classTable)
            {
                return;
            }

            classTable = new DSASM.ClassTable();

            classTable.Reserve((int)PrimitiveType.kMaxPrimitives);

            ClassNode cnode;

            cnode = new ClassNode {
                name = DSDefinitions.Keyword.Array, size = 0, rank = 5, symbols = null, vtable = null, typeSystem = this
            };

            /*cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
             * cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
             * cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
             * cnode.coerceTypes.Add((int)PrimitiveType.kTypeChar, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
             * cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
             */
            cnode.classId = (int)PrimitiveType.kTypeArray;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeArray);

            //
            //
            cnode = new ClassNode {
                name = DSDefinitions.Keyword.Double, size = 0, rank = 4, symbols = null, vtable = null, typeSystem = this
            };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceDoubleToIntScore);
            cnode.classId = (int)PrimitiveType.kTypeDouble;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeDouble);

            //
            //
            cnode = new ClassNode {
                name = DSDefinitions.Keyword.Int, size = 0, rank = 3, symbols = null, vtable = null, typeSystem = this
            };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceIntToDoubleScore);
            cnode.classId = (int)PrimitiveType.kTypeInt;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeInt);

            //
            //
            cnode = new ClassNode {
                name = DSDefinitions.Keyword.Bool, size = 0, rank = 2, symbols = null, vtable = null, typeSystem = this
            };
            // if convert operator to method call, without the following statement
            // a = true + 1 will fail, because _add expects two integers
            //cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeBool;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeBool);

            //
            //
            cnode = new ClassNode {
                name = DSDefinitions.Keyword.Char, size = 0, rank = 1, symbols = null, vtable = null, typeSystem = this
            };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);

            cnode.classId = (int)PrimitiveType.kTypeChar;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeChar);

            //
            //
            cnode = new ClassNode {
                name = DSDefinitions.Keyword.String, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeString;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeString);

            //
            //
            cnode = new ClassNode {
                name = DSDefinitions.Keyword.Var, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };

            /*cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            *  cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            *  cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            *  cnode.coerceTypes.Add((int)PrimitiveType.kTypeChar, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            *  cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);*/
            cnode.classId = (int)PrimitiveType.kTypeVar;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeVar);

            //
            //
            cnode = new ClassNode {
                name = DSDefinitions.Keyword.Null, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeDouble, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeBool, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeChar, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeString, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeNull;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeNull);

            //
            //
            cnode = new ClassNode {
                name = DSDefinitions.Keyword.Void, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            cnode.classId = (int)PrimitiveType.kTypeVoid;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeVoid);

            //
            //
            cnode = new ClassNode {
                name = "hostentityid", size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            cnode.classId = (int)PrimitiveType.kTypeHostEntityID;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeHostEntityID);
            //
            //
            cnode = new ClassNode {
                name = "pointer_reserved", size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            // if convert operator to method call, without the following statement,
            // a = b.c + d.e will fail, b.c and d.e are resolved as pointer and _add method requires two integer
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypePointer;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypePointer);
            //
            //
            cnode = new ClassNode {
                name = DSDefinitions.Keyword.FunctionPointer, size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            cnode.coerceTypes.Add((int)PrimitiveType.kTypeInt, (int)ProtoCore.DSASM.ProcedureDistance.kCoerceScore);
            cnode.classId = (int)PrimitiveType.kTypeFunctionPointer;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeFunctionPointer);

            //
            //
            cnode = new ClassNode {
                name = "return_reserved", size = 0, rank = 0, symbols = null, vtable = null, typeSystem = this
            };
            cnode.classId = (int)PrimitiveType.kTypeReturn;
            classTable.SetClassNodeAt(cnode, (int)PrimitiveType.kTypeReturn);
        }
Ejemplo n.º 11
0
 public void ResetModifedSymbols()
 {
     Validity.Assert(null != mapModifiedSymbols);
     mapModifiedSymbols.Clear();
 }
Ejemplo n.º 12
0
 public void SetGlobalStackData(int globalOffset, StackValue svData)
 {
     Validity.Assert(globalOffset >= 0);
     Validity.Assert(Stack.Count > 0);
     Stack[globalOffset] = svData;
 }
Ejemplo n.º 13
0
        public StackValue Evaluate(List <StackValue> args, StackFrame stackFrame)
        {
            // Build the stackframe
            var core = interpreter.runtime.Core;

            int        classScopeCaller = stackFrame.ClassScope;
            int        returnAddr       = stackFrame.ReturnPC;
            int        blockDecl        = procNode.runtimeIndex;
            int        blockCaller      = stackFrame.FunctionCallerBlock;
            int        framePointer     = core.Rmem.FramePointer;
            StackValue thisPtr          = StackValue.BuildPointer(Constants.kInvalidIndex);

            // Functoion has variable input parameter. This case only happen
            // for FFI functions whose last parameter's type is (params T[]).
            // In this case, we need to convert argument list from
            //
            //    {a1, a2, ..., am, v1, v2, ..., vn}
            //
            // to
            //
            //    {a1, a2, ..., am, {v1, v2, ..., vn}}
            if (procNode.isVarArg)
            {
                int paramCount = procNode.argInfoList.Count;
                Validity.Assert(paramCount >= 1);

                int varParamCount = args.Count - (paramCount - 1);
                var varParams     = args.GetRange(paramCount - 1, varParamCount).ToArray();
                args.RemoveRange(paramCount - 1, varParamCount);

                var packedParams = interpreter.runtime.Core.Heap.AllocateArray(varParams, null);
                args.Add(packedParams);
            }

            bool isCallingMemberFunciton = procNode.classScope != Constants.kInvalidIndex &&
                                           !procNode.isConstructor &&
                                           !procNode.isStatic;

            bool isValidThisPointer = true;

            if (isCallingMemberFunciton)
            {
                Validity.Assert(args.Count >= 1);
                thisPtr = args[0];
                if (thisPtr.IsArray)
                {
                    isValidThisPointer = ArrayUtils.GetFirstNonArrayStackValue(thisPtr, ref thisPtr, core);
                }
                else
                {
                    args.RemoveAt(0);
                }
            }

            if (!isValidThisPointer || (!thisPtr.IsPointer && !thisPtr.IsArray))
            {
                core.RuntimeStatus.LogWarning(WarningID.kDereferencingNonPointer,
                                              Resources.kDeferencingNonPointer);
                return(StackValue.Null);
            }

            var callerType = stackFrame.StackFrameType;

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

            StackValue svBlockDecl = StackValue.BuildBlockIndex(blockDecl);

            interpreter.runtime.SX = svBlockDecl;

            var repGuides = new List <List <ProtoCore.ReplicationGuide> >();

            List <StackValue> registers = new List <StackValue>();

            interpreter.runtime.SaveRegisters(registers);
            var newStackFrame = new StackFrame(thisPtr,
                                               classScopeCaller,
                                               1,
                                               returnAddr,
                                               blockDecl,
                                               blockCaller,
                                               callerType,
                                               StackFrameType.kTypeFunction,
                                               0,   // depth
                                               framePointer,
                                               registers,
                                               null);

            bool isInDebugMode = core.Options.IDEDebugMode &&
                                 core.ExecMode != InterpreterMode.kExpressionInterpreter;

            if (isInDebugMode)
            {
                core.DebugProps.SetUpCallrForDebug(core,
                                                   interpreter.runtime,
                                                   procNode,
                                                   returnAddr - 1,
                                                   false,
                                                   callsite,
                                                   args,
                                                   repGuides,
                                                   newStackFrame);
            }

            StackValue rx = callsite.JILDispatchViaNewInterpreter(
                new Runtime.Context(),
                args,
                repGuides,
                newStackFrame,
                core);

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

            return(rx);
        }
Ejemplo n.º 14
0
        public override StackValue Execute(Runtime.Context c, List <StackValue> formalParameters, StackFrame stackFrame, RuntimeCore runtimeCore)
        {
            StackValue svThisPtr = stackFrame.ThisPtr;

            if (mInterpreter == null)
            {
                Init(runtimeCore);
            }

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

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

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

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

                // Make sure we to pass a pointer to unmarshal.
                if (formalParameters[thisPtrIndex].IsPointer)
                {
                    svThisPtr = formalParameters[thisPtrIndex];
                }

                formalParameters.RemoveAt(thisPtrIndex);
            }

            formalParameters.Add(svThisPtr);

            Object     ret = mFunctionPointer.Execute(c, mInterpreter, formalParameters);
            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));
            }
            return(op);
        }
Ejemplo n.º 15
0
 public string GetType(Type type)
 {
     Validity.Assert(null != classTable);
     return(classTable.GetTypeName(type.UID));
 }
Ejemplo n.º 16
0
        public void RunExpression(HomeWorkspaceModel workspaceModel, int?executionInterval = null)
        {
            if (workspaceModel == null)
            {
                return;
            }

            var dynamoModel = workspaceModel.DynamoModel;

            execInternval = executionInterval;

            lock (RunControlMutex)
            {
                if (Running)
                {
                    //We're already running, so we might need an additional run
                    NeedsAdditionalRun = true;
                    return;
                }
                //We're new so if we needed an additional run, this one counts
                NeedsAdditionalRun = false;

                // If there is preloaded trace data, send that along to the current
                // LiveRunner instance. Here we make sure it is done exactly once
                // by resetting WorkspaceModel.PreloadedTraceData property after it
                // is obtained.
                //
                IEnumerable <KeyValuePair <Guid, List <string> > > traceData =
                    workspaceModel.PreloadedTraceData;
                workspaceModel.PreloadedTraceData = null; // Reset.

                if (dynamoModel == null || dynamoModel.EngineController == null)
                {
                    return;
                }

                dynamoModel.EngineController.LiveRunnerCore.SetTraceDataForNodes(traceData);

                //We are now considered running
                Running = true;
            }

            if (!DynamoModel.IsTestMode)
            {
                //Setup background worker
                dynamoModel.RunEnabled = false;

                //As we are the only place that is allowed to activate this, it is a trap door, so this is safe
                lock (RunControlMutex)
                {
                    Validity.Assert(Running);
                }
                RunAsync(workspaceModel);
            }
            else
            {
                //for testing, we do not want to run asynchronously, as it will finish the
                //test before the evaluation (and the run) is complete
                //RunThread(evaluationWorker, new DoWorkEventArgs(executionInterval));
                RunSync(workspaceModel);
            }
        }
Ejemplo n.º 17
0
        private void CompileToAstNodes(NodeModel node, List <AssociativeNode> resultList, CompilationContext context, bool verboseLogging)
        {
            var inputAstNodes = new List <AssociativeNode>();

            foreach (int index in Enumerable.Range(0, node.InPortData.Count))
            {
                Tuple <int, NodeModel> inputTuple;

                if (node.TryGetInput(index, out inputTuple))
                {
                    int             outputIndexOfInput = inputTuple.Item1;
                    NodeModel       inputModel         = inputTuple.Item2;
                    AssociativeNode inputNode          = inputModel.GetAstIdentifierForOutputIndex(outputIndexOfInput);

#if DEBUG
                    Validity.Assert(inputNode != null,
                                    "Shouldn't have null nodes in the AST list");
#endif
                    inputAstNodes.Add(inputNode);
                }
                else
                {
                    PortData port = node.InPortData[index];
                    inputAstNodes.Add(port.DefaultValue ?? new NullNode());
                }
            }

            //TODO: This should do something more than just log a generic message. --SJE
            if (node.State == ElementState.Error)
            {
                Log("Error in Node. Not sent for building and compiling");
            }

            if (context == CompilationContext.DeltaExecution || context == CompilationContext.PreviewGraph)
            {
                OnAstNodeBuilding(node.GUID);
            }

#if DEBUG
            Validity.Assert(inputAstNodes.All(n => n != null),
                            "Shouldn't have null nodes in the AST list");
#endif

            var scopedNode = node as ScopedNodeModel;
            IEnumerable <AssociativeNode> astNodes =
                scopedNode != null
                    ? scopedNode.BuildAstInScope(inputAstNodes, verboseLogging, this)
                    : node.BuildAst(inputAstNodes, context);

            if (verboseLogging)
            {
                foreach (var n in astNodes)
                {
                    Log(n.ToString());
                }
            }

            if (null == astNodes)
            {
                resultList.AddRange(new AssociativeNode[0]);
            }
            else if (context == CompilationContext.DeltaExecution || context == CompilationContext.PreviewGraph)
            {
                OnAstNodeBuilt(node.GUID, astNodes);
                resultList.AddRange(astNodes);
            }
            else if (context == CompilationContext.NodeToCode)
            {
                resultList.AddRange(astNodes);
            }
            else //Inside custom node compilation.
            {
                bool notified = false;
                foreach (var item in astNodes)
                {
                    if (item is FunctionDefinitionNode)
                    {
                        if (!notified)
                        {
                            OnAstNodeBuilding(node.GUID);
                        }
                        notified = true;
                        //Register the function node in global scope with Graph Sync data,
                        //so that we don't have a function definition inside the function def
                        //of custom node.
                        OnAstNodeBuilt(node.GUID, new[] { item });
                    }
                    else
                    {
                        resultList.Add(item);
                    }
                }
            }
        }