From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Kelly Dean Newsgroups: gmane.emacs.devel Subject: [PATCH] (Updated) Run hook when variable is set Date: Mon, 09 Feb 2015 03:24:51 +0000 Message-ID: References: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: ger.gmane.org 1423452386 32021 80.91.229.3 (9 Feb 2015 03:26:26 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 9 Feb 2015 03:26:26 +0000 (UTC) Cc: emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Feb 09 04:26:21 2015 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1YKezK-0007Lo-Le for ged-emacs-devel@m.gmane.org; Mon, 09 Feb 2015 04:26:19 +0100 Original-Received: from localhost ([::1]:58651 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YKezJ-0003kz-TT for ged-emacs-devel@m.gmane.org; Sun, 08 Feb 2015 22:26:17 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:42690) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YKezF-0003ko-Us for emacs-devel@gnu.org; Sun, 08 Feb 2015 22:26:15 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YKezC-0005IZ-NY for emacs-devel@gnu.org; Sun, 08 Feb 2015 22:26:13 -0500 Original-Received: from relay5-d.mail.gandi.net ([2001:4b98:c:538::197]:44950) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YKezC-0005IG-7R for emacs-devel@gnu.org; Sun, 08 Feb 2015 22:26:10 -0500 Original-Received: from mfilter12-d.gandi.net (mfilter12-d.gandi.net [217.70.178.129]) by relay5-d.mail.gandi.net (Postfix) with ESMTP id B490741C062; Mon, 9 Feb 2015 04:26:05 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at mfilter12-d.gandi.net Original-Received: from relay5-d.mail.gandi.net ([217.70.183.197]) by mfilter12-d.gandi.net (mfilter12-d.gandi.net [10.0.15.180]) (amavisd-new, port 10024) with ESMTP id 0g40PRgLQNtH; Mon, 9 Feb 2015 04:26:04 +0100 (CET) X-Originating-IP: 66.220.3.179 Original-Received: from localhost (gm179.geneticmail.com [66.220.3.179]) (Authenticated sender: kelly@prtime.org) by relay5-d.mail.gandi.net (Postfix) with ESMTPSA id 8A9E441C061; Mon, 9 Feb 2015 04:25:59 +0100 (CET) In-Reply-To: X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4b98:c:538::197 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 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-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:182654 Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Stefan Monnier wrote: > No, the idea was rather to do: > > (defun set-internal-1 (args) > (block nil ; Because Elisp isn't CL > (if (constant-or-hooked-p) > (if (constant-p) > (if (forbidden-p) > (error "setting constant") > (return)) > (funcall symbol-watch-function ..args..)) > (do-some-stuff) > (and-many-more-lines-of-stuff) > (set-some-variable)))) Then the many more lines of stuff have to be copied into symbol-watch-fun= ction. Those lines can't just be skipped; they're necessary for correctly= setting localized and forwarded symbols. By default, hooking a symbol mu= st not change the behavior of Emacs, except for slowing it down. A hook h= andler can optionally change the behavior, but just hooking the symbol mu= st cause no change if the handler doesn't. I decided to solve the problem by factoring out the many more lines of st= uff to a separate function, so they don't have to be duplicated. This int= roduces an extra function call for them, but that's ok, since setting loc= alized and forwarded symbols isn't the hot path (and they're already slow= anyway). This change has no effect on the hot path. > I think watchpoints usually have the functionality of catching the > modifications, being able to see the "before-change value" and being > able to replace the assignment with something else. So "watch" makes > a lot of sense to me. Um, ok. I already improved the names, but I can change them again if nece= ssary. Updated patches attached. The first applies to 24.4. The second applies t= o trunk (using =C2=ABpatch=C2=BB, not =C2=ABgit apply=C2=BB). Feature improvements: It reports the environment as =C2=ABdyn-local=C2=BB rather than =C2=ABinv= alid=C2=BB for set-default within a dynamic let-binding, since you said t= hat's a valid thing to do. It passes not only the new value being set, but also the current value of= the variable. The function names are more informative. The API now uses function advice instead of a standard hook. Whenever a h= ooked variable is set, symbol-setter-function is called. Since it's the s= etter function, it's natural that overriding it would override the settin= g that occurs, so this is how I implemented the API. As a result, it's no= t necessary to explicitly set the variable in your handler, which means i= t's not necessary to temporarily unhook it either; all you have to do is = return the value you want to set it to. See the docstring for symbol-sett= er-function for details. Performance improvements: I put =C2=ABhooked=C2=BB into =C2=ABconstant=C2=BB, and removed my branch= es from the hot paths of specbind and set_internal. I did the minor optimizations of set_internal I mentioned previously, plu= s the relevant one in specbind and in find_symbol_value. Also in a few ot= hers that aren't on hot paths, but they were trivial so I did them anyway= . I inlined grow_specpdl, which speeds up specbind, which more than compens= ates for the conditional branch that varhook requires in unbind_to. I als= o inlined the first part (the hot path) of set_internal (i.e. of set_inte= rnal_1 in my patch). Both of those are fairly small and not used in very = many places. The cost is an increase in the size of the Emacs executable = by about 20kB (out of 18.9MB on my system, so that's about 0.1%). The result of these changes is a measurable performance improvement compa= red to unmodified Emacs for the common cases, i.e. for setting and dynami= cally binding plainval (non-buffer-local, non-forwarded) symbols. So now,= my patch actually _does_ make Emacs faster. ;-) Here are the benchmarks: (require 'cl) (defun test () (setq x 0) (benchmark-run-compiled 100000 (incf x))) (defun test1 () (setq x 0) (benchmark-run-compiled (do () ((> x 100000)) (incf x)))) (defun test2 () (benchmark-run-compiled 1000 (letrec ((foo (lambda (x) (let ((x (1+ x))) (if (> x 100) x (1- (funcall foo x))))))) (funcall foo 0)))) Execution time results to 4 significant digits: test minimum average maximum Emacs 24.4 0.006253 0.007259 0.009721 with patch 0.001816 0.002148 0.002425 Average improvement: 70% test1 minimum average maximum Emacs 24.4 0.01074 0.01075 0.01078 with patch 0.009081 0.009301 0.009671 Average improvement: 13% test2 minimum average maximum Emacs 24.4 0.04401 0.04409 0.04417 with patch 0.04196 0.04202 0.04207 Average improvement: 4.7% For all three tests, the slowest run with the patch was faster than the f= astest run without the patch. --=-=-= Content-Type: application/octet-stream Content-Disposition: attachment; filename=varhook-advice-24.4.patch.gz Content-Transfer-Encoding: base64 H4sIAAAAAAAAA+09a3fbNpafpbM/AnXP1lIluZbkZ3ySqWLLjWccO/EjTXdnl6EkyuZEJlWSsuN2 8t/3vgCCL9lOMzN79mwm00gkcAFc3Pe9gDqdjoqj8Q8zP56vXddbrZb99ccfVae/vtneUi38p7ut fvyxrr71gok/rSv4X+uH79XFtRd7yo08lVx76saNP8ZqGkb0bRwGceIGiRNGznUYfvQmaup7s4kK p+oYxnDO729G4Wyt3lJKvfSTWK0rN5ioroqTUCBqGNxzjdqpHjeIqYUNGd5//0O99e3Em/qBp85/ ef3y9NjZPz05vxicXDivB+d/Uf3C+1enp38ZHvDbjXoL3qu0Qdr7TSO+v2mqRoP+7bwoLq+p/lpv 1eCP4j/flc6gmRtAhv8D4K0FNHH+dQU7cx7eeCqce5Gb+ACK9igOAaE3N2Ewu1feJ2+8SABzybWb ICbvqYl/M595N14Ab+o4iBvDro6jMG6rIIRtWARjgtdWI2/sLmDzQ+gb3fnwKVoEiQ+jwqBAAzdu MPbUXbiYMaR4MZ16QBlhqG4W42t1d+0FOJ25P/ODK3XnJ9fqp/19+hAuEpg7APN/o+mvMTVu7ra3 gRq319tCjIJGpFjn2jk5On7T+NRUw7eq8amt3gb+rFlodD68cARv7wbHiOy2ukXU4hwbnhvHXpQo vQuRN/Ejb5yo5881tt8cD45OoGuzraTRrTtbg/8vPPVcNW6bzXonP2aODPRev+cXKrflzZREHwCQ JdAcwGbJ4jML/0qrrhqG9qLx/uKXN0OFHwGYxfZN2tLu5u52u7uuWt2t9Z12d4O2lf701TPlJ6tA uChQ7txoglRy60a+O5p5beJ9RrofKz9QH6TVKgsBgDA8uXztvDyk+cKAjl5VU5n1PVP9PZBkHYUc cxIGnd+8CMjTc4FhuBdC1/vSVv6at6bG125whZNBkUVTQABI4ddI7Cr2rwJ3BqJMeVEURjCfo2l2 un2afiAPI+k+hh4jj8F7E2AwZAJk1dG9+gAIpmnI8qDHIsCBgIGNjHymensoTGEtPyN4FMfwnjir TBIhS5cvmUSyenjhDy1Z4FQt/LFLFjBVi7LkX3FJXpLAlAWCLPDOn81QWuEcULbCfFmRJXchaxKW lyCdRj6i2A+SECam1wPkFkYTEmZaTLG6mrpxouYuTA103CIQ3YRT0qiMYWkC5dq9RWTSegE2Ynvi o7QDTI4ikJ7XokpBPo/d2BPtVrLzloYVilZEBUcgxiNsCK0SD+eEk2Qk0JqRdWLatmBxg6oCxptG 4Y3wID6V5o4vsHgWJI77Wz2Sx/3tbRHI3idsxGx+OvobshhKYZDFQENvf12ECXDu25l7M5q48GER jMJFMNkr70ik5BisgMqRRzdeHLtXCCkJ587Mu/Vmy0DQyD5OwI2uYgd0ixNOnQhJbq/eKet2G/oT JxU1/F2rPmCxJ/eB70KIjt6zihn7ATAL9Iw8d+LE90HifnqgpTXGXRTCCLBpIy/CNcJ6F6jLEXVB 6IzdZHxdAQ00eeRodIGNh92nPq0E1pRcm3c3bvQRiMGFMW8Bf0wIu10yEzfWt7QMH74/vDxRjcPR feIRr7TVelMNLi7Ojl5eXgxZEBGlAp0ekPZANlMTN3HXxkLqyf3cAylAdIiE/ztzzsF94FwGwJkT ULidbjt9ur+IIlgvPF63nr7klnbD84/+HB71rEc/zcIRcN5ztBCV+mx6OgekK2jny1AHTaiB2QjV sF43yztNEbBwFkvHQifkvQGhfh+MJNiEGED/zgjf6O8Q521sdbVhXhPLsHxs5wQM5mSRmwXTC2LZ kEpmHu0KaDaMSYjrgDU4lppuLAJEBLU7vJuo75sppyFjoFgWiQIorxwy92UUgtlQzn4gzB0R5qDv k2gBzyxj43vu3C7Z1Dbb1EtW3aqauNN1UA2lA1dOnceoFZdj3pRMTBXXQYisns8sHINI+M2boEKQ 7QC2enBeSyZWOjPz7rEzBCZ2F7NHbbl2cYrDWgTIgO9vYhRTKDLA7oZHhRZ37hzGdK6ItR2UGESd FdNWxFwbm7vk9G5s9YDJusYiFf6ZurMY5J76LB7wsf/Ry5IzGjFknkz0zJXhLjAYcBJjVMfgAKHr BDpZDC4jQGAXyfCcgFyAHq4yM++C/Q3qehGYJx18BGo78HyC1lhvsr00AONn7o19mBFaD6ADXDHE wA7okd5X05l7hSNM/BjVVoaNwFlE04NgyTOyioJVYjeYXIQTGLnjj0nkjmkAkLPWIP10EIIiK8de 4nTC+6pFW2TTBlT5YA1Bg/COUWVPlOePYBd+fA325J0nJibvO00Lv07ugw6xiManqJl66+jk+Ohk SERTb2VZPEOqYgxlKBYwfwdLzj6DvY08omVkJhoP0VAmgJBMwOMj3VZGmDDkHs6RLbop0CFGP8gM B8JSEzAUgOTQt26DMEYv/TpdGnXyp6rx8vLwcHgGLiLNrKm++06huwz+Gb/RLzovAvfGA9eRbVSh +j3Bk1L7r4b7f3EsN3PEMplsa1Ce78te4QTge2lQgwf6XY+HTe2oiLiygEloAmJhqfzVu6N3hHfB wj6guo0TxWnVzOLg82d7fEbM4Ufv/g5Ml7lZS5M6/f3v6huMMOhBDrNqXLfFxp/YLwIaKph/bWUj iIxtkCvQB/ZrgHSuPRcl04iRzoGK/UiFdwEzmWxyzawD4XymjYJBouQZ7QvgCJiHN8D4wBm0o3zI O/rPVDZSojhUwqtu7qnMmDaAd4OzwfHR4PyZUISxj7RxzFu6p65CZHOcp0ARdn/2GKUGq37adgtq CDsYHjMhRt63k+HPuEhy9HghLEWB4Zi5fphGwBgsP/zkXvwmP44XMOTPr4ZnQxa34D7GIq9grxNQ R7hxYF4zvAa4Q7joYGIFSsVqtQdCIa4n8PLo5ODwePATjknqR7xof8oiNI1UxIv5PIwxqBdifC68 YY+VhR6IC3CVonsZh9EFvjx19BIBeodh3I/0nLqtlc0CxBRMAppOQlQHE1YVD4vTPyhMmVEyEtVI zpzQfpA2LHcByYPoQoexXg9+eTl0zi5PkJhREjVA6JIiIh4A/DFVCoWFswmNIbxR+yv5KjX9569M fBWSLdMG6INHagLjZG3aRwy8x2BwKYq3wHk1HBwMz5zhyQG6Why8R5UwfD3YP3eOj87fOK8oniSp AA+jemOTCpCvZBbtkFG0I54+RhT8cdaHdNFtnHMEY6+8iR9c+yMfNftocXXlRRXNJt54BqYG7EvZ W3Kt59A1B1p2nz7MQT6hRxvc+uDkoO0Fvut4FsYLBKuqhoVZsU/b28KYRqu3pResgC0+ORTgRKzA CuZg4oHCOzq5AC26fwAqFC3RZlOMw46MQJboVRTeOSgf5pOZsVX14vxghlRX3ZC95H00kFBe4JyV xmBbXfm3HJRLzczB2U8SBqXFbK2Tf7613mtvbOQNWorKTLRFezAkv30FR+7MV0C9Mbbb6lx/6LbV 5ckQpOXx8KBtHG2U3+H4GU70jAEnSPIwE3XtxmCWiMoC6cBPyTbE0NjM++SjfLJjuxyY8n5d+NCL Ded6q4EZiAaFjEAp07wREuhaEpaXgEYQXB+4wWq7YF+CuTRDqxYMKBg6PyzBOPc8bvQBV4uRxwWG mp7xVnTmNB5ilhRoRpphcElLo8i7AosUZKzd4Ba5IjXyrsbzKOT/dun5T/tvzk5BdBEgYzdhoOSN JjB6pY0zsS56YF0sC/zobTsEPF4ByQoQsSlvKeTxfn9wlg6sh5YwPqzdnelBf1eU9QPEjkASfSSD 3Yv8W0zBReENR0H9CDDM78ENIHaJFyMxSFU2SIH7oD0zEPHP1Tdsfr17iJ/RwPqTOnTj+FeaYVs9 qsszikju2faeoNiaCFlvGjWIePtd3mLjdiURHTaU0KBjb5S2C1mVYmk4tARADWbIDGWwEjcHyAZ/ DNDeN7RDaek6lNpUf1JvMRNgFnl5QnS1x2RJjMmESGqirjTDg+oDToD5uTFyvfUVWD/zrdfGOD7w vcrx/Wu0G8CQ6pD9R56gWHzUk+wdsVVeDs6HHVCuR4OXx0PO7m31MK3X2qIkH8qouio4FaDoHILV lLRNwbNoWsSbSY2xG0HzpVwPmB+gCsAuuOe0A3xA3+lPOnukZJcaK/tugIKHrCI3zbaQOEFsmcjB 1ibFw7d2u0ZnmJmPwEI2FjB4WaLhJo720Z8rkAK8YjsBl7eqqY1lmTOq2TyoGAxjbwLXTP55ISH0 Jt9NO3VlXtvj+iOjnw4OXh2dXziDi4vB/qvcDtJWDG/ZlAUqAslImgzUhT97BuR6E956aOWkL012 73AOm5aCQ0EnIzvQmKSfy2E007cpqn19nXX7+saW2SiwocA27izQeIauYCX/bYFCzJtqP2EUJgkI OJ1ESdzxxz0Vg4mNOe8Yc2KcMJ9MwIQj9ZUAxQRaD9vmQJnmr5ep/jp4aEgT/NCZJ1GrJYvY7pNO 721jNrwvqxAGZ+bPKnRmvA56lbBOrRVXUv+V31jphPOqFxv0t1rxiy8F7TmvB1r0IqOKMacKxgym 8cDlQMQDYwllGZnBXsmaEBrhExOKIkBGHlIKNRievJO3ypL1+IjdMMoiW+1Pjw9gevWW9NHel3jU 2hHkl0Bf4iCCR8XgaPcJJYAAyosSFFxPhNThpuuMsc4BBN8HaP8rGCRo8kDHmznHwCjIxasyRggm IpU7ThYgEioGNxiiNOaIZmPQk4r4hST8LMTrQBo80svMtYCt9NBYS+qtaxd4z53c+mOPw3XAi1Hk T4jWyVi6gFlhSim/dRgJhH6YT83AXsSk4xsMtAOcor5dLadL9Uw479vV+3ARdbhLU0bVM9HYjDUu /xETMYMVpzKg3VNU9EIBRnQfKVmJqMfWGoFozOKeuAmmuT+I7dkRk2K13rphaaMYs0fUG6MG6fjt DEBqL5udRjFSOiF81Fs2vQBthcolU0RgciRWk/OqoU6LNE1vgBUK1bT1wPyV4LK1hx0EBkeDZx5S URaOkQsGDnPkGkYZhJkxVEsJPtDA+JkD3oQCLhrA4Xh5DAwRTjhgbS7tVhMFVuAtORBUTQasHs9D Dp2PI8/lvYrqLSBrMstl71wc1b0BEW2JFGLOiOiyzTOgwiWMmvC0AYyeN/Em4lCLr8DIE1tIYT7A FFNIm3ABm1FvZVxXxGXZiBZyKoastwjeg6Pa71lYEkrCe5LfRJIZ4YMynCXn7J4UWFu20YglfLim a1+YxEjoZkWgTN6G3dbSKQvpAv02jpkhqomJ2U/rzFdpoBKekTnBsDxHRCQ2E8rzMeFUFKpgebh+ kK4gVQpVUEQ5lTBSyQJRMYw9bxITcJ25MdABcr2FVB4nOJkyAKN7GVuzMIeNtHVipJdxY8EQoFBd nq1x+y25AhMCW89zYRZ+VoIFOF8SAnkQbcL5h1SYrnL6y+yCVhYUycIghpHPzGo6VkdgRAxj21WS LFxGgyPetHHX0zb8Jt16qqS5c5nAWTMBtRj5jbZaOjTwhT02xT6n/gxZxR2DoJgIfQKf8X77pfQV Y8HkvdG7Qig6shsGsEbsxXFSPTdw+cdgI66VBxLKwqLAndkHOvRXjJ2mMQiaET/UEU47vKODOxLa QYuO/1bZdTq1JOacmEhcr7UA1HWAloYYIUvpjwwHbVPoKbkmFHRWScO2uvYCJhY3uOdqU/OK6JFV WsoOKXiM53ASxfJFOY1SOVgx7JQmW7Pa9BA22fvkYsEsFkWCiQf7Horl3iRRl4GkGuBCao9/FZo2 icmwT2UsLBPYSrtXB7dAWi4kASByw623HhHqIhFqyDFHQ2mhFkcNNBXh8MDPSEjyEWjJfOq21evB yS+loQKKZXKcyAQt3diyndtq7sYk4VkW0ybqqBYrsLW6iTSmBhDSm8EKTz+W6uFuv9feUa1+r4+h bHKYJEumKrNkirNkncokl9RuPpTreg8uezYzKompTBZMVSbjNAK55F7dhIA4LuXm9sSLbsLy1K43 TEseQSK7dVVT4Arf+kQMnEGkqA11xhANFjDCv3fo0QRWrV93o9vudhF7G5vt7mZap2s7p50XM3Cw ZMTnMvReZUOQYY6um84lGpumV9Yr5liGDtx9kwv9dGqlOUuuUs6E/L6pCGw0y7OeOQgYoVuSqS4F YWVzqMSFn0o6T1cFtDngYkqr9cgpOig42Kllk2qaoqQPl1x2KcldlRfLNk1nkI40AvP447L8rsbG P4b0j0/3YZj/GB4Y2k9D0s7L43e6DJ2ypZwVA3at6aDdYZqtRbGHAQeK4oF8BNLrkDhbkYBQv7u9 ReV0vZ0NCQhJqvF3rKsr0O1Hric8fzPcf3MAM4XtBok4uDzGgsZarUixtdqhVc6S2wTaplp5lVRu t+xNqpmsv57sZ/r0WZZES4El7fbSJT1iJZRsKlvCP5TiakJsyqyElIWuBwANMI4ddxTiGQW9af0u nwbZ6G23d9NNqyihyZSmCBpEUDUstBCn1TS15WKxxcMQFqHAJpfyvQaeCrv8eK1M9aFYdig+l/ek joVMtWpoyzAvXy7Fhc5LGG7P4EpXYBoAzel9ypCcSCXeld4uKdmNPv5rsZKmTlVjLi8yD+hSaJHj lCVb1Uac1x6DX1VRhLgcOhUiPgDeRq2QjkFRYZ0k0p5RI6njBeJlGt7s2YKHC73IwrsjqyhTtYZh k9QHs1x4dw6OxRykb+IZtJvSMHO0gkJ+rq42wdCoWLfsbYKpGCexRK0NJ0hS7pAmYkS8M0/Zm8vH 8PCTjFwuMAweTUlGV7Yo38eWHSW9SjD/OYt/kYSbfYr297c2tm0c5zwui980NSQ3cyMNcgxqzJYS 8rC74XrKm3CKjegxLRyjVA11LOgLCwcGX5U6I4MwXe5ejqQqImXUbfYZdVv9Mr1Ytjh8ofQKmcQc TTRWfZyhF9KOTyOVSg1TSSXW8rOiyCCClru9uUHHGHa2NkxeCGQTCETVKFSutNWKPOroRytsPJku dHAS2tG/+ZeSAITX8mmF7UvTQOftdSlGMz3Xc4KVD/rcpo4mqGs3mFB6mbw68AJj9Ra4OZH8pmcF IUTRsvmV+FSJ4AO0O3+MMY0QW1P+a0LPEZmWL7CLdSSqtbHe7Rs8AR3GixFYXt+dm4pgh3deUn1W C8l5WnKk0ET7cHPGit25NCtVaKZrbAoPebDPpuSJT5yYkif5SiVPJDiM2CirGBrfj2f+2MzC0VYw nxZZ0sMsPdsj29SPxgsgDaw6AhO5UwaueKyo9cD7x5w3+koHjbJnsZ52qGhri0qWtkwxQBY1k6rS MVgGRyIB3jRs8wOEC1rRSI2KwrKqhOdbLiSHD1YF3tsJSBb7M5tX9JFDL9V1ZiGGNMzqMcyB++wn 9+YZuCdeNJ2BGU5P8sik02umMYYj7baEv26PEAg82lsnFP4bVZENPyFvJhTSRCsCT2CHAUVVwqm4 7Fr9F7LH7CRzXZggix9RgVjhSZf+PlAhluZ3ueOaFSuGOUr4F8VYIT5MDfLR4HqLzokysLYpo5Zh zNFP3S2X77OjYKVVXFK2/WDB/heWyt9d++I6l3oe2vmWaqzlrrcVwSsGKnKFQpm4HlfQ4SbzJ9hb /cFsqXpwS1dNhomjv5RNqVvKC1oWMqFymtsDw2GcSJQz8sCK0PXvIhy4oBH89o2tbO2DnGrI4bbz wigKXDgWYcPSk4oiCaSdHIlnyXsJab9CajUV5KWk6CePIEPiggriT0n9QsoZ9VkiqnXQ4+X5xaMo r46660n+a+m9qsDo789LTnd/AYf8/rgoldXqidORoj2hPh3yzGZbMttmERY/SElLf68krkumhyx5 6XPmRQKjnMuDRFYtX/8vE9h3z0000b4A5r9Vp/slkvgr0dmDs1pCbkZ8p3kipLX0GxCa/aVSlFNG ICfDdRbe5Fwym0tXeXTB0d5RrW53tyehn6+QX3nKISKVh5KeZYrsSdtZhq9zfKkwcjF6jS6zTdwv 2Tc+Jt/4HeH4+9HsNk2FmBj3nqB3axt1XrfX67U3e6L0rBNmuQsIDA+Yk6qHkpSW+MZ5WhNH2QlV UQBFmaNE7nkSM59j/+tr6pw+dNfUwJxCsg955iryAqlOOkctn1bkEYwel75lqvHQIj3n6JabZCpx qEufu1TW51XW22UToQDJyiOmeeFyfOgxizV4fL5rdA8m9cTT13bMZrGd+mmyFeMmSp8oypVi6cUQ sC9YkD6CZUnYeuuh0/FyrInOVaUOTvlRVXMO62nVCEWJv5d/DPtrTj3AQChrTfAGxdIhni9IgwtU Fr8IIu/Otyro81UPqjr/ZB+O5DO4liAnZrbOiJlsFx5DJUzF1+4kvMOTM60aTtlgjo+J6tfA0DMM lNHX2JGQmJi7EkClsBYlFSt6ZQ+wp2HXph5c92siFqFz6pwa0Nk56nbmiWknL3hIfGonAkX9WPjh azMy6MGRHjV7xlTljJ84E6TVZzY08sGLecw0bpxpLT57pn1lBqqgiZHTN/Ccb0UIQVMeFfLkz+3l 9Dd0JiMRBfM5/bdHf0tU9bkp9zOa2irTRPc4V6pJ6lott8XK+ZiV0PYmelyghdD16mVdL810fPzt kYdsUfV/zUO2CO8Jh2w7egJ/6JAtwvhjh2xLZrH0kC1gNxM1l3COHRen6/wCxdc56msVWOvyuYOJ CfPgXs0B43yGKweHAsGmzgovi8IQUtl1VWFgbsEiDqGbsHADsCIlX5stg9PZh85XOySss0/5Q8KP vbflC254qBUHrFSeVf4NnfToCBREiSenu/TQ5oAXH+ap8pI6WZUKpkJ3j2n86ZdHdL788gip0bEu j6A5VDhwnUxtR+7QluiJhy80sF2Jh+5x6DzlHofOI+9xkJGlQucL7nGodF9s5fpQcZHKFBbpGxAy GX+R6JQRy1zjkNWp/9T7HJ52eYee62c+BVjl/iPRabpZKuKMdCPTfbKAhmM5PaavOR0BaxQkbDCh lS4TLnRQY8xHt62KTdnykhtnHnGJ0zIhZV0RWxRXOSlltX2yvGKzPpVXBXOeZY9mXBQlf84okgg0 0USf0tMlDBprc6re5pN+/4zQQQHK0mtQVMk9KI8KAYjrYIxumB5q+b0/EBtQtVTUSU7dqjDp9jbp 3oZuf3NTp/Bxw/NXMd15q3g/sOdpP1TXHkgptZK75T56dNOvnzsMgif8R3jrkqmtM+OUGF/62pqa jQd9r1aNnSkhUZLSsPTOCy4i8KdoWgtwfPmwb9Xk1hofO5uMj51+pmoMwMAwKPzHHvBqA760iYTT sgmYcUm5lRZXcdkFHQIS9Ql8bNoWf+0BLQ/+QC1jQqenATVS8VpnnK0u1rEWISNaA/IR5W6/S3nV 7kZ3G+t5rZoOpPM3wzOHVTrS+uWQTvUupm3lTz5x+cWjccGWUeP94c8HfAOwHwReRNZ6kMTN5vPn +nZATe4gN6QX4a78YsEslKciFEmLmgmPiFWkbSKSS1ilbw7GscSjWoK2voeYy6iS6yhcXF3nC606 2g0g/sLsLAbhpbGRj9O7CbiCyTgtquj2Nzh6urHZ///oaWn0lPcKrw1mX0ot5uRcuNrXIkk2c8cf 05I5ZgVshSe9CNEb3T5xwGZ3V9+dqQ+VZcNo7Cc/pHZv5QpscwvRo6p4OWqSSdHS2730hiq6WNCu A2svu1lwTeF5jpx9MsWTjbAINPTjceTP9fFGWmzalUOGqS2y9LrGaiwQ96ol5gRZDWqJ+0IFThVe Am9er9/u0e5trLf7HH94pHmuLPNcfYF53qnlNqqWUf2fS66rSMd+Ajc/zg14VJV16gQ07fkaW7/A eF/bdhKMIRUXq94fyfZfbBiV6yhBUMFJ4nteyNTAi8dBrTatAn1bGduKWA6TSQVzh5SmimdhonUy Rp8LkC0cGLlmG126IpcKJ+5AlLkTSe9Ss7Ph4DgdCX9RQY9GphMOBAoGvXRUhdmB6ZtYOWIp0o9p lOlaDclQ1cnl8TFVbC7lhFLKOjw9+3lwdpDZW+boTTZINrczBeOAWhBUU1wyMJTYJKcv/wzmBO2h MQE6L7jZntURrBXoZRkzRwfvVYPbCWVg0ydQxxztSiY+U5Ur8LJUoo3J6g7Zzcf2Vrm3fbwaDQd3 dufex2lsEf1IBhtrdba1wz+gsLnbb3f7xsSnqu1Se46sOW0WF2arjce2KkzXlM9ykC1PBOmztNJY giFquSRo1Vio6ek8VbDZI7dqhv4ePkgijeSXKOg8SXe7t53eCvNg1y+/hUifVBIF+O/4Qyt0BRGm E21jcqWtzg8GFwMTITsZvB4iqer7fXRlMG05+hm8oK1tOlzQ3Vlf/9+2IKalR6yKFrKz1aWF7O7s /usXYmUoHr0xrKIw4o/+mY7Q6dAO0baRZ1KLvrG9TrXom7s7mqut2vB8keuKO5F7STr4IF9rXlYC K53kcUc/5jJzuw69KqNVdaNQroxdl86u8If8a8tjXoHPgthcI6vSdsVc4lzWiEtwV/QtHGVN9E0i K+nNGSssu2XjncT1MSAxX4BWJB+7YX5HAn9RKC3DH56dnZ6hpKYT13RQhy1RPKEOFBS5wSS8Yaic iOKUlUTZ5RhpzBu+tc4Hp7Y3NrRjnildL/zMQLGqnjdqjtXiVS8pPl9RUU/1CRXvuMasADUtJyoW 8GfeVQ7oTUqK/7nYtAiy6jmrdUbjNqvD/k53Cz8YxgEVT/edYn1UGCedeRj7WG3emfqfgsUN8PI7 fO7o5w4/b6cOvs65Yv3HDJwnLIuzTp1Toeocj2YFib5Zw+W7OpG5riTuxbMvHUvLCK6rV43Xp+cg mk7Pjy6O3g2dw6P3J5evOc9gPAxmW2fsyNVpFYtrNjN3v3WlMOLLgWSugusKS5RgOfCu3DIs6+fL sRzf4K1afxjNucFK0Xwy/GnwZDTnV/dFaF4GpIDm9NgKXoY/ts6t6O/ygyzr/Ms8u6nqp+NaIgUw Yc4XR4pJD+/nnRdXYzyIMfITKx5LL/SP/6SO1uXJ0cnF8OxkeECYmmcWvk4Ln1esY11DLbkDMTPq HIN9k8xTBIj+PfwHlN/VWLWeg8z9zQunZYVNuIv6Nw7xgIuFLv2d0LXTIwND/mV0oY3QOD8bHhJg Ona5Tr9htvpstantS3GxQLFFkXsPhjXe/gV2qzxo5rOSFT/4ZmhlSZsCKZS2Ll4cqZ1x0yOfz8hA yCXY6BTUOh9SlX8LxJT+7M1bU1qqFWWmISmm8laVc6ImpqXNkvRoGbvlGpTgL9+0+k7O4iL4V63K lmnhw27EqNxcZ1Rupnz5NqFAS142JCsPoQZdz7ei6R+3lAz+kuXYSx6S9iCj3yb883gRkZwnF3nu D05OTi+cg8vXb9YUBS8W8zVvlt5PloR4v6eiks6JudDzHRhc/vTeobTPczqcoZlX0kYp95oHiNXN bT6mKv8iVi/yvnQmOG9dEIdGPV2fmEhMdXYPy1vEXu4arRjzWgzjBpwOH3/WahUXIrfPuelx6lQ7 8S9XKnPRzhGY5mD8TTz1oeFhWU7zAgXxWaZDvKr113IFxJcipbPpwEzwYJcXxU/WQ4+FtUzrp6EG PEDEqMKzfp1xiNGkTnwfJ94NuX6s6r97+Q4vnZbUoJOeU6cwBHZ1uKvDXUUMtA1VTMFlsmhCvhJF dPFXJXeBJOSD9hn/E1T78OxoXwJ1jBH4So4bRT7549ra2n/VVbax1KKxjcG1ddn++MSCQT+4qo/T GYMEZ+ncef7VdeKw/fJcvbw8Oj5wzi9+OR46F3ghsmrYLR4kBYTZ4R4d6vFkAlgO4SFjzzk5fXN2 qsHEM+giUNqyYHrGqykx9dQ7YLyQLk/F1opaa9yp27jk7kb6uUK8TRcNw1iY7ENhGaum/I9+kNbc j3dLA+a3xZpl+a5YDR63KTYuvmhPqgA8bUvu/ElyndsSela9JQPSc3pHqPG/YEesSVbwSdrgkWxi oeLLuKQCQOmOpKfrG98xiSX3INf0fKFF/ql2ThYB2pIOo0U1+tD6fwCaNrHNr3sAAA== --=-=-= Content-Type: application/octet-stream Content-Disposition: attachment; filename=varhook-advice.patch.gz Content-Transfer-Encoding: base64 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 5J9qZ2QeoO3oMFpUrQut/wf2YhAx6nUAAA== --=-=-=--