Example #1
0
 // CodeBlockExpression
 private void DefaultWalk(CodeBlockExpression node)
 {
     if (node.IsDeclarative && Walk(node))
     {
         WalkNode(node.Block);
     }
     PostWalk(node);
 }
        protected internal override void PostWalk(CodeBlockExpression node) {
            // We use PostWalk here since Walk is only called for IsDeclarative=true

            // Currently, CodeBlockExpression ignores the DelegateType. This will result in the generation of 
            // an incorrectly type delegate. For eg, for event hookup with a source code snippet, a language might 
            // generate a rule that creates CodeBlockExpressions with the source code snippet typed as EventHandler.
            // The interpreter will ignore that a create a CallWithContextN delegate, which will cause a problem 
            // with the event hookup
            if (node.DelegateType != null) {
                _hasUnsupportedNodes = true;
            }
        }
        protected internal override void PostWalk(CodeBlockExpression node)
        {
            // We use PostWalk here since Walk is only called for IsDeclarative=true

            // Currently, CodeBlockExpression ignores the DelegateType. This will result in the generation of
            // an incorrectly type delegate. For eg, for event hookup with a source code snippet, a language might
            // generate a rule that creates CodeBlockExpressions with the source code snippet typed as EventHandler.
            // The interpreter will ignore that a create a CallWithContextN delegate, which will cause a problem
            // with the event hookup
            if (node.DelegateType != null)
            {
                _hasUnsupportedNodes = true;
            }
        }
Example #4
0
        // CodeBlockExpression
        private void Dump(CodeBlockExpression node)
        {
            int id = Enqueue(node.Block);

            Out(String.Format(".block ({0} #{1}", node.Block.Name, id));
            Indent();
            bool nl = false;

            if (node.ForceWrapperMethod)
            {
                nl = true; Out(Flow.NewLine, "ForceWrapper");
            }
            if (node.IsStronglyTyped)
            {
                nl = true; Out(Flow.NewLine, "StronglyTyped");
            }
            if (node.IsDeclarative)
            {
                nl = true; Out(Flow.NewLine, "Declarative");
            }
            Dedent();
            Out(nl ? Flow.NewLine : Flow.None, ")");
        }
Example #5
0
    protected internal static Expression InlineCall(CodeBlock parent, CodeBlockExpression cbe, bool istailpostion, params Expression[] pp)
    {
      // all var names are unique.
      CodeBlock cb = cbe.Block;

      if (parent.IsGlobal) 
      {
        return CallNormal(cbe, pp);
      }

      List<Statement> assigns = new List<Statement>();
      int i = 0;

      cb.Inlined = true;

      if (parent.Filename == null && cb.Filename != null)
      {
        parent.Filename = cb.Filename;
      }

      var parentvars = new List<Variable>(parent.Variables);

      foreach (Variable p in cb.Parameters)
      {
        SymbolId origname = p.Name;

        p.Name = (SymbolId)Builtins.GenSym(p.Name);
        p.Block = parent;
        p.Kind = Variable.VariableKind.Local;
        parent.AddVariable(p);

        Expression val = Unwrap(pp[i]);
        if (val.Type != typeof(SymbolId) && !Generator.assigns.ContainsKey(origname))
        {
          if (p.Type == typeof(object))
          {
            p.Type = val.Type;
            assigns.Add(Ast.Write(p, val));
          }
          else
          {
            assigns.Add(Ast.Write(p, Ast.ConvertHelper(val, p.Type)));
          }
        }
        else
        {
          if (p.Type == typeof(object))
          {
            assigns.Add(Ast.Write(p, pp[i]));
          }
          else
          {
            assigns.Add(Ast.Write(p, Ast.ConvertHelper(pp[i], p.Type)));
          }
        }
          
        if (p.Lift)
        {
          parent.HasEnvironment = true;
        }
        i++;
      }

      foreach (Variable l in cb.Variables)
      {
        if (l.DefaultValue == null && l.Kind != Variable.VariableKind.Global)
        {
          l.Name = (SymbolId)Builtins.GenSym(l.Name);
        }
        l.Block = parent;
        parent.AddVariable(l);

        if (l.Lift)
        {
          parent.HasEnvironment = true;
        }
      }

      Expression body = RewriteReturn(cb.Body);

      if (assigns.Count > 0)
      {
        return Ast.Comma(Ast.Void(Ast.Block(assigns)), body);
      }
      else
      {
        return body;
      }
    }
