/// <summary> /// Pops the value on the stack, converts it from one type to another, then pushes the /// result onto the stack. Undefined is converted to the given default value. /// </summary> /// <param name="generator"> The IL generator. </param> /// <param name="fromType"> The type to convert from. </param> /// <param name="targetParameter"> The type to convert to and the default value, if there is one. </param> private static void EmitTypeConversion(ILGenerator generator, Type fromType, BinderArgument argument) { // Emit either the default value if there is one, otherwise emit "undefined". if (argument.HasDefaultValue) { // Check if the input value is undefined. var elseClause = generator.CreateLabel(); generator.Duplicate(); generator.BranchIfNull(elseClause); generator.Duplicate(); generator.LoadField(ReflectionHelpers.Undefined_Value); generator.CompareEqual(); generator.BranchIfTrue(elseClause); // Convert as per normal. EmitTypeConversion(generator, fromType, argument.Type); // Jump to the end. var endOfIf = generator.CreateLabel(); generator.Branch(endOfIf); generator.DefineLabelPosition(elseClause); // Pop the existing value and emit the default value. generator.Pop(); EmitUndefined(generator, argument); // Define the end of the block. generator.DefineLabelPosition(endOfIf); } else { // Convert as per normal. EmitTypeConversion(generator, fromType, argument.Type); } }
/// <summary> /// Pushes the result of converting <c>undefined</c> to the given type onto the stack. /// </summary> /// <param name="il"> The IL generator. </param> /// <param name="targetParameter"> The type to convert to, and optionally a default value. </param> private static void EmitUndefined(ILGenerator il, BinderArgument argument) { // Emit either the default value if there is one, otherwise emit "undefined". if (argument.HasDefaultValue == true) { // Emit the default value. EmitHelpers.EmitValue(il, argument.DefaultValue); } else { // Convert Undefined to the target type and emit. EmitHelpers.EmitUndefined(il); EmitTypeConversion(il, typeof(object), argument.Type); } }