Пример #1
0
        public override void Emit(CodeGen cg)
        {
            // emit "this", if any
            if (_expression != null)
            {
                if (_member.DeclaringType.IsValueType)
                {
                    _expression.EmitAddress(cg, _member.DeclaringType);
                }
                else
                {
                    _expression.Emit(cg);
                }
            }

            switch (_member.MemberType)
            {
            case MemberTypes.Field:
                _value.Emit(cg);
                cg.EmitFieldSet((FieldInfo)_member);
                break;

            case MemberTypes.Property:
                _value.Emit(cg);
                cg.EmitPropertySet((PropertyInfo)_member);
                break;

            default:
                Debug.Assert(false, "Invalid member type");
                break;
            }
        }
Пример #2
0
 internal override void EmitAddress(CodeGen cg, Type asType)
 {
     if (NodeType == AstNodeType.Convert && Type == asType)
     {
         _operand.EmitAddress(cg, asType);
     }
     else
     {
         base.EmitAddress(cg, asType);
     }
 }
Пример #3
0
        internal override void EmitAddress(CodeGen cg, Type asType)
        {
            Label eoi  = cg.DefineLabel();
            Label next = cg.DefineLabel();

            _test.Emit(cg);
            cg.Emit(OpCodes.Brfalse, next);
            _true.EmitAddress(cg, asType);
            cg.Emit(OpCodes.Br, eoi);
            cg.MarkLabel(next);
            _false.EmitAddress(cg, asType);
            cg.MarkLabel(eoi);
        }
Пример #4
0
 private void EmitInstance(CodeGen cg)
 {
     if (_expression != null)
     {
         if (_member.DeclaringType.IsValueType)
         {
             _expression.EmitAddress(cg, _member.DeclaringType);
         }
         else
         {
             _expression.Emit(cg);
         }
     }
 }
Пример #5
0
        private static void EmitArgument(CodeGen cg, Expression argument, Type type)
        {
            //if (argument.Type != type && (argument.Type.IsValueType || type.IsValueType))
            if (!type.IsAssignableFrom(argument.Type) || (argument.Type != type && (argument.Type.IsValueType || type.IsValueType)))
            {
                argument = Ast.Convert(argument, type);
            }

            if (type.IsByRef)
            {
                argument.EmitAddress(cg, type.GetElementType());
            }
            else
            {
                argument.Emit(cg);
            }
        }
Пример #6
0
        internal override void EmitAddress(CodeGen cg, Type asType)
        {
            for (int index = 0; index < _expressions.Count; index++)
            {
                Expression current = _expressions[index];

                // Emit the expression
                if (index == _valueIndex)
                {
                    current.EmitAddress(cg, asType);
                }
                else
                {
                    current.Emit(cg);
                    // If we don't want the expression just emitted as the result,
                    // pop it off of the stack, unless it is a void expression.
                    if (current.Type != typeof(void))
                    {
                        cg.Emit(OpCodes.Pop);
                    }
                }
            }
        }
Пример #7
0
        private static void EmitArgument(CodeGen cg, Expression argument, Type type)
        {
            //if (argument.Type != type && (argument.Type.IsValueType || type.IsValueType))
              if (!type.IsAssignableFrom(argument.Type) || (argument.Type != type && (argument.Type.IsValueType || type.IsValueType)))
              {
            argument = Ast.Convert(argument, type);
              }

            if (type.IsByRef) {
                argument.EmitAddress(cg, type.GetElementType());
            } else {
                argument.Emit(cg);
            }
        }
Пример #8
0
        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);
            }
        }