Пример #1
0
            /// <summary>Loads copied parameter value.</summary>
            public TypeSymbol EmitLoad(CodeGenerator cg)
            {
                if (_isparams)
                {
                    // converts params -> PhpArray
                    Debug.Assert(_place.TypeOpt.IsSZArray());
                    return(cg.ArrayToPhpArray(_place, deepcopy: true));
                }
                else
                {
                    // load parameter & dereference PhpValue
                    TypeSymbol t;
                    if (_place.TypeOpt == cg.CoreTypes.PhpValue)
                    {
                        // p.GetValue() : PhpValue
                        _place.EmitLoadAddress(cg.Builder);
                        t = cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpValue.GetValue);
                    }
                    else
                    {
                        // p
                        t = _place.EmitLoad(cg.Builder);
                    }

                    // make copy of given value
                    return(cg.EmitDeepCopy(t, nullcheck: !_notNull));
                }
            }
Пример #2
0
        override protected void EmitHolder(ILBuilder il)
        {
            Debug.Assert(_field.IsStatic == (_holder == null));

            if (_holder != null)
            {
                if (_holder.Type != null && _holder.Type.IsValueType)
                {
                    Debug.Assert(_holder.HasAddress);
                    _holder.EmitLoadAddress(il);
                }
                else
                {
                    _holder.EmitLoad(il);
                }
            }
        }
Пример #3
0
            public void EmitPass(CodeGenerator cg)
            {
                // inplace copies the parameter

                if (_place.TypeOpt == cg.CoreTypes.PhpValue)
                {
                    // dereference & copy
                    // (ref <param>).PassValue()
                    _place.EmitLoadAddress(cg.Builder);
                    cg.EmitCall(ILOpCode.Call, cg.CoreMethods.PhpValue.PassValue);
                }
                else if (cg.IsCopiable(_place.TypeOpt))
                {
                    _place.EmitStorePrepare(cg.Builder);

                    // copy
                    // <param> = DeepCopy(<param>)
                    cg.EmitDeepCopy(_place.EmitLoad(cg.Builder), nullcheck: !_notNull);

                    _place.EmitStore(cg.Builder);
                }
            }
Пример #4
0
 public void EmitLoadAddress(ILBuilder il) => _place.EmitLoadAddress(il);
Пример #5
0
        /// <summary>
        /// If possible, based on type analysis, unwraps most specific type from give variable without a runtime type check.
        /// </summary>
        internal TypeSymbol TryEmitVariableSpecialize(IPlace place, TypeRefMask tmask)
        {
            if (place != null && tmask.IsSingleType && !tmask.IsRef)
            {
                if (place.HasAddress)
                {
                    if (place.TypeOpt == CoreTypes.PhpNumber)
                    {
                        // access directly without type checking
                        if (IsDoubleOnly(tmask))
                        {
                            place.EmitLoadAddress(_il);
                            return EmitCall(ILOpCode.Call, CoreMethods.PhpNumber.get_Double)
                                .Expect(SpecialType.System_Double);
                        }
                        else if (IsLongOnly(tmask))
                        {
                            place.EmitLoadAddress(_il);
                            return EmitCall(ILOpCode.Call, CoreMethods.PhpNumber.get_Long)
                                .Expect(SpecialType.System_Int64);
                        }
                    }
                    else if (place.TypeOpt == CoreTypes.PhpValue)
                    {
                        // access directly without type checking
                        if (IsDoubleOnly(tmask))
                        {
                            place.EmitLoadAddress(_il);
                            return EmitCall(ILOpCode.Call, CoreMethods.PhpValue.get_Double)
                                .Expect(SpecialType.System_Double);
                        }
                        else if (IsLongOnly(tmask))
                        {
                            place.EmitLoadAddress(_il);
                            return EmitCall(ILOpCode.Call, CoreMethods.PhpValue.get_Long)
                                .Expect(SpecialType.System_Int64);
                        }
                        else if (IsBooleanOnly(tmask))
                        {
                            place.EmitLoadAddress(_il);
                            return EmitCall(ILOpCode.Call, CoreMethods.PhpValue.get_Boolean)
                                .Expect(SpecialType.System_Boolean);
                        }
                        else if (IsReadonlyStringOnly(tmask))
                        {
                            place.EmitLoadAddress(_il);
                            return EmitCall(ILOpCode.Call, CoreMethods.PhpValue.get_String)
                                .Expect(SpecialType.System_String);
                        }
                        //else if (IsArrayOnly(tmask))
                        //{
                        //    place.EmitLoadAddress(_il);
                        //    return EmitCall(ILOpCode.Call, CoreMethods.PhpValue.get_Array)    NOTE!! PhpValue.Array is PhpArray
                        //        .Expect(CoreTypes.IPhpArray);
                        //}
                        else if (IsClassOnly(tmask))
                        {
                            place.EmitLoadAddress(_il);
                            EmitCall(ILOpCode.Call, CoreMethods.PhpValue.get_Object)
                                .Expect(SpecialType.System_Object);

                            // DEBUG:
                            //if (tmask.IsSingleType)
                            //{
                            //    var tref = this.TypeRefContext.GetTypes(tmask)[0];
                            //    var clrtype = (TypeSymbol)this.DeclaringCompilation.GlobalSemantics.GetType(tref.QualifiedName);
                            //    if (clrtype != null && !clrtype.IsErrorType())
                            //    {
                            //        this.EmitCastClass(clrtype);
                            //        return clrtype;
                            //    }
                            //}

                            return this.CoreTypes.Object;
                        }
                    }
                }
            }

            return null;
        }
Пример #6
0
        internal TypeSymbol EmitGetProperty(IPlace holder, PropertySymbol prop)
        {
            Debug.Assert(prop.IsStatic || holder != null);
            Debug.Assert(prop.GetMethod != null);
            Debug.Assert(prop.GetMethod.ParameterCount == 0);

            var getter = prop.GetMethod;

            if (holder != null && !getter.IsStatic)
            {
                Debug.Assert(holder.TypeOpt != null);
                if (holder.TypeOpt.IsValueType)
                {
                    holder.EmitLoadAddress(_il);
                }
                else
                {
                    holder.EmitLoad(_il);
                }
            }

            return EmitCall(getter.IsVirtual ? ILOpCode.Callvirt : ILOpCode.Call, getter);
        }