code: public static void convertValue(CodeBuilder b, Class from, Class to) {
          if (from == to) {
              return;
          }
  
          TypeDesc fromType = TypeDesc.forClass(from);
          TypeDesc toType = TypeDesc.forClass(to);
  
          // Let CodeBuilder have a crack at the conversion first.
          try {
              b.convert(fromType, toType);
              return;
          } catch (IllegalArgumentException e) {
              if (to != String.class && to != Object.class && to != CharSequence.class) {
                  throw e;
              }
          }
  
          // Fallback case is to convert to a String.
  
          if (fromType.isPrimitive()) {
              b.invokeStatic(TypeDesc.STRING, "valueOf", TypeDesc.STRING, new TypeDesc[]{fromType});
          } else {
              // If object on stack is null, then just leave it alone.
              b.dup();
              Label isNull = b.createLabel();
              b.ifNullBranch(isNull, true);
              b.invokeStatic(TypeDesc.STRING, "valueOf", TypeDesc.STRING,
                             new TypeDesc[]{TypeDesc.OBJECT});
              isNull.setLocation();
          }
      }
docs: Converts a value on the stack. If "to" type is a String, then conversion
  may call the String.valueOf(from).