Ejemplo n.º 1
0
        public override void Emit(CodeGen cg)
        {
            Slot tempContext = cg.ContextSlot;
            Slot newContext  = cg.GetLocalTmp(typeof(CodeContext));

            _scope.Emit(cg);            //Locals dictionary
            cg.EmitCodeContext();       //CodeContext
            //cg.EmitBoolean(true);       //Visible = true
            cg.EmitCall(typeof(RuntimeHelpers), "CreateNestedCodeContext");

            newContext.EmitSet(cg);

            cg.ContextSlot = newContext;
            _body.Emit(cg);
            cg.ContextSlot = tempContext;
        }
Ejemplo n.º 2
0
        public override void Emit(CodeGen cg)
        {
            Nullable <Label> firstTime      = null;
            Label            eol            = cg.DefineLabel();
            Label            breakTarget    = cg.DefineLabel();
            Label            continueTarget = cg.DefineLabel();

            if (_increment != null)
            {
                firstTime = cg.DefineLabel();
                cg.Emit(OpCodes.Br, firstTime.Value);
            }

            if (_header.IsValid)
            {
                //cg.EmitPosition(Start, _header);
            }
            cg.MarkLabel(continueTarget);

            if (_increment != null)
            {
                _increment.EmitAs(cg, typeof(void));
                cg.MarkLabel(firstTime.Value);
            }

            if (_test != null)
            {
                _test.Emit(cg);
                cg.Emit(OpCodes.Brfalse, eol);
            }

            cg.PushTargets(breakTarget, continueTarget, this);

            _body.Emit(cg);


            cg.Emit(OpCodes.Br, continueTarget);

            cg.PopTargets();

            cg.MarkLabel(eol);
            if (_else != null)
            {
                _else.Emit(cg);
            }
            cg.MarkLabel(breakTarget);
        }
Ejemplo n.º 3
0
        private void Emit(CodeGen cg, int count)
        {
            for (int index = 0; index < count; index++)
            {
                Expression current = _expressions[index];

                // Emit the expression
                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 (index != _valueIndex && current.Type != typeof(void))
                {
                    cg.Emit(OpCodes.Pop);
                }
            }
        }
Ejemplo n.º 4
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);
            }
        }
Ejemplo n.º 5
0
        public override void Emit(CodeGen cg)
        {
            Label eoi  = cg.DefineLabel();
            Label next = cg.DefineLabel();

            _test.Emit(cg);
            //cg.EmitSequencePointNone();
            //cg.Emit(OpCodes.Nop);
            cg.Emit(OpCodes.Brfalse, next);
            _true.Emit(cg);
            //cg.EmitSequencePointNone();
            //cg.Emit(OpCodes.Nop);
            cg.Emit(OpCodes.Br, eoi);
            cg.MarkLabel(next);
            _false.Emit(cg);
            //cg.EmitSequencePointNone();
            //cg.Emit(OpCodes.Nop);
            cg.MarkLabel(eoi);
        }
Ejemplo n.º 6
0
        public override void Emit(CodeGen cg)
        {
            Label startTarget    = cg.DefineLabel();
            Label breakTarget    = cg.DefineLabel();
            Label continueTarget = cg.DefineLabel();

            cg.MarkLabel(startTarget);
            cg.PushTargets(breakTarget, continueTarget, this);
            _body.Emit(cg);

            cg.MarkLabel(continueTarget);
            // TODO: Check if we need to emit position somewhere else also.
            //cg.EmitPosition(Start, _header);

            _test.Emit(cg);
            cg.Emit(OpCodes.Brtrue, startTarget);

            cg.PopTargets();
            cg.MarkLabel(breakTarget);
        }
Ejemplo n.º 7
0
        public override void Emit(CodeGen cg)
        {
            //_value.Emit(cg);

            // Save the expression value - order of evaluation is different than that of the Stelem* instruction
            //Slot temp = cg.GetLocalTmp(_elementType);
            //temp.EmitSet(cg);

            // Emit the array reference
            _array.Emit(cg);
            // Emit the index (as integer)
            _index.Emit(cg);
            // Emit the value
            _value.EmitAs(cg, _elementType);
            //temp.EmitGet(cg);
            // Store it in the array
            EmitLocation(cg);
            cg.EmitStoreElement(_elementType);

            //temp.EmitGet(cg); //DO NOT WANT!!!
            //cg.FreeLocalTmp(temp);
        }
Ejemplo n.º 8
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);
                    }
                }
            }
        }
Ejemplo n.º 9
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);
            }
        }
Ejemplo n.º 10
0
 public virtual void EmitSet(CodeGen cg, Expression value)
 {
     value.Emit(cg);
       EmitSet(cg);
 }
