internal override void EmitInit(CodeGenerator cg) { if (_symbol is SourceReturnSymbol) // TODO: remove SourceReturnSymbol { return; } if (cg.HasUnoptimizedLocals) { return; } // declare variable in global scope var il = cg.Builder; var def = il.LocalSlotManager.DeclareLocal( (Cci.ITypeReference)_symbol.Type, _symbol as ILocalSymbolInternal, this.Name, SynthesizedLocalKind.UserDefined, LocalDebugId.None, 0, LocalSlotConstraints.None, false, default(ImmutableArray <TypedConstant>), false); _place = new LocalPlace(def); il.AddLocalToScope(def); // if (_symbol is SynthesizedLocalSymbol) { return; } // Initialize local variable with void. // This is mandatory since even assignments reads the target value to assign properly to PhpAlias. // TODO: Once analysis tells us, the target cannot be alias, this step won't be necessary. // TODO: only if the local will be used uninitialized if (_place.TypeOpt == cg.CoreTypes.PhpValue) { _place.EmitStorePrepare(cg.Builder); cg.Emit_PhpValue_Void(); _place.EmitStore(cg.Builder); } else if (_place.TypeOpt == cg.CoreTypes.PhpNumber) { // <place> = PhpNumber(0) _place.EmitStorePrepare(cg.Builder); cg.Builder.EmitOpCode(ILOpCode.Ldsfld); cg.EmitSymbolToken(cg.CoreMethods.PhpNumber.Default, null); _place.EmitStore(cg.Builder); } else if (_place.TypeOpt == cg.CoreTypes.PhpAlias) { _place.EmitStorePrepare(cg.Builder); cg.Emit_PhpValue_Void(); cg.Emit_PhpValue_MakeAlias(); _place.EmitStore(cg.Builder); } }
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); } }
/// <summary> /// Initializes place with a default value. /// This applies to structs without default ctor that won't work properly when uninitialized. /// </summary> internal void EmitInitializePlace(IPlace place) { Contract.ThrowIfNull(place); var t = place.TypeOpt; Contract.ThrowIfNull(t); switch (t.SpecialType) { // we don't have to initialize those: case SpecialType.System_Boolean: case SpecialType.System_Int32: case SpecialType.System_Int64: case SpecialType.System_Double: case SpecialType.System_Object: break; default: if (t.IsValueType || t == CoreTypes.PhpAlias) // PhpValue, PhpNumber, PhpAlias { // fld = default(T) place.EmitStorePrepare(_il); EmitLoadDefault(t, 0); place.EmitStore(_il); } break; } }