Example #6
0
 protected static Expression InlineCall(CodeBlock parent, CodeBlockExpression cbe, params Expression[] pp)
 {
   return InlineCall(parent, cbe, false, pp);
 }
Example #7
0
    protected static Expression CallVarArgs(CodeBlockExpression cbe, Expression[] ppp)
    {
      bool needscontext = NeedsContext(cbe); //true;

      int pc = cbe.Block.ParameterCount;

      Expression[] tail = new Expression[ppp.Length - (pc - 1)];

      Array.Copy(ppp, ppp.Length - tail.Length, tail, 0, tail.Length);

      Expression[] nppp = new Expression[pc];

      Array.Copy(ppp, nppp, ppp.Length - tail.Length);

      if (tail.Length > 0)
      {
        nppp[nppp.Length - 1] = Ast.ComplexCallHelper(MakeList(tail, true), tail);
      }
      else
      {
        nppp[nppp.Length - 1] = Ast.Null();
      }

      ppp = nppp;

      MethodInfo dc = GetDirectCallable(needscontext, pc, cbe.Type);
      if (needscontext)
      {
        ppp = ArrayUtils.Insert<Expression>(Ast.CodeContext(), ppp);
      }

      cbe = Ast.CodeBlockReference(cbe.Block, CallTargets.GetTargetType(needscontext, pc, false));

      cbe.Block.Bind();

      var r = Ast.ComplexCallHelper(cbe, dc, ppp);
      if (SpanHint.IsValid)
      {
        r.SetLoc(SpanHint);
      }
      return r;
    }
Example #8
0
 static bool NeedsContext(CodeBlockExpression cbe)
 {
   return cbe.Block.IsClosure || 
     cbe.Block.ExplicitCodeContextExpression == null && 
     (cbe.Block.Parent != null && !cbe.Block.Parent.IsGlobal);
 }
