From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Vibhav Pant Newsgroups: gmane.emacs.devel Subject: [PATCH]: Add new bytecode op `switch' for implementing branch tables. Date: Mon, 6 Feb 2017 23:20:06 +0530 Message-ID: NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary=001a114d72ea47b6030547e0448e X-Trace: blaine.gmane.org 1486404525 31474 195.159.176.226 (6 Feb 2017 18:08:45 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 6 Feb 2017 18:08:45 +0000 (UTC) To: "emacs-devel@gnu.org" Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Feb 06 19:08:39 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1caniN-0007oJ-Be for ged-emacs-devel@m.gmane.org; Mon, 06 Feb 2017 19:08:35 +0100 Original-Received: from localhost ([::1]:50055 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1caniS-0007SQ-Pq for ged-emacs-devel@m.gmane.org; Mon, 06 Feb 2017 13:08:40 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:50309) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1canQw-0001f2-Tf for emacs-devel@gnu.org; Mon, 06 Feb 2017 12:50:39 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1canQs-00042T-1c for emacs-devel@gnu.org; Mon, 06 Feb 2017 12:50:34 -0500 Original-Received: from mail-yw0-x22f.google.com ([2607:f8b0:4002:c05::22f]:34393) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1canQr-000413-QM for emacs-devel@gnu.org; Mon, 06 Feb 2017 12:50:29 -0500 Original-Received: by mail-yw0-x22f.google.com with SMTP id w75so52839425ywg.1 for ; Mon, 06 Feb 2017 09:50:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=tZLEQD6g4SD/0z8nub81z/rJ9txhslBgosD/eZQV9Yk=; b=akrwGAUNkytAu89GXDiQJH9VeuXMzcbdYEykngMsVM19sHidgUfHF8nlrlBFwks+AD hm/LGagUFaaOLBYppExIFdUbLIlr0grpyZEO7VY8Vt5CfUwqzKV9rhXATdDWlGjmA/WD 0qy2/wCOj9m+yEmr+FV2C2tvGgdguebss8xGfKXCcD7lbAMVuQCW6Wrm2xZiQOgDpdN4 JkYz1OazaXEdSo3N+LTATe8F1vi57GP0xOGKQkG7OXq8XlZx65FyZAsb4OLXoYychYJs ZBpWq9+zYsksXAHygDhrAssxnRaz2ayf78rFKvDOYB29uzX9I3JxAaWZ2rn5QSpEi6c7 iDMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=tZLEQD6g4SD/0z8nub81z/rJ9txhslBgosD/eZQV9Yk=; b=Iq2bwCGbVp9CZkTKsU6aEc5FqhreDlwImtlzVWsbAg70NvX2vAlyU+VZFB4DPTlI4I MQBwEuSanXJdcVG6j/8nGkQMq4LwZbB1DjUM3ckPWomxkbrH9/WbUI72G4u494DZpi43 xWfwkMFhZGnQGx7EX3TYclj8HUpzfNK+pZps9TEkM4xmiETvkUPh4yx/yG2oh3b55Nhj eYyLm+Rt69vrq+Mj5Aq5wt5SwXGV7ADcQAjFAMOo0gwqYvCZJo+iL5DS1jLoYrIcW4fO Spspm7tLymi1pcGRSYPyo0+LdHWDHPTYQ+gIIRJ333DNSKNhVUrAZnsdr17larwOjV3U fuXg== X-Gm-Message-State: AIkVDXJSV3VL50b0/cMEjzksKt0sH9Y4Dv/drbyPxiGfe6gabmoq9ngAFSAQUutsKZWIXkVpCNW+B6gRJeNugg== X-Received: by 10.129.71.11 with SMTP id u11mr7611479ywa.79.1486403427334; Mon, 06 Feb 2017 09:50:27 -0800 (PST) Original-Received: by 10.129.153.77 with HTTP; Mon, 6 Feb 2017 09:50:06 -0800 (PST) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2607:f8b0:4002:c05::22f X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:212052 Archived-At: --001a114d72ea47b6030547e0448e Content-Type: text/plain; charset=UTF-8 The following patch adds support for a new op `switch` to the Emacs bytecode VM and compiler. As described in etc/TODO, switch takes 2 arguments from the stack: a value to test, and a hash table from the constant pool. It then jumps to the "address" the value in the hash-table maps to. This replaces the traditional goto/goto-if-(not)-nil bytecode for cond forms, with a smaller and more performant bytecode. Currently, certain cond forms like: (cond ((eq v 1) 'foo) ((eq v 'bar) 'baz) (t 'blah)) are compiled using byte- switch. The structure of switch bytecode for the cond form above is as follows: varref v constant #s(hash-table data (1 TAG1 bar TAG2)) switch goto DEFAULT-TAG TAG1: constant 1 goto DONETAG TAG2: constant 'baz goto DONETAG DEFAULT-TAG: constant 'blah ;; 'blah is 'nil' when there is no 't' clause. DONETAG: ... (This should also work with `pcase' forms, as it expands to a `cond') The hash table used as the jump table for switch maps possible values to a cons pair of two numbers. The jump address for the value is found by calculating car(pair) + (cdr(pair) << 8), an inexpensive operation. The hash table is also declared with :purecopy t, as it is always constant and can thus be copied to pure storage. However, since switch replaces all goto-if-nil code, I've used a few workarounds to avoid breaking compiler invariants: * byte-compile-cond-jump-table: After emitting an unconditional jump to DONETAG, (cdr (cdr DONETAG)) is set to nil, and the value of byte-compile-depth is restored (unconditional jumps set it to nil). This is to avoid depth conflicts down the road, and is documented in `byte-compile-cond-jump-table'. * byte-compile-inline-lapcode also replicates this behavior if any lapcode containing byte-switch is being inlined. Aside from this, the peephole optimizer in byte-opt.el has been modified so as to not screw up switch bytecode (and has been documented as well). disass.el has also been changed to the show contents of the jump table with the correct tags. Lastly, I've added a defcustom `byte-compile-cond-use-jump-table', which when nil will use the original goto-if-(not)-nil bytecode while compiling cond. This is a workaround for when `byte-compile-cond-jump-table' accidentally generates wrong code (hasn't happened so far in my tests), and should be removed once we're sure there are no issues with it. The code for this feature is in the branch 'feature/byte-switch', feedback would be appreciated. -- Vibhav Pant vibhavp@gmail.com diff --git a/lisp/emacs-lisp/byte-opt.el b/lisp/emacs-lisp/byte-opt.el index 13f885448a..888a5f8500 100644 --- a/lisp/emacs-lisp/byte-opt.el +++ b/lisp/emacs-lisp/byte-opt.el @@ -185,6 +185,7 @@ (require 'bytecomp) (eval-when-compile (require 'cl-lib)) (require 'macroexp) +(require 'subr-x) (defun byte-compile-log-lap-1 (format &rest args) ;; Newer byte codes for stack-ref make the slot 0 non-nil again. @@ -1356,7 +1357,7 @@ byte-decompile-bytecode (defun byte-decompile-bytecode-1 (bytes constvec &optional make-spliceable) (let ((length (length bytes)) (bytedecomp-ptr 0) optr tags bytedecomp-op offset - lap tmp) + lap tmp last-constant) (while (not (= bytedecomp-ptr length)) (or make-spliceable (push bytedecomp-ptr lap)) @@ -1385,7 +1386,8 @@ byte-decompile-bytecode-1 (or (assq tmp byte-compile-variables) (let ((new (list tmp))) (push new byte-compile-variables) - new))))) + new))) + last-constant tmp)) ((eq bytedecomp-op 'byte-stack-set2) (setq bytedecomp-op 'byte-stack-set)) ((and (eq bytedecomp-op 'byte-discardN) (>= offset #x80)) @@ -1394,7 +1396,34 @@ byte-decompile-bytecode-1 ;; lapcode, we represent this by using a different opcode ;; (with the flag removed from the operand). (setq bytedecomp-op 'byte-discardN-preserve-tos) - (setq offset (- offset #x80)))) + (setq offset (- offset #x80))) + ((eq bytedecomp-op 'byte-switch) + (cl-assert (hash-table-p last-constant) nil + "byte-switch used without preceeding hash table") + ;; We cannot use the original hash table referenced in the op, + ;; so we create a copy of it, and replace the addresses with + ;; TAGs. + (let ((orig-table last-constant)) + (cl-loop for e across constvec + when (eq e last-constant) + do (setq last-constant (copy-hash-table e)) + and return nil) + ;; Replace all addresses with TAGs. + (maphash #'(lambda (value tag) + (let (newtag) + (cl-assert (consp tag) + nil "Invalid address for byte-switch") + (setq newtag (byte-compile-make-tag)) + (push (cons (+ (car tag) (lsh (cdr tag) 8)) newtag) tags) + (puthash value newtag last-constant))) + last-constant) + ;; Replace the hash table referenced in the lapcode with our + ;; modified one. + (cl-loop for el in-ref lap + when (and (listp el) ;; make sure we're at the correct op + (eq (nth 1 el) 'byte-constant) + (eq (nth 2 el) orig-table)) + do (setf (nth 2 el) last-constant) and return nil)))) ;; lap = ( [ (pc . (op . arg)) ]* ) (push (cons optr (cons bytedecomp-op (or offset 0))) lap) @@ -1728,7 +1757,10 @@ byte-optimize-lapcode ;; unused-TAG: --> ;; ((and (eq 'TAG (car lap0)) - (not (rassq lap0 lap))) + (not (rassq lap0 lap)) + (cl-loop for table in byte-compile-jump-tables + when (member lap0 (hash-table-values table)) + return nil finally return t)) (and (memq byte-optimize-log '(t byte)) (byte-compile-log " unused tag %d removed" (nth 1 lap0))) (setq lap (delq lap0 lap) @@ -1736,9 +1768,15 @@ byte-optimize-lapcode ;; ;; goto ... --> goto ;; return ... --> return - ;; + ;; (unless a jump-table is being used, where deleting may affect + ;; other valid case bodies) + ;; ((and (memq (car lap0) '(byte-goto byte-return)) - (not (memq (car lap1) '(TAG nil)))) + (not (memq (car lap1) '(TAG nil))) + ;; FIXME: Instead of deferring simply when jump-tables are + ;; being used, keep a list of tags used for switch tags and + ;; use them instead (see `byte-compile-inline-lapcode'). + (not byte-compile-jump-tables)) (setq tmp rest) (let ((i 0) (opt-p (memq byte-optimize-log '(t lap))) diff --git a/lisp/emacs-lisp/bytecomp.el b/lisp/emacs-lisp/bytecomp.el index 63be7e208b..d5a163e5fd 100644 --- a/lisp/emacs-lisp/bytecomp.el +++ b/lisp/emacs-lisp/bytecomp.el @@ -223,6 +223,11 @@ byte-compile-delete-errors :group 'bytecomp :type 'boolean) +(defcustom byte-compile-cond-use-jump-table t + "Compile `cond' clauses to a jump table implementation (using a hash-table)." + :group 'bytecomp + :type 'boolean) + (defvar byte-compile-dynamic nil "If non-nil, compile function bodies so they load lazily. They are hidden in comments in the compiled file, @@ -412,6 +417,8 @@ byte-compile-call-tree-sort (const calls+callers) (const nil))) (defvar byte-compile-debug nil) +(defvar byte-compile-jump-tables nil + "List of all jump tables used during compilation of this form.") (defvar byte-compile-constants nil "List of all constants encountered during compilation of this form.") (defvar byte-compile-variables nil @@ -747,6 +754,10 @@ byte-extrude-byte-code-vectors ;; `byte-compile-lapcode'). (defconst byte-discardN-preserve-tos byte-discardN) +(byte-defop 183 -2 byte-switch + "to take a hash table and a value from the stack, and jump to the address +the value maps to, if any.") + ;; unused: 182-191 (byte-defop 192 1 byte-constant "for reference to a constant") @@ -823,7 +834,7 @@ byte-compile-lapcode op off ; Operation & offset opcode ; numeric value of OP (bytes '()) ; Put the output bytes here - (patchlist nil)) ; List of gotos to patch + (patchlist nil)) ; List of gotos to patch (dolist (lap-entry lap) (setq op (car lap-entry) off (cdr lap-entry)) @@ -905,6 +916,11 @@ byte-compile-lapcode ;; FIXME: Replace this by some workaround. (if (> (car bytes-tail) 255) (error "Bytecode overflow"))) + (dolist (hash-table byte-compile-jump-tables) + (cl-loop for k being the hash-keys of hash-table do + (let ((tag (cdr (gethash k hash-table)))) + (setq pc (car tag)) + (puthash k (cons (logand pc 255) (lsh pc -8)) hash-table)))) (apply 'unibyte-string (nreverse bytes)))) @@ -1954,7 +1970,8 @@ byte-compile-from-buffer ;; (edebug-all-defs nil) ;; (edebug-all-forms nil) ;; Simulate entry to byte-compile-top-level - (byte-compile-constants nil) + (byte-compile-jump-tables nil) + (byte-compile-constants nil) (byte-compile-variables nil) (byte-compile-tag-number 0) (byte-compile-depth 0) @@ -2250,7 +2267,8 @@ byte-compile-flush-pending byte-compile-variables nil byte-compile-depth 0 byte-compile-maxdepth 0 - byte-compile-output nil)))) + byte-compile-output nil + byte-compile-jump-tables nil)))) (defvar byte-compile-force-lexical-warnings nil) @@ -2862,7 +2880,8 @@ byte-compile-top-level (byte-compile-maxdepth 0) (byte-compile--lexical-environment lexenv) (byte-compile-reserved-constants (or reserved-csts 0)) - (byte-compile-output nil)) + (byte-compile-output nil) + (byte-compile-jump-tables nil)) (if (memq byte-optimize '(t source)) (setq form (byte-optimize-form form byte-compile--for-effect))) (while (and (eq (car-safe form) 'progn) (null (cdr (cdr form)))) @@ -3114,15 +3133,49 @@ byte-compile-inline-lapcode ;; happens to be true for byte-code generated by bytecomp.el without ;; lexical-binding, but it's not true in general, and it's not true for ;; code output by bytecomp.el with lexical-binding. - (let ((endtag (byte-compile-make-tag))) + ;; We also restore the value of `byte-compile-depth' and remove TAG depths + ;; accordingly when inlining byte-switch lap code, as documented in + ;; `byte-compile-cond-jump-table'. + (let ((endtag (byte-compile-make-tag)) + last-jump-tag ;; last TAG we have jumped to + last-depth ;; last value of `byte-compile-depth' + last-constant ;; value of the last constant encountered + last-switch ;; whether the last op encountered was byte-switch + switch-tags ;; a list of tags that byte-switch could jump to + ;; a list of tags byte-switch will jump to, if the value doesn't + ;; match any entry in the hash table + switch-default-tags) (dolist (op lap) (cond - ((eq (car op) 'TAG) (byte-compile-out-tag op)) - ((memq (car op) byte-goto-ops) (byte-compile-goto (car op) (cdr op))) + ((eq (car op) 'TAG) + (when (or (member op switch-tags) (member op switch-default-tags)) + (when last-jump-tag + (setcdr (cdr last-jump-tag) nil)) + (setq byte-compile-depth last-depth + last-jump-tag nil)) + (byte-compile-out-tag op)) + ((memq (car op) byte-goto-ops) + (setq last-depth byte-compile-depth + last-jump-tag (cdr op)) + (byte-compile-goto (car op) (cdr op)) + (when last-switch + (push (cdr op) switch-default-tags) + (setcdr (cdr (cdr op)) nil) + (setq byte-compile-depth last-depth + last-switch nil))) ((eq (car op) 'byte-return) (byte-compile-discard (- byte-compile-depth end-depth) t) (byte-compile-goto 'byte-goto endtag)) - (t (byte-compile-out (car op) (cdr op))))) + (t + (when (eq (car op) 'byte-switch) + (push last-constant byte-compile-jump-tables) + (setq last-switch t) + (maphash #'(lambda (_k tag) + (push tag switch-tags)) + last-constant)) + (setq last-constant (and (eq (car op) 'byte-constant) (cadr op))) + (setq last-depth byte-compile-depth) + (byte-compile-out (car op) (cdr op))))) (byte-compile-out-tag endtag))) (defun byte-compile-unfold-bcf (form) @@ -3951,37 +4004,162 @@ byte-compile-if (byte-compile-out-tag donetag)))) (setq byte-compile--for-effect nil)) +(defun byte-compile-cond-vars (obj1 obj2) + ;; We make sure that of OBJ1 and OBJ2, one of them is a symbol, + ;; and the other is a constant expression whose value can be + ;; compared with `eq' (with `macroexp-const-p'). + (or + (and (symbolp obj1) (macroexp-const-p obj2) (cons obj1 obj2)) + (and (symbolp obj2) (macroexp-const-p obj1) (cons obj2 obj1)))) + +(defun byte-compile-cond-jump-table-info (clauses) + "If CLAUSES is a `cond' form where: +The condition for each clause is of the form (TEST VAR VALUE). +VAR is a variable. +TEST and VAR are the same throughout all conditions. +VALUE is either a constant or a quoted form. + +Return a list of the form ((TEST . VAR) ((VALUE BODY) ...))" + (let ((cases '()) + (ok t) + prev-var prev-test) + (and (catch 'break + (dolist (clause (cdr clauses) ok) + (let* ((condition (car clause)) + (test (car-safe condition)) + (vars (when (consp condition) + (byte-compile-cond-vars (cadr condition) (cl-caddr condition)))) + (obj1 (car-safe vars)) + (obj2 (cdr-safe vars)) + (body (cdr-safe clause))) + (unless prev-var + (setq prev-var obj1)) + (unless prev-test + (setq prev-test test)) + (if (and obj1 (memq test '(eq eql equal)) + (consp condition) + (eq test prev-test) + (eq obj1 prev-var) + ;; discard duplicate clauses + (not (assq obj2 cases))) + (push (list (if (consp obj2) (eval obj2) obj2) body) cases) + (if (eq condition t) + (progn (push (list 'default body) cases) + (throw 'break t)) + (setq ok nil) + (throw 'break nil)))))) + (list (cons prev-test prev-var) (nreverse cases))))) + +(defun byte-compile-cond-jump-table (clauses) + (let* ((table-info (byte-compile-cond-jump-table-info clauses)) + (test (caar table-info)) + (var (cdar table-info)) + (cases (cadr table-info)) + jump-table test-obj body tag donetag default-tag default-case) + (when (and cases (not (= (length cases) 1))) + ;; TODO: Once :linear-search is implemented for `make-hash-table' + ;; set it to `t' for cond forms with a small number of cases. + (setq jump-table (make-hash-table :test test + :purecopy t + :size (if (assq 'default cases) + (1- (length cases)) + (length cases))) + default-tag (byte-compile-make-tag) + donetag (byte-compile-make-tag)) + ;; The structure of byte-switch code: + ;; + ;; varref var + ;; constant #s(hash-table purecopy t data (val1 (TAG1) val2 (TAG2))) + ;; switch + ;; goto DEFAUT-TAG + ;; TAG1 + ;; + ;; goto DONETAG + ;; TAG2 + ;; + ;; goto DONETAG + ;; DEFAULT-TAG + ;; + ;; DONETAG + + (byte-compile-variable-ref var) + (byte-compile-push-constant jump-table) + (byte-compile-out 'byte-switch) + + ;; When the opcode argument is `byte-goto', `byte-compile-goto' sets + ;; `byte-compile-depth' to `nil'. However, we need `byte-compile-depth' + ;; to be non-nil for generating tags for all cases. Since + ;; `byte-compile-depth' will increase by atmost 1 after compiling + ;; all of the clause (which is further enforced by cl-assert below) + ;; it should be safe to preserve it's value. + (let ((byte-compile-depth byte-compile-depth)) + (byte-compile-goto 'byte-goto default-tag)) + + (when (assq 'default cases) + (setq default-case (cadr (assq 'default cases)) + cases (butlast cases 1))) + + (dolist (case cases) + (setq tag (byte-compile-make-tag) + test-obj (nth 0 case) + body (nth 1 case)) + (byte-compile-out-tag tag) + (puthash test-obj tag jump-table) + + (let ((byte-compile-depth byte-compile-depth) + (init-depth byte-compile-depth)) + ;; Since `byte-compile-body' might increase `byte-compile-depth' + ;; by 1, not preserving it's value will cause it to potentially + ;; increase by one for every clause body compiled, causing + ;; depth/tag conflicts or violating asserts down the road. + ;; To make sure `byte-compile-body' itself doesn't violate this, + ;; we use `cl-assert'. + (byte-compile-body body byte-compile--for-effect) + (cl-assert (or (= byte-compile-depth init-depth) + (= byte-compile-depth (1+ init-depth)))) + (byte-compile-goto 'byte-goto donetag) + (setcdr (cdr donetag) nil))) + + (byte-compile-out-tag default-tag) + (if default-case + (byte-compile-body-do-effect default-case) + (byte-compile-constant nil)) + (byte-compile-out-tag donetag) + (push jump-table byte-compile-jump-tables)))) + (defun byte-compile-cond (clauses) - (let ((donetag (byte-compile-make-tag)) - nexttag clause) - (while (setq clauses (cdr clauses)) - (setq clause (car clauses)) - (cond ((or (eq (car clause) t) - (and (eq (car-safe (car clause)) 'quote) - (car-safe (cdr-safe (car clause))))) - ;; Unconditional clause - (setq clause (cons t clause) - clauses nil)) - ((cdr clauses) - (byte-compile-form (car clause)) - (if (null (cdr clause)) - ;; First clause is a singleton. - (byte-compile-goto-if t byte-compile--for-effect donetag) - (setq nexttag (byte-compile-make-tag)) - (byte-compile-goto 'byte-goto-if-nil nexttag) - (byte-compile-maybe-guarded (car clause) - (byte-compile-body (cdr clause) byte-compile--for-effect)) - (byte-compile-goto 'byte-goto donetag) - (byte-compile-out-tag nexttag))))) - ;; Last clause - (let ((guard (car clause))) - (and (cdr clause) (not (eq guard t)) - (progn (byte-compile-form guard) - (byte-compile-goto-if nil byte-compile--for-effect donetag) - (setq clause (cdr clause)))) - (byte-compile-maybe-guarded guard - (byte-compile-body-do-effect clause))) - (byte-compile-out-tag donetag))) + (or (and byte-compile-cond-use-jump-table + (byte-compile-cond-jump-table clauses)) + (let ((donetag (byte-compile-make-tag)) + nexttag clause) + (while (setq clauses (cdr clauses)) + (setq clause (car clauses)) + (cond ((or (eq (car clause) t) + (and (eq (car-safe (car clause)) 'quote) + (car-safe (cdr-safe (car clause))))) + ;; Unconditional clause + (setq clause (cons t clause) + clauses nil)) + ((cdr clauses) + (byte-compile-form (car clause)) + (if (null (cdr clause)) + ;; First clause is a singleton. + (byte-compile-goto-if t byte-compile--for-effect donetag) + (setq nexttag (byte-compile-make-tag)) + (byte-compile-goto 'byte-goto-if-nil nexttag) + (byte-compile-maybe-guarded (car clause) + (byte-compile-body (cdr clause) byte-compile--for-effect)) + (byte-compile-goto 'byte-goto donetag) + (byte-compile-out-tag nexttag))))) + ;; Last clause + (let ((guard (car clause))) + (and (cdr clause) (not (eq guard t)) + (progn (byte-compile-form guard) + (byte-compile-goto-if nil byte-compile--for-effect donetag) + (setq clause (cdr clause)))) + (byte-compile-maybe-guarded guard + (byte-compile-body-do-effect clause))) + (byte-compile-out-tag donetag)))) (defun byte-compile-and (form) (let ((failtag (byte-compile-make-tag)) @@ -4528,7 +4706,7 @@ byte-compile-out-tag (and byte-compile-depth (not (= (cdr (cdr tag)) byte-compile-depth)) (error "Compiler bug: depth conflict at tag %d" (car (cdr tag)))) - (setq byte-compile-depth (cdr (cdr tag)))) + (setq byte-compile-depth (cdr (cdr tag)))) (setcdr (cdr tag) byte-compile-depth))) (defun byte-compile-goto (opcode tag) diff --git a/lisp/emacs-lisp/disass.el b/lisp/emacs-lisp/disass.el index 97e45e070d..66673b4d26 100644 --- a/lisp/emacs-lisp/disass.el +++ b/lisp/emacs-lisp/disass.el @@ -221,9 +221,21 @@ disassemble-1 ((memq op '(byte-constant byte-constant2)) ;; it's a constant (setq arg (car arg)) - ;; but if the value of the constant is compiled code, then - ;; recursively disassemble it. - (cond ((or (byte-code-function-p arg) + ;; if the succeeding op is byte-switch, display the jump table + ;; used + (cond ((eq (car-safe (car-safe (cdr lap))) 'byte-switch) + (insert (format "")) + ;; if the value of the constant is compiled code, then + ;; recursively disassemble it. + ((or (byte-code-function-p arg) (and (consp arg) (functionp arg) (assq 'byte-code arg)) (and (eq (car-safe arg) 'macro) diff --git a/src/bytecode.c b/src/bytecode.c index 0f7420c19e..f9531761b3 100644 --- a/src/bytecode.c +++ b/src/bytecode.c @@ -267,6 +267,8 @@ DEFINE (Bstack_set, 0262) \ DEFINE (Bstack_set2, 0263) \ DEFINE (BdiscardN, 0266) \ \ +DEFINE (Bswitch, 0267) \ + \ DEFINE (Bconstant, 0300) enum byte_code_op @@ -1411,6 +1413,25 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth, DISCARD (op); NEXT; + CASE (Bswitch): + { + Lisp_Object jmp_table = POP; + Lisp_Object v1 = POP; +#ifdef BYTE_CODE_SAFE + CHECK_TYPE (HASH_TABLE_P (jmp_table), Qhash_table_p, jmp_table); +#endif + struct Lisp_Hash_Table *h = XHASH_TABLE(jmp_table); + ptrdiff_t i = hash_lookup(h, v1, NULL); + if (i >= 0) { + Lisp_Object dest = HASH_VALUE(h, i); + int car = XINT(XCAR(dest)); + int cdr = XINT(XCDR(dest)); + op = car + (cdr << 8); /* Simulate FETCH2 */ + goto op_branch; + } + } + NEXT; + CASE_DEFAULT CASE (Bconstant): if (BYTE_CODE_SAFE --001a114d72ea47b6030547e0448e Content-Type: text/plain; charset=US-ASCII; name="switch.diff" Content-Disposition: attachment; filename="switch.diff" Content-Transfer-Encoding: base64 X-Attachment-Id: f_iyue3trv0 ZGlmZiAtLWdpdCBhL2xpc3AvZW1hY3MtbGlzcC9ieXRlLW9wdC5lbCBiL2xpc3AvZW1hY3MtbGlz cC9ieXRlLW9wdC5lbAppbmRleCAxM2Y4ODU0NDhhLi44ODhhNWY4NTAwIDEwMDY0NAotLS0gYS9s aXNwL2VtYWNzLWxpc3AvYnl0ZS1vcHQuZWwKKysrIGIvbGlzcC9lbWFjcy1saXNwL2J5dGUtb3B0 LmVsCkBAIC0xODUsNiArMTg1LDcgQEAKIChyZXF1aXJlICdieXRlY29tcCkKIChldmFsLXdoZW4t Y29tcGlsZSAocmVxdWlyZSAnY2wtbGliKSkKIChyZXF1aXJlICdtYWNyb2V4cCkKKyhyZXF1aXJl ICdzdWJyLXgpCiAKIChkZWZ1biBieXRlLWNvbXBpbGUtbG9nLWxhcC0xIChmb3JtYXQgJnJlc3Qg YXJncykKICAgOzsgTmV3ZXIgYnl0ZSBjb2RlcyBmb3Igc3RhY2stcmVmIG1ha2UgdGhlIHNsb3Qg MCBub24tbmlsIGFnYWluLgpAQCAtMTM1Niw3ICsxMzU3LDcgQEAgYnl0ZS1kZWNvbXBpbGUtYnl0 ZWNvZGUKIChkZWZ1biBieXRlLWRlY29tcGlsZS1ieXRlY29kZS0xIChieXRlcyBjb25zdHZlYyAm b3B0aW9uYWwgbWFrZS1zcGxpY2VhYmxlKQogICAobGV0ICgobGVuZ3RoIChsZW5ndGggYnl0ZXMp KQogICAgICAgICAoYnl0ZWRlY29tcC1wdHIgMCkgb3B0ciB0YWdzIGJ5dGVkZWNvbXAtb3Agb2Zm c2V0Ci0JbGFwIHRtcCkKKwlsYXAgdG1wIGxhc3QtY29uc3RhbnQpCiAgICAgKHdoaWxlIChub3Qg KD0gYnl0ZWRlY29tcC1wdHIgbGVuZ3RoKSkKICAgICAgIChvciBtYWtlLXNwbGljZWFibGUKIAkg IChwdXNoIGJ5dGVkZWNvbXAtcHRyIGxhcCkpCkBAIC0xMzg1LDcgKzEzODYsOCBAQCBieXRlLWRl Y29tcGlsZS1ieXRlY29kZS0xCiAJCQkgICAgKG9yIChhc3NxIHRtcCBieXRlLWNvbXBpbGUtdmFy aWFibGVzKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobGV0ICgobmV3IChsaXN0 IHRtcCkpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChwdXNoIG5ldyBieXRl LWNvbXBpbGUtdmFyaWFibGVzKQotICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5l dykpKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3KSkpCisgICAgICAg ICAgICAgICAgICAgbGFzdC1jb25zdGFudCB0bXApKQogCSAgICAoKGVxIGJ5dGVkZWNvbXAtb3Ag J2J5dGUtc3RhY2stc2V0MikKIAkgICAgIChzZXRxIGJ5dGVkZWNvbXAtb3AgJ2J5dGUtc3RhY2st c2V0KSkKIAkgICAgKChhbmQgKGVxIGJ5dGVkZWNvbXAtb3AgJ2J5dGUtZGlzY2FyZE4pICg+PSBv ZmZzZXQgI3g4MCkpCkBAIC0xMzk0LDcgKzEzOTYsMzQgQEAgYnl0ZS1kZWNvbXBpbGUtYnl0ZWNv ZGUtMQogCSAgICAgOzsgbGFwY29kZSwgd2UgcmVwcmVzZW50IHRoaXMgYnkgdXNpbmcgYSBkaWZm ZXJlbnQgb3Bjb2RlCiAJICAgICA7OyAod2l0aCB0aGUgZmxhZyByZW1vdmVkIGZyb20gdGhlIG9w ZXJhbmQpLgogCSAgICAgKHNldHEgYnl0ZWRlY29tcC1vcCAnYnl0ZS1kaXNjYXJkTi1wcmVzZXJ2 ZS10b3MpCi0JICAgICAoc2V0cSBvZmZzZXQgKC0gb2Zmc2V0ICN4ODApKSkpCisJICAgICAoc2V0 cSBvZmZzZXQgKC0gb2Zmc2V0ICN4ODApKSkKKyAgICAgICAgICAgICgoZXEgYnl0ZWRlY29tcC1v cCAnYnl0ZS1zd2l0Y2gpCisgICAgICAgICAgICAgKGNsLWFzc2VydCAoaGFzaC10YWJsZS1wIGxh c3QtY29uc3RhbnQpIG5pbAorICAgICAgICAgICAgICAgICAgICAgICAgImJ5dGUtc3dpdGNoIHVz ZWQgd2l0aG91dCBwcmVjZWVkaW5nIGhhc2ggdGFibGUiKQorICAgICAgICAgICAgIDs7IFdlIGNh bm5vdCB1c2UgdGhlIG9yaWdpbmFsIGhhc2ggdGFibGUgcmVmZXJlbmNlZCBpbiB0aGUgb3AsCisg ICAgICAgICAgICAgOzsgc28gd2UgY3JlYXRlIGEgY29weSBvZiBpdCwgYW5kIHJlcGxhY2UgdGhl IGFkZHJlc3NlcyB3aXRoCisgICAgICAgICAgICAgOzsgVEFHcy4KKyAgICAgICAgICAgICAobGV0 ICgob3JpZy10YWJsZSBsYXN0LWNvbnN0YW50KSkKKyAgICAgICAgICAgICAgIChjbC1sb29wIGZv ciBlIGFjcm9zcyBjb25zdHZlYworICAgICAgICAgICAgICAgICAgICAgICAgd2hlbiAoZXEgZSBs YXN0LWNvbnN0YW50KQorICAgICAgICAgICAgICAgICAgICAgICAgZG8gKHNldHEgbGFzdC1jb25z dGFudCAoY29weS1oYXNoLXRhYmxlIGUpKQorICAgICAgICAgICAgICAgICAgICAgICAgYW5kIHJl dHVybiBuaWwpCisgICAgICAgICAgICAgICA7OyBSZXBsYWNlIGFsbCBhZGRyZXNzZXMgd2l0aCBU QUdzLgorICAgICAgICAgICAgICAgKG1hcGhhc2ggIycobGFtYmRhICh2YWx1ZSB0YWcpCisgICAg ICAgICAgICAgICAgICAgICAgICAgICAgKGxldCAobmV3dGFnKQorICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgKGNsLWFzc2VydCAoY29uc3AgdGFnKQorICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICBuaWwgIkludmFsaWQgYWRkcmVzcyBmb3IgYnl0ZS1zd2l0Y2gi KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHNldHEgbmV3dGFnIChieXRlLWNvbXBp bGUtbWFrZS10YWcpKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHB1c2ggKGNvbnMg KCsgKGNhciB0YWcpIChsc2ggKGNkciB0YWcpIDgpKSBuZXd0YWcpIHRhZ3MpCisgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAocHV0aGFzaCB2YWx1ZSBuZXd0YWcgbGFzdC1jb25zdGFudCkp KQorICAgICAgICAgICAgICAgICAgICAgICAgbGFzdC1jb25zdGFudCkKKyAgICAgICAgICAgICAg IDs7IFJlcGxhY2UgdGhlIGhhc2ggdGFibGUgcmVmZXJlbmNlZCBpbiB0aGUgbGFwY29kZSB3aXRo IG91cgorICAgICAgICAgICAgICAgOzsgbW9kaWZpZWQgb25lLgorICAgICAgICAgICAgICAgKGNs LWxvb3AgZm9yIGVsIGluLXJlZiBsYXAKKyAgICAgICAgICAgICAgICAgICAgICAgIHdoZW4gKGFu ZCAobGlzdHAgZWwpIDs7IG1ha2Ugc3VyZSB3ZSdyZSBhdCB0aGUgY29ycmVjdCBvcAorICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcSAobnRoIDEgZWwpICdieXRlLWNvbnN0YW50 KQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChlcSAobnRoIDIgZWwpIG9yaWct dGFibGUpKQorICAgICAgICAgICAgICAgICAgICAgICAgZG8gKHNldGYgKG50aCAyIGVsKSBsYXN0 LWNvbnN0YW50KSBhbmQgcmV0dXJuIG5pbCkpKSkKICAgICAgIDs7IGxhcCA9ICggWyAocGMgLiAo b3AgLiBhcmcpKSBdKiApCiAgICAgICAocHVzaCAoY29ucyBvcHRyIChjb25zIGJ5dGVkZWNvbXAt b3AgKG9yIG9mZnNldCAwKSkpCiAgICAgICAgICAgICBsYXApCkBAIC0xNzI4LDcgKzE3NTcsMTAg QEAgYnl0ZS1vcHRpbWl6ZS1sYXBjb2RlCiAJICAgICAgOzsgdW51c2VkLVRBRzogLS0+IDxkZWxl dGVkPgogCSAgICAgIDs7CiAJICAgICAgKChhbmQgKGVxICdUQUcgKGNhciBsYXAwKSkKLQkJICAg IChub3QgKHJhc3NxIGxhcDAgbGFwKSkpCisJCSAgICAobm90IChyYXNzcSBsYXAwIGxhcCkpCisg ICAgICAgICAgICAgICAgICAgIChjbC1sb29wIGZvciB0YWJsZSBpbiBieXRlLWNvbXBpbGUtanVt cC10YWJsZXMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2hlbiAobWVtYmVyIGxhcDAg KGhhc2gtdGFibGUtdmFsdWVzIHRhYmxlKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg cmV0dXJuIG5pbCBmaW5hbGx5IHJldHVybiB0KSkKIAkgICAgICAgKGFuZCAobWVtcSBieXRlLW9w dGltaXplLWxvZyAnKHQgYnl0ZSkpCiAJCSAgICAoYnl0ZS1jb21waWxlLWxvZyAiICB1bnVzZWQg dGFnICVkIHJlbW92ZWQiIChudGggMSBsYXAwKSkpCiAJICAgICAgIChzZXRxIGxhcCAoZGVscSBs YXAwIGxhcCkKQEAgLTE3MzYsOSArMTc2OCwxNSBAQCBieXRlLW9wdGltaXplLWxhcGNvZGUKIAkg ICAgICA7OwogCSAgICAgIDs7IGdvdG8gICAuLi4gLS0+IGdvdG8gICA8ZGVsZXRlIHVudGlsIFRB RyBvciBlbmQ+CiAJICAgICAgOzsgcmV0dXJuIC4uLiAtLT4gcmV0dXJuIDxkZWxldGUgdW50aWwg VEFHIG9yIGVuZD4KLQkgICAgICA7OworCSAgICAgIDs7ICh1bmxlc3MgYSBqdW1wLXRhYmxlIGlz IGJlaW5nIHVzZWQsIHdoZXJlIGRlbGV0aW5nIG1heSBhZmZlY3QKKyAgICAgICAgICAgICAgOzsg b3RoZXIgdmFsaWQgY2FzZSBib2RpZXMpCisgICAgICAgICAgICAgIDs7CiAJICAgICAgKChhbmQg KG1lbXEgKGNhciBsYXAwKSAnKGJ5dGUtZ290byBieXRlLXJldHVybikpCi0JCSAgICAobm90ICht ZW1xIChjYXIgbGFwMSkgJyhUQUcgbmlsKSkpKQorCQkgICAgKG5vdCAobWVtcSAoY2FyIGxhcDEp ICcoVEFHIG5pbCkpKQorICAgICAgICAgICAgICAgICAgICA7OyBGSVhNRTogSW5zdGVhZCBvZiBk ZWZlcnJpbmcgc2ltcGx5IHdoZW4ganVtcC10YWJsZXMgYXJlCisgICAgICAgICAgICAgICAgICAg IDs7IGJlaW5nIHVzZWQsIGtlZXAgYSBsaXN0IG9mIHRhZ3MgdXNlZCBmb3Igc3dpdGNoIHRhZ3Mg YW5kCisgICAgICAgICAgICAgICAgICAgIDs7IHVzZSB0aGVtIGluc3RlYWQgKHNlZSBgYnl0ZS1j b21waWxlLWlubGluZS1sYXBjb2RlJykuCisgICAgICAgICAgICAgICAgICAgIChub3QgYnl0ZS1j b21waWxlLWp1bXAtdGFibGVzKSkKIAkgICAgICAgKHNldHEgdG1wIHJlc3QpCiAJICAgICAgIChs ZXQgKChpIDApCiAJCSAgICAgKG9wdC1wIChtZW1xIGJ5dGUtb3B0aW1pemUtbG9nICcodCBsYXAp KSkKZGlmZiAtLWdpdCBhL2xpc3AvZW1hY3MtbGlzcC9ieXRlY29tcC5lbCBiL2xpc3AvZW1hY3Mt bGlzcC9ieXRlY29tcC5lbAppbmRleCA2M2JlN2UyMDhiLi5kNWExNjNlNWZkIDEwMDY0NAotLS0g YS9saXNwL2VtYWNzLWxpc3AvYnl0ZWNvbXAuZWwKKysrIGIvbGlzcC9lbWFjcy1saXNwL2J5dGVj b21wLmVsCkBAIC0yMjMsNiArMjIzLDExIEBAIGJ5dGUtY29tcGlsZS1kZWxldGUtZXJyb3JzCiAg IDpncm91cCAnYnl0ZWNvbXAKICAgOnR5cGUgJ2Jvb2xlYW4pCiAKKyhkZWZjdXN0b20gYnl0ZS1j b21waWxlLWNvbmQtdXNlLWp1bXAtdGFibGUgdAorICAiQ29tcGlsZSBgY29uZCcgY2xhdXNlcyB0 byBhIGp1bXAgdGFibGUgaW1wbGVtZW50YXRpb24gKHVzaW5nIGEgaGFzaC10YWJsZSkuIgorICA6 Z3JvdXAgJ2J5dGVjb21wCisgIDp0eXBlICdib29sZWFuKQorCiAoZGVmdmFyIGJ5dGUtY29tcGls ZS1keW5hbWljIG5pbAogICAiSWYgbm9uLW5pbCwgY29tcGlsZSBmdW5jdGlvbiBib2RpZXMgc28g dGhleSBsb2FkIGxhemlseS4KIFRoZXkgYXJlIGhpZGRlbiBpbiBjb21tZW50cyBpbiB0aGUgY29t cGlsZWQgZmlsZSwKQEAgLTQxMiw2ICs0MTcsOCBAQCBieXRlLWNvbXBpbGUtY2FsbC10cmVlLXNv cnQKIAkJIChjb25zdCBjYWxscytjYWxsZXJzKSAoY29uc3QgbmlsKSkpCiAKIChkZWZ2YXIgYnl0 ZS1jb21waWxlLWRlYnVnIG5pbCkKKyhkZWZ2YXIgYnl0ZS1jb21waWxlLWp1bXAtdGFibGVzIG5p bAorICAiTGlzdCBvZiBhbGwganVtcCB0YWJsZXMgdXNlZCBkdXJpbmcgY29tcGlsYXRpb24gb2Yg dGhpcyBmb3JtLiIpCiAoZGVmdmFyIGJ5dGUtY29tcGlsZS1jb25zdGFudHMgbmlsCiAgICJMaXN0 IG9mIGFsbCBjb25zdGFudHMgZW5jb3VudGVyZWQgZHVyaW5nIGNvbXBpbGF0aW9uIG9mIHRoaXMg Zm9ybS4iKQogKGRlZnZhciBieXRlLWNvbXBpbGUtdmFyaWFibGVzIG5pbApAQCAtNzQ3LDYgKzc1 NCwxMCBAQCBieXRlLWV4dHJ1ZGUtYnl0ZS1jb2RlLXZlY3RvcnMKIDs7IGBieXRlLWNvbXBpbGUt bGFwY29kZScpLgogKGRlZmNvbnN0IGJ5dGUtZGlzY2FyZE4tcHJlc2VydmUtdG9zIGJ5dGUtZGlz Y2FyZE4pCiAKKyhieXRlLWRlZm9wIDE4MyAtMiBieXRlLXN3aXRjaAorICJ0byB0YWtlIGEgaGFz aCB0YWJsZSBhbmQgYSB2YWx1ZSBmcm9tIHRoZSBzdGFjaywgYW5kIGp1bXAgdG8gdGhlIGFkZHJl c3MKK3RoZSB2YWx1ZSBtYXBzIHRvLCBpZiBhbnkuIikKKwogOzsgdW51c2VkOiAxODItMTkxCiAK IChieXRlLWRlZm9wIDE5MiAgMSBieXRlLWNvbnN0YW50CSJmb3IgcmVmZXJlbmNlIHRvIGEgY29u c3RhbnQiKQpAQCAtODIzLDcgKzgzNCw3IEBAIGJ5dGUtY29tcGlsZS1sYXBjb2RlCiAJb3Agb2Zm CQkJOyBPcGVyYXRpb24gJiBvZmZzZXQKIAlvcGNvZGUJCQk7IG51bWVyaWMgdmFsdWUgb2YgT1AK IAkoYnl0ZXMgJygpKQkJOyBQdXQgdGhlIG91dHB1dCBieXRlcyBoZXJlCi0JKHBhdGNobGlzdCBu aWwpKQk7IExpc3Qgb2YgZ290b3MgdG8gcGF0Y2gKKwkocGF0Y2hsaXN0IG5pbCkpICAgICAgICA7 IExpc3Qgb2YgZ290b3MgdG8gcGF0Y2gKICAgICAoZG9saXN0IChsYXAtZW50cnkgbGFwKQogICAg ICAgKHNldHEgb3AgKGNhciBsYXAtZW50cnkpCiAJICAgIG9mZiAoY2RyIGxhcC1lbnRyeSkpCkBA IC05MDUsNiArOTE2LDExIEBAIGJ5dGUtY29tcGlsZS1sYXBjb2RlCiAgICAgICA7OyBGSVhNRTog UmVwbGFjZSB0aGlzIGJ5IHNvbWUgd29ya2Fyb3VuZC4KICAgICAgIChpZiAoPiAoY2FyIGJ5dGVz LXRhaWwpIDI1NSkgKGVycm9yICJCeXRlY29kZSBvdmVyZmxvdyIpKSkKIAorICAgIChkb2xpc3Qg KGhhc2gtdGFibGUgYnl0ZS1jb21waWxlLWp1bXAtdGFibGVzKQorICAgICAgKGNsLWxvb3AgZm9y IGsgYmVpbmcgdGhlIGhhc2gta2V5cyBvZiBoYXNoLXRhYmxlIGRvCisgICAgICAgICAgICAgICAo bGV0ICgodGFnIChjZHIgKGdldGhhc2ggayBoYXNoLXRhYmxlKSkpKQorICAgICAgICAgICAgICAg ICAoc2V0cSBwYyAoY2FyIHRhZykpCisgICAgICAgICAgICAgICAgIChwdXRoYXNoIGsgKGNvbnMg KGxvZ2FuZCBwYyAyNTUpIChsc2ggcGMgLTgpKSBoYXNoLXRhYmxlKSkpKQogICAgIChhcHBseSAn dW5pYnl0ZS1zdHJpbmcgKG5yZXZlcnNlIGJ5dGVzKSkpKQogCiAMCkBAIC0xOTU0LDcgKzE5NzAs OCBAQCBieXRlLWNvbXBpbGUtZnJvbS1idWZmZXIKIDs7IAkoZWRlYnVnLWFsbC1kZWZzIG5pbCkK IDs7IAkoZWRlYnVnLWFsbC1mb3JtcyBuaWwpCiAJOzsgU2ltdWxhdGUgZW50cnkgdG8gYnl0ZS1j b21waWxlLXRvcC1sZXZlbAotCShieXRlLWNvbXBpbGUtY29uc3RhbnRzIG5pbCkKKyAgICAgICAg KGJ5dGUtY29tcGlsZS1qdW1wLXRhYmxlcyBuaWwpCisgICAgICAgIChieXRlLWNvbXBpbGUtY29u c3RhbnRzIG5pbCkKIAkoYnl0ZS1jb21waWxlLXZhcmlhYmxlcyBuaWwpCiAJKGJ5dGUtY29tcGls ZS10YWctbnVtYmVyIDApCiAJKGJ5dGUtY29tcGlsZS1kZXB0aCAwKQpAQCAtMjI1MCw3ICsyMjY3 LDggQEAgYnl0ZS1jb21waWxlLWZsdXNoLXBlbmRpbmcKIAkgICAgICBieXRlLWNvbXBpbGUtdmFy aWFibGVzIG5pbAogCSAgICAgIGJ5dGUtY29tcGlsZS1kZXB0aCAwCiAJICAgICAgYnl0ZS1jb21w aWxlLW1heGRlcHRoIDAKLQkgICAgICBieXRlLWNvbXBpbGUtb3V0cHV0IG5pbCkpKSkKKwkgICAg ICBieXRlLWNvbXBpbGUtb3V0cHV0IG5pbAorICAgICAgICAgICAgICBieXRlLWNvbXBpbGUtanVt cC10YWJsZXMgbmlsKSkpKQogCiAoZGVmdmFyIGJ5dGUtY29tcGlsZS1mb3JjZS1sZXhpY2FsLXdh cm5pbmdzIG5pbCkKIApAQCAtMjg2Miw3ICsyODgwLDggQEAgYnl0ZS1jb21waWxlLXRvcC1sZXZl bAogCShieXRlLWNvbXBpbGUtbWF4ZGVwdGggMCkKICAgICAgICAgKGJ5dGUtY29tcGlsZS0tbGV4 aWNhbC1lbnZpcm9ubWVudCBsZXhlbnYpCiAgICAgICAgIChieXRlLWNvbXBpbGUtcmVzZXJ2ZWQt Y29uc3RhbnRzIChvciByZXNlcnZlZC1jc3RzIDApKQotCShieXRlLWNvbXBpbGUtb3V0cHV0IG5p bCkpCisJKGJ5dGUtY29tcGlsZS1vdXRwdXQgbmlsKQorICAgICAgICAoYnl0ZS1jb21waWxlLWp1 bXAtdGFibGVzIG5pbCkpCiAgICAgKGlmIChtZW1xIGJ5dGUtb3B0aW1pemUgJyh0IHNvdXJjZSkp CiAJKHNldHEgZm9ybSAoYnl0ZS1vcHRpbWl6ZS1mb3JtIGZvcm0gYnl0ZS1jb21waWxlLS1mb3It ZWZmZWN0KSkpCiAgICAgKHdoaWxlIChhbmQgKGVxIChjYXItc2FmZSBmb3JtKSAncHJvZ24pIChu dWxsIChjZHIgKGNkciBmb3JtKSkpKQpAQCAtMzExNCwxNSArMzEzMyw0OSBAQCBieXRlLWNvbXBp bGUtaW5saW5lLWxhcGNvZGUKICAgOzsgaGFwcGVucyB0byBiZSB0cnVlIGZvciBieXRlLWNvZGUg Z2VuZXJhdGVkIGJ5IGJ5dGVjb21wLmVsIHdpdGhvdXQKICAgOzsgbGV4aWNhbC1iaW5kaW5nLCBi dXQgaXQncyBub3QgdHJ1ZSBpbiBnZW5lcmFsLCBhbmQgaXQncyBub3QgdHJ1ZSBmb3IKICAgOzsg Y29kZSBvdXRwdXQgYnkgYnl0ZWNvbXAuZWwgd2l0aCBsZXhpY2FsLWJpbmRpbmcuCi0gIChsZXQg KChlbmR0YWcgKGJ5dGUtY29tcGlsZS1tYWtlLXRhZykpKQorICA7OyBXZSBhbHNvIHJlc3RvcmUg dGhlIHZhbHVlIG9mIGBieXRlLWNvbXBpbGUtZGVwdGgnIGFuZCByZW1vdmUgVEFHIGRlcHRocwor ICA7OyBhY2NvcmRpbmdseSB3aGVuIGlubGluaW5nIGJ5dGUtc3dpdGNoIGxhcCBjb2RlLCBhcyBk b2N1bWVudGVkIGluCisgIDs7IGBieXRlLWNvbXBpbGUtY29uZC1qdW1wLXRhYmxlJy4KKyAgKGxl dCAoKGVuZHRhZyAoYnl0ZS1jb21waWxlLW1ha2UtdGFnKSkKKyAgICAgICAgbGFzdC1qdW1wLXRh ZyA7OyBsYXN0IFRBRyB3ZSBoYXZlIGp1bXBlZCB0bworICAgICAgICBsYXN0LWRlcHRoIDs7IGxh c3QgdmFsdWUgb2YgYGJ5dGUtY29tcGlsZS1kZXB0aCcKKyAgICAgICAgbGFzdC1jb25zdGFudCA7 OyB2YWx1ZSBvZiB0aGUgbGFzdCBjb25zdGFudCBlbmNvdW50ZXJlZAorICAgICAgICBsYXN0LXN3 aXRjaCA7OyB3aGV0aGVyIHRoZSBsYXN0IG9wIGVuY291bnRlcmVkIHdhcyBieXRlLXN3aXRjaAor ICAgICAgICBzd2l0Y2gtdGFncyA7OyBhIGxpc3Qgb2YgdGFncyB0aGF0IGJ5dGUtc3dpdGNoIGNv dWxkIGp1bXAgdG8KKyAgICAgICAgOzsgYSBsaXN0IG9mIHRhZ3MgYnl0ZS1zd2l0Y2ggd2lsbCBq dW1wIHRvLCBpZiB0aGUgdmFsdWUgZG9lc24ndAorICAgICAgICA7OyBtYXRjaCBhbnkgZW50cnkg aW4gdGhlIGhhc2ggdGFibGUKKyAgICAgICAgc3dpdGNoLWRlZmF1bHQtdGFncykKICAgICAoZG9s aXN0IChvcCBsYXApCiAgICAgICAoY29uZAotICAgICAgICgoZXEgKGNhciBvcCkgJ1RBRykgKGJ5 dGUtY29tcGlsZS1vdXQtdGFnIG9wKSkKLSAgICAgICAoKG1lbXEgKGNhciBvcCkgYnl0ZS1nb3Rv LW9wcykgKGJ5dGUtY29tcGlsZS1nb3RvIChjYXIgb3ApIChjZHIgb3ApKSkKKyAgICAgICAoKGVx IChjYXIgb3ApICdUQUcpCisgICAgICAgICh3aGVuIChvciAobWVtYmVyIG9wIHN3aXRjaC10YWdz KSAobWVtYmVyIG9wIHN3aXRjaC1kZWZhdWx0LXRhZ3MpKQorICAgICAgICAgICh3aGVuIGxhc3Qt anVtcC10YWcKKyAgICAgICAgICAgIChzZXRjZHIgKGNkciBsYXN0LWp1bXAtdGFnKSBuaWwpKQor ICAgICAgICAgIChzZXRxIGJ5dGUtY29tcGlsZS1kZXB0aCBsYXN0LWRlcHRoCisgICAgICAgICAg ICAgICAgbGFzdC1qdW1wLXRhZyBuaWwpKQorICAgICAgICAoYnl0ZS1jb21waWxlLW91dC10YWcg b3ApKQorICAgICAgICgobWVtcSAoY2FyIG9wKSBieXRlLWdvdG8tb3BzKQorICAgICAgICAoc2V0 cSBsYXN0LWRlcHRoIGJ5dGUtY29tcGlsZS1kZXB0aAorICAgICAgICAgICAgICBsYXN0LWp1bXAt dGFnIChjZHIgb3ApKQorICAgICAgICAoYnl0ZS1jb21waWxlLWdvdG8gKGNhciBvcCkgKGNkciBv cCkpCisgICAgICAgICh3aGVuIGxhc3Qtc3dpdGNoCisgICAgICAgICAgKHB1c2ggKGNkciBvcCkg c3dpdGNoLWRlZmF1bHQtdGFncykKKyAgICAgICAgICAoc2V0Y2RyIChjZHIgKGNkciBvcCkpIG5p bCkKKyAgICAgICAgICAoc2V0cSBieXRlLWNvbXBpbGUtZGVwdGggbGFzdC1kZXB0aAorICAgICAg ICAgICAgICAgIGxhc3Qtc3dpdGNoIG5pbCkpKQogICAgICAgICgoZXEgKGNhciBvcCkgJ2J5dGUt cmV0dXJuKQogICAgICAgICAoYnl0ZS1jb21waWxlLWRpc2NhcmQgKC0gYnl0ZS1jb21waWxlLWRl cHRoIGVuZC1kZXB0aCkgdCkKICAgICAgICAgKGJ5dGUtY29tcGlsZS1nb3RvICdieXRlLWdvdG8g ZW5kdGFnKSkKLSAgICAgICAodCAoYnl0ZS1jb21waWxlLW91dCAoY2FyIG9wKSAoY2RyIG9wKSkp KSkKKyAgICAgICAodAorICAgICAgICAod2hlbiAoZXEgKGNhciBvcCkgJ2J5dGUtc3dpdGNoKQor ICAgICAgICAgIChwdXNoIGxhc3QtY29uc3RhbnQgYnl0ZS1jb21waWxlLWp1bXAtdGFibGVzKQor ICAgICAgICAgIChzZXRxIGxhc3Qtc3dpdGNoIHQpCisgICAgICAgICAgKG1hcGhhc2ggIycobGFt YmRhIChfayB0YWcpCisgICAgICAgICAgICAgICAgICAgICAgIChwdXNoIHRhZyBzd2l0Y2gtdGFn cykpCisgICAgICAgICAgICAgICAgICAgbGFzdC1jb25zdGFudCkpCisgICAgICAgIChzZXRxIGxh c3QtY29uc3RhbnQgKGFuZCAoZXEgKGNhciBvcCkgJ2J5dGUtY29uc3RhbnQpIChjYWRyIG9wKSkp CisgICAgICAgIChzZXRxIGxhc3QtZGVwdGggYnl0ZS1jb21waWxlLWRlcHRoKQorICAgICAgICAo Ynl0ZS1jb21waWxlLW91dCAoY2FyIG9wKSAoY2RyIG9wKSkpKSkKICAgICAoYnl0ZS1jb21waWxl LW91dC10YWcgZW5kdGFnKSkpCiAKIChkZWZ1biBieXRlLWNvbXBpbGUtdW5mb2xkLWJjZiAoZm9y bSkKQEAgLTM5NTEsMzcgKzQwMDQsMTYyIEBAIGJ5dGUtY29tcGlsZS1pZgogCShieXRlLWNvbXBp bGUtb3V0LXRhZyBkb25ldGFnKSkpKQogICAoc2V0cSBieXRlLWNvbXBpbGUtLWZvci1lZmZlY3Qg bmlsKSkKIAorKGRlZnVuIGJ5dGUtY29tcGlsZS1jb25kLXZhcnMgKG9iajEgb2JqMikKKyAgOzsg V2UgbWFrZSBzdXJlIHRoYXQgb2YgT0JKMSBhbmQgT0JKMiwgb25lIG9mIHRoZW0gaXMgYSBzeW1i b2wsCisgIDs7IGFuZCB0aGUgb3RoZXIgaXMgYSBjb25zdGFudCBleHByZXNzaW9uIHdob3NlIHZh bHVlIGNhbiBiZQorICA7OyBjb21wYXJlZCB3aXRoIGBlcScgKHdpdGggYG1hY3JvZXhwLWNvbnN0 LXAnKS4KKyAgKG9yCisgICAoYW5kIChzeW1ib2xwIG9iajEpIChtYWNyb2V4cC1jb25zdC1wIG9i ajIpIChjb25zIG9iajEgb2JqMikpCisgICAoYW5kIChzeW1ib2xwIG9iajIpIChtYWNyb2V4cC1j b25zdC1wIG9iajEpIChjb25zIG9iajIgb2JqMSkpKSkKKworKGRlZnVuIGJ5dGUtY29tcGlsZS1j b25kLWp1bXAtdGFibGUtaW5mbyAoY2xhdXNlcykKKyAgIklmIENMQVVTRVMgaXMgYSBgY29uZCcg Zm9ybSB3aGVyZToKK1RoZSBjb25kaXRpb24gZm9yIGVhY2ggY2xhdXNlIGlzIG9mIHRoZSBmb3Jt IChURVNUIFZBUiBWQUxVRSkuCitWQVIgaXMgYSB2YXJpYWJsZS4KK1RFU1QgYW5kIFZBUiBhcmUg dGhlIHNhbWUgdGhyb3VnaG91dCBhbGwgY29uZGl0aW9ucy4KK1ZBTFVFIGlzIGVpdGhlciBhIGNv bnN0YW50IG9yIGEgcXVvdGVkIGZvcm0uCisKK1JldHVybiBhIGxpc3Qgb2YgdGhlIGZvcm0gKChU RVNUIC4gVkFSKSAgKChWQUxVRSBCT0RZKSAuLi4pKSIKKyAgKGxldCAoKGNhc2VzICcoKSkKKyAg ICAgICAgKG9rIHQpCisgICAgICAgIHByZXYtdmFyIHByZXYtdGVzdCkKKyAgICAoYW5kIChjYXRj aCAnYnJlYWsKKyAgICAgICAgICAgKGRvbGlzdCAoY2xhdXNlIChjZHIgY2xhdXNlcykgb2spCisg ICAgICAgICAgICAgKGxldCogKChjb25kaXRpb24gKGNhciBjbGF1c2UpKQorICAgICAgICAgICAg ICAgICAgICAodGVzdCAoY2FyLXNhZmUgY29uZGl0aW9uKSkKKyAgICAgICAgICAgICAgICAgICAg KHZhcnMgKHdoZW4gKGNvbnNwIGNvbmRpdGlvbikKKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICAoYnl0ZS1jb21waWxlLWNvbmQtdmFycyAoY2FkciBjb25kaXRpb24pIChjbC1jYWRkciBjb25k aXRpb24pKSkpCisgICAgICAgICAgICAgICAgICAgIChvYmoxIChjYXItc2FmZSB2YXJzKSkKKyAg ICAgICAgICAgICAgICAgICAgKG9iajIgKGNkci1zYWZlIHZhcnMpKQorICAgICAgICAgICAgICAg ICAgICAoYm9keSAoY2RyLXNhZmUgY2xhdXNlKSkpCisgICAgICAgICAgICAgICAodW5sZXNzIHBy ZXYtdmFyCisgICAgICAgICAgICAgICAgIChzZXRxIHByZXYtdmFyIG9iajEpKQorICAgICAgICAg ICAgICAgKHVubGVzcyBwcmV2LXRlc3QKKyAgICAgICAgICAgICAgICAgKHNldHEgcHJldi10ZXN0 IHRlc3QpKQorICAgICAgICAgICAgICAgKGlmIChhbmQgb2JqMSAobWVtcSB0ZXN0ICcoZXEgZXFs IGVxdWFsKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIChjb25zcCBjb25kaXRpb24pCisgICAg ICAgICAgICAgICAgICAgICAgICAoZXEgdGVzdCBwcmV2LXRlc3QpCisgICAgICAgICAgICAgICAg ICAgICAgICAoZXEgb2JqMSBwcmV2LXZhcikKKyAgICAgICAgICAgICAgICAgICAgICAgIDs7IGRp c2NhcmQgZHVwbGljYXRlIGNsYXVzZXMKKyAgICAgICAgICAgICAgICAgICAgICAgIChub3QgKGFz c3Egb2JqMiBjYXNlcykpKQorICAgICAgICAgICAgICAgICAgIChwdXNoIChsaXN0IChpZiAoY29u c3Agb2JqMikgKGV2YWwgb2JqMikgb2JqMikgYm9keSkgY2FzZXMpCisgICAgICAgICAgICAgICAg IChpZiAoZXEgY29uZGl0aW9uIHQpCisgICAgICAgICAgICAgICAgICAgICAocHJvZ24gKHB1c2gg KGxpc3QgJ2RlZmF1bHQgYm9keSkgY2FzZXMpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAg KHRocm93ICdicmVhayB0KSkKKyAgICAgICAgICAgICAgICAgICAoc2V0cSBvayBuaWwpCisgICAg ICAgICAgICAgICAgICAgKHRocm93ICdicmVhayBuaWwpKSkpKSkKKyAgICAgICAgIChsaXN0IChj b25zIHByZXYtdGVzdCBwcmV2LXZhcikgKG5yZXZlcnNlIGNhc2VzKSkpKSkKKworKGRlZnVuIGJ5 dGUtY29tcGlsZS1jb25kLWp1bXAtdGFibGUgKGNsYXVzZXMpCisgIChsZXQqICgodGFibGUtaW5m byAoYnl0ZS1jb21waWxlLWNvbmQtanVtcC10YWJsZS1pbmZvIGNsYXVzZXMpKQorICAgICAgICAg KHRlc3QgKGNhYXIgdGFibGUtaW5mbykpCisgICAgICAgICAodmFyIChjZGFyIHRhYmxlLWluZm8p KQorICAgICAgICAgKGNhc2VzIChjYWRyIHRhYmxlLWluZm8pKQorICAgICAgICAganVtcC10YWJs ZSB0ZXN0LW9iaiBib2R5IHRhZyBkb25ldGFnIGRlZmF1bHQtdGFnIGRlZmF1bHQtY2FzZSkKKyAg ICAod2hlbiAoYW5kIGNhc2VzIChub3QgKD0gKGxlbmd0aCBjYXNlcykgMSkpKQorICAgICAgOzsg VE9ETzogT25jZSA6bGluZWFyLXNlYXJjaCBpcyBpbXBsZW1lbnRlZCBmb3IgYG1ha2UtaGFzaC10 YWJsZScKKyAgICAgIDs7IHNldCBpdCB0byBgdCcgZm9yIGNvbmQgZm9ybXMgd2l0aCBhIHNtYWxs IG51bWJlciBvZiBjYXNlcy4KKyAgICAgIChzZXRxIGp1bXAtdGFibGUgKG1ha2UtaGFzaC10YWJs ZSA6dGVzdCB0ZXN0CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOnB1 cmVjb3B5IHQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6c2l6ZSAo aWYgKGFzc3EgJ2RlZmF1bHQgY2FzZXMpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICgxLSAobGVuZ3RoIGNhc2VzKSkKKyAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsZW5ndGggY2FzZXMpKSkKKyAgICAgICAg ICAgIGRlZmF1bHQtdGFnIChieXRlLWNvbXBpbGUtbWFrZS10YWcpCisgICAgICAgICAgICBkb25l dGFnIChieXRlLWNvbXBpbGUtbWFrZS10YWcpKQorICAgICAgOzsgVGhlIHN0cnVjdHVyZSBvZiBi eXRlLXN3aXRjaCBjb2RlOgorICAgICAgOzsKKyAgICAgIDs7IHZhcnJlZiB2YXIKKyAgICAgIDs7 IGNvbnN0YW50ICNzKGhhc2gtdGFibGUgcHVyZWNvcHkgdCBkYXRhICh2YWwxIChUQUcxKSB2YWwy IChUQUcyKSkpCisgICAgICA7OyBzd2l0Y2gKKyAgICAgIDs7IGdvdG8gREVGQVVULVRBRworICAg ICAgOzsgVEFHMQorICAgICAgOzsgPGNsYXVzZSBib2R5PgorICAgICAgOzsgZ290byBET05FVEFH CisgICAgICA7OyBUQUcyCisgICAgICA7OyA8Y2xhdXNlIGJvZHk+CisgICAgICA7OyBnb3RvIERP TkVUQUcKKyAgICAgIDs7IERFRkFVTFQtVEFHCisgICAgICA7OyA8Ym9keSBmb3IgYHQnIGNsYXVz ZSwgaWYgYW55IChlbHNlIGBjb25zdGFudCBuaWwnKT4KKyAgICAgIDs7IERPTkVUQUcKKworICAg ICAgKGJ5dGUtY29tcGlsZS12YXJpYWJsZS1yZWYgdmFyKQorICAgICAgKGJ5dGUtY29tcGlsZS1w dXNoLWNvbnN0YW50IGp1bXAtdGFibGUpCisgICAgICAoYnl0ZS1jb21waWxlLW91dCAnYnl0ZS1z d2l0Y2gpCisKKyAgICAgIDs7IFdoZW4gdGhlIG9wY29kZSBhcmd1bWVudCBpcyBgYnl0ZS1nb3Rv JywgYGJ5dGUtY29tcGlsZS1nb3RvJyBzZXRzCisgICAgICA7OyBgYnl0ZS1jb21waWxlLWRlcHRo JyB0byBgbmlsJy4gSG93ZXZlciwgd2UgbmVlZCBgYnl0ZS1jb21waWxlLWRlcHRoJworICAgICAg OzsgdG8gYmUgbm9uLW5pbCBmb3IgZ2VuZXJhdGluZyB0YWdzIGZvciBhbGwgY2FzZXMuIFNpbmNl CisgICAgICA7OyBgYnl0ZS1jb21waWxlLWRlcHRoJyB3aWxsIGluY3JlYXNlIGJ5IGF0bW9zdCAx IGFmdGVyIGNvbXBpbGluZworICAgICAgOzsgYWxsIG9mIHRoZSBjbGF1c2UgKHdoaWNoIGlzIGZ1 cnRoZXIgZW5mb3JjZWQgYnkgY2wtYXNzZXJ0IGJlbG93KQorICAgICAgOzsgaXQgc2hvdWxkIGJl IHNhZmUgdG8gcHJlc2VydmUgaXQncyB2YWx1ZS4KKyAgICAgIChsZXQgKChieXRlLWNvbXBpbGUt ZGVwdGggYnl0ZS1jb21waWxlLWRlcHRoKSkKKyAgICAgICAgKGJ5dGUtY29tcGlsZS1nb3RvICdi eXRlLWdvdG8gZGVmYXVsdC10YWcpKQorCisgICAgICAod2hlbiAoYXNzcSAnZGVmYXVsdCBjYXNl cykKKyAgICAgICAgKHNldHEgZGVmYXVsdC1jYXNlIChjYWRyIChhc3NxICdkZWZhdWx0IGNhc2Vz KSkKKyAgICAgICAgICAgICAgY2FzZXMgKGJ1dGxhc3QgY2FzZXMgMSkpKQorCisgICAgICAoZG9s aXN0IChjYXNlIGNhc2VzKQorICAgICAgICAoc2V0cSB0YWcgKGJ5dGUtY29tcGlsZS1tYWtlLXRh ZykKKyAgICAgICAgICAgICAgdGVzdC1vYmogKG50aCAwIGNhc2UpCisgICAgICAgICAgICAgIGJv ZHkgKG50aCAxIGNhc2UpKQorICAgICAgICAoYnl0ZS1jb21waWxlLW91dC10YWcgdGFnKQorICAg ICAgICAocHV0aGFzaCB0ZXN0LW9iaiB0YWcganVtcC10YWJsZSkKKworICAgICAgICAobGV0ICgo Ynl0ZS1jb21waWxlLWRlcHRoIGJ5dGUtY29tcGlsZS1kZXB0aCkKKyAgICAgICAgICAgICAgKGlu aXQtZGVwdGggYnl0ZS1jb21waWxlLWRlcHRoKSkKKyAgICAgICAgICA7OyBTaW5jZSBgYnl0ZS1j b21waWxlLWJvZHknIG1pZ2h0IGluY3JlYXNlIGBieXRlLWNvbXBpbGUtZGVwdGgnCisgICAgICAg ICAgOzsgYnkgMSwgbm90IHByZXNlcnZpbmcgaXQncyB2YWx1ZSB3aWxsIGNhdXNlIGl0IHRvIHBv dGVudGlhbGx5CisgICAgICAgICAgOzsgaW5jcmVhc2UgYnkgb25lIGZvciBldmVyeSBjbGF1c2Ug Ym9keSBjb21waWxlZCwgY2F1c2luZworICAgICAgICAgIDs7IGRlcHRoL3RhZyBjb25mbGljdHMg b3IgdmlvbGF0aW5nIGFzc2VydHMgZG93biB0aGUgcm9hZC4KKyAgICAgICAgICA7OyBUbyBtYWtl IHN1cmUgYGJ5dGUtY29tcGlsZS1ib2R5JyBpdHNlbGYgZG9lc24ndCB2aW9sYXRlIHRoaXMsCisg ICAgICAgICAgOzsgd2UgdXNlIGBjbC1hc3NlcnQnLgorICAgICAgICAgIChieXRlLWNvbXBpbGUt Ym9keSBib2R5IGJ5dGUtY29tcGlsZS0tZm9yLWVmZmVjdCkKKyAgICAgICAgICAoY2wtYXNzZXJ0 IChvciAoPSBieXRlLWNvbXBpbGUtZGVwdGggaW5pdC1kZXB0aCkKKyAgICAgICAgICAgICAgICAg ICAgICAgICAoPSBieXRlLWNvbXBpbGUtZGVwdGggKDErIGluaXQtZGVwdGgpKSkpCisgICAgICAg ICAgKGJ5dGUtY29tcGlsZS1nb3RvICdieXRlLWdvdG8gZG9uZXRhZykKKyAgICAgICAgICAoc2V0 Y2RyIChjZHIgZG9uZXRhZykgbmlsKSkpCisKKyAgICAgIChieXRlLWNvbXBpbGUtb3V0LXRhZyBk ZWZhdWx0LXRhZykKKyAgICAgIChpZiBkZWZhdWx0LWNhc2UKKyAgICAgICAgICAoYnl0ZS1jb21w aWxlLWJvZHktZG8tZWZmZWN0IGRlZmF1bHQtY2FzZSkKKyAgICAgICAgKGJ5dGUtY29tcGlsZS1j b25zdGFudCBuaWwpKQorICAgICAgKGJ5dGUtY29tcGlsZS1vdXQtdGFnIGRvbmV0YWcpCisgICAg ICAocHVzaCBqdW1wLXRhYmxlIGJ5dGUtY29tcGlsZS1qdW1wLXRhYmxlcykpKSkKKwogKGRlZnVu IGJ5dGUtY29tcGlsZS1jb25kIChjbGF1c2VzKQotICAobGV0ICgoZG9uZXRhZyAoYnl0ZS1jb21w aWxlLW1ha2UtdGFnKSkKLQluZXh0dGFnIGNsYXVzZSkKLSAgICAod2hpbGUgKHNldHEgY2xhdXNl cyAoY2RyIGNsYXVzZXMpKQotICAgICAgKHNldHEgY2xhdXNlIChjYXIgY2xhdXNlcykpCi0gICAg ICAoY29uZCAoKG9yIChlcSAoY2FyIGNsYXVzZSkgdCkKLQkJIChhbmQgKGVxIChjYXItc2FmZSAo Y2FyIGNsYXVzZSkpICdxdW90ZSkKLQkJICAgICAgKGNhci1zYWZlIChjZHItc2FmZSAoY2FyIGNs YXVzZSkpKSkpCi0JICAgICA7OyBVbmNvbmRpdGlvbmFsIGNsYXVzZQotCSAgICAgKHNldHEgY2xh dXNlIChjb25zIHQgY2xhdXNlKQotCQkgICBjbGF1c2VzIG5pbCkpCi0JICAgICgoY2RyIGNsYXVz ZXMpCi0JICAgICAoYnl0ZS1jb21waWxlLWZvcm0gKGNhciBjbGF1c2UpKQotCSAgICAgKGlmIChu dWxsIChjZHIgY2xhdXNlKSkKLQkJIDs7IEZpcnN0IGNsYXVzZSBpcyBhIHNpbmdsZXRvbi4KLQkJ IChieXRlLWNvbXBpbGUtZ290by1pZiB0IGJ5dGUtY29tcGlsZS0tZm9yLWVmZmVjdCBkb25ldGFn KQotCSAgICAgICAoc2V0cSBuZXh0dGFnIChieXRlLWNvbXBpbGUtbWFrZS10YWcpKQotCSAgICAg ICAoYnl0ZS1jb21waWxlLWdvdG8gJ2J5dGUtZ290by1pZi1uaWwgbmV4dHRhZykKLQkgICAgICAg KGJ5dGUtY29tcGlsZS1tYXliZS1ndWFyZGVkIChjYXIgY2xhdXNlKQotCQkgKGJ5dGUtY29tcGls ZS1ib2R5IChjZHIgY2xhdXNlKSBieXRlLWNvbXBpbGUtLWZvci1lZmZlY3QpKQotCSAgICAgICAo Ynl0ZS1jb21waWxlLWdvdG8gJ2J5dGUtZ290byBkb25ldGFnKQotCSAgICAgICAoYnl0ZS1jb21w aWxlLW91dC10YWcgbmV4dHRhZykpKSkpCi0gICAgOzsgTGFzdCBjbGF1c2UKLSAgICAobGV0ICgo Z3VhcmQgKGNhciBjbGF1c2UpKSkKLSAgICAgIChhbmQgKGNkciBjbGF1c2UpIChub3QgKGVxIGd1 YXJkIHQpKQotCSAgIChwcm9nbiAoYnl0ZS1jb21waWxlLWZvcm0gZ3VhcmQpCi0JCSAgKGJ5dGUt Y29tcGlsZS1nb3RvLWlmIG5pbCBieXRlLWNvbXBpbGUtLWZvci1lZmZlY3QgZG9uZXRhZykKLQkJ ICAoc2V0cSBjbGF1c2UgKGNkciBjbGF1c2UpKSkpCi0gICAgICAoYnl0ZS1jb21waWxlLW1heWJl LWd1YXJkZWQgZ3VhcmQKLQkoYnl0ZS1jb21waWxlLWJvZHktZG8tZWZmZWN0IGNsYXVzZSkpKQot ICAgIChieXRlLWNvbXBpbGUtb3V0LXRhZyBkb25ldGFnKSkpCisgIChvciAoYW5kIGJ5dGUtY29t cGlsZS1jb25kLXVzZS1qdW1wLXRhYmxlCisgICAgICAgICAgIChieXRlLWNvbXBpbGUtY29uZC1q dW1wLXRhYmxlIGNsYXVzZXMpKQorICAgIChsZXQgKChkb25ldGFnIChieXRlLWNvbXBpbGUtbWFr ZS10YWcpKQorICAgICAgICAgIG5leHR0YWcgY2xhdXNlKQorICAgICAgKHdoaWxlIChzZXRxIGNs YXVzZXMgKGNkciBjbGF1c2VzKSkKKyAgICAgICAgKHNldHEgY2xhdXNlIChjYXIgY2xhdXNlcykp CisgICAgICAgIChjb25kICgob3IgKGVxIChjYXIgY2xhdXNlKSB0KQorICAgICAgICAgICAgICAg ICAgIChhbmQgKGVxIChjYXItc2FmZSAoY2FyIGNsYXVzZSkpICdxdW90ZSkKKyAgICAgICAgICAg ICAgICAgICAgICAgIChjYXItc2FmZSAoY2RyLXNhZmUgKGNhciBjbGF1c2UpKSkpKQorICAgICAg ICAgICAgICAgOzsgVW5jb25kaXRpb25hbCBjbGF1c2UKKyAgICAgICAgICAgICAgIChzZXRxIGNs YXVzZSAoY29ucyB0IGNsYXVzZSkKKyAgICAgICAgICAgICAgICAgICAgIGNsYXVzZXMgbmlsKSkK KyAgICAgICAgICAgICAgKChjZHIgY2xhdXNlcykKKyAgICAgICAgICAgICAgIChieXRlLWNvbXBp bGUtZm9ybSAoY2FyIGNsYXVzZSkpCisgICAgICAgICAgICAgICAoaWYgKG51bGwgKGNkciBjbGF1 c2UpKQorICAgICAgICAgICAgICAgICAgIDs7IEZpcnN0IGNsYXVzZSBpcyBhIHNpbmdsZXRvbi4K KyAgICAgICAgICAgICAgICAgICAoYnl0ZS1jb21waWxlLWdvdG8taWYgdCBieXRlLWNvbXBpbGUt LWZvci1lZmZlY3QgZG9uZXRhZykKKyAgICAgICAgICAgICAgICAgKHNldHEgbmV4dHRhZyAoYnl0 ZS1jb21waWxlLW1ha2UtdGFnKSkKKyAgICAgICAgICAgICAgICAgKGJ5dGUtY29tcGlsZS1nb3Rv ICdieXRlLWdvdG8taWYtbmlsIG5leHR0YWcpCisgICAgICAgICAgICAgICAgIChieXRlLWNvbXBp bGUtbWF5YmUtZ3VhcmRlZCAoY2FyIGNsYXVzZSkKKyAgICAgICAgICAgICAgICAgICAoYnl0ZS1j b21waWxlLWJvZHkgKGNkciBjbGF1c2UpIGJ5dGUtY29tcGlsZS0tZm9yLWVmZmVjdCkpCisgICAg ICAgICAgICAgICAgIChieXRlLWNvbXBpbGUtZ290byAnYnl0ZS1nb3RvIGRvbmV0YWcpCisgICAg ICAgICAgICAgICAgIChieXRlLWNvbXBpbGUtb3V0LXRhZyBuZXh0dGFnKSkpKSkKKyAgICAgIDs7 IExhc3QgY2xhdXNlCisgICAgICAobGV0ICgoZ3VhcmQgKGNhciBjbGF1c2UpKSkKKyAgICAgICAg KGFuZCAoY2RyIGNsYXVzZSkgKG5vdCAoZXEgZ3VhcmQgdCkpCisgICAgICAgICAgICAgKHByb2du IChieXRlLWNvbXBpbGUtZm9ybSBndWFyZCkKKyAgICAgICAgICAgICAgICAgICAgKGJ5dGUtY29t cGlsZS1nb3RvLWlmIG5pbCBieXRlLWNvbXBpbGUtLWZvci1lZmZlY3QgZG9uZXRhZykKKyAgICAg ICAgICAgICAgICAgICAgKHNldHEgY2xhdXNlIChjZHIgY2xhdXNlKSkpKQorICAgICAgICAoYnl0 ZS1jb21waWxlLW1heWJlLWd1YXJkZWQgZ3VhcmQKKyAgICAgICAgICAoYnl0ZS1jb21waWxlLWJv ZHktZG8tZWZmZWN0IGNsYXVzZSkpKQorICAgICAgKGJ5dGUtY29tcGlsZS1vdXQtdGFnIGRvbmV0 YWcpKSkpCiAKIChkZWZ1biBieXRlLWNvbXBpbGUtYW5kIChmb3JtKQogICAobGV0ICgoZmFpbHRh ZyAoYnl0ZS1jb21waWxlLW1ha2UtdGFnKSkKQEAgLTQ1MjgsNyArNDcwNiw3IEBAIGJ5dGUtY29t cGlsZS1vdXQtdGFnCiAJKGFuZCBieXRlLWNvbXBpbGUtZGVwdGgKICAgICAgICAgICAgICAobm90 ICg9IChjZHIgKGNkciB0YWcpKSBieXRlLWNvbXBpbGUtZGVwdGgpKQogICAgICAgICAgICAgIChl cnJvciAiQ29tcGlsZXIgYnVnOiBkZXB0aCBjb25mbGljdCBhdCB0YWcgJWQiIChjYXIgKGNkciB0 YWcpKSkpCi0JKHNldHEgYnl0ZS1jb21waWxlLWRlcHRoIChjZHIgKGNkciB0YWcpKSkpCisgICAg ICAgICAoc2V0cSBieXRlLWNvbXBpbGUtZGVwdGggKGNkciAoY2RyIHRhZykpKSkKICAgICAoc2V0 Y2RyIChjZHIgdGFnKSBieXRlLWNvbXBpbGUtZGVwdGgpKSkKIAogKGRlZnVuIGJ5dGUtY29tcGls ZS1nb3RvIChvcGNvZGUgdGFnKQpkaWZmIC0tZ2l0IGEvbGlzcC9lbWFjcy1saXNwL2Rpc2Fzcy5l bCBiL2xpc3AvZW1hY3MtbGlzcC9kaXNhc3MuZWwKaW5kZXggOTdlNDVlMDcwZC4uNjY2NzNiNGQy NiAxMDA2NDQKLS0tIGEvbGlzcC9lbWFjcy1saXNwL2Rpc2Fzcy5lbAorKysgYi9saXNwL2VtYWNz LWxpc3AvZGlzYXNzLmVsCkBAIC0yMjEsOSArMjIxLDIxIEBAIGRpc2Fzc2VtYmxlLTEKIAkJKCht ZW1xIG9wICcoYnl0ZS1jb25zdGFudCBieXRlLWNvbnN0YW50MikpCiAJCSA7OyBpdCdzIGEgY29u c3RhbnQKIAkJIChzZXRxIGFyZyAoY2FyIGFyZykpCi0JCSA7OyBidXQgaWYgdGhlIHZhbHVlIG9m IHRoZSBjb25zdGFudCBpcyBjb21waWxlZCBjb2RlLCB0aGVuCi0JCSA7OyByZWN1cnNpdmVseSBk aXNhc3NlbWJsZSBpdC4KLQkJIChjb25kICgob3IgKGJ5dGUtY29kZS1mdW5jdGlvbi1wIGFyZykK KyAgICAgICAgICAgICAgICAgOzsgaWYgdGhlIHN1Y2NlZWRpbmcgb3AgaXMgYnl0ZS1zd2l0Y2gs IGRpc3BsYXkgdGhlIGp1bXAgdGFibGUKKyAgICAgICAgICAgICAgICAgOzsgdXNlZAorCQkgKGNv bmQgKChlcSAoY2FyLXNhZmUgKGNhci1zYWZlIChjZHIgbGFwKSkpICdieXRlLXN3aXRjaCkKKyAg ICAgICAgICAgICAgICAgICAgICAgICAoaW5zZXJ0IChmb3JtYXQgIjxqdW1wLXRhYmxlLSVzICgi IChoYXNoLXRhYmxlLXRlc3QgYXJnKSkpCisgICAgICAgICAgICAgICAgICAgICAgICAgKGxldCAo KGZpcnN0LXRpbWUgdCkpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAobWFwaGFzaCAjJyhs YW1iZGEgKHZhbHVlIHRhZykKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAoaWYgZmlyc3QtdGltZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAoc2V0cSBmaXJzdC10aW1lIG5pbCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIChpbnNlcnQgIiAiKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAoaW5zZXJ0IChmb3JtYXQgIiVzICVzIiB2YWx1ZSAoY2FkciB0YWcpKSkpCisg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmcpKQorICAgICAgICAgICAgICAg ICAgICAgICAgIChpbnNlcnQgIik+IikpCisgICAgICAgICAgICAgICAgICA7OyBpZiB0aGUgdmFs dWUgb2YgdGhlIGNvbnN0YW50IGlzIGNvbXBpbGVkIGNvZGUsIHRoZW4KKyAgICAgICAgICAgICAg ICAgIDs7IHJlY3Vyc2l2ZWx5IGRpc2Fzc2VtYmxlIGl0LgorICAgICAgICAgICAgICAgICAgKChv ciAoYnl0ZS1jb2RlLWZ1bmN0aW9uLXAgYXJnKQogCQkJICAgIChhbmQgKGNvbnNwIGFyZykgKGZ1 bmN0aW9ucCBhcmcpCiAJCQkJIChhc3NxICdieXRlLWNvZGUgYXJnKSkKIAkJCSAgICAoYW5kIChl cSAoY2FyLXNhZmUgYXJnKSAnbWFjcm8pCmRpZmYgLS1naXQgYS9zcmMvYnl0ZWNvZGUuYyBiL3Ny Yy9ieXRlY29kZS5jCmluZGV4IDBmNzQyMGMxOWUuLmY5NTMxNzYxYjMgMTAwNjQ0Ci0tLSBhL3Ny Yy9ieXRlY29kZS5jCisrKyBiL3NyYy9ieXRlY29kZS5jCkBAIC0yNjcsNiArMjY3LDggQEAgREVG SU5FIChCc3RhY2tfc2V0LCAgMDI2MikJCQkJCQlcCiBERUZJTkUgKEJzdGFja19zZXQyLCAwMjYz KQkJCQkJCVwKIERFRklORSAoQmRpc2NhcmROLCAgIDAyNjYpCQkJCQkJXAogCQkJCQkJCQkJXAor REVGSU5FIChCc3dpdGNoLCAwMjY3KSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogREVGSU5FIChCY29uc3RhbnQsIDAz MDApCiAKIGVudW0gYnl0ZV9jb2RlX29wCkBAIC0xNDExLDYgKzE0MTMsMjUgQEAgZXhlY19ieXRl X2NvZGUgKExpc3BfT2JqZWN0IGJ5dGVzdHIsIExpc3BfT2JqZWN0IHZlY3RvciwgTGlzcF9PYmpl Y3QgbWF4ZGVwdGgsCiAJICBESVNDQVJEIChvcCk7CiAJICBORVhUOwogCisgICAgICAgIENBU0Ug KEJzd2l0Y2gpOgorICAgICAgICAgIHsKKyAgICAgICAgICAgIExpc3BfT2JqZWN0IGptcF90YWJs ZSA9IFBPUDsKKyAgICAgICAgICAgIExpc3BfT2JqZWN0IHYxID0gUE9QOworI2lmZGVmIEJZVEVf Q09ERV9TQUZFCisgICAgICAgICAgICBDSEVDS19UWVBFIChIQVNIX1RBQkxFX1AgKGptcF90YWJs ZSksIFFoYXNoX3RhYmxlX3AsIGptcF90YWJsZSk7CisjZW5kaWYKKyAgICAgICAgICAgIHN0cnVj dCBMaXNwX0hhc2hfVGFibGUgKmggPSBYSEFTSF9UQUJMRShqbXBfdGFibGUpOworICAgICAgICAg ICAgcHRyZGlmZl90IGkgPSBoYXNoX2xvb2t1cChoLCB2MSwgTlVMTCk7CisgICAgICAgICAgICBp ZiAoaSA+PSAwKSB7CisgICAgICAgICAgICAgIExpc3BfT2JqZWN0IGRlc3QgPSBIQVNIX1ZBTFVF KGgsIGkpOworICAgICAgICAgICAgICBpbnQgY2FyID0gWElOVChYQ0FSKGRlc3QpKTsKKyAgICAg ICAgICAgICAgaW50IGNkciA9IFhJTlQoWENEUihkZXN0KSk7CisgICAgICAgICAgICAgIG9wID0g Y2FyICsgKGNkciA8PCA4KTsgLyogU2ltdWxhdGUgRkVUQ0gyICovCisgICAgICAgICAgICAgIGdv dG8gb3BfYnJhbmNoOworICAgICAgICAgICAgfQorICAgICAgICAgIH0KKyAgICAgICAgICBORVhU OworCiAJQ0FTRV9ERUZBVUxUCiAJQ0FTRSAoQmNvbnN0YW50KToKIAkgIGlmIChCWVRFX0NPREVf U0FGRQo= --001a114d72ea47b6030547e0448e--