|
67 | 67 | ~@args] |
68 | 68 | (let [~'&op ~field] |
69 | 69 | ~@body))))) |
70 | | - (alter-meta! #'~fname assoc :arglists '~alists) |
| 70 | + (alter-meta! #'~fname assoc :arglists '~alists ::op true) |
71 | 71 | (def-op-method ~fname))))))) |
72 | 72 |
|
73 | 73 | ;;; |
|
236 | 236 | bootstrap method." |
237 | 237 | ([v mname desc boot] (&fn v mname desc boot [])) |
238 | 238 | ([v mname desc boot args] |
239 | | - (let [boot (if (sequential? boot) |
240 | | - (apply util/handle boot) |
241 | | - boot)] |
| 239 | + (let [boot (if (util/handle? boot) boot (apply util/handle boot))] |
242 | 240 | (.visitInvokeDynamicInsn v (util/method-name mname) (util/method-desc desc) |
243 | 241 | boot (object-array args))))) |
244 | 242 |
|
|
384 | 382 | (def-op-method pop1) |
385 | 383 | (def-op-method trycatch) |
386 | 384 |
|
| 385 | +(def op? |
| 386 | + "Returns true if the given value is a valid op vector." |
| 387 | + (comp keyword? first)) |
| 388 | + |
387 | 389 | (defn op-seq |
388 | 390 | "Return a flattened sequence of ops." |
389 | | - [xs] |
390 | | - (let [op? (comp keyword? first) |
391 | | - go (fn go [[x & xs]] |
392 | | - (lazy-seq |
393 | | - (cond |
394 | | - (op? x) |
395 | | - (cons x (go xs)) |
396 | | - (seq x) |
397 | | - (concat (go x) (go xs)) |
398 | | - (seq xs) |
399 | | - (go xs))))] |
400 | | - (go xs))) |
| 391 | + ([xs] (op-seq op? xs)) |
| 392 | + ([op? [x & xs]] |
| 393 | + (lazy-seq |
| 394 | + (cond |
| 395 | + (op? x) (cons x (op-seq xs)) |
| 396 | + (seq x) (concat (op-seq x) (op-seq xs)) |
| 397 | + (seq xs) (op-seq xs))))) |
401 | 398 |
|
402 | 399 | (defn compile |
403 | 400 | "Compile a sequence of op seqs to a fn that accepts an ASM |
|
409 | 406 | (fn [v] |
410 | 407 | (doseq [op ops] |
411 | 408 | (apply (::fn op) v (::args op)))))) |
| 409 | + |
| 410 | +(def ^:private keyword-opcode* |
| 411 | + (into {} (for [var (vals (ns-publics *ns*)) |
| 412 | + :let [m (meta var)] |
| 413 | + :when (::op m)] |
| 414 | + (let [sym (:name m) |
| 415 | + field (-> sym name .toUpperCase (.replace \- \_))] |
| 416 | + [(keyword sym) |
| 417 | + (.getInt (.getField Opcodes field) nil)])))) |
| 418 | + |
| 419 | +(defn keyword-opcode |
| 420 | + "Return the ASM opcode number as a long for the given op keyword. If |
| 421 | + the keyword is invalid an error is raised." |
| 422 | + ^long [k] |
| 423 | + (let [v (util/check-valid "op keyword" keyword-opcode* k)] |
| 424 | + (.longValue ^Integer v))) |
| 425 | + |
| 426 | +(defn emit-seq |
| 427 | + "Emit the op sequence to the given ASM MethodVisitor. See `compile`." |
| 428 | + [v ops] |
| 429 | + ((compile ops) v)) |
0 commit comments