diff options
author | Mark Shannon <mark@hotpy.org> | 2022-06-27 11:24:23 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-27 11:24:23 (GMT) |
commit | c0453a40faaadb43d2e69767af6c9680f8689063 (patch) | |
tree | d8ab19e5244e552e5d1b371651593be9be5142e4 /Python/compile.c | |
parent | 33fc3b5e42f241ab81cc6d115711545b4f9e271e (diff) | |
download | cpython-c0453a40faaadb43d2e69767af6c9680f8689063.zip cpython-c0453a40faaadb43d2e69767af6c9680f8689063.tar.gz cpython-c0453a40faaadb43d2e69767af6c9680f8689063.tar.bz2 |
GH-94163: Add BINARY_SLICE and STORE_SLICE instructions. (GH-94168)
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 88 |
1 files changed, 70 insertions, 18 deletions
diff --git a/Python/compile.c b/Python/compile.c index 3946aac..74c21fd 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -1030,8 +1030,12 @@ stack_effect(int opcode, int oparg, int jump) case BINARY_SUBSCR: return -1; + case BINARY_SLICE: + return -2; case STORE_SUBSCR: return -3; + case STORE_SLICE: + return -4; case DELETE_SUBSCR: return -2; @@ -5864,7 +5868,14 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) } break; case Slice_kind: - return compiler_slice(c, e); + { + int n = compiler_slice(c, e); + if (n == 0) { + return 0; + } + ADDOP_I(c, BUILD_SLICE, n); + break; + } case Name_kind: return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx); /* child nodes of List and Tuple will have expr_context set */ @@ -5886,6 +5897,13 @@ compiler_visit_expr(struct compiler *c, expr_ty e) return res; } +static bool +is_two_element_slice(expr_ty s) +{ + return s->kind == Slice_kind && + s->v.Slice.step == NULL; +} + static int compiler_augassign(struct compiler *c, stmt_ty s) { @@ -5906,10 +5924,21 @@ compiler_augassign(struct compiler *c, stmt_ty s) break; case Subscript_kind: VISIT(c, expr, e->v.Subscript.value); - VISIT(c, expr, e->v.Subscript.slice); - ADDOP_I(c, COPY, 2); - ADDOP_I(c, COPY, 2); - ADDOP(c, BINARY_SUBSCR); + if (is_two_element_slice(e->v.Subscript.slice)) { + if (!compiler_slice(c, e->v.Subscript.slice)) { + return 0; + } + ADDOP_I(c, COPY, 3); + ADDOP_I(c, COPY, 3); + ADDOP_I(c, COPY, 3); + ADDOP(c, BINARY_SLICE); + } + else { + VISIT(c, expr, e->v.Subscript.slice); + ADDOP_I(c, COPY, 2); + ADDOP_I(c, COPY, 2); + ADDOP(c, BINARY_SUBSCR); + } break; case Name_kind: if (!compiler_nameop(c, e->v.Name.id, Load)) @@ -5936,9 +5965,17 @@ compiler_augassign(struct compiler *c, stmt_ty s) ADDOP_NAME(c, STORE_ATTR, e->v.Attribute.attr, names); break; case Subscript_kind: - ADDOP_I(c, SWAP, 3); - ADDOP_I(c, SWAP, 2); - ADDOP(c, STORE_SUBSCR); + if (is_two_element_slice(e->v.Subscript.slice)) { + ADDOP_I(c, SWAP, 4); + ADDOP_I(c, SWAP, 3); + ADDOP_I(c, SWAP, 2); + ADDOP(c, STORE_SLICE); + } + else { + ADDOP_I(c, SWAP, 3); + ADDOP_I(c, SWAP, 2); + ADDOP(c, STORE_SUBSCR); + } break; case Name_kind: return compiler_nameop(c, e->v.Name.id, Store); @@ -6146,18 +6183,34 @@ compiler_subscript(struct compiler *c, expr_ty e) } } - switch (ctx) { - case Load: op = BINARY_SUBSCR; break; - case Store: op = STORE_SUBSCR; break; - case Del: op = DELETE_SUBSCR; break; - } - assert(op); VISIT(c, expr, e->v.Subscript.value); - VISIT(c, expr, e->v.Subscript.slice); - ADDOP(c, op); + if (is_two_element_slice(e->v.Subscript.slice) && ctx != Del) { + if (!compiler_slice(c, e->v.Subscript.slice)) { + return 0; + } + if (ctx == Load) { + ADDOP(c, BINARY_SLICE); + } + else { + assert(ctx == Store); + ADDOP(c, STORE_SLICE); + } + } + else { + VISIT(c, expr, e->v.Subscript.slice); + switch (ctx) { + case Load: op = BINARY_SUBSCR; break; + case Store: op = STORE_SUBSCR; break; + case Del: op = DELETE_SUBSCR; break; + } + assert(op); + ADDOP(c, op); + } return 1; } +/* Returns the number of the values emitted, + * thus are needed to build the slice, or 0 if there is an error. */ static int compiler_slice(struct compiler *c, expr_ty s) { @@ -6183,8 +6236,7 @@ compiler_slice(struct compiler *c, expr_ty s) n++; VISIT(c, expr, s->v.Slice.step); } - ADDOP_I(c, BUILD_SLICE, n); - return 1; + return n; } |