public int Execute(Frame frame) { object result = frame.result; if (to.IsAssignableFrom(result)) { return(1); } RedwoodType type; if (result is RedwoodObject rwo) { type = rwo.Type; } else { type = RedwoodType.GetForCSharpType(result.GetType()); } // TODO: this may be repeating existing work that occurs later if (!type.HasImplicitConversion(to)) { throw new NotImplementedException(); } Lambda conversion = RuntimeUtil.GetConversionLambda(type, to); frame.result = conversion.Run(frame.result); return(1); }
internal static IEnumerable <Instruction> CompileImplicitConversion( RedwoodType from, RedwoodType to) { if (to == null) { // If we have a null destination, this shouldn't // even get called; we will be resolving it closer // to runtime throw new ArgumentException("Cannot convert to dynamic type"); } if (from == null) { return(new Instruction[] { new DynamicConvertInstruction(to) }); } else if (to.IsAssignableFrom(from)) { // In this case, we are a subtype or the correct type // so we don't need to do anything return(new Instruction[0]); } else if (from.HasImplicitConversion(to)) { if (from.CSharpType == null) { if (!from.HasImplicitConversion(to)) { throw new NotImplementedException(); } int slot = from.implicitConversionMap[to]; return(new Instruction[] { new LookupDirectMemberInstruction(slot), new InternalCallInstruction(new int[0]) }); } // This call won't work on a RedwoodType in the compile phase // because the static lambdas aren't populated yet return(new Instruction[] { new CallWithResultInstruction( RuntimeUtil.GetConversionLambda(from, to) ) }); } else { // Cannot convert between the types throw new NotImplementedException(); } }