private void EmitReturnPhpReference(CodeGenerator codeGenerator) { ILEmitter il = codeGenerator.IL; PhpTypeCode result; if (expr != null) { result = expr.Emit(codeGenerator); if (result != PhpTypeCode.PhpReference) { // return value is "boxed" to PhpReference: if (result != PhpTypeCode.Void) { codeGenerator.EmitBoxing(result); // We can box the value without making a copy since the result of the return expression // is not accessible after returnign from the routine as it is a value (not a reference). il.Emit(OpCodes.Newobj, Constructors.PhpReference_Object); } else { il.Emit(OpCodes.Newobj, Constructors.PhpReference_Void); } } } else { il.Emit(OpCodes.Newobj, Constructors.PhpReference_Void); } codeGenerator.EmitReturnBranch(); }
/// <summary> /// Return value is not deeply copied since the deep copy takes place when the caller accesses the value. /// </summary> private void EmitReturnObject(CodeGenerator/*!*/ codeGenerator) { ILEmitter il = codeGenerator.IL; PhpTypeCode result; if (expr != null) { result = expr.Emit(codeGenerator); // dereference return value: if (result == PhpTypeCode.PhpReference) { il.Emit(OpCodes.Ldfld, Fields.PhpReference_Value); } else if (result == PhpTypeCode.PhpArray) { // <array>.InplaceCopyOnReturn = true; il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Call, Properties.PhpArray_InplaceCopyOnReturn.GetSetMethod()); } else { codeGenerator.EmitBoxing(result); } } else { il.Emit(OpCodes.Ldnull); } codeGenerator.EmitReturnBranch(); }