 (defmethod emit-dup clojure.lang.Seqable
   [gen ^clojure.lang.Seqable lis]
   (println "emit-dup list" lis)
-  (. gen push (count lis))
-  (. gen newArray object-type)
-  (dotimes [n (count lis)]
-    (. gen dup)
-    (AsmUtil/pushInt gen n)
-    (emit-value :context/expression gen (nth lis n))
-    (. gen arrayStore object-type))
+  (emit-array gen object-type (map #(fn [] (emit-value :context/expression gen %)) lis))
   (. gen invokeStatic (asmtype java.util.Arrays) (Method/getMethod "java.util.List asList(Object[])"))
   (. gen invokeStatic (asmtype clojure.lang.PersistentList) (Method/getMethod "clojure.lang.IPersistentList create(java.util.List)")))
 

    (. gen returnValue)
    (. gen endMethod)))

(defn compile
  "Compiles a given sanitized lambda form. If the input is not already
  sanitized, the results are undefined!

  Returns a vector of [<class name>, <closed-overs>, <bytecode>]"
  [[_ params & body :as lambda]]
  (println "Compiling:" lambda)
  (let [fv (vec (free-vars lambda))
        cw (ClassWriter. ClassWriter/COMPUTE_FRAMES)
        lname (str "lambda_" (next-id))
        fqname (str "cljstatic/scheme2/" lname)
        _ (println "fqname:" fqname)
        dotname (.replace fqname "/" ".")
        ifaces (make-array String 0)
        env {:params params, :closed-overs fv, :locals {}}]
    (. cw visit Opcodes/V1_7 Opcodes/ACC_PUBLIC fqname nil "java/lang/Object" ifaces)
    (gen-closure-fields cw fv)
    (gen-ctor cw fv)
    (gen-body cw env body)
    (gen-handle cw fqname (count params))
    [dotname fv (.toByteArray cw)]))

(defn emit
  [env context gen form]

(defn gen-closure-fields
  [^ClassVisitor cv closed-overs]
  (doseq [c closed-overs]
    (. cv visitField Opcodes/ACC_FINAL (close-name c) (.getDescriptor object-type) nil nil)))

(defn gen-ctor
  [cw fqname fv]
  (let [ctor (Method. "<init>" Type/VOID_TYPE (into-array Type (repeat (count fv) object-type)))
        gen (GeneratorAdapter. Opcodes/ACC_PUBLIC ctor nil nil cw)]
    (. gen visitCode)