Ejemplo n.º 11
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);
            }
        }
Ejemplo n.º 12
0
 public override void Emit(CodeGen cg)
 {
     _expression.Emit(cg);
     cg.EmitConvert(_expression.Type, _conversion);
 }
Ejemplo n.º 13
0
 public override void Emit(CodeGen cg)
 {
     _expression.Emit(cg);
 }
Ejemplo n.º 14
0
        internal void Allocate(CodeGen cg)
        {
            Debug.Assert(cg.Allocator.Block == Block);

            switch (_kind)
            {
            case VariableKind.Local:
                if (_block.IsGlobal)
                {
                    // Local on global level, simply allocate the storage
                    _storage = cg.Allocator.LocalAllocator.AllocateStorage(_name, _type);
                    if (_defaultValue != null)
                    {
                        Slot slot = CreateSlotForVariable(cg);
                        _defaultValue.Emit(cg);
                        slot.EmitSet(cg);
                    }
                }
                else
                {
                    Slot slot;
                    // If lifting local into closure, allocate in the environment
                    if (_lift)
                    {
                        // allocate space in the environment and set it to Uninitialized
                        slot = AllocInEnv(cg);
                    }
                    else
                    {
                        // Allocate the storage
                        _storage = cg.Allocator.LocalAllocator.AllocateStorage(_name, _type);
                        // No access slot for local variables, pass null.
                        slot = _storage.CreateSlot(_storage.RequireAccessSlot ? cg.Allocator.GetScopeAccessSlot(_block) : null);
                        MarkLocal(slot);
                    }
                    if (_uninitialized || _defaultValue != null)
                    {
                        // Emit initialization (environments will be initialized all at once)
                        if (_defaultValue != null)
                        {
                            _defaultValue.Emit(cg);
                            slot.EmitSet(cg);
                        }
                        else if (_type == typeof(object))
                        {
                            // Only set variables of type object to "Uninitialized"
                            //throw new UnInitializedUsageException(this, "Attempted to use uninitialized variable");

                            slot.EmitSetUninitialized(cg);
                        }
                    }
                }
                break;

            case VariableKind.Parameter:
                // Lifting parameter into closure, allocate in env and move.
                if (_lift)
                {
                    Slot slot = AllocInEnv(cg);
                    Slot src  = GetArgumentSlot(cg);
                    // Copy the value from the parameter (src) into the environment (slot)
                    slot.EmitSet(cg, src);
                }
                else
                {
                    Debug.Assert(cg.Allocator.Block == Block);
                    // Nothing to do here
                }
                break;

            case VariableKind.Global:
                if (_defaultValue is UnboundExpression || cg.Allocator.Parent.Parent.Parent != null)
                {
                    _storage = cg.Allocator.GlobalAllocator.AllocateStorage(_name, _type);
                }
                else
                {
                    _storage = cg.Allocator.Parent.LocalAllocator.AllocateStorage(_name, _type);
                }
                Debug.Assert(_storage != null);
                break;

            case VariableKind.Temporary:
                // Nothing to do here
                break;

            case VariableKind.GeneratorTemporary:
                // Do the work in CreateSlot
                break;
            }
        }
Ejemplo n.º 15
0
        public override void Emit(CodeGen cg)
        {
            //if (NodeType == AstNodeType.Convert && _operand is BoundExpression)
            //{
            //  var be = _operand as BoundExpression;
            //  var tv = be.Variable.GetTypedVariable(Type);
            //  if (tv != null)
            //  {
            //    tv.
            //    return;
            //  }
            //}
            if (NodeType == AstNodeType.Convert && _operand is ConstantExpression &&
                _operand.Type == typeof(bool) && _type == typeof(object))
            {
                _operand.EmitAs(cg, typeof(object));
            }
            else
            {
                _operand.Emit(cg);

                EmitLocation(cg);

                switch (NodeType)
                {
                case AstNodeType.Convert:
                    if (_type != _operand.Type && _type.Name == "Callable" && Converter != null)
                    {
                        cg.EmitCall(Converter);
                    }
                    else
                    {
                        cg.EmitCast(_operand.Type, _type);
                    }
                    break;

                case AstNodeType.Not:
                    if (_operand.Type == typeof(bool))
                    {
                        cg.Emit(OpCodes.Ldc_I4_0);
                        cg.Emit(OpCodes.Ceq);
                    }
                    else
                    {
                        cg.Emit(OpCodes.Not);
                    }
                    break;

                case AstNodeType.Negate:
                    cg.Emit(OpCodes.Neg);
                    break;

                case AstNodeType.OnesComplement:
                    cg.Emit(OpCodes.Not);
                    break;

                default:
                    throw new NotImplementedException();
                }
            }
        }