depyo 1.2.1 → 1.2.3
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.
|
@@ -95,6 +95,14 @@ function processListAppend() {
|
|
|
95
95
|
let node = new AST.ASTComprehension (value);
|
|
96
96
|
node.line = this.code.Current.LineNo;
|
|
97
97
|
this.dataStack.push(node);
|
|
98
|
+
} else if (list instanceof AST.ASTList) {
|
|
99
|
+
// CPython's "big list" path: when a list literal exceeds the
|
|
100
|
+
// STACK_USE_GUIDELINE and not every element is a compile-time
|
|
101
|
+
// constant, the compiler emits BUILD_LIST 0 + N×LIST_APPEND
|
|
102
|
+
// instead of a single BUILD_LIST N. Mutate the list literal in
|
|
103
|
+
// place; the list reference must remain on top of the data stack
|
|
104
|
+
// for the next LIST_APPEND (or the final STORE_*) to find it.
|
|
105
|
+
list.values.push(value);
|
|
98
106
|
} else {
|
|
99
107
|
let node = new AST.ASTSubscr (list, value);
|
|
100
108
|
node.line = this.code.Current.LineNo;
|
|
@@ -26,10 +26,32 @@ const INTRINSIC_2 = Object.freeze({
|
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
function handleKwNamesA() {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
// CPython 3.11/3.12: KW_NAMES(consti) stores a reference to co_consts[consti],
|
|
30
|
+
// which is guaranteed to be a tuple of strings. The following PRECALL/CALL pair
|
|
31
|
+
// pops that many trailing positional slots and rebinds them as kwargs.
|
|
32
|
+
//
|
|
33
|
+
// ConstantObject here is a PythonObject (Py_Tuple or Py_SmallTuple) — NOT a
|
|
34
|
+
// raw JS array — and each element is a PythonObject (Py_Unicode/Py_String).
|
|
35
|
+
// The original code did `keys.length - 1` (works via PythonObject.length) but
|
|
36
|
+
// then `keys[idx]` returned undefined because indexed access does not reach
|
|
37
|
+
// into `.Value`. The result was an ASTKwNamesMap with `undefined` keys and a
|
|
38
|
+
// shifted stack that mangled the next CALL into `##ERROR##(func, =val)`.
|
|
39
|
+
// GitHub depyo.js issue #11.
|
|
40
|
+
const constObj = this.code.Current.ConstantObject;
|
|
41
|
+
let keyObjs = [];
|
|
42
|
+
if (constObj && (constObj.ClassName === 'Py_Tuple' || constObj.ClassName === 'Py_SmallTuple') && Array.isArray(constObj.Value)) {
|
|
43
|
+
keyObjs = constObj.Value;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const toKwName = (v) => {
|
|
47
|
+
const raw = v?.Value ?? v?.name ?? v;
|
|
48
|
+
const name = typeof raw === 'string' ? raw : String(raw);
|
|
49
|
+
return new AST.ASTName(name.replace(/^['"]|['"]$/g, ''));
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const astNode = new AST.ASTKwNamesMap();
|
|
53
|
+
for (let idx = keyObjs.length - 1; idx >= 0; idx--) {
|
|
54
|
+
astNode.add(toKwName(keyObjs[idx]), this.dataStack.pop());
|
|
33
55
|
}
|
|
34
56
|
|
|
35
57
|
astNode.line = this.code.Current.LineNo;
|
|
@@ -177,9 +199,16 @@ function handleInstrumentedCallA() {
|
|
|
177
199
|
let kwparams_map = this.dataStack.top();
|
|
178
200
|
if (kwparams_map instanceof AST.ASTKwNamesMap) {
|
|
179
201
|
this.dataStack.pop();
|
|
202
|
+
// CPython 3.11/3.12: KW_NAMES sets the trailing-keyword count for the
|
|
203
|
+
// next CALL. CALL's oparg is the total positional+keyword count packed
|
|
204
|
+
// into the low byte (`pparams` here); the high byte (`kwparams`) is
|
|
205
|
+
// always zero for these versions. Each keyword consumed by KW_NAMES
|
|
206
|
+
// already popped its value from the stack, so the CALL must pop only
|
|
207
|
+
// (total - kwcount) positional slots — i.e. decrement `pparams`, not
|
|
208
|
+
// `kwparams`. depyo.js issue #11.
|
|
180
209
|
for (let kwParam of kwparams_map.values) {
|
|
181
210
|
kwparamList.unshift(kwParam);
|
|
182
|
-
|
|
211
|
+
pparams--;
|
|
183
212
|
}
|
|
184
213
|
}
|
|
185
214
|
}
|