Place() private method

private Place ( ILBuilder il ) : IPlace
il Microsoft.CodeAnalysis.CodeGen.ILBuilder
return IPlace
Ejemplo n.º 1
0
        internal override void EmitInit(CodeGenerator cg)
        {
            // TODO: ? if (cg.HasUnoptimizedLocals && $this) <locals>["this"] = ...

            var srcparam = _symbol as SourceParameterSymbol;

            if (srcparam != null)
            {
                var srcplace = new ParamPlace(_symbol);
                var routine  = srcparam.Routine;

                if (cg.HasUnoptimizedLocals)
                {
                    Debug.Assert(cg.LocalsPlaceOpt != null);

                    // copy parameter to <locals>[Name]

                    // <locals>[name] = value
                    cg.LocalsPlaceOpt.EmitLoad(cg.Builder);                     // <locals>
                    cg.EmitIntStringKey(new BoundLiteral(this.Name));           // [key]
                    cg.EmitConvertToPhpValue(srcplace.EmitLoad(cg.Builder), 0); // value
                    cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpArray.SetItemValue_IntStringKey_PhpValue);

                    //
                    _isUnoptimized = true;
                }
                else
                {
                    // TODO: copy parameter by value in case of PhpValue, Array, PhpString

                    // create local variable in case of parameter type is not enough for its use within routine
                    if (_symbol.Type != cg.CoreTypes.PhpValue && _symbol.Type != cg.CoreTypes.PhpAlias)
                    {
                        var tmask   = routine.ControlFlowGraph.GetParamTypeMask(srcparam);
                        var clrtype = cg.DeclaringCompilation.GetTypeFromTypeRef(routine, tmask);
                        if (clrtype != _symbol.Type)    // Assert: only if clrtype is not covered by _symbol.Type
                        {
                            // TODO: performance warning

                            _lazyLocal = new BoundLocal(new SynthesizedLocalSymbol(routine, srcparam.Name, clrtype));
                            _lazyLocal.EmitInit(cg);
                            var localplace = _lazyLocal.Place(cg.Builder);

                            // <local> = <param>
                            localplace.EmitStorePrepare(cg.Builder);
                            cg.EmitConvert(srcplace.EmitLoad(cg.Builder), 0, clrtype);
                            localplace.EmitStore(cg.Builder);
                        }
                    }
                }
            }
        }
Ejemplo n.º 2
0
        internal override IPlace Place(ILBuilder il)
        {
            if (_isUnoptimized)
            {
                return(null);
            }

            var place = (_lazyLocal != null) ? _lazyLocal.Place(il) : new ParamPlace(_symbol);

            if (this.VariableKind == VariableKind.ThisParameter)
            {
                place = new ReadOnlyPlace(place);
            }

            return(place);
        }
