public string MethodName; //either BindingInfo.Name, or name of the variable storing lambda expression #endregion Fields #region Constructors public Closure(Frame parentFrame, AstNode node, FunctionBindingInfo bindingInfo) { MethodName = bindingInfo.Name; ParentFrame = parentFrame; Node = node; BindingInfo = bindingInfo; }
private void EvaluateArgs(EvaluationContext context, FunctionBindingInfo targetInfo) { object[] values = context.CreateCallArgs(this.Arguments.Count); //Just for perfomance, we implement two cases separately if (targetInfo.IsSet(FunctionFlags.HasParamArray)) { //with params array for (int i = 0; i < targetInfo.ParamCount - 1; i++) { Arguments[i].Evaluate(context); values[i] = context.CurrentResult; } //Now combine all remaining arguments into one array and put it into the last element int startIndex = targetInfo.ParamCount - 1; int arrayLen = Arguments.Count - startIndex; object[] arrayArgs = new object[arrayLen]; for (int i = 0; i < arrayLen; i++) { Arguments[startIndex + i].Evaluate(context); arrayArgs[i] = context.CurrentResult; } values[startIndex] = arrayArgs; } else { //No params array for (int i = 0; i < Arguments.Count; i++) { Arguments[i].Evaluate(context); values[i] = context.CurrentResult; } } context.CallArgs = values; }//method
public override void OnCodeAnalysis(CodeAnalysisArgs args) { //process child nodes first, so that NameRef is processed base.OnCodeAnalysis(args); switch (args.Phase) { case CodeAnalysisPhase.Binding: if (NameRef.Slot != null) { NameRef.Slot.Flags |= SlotFlags.UsedAsCallTarget; } else { // Slot does not exist so it is not locally-defined method. Let's try global/library function // TODO: implement support for library references at scope level, so that all "import.." statements are checked // before checking global methods FixedTargetInfo = args.Context.Runtime.GetFunctionBindingInfo(NameRef.Name, Arguments); if (FixedTargetInfo == null) { args.Context.ReportError(this.Location, "Method not found: {0}", NameRef.Name); return; } }//else break; case CodeAnalysisPhase.MarkTailCalls: _isTail = IsSet(AstNodeFlags.IsTail) && this.Scope.Level > 0; break; case CodeAnalysisPhase.Optimization: if (this.FixedTargetInfo != null) this.Evaluate = InvokeFixed; else this.Evaluate = InvokeDynamic; break; }//switch }
public AnonFunctionNode(NodeArgs args, AstNode parameters, AstNode body) : base(args) { ChildNodes.Clear(); Parameters = parameters; AddChild("Params", Parameters); Body = body; AddChild("Body", Body); foreach (VarRefNode prm in Parameters.ChildNodes) prm.Flags |= AstNodeFlags.AllocateSlot; BindingInfo = new FunctionBindingInfo(null, Parameters.ChildNodes.Count, this.Body.Evaluate, this, FunctionFlags.IsLocal); }
public AnonFunctionNode(NodeArgs args, AstNode parameters, AstNode body) : base(args) { ChildNodes.Clear(); Parameters = parameters; AddChild("Params", Parameters); Body = body; AddChild("Body", Body); foreach (VarRefNode prm in Parameters.ChildNodes) { prm.Flags |= AstNodeFlags.AllocateSlot; } BindingInfo = new FunctionBindingInfo(null, Parameters.ChildNodes.Count, this.Body.Evaluate, this, FunctionFlags.IsLocal); }
}//constructor public override void OnCodeAnalysis(CodeAnalysisArgs args) { //process child nodes first, so that NameRef is processed base.OnCodeAnalysis(args); switch (args.Phase) { case CodeAnalysisPhase.Binding: if (NameRef.Slot != null) { NameRef.Slot.Flags |= SlotFlags.UsedAsCallTarget; } else { // Slot does not exist so it is not locally-defined method. Let's try global/library function // TODO: implement support for library references at scope level, so that all "import.." statements are checked // before checking global methods FixedTargetInfo = args.Context.Runtime.GetFunctionBindingInfo(NameRef.Name, Arguments); if (FixedTargetInfo == null) { args.Context.ReportError(this.Location, "Method not found: {0}", NameRef.Name); return; } }//else break; case CodeAnalysisPhase.MarkTailCalls: _isTail = IsSet(AstNodeFlags.IsTail) && this.Scope.Level > 0; break; case CodeAnalysisPhase.Optimization: if (this.FixedTargetInfo != null) { this.Evaluate = InvokeFixed; } else { this.Evaluate = InvokeDynamic; } break; } //switch } //method
private void EvaluateArgs(EvaluationContext context, FunctionBindingInfo targetInfo) { object[] values = context.CreateCallArgs(this.Arguments.Count); //Just for perfomance, we implement two cases separately if (targetInfo.IsSet(FunctionFlags.HasParamArray)) { //with params array for (int i = 0; i < targetInfo.ParamCount-1; i++) { Arguments[i].Evaluate(context); values[i] = context.CurrentResult; } //Now combine all remaining arguments into one array and put it into the last element int startIndex = targetInfo.ParamCount - 1; int arrayLen = Arguments.Count - startIndex; object[] arrayArgs = new object[arrayLen]; for (int i = 0; i < arrayLen; i++) { Arguments[startIndex + i].Evaluate(context); arrayArgs[i] = context.CurrentResult; } values[startIndex] = arrayArgs; } else { //No params array for (int i = 0; i < Arguments.Count; i++) { Arguments[i].Evaluate(context); values[i] = context.CurrentResult; } } context.CallArgs = values; }//method