protected override void PostWalk(MethodCallExpression node)
        {
          base.PostWalk(node);

          var i = Unwrap(node.Instance);

          if (i != null && node.Method.Name == "Call" &&  i.Type.IsSubclassOf(typeof(Callable)))
          {
            var mi = i.Type.GetMethod("Invoke");
            node.Method = mi;
            node.Instance = i;
            node.Arguments = node.Arguments.ConvertAll(e => Unwrap(e));
            node.ParameterInfos = mi.GetParameters();
          }
        }
                protected override void PostWalk(MethodCallExpression node)
                {
                    base.PostWalk(node);

                      var i = Unwrap(node.Instance);

                      if (i != null && node.Method.Name == "Call" && typeof(IronScheme.Runtime.Typed.ITypedCallable).IsAssignableFrom(i.Type))
                      {
                    var mi = i.Type.GetMethod("Invoke");
                    node.Method = mi;
                    node.Instance = i;
                    node.Arguments = node.Arguments.ConvertAll(e => Unwrap(e));
                    node.ParameterInfos = mi.GetParameters();
                      }
                }
예제 #3
0
    static bool IsSimpleCall(MethodCallExpression mce)
    {
      if (mce.Instance != null && !IsSimpleExpression(mce.Instance))
      {
        return false;
      }

      foreach (var arg in mce.Arguments)
      {
        if (arg is MethodCallExpression)
        {
          MethodCallExpression imce = (MethodCallExpression)arg;

          if (!IsSimpleCall(imce))
          {
            return false;
          }
        }

        if (!IsSimpleExpression(arg))
        {
          return false;
        }

      }

      return true;
    }
예제 #4
0
 // MethodCallExpression
 private void DefaultWalk(MethodCallExpression node)
 {
     if (Walk(node)) {
         WalkNode(node.Instance);
         IList<Expression> args = node.Arguments;
         if (args != null) {
             foreach (Expression e in args) {
                 WalkNode(e);
             }
         }
     }
     PostWalk(node);
 }
예제 #5
0
                bool IsTCE(MethodCallExpression mce, out Variable var)
                {
                    var = null;
                      // this could possibly removed if the label can be moved before the environment is allocated
                      if (Current.HasEnvironment) return false;
                      // i think this is to check if it is a return?
                      //if (!mce.TailCall) return false;
                      if (mce.Instance == null) return false;
                      if (mce.Arguments.Count > 8) return false;
                      var i = Unwrap(mce.Instance);
                      if (i is CodeBlockExpression)
                      {
                    var cbe = i as CodeBlockExpression;
                    if (cbe.Block == Current)
                    {
                      return true;
                    }
                    return false;
                      }
                      else
                      {
                    if (!typeof(Callable).IsAssignableFrom(i.Type)) return false;
                    var be = i as BoundExpression;
                    if (be == null) return false;
                    var = be.Variable;
                    if (/*!var.Lift ||*/ !typeof(Callable).IsAssignableFrom(var.Type) || var.ReAssigned) return false;
                    if (!(mce.Method.Name == "Call" || mce.Method.Name == "Invoke")) return false;
                    if (mce.Arguments.Count > 0 && mce.Arguments[0].Type == typeof(object[])) return false;
                    var av = var.AssumedValue as MethodCallExpression;

                    while (av == null && be.Variable.AssumedValue is BoundExpression)
                    {
                      be = be.Variable.AssumedValue as BoundExpression;
                      av = be.Variable.AssumedValue as MethodCallExpression;
                    }

                    if (av == null && be.Variable.AssumedValue is NewExpression)
                    {
                      var ne = be.Variable.AssumedValue as NewExpression;
                      if (!typeof(Callable).IsAssignableFrom(ne.Type)) return false;
                      var cbe = ne.Arguments[0] as CodeBlockExpression;
                      if (cbe == null || cbe.Block != Current) return false;
                    }
                    else
                    {
                      if (av == null || !typeof(Callable).IsAssignableFrom(av.Type) || av.Method.Name != "Create") return false;
                      var cbe = av.Arguments[0] as CodeBlockExpression;
                      if (cbe == null || cbe.Block != Current) return false;
                    }

                    return true;
                      }
                }
