├── .eslintignore
├── .eslintrc.json
├── .gitignore
├── .prettierrc.json
├── CNAME
├── LICENSE
├── README.md
├── dist
├── bundle.js
└── bundle.js.map
├── index.html
├── package-lock.json
├── package.json
├── rollup.config.js
└── src
├── dis-table-element.js
├── highlightable-editor.js
├── links.json
├── main.js
├── opcode_links_gen.py
└── permalink-element.js
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules/*
2 | docs/*
3 | docs-src/*
4 | dist/*
5 | rollup-config.js
6 | custom-elements.json
7 | package-lock.json
8 | web-dev-server.config.js
9 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 | "extends": ["eslint:recommended"],
4 | "parser": "@babel/eslint-parser",
5 | "parserOptions": {
6 | "requireConfigFile": false,
7 | "sourceType": "module"
8 | },
9 | "env": {
10 | "browser": true
11 | },
12 | "rules": {
13 | "no-unexpected-multiline": "off"
14 | },
15 | "overrides": [
16 | {
17 | "files": ["rollup.config.js", "web-test-runner.config.js"],
18 | "env": {
19 | "node": true
20 | }
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "tabWidth": 2,
4 | "singleQuote": true,
5 | "bracketSpacing": false,
6 | "arrowParens": "always",
7 | "bracketSameLine": true,
8 | "printWidth": 127
9 | }
10 |
--------------------------------------------------------------------------------
/CNAME:
--------------------------------------------------------------------------------
1 | www.dis-this.com
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # dis-this
2 |
3 | An online tool to disassemble Python code
4 |
5 | ## Development
6 |
7 | Install packages:
8 |
9 | ```
10 | npm install
11 | ```
12 |
13 | Run the development server (with hot reloading):
14 |
15 | ```
16 | npm run dev
17 | ```
18 |
19 | Lint the code:
20 |
21 | ```
22 | npm run lint
23 | ```
24 |
25 | Format the code:
26 |
27 | ```
28 | npm run format
29 | ```
30 |
31 | Build the production version:
32 |
33 | ```
34 | npm run build
35 | ```
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Dis This: Online Python Disassembler
8 |
11 |
44 |
45 |
46 |
47 |
48 |
Disassemble Python code
49 |
50 |
82 |
83 |
84 |
85 |
Python version:
86 |
87 |
88 |
89 |
104 |
105 |
106 |
107 |
108 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dis-this",
3 | "repository": "https://github.com/pamelafox/dis-this",
4 | "license": "Apache-2.0",
5 | "devDependencies": {
6 | "@babel/eslint-parser": "^7.17.0",
7 | "@babel/core": "^7.11.0",
8 | "@rollup/plugin-node-resolve": "^11.1.0",
9 | "@rollup/plugin-terser": "^0.4.0",
10 | "@rollup/plugin-json": "^6.0.0",
11 | "npm-run-all": "^4.1.5",
12 | "rollup": "^2.36.2",
13 | "serve": "^11.3.2",
14 | "eslint": "^8.15.0",
15 | "prettier": "^2.6.2",
16 | "lit-analyzer": "^1.2.1"
17 | },
18 | "dependencies": {
19 | "@codemirror/lang-python": "^6.0.0",
20 | "codemirror": "^6.0.0",
21 | "lit": "^2.2.4"
22 | },
23 | "scripts": {
24 | "lint": "npm run lint:lit-analyzer && npm run lint:eslint",
25 | "lint:eslint": "eslint 'src/*.js'",
26 | "lint:lit-analyzer": "lit-analyzer src/*-element.js",
27 | "format": "prettier \"**/*.{js,json}\" --ignore-path ./.eslintignore --write",
28 | "build": "rollup -c",
29 | "watch": "rollup -c -w",
30 | "dev": "npm-run-all --parallel start watch",
31 | "start": "serve"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import resolve from '@rollup/plugin-node-resolve';
2 | import terser from '@rollup/plugin-terser';
3 | import json from '@rollup/plugin-json';
4 |
5 | // `npm run build` -> `production` is true
6 | // `npm run dev` -> `production` is false
7 | const production = !process.env.ROLLUP_WATCH;
8 |
9 | export default {
10 | input: 'src/main.js',
11 | output: {
12 | file: 'dist/bundle.js',
13 | format: 'iife',
14 | sourcemap: true,
15 | },
16 | plugins: [
17 | json(),
18 | resolve(), // tells Rollup how to find date-fns in node_modules
19 | production && terser(), // minify, but only in production
20 | ],
21 | };
22 |
--------------------------------------------------------------------------------
/src/dis-table-element.js:
--------------------------------------------------------------------------------
1 | import {LitElement, html, css} from 'lit';
2 |
3 | export class DisTable extends LitElement {
4 | static properties = {
5 | operations: {type: Array},
6 | activeLine: {type: Number},
7 | links: {type: Object},
8 | };
9 |
10 | static styles = css`
11 | .highlighted {
12 | background-color: #d2ffff;
13 | }
14 | `;
15 |
16 | constructor() {
17 | super();
18 | }
19 |
20 | render() {
21 | if (!this.operations || !this.operations.length) return;
22 |
23 | return html`
24 |
25 |
26 |
27 | Line number
28 | Offset
29 | Opcode name
30 | Opcode parameters
31 | Interpretation of parameters
32 |
33 |
34 |
35 | ${this.operations.map(
36 | (operation) => html` this.onMouseover(operation.lineNo)}
38 | class=${operation.lineNo == this.activeLine ? 'highlighted' : ''}>
39 | ${operation.lineNo}
40 | ${operation.offset}
41 |
42 | ${operation.opcode}
43 |
44 | ${operation.param}
45 | ${operation.paramD}
46 | `
47 | )}
48 |
49 |
50 | `;
51 | }
52 |
53 | onMouseover(lineNo) {
54 | this.activeLine = lineNo;
55 | this.dispatchEvent(new CustomEvent('line-highlight', {detail: {line: lineNo}}));
56 | }
57 | }
58 |
59 | customElements.define('dis-table-element', DisTable);
60 |
--------------------------------------------------------------------------------
/src/highlightable-editor.js:
--------------------------------------------------------------------------------
1 | import {basicSetup} from 'codemirror';
2 | import {EditorState, StateField, StateEffect} from '@codemirror/state';
3 | import {python} from '@codemirror/lang-python';
4 | import {EditorView, Decoration} from '@codemirror/view';
5 |
6 | const addLineHighlight = StateEffect.define();
7 |
8 | const lineHighlightField = StateField.define({
9 | create() {
10 | return Decoration.none;
11 | },
12 | update(lines, tr) {
13 | lines = lines.map(tr.changes);
14 | for (let e of tr.effects) {
15 | if (e.is(addLineHighlight)) {
16 | lines = Decoration.none;
17 | lines = lines.update({add: [lineHighlightMark.range(e.value)]});
18 | }
19 | }
20 | return lines;
21 | },
22 | provide: (f) => EditorView.decorations.from(f),
23 | });
24 |
25 | const lineHighlightMark = Decoration.line({
26 | attributes: {style: 'background-color: #d2ffff'},
27 | });
28 |
29 | export default class HighlightableEditor {
30 | constructor(parent, code, onHighlight) {
31 | this.editorView = new EditorView({
32 | state: EditorState.create({
33 | doc: code,
34 | extensions: [basicSetup, lineHighlightField, python()],
35 | }),
36 | parent: parent,
37 | });
38 |
39 | this.editorView.dom.addEventListener('mousemove', (event) => {
40 | const lastMove = {
41 | x: event.clientX,
42 | y: event.clientY,
43 | target: event.target,
44 | time: Date.now(),
45 | };
46 | const pos = this.editorView.posAtCoords(lastMove);
47 | let lineNo = this.editorView.state.doc.lineAt(pos).number;
48 | const docPosition = this.editorView.state.doc.line(lineNo).from;
49 | this.editorView.dispatch({effects: addLineHighlight.of(docPosition)});
50 | onHighlight(lineNo);
51 | });
52 | }
53 |
54 | getCode() {
55 | return this.editorView.state.doc.toString();
56 | }
57 |
58 | highlightLine(lineNo) {
59 | if (lineNo <= 0) return;
60 | const docPosition = this.editorView.state.doc.line(lineNo).from;
61 | this.editorView.dispatch({effects: addLineHighlight.of(docPosition)});
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/src/links.json:
--------------------------------------------------------------------------------
1 | {
2 | "3.9": {
3 | "NOP": "https://docs.python.org/3.9/library/dis.html#opcode-NOP",
4 | "POP_TOP": "https://docs.python.org/3.9/library/dis.html#opcode-POP_TOP",
5 | "ROT_TWO": "https://docs.python.org/3.9/library/dis.html#opcode-ROT_TWO",
6 | "ROT_THREE": "https://docs.python.org/3.9/library/dis.html#opcode-ROT_THREE",
7 | "ROT_FOUR": "https://docs.python.org/3.9/library/dis.html#opcode-ROT_FOUR",
8 | "DUP_TOP": "https://docs.python.org/3.9/library/dis.html#opcode-DUP_TOP",
9 | "DUP_TOP_TWO": "https://docs.python.org/3.9/library/dis.html#opcode-DUP_TOP_TWO",
10 | "UNARY_POSITIVE": "https://docs.python.org/3.9/library/dis.html#opcode-UNARY_POSITIVE",
11 | "UNARY_NEGATIVE": "https://docs.python.org/3.9/library/dis.html#opcode-UNARY_NEGATIVE",
12 | "UNARY_NOT": "https://docs.python.org/3.9/library/dis.html#opcode-UNARY_NOT",
13 | "UNARY_INVERT": "https://docs.python.org/3.9/library/dis.html#opcode-UNARY_INVERT",
14 | "GET_ITER": "https://docs.python.org/3.9/library/dis.html#opcode-GET_ITER",
15 | "GET_YIELD_FROM_ITER": "https://docs.python.org/3.9/library/dis.html#opcode-GET_YIELD_FROM_ITER",
16 | "BINARY_POWER": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_POWER",
17 | "BINARY_MULTIPLY": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_MULTIPLY",
18 | "BINARY_MATRIX_MULTIPLY": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_MATRIX_MULTIPLY",
19 | "BINARY_FLOOR_DIVIDE": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_FLOOR_DIVIDE",
20 | "BINARY_TRUE_DIVIDE": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_TRUE_DIVIDE",
21 | "BINARY_MODULO": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_MODULO",
22 | "BINARY_ADD": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_ADD",
23 | "BINARY_SUBTRACT": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_SUBTRACT",
24 | "BINARY_SUBSCR": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_SUBSCR",
25 | "BINARY_LSHIFT": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_LSHIFT",
26 | "BINARY_RSHIFT": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_RSHIFT",
27 | "BINARY_AND": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_AND",
28 | "BINARY_XOR": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_XOR",
29 | "BINARY_OR": "https://docs.python.org/3.9/library/dis.html#opcode-BINARY_OR",
30 | "INPLACE_POWER": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_POWER",
31 | "INPLACE_MULTIPLY": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_MULTIPLY",
32 | "INPLACE_MATRIX_MULTIPLY": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_MATRIX_MULTIPLY",
33 | "INPLACE_FLOOR_DIVIDE": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_FLOOR_DIVIDE",
34 | "INPLACE_TRUE_DIVIDE": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_TRUE_DIVIDE",
35 | "INPLACE_MODULO": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_MODULO",
36 | "INPLACE_ADD": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_ADD",
37 | "INPLACE_SUBTRACT": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_SUBTRACT",
38 | "INPLACE_LSHIFT": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_LSHIFT",
39 | "INPLACE_RSHIFT": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_RSHIFT",
40 | "INPLACE_AND": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_AND",
41 | "INPLACE_XOR": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_XOR",
42 | "INPLACE_OR": "https://docs.python.org/3.9/library/dis.html#opcode-INPLACE_OR",
43 | "STORE_SUBSCR": "https://docs.python.org/3.9/library/dis.html#opcode-STORE_SUBSCR",
44 | "DELETE_SUBSCR": "https://docs.python.org/3.9/library/dis.html#opcode-DELETE_SUBSCR",
45 | "GET_AWAITABLE": "https://docs.python.org/3.9/library/dis.html#opcode-GET_AWAITABLE",
46 | "GET_AITER": "https://docs.python.org/3.9/library/dis.html#opcode-GET_AITER",
47 | "GET_ANEXT": "https://docs.python.org/3.9/library/dis.html#opcode-GET_ANEXT",
48 | "END_ASYNC_FOR": "https://docs.python.org/3.9/library/dis.html#opcode-END_ASYNC_FOR",
49 | "BEFORE_ASYNC_WITH": "https://docs.python.org/3.9/library/dis.html#opcode-BEFORE_ASYNC_WITH",
50 | "SETUP_ASYNC_WITH": "https://docs.python.org/3.9/library/dis.html#opcode-SETUP_ASYNC_WITH",
51 | "PRINT_EXPR": "https://docs.python.org/3.9/library/dis.html#opcode-PRINT_EXPR",
52 | "SET_ADD": "https://docs.python.org/3.9/library/dis.html#opcode-SET_ADD",
53 | "LIST_APPEND": "https://docs.python.org/3.9/library/dis.html#opcode-LIST_APPEND",
54 | "MAP_ADD": "https://docs.python.org/3.9/library/dis.html#opcode-MAP_ADD",
55 | "RETURN_VALUE": "https://docs.python.org/3.9/library/dis.html#opcode-RETURN_VALUE",
56 | "YIELD_VALUE": "https://docs.python.org/3.9/library/dis.html#opcode-YIELD_VALUE",
57 | "YIELD_FROM": "https://docs.python.org/3.9/library/dis.html#opcode-YIELD_FROM",
58 | "SETUP_ANNOTATIONS": "https://docs.python.org/3.9/library/dis.html#opcode-SETUP_ANNOTATIONS",
59 | "IMPORT_STAR": "https://docs.python.org/3.9/library/dis.html#opcode-IMPORT_STAR",
60 | "POP_BLOCK": "https://docs.python.org/3.9/library/dis.html#opcode-POP_BLOCK",
61 | "POP_EXCEPT": "https://docs.python.org/3.9/library/dis.html#opcode-POP_EXCEPT",
62 | "RERAISE": "https://docs.python.org/3.9/library/dis.html#opcode-RERAISE",
63 | "WITH_EXCEPT_START": "https://docs.python.org/3.9/library/dis.html#opcode-WITH_EXCEPT_START",
64 | "LOAD_ASSERTION_ERROR": "https://docs.python.org/3.9/library/dis.html#opcode-LOAD_ASSERTION_ERROR",
65 | "LOAD_BUILD_CLASS": "https://docs.python.org/3.9/library/dis.html#opcode-LOAD_BUILD_CLASS",
66 | "SETUP_WITH": "https://docs.python.org/3.9/library/dis.html#opcode-SETUP_WITH",
67 | "STORE_NAME": "https://docs.python.org/3.9/library/dis.html#opcode-STORE_NAME",
68 | "DELETE_NAME": "https://docs.python.org/3.9/library/dis.html#opcode-DELETE_NAME",
69 | "UNPACK_SEQUENCE": "https://docs.python.org/3.9/library/dis.html#opcode-UNPACK_SEQUENCE",
70 | "UNPACK_EX": "https://docs.python.org/3.9/library/dis.html#opcode-UNPACK_EX",
71 | "STORE_ATTR": "https://docs.python.org/3.9/library/dis.html#opcode-STORE_ATTR",
72 | "DELETE_ATTR": "https://docs.python.org/3.9/library/dis.html#opcode-DELETE_ATTR",
73 | "STORE_GLOBAL": "https://docs.python.org/3.9/library/dis.html#opcode-STORE_GLOBAL",
74 | "DELETE_GLOBAL": "https://docs.python.org/3.9/library/dis.html#opcode-DELETE_GLOBAL",
75 | "LOAD_CONST": "https://docs.python.org/3.9/library/dis.html#opcode-LOAD_CONST",
76 | "LOAD_NAME": "https://docs.python.org/3.9/library/dis.html#opcode-LOAD_NAME",
77 | "BUILD_TUPLE": "https://docs.python.org/3.9/library/dis.html#opcode-BUILD_TUPLE",
78 | "BUILD_LIST": "https://docs.python.org/3.9/library/dis.html#opcode-BUILD_LIST",
79 | "BUILD_SET": "https://docs.python.org/3.9/library/dis.html#opcode-BUILD_SET",
80 | "BUILD_MAP": "https://docs.python.org/3.9/library/dis.html#opcode-BUILD_MAP",
81 | "BUILD_CONST_KEY_MAP": "https://docs.python.org/3.9/library/dis.html#opcode-BUILD_CONST_KEY_MAP",
82 | "BUILD_STRING": "https://docs.python.org/3.9/library/dis.html#opcode-BUILD_STRING",
83 | "LIST_TO_TUPLE": "https://docs.python.org/3.9/library/dis.html#opcode-LIST_TO_TUPLE",
84 | "LIST_EXTEND": "https://docs.python.org/3.9/library/dis.html#opcode-LIST_EXTEND",
85 | "SET_UPDATE": "https://docs.python.org/3.9/library/dis.html#opcode-SET_UPDATE",
86 | "DICT_UPDATE": "https://docs.python.org/3.9/library/dis.html#opcode-DICT_UPDATE",
87 | "DICT_MERGE": "https://docs.python.org/3.9/library/dis.html#opcode-DICT_MERGE",
88 | "LOAD_ATTR": "https://docs.python.org/3.9/library/dis.html#opcode-LOAD_ATTR",
89 | "COMPARE_OP": "https://docs.python.org/3.9/library/dis.html#opcode-COMPARE_OP",
90 | "IS_OP": "https://docs.python.org/3.9/library/dis.html#opcode-IS_OP",
91 | "CONTAINS_OP": "https://docs.python.org/3.9/library/dis.html#opcode-CONTAINS_OP",
92 | "IMPORT_NAME": "https://docs.python.org/3.9/library/dis.html#opcode-IMPORT_NAME",
93 | "IMPORT_FROM": "https://docs.python.org/3.9/library/dis.html#opcode-IMPORT_FROM",
94 | "JUMP_FORWARD": "https://docs.python.org/3.9/library/dis.html#opcode-JUMP_FORWARD",
95 | "POP_JUMP_IF_TRUE": "https://docs.python.org/3.9/library/dis.html#opcode-POP_JUMP_IF_TRUE",
96 | "POP_JUMP_IF_FALSE": "https://docs.python.org/3.9/library/dis.html#opcode-POP_JUMP_IF_FALSE",
97 | "JUMP_IF_NOT_EXC_MATCH": "https://docs.python.org/3.9/library/dis.html#opcode-JUMP_IF_NOT_EXC_MATCH",
98 | "JUMP_IF_TRUE_OR_POP": "https://docs.python.org/3.9/library/dis.html#opcode-JUMP_IF_TRUE_OR_POP",
99 | "JUMP_IF_FALSE_OR_POP": "https://docs.python.org/3.9/library/dis.html#opcode-JUMP_IF_FALSE_OR_POP",
100 | "JUMP_ABSOLUTE": "https://docs.python.org/3.9/library/dis.html#opcode-JUMP_ABSOLUTE",
101 | "FOR_ITER": "https://docs.python.org/3.9/library/dis.html#opcode-FOR_ITER",
102 | "LOAD_GLOBAL": "https://docs.python.org/3.9/library/dis.html#opcode-LOAD_GLOBAL",
103 | "SETUP_FINALLY": "https://docs.python.org/3.9/library/dis.html#opcode-SETUP_FINALLY",
104 | "LOAD_FAST": "https://docs.python.org/3.9/library/dis.html#opcode-LOAD_FAST",
105 | "STORE_FAST": "https://docs.python.org/3.9/library/dis.html#opcode-STORE_FAST",
106 | "DELETE_FAST": "https://docs.python.org/3.9/library/dis.html#opcode-DELETE_FAST",
107 | "LOAD_CLOSURE": "https://docs.python.org/3.9/library/dis.html#opcode-LOAD_CLOSURE",
108 | "LOAD_DEREF": "https://docs.python.org/3.9/library/dis.html#opcode-LOAD_DEREF",
109 | "LOAD_CLASSDEREF": "https://docs.python.org/3.9/library/dis.html#opcode-LOAD_CLASSDEREF",
110 | "STORE_DEREF": "https://docs.python.org/3.9/library/dis.html#opcode-STORE_DEREF",
111 | "DELETE_DEREF": "https://docs.python.org/3.9/library/dis.html#opcode-DELETE_DEREF",
112 | "RAISE_VARARGS": "https://docs.python.org/3.9/library/dis.html#opcode-RAISE_VARARGS",
113 | "CALL_FUNCTION": "https://docs.python.org/3.9/library/dis.html#opcode-CALL_FUNCTION",
114 | "CALL_FUNCTION_KW": "https://docs.python.org/3.9/library/dis.html#opcode-CALL_FUNCTION_KW",
115 | "CALL_FUNCTION_EX": "https://docs.python.org/3.9/library/dis.html#opcode-CALL_FUNCTION_EX",
116 | "LOAD_METHOD": "https://docs.python.org/3.9/library/dis.html#opcode-LOAD_METHOD",
117 | "CALL_METHOD": "https://docs.python.org/3.9/library/dis.html#opcode-CALL_METHOD",
118 | "MAKE_FUNCTION": "https://docs.python.org/3.9/library/dis.html#opcode-MAKE_FUNCTION",
119 | "BUILD_SLICE": "https://docs.python.org/3.9/library/dis.html#opcode-BUILD_SLICE",
120 | "EXTENDED_ARG": "https://docs.python.org/3.9/library/dis.html#opcode-EXTENDED_ARG",
121 | "FORMAT_VALUE": "https://docs.python.org/3.9/library/dis.html#opcode-FORMAT_VALUE",
122 | "HAVE_ARGUMENT": "https://docs.python.org/3.9/library/dis.html#opcode-HAVE_ARGUMENT"
123 | },
124 | "3.10": {
125 | "NOP": "https://docs.python.org/3.10/library/dis.html#opcode-NOP",
126 | "POP_TOP": "https://docs.python.org/3.10/library/dis.html#opcode-POP_TOP",
127 | "ROT_TWO": "https://docs.python.org/3.10/library/dis.html#opcode-ROT_TWO",
128 | "ROT_THREE": "https://docs.python.org/3.10/library/dis.html#opcode-ROT_THREE",
129 | "ROT_FOUR": "https://docs.python.org/3.10/library/dis.html#opcode-ROT_FOUR",
130 | "DUP_TOP": "https://docs.python.org/3.10/library/dis.html#opcode-DUP_TOP",
131 | "DUP_TOP_TWO": "https://docs.python.org/3.10/library/dis.html#opcode-DUP_TOP_TWO",
132 | "UNARY_POSITIVE": "https://docs.python.org/3.10/library/dis.html#opcode-UNARY_POSITIVE",
133 | "UNARY_NEGATIVE": "https://docs.python.org/3.10/library/dis.html#opcode-UNARY_NEGATIVE",
134 | "UNARY_NOT": "https://docs.python.org/3.10/library/dis.html#opcode-UNARY_NOT",
135 | "UNARY_INVERT": "https://docs.python.org/3.10/library/dis.html#opcode-UNARY_INVERT",
136 | "GET_ITER": "https://docs.python.org/3.10/library/dis.html#opcode-GET_ITER",
137 | "GET_YIELD_FROM_ITER": "https://docs.python.org/3.10/library/dis.html#opcode-GET_YIELD_FROM_ITER",
138 | "BINARY_POWER": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_POWER",
139 | "BINARY_MULTIPLY": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_MULTIPLY",
140 | "BINARY_MATRIX_MULTIPLY": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_MATRIX_MULTIPLY",
141 | "BINARY_FLOOR_DIVIDE": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_FLOOR_DIVIDE",
142 | "BINARY_TRUE_DIVIDE": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_TRUE_DIVIDE",
143 | "BINARY_MODULO": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_MODULO",
144 | "BINARY_ADD": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_ADD",
145 | "BINARY_SUBTRACT": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_SUBTRACT",
146 | "BINARY_SUBSCR": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_SUBSCR",
147 | "BINARY_LSHIFT": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_LSHIFT",
148 | "BINARY_RSHIFT": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_RSHIFT",
149 | "BINARY_AND": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_AND",
150 | "BINARY_XOR": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_XOR",
151 | "BINARY_OR": "https://docs.python.org/3.10/library/dis.html#opcode-BINARY_OR",
152 | "INPLACE_POWER": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_POWER",
153 | "INPLACE_MULTIPLY": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_MULTIPLY",
154 | "INPLACE_MATRIX_MULTIPLY": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_MATRIX_MULTIPLY",
155 | "INPLACE_FLOOR_DIVIDE": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_FLOOR_DIVIDE",
156 | "INPLACE_TRUE_DIVIDE": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_TRUE_DIVIDE",
157 | "INPLACE_MODULO": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_MODULO",
158 | "INPLACE_ADD": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_ADD",
159 | "INPLACE_SUBTRACT": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_SUBTRACT",
160 | "INPLACE_LSHIFT": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_LSHIFT",
161 | "INPLACE_RSHIFT": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_RSHIFT",
162 | "INPLACE_AND": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_AND",
163 | "INPLACE_XOR": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_XOR",
164 | "INPLACE_OR": "https://docs.python.org/3.10/library/dis.html#opcode-INPLACE_OR",
165 | "STORE_SUBSCR": "https://docs.python.org/3.10/library/dis.html#opcode-STORE_SUBSCR",
166 | "DELETE_SUBSCR": "https://docs.python.org/3.10/library/dis.html#opcode-DELETE_SUBSCR",
167 | "GET_AWAITABLE": "https://docs.python.org/3.10/library/dis.html#opcode-GET_AWAITABLE",
168 | "GET_AITER": "https://docs.python.org/3.10/library/dis.html#opcode-GET_AITER",
169 | "GET_ANEXT": "https://docs.python.org/3.10/library/dis.html#opcode-GET_ANEXT",
170 | "END_ASYNC_FOR": "https://docs.python.org/3.10/library/dis.html#opcode-END_ASYNC_FOR",
171 | "BEFORE_ASYNC_WITH": "https://docs.python.org/3.10/library/dis.html#opcode-BEFORE_ASYNC_WITH",
172 | "SETUP_ASYNC_WITH": "https://docs.python.org/3.10/library/dis.html#opcode-SETUP_ASYNC_WITH",
173 | "PRINT_EXPR": "https://docs.python.org/3.10/library/dis.html#opcode-PRINT_EXPR",
174 | "SET_ADD": "https://docs.python.org/3.10/library/dis.html#opcode-SET_ADD",
175 | "LIST_APPEND": "https://docs.python.org/3.10/library/dis.html#opcode-LIST_APPEND",
176 | "MAP_ADD": "https://docs.python.org/3.10/library/dis.html#opcode-MAP_ADD",
177 | "RETURN_VALUE": "https://docs.python.org/3.10/library/dis.html#opcode-RETURN_VALUE",
178 | "YIELD_VALUE": "https://docs.python.org/3.10/library/dis.html#opcode-YIELD_VALUE",
179 | "YIELD_FROM": "https://docs.python.org/3.10/library/dis.html#opcode-YIELD_FROM",
180 | "SETUP_ANNOTATIONS": "https://docs.python.org/3.10/library/dis.html#opcode-SETUP_ANNOTATIONS",
181 | "IMPORT_STAR": "https://docs.python.org/3.10/library/dis.html#opcode-IMPORT_STAR",
182 | "POP_BLOCK": "https://docs.python.org/3.10/library/dis.html#opcode-POP_BLOCK",
183 | "POP_EXCEPT": "https://docs.python.org/3.10/library/dis.html#opcode-POP_EXCEPT",
184 | "RERAISE": "https://docs.python.org/3.10/library/dis.html#opcode-RERAISE",
185 | "WITH_EXCEPT_START": "https://docs.python.org/3.10/library/dis.html#opcode-WITH_EXCEPT_START",
186 | "LOAD_ASSERTION_ERROR": "https://docs.python.org/3.10/library/dis.html#opcode-LOAD_ASSERTION_ERROR",
187 | "LOAD_BUILD_CLASS": "https://docs.python.org/3.10/library/dis.html#opcode-LOAD_BUILD_CLASS",
188 | "SETUP_WITH": "https://docs.python.org/3.10/library/dis.html#opcode-SETUP_WITH",
189 | "COPY_DICT_WITHOUT_KEYS": "https://docs.python.org/3.10/library/dis.html#opcode-COPY_DICT_WITHOUT_KEYS",
190 | "GET_LEN": "https://docs.python.org/3.10/library/dis.html#opcode-GET_LEN",
191 | "MATCH_MAPPING": "https://docs.python.org/3.10/library/dis.html#opcode-MATCH_MAPPING",
192 | "MATCH_SEQUENCE": "https://docs.python.org/3.10/library/dis.html#opcode-MATCH_SEQUENCE",
193 | "MATCH_KEYS": "https://docs.python.org/3.10/library/dis.html#opcode-MATCH_KEYS",
194 | "STORE_NAME": "https://docs.python.org/3.10/library/dis.html#opcode-STORE_NAME",
195 | "DELETE_NAME": "https://docs.python.org/3.10/library/dis.html#opcode-DELETE_NAME",
196 | "UNPACK_SEQUENCE": "https://docs.python.org/3.10/library/dis.html#opcode-UNPACK_SEQUENCE",
197 | "UNPACK_EX": "https://docs.python.org/3.10/library/dis.html#opcode-UNPACK_EX",
198 | "STORE_ATTR": "https://docs.python.org/3.10/library/dis.html#opcode-STORE_ATTR",
199 | "DELETE_ATTR": "https://docs.python.org/3.10/library/dis.html#opcode-DELETE_ATTR",
200 | "STORE_GLOBAL": "https://docs.python.org/3.10/library/dis.html#opcode-STORE_GLOBAL",
201 | "DELETE_GLOBAL": "https://docs.python.org/3.10/library/dis.html#opcode-DELETE_GLOBAL",
202 | "LOAD_CONST": "https://docs.python.org/3.10/library/dis.html#opcode-LOAD_CONST",
203 | "LOAD_NAME": "https://docs.python.org/3.10/library/dis.html#opcode-LOAD_NAME",
204 | "BUILD_TUPLE": "https://docs.python.org/3.10/library/dis.html#opcode-BUILD_TUPLE",
205 | "BUILD_LIST": "https://docs.python.org/3.10/library/dis.html#opcode-BUILD_LIST",
206 | "BUILD_SET": "https://docs.python.org/3.10/library/dis.html#opcode-BUILD_SET",
207 | "BUILD_MAP": "https://docs.python.org/3.10/library/dis.html#opcode-BUILD_MAP",
208 | "BUILD_CONST_KEY_MAP": "https://docs.python.org/3.10/library/dis.html#opcode-BUILD_CONST_KEY_MAP",
209 | "BUILD_STRING": "https://docs.python.org/3.10/library/dis.html#opcode-BUILD_STRING",
210 | "LIST_TO_TUPLE": "https://docs.python.org/3.10/library/dis.html#opcode-LIST_TO_TUPLE",
211 | "LIST_EXTEND": "https://docs.python.org/3.10/library/dis.html#opcode-LIST_EXTEND",
212 | "SET_UPDATE": "https://docs.python.org/3.10/library/dis.html#opcode-SET_UPDATE",
213 | "DICT_UPDATE": "https://docs.python.org/3.10/library/dis.html#opcode-DICT_UPDATE",
214 | "DICT_MERGE": "https://docs.python.org/3.10/library/dis.html#opcode-DICT_MERGE",
215 | "LOAD_ATTR": "https://docs.python.org/3.10/library/dis.html#opcode-LOAD_ATTR",
216 | "COMPARE_OP": "https://docs.python.org/3.10/library/dis.html#opcode-COMPARE_OP",
217 | "IS_OP": "https://docs.python.org/3.10/library/dis.html#opcode-IS_OP",
218 | "CONTAINS_OP": "https://docs.python.org/3.10/library/dis.html#opcode-CONTAINS_OP",
219 | "IMPORT_NAME": "https://docs.python.org/3.10/library/dis.html#opcode-IMPORT_NAME",
220 | "IMPORT_FROM": "https://docs.python.org/3.10/library/dis.html#opcode-IMPORT_FROM",
221 | "JUMP_FORWARD": "https://docs.python.org/3.10/library/dis.html#opcode-JUMP_FORWARD",
222 | "POP_JUMP_IF_TRUE": "https://docs.python.org/3.10/library/dis.html#opcode-POP_JUMP_IF_TRUE",
223 | "POP_JUMP_IF_FALSE": "https://docs.python.org/3.10/library/dis.html#opcode-POP_JUMP_IF_FALSE",
224 | "JUMP_IF_NOT_EXC_MATCH": "https://docs.python.org/3.10/library/dis.html#opcode-JUMP_IF_NOT_EXC_MATCH",
225 | "JUMP_IF_TRUE_OR_POP": "https://docs.python.org/3.10/library/dis.html#opcode-JUMP_IF_TRUE_OR_POP",
226 | "JUMP_IF_FALSE_OR_POP": "https://docs.python.org/3.10/library/dis.html#opcode-JUMP_IF_FALSE_OR_POP",
227 | "JUMP_ABSOLUTE": "https://docs.python.org/3.10/library/dis.html#opcode-JUMP_ABSOLUTE",
228 | "FOR_ITER": "https://docs.python.org/3.10/library/dis.html#opcode-FOR_ITER",
229 | "LOAD_GLOBAL": "https://docs.python.org/3.10/library/dis.html#opcode-LOAD_GLOBAL",
230 | "SETUP_FINALLY": "https://docs.python.org/3.10/library/dis.html#opcode-SETUP_FINALLY",
231 | "LOAD_FAST": "https://docs.python.org/3.10/library/dis.html#opcode-LOAD_FAST",
232 | "STORE_FAST": "https://docs.python.org/3.10/library/dis.html#opcode-STORE_FAST",
233 | "DELETE_FAST": "https://docs.python.org/3.10/library/dis.html#opcode-DELETE_FAST",
234 | "LOAD_CLOSURE": "https://docs.python.org/3.10/library/dis.html#opcode-LOAD_CLOSURE",
235 | "LOAD_DEREF": "https://docs.python.org/3.10/library/dis.html#opcode-LOAD_DEREF",
236 | "LOAD_CLASSDEREF": "https://docs.python.org/3.10/library/dis.html#opcode-LOAD_CLASSDEREF",
237 | "STORE_DEREF": "https://docs.python.org/3.10/library/dis.html#opcode-STORE_DEREF",
238 | "DELETE_DEREF": "https://docs.python.org/3.10/library/dis.html#opcode-DELETE_DEREF",
239 | "RAISE_VARARGS": "https://docs.python.org/3.10/library/dis.html#opcode-RAISE_VARARGS",
240 | "CALL_FUNCTION": "https://docs.python.org/3.10/library/dis.html#opcode-CALL_FUNCTION",
241 | "CALL_FUNCTION_KW": "https://docs.python.org/3.10/library/dis.html#opcode-CALL_FUNCTION_KW",
242 | "CALL_FUNCTION_EX": "https://docs.python.org/3.10/library/dis.html#opcode-CALL_FUNCTION_EX",
243 | "LOAD_METHOD": "https://docs.python.org/3.10/library/dis.html#opcode-LOAD_METHOD",
244 | "CALL_METHOD": "https://docs.python.org/3.10/library/dis.html#opcode-CALL_METHOD",
245 | "MAKE_FUNCTION": "https://docs.python.org/3.10/library/dis.html#opcode-MAKE_FUNCTION",
246 | "BUILD_SLICE": "https://docs.python.org/3.10/library/dis.html#opcode-BUILD_SLICE",
247 | "EXTENDED_ARG": "https://docs.python.org/3.10/library/dis.html#opcode-EXTENDED_ARG",
248 | "FORMAT_VALUE": "https://docs.python.org/3.10/library/dis.html#opcode-FORMAT_VALUE",
249 | "MATCH_CLASS": "https://docs.python.org/3.10/library/dis.html#opcode-MATCH_CLASS",
250 | "GEN_START": "https://docs.python.org/3.10/library/dis.html#opcode-GEN_START",
251 | "ROT_N": "https://docs.python.org/3.10/library/dis.html#opcode-ROT_N",
252 | "HAVE_ARGUMENT": "https://docs.python.org/3.10/library/dis.html#opcode-HAVE_ARGUMENT"
253 | },
254 | "3.11": {
255 | "NOP": "https://docs.python.org/3.11/library/dis.html#opcode-NOP",
256 | "POP_TOP": "https://docs.python.org/3.11/library/dis.html#opcode-POP_TOP",
257 | "COPY": "https://docs.python.org/3.11/library/dis.html#opcode-COPY",
258 | "SWAP": "https://docs.python.org/3.11/library/dis.html#opcode-SWAP",
259 | "CACHE": "https://docs.python.org/3.11/library/dis.html#opcode-CACHE",
260 | "UNARY_POSITIVE": "https://docs.python.org/3.11/library/dis.html#opcode-UNARY_POSITIVE",
261 | "UNARY_NEGATIVE": "https://docs.python.org/3.11/library/dis.html#opcode-UNARY_NEGATIVE",
262 | "UNARY_NOT": "https://docs.python.org/3.11/library/dis.html#opcode-UNARY_NOT",
263 | "UNARY_INVERT": "https://docs.python.org/3.11/library/dis.html#opcode-UNARY_INVERT",
264 | "GET_ITER": "https://docs.python.org/3.11/library/dis.html#opcode-GET_ITER",
265 | "GET_YIELD_FROM_ITER": "https://docs.python.org/3.11/library/dis.html#opcode-GET_YIELD_FROM_ITER",
266 | "BINARY_OP": "https://docs.python.org/3.11/library/dis.html#opcode-BINARY_OP",
267 | "BINARY_SUBSCR": "https://docs.python.org/3.11/library/dis.html#opcode-BINARY_SUBSCR",
268 | "STORE_SUBSCR": "https://docs.python.org/3.11/library/dis.html#opcode-STORE_SUBSCR",
269 | "DELETE_SUBSCR": "https://docs.python.org/3.11/library/dis.html#opcode-DELETE_SUBSCR",
270 | "GET_AWAITABLE": "https://docs.python.org/3.11/library/dis.html#opcode-GET_AWAITABLE",
271 | "GET_AITER": "https://docs.python.org/3.11/library/dis.html#opcode-GET_AITER",
272 | "GET_ANEXT": "https://docs.python.org/3.11/library/dis.html#opcode-GET_ANEXT",
273 | "END_ASYNC_FOR": "https://docs.python.org/3.11/library/dis.html#opcode-END_ASYNC_FOR",
274 | "BEFORE_ASYNC_WITH": "https://docs.python.org/3.11/library/dis.html#opcode-BEFORE_ASYNC_WITH",
275 | "PRINT_EXPR": "https://docs.python.org/3.11/library/dis.html#opcode-PRINT_EXPR",
276 | "SET_ADD": "https://docs.python.org/3.11/library/dis.html#opcode-SET_ADD",
277 | "LIST_APPEND": "https://docs.python.org/3.11/library/dis.html#opcode-LIST_APPEND",
278 | "MAP_ADD": "https://docs.python.org/3.11/library/dis.html#opcode-MAP_ADD",
279 | "RETURN_VALUE": "https://docs.python.org/3.11/library/dis.html#opcode-RETURN_VALUE",
280 | "YIELD_VALUE": "https://docs.python.org/3.11/library/dis.html#opcode-YIELD_VALUE",
281 | "SETUP_ANNOTATIONS": "https://docs.python.org/3.11/library/dis.html#opcode-SETUP_ANNOTATIONS",
282 | "IMPORT_STAR": "https://docs.python.org/3.11/library/dis.html#opcode-IMPORT_STAR",
283 | "POP_EXCEPT": "https://docs.python.org/3.11/library/dis.html#opcode-POP_EXCEPT",
284 | "RERAISE": "https://docs.python.org/3.11/library/dis.html#opcode-RERAISE",
285 | "PUSH_EXC_INFO": "https://docs.python.org/3.11/library/dis.html#opcode-PUSH_EXC_INFO",
286 | "CHECK_EXC_MATCH": "https://docs.python.org/3.11/library/dis.html#opcode-CHECK_EXC_MATCH",
287 | "CHECK_EG_MATCH": "https://docs.python.org/3.11/library/dis.html#opcode-CHECK_EG_MATCH",
288 | "PREP_RERAISE_STAR": "https://docs.python.org/3.11/library/dis.html#opcode-PREP_RERAISE_STAR",
289 | "WITH_EXCEPT_START": "https://docs.python.org/3.11/library/dis.html#opcode-WITH_EXCEPT_START",
290 | "LOAD_ASSERTION_ERROR": "https://docs.python.org/3.11/library/dis.html#opcode-LOAD_ASSERTION_ERROR",
291 | "LOAD_BUILD_CLASS": "https://docs.python.org/3.11/library/dis.html#opcode-LOAD_BUILD_CLASS",
292 | "BEFORE_WITH": "https://docs.python.org/3.11/library/dis.html#opcode-BEFORE_WITH",
293 | "GET_LEN": "https://docs.python.org/3.11/library/dis.html#opcode-GET_LEN",
294 | "MATCH_MAPPING": "https://docs.python.org/3.11/library/dis.html#opcode-MATCH_MAPPING",
295 | "MATCH_SEQUENCE": "https://docs.python.org/3.11/library/dis.html#opcode-MATCH_SEQUENCE",
296 | "MATCH_KEYS": "https://docs.python.org/3.11/library/dis.html#opcode-MATCH_KEYS",
297 | "STORE_NAME": "https://docs.python.org/3.11/library/dis.html#opcode-STORE_NAME",
298 | "DELETE_NAME": "https://docs.python.org/3.11/library/dis.html#opcode-DELETE_NAME",
299 | "UNPACK_SEQUENCE": "https://docs.python.org/3.11/library/dis.html#opcode-UNPACK_SEQUENCE",
300 | "UNPACK_EX": "https://docs.python.org/3.11/library/dis.html#opcode-UNPACK_EX",
301 | "STORE_ATTR": "https://docs.python.org/3.11/library/dis.html#opcode-STORE_ATTR",
302 | "DELETE_ATTR": "https://docs.python.org/3.11/library/dis.html#opcode-DELETE_ATTR",
303 | "STORE_GLOBAL": "https://docs.python.org/3.11/library/dis.html#opcode-STORE_GLOBAL",
304 | "DELETE_GLOBAL": "https://docs.python.org/3.11/library/dis.html#opcode-DELETE_GLOBAL",
305 | "LOAD_CONST": "https://docs.python.org/3.11/library/dis.html#opcode-LOAD_CONST",
306 | "LOAD_NAME": "https://docs.python.org/3.11/library/dis.html#opcode-LOAD_NAME",
307 | "BUILD_TUPLE": "https://docs.python.org/3.11/library/dis.html#opcode-BUILD_TUPLE",
308 | "BUILD_LIST": "https://docs.python.org/3.11/library/dis.html#opcode-BUILD_LIST",
309 | "BUILD_SET": "https://docs.python.org/3.11/library/dis.html#opcode-BUILD_SET",
310 | "BUILD_MAP": "https://docs.python.org/3.11/library/dis.html#opcode-BUILD_MAP",
311 | "BUILD_CONST_KEY_MAP": "https://docs.python.org/3.11/library/dis.html#opcode-BUILD_CONST_KEY_MAP",
312 | "BUILD_STRING": "https://docs.python.org/3.11/library/dis.html#opcode-BUILD_STRING",
313 | "LIST_TO_TUPLE": "https://docs.python.org/3.11/library/dis.html#opcode-LIST_TO_TUPLE",
314 | "LIST_EXTEND": "https://docs.python.org/3.11/library/dis.html#opcode-LIST_EXTEND",
315 | "SET_UPDATE": "https://docs.python.org/3.11/library/dis.html#opcode-SET_UPDATE",
316 | "DICT_UPDATE": "https://docs.python.org/3.11/library/dis.html#opcode-DICT_UPDATE",
317 | "DICT_MERGE": "https://docs.python.org/3.11/library/dis.html#opcode-DICT_MERGE",
318 | "LOAD_ATTR": "https://docs.python.org/3.11/library/dis.html#opcode-LOAD_ATTR",
319 | "COMPARE_OP": "https://docs.python.org/3.11/library/dis.html#opcode-COMPARE_OP",
320 | "IS_OP": "https://docs.python.org/3.11/library/dis.html#opcode-IS_OP",
321 | "CONTAINS_OP": "https://docs.python.org/3.11/library/dis.html#opcode-CONTAINS_OP",
322 | "IMPORT_NAME": "https://docs.python.org/3.11/library/dis.html#opcode-IMPORT_NAME",
323 | "IMPORT_FROM": "https://docs.python.org/3.11/library/dis.html#opcode-IMPORT_FROM",
324 | "JUMP_FORWARD": "https://docs.python.org/3.11/library/dis.html#opcode-JUMP_FORWARD",
325 | "JUMP_BACKWARD": "https://docs.python.org/3.11/library/dis.html#opcode-JUMP_BACKWARD",
326 | "JUMP_BACKWARD_NO_INTERRUPT": "https://docs.python.org/3.11/library/dis.html#opcode-JUMP_BACKWARD_NO_INTERRUPT",
327 | "POP_JUMP_FORWARD_IF_TRUE": "https://docs.python.org/3.11/library/dis.html#opcode-POP_JUMP_FORWARD_IF_TRUE",
328 | "POP_JUMP_BACKWARD_IF_TRUE": "https://docs.python.org/3.11/library/dis.html#opcode-POP_JUMP_BACKWARD_IF_TRUE",
329 | "POP_JUMP_FORWARD_IF_FALSE": "https://docs.python.org/3.11/library/dis.html#opcode-POP_JUMP_FORWARD_IF_FALSE",
330 | "POP_JUMP_BACKWARD_IF_FALSE": "https://docs.python.org/3.11/library/dis.html#opcode-POP_JUMP_BACKWARD_IF_FALSE",
331 | "POP_JUMP_FORWARD_IF_NOT_NONE": "https://docs.python.org/3.11/library/dis.html#opcode-POP_JUMP_FORWARD_IF_NOT_NONE",
332 | "POP_JUMP_BACKWARD_IF_NOT_NONE": "https://docs.python.org/3.11/library/dis.html#opcode-POP_JUMP_BACKWARD_IF_NOT_NONE",
333 | "POP_JUMP_FORWARD_IF_NONE": "https://docs.python.org/3.11/library/dis.html#opcode-POP_JUMP_FORWARD_IF_NONE",
334 | "POP_JUMP_BACKWARD_IF_NONE": "https://docs.python.org/3.11/library/dis.html#opcode-POP_JUMP_BACKWARD_IF_NONE",
335 | "JUMP_IF_TRUE_OR_POP": "https://docs.python.org/3.11/library/dis.html#opcode-JUMP_IF_TRUE_OR_POP",
336 | "JUMP_IF_FALSE_OR_POP": "https://docs.python.org/3.11/library/dis.html#opcode-JUMP_IF_FALSE_OR_POP",
337 | "FOR_ITER": "https://docs.python.org/3.11/library/dis.html#opcode-FOR_ITER",
338 | "LOAD_GLOBAL": "https://docs.python.org/3.11/library/dis.html#opcode-LOAD_GLOBAL",
339 | "LOAD_FAST": "https://docs.python.org/3.11/library/dis.html#opcode-LOAD_FAST",
340 | "STORE_FAST": "https://docs.python.org/3.11/library/dis.html#opcode-STORE_FAST",
341 | "DELETE_FAST": "https://docs.python.org/3.11/library/dis.html#opcode-DELETE_FAST",
342 | "MAKE_CELL": "https://docs.python.org/3.11/library/dis.html#opcode-MAKE_CELL",
343 | "LOAD_CLOSURE": "https://docs.python.org/3.11/library/dis.html#opcode-LOAD_CLOSURE",
344 | "LOAD_DEREF": "https://docs.python.org/3.11/library/dis.html#opcode-LOAD_DEREF",
345 | "LOAD_CLASSDEREF": "https://docs.python.org/3.11/library/dis.html#opcode-LOAD_CLASSDEREF",
346 | "STORE_DEREF": "https://docs.python.org/3.11/library/dis.html#opcode-STORE_DEREF",
347 | "DELETE_DEREF": "https://docs.python.org/3.11/library/dis.html#opcode-DELETE_DEREF",
348 | "COPY_FREE_VARS": "https://docs.python.org/3.11/library/dis.html#opcode-COPY_FREE_VARS",
349 | "RAISE_VARARGS": "https://docs.python.org/3.11/library/dis.html#opcode-RAISE_VARARGS",
350 | "CALL": "https://docs.python.org/3.11/library/dis.html#opcode-CALL",
351 | "CALL_FUNCTION_EX": "https://docs.python.org/3.11/library/dis.html#opcode-CALL_FUNCTION_EX",
352 | "LOAD_METHOD": "https://docs.python.org/3.11/library/dis.html#opcode-LOAD_METHOD",
353 | "PRECALL": "https://docs.python.org/3.11/library/dis.html#opcode-PRECALL",
354 | "PUSH_NULL": "https://docs.python.org/3.11/library/dis.html#opcode-PUSH_NULL",
355 | "KW_NAMES": "https://docs.python.org/3.11/library/dis.html#opcode-KW_NAMES",
356 | "MAKE_FUNCTION": "https://docs.python.org/3.11/library/dis.html#opcode-MAKE_FUNCTION",
357 | "BUILD_SLICE": "https://docs.python.org/3.11/library/dis.html#opcode-BUILD_SLICE",
358 | "EXTENDED_ARG": "https://docs.python.org/3.11/library/dis.html#opcode-EXTENDED_ARG",
359 | "FORMAT_VALUE": "https://docs.python.org/3.11/library/dis.html#opcode-FORMAT_VALUE",
360 | "MATCH_CLASS": "https://docs.python.org/3.11/library/dis.html#opcode-MATCH_CLASS",
361 | "RESUME": "https://docs.python.org/3.11/library/dis.html#opcode-RESUME",
362 | "RETURN_GENERATOR": "https://docs.python.org/3.11/library/dis.html#opcode-RETURN_GENERATOR",
363 | "SEND": "https://docs.python.org/3.11/library/dis.html#opcode-SEND",
364 | "ASYNC_GEN_WRAP": "https://docs.python.org/3.11/library/dis.html#opcode-ASYNC_GEN_WRAP",
365 | "HAVE_ARGUMENT": "https://docs.python.org/3.11/library/dis.html#opcode-HAVE_ARGUMENT",
366 | "NB_ADD": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L872",
367 | "NB_AND": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L873",
368 | "NB_FLOOR_DIVIDE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L874",
369 | "NB_LSHIFT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L875",
370 | "NB_MATRIX_MULTIPLY": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L876",
371 | "NB_MULTIPLY": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L877",
372 | "NB_REMAINDER": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L878",
373 | "NB_OR": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L879",
374 | "NB_POWER": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L880",
375 | "NB_RSHIFT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L881",
376 | "NB_SUBTRACT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L882",
377 | "NB_TRUE_DIVIDE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L883",
378 | "NB_XOR": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L884",
379 | "NB_INPLACE_ADD": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L885",
380 | "NB_INPLACE_AND": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L886",
381 | "NB_INPLACE_FLOOR_DIVIDE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L887",
382 | "NB_INPLACE_LSHIFT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L888",
383 | "NB_INPLACE_MATRIX_MULTIPLY": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L889",
384 | "NB_INPLACE_MULTIPLY": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L890",
385 | "NB_INPLACE_REMAINDER": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L891",
386 | "NB_INPLACE_OR": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L892",
387 | "NB_INPLACE_POWER": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L893",
388 | "NB_INPLACE_RSHIFT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L894",
389 | "NB_INPLACE_SUBTRACT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L895",
390 | "NB_INPLACE_TRUE_DIVIDE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L896",
391 | "NB_INPLACE_XOR": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L897",
392 | "RESUME_QUICK": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L1780",
393 | "LOAD_FAST__LOAD_FAST": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L1826",
394 | "LOAD_FAST__LOAD_CONST": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L1844",
395 | "STORE_FAST__LOAD_FAST": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L1859",
396 | "STORE_FAST__STORE_FAST": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L1873",
397 | "LOAD_CONST__LOAD_FAST": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L1883",
398 | "BINARY_OP_MULTIPLY_INT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L1958",
399 | "BINARY_OP_MULTIPLY_FLOAT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L1977",
400 | "BINARY_OP_SUBTRACT_INT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L1998",
401 | "BINARY_OP_SUBTRACT_FLOAT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2017",
402 | "BINARY_OP_ADD_UNICODE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2037",
403 | "BINARY_OP_INPLACE_ADD_UNICODE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2056",
404 | "BINARY_OP_ADD_FLOAT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2092",
405 | "BINARY_OP_ADD_INT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2113",
406 | "BINARY_SUBSCR_ADAPTIVE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2146",
407 | "BINARY_SUBSCR_LIST_INT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2165",
408 | "BINARY_SUBSCR_TUPLE_INT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2190",
409 | "BINARY_SUBSCR_DICT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2215",
410 | "BINARY_SUBSCR_GETITEM": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2234",
411 | "STORE_SUBSCR_ADAPTIVE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2312",
412 | "STORE_SUBSCR_LIST_INT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2331",
413 | "STORE_SUBSCR_DICT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2357",
414 | "UNPACK_SEQUENCE_ADAPTIVE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2808",
415 | "UNPACK_SEQUENCE_TWO_TUPLE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2824",
416 | "UNPACK_SEQUENCE_TUPLE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2836",
417 | "UNPACK_SEQUENCE_LIST": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L2851",
418 | "LOAD_GLOBAL_ADAPTIVE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3049",
419 | "LOAD_GLOBAL_MODULE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3068",
420 | "LOAD_GLOBAL_BUILTIN": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3089",
421 | "LOAD_ATTR_ADAPTIVE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3474",
422 | "LOAD_ATTR_INSTANCE_VALUE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3494",
423 | "LOAD_ATTR_MODULE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3517",
424 | "LOAD_ATTR_WITH_HINT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3529",
425 | "LOAD_ATTR_SLOT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3564",
426 | "STORE_ATTR_ADAPTIVE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3584",
427 | "STORE_ATTR_INSTANCE_VALUE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3604",
428 | "STORE_ATTR_WITH_HINT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3632",
429 | "STORE_ATTR_SLOT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3679",
430 | "COMPARE_OP_ADAPTIVE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3715",
431 | "COMPARE_OP_FLOAT_JUMP": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3732",
432 | "COMPARE_OP_INT_JUMP": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3774",
433 | "COMPARE_OP_STR_JUMP": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L3817",
434 | "JUMP_BACKWARD_QUICK": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4205",
435 | "LOAD_METHOD_ADAPTIVE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4522",
436 | "LOAD_METHOD_WITH_VALUES": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4542",
437 | "LOAD_METHOD_WITH_DICT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4568",
438 | "LOAD_METHOD_NO_DICT": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4600",
439 | "LOAD_METHOD_MODULE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4619",
440 | "LOAD_METHOD_CLASS": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4632",
441 | "PRECALL_BOUND_METHOD": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4701",
442 | "PRECALL_PYFUNC": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4717",
443 | "PRECALL_ADAPTIVE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4795",
444 | "CALL_ADAPTIVE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4817",
445 | "CALL_PY_EXACT_ARGS": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4839",
446 | "CALL_PY_WITH_DEFAULTS": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4873",
447 | "PRECALL_NO_KW_TYPE_1": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4915",
448 | "PRECALL_NO_KW_STR_1": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4933",
449 | "PRECALL_NO_KW_TUPLE_1": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4955",
450 | "PRECALL_BUILTIN_CLASS": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L4976",
451 | "PRECALL_NO_KW_BUILTIN_O": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L5004",
452 | "PRECALL_NO_KW_BUILTIN_FAST": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L5038",
453 | "PRECALL_BUILTIN_FAST_WITH_KEYWORDS": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L5078",
454 | "PRECALL_NO_KW_LEN": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L5117",
455 | "PRECALL_NO_KW_ISINSTANCE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L5147",
456 | "PRECALL_NO_KW_LIST_APPEND": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L5180",
457 | "PRECALL_NO_KW_METHOD_DESCRIPTOR_O": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L5203",
458 | "PRECALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L5239",
459 | "PRECALL_NO_KW_METHOD_DESCRIPTOR_NOARGS": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L5276",
460 | "PRECALL_NO_KW_METHOD_DESCRIPTOR_FAST": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L5310",
461 | "BINARY_OP_ADAPTIVE": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L5562",
462 | "EXTENDED_ARG_QUICK": "https://github.com/python/cpython/blob/v3.11.1/Python/ceval.c#L5604"
463 | }
464 | }
465 |
--------------------------------------------------------------------------------
/src/main.js:
--------------------------------------------------------------------------------
1 | import './dis-table-element.js';
2 | import './permalink-element.js';
3 | import HighlightableEditor from './highlightable-editor.js';
4 | import opcodeLinks from './links.json';
5 |
6 | async function main() {
7 | let pyodide,
8 | editor,
9 | ops = [],
10 | disTable,
11 | callMode = false,
12 | permalink,
13 | pythonVersion;
14 | const codeDiv = document.getElementById('code-area');
15 | const button = document.getElementById('button');
16 | const statusDiv = document.getElementById('status');
17 | const tableDiv = document.getElementById('table-area');
18 | const permalinkDiv = document.getElementById('permalink-area');
19 | const errorDiv = document.getElementById('error-area');
20 | const outputDiv = document.getElementById('output-area');
21 |
22 | function disassembleCode() {
23 | statusDiv.innerText = 'Disassembling...';
24 | const code = editor.getCode();
25 | const functionCall = document.getElementById('call-input').value;
26 | const functionName = functionCall.split('(')[0];
27 | ops = [];
28 | const enableAdaptive = document.getElementById('adaptive-checkbox').checked ? 'True' : 'False';
29 | // Support the old way of disassembling a sequence of statements
30 | if (!functionCall) {
31 | callMode = false;
32 | pyodide.runPython(`import dis; dis.dis('''${code}''');`);
33 | } else {
34 | callMode = true;
35 | try {
36 | let disLine = `dis.dis(${functionName})`;
37 | if (enableAdaptive === 'True') {
38 | disLine = `dis.dis(${functionName}, adaptive=${enableAdaptive}, show_caches=False)`;
39 | }
40 |
41 | pyodide.runPython(`
42 | import sys, dis
43 | print(sys.version)
44 | ${code}
45 | for _ in range(10):
46 | ${functionCall}
47 | ${disLine}
48 | `);
49 | } catch (e) {
50 | statusDiv.innerText = '';
51 | errorDiv.style.display = 'block';
52 | outputDiv.style.display = 'none';
53 | errorDiv.innerText = e;
54 | return;
55 | }
56 | }
57 | statusDiv.innerText = '';
58 | errorDiv.style.display = 'none';
59 | outputDiv.style.display = 'block';
60 | disTable.setAttribute('operations', JSON.stringify(ops));
61 | permalink.setAttribute('code', code);
62 | permalink.setAttribute('call', functionCall);
63 | permalink.setAttribute('adaptive', enableAdaptive);
64 | permalink.setAttribute('version', pythonVersion);
65 | }
66 |
67 | function handleStdOut(output) {
68 | if (output.startsWith('3.')) {
69 | // Python version
70 | document.getElementById('version-number').innerText = output.split(' ')[0];
71 | return;
72 | }
73 | const matches = output.match(/\s*(\d+)?\s+(\d+)\s+([A-Z_]+)\s*(\d+)?\s*(\([^\)]+\))?/);
74 | if (!matches) {
75 | return;
76 | }
77 | let lineNo;
78 | if (typeof matches[1] !== 'undefined') {
79 | // Some instructions start with a line number
80 | lineNo = parseInt(matches[1], 10) - (callMode ? 3 : 0);
81 | } else {
82 | // If not, assume line number is same as most recent line number
83 | lineNo = ops[ops.length - 1].lineNo;
84 | }
85 | const offset = matches[2];
86 | const opcode = matches[3];
87 | const param = matches[4] || '';
88 | const paramD = matches[5] || '';
89 | ops.push({lineNo, offset, opcode, param, paramD});
90 | }
91 |
92 | async function loadPyodideScript() {
93 | const versionMap = {
94 | 3.11: 'dev',
95 | '3.10': 'v0.22.1',
96 | 3.9: 'v0.19.1',
97 | };
98 | if (pythonVersion !== '3.11') {
99 | document.getElementById('adaptive-area').style.display = 'none';
100 | }
101 | const pyodideVersion = versionMap[pythonVersion];
102 | const scriptUrl = `https://cdn.jsdelivr.net/pyodide/${pyodideVersion}/full/pyodide.js`;
103 |
104 | const script = document.createElement('script');
105 | script.src = scriptUrl;
106 | script.onload = async () => {
107 | pyodide = await loadPyodide({
108 | indexURL: `https://cdn.jsdelivr.net/pyodide/${pyodideVersion}/full/`,
109 | stdout: handleStdOut,
110 | });
111 | statusDiv.innerText = '';
112 | button.removeAttribute('disabled');
113 | button.addEventListener('click', disassembleCode);
114 | code && disassembleCode();
115 | };
116 | document.head.appendChild(script);
117 | }
118 |
119 | let code = new URLSearchParams(window.location.search).get('code');
120 | let call = new URLSearchParams(window.location.search).get('call');
121 | if (!code) {
122 | code = `def feet_to_meters(feet):
123 | result = 0.3048 * feet
124 | return result`;
125 | call = 'feet_to_meters(10)';
126 | }
127 | pythonVersion = new URLSearchParams(window.location.search).get('version') || '3.11';
128 | document.getElementById('version-select').value = pythonVersion;
129 | let adaptive = new URLSearchParams(window.location.search).get('adaptive');
130 | document.getElementById('adaptive-checkbox').checked = pythonVersion == '3.11' && adaptive === 'True';
131 |
132 | editor = new HighlightableEditor(codeDiv, code, (lineNo) => {
133 | disTable.setAttribute('activeLine', lineNo);
134 | });
135 | document.getElementById('call-input').value = call;
136 | disTable = document.createElement('dis-table-element');
137 | disTable.setAttribute('links', JSON.stringify(opcodeLinks[pythonVersion]));
138 | disTable.setAttribute('operations', JSON.stringify(ops));
139 | disTable.addEventListener('line-highlight', (e) => {
140 | editor.highlightLine(e.detail.line);
141 | });
142 | tableDiv.appendChild(disTable);
143 | permalink = document.createElement('permalink-element');
144 | permalinkDiv.appendChild(permalink);
145 |
146 | document.getElementById('version-select').addEventListener('change', async () => {
147 | pythonVersion = document.getElementById('version-select').value;
148 | permalink.setAttribute('version', pythonVersion);
149 | window.location.search = permalink.path;
150 | });
151 | await loadPyodideScript();
152 | }
153 |
154 | main();
155 |
--------------------------------------------------------------------------------
/src/opcode_links_gen.py:
--------------------------------------------------------------------------------
1 | # Run this in cpython repo when tag is checked out for version
2 | # This will generate a json file with opcode links for that version
3 |
4 | opcode_links = {}
5 |
6 | file = open("Include/patchlevel.h", "r")
7 | for line in file.readlines():
8 | if line.startswith("#define PY_VERSION"):
9 | full_version = line.split()[2].strip('"')
10 | major_version = full_version.rsplit(".", 1)[0]
11 | break
12 | file.close()
13 |
14 | file = open("Include/opcode.h", "r")
15 | lines = file.readlines()
16 | file.close()
17 |
18 | opcodes = []
19 | for line in lines:
20 | if line.startswith("#define"):
21 | opcodes.append(line.split()[1]) # get opcode name
22 |
23 | file = open("Doc/library/dis.rst", "r")
24 | lines = file.readlines()
25 | file.close()
26 |
27 | for line in lines:
28 | if line.strip().startswith(".. opcode:: "):
29 | opcode = line.split(".. opcode:: ")[1].split()[0].strip()
30 | if opcode in opcodes:
31 | opcodes.remove(opcode)
32 | opcode_links[opcode] = f"https://docs.python.org/{major_version}/library/dis.html#opcode-%s" % opcode
33 |
34 | file = open("Python/ceval.c", "r")
35 | lines = file.readlines()
36 | for line_no, line in enumerate(lines):
37 | if line.strip().startswith("TARGET("):
38 | opcode = line.split("TARGET(")[1].split(")")[0].strip()
39 | elif line.strip().startswith("[NB"):
40 | opcode = line.split("[")[1].split("]")[0].strip()
41 | if opcode in opcodes:
42 | opcode_links[opcode] = f"https://github.com/python/cpython/blob/v{full_version}/Python/ceval.c#L{line_no + 1}"
43 | opcodes.remove(opcode)
44 |
45 | print("Remaining opcodes:")
46 | print(opcodes)
47 |
48 | # save opcode links to file, as json
49 | import json
50 | with open(f"opcodes_{major_version}.json", "w") as file:
51 | json.dump(opcode_links, file, indent=4)
--------------------------------------------------------------------------------
/src/permalink-element.js:
--------------------------------------------------------------------------------
1 | import {LitElement, html} from 'lit';
2 |
3 | export class Permalink extends LitElement {
4 | static properties = {
5 | code: {type: String},
6 | call: {type: String},
7 | adaptive: {type: String},
8 | version: {type: String},
9 | };
10 |
11 | constructor() {
12 | super();
13 | }
14 |
15 | get path() {
16 | let pathParams = [];
17 | Object.keys(Permalink.properties).forEach((key) => {
18 | if (this[key]) {
19 | pathParams.push(`${key}=${encodeURIComponent(this[key])}`);
20 | }
21 | });
22 | return pathParams.join('&');
23 | }
24 |
25 | render() {
26 | if (!this.code) return;
27 |
28 | const url = `${window.location.origin}/?${this.path.replace(/\(/g, '%28').replace(/\)/g, '%29')}`;
29 | return html`
30 | Permalink:
31 |
32 | `;
33 | }
34 | }
35 |
36 | customElements.define('permalink-element', Permalink);
37 |
--------------------------------------------------------------------------------