presto-main/src/main/java/io/prestosql/sql/gen/VarArgsToMapAdapterGenerator.java/VarArgsToMapAdapterGenerator/generateVarArgsToMapAdapter
class VarArgsToMapAdapterGenerator:    public static MethodHandle generateVarArgsToMapAdapter(Class<?> returnType, List<Class<?>> javaTypes, List<String> names, Function<Map<String, Object>, Object> function)
    {
        checkCondition(javaTypes.size() <= 254, NOT_SUPPORTED, "Too many arguments for vararg function");
        CallSiteBinder callSiteBinder = new CallSiteBinder();

        ClassDefinition classDefinition = new ClassDefinition(a(PUBLIC, FINAL), makeClassName("VarArgsToMapAdapter"), type(Object.class));

        ImmutableList.Builder<Parameter> parameterListBuilder = ImmutableList.builder();
        for (int i = 0; i < javaTypes.size(); i++) {
            Class<?> javaType = javaTypes.get(i);
            parameterListBuilder.add(arg("input_" + i, javaType));
        }
        ImmutableList<Parameter> parameterList = parameterListBuilder.build();

        MethodDefinition methodDefinition = classDefinition.declareMethod(a(PUBLIC, STATIC), "varArgsToMap", type(returnType), parameterList);
        BytecodeBlock body = methodDefinition.getBody();

        // ImmutableMap.Builder can not be used here because it doesn't allow nulls.
        Variable map = methodDefinition.getScope().declareVariable(
                "map",
                methodDefinition.getBody(),
                invokeStatic(Maps.class, "newHashMapWithExpectedSize", HashMap.class, constantInt(javaTypes.size())));
        for (int i = 0; i < javaTypes.size(); i++) {
            body.append(map.invoke("put", Object.class, constantString(names.get(i)).cast(Object.class), parameterList.get(i).cast(Object.class)));
        }
        body.append(
                loadConstant(callSiteBinder, function, Function.class)
                        .invoke("apply", Object.class, map.cast(Object.class))
                        .cast(returnType)
                        .ret());

        Class<?> generatedClass = defineClass(classDefinition, Object.class, callSiteBinder.getBindings(), new DynamicClassLoader(VarArgsToMapAdapterGenerator.class.getClassLoader()));
        return Reflection.methodHandle(generatedClass, "varArgsToMap", javaTypes.toArray(new Class<?>[javaTypes.size()]));
    }