예제 #6
0
                bool IsHoistable(MethodCallExpression mce, out CodeBlockExpression cbe, out Variable var)
                {
                    cbe = null;
                      var = null;

                      // Am I needed?
                      //if (!mce.TailCall) return false;
                      if (mce.Instance == null) return false;
                      var i = Unwrap(mce.Instance);
                      if (!typeof(Callable).IsAssignableFrom(i.Type)) return false;
                      var be = i as BoundExpression;
                      if (be == null) return false;
                      var = be.Variable;

                      int x;
                      if (!refmap.TryGetValue(var, out x))
                      {
                    return false;
                      }
                      else
                      {
                    if (x != 1)
                    {
                      return false;
                    }
                      }

                      if (!callsites.TryGetValue(var, out x))
                      {
                    return false;
                      }
                      else
                      {
                    if (x != 1)
                    {
                      return false;
                    }
                      }

                      if (var.Lift || !typeof(Callable).IsAssignableFrom(var.Type) || var.ReAssigned) return false;
                      if (!(mce.Method.Name == "Call" || mce.Method.Name == "Invoke")) return false;
                      if (mce.Arguments.Count > 0 && mce.Arguments[0].Type == typeof(object[])) return false;
                      if (mce.Arguments.Count > 8) return false;

                      var av = var.AssumedValue as MethodCallExpression;

                      while (av == null && be.Variable.AssumedValue is BoundExpression)
                      {
                    be = be.Variable.AssumedValue as BoundExpression;
                    av = be.Variable.AssumedValue as MethodCallExpression;
                      }

                      if (av == null && be.Variable.AssumedValue is NewExpression)
                      {
                    var ne = be.Variable.AssumedValue as NewExpression;
                    if (!typeof(Callable).IsAssignableFrom(ne.Type)) return false;
                    cbe = ne.Arguments[0] as CodeBlockExpression;
                    if (cbe == null || cbe.Block.Parent != Current) return false;
                      }
                      else
                      {
                    if (av == null || !typeof(Callable).IsAssignableFrom(av.Type) || av.Method.Name != "Create") return false;
                    cbe = av.Arguments[0] as CodeBlockExpression;
                    if (cbe == null || cbe.Block.Parent != Current) return false;
                      }

                      //if (av == null || av.Type != typeof(Callable) || av.Method.Name != "Create") return false;
                      //cbe = av.Arguments[0] as CodeBlockExpression;
                      //if (cbe == null || cbe.Block.Parent != Current) return false;
                      //if (mce.Arguments.Count > 8) return false;

                      return true;
                }
예제 #7
0
                bool IsGood(MethodCallExpression mce, out Variable var)
                {
                    var = null;
                      // Am I needed?
                      //if (!mce.TailCall) return false;
                      if (mce.Instance == null) return false;
                      var i = Unwrap(mce.Instance);
                      if (!typeof(Callable).IsAssignableFrom(i.Type)) return false;
                      var be = i as BoundExpression;
                      if (be == null) return false;
                      var = be.Variable;

                      return true;
                }
                protected override bool Walk(MethodCallExpression node)
                {
                    var i = node.Instance;

                      if (node.Method != Generator.ICallable_CallN)
                      {

                    while (i is UnaryExpression && i.NodeType == AstNodeType.Convert)
                    {
                      i = ((UnaryExpression)i).Operand;
                    }

                    if (i is BoundExpression)
                    {

                      var be = (BoundExpression)i;
                      var v = be.Variable.Name;

                      if (Builtins.IsTrue(Builtins.IsSymbolBound(v)))
                      {
                    var val = Builtins.SymbolValue(v);

                    var c = val as BuiltinMethod;
                    if (c != null)
                    {
                      var mb = c.Binder;

                      var pars = new Expression[node.Arguments.Count];
                      node.Arguments.CopyTo(pars, 0);

                      Type[] types = Array.ConvertAll(pars, x => x.Type);
                      MethodCandidate mc = mb.MakeBindingTarget(CallType.None, types);
                      if (mc != null)
                      {
                    var meth = mc.Target.Method as MethodInfo;

                    node.Method = meth;
                    node.Instance = null;
                      }
                    }
                    else if (val is Closure)
                    {
                      var cc = val as Closure;

                      // will not work on varargs, need to somehow decorate them
                      var meth = Array.Find(cc.Targets,
                    x => x.GetParameters().Length == node.Arguments.Count && (Generator.AllowTransientBinding || !Generator.IsTransient(x.Module)));

                      if (meth != null)
                      {
                    node.Method = meth;
                    node.Instance = null;
                      }
                      else
                      {
                    meth = Array.Find(cc.VarargTargets,
                      x => x.GetParameters().Length - 1 <= node.Arguments.Count && (Generator.AllowTransientBinding || !Generator.IsTransient(x.Module)));

                    if (meth != null)
                    {
                      var newargs = new List<Expression>();

                      var pars = meth.GetParameters();
                      var parlen = pars.Length;
                      int x = 0;
                      for (; x < parlen - 1; x++)
                      {
                        newargs.Add(node.Arguments[x]);
                      }

                      var tail = new List<Expression>();
                      for (; x < node.Arguments.Count; x++)
                      {
                        tail.Add(node.Arguments[x]);
                      }

                      var tailarr = tail.ToArray();

                      newargs.Add(Ast.ComplexCallHelper(Compiler.Generator.MakeList(tailarr, true), tailarr));

                      node.Arguments.Clear();
                      node.Arguments.AddRange(newargs);

                      node.Method = meth;

                      node.ParameterInfos = pars;

                      node.Instance = null;
                    }
                      }

                    }
                      }
                    }
                      }

                      return base.Walk(node);
                }