/// <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)); } }
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); } } }
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); } }
public void EmitLoadAddress(ILBuilder il) => _place.EmitLoadAddress(il);
/// <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; }
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); }