Function: comp-emit-switch

comp-emit-switch is a byte-compiled function defined in comp.el.gz.

Signature

(comp-emit-switch VAR LAST-INSN)

Documentation

Emit a Limple for a lap jump table given VAR and LAST-INSN.

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/comp.el.gz
(defun comp-emit-switch (var last-insn)
  "Emit a Limple for a lap jump table given VAR and LAST-INSN."
  ;; FIXME this not efficient for big jump tables. We should have a second
  ;; strategy for this case.
  (pcase last-insn
    (`(setimm ,_ ,jmp-table)
     (unless (comp-jump-table-optimizable jmp-table)
       (cl-loop
        for test being each hash-keys of jmp-table
        using (hash-value target-label)
        with len = (hash-table-count jmp-table)
        with test-func = (hash-table-test jmp-table)
        for n from 1
        for last = (= n len)
        for m-test = (make-comp-mvar :constant test)
        for target-name = (comp-block-name (comp-bb-maybe-add
                                            (comp-label-to-addr target-label)
                                            (comp-sp)))
        for ff-bb = (if last
                        (comp-bb-maybe-add (1+ (comp-limplify-pc comp-pass))
                                           (comp-sp))
                      (make--comp-block-lap nil
                                            (comp-sp)
                                            (comp-new-block-sym)))
        for ff-bb-name = (comp-block-name ff-bb)
        if (eq test-func 'eq)
          do (comp-emit (list 'cond-jump var m-test target-name ff-bb-name))
        else
        ;; Store the result of the comparison into the scratch slot before
        ;; emitting the conditional jump.
          do (comp-emit (list 'set (make-comp-mvar :slot 'scratch)
                              (comp-call test-func var m-test)))
             (comp-emit (list 'cond-jump
                              (make-comp-mvar :slot 'scratch)
                              (make-comp-mvar :constant nil)
                              ff-bb-name target-name))
        unless last
        ;; All fall through are artificially created here except the last one.
          do (puthash ff-bb-name ff-bb (comp-func-blocks comp-func))
             (setf (comp-limplify-curr-block comp-pass) ff-bb))))
    (_ (signal 'native-ice
               "missing previous setimm while creating a switch"))))