depyo 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +97 -0
  3. package/depyo.js +213 -0
  4. package/lib/BinaryReader.js +153 -0
  5. package/lib/OpCode.js +90 -0
  6. package/lib/OpCodes.js +940 -0
  7. package/lib/PycDecompiler.js +2031 -0
  8. package/lib/PycDisassembler.js +55 -0
  9. package/lib/PycReader.js +905 -0
  10. package/lib/PycResult.js +82 -0
  11. package/lib/PythonObject.js +242 -0
  12. package/lib/Unpickle.js +173 -0
  13. package/lib/ast/ast_node.js +3442 -0
  14. package/lib/bytecode/python_1_0.js +116 -0
  15. package/lib/bytecode/python_1_1.js +116 -0
  16. package/lib/bytecode/python_1_3.js +119 -0
  17. package/lib/bytecode/python_1_4.js +121 -0
  18. package/lib/bytecode/python_1_5.js +120 -0
  19. package/lib/bytecode/python_1_6.js +124 -0
  20. package/lib/bytecode/python_2_0.js +137 -0
  21. package/lib/bytecode/python_2_1.js +142 -0
  22. package/lib/bytecode/python_2_2.js +147 -0
  23. package/lib/bytecode/python_2_3.js +145 -0
  24. package/lib/bytecode/python_2_4.js +147 -0
  25. package/lib/bytecode/python_2_5.js +147 -0
  26. package/lib/bytecode/python_2_6.js +147 -0
  27. package/lib/bytecode/python_2_7.js +151 -0
  28. package/lib/bytecode/python_3_0.js +132 -0
  29. package/lib/bytecode/python_3_1.js +135 -0
  30. package/lib/bytecode/python_3_10.js +312 -0
  31. package/lib/bytecode/python_3_11.js +284 -0
  32. package/lib/bytecode/python_3_12.js +327 -0
  33. package/lib/bytecode/python_3_13.js +173 -0
  34. package/lib/bytecode/python_3_14.js +177 -0
  35. package/lib/bytecode/python_3_2.js +136 -0
  36. package/lib/bytecode/python_3_3.js +136 -0
  37. package/lib/bytecode/python_3_4.js +137 -0
  38. package/lib/bytecode/python_3_5.js +149 -0
  39. package/lib/bytecode/python_3_6.js +153 -0
  40. package/lib/bytecode/python_3_7.js +292 -0
  41. package/lib/bytecode/python_3_8.js +294 -0
  42. package/lib/bytecode/python_3_9.js +296 -0
  43. package/lib/code_reader.js +146 -0
  44. package/lib/handlers/binary_ops.js +174 -0
  45. package/lib/handlers/collections_update.js +239 -0
  46. package/lib/handlers/comparisons.js +95 -0
  47. package/lib/handlers/context_managers.js +250 -0
  48. package/lib/handlers/control_flow_jumps.js +954 -0
  49. package/lib/handlers/exceptions_blocks.js +952 -0
  50. package/lib/handlers/formatting.js +31 -0
  51. package/lib/handlers/function_calls.js +496 -0
  52. package/lib/handlers/function_class_build.js +330 -0
  53. package/lib/handlers/generators_async.js +172 -0
  54. package/lib/handlers/imports.js +53 -0
  55. package/lib/handlers/load_store_names.js +711 -0
  56. package/lib/handlers/loop_iterator.js +318 -0
  57. package/lib/handlers/misc_other.js +1201 -0
  58. package/lib/handlers/pattern_matching.js +226 -0
  59. package/lib/handlers/stack_ops.js +280 -0
  60. package/lib/handlers/subscript_slice.js +394 -0
  61. package/lib/handlers/unary_ops.js +91 -0
  62. package/lib/handlers/unpack.js +141 -0
  63. package/lib/stack_history.js +63 -0
  64. package/lib/zip_reader.js +217 -0
  65. package/package.json +35 -0