Ejemplo n.º 3
0
        internal override void EmitInit(CodeGenerator cg)
        {
            var srcparam = _symbol as SourceParameterSymbol;

            if (srcparam == null)
            {
                // an implicit parameter
                return;
            }

            // TODO: check callable, iterable

            // TODO: ? if (cg.HasUnoptimizedLocals && $this) <locals>["this"] = ...

            var srcplace = new ParamPlace(_symbol);
            var routine  = srcparam.Routine;

            if (cg.HasUnoptimizedLocals)
            {
                Debug.Assert(cg.LocalsPlaceOpt != null);

                // copy parameter to <locals>[Name]

                // <locals>[name] = value
                cg.LocalsPlaceOpt.EmitLoad(cg.Builder);           // <locals>
                cg.EmitIntStringKey(new BoundLiteral(this.Name)); // [key]

                if (srcparam.Syntax.PassedByRef)
                {
                    var srcpt = srcplace.EmitLoad(cg.Builder);  // PhpAlias
                    Debug.Assert(srcpt == cg.CoreTypes.PhpAlias);
                    cg.EmitConvert(srcpt, 0, cg.CoreTypes.PhpAlias);
                    cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpArray.SetItemAlias_IntStringKey_PhpAlias);
                }
                else
                {
                    if (_symbol.IsParams)
                    {
                        // (PhhpValue)new PhpArray( params )
                        cg.EmitConvertToPhpValue(cg.ArrayToPhpArray(srcplace, true), 0);
                    }
                    else
                    {
                        if (_symbol.Type == cg.CoreTypes.PhpValue)
                        {
                            // <param>.GetValue()
                            srcplace.EmitLoadAddress(cg.Builder);
                            cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpValue.GetValue);
                        }
                        else
                        {
                            // (PhpValue)<param>
                            cg.EmitConvertToPhpValue(srcplace.EmitLoad(cg.Builder), 0); // PhpValue
                        }

                        // copy <value>
                        if (cg.IsCopiable(_symbol.Type))
                        {
                            cg.EmitDeepCopy(cg.CoreTypes.PhpValue);
                        }
                    }

                    cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpArray.Add_IntStringKey_PhpValue);
                }

                //
                _isUnoptimized = true;
            }
            else
            {
                // create local variable in case of parameter type is not enough for its use within routine
                if (_symbol.Type != cg.CoreTypes.PhpValue && _symbol.Type != cg.CoreTypes.PhpAlias)
                {
                    var tmask   = routine.ControlFlowGraph.GetLocalTypeMask(srcparam.Name);
                    var clrtype = cg.DeclaringCompilation.GetTypeFromTypeRef(routine, tmask);
                    if (clrtype != _symbol.Type)    // Assert: only if clrtype is not covered by _symbol.Type
                    {
                        // TODO: performance warning

                        _lazyLocal = new BoundLocal(new SynthesizedLocalSymbol(routine, srcparam.Name, clrtype));
                        _lazyLocal.EmitInit(cg);
                        var localplace = _lazyLocal.Place(cg.Builder);

                        localplace.EmitStorePrepare(cg.Builder);

                        if (_symbol.IsParams)
                        {
                            Debug.Assert(_symbol.Type.IsSZArray());
                            Debug.Assert(clrtype == cg.CoreTypes.PhpArray);

                            // <local> = new PhpArray(){ ... }
                            cg.ArrayToPhpArray(srcplace, true);
                        }
                        else
                        {
                            // <local> = <param>
                            cg.EmitConvert(srcplace.EmitLoad(cg.Builder), 0, clrtype);
                        }
                        localplace.EmitStore(cg.Builder);
                    }
                }
                else
                {
                    if (_symbol.Type == cg.CoreTypes.PhpValue)
                    {
                        srcplace.EmitStorePrepare(cg.Builder);

                        // dereference & copy
                        // <param> = <param>.GetValue().DeepCopy()
                        srcplace.EmitLoadAddress(cg.Builder);
                        cg.EmitDeepCopy(cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpValue.GetValue));

                        srcplace.EmitStore(cg.Builder);
                    }
                    else if (cg.IsCopiable(_symbol.Type))
                    {
                        srcplace.EmitStorePrepare(cg.Builder);

                        // copy
                        // <param> = DeepCopy(<param>)
                        cg.EmitDeepCopy(srcplace.EmitLoad(cg.Builder));

                        srcplace.EmitStore(cg.Builder);
                    }
                }
            }
        }
Ejemplo n.º 4
0
        internal override void EmitInit(CodeGenerator cg)
        {
            // TODO: check callable, iterable
            
            // TODO: ? if (cg.HasUnoptimizedLocals && $this) <locals>["this"] = ...

            var srcparam = _symbol as SourceParameterSymbol;
            if (srcparam != null)
            {
                var srcplace = new ParamPlace(_symbol);
                var routine = srcparam.Routine;

                if (cg.HasUnoptimizedLocals)
                {
                    Debug.Assert(cg.LocalsPlaceOpt != null);

                    // copy parameter to <locals>[Name]

                    // <locals>[name] = value
                    cg.LocalsPlaceOpt.EmitLoad(cg.Builder); // <locals>
                    cg.EmitIntStringKey(new BoundLiteral(this.Name));   // [key]
                    cg.EmitConvertToPhpValue(srcplace.EmitLoad(cg.Builder), 0); // value
                    cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpArray.SetItemValue_IntStringKey_PhpValue);

                    //
                    _isUnoptimized = true;
                }
                else
                {
                    // TODO: copy parameter by value in case of PhpValue, Array, PhpString

                    // create local variable in case of parameter type is not enough for its use within routine
                    if (_symbol.Type != cg.CoreTypes.PhpValue && _symbol.Type != cg.CoreTypes.PhpAlias)
                    {
                        var tmask = routine.ControlFlowGraph.GetLocalTypeMask(srcparam.Name);
                        var clrtype = cg.DeclaringCompilation.GetTypeFromTypeRef(routine, tmask);
                        if (clrtype != _symbol.Type)    // Assert: only if clrtype is not covered by _symbol.Type
                        {
                            // TODO: performance warning

                            _lazyLocal = new BoundLocal(new SynthesizedLocalSymbol(routine, srcparam.Name, clrtype));
                            _lazyLocal.EmitInit(cg);
                            var localplace = _lazyLocal.Place(cg.Builder);

                            // <local> = <param>
                            localplace.EmitStorePrepare(cg.Builder);
                            cg.EmitConvert(srcplace.EmitLoad(cg.Builder), 0, clrtype);
                            localplace.EmitStore(cg.Builder);
                        }
                    }
                }
            }
        }