Example #9
0
    protected static Expression CallNormal(CodeBlockExpression cbe, params Expression[] ppp)
    {
      bool needscontext = NeedsContext(cbe); // true;
      int pc = ppp.Length;
      MethodInfo dc = GetDirectCallable(needscontext, pc, cbe.Type);

      List<Variable> paruninit = new List<Variable>(cbe.Block.Parameters);

      for (int i = 0; i < ppp.Length; i++)
      {
        if (ppp[i].Type == typeof(Uninitialized))
        {
          paruninit[i].SetUnInitialized();
        }
      }

      if (needscontext)
      {
        ppp = ArrayUtils.Insert<Expression>(Ast.CodeContext(), ppp);
      }

      var delegatetype = cbe.Type != typeof(Delegate) ? cbe.Type : CallTargets.GetTargetType(needscontext, pc, false);

      cbe = Ast.CodeBlockReference(cbe.Block, delegatetype);

      cbe.Block.Bind();

      var r = Ast.ComplexCallHelper(cbe, dc, ppp);
      if (SpanHint.IsValid)
      {
        r.SetLoc(SpanHint);
      }
      return r;
    }
        public override void Emit(CodeGen cg)
        {
            // TODO: Improve the following to direct call: Callable.Call(Callable.Create(...))
            //EmitLocation(cg);
            if (_instance != null && !cg.IsDynamicMethod) // damn DM! // go away! // this dangerous too for now
            {
                if (!IsParamsMethod())
                {
                    if (_instance is CodeBlockExpression)
                    {
                        CodeBlockExpression cbe = (CodeBlockExpression)_instance;

                        Debug.Assert(_arguments.Count == _parameterInfos.Length);
                        for (int arg = 0; arg < _parameterInfos.Length; arg++)
                        {
                            Expression argument = _arguments[arg];
                            Type       type     = _parameterInfos[arg].ParameterType;
                            EmitArgument(cg, argument, type);
                        }

                        EmitLocation(cg);

                        if (tailcall)
                        {
                            // TODO: Remove tail calls from list of known non-recursive methods
                            //Console.WriteLine(cbe.Block.Name);
                            tailcall = true;
                        }

                        cbe.EmitDirect(cg, tailcall);

                        if (ScriptDomainManager.Options.LightweightDebugging && !tailcall && Span.IsValid)
                        {
                            cg.EmitConstant(SpanToLong(Span));
                            cg.EmitCall(Debugging.DebugMethods.ExpressionOut);
                        }

                        return;
                    }
                }
                else // 'params'
                {
                }
            }

            if (_method == BuiltinsIsTrue)
            {
                EmitLocation(cg);
                var arg = Unwrap(_arguments[0]);
                if (arg.Type == typeof(bool))
                {
                    arg.Emit(cg);
                }
                else if (arg.Type == typeof(object))
                {
                    Label next = cg.DefineLabel();
                    Label end  = cg.DefineLabel();
                    arg.Emit(cg);
                    cg.Emit(OpCodes.Dup);
                    cg.Emit(OpCodes.Isinst, typeof(bool));
                    cg.Emit(OpCodes.Brfalse, next);

                    cg.EmitUnbox(typeof(bool));
                    cg.Emit(OpCodes.Br, end);

                    cg.MarkLabel(next);
                    cg.Emit(OpCodes.Pop);
                    cg.EmitConstant(true);
                    cg.MarkLabel(end);
                }
                else
                {
                    cg.EmitConstant(true);
                }
                return;
            }

            var ii = _instance;

            ii = Unwrap(ii);

            BoundExpression.Emitter fixup = null;
            bool varargs = false;
            var  pttt    = Array.ConvertAll(_parameterInfos, x => x.ParameterType);

            if (ii is BoundExpression)
            {
                var be = ii as BoundExpression;

                if (BoundExpression.Fixups.ContainsKey(be.Variable.Name))
                {
                    fixup = BoundExpression.Fixups[be.Variable.Name];
                    pttt  = BoundExpression.FixupTypes[be.Variable.Name];
                }
                else
                {
                    CodeGen             rcg;
                    CodeGenDescriptor[] cgd;
                    if (CodeGen._codeBlockLookup.TryGetValue(be.Variable.Name, out rcg))
                    {
                        var lpttt = pt.GetValue(rcg.MethodInfo) as Type[];
                        if (_arguments.Count == lpttt.Length)
                        {
                            _method = rcg.MethodInfo;
                            pttt    = lpttt;
                        }
                    }
                    else if (CodeGen._codeBlockLookupX.TryGetValue(be.Variable.Name, out rcg))
                    {
                        var lpppt = pt.GetValue(rcg.MethodInfo) as Type[];
                        if (lpppt.Length - 1 > _arguments.Count)
                        {
                        }
                        else if (AllArgsAreObject(_arguments))
                        {
                            _method = rcg.MethodInfo;
                            pttt    = lpppt;
                            varargs = true;
                        }
                        else if (_arguments.Count == 1 && lpppt.Length == 1 &&
                                 _arguments[0].Type == typeof(object[]) && _arguments[0] is MethodCallExpression &&
                                 ((MethodCallExpression)_arguments[0])._method.Name == "ListToVector")
                        {
                            _arguments[0] = Unwrap(((MethodCallExpression)_arguments[0]).Arguments[0]);
                            _method       = rcg.MethodInfo;
                            pttt          = lpppt;
                        }
                    }
                    else if (CodeGen._codeBlockLookupN.TryGetValue(be.Variable.Name, out cgd))
                    {
                        if (AllArgsAreObject(_arguments))
                        {
                            foreach (var i in cgd)
                            {
                                if (i.arity == _arguments.Count)
                                {
                                    _method = i.cg.MethodInfo;
                                    pttt    = pt.GetValue(_method) as Type[];
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            // Emit instance, if calling an instance method
            if (!_method.IsStatic)
            {
                Type type = _method.DeclaringType;

                if (type.IsValueType)
                {
                    _instance.EmitAddress(cg, type);
                }
                else
                {
                    if (fixup == null)
                    {
                        _instance.Emit(cg);
                    }
                }
            }

            if (varargs)
            {
                int arg = 0;
                for (; arg < pttt.Length - 1; arg++)
                {
                    Expression argument = _arguments[arg];
                    Type       type     = pttt[arg];
                    EmitArgument(cg, argument, type);
                }
                // make tail
                var tailargs = new List <Expression>();
                for (; arg < _arguments.Count; arg++)
                {
                    tailargs.Add(_arguments[arg]);
                }
                var tailarr = tailargs.ToArray();
                var tail    = Ast.ComplexCallHelper(MakeList(tailarr, true), tailarr);
                EmitArgument(cg, tail, typeof(object));
            }
            else
            {
                // Emit arguments
                // we cant really complain here or show error...
                Debug.Assert(_arguments.Count == pttt.Length);
                for (int arg = 0; arg < pttt.Length && arg < _arguments.Count; arg++)
                {
                    Expression argument = _arguments[arg];
                    Type       type     = pttt[arg];
                    EmitArgument(cg, argument, type);
                }
            }

            // check for possible conversion/boxing needed, disabled tail call
            if (tailcall)
            {
                if (ShouldTailCallBeRemoved(cg))
                {
                    //Console.WriteLine("Removing tail call: {0} in {1}", cg.MethodBase, cg.TypeGen.AssemblyGen.AssemblyBuilder);
                    tailcall = false;
                }
            }

            EmitLocation(cg);

            // Emit the actual call
            if (fixup == null)
            {
                cg.EmitCall(_method, tailcall);
            }
            else
            {
                fixup(cg, tailcall);
            }

            if (ScriptDomainManager.Options.LightweightDebugging && !tailcall && Span.IsValid)
            {
                cg.EmitConstant(SpanToLong(Span));
                cg.EmitCall(Debugging.DebugMethods.ExpressionOut);
            }
        }
Example #11
0
 // CodeBlockExpression interrupt flow analysis
 protected internal override bool Walk(CodeBlockExpression node)
 {
     return false;
 }
Example #12
0
 // CodeBlockExpression interrupt flow analysis
 protected internal override bool Walk(CodeBlockExpression node)
 {
     return(false);
 }
Example #13
0
 // CodeBlockExpression
 private void DefaultWalk(CodeBlockExpression node)
 {
     if (node.IsDeclarative && Walk(node)) {
         WalkNode(node.Block);
     }
     PostWalk(node);
 }
                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;
                }
                static Expression InlineCall(CodeBlock parent, CodeBlockExpression cbe, params Expression[] pp)
                {
                    // all var names are unique.
                      CodeBlock cb = cbe.Block;

                      List<Statement> assigns = new List<Statement>();
                      int i = 0;

                      cb.Inlined = true;

                      var parentvars = new List<Variable>(parent.Variables);

                      foreach (Variable p in cb.Parameters)
                      {
                    SymbolId origname = p.Name;

                    p.Name = (SymbolId)Builtins.GenSym(p.Name);
                    p.Block = parent;
                    p.Kind = Variable.VariableKind.Local;
                    parent.AddVariable(p);

                    assigns.Add(Ast.Write(p, pp[i]));

                    if (p.Lift)
                    {
                      parent.HasEnvironment = true;
                    }
                    i++;
                      }

                      foreach (Variable l in cb.Variables)
                      {
                    if (l.DefaultValue == null && l.Kind != Variable.VariableKind.Global)
                    {
                      l.Name = (SymbolId)Builtins.GenSym(l.Name);
                    }
                    l.Block = parent;
                    parent.AddVariable(l);

                    if (l.Lift)
                    {
                      parent.HasEnvironment = true;
                    }
                      }

                      assigns.Add(cb.Body);

                      return Ast.Void(Ast.Block(assigns));
                }
Example #16
0
 // CodeBlockExpression
 private Expression Rewrite(CodeBlockExpression node)
 {
     // No action necessary
     return(node);
 }