@@ -0,0 +1,82 @@
1
+ class PycResult {
2
+ result = [];
3
+ indent = 0;
4
+ doNotIndent = false;
5
+
6
+ constructor(lines, doNotIndent = false) {
7
+ if (lines) {
8
+ this.add(lines);
9
+ }
10
+ this.doNotIndent = doNotIndent;
11
+ }
12
+
13
+ get length() {
14
+ return this.result.length;
15
+ }
16
+
17
+ get last() {
18
+ return this.result[this.result.length - 1];
19
+ }
20
+
21
+ get hasResult() {
22
+ return this.result.length > 1 || (this.result.length == 1 && this.result[0].length > 0);
23
+ }
24
+
25
+ increaseIndent() {
26
+ this.indent++;
27
+ }
28
+
29
+ decreaseIndent() {
30
+ if (this.indent > 0) {
31
+ this.indent--;
32
+ }
33
+ }
34
+
35
+ clear() {
36
+ this.indent = 0;
37
+ this.result = [];
38
+ }
39
+
40
+ add(line) {
41
+ let padding = " ".repeat(4 * this.indent);
42
+ let lines = [];
43
+
44
+ if (line instanceof PycResult) {
45
+ if (!line.doNotIndent) {
46
+ padding = " ".repeat(4 * (this.indent + 1));
47
+ }
48
+ lines = line.result;
49
+ } else {
50
+ lines.push(line)
51
+ }
52
+
53
+ for (line of lines) {
54
+ this.result.push(padding + line);
55
+ }
56
+ }
57
+
58
+ lastLineAppend(data, shouldTrim = true) {
59
+ if (this.result.length == 0) {
60
+ this.result.push("");
61
+ }
62
+ if (data.constructor.name == "String") {
63
+ this.result[this.result.length - 1] += shouldTrim ? data.trim() : data;
64
+ } else {
65
+ let str = data?.result?.shift();
66
+ this.result[this.result.length - 1] += shouldTrim? str.trim() : str;
67
+ this.add(data);
68
+ }
69
+ }
70
+
71
+ chop(suffix) {
72
+ if (this.last.endsWith(suffix)) {
73
+ this.result[this.result.length - 1] = this.last.substring(0,this.last.length - suffix.length);
74
+ }
75
+ }
76
+
77
+ toString() {
78
+ return this.result.join("\n");
79
+ }
80
+ }
81
+
82
+ module.exports = PycResult;
@@ -0,0 +1,242 @@
1
+ class PythonObject {
2
+ ClassName = null;
3
+ Value = null;
4
+
5
+ constructor(class_name, value) {
6
+ this.ClassName = class_name || null;
7
+ this.Value = value || null;
8
+ }
9
+
10
+ add(po) {
11
+ if (["Py_List", "Py_Tuple", "Py_Set", "Py_FrozenSet"].includes(this.ClassName))
12
+ {
13
+ let list = this.Value;
14
+
15
+ if (list == null) {
16
+ list = [];
17
+ this.Value = list;
18
+ }
19
+
20
+ list.push(po);
21
+ }
22
+ }
23
+
24
+ add(key, val) {
25
+ if (this.ClassName == "Py_Dict") {
26
+ let dict = this.Value;
27
+ if (dict == null)
28
+ {
29
+ dict = [];
30
+ this.Value = dict;
31
+ }
32
+
33
+ dict.push({key, value: val});
34
+ }
35
+ }
36
+
37
+ get length() {
38
+ if (["Py_String", "Py_List", "Py_Dict", "Py_Tuple", "Py_Set", "Py_FrozenSet", "Py_VeryLong"].includes(this.ClassName)) {
39
+ if (this.Value && this.Value.length) {
40
+ return this.Value.length;
41
+ } else {
42
+ return 0;
43
+ }
44
+ } else {
45
+ return 1;
46
+ }
47
+ }
48
+
49
+ // TODO: Refactor to use Symbol.toPrimitive() and Object.valueOf()
50
+
51
+ toString()
52
+ {
53
+ switch(this.ClassName) {
54
+ case "Py_Unicode":
55
+ case "Py_String":
56
+ let strValue = this.Value;
57
+ if (strValue.ClassName) {
58
+ throw new SyntaxError("Recursion");
59
+ }
60
+ if (!strValue || strValue.length == 0) {
61
+ return "";
62
+ }
63
+ strValue = strValue.toString();
64
+ if (strValue.includes("\n")) {
65
+ strValue = strValue.replaceAll("\n", "\\n");
66
+ }
67
+ return strValue;
68
+
69
+ case "Py_Int":
70
+ case "Py_Long":
71
+ case "Py_Long64":
72
+ return this.Value !== null ? this.Value.toString() : "0";
73
+
74
+ case "Py_Interned":
75
+ return this.Value !== null ? this.Value.toString() : "0";
76
+
77
+ case "Py_Float":
78
+ return this.Value !== null ? `${this.Value}${Number.isInteger(this.Value) ? ".0" : ""}` : "0.0";
79
+
80
+ case "Py_VeryLong":
81
+ if (this.Value) {
82
+ if (this.Value.length < 8) {
83
+ return this.Value.toString();
84
+ } else {
85
+ let result = "0x";
86
+ let skipFirstZeros = true;
87
+ let shortFlag = true;
88
+ for (let idx = this.Value.length - 1; idx >= 0; idx--) {
89
+ let value = this.Value[idx];
90
+ value = value.toString(16);
91
+ if (skipFirstZeros && value == 0) {
92
+ continue;
93
+ } else if (skipFirstZeros && value) {
94
+ skipFirstZeros = false;
95
+ }
96
+ if (!shortFlag) {
97
+ value = value.length < 2 ? "0" + value : value;
98
+ }
99
+ shortFlag = false;
100
+ result += value;
101
+ }
102
+ return result;
103
+ }
104
+ } else {
105
+ return "0";
106
+ }
107
+
108
+ case "Py_Null":
109
+ return "None";
110
+
111
+ case "Py_False":
112
+ return "False";
113
+
114
+ case "Py_True":
115
+ return "True";
116
+
117
+ case "Py_None":
118
+ return "None";
119
+
120
+ case "Py_Tuple":
121
+ case "Py_Set":
122
+ case "Py_FrozenSet":
123
+ let res = "(";
124
+ if (this.Value) {
125
+ for (let obj of this.Value) {
126
+ if (res != "(") {
127
+ res += ", " + obj;
128
+ } else {
129
+ res += obj;
130
+ }
131
+ }
132
+ res += ")";
133
+ return res;
134
+ } else {
135
+ return "null";
136
+ }
137
+
138
+ case "Py_CodeObject":
139
+ return `<code object ${this.Name.toString()}, file '${this.FileName.toString()}', line ${this.FirstLineNo}>`;
140
+
141
+ case "Py_Dict":
142
+ if (this.Value) {
143
+ let res = "(";
144
+ for (let pair of this.Value) {
145
+ if (res != "(") {
146
+ res += ", ";
147
+ }
148
+ res += pair.key + ": " + pair.value;
149
+ }
150
+ res += ")";
151
+ return res;
152
+ } else {
153
+ return "()";
154
+ }
155
+
156
+ case "Py_StringRef":
157
+ return this.Strings[this.Value];
158
+
159
+ case "Py_Complex":
160
+ return `${this.Value[0]}+${this.Value[1]}j`;
161
+
162
+ default:
163
+ return ["Py_String"].includes(this.ClassName) ? this.Value.toString("ascii") : null;
164
+ }
165
+ }
166
+ }
167
+
168
+ class PythonCodeObject extends PythonObject {
169
+ ClassName = "Py_CodeObject";
170
+ ArgCount = 0;
171
+ PosOnlyArgCount = 0;
172
+ KWOnlyArgCount = 0;
173
+ NumLocals = 0;
174
+ StackSize = 0;
175
+ Flags = 0;
176
+ Code = null;
177
+ Consts = [];
178
+ Names = [];
179
+ VarNames = [];
180
+ FreeVars = [];
181
+ CellVars = [];
182
+ FileName = null;
183
+ Name = null;
184
+ FirstLineNo = 0;
185
+ LineNoTab = [];
186
+ LineNoTabObject = null;
187
+ ExceptionTable = null; // Python 3.11+ exception table (raw bytes or parsed entries)
188
+ Methods = [];
189
+ SourceCode = null;
190
+ FuncParams = null;
191
+ FuncDecos = null;
192
+ FuncName = null;
193
+ ASTTree = [];
194
+ Globals = new Set();
195
+ CachedLineNo = -1;
196
+
197
+ getLineNumber(offset, isVer310 = false) {
198
+ if (offset < 0) {
199
+ return this.FirstLineNo;
200
+ }
201
+
202
+ if (this.CachedLineNo > -1) {
203
+ return this.CachedLineNo;
204
+ }
205
+
206
+ if (!this.LineNoTabObject || this.LineNoTabObject.Value.length < 2 || offset >= this.Code.length) {
207
+ return -1;
208
+ }
209
+
210
+ let lnTable = this.LineNoTabObject.Value;
211
+ let size = lnTable.length / 2;
212
+ let sDelta = 0;
213
+ let lDelta = 0;
214
+
215
+ let line = this.FirstLineNo;
216
+ let addr = 0;
217
+ let index = 0;
218
+ while (--size >= 0) {
219
+ sDelta = lnTable[index++];
220
+ lDelta = lnTable[index++];
221
+
222
+ addr += sDelta;
223
+ if (addr > offset)
224
+ break;
225
+
226
+ if (isVer310 && lDelta == -128) { // Should we treat no line number? or treat it as previous line?
227
+ lDelta = 0;
228
+ }
229
+
230
+ line += lDelta;
231
+ }
232
+ return line;
233
+ }
234
+ }
235
+
236
+
237
+ module.exports = {PythonObject, PythonCodeObject};
238
+
239
+ // Registering classes in global scope for propoer class deserialization.
240
+ for (let className of Object.keys(module.exports)) {
241
+ global[className] = new module.exports[className]();
242
+ }
@@ -0,0 +1,173 @@
1
+ // public class Unpickle
2
+ // {
3
+ // public static List<object> Load(string fileName)
4
+ // {
5
+ // List<object> result = null;
6
+ // BinaryReader rdr = new BinaryReader(File.OpenRead(fileName));
7
+
8
+ // result = Load(rdr);
9
+
10
+
11
+ // return result;
12
+ // }
13
+
14
+ // public static List<object> Load(byte[] data)
15
+ // {
16
+ // MemoryStream memStream = new MemoryStream(data);
17
+ // BinaryReader rdr = new BinaryReader(memStream);
18
+ // return Load(rdr);
19
+ // }
20
+
21
+ // public static List<object> Load(BinaryReader rdr)
22
+ // {
23
+ // List<object> result = new List<object>();
24
+ // List<object> memo = new List<object>();
25
+
26
+ // while (rdr.BaseStream.Position < rdr.BaseStream.Length)
27
+ // {
28
+
29
+ // byte opCode = rdr.ReadByte();
30
+
31
+ // switch ((char)opCode)
32
+ // {
33
+ // case '(': // MARK
34
+ // break;
35
+ // case '.': // STOP
36
+ // break;
37
+ // case '0': // POP
38
+ // break;
39
+ // case '1': // POP_MARK
40
+ // break;
41
+ // case '2': // DUP
42
+ // break;
43
+ // case 'F': // FLOAT
44
+ // break;
45
+ // case 'I': // INT
46
+ // break;
47
+ // case 'J': // BININT
48
+ // result.Add(rdr.ReadInt32());
49
+ // break;
50
+ // case 'K': // BININT1
51
+ // result.Add(rdr.ReadByte());
52
+ // break;
53
+ // case 'L': // LONG
54
+ // break;
55
+ // case 'M': // BININT2
56
+ // result.Add(rdr.ReadInt16());
57
+ // break;
58
+ // case 'N': // NONE
59
+ // break;
60
+ // case 'P': // PERSID
61
+ // rdr.ReadByte();
62
+ // break;
63
+ // case 'Q': // BINPERSID
64
+ // break;
65
+ // case 'R': // REDUCE
66
+ // break;
67
+ // case 'S': // STRING
68
+ // break;
69
+ // case 'T': // BINSTRING
70
+ // int size = rdr.ReadInt32();
71
+ // result.Add(rdr.ReadBytes(size));
72
+ // break;
73
+ // case 'U': // SHORT_BINSTRING
74
+ // int uSize = (int)rdr.ReadByte();
75
+ // result.Add(rdr.ReadBytes(uSize));
76
+ // break;
77
+ // case 'V': // UNICODE
78
+ // break;
79
+ // case 'X': // BINUNICODE
80
+ // uSize = (int)rdr.ReadByte();
81
+ // result.Add(rdr.ReadBytes(uSize));
82
+ // break;
83
+ // case 'a': // APPEND
84
+ // break;
85
+ // case 'b': // BUILD
86
+ // break;
87
+ // case 'c': // GLOBAL
88
+ // break;
89
+ // case 'd': // DICT
90
+ // break;
91
+ // case '}': // EMPTY_DICT
92
+ // break;
93
+ // case 'e': // APPENDS
94
+ // break;
95
+ // case 'g': // GET
96
+ // break;
97
+ // case 'h': // BINGET
98
+ // int idx = rdr.ReadByte();
99
+ // if (idx < memo.Count)
100
+ // result.Add(memo[idx]);
101
+ // break;
102
+ // case 'i': // INST
103
+ // break;
104
+ // case 'j': // LONG_BINGET
105
+ // idx = rdr.ReadInt32();
106
+ // break;
107
+ // case 'l': // LIST
108
+ // break;
109
+ // case ']': // EMPTY_LIST
110
+ // break;
111
+ // case 'o': // OBJ
112
+ // break;
113
+ // case 'p': // PUT
114
+ // break;
115
+ // case 'q': // BINPUT
116
+ // idx = rdr.ReadByte();
117
+ // break;
118
+ // case 'r': // LONG_BINPUT
119
+ // idx = rdr.ReadInt32();
120
+ // break;
121
+ // case 's': // SETITEM
122
+ // break;
123
+ // case 't': // TUPLE
124
+ // break;
125
+ // case ')': // EMPTY_TUPLE
126
+ // break;
127
+ // case 'u': // SETITEMS
128
+ // break;
129
+ // case 'G': // BINFLOAT
130
+ // result.Add(rdr.ReadDouble());
131
+ // break;
132
+ // case '\x80': // PROTO
133
+ // rdr.ReadByte();
134
+ // break;
135
+ // case '\x81': // NEWOBJ
136
+ // break;
137
+ // case '\x82': // EXT1
138
+ // break;
139
+ // case '\x83': // EXT2
140
+ // break;
141
+ // case '\x84': // EXT4
142
+ // break;
143
+ // case '\x85': // TUPLE1
144
+ // break;
145
+ // case '\x86': // TUPLE2
146
+ // break;
147
+ // case '\x87': // TUPLE3
148
+ // break;
149
+ // case '\x88': // NEWTRUE
150
+ // result.Add(true);
151
+ // break;
152
+ // case '\x89': // NEWFALSE
153
+ // result.Add(false);
154
+ // break;
155
+ // case '\x8A': // LONG1
156
+ // idx = rdr.ReadByte();
157
+ // result.Add(rdr.ReadBytes(idx));
158
+ // break;
159
+ // case '\x8B': // LONG4
160
+ // idx = rdr.ReadInt32();
161
+ // result.Add(rdr.ReadBytes(idx));
162
+ // break;
163
+ // case '\x9D':
164
+ // rdr.ReadBytes(1);
165
+ // break;
166
+ // default:
167
+ // throw new ArgumentOutOfRangeException();
168
+ // }
169
+ // }
170
+
171
+ // return result;
172
+ // }
173
+ // }