Skip to content

Commit a829313

Browse files
committed
Remove asdl_seq_APPEND() and simplify asdl seq implementation.
Clarify intended use of set_context() and check errors at all call sites.
1 parent 03bdedd commit a829313

File tree

3 files changed

+59
-81
lines changed

3 files changed

+59
-81
lines changed

Include/asdl.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,33 +15,23 @@ typedef enum {false, true} bool;
1515

1616
/* XXX A sequence should be typed so that its use can be typechecked. */
1717

18-
/* XXX We shouldn't pay for offset when we don't need APPEND. */
19-
2018
typedef struct {
2119
int size;
22-
int offset;
2320
void *elements[1];
2421
} asdl_seq;
2522

2623
asdl_seq *asdl_seq_new(int size, PyArena *arena);
27-
void asdl_seq_free(asdl_seq *);
2824

29-
#ifdef Py_DEBUG
3025
#define asdl_seq_GET(S, I) (S)->elements[(I)]
26+
#define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size)
27+
#ifdef Py_DEBUG
3128
#define asdl_seq_SET(S, I, V) { \
3229
int _asdl_i = (I); \
3330
assert((S) && _asdl_i < (S)->size); \
3431
(S)->elements[_asdl_i] = (V); \
3532
}
36-
#define asdl_seq_APPEND(S, V) { \
37-
assert((S) && (S)->offset < (S)->size); \
38-
(S)->elements[(S)->offset++] = (V); \
39-
}
4033
#else
41-
#define asdl_seq_GET(S, I) (S)->elements[(I)]
4234
#define asdl_seq_SET(S, I, V) (S)->elements[I] = (V)
43-
#define asdl_seq_APPEND(S, V) (S)->elements[(S)->offset++] = (V)
4435
#endif
45-
#define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size)
4636

4737
#endif /* !Py_ASDL_H */

Python/asdl.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,12 @@ asdl_seq_new(int size, PyArena *arena)
88
size_t n = sizeof(asdl_seq) +
99
(size ? (sizeof(void *) * (size - 1)) : 0);
1010

11-
seq = (asdl_seq *)malloc(n);
11+
seq = (asdl_seq *)PyArena_Malloc(arena, n);
1212
if (!seq) {
1313
PyErr_NoMemory();
1414
return NULL;
1515
}
16-
PyArena_AddMallocPointer(arena, (void *)seq);
1716
memset(seq, 0, n);
1817
seq->size = size;
1918
return seq;
2019
}
21-
22-
void
23-
asdl_seq_free(asdl_seq *seq)
24-
{
25-
}

Python/ast.c

Lines changed: 56 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ mod_ty
183183
PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
184184
PyArena *arena)
185185
{
186-
int i, j, num;
186+
int i, j, k, num;
187187
asdl_seq *stmts = NULL;
188188
stmt_ty s;
189189
node *ch;
@@ -199,6 +199,7 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
199199
}
200200
c.c_arena = arena;
201201

202+
k = 0;
202203
switch (TYPE(n)) {
203204
case file_input:
204205
stmts = asdl_seq_new(num_stmts(n), arena);
@@ -214,7 +215,7 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
214215
s = ast_for_stmt(&c, ch);
215216
if (!s)
216217
goto error;
217-
asdl_seq_APPEND(stmts, s);
218+
asdl_seq_SET(stmts, k++, s);
218219
}
219220
else {
220221
ch = CHILD(ch, 0);
@@ -223,7 +224,7 @@ PyAST_FromNode(const node *n, PyCompilerFlags *flags, const char *filename,
223224
s = ast_for_stmt(&c, CHILD(ch, j * 2));
224225
if (!s)
225226
goto error;
226-
asdl_seq_APPEND(stmts, s);
227+
asdl_seq_SET(stmts, k++, s);
227228
}
228229
}
229230
}
@@ -314,15 +315,11 @@ get_operator(const node *n)
314315
}
315316
}
316317

317-
/* Set the context ctx for expr_ty e returning 1 on success, 0 on error.
318+
/* Set the context ctx for expr_ty e, recursively traversing e.
318319
319320
Only sets context for expr kinds that "can appear in assignment context"
320321
(according to ../Parser/Python.asdl). For other expr kinds, it sets
321322
an appropriate syntax error and returns false.
322-
323-
If e is a sequential type, items in sequence will also have their context
324-
set.
325-
326323
*/
327324

328325
static int
@@ -346,7 +343,7 @@ set_context(expr_ty e, expr_context_ty ctx, const node *n)
346343
switch (e->kind) {
347344
case Attribute_kind:
348345
if (ctx == Store &&
349-
!strcmp(PyString_AS_STRING(e->v.Attribute.attr), "None")) {
346+
!strcmp(PyString_AS_STRING(e->v.Attribute.attr), "None")) {
350347
return ast_error(n, "assignment to None");
351348
}
352349
e->v.Attribute.ctx = ctx;
@@ -416,7 +413,7 @@ set_context(expr_ty e, expr_context_ty ctx, const node *n)
416413
}
417414

418415
/* If the LHS is a list or tuple, we need to set the assignment
419-
context for all the tuple elements.
416+
context for all the contained elements.
420417
*/
421418
if (s) {
422419
int i;
@@ -559,34 +556,31 @@ compiler_complex_args(struct compiling *c, const node *n)
559556
return NULL;
560557

561558
REQ(n, fplist);
562-
563559
for (i = 0; i < len; i++) {
564560
const node *child = CHILD(CHILD(n, 2*i), 0);
565561
expr_ty arg;
566562
if (TYPE(child) == NAME) {
567-
if (!strcmp(STR(child), "None")) {
568-
ast_error(child, "assignment to None");
569-
return NULL;
570-
}
563+
if (!strcmp(STR(child), "None")) {
564+
ast_error(child, "assignment to None");
565+
return NULL;
566+
}
571567
arg = Name(NEW_IDENTIFIER(child), Store, LINENO(child),
572568
c->c_arena);
573-
}
574-
else
569+
}
570+
else {
575571
arg = compiler_complex_args(c, CHILD(CHILD(n, 2*i), 1));
576-
set_context(arg, Store, n);
572+
}
577573
asdl_seq_SET(args, i, arg);
578574
}
579575

580576
result = Tuple(args, Store, LINENO(n), c->c_arena);
581-
set_context(result, Store, n);
577+
if (!set_context(result, Store, n))
578+
return NULL;
582579
return result;
583580
}
584581

585-
/* Create AST for argument list.
586582

587-
XXX TO DO:
588-
- check for invalid argument lists like normal after default
589-
*/
583+
/* Create AST for argument list. */
590584

591585
static arguments_ty
592586
ast_for_arguments(struct compiling *c, const node *n)
@@ -595,7 +589,7 @@ ast_for_arguments(struct compiling *c, const node *n)
595589
varargslist: (fpdef ['=' test] ',')* ('*' NAME [',' '**' NAME]
596590
| '**' NAME) | fpdef ['=' test] (',' fpdef ['=' test])* [',']
597591
*/
598-
int i, n_args = 0, n_defaults = 0, found_default = 0;
592+
int i, j, k, n_args = 0, n_defaults = 0, found_default = 0;
599593
asdl_seq *args, *defaults;
600594
identifier vararg = NULL, kwarg = NULL;
601595
node *ch;
@@ -626,6 +620,8 @@ ast_for_arguments(struct compiling *c, const node *n)
626620
fplist: fpdef (',' fpdef)* [',']
627621
*/
628622
i = 0;
623+
j = 0; /* index for defaults */
624+
k = 0; /* index for args */
629625
while (i < NCH(n)) {
630626
ch = CHILD(n, i);
631627
switch (TYPE(ch)) {
@@ -634,7 +630,7 @@ ast_for_arguments(struct compiling *c, const node *n)
634630
anything other than EQUAL or a comma? */
635631
/* XXX Should NCH(n) check be made a separate check? */
636632
if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) {
637-
asdl_seq_APPEND(defaults,
633+
asdl_seq_SET(defaults, j++,
638634
ast_for_expr(c, CHILD(n, i + 2)));
639635
i += 2;
640636
found_default = 1;
@@ -644,9 +640,8 @@ ast_for_arguments(struct compiling *c, const node *n)
644640
"non-default argument follows default argument");
645641
goto error;
646642
}
647-
648643
if (NCH(ch) == 3) {
649-
asdl_seq_APPEND(args,
644+
asdl_seq_SET(args, k++,
650645
compiler_complex_args(c, CHILD(ch, 1)));
651646
}
652647
else if (TYPE(CHILD(ch, 0)) == NAME) {
@@ -659,7 +654,7 @@ ast_for_arguments(struct compiling *c, const node *n)
659654
Param, LINENO(ch), c->c_arena);
660655
if (!name)
661656
goto error;
662-
asdl_seq_APPEND(args, name);
657+
asdl_seq_SET(args, k++, name);
663658

664659
}
665660
i += 2; /* the name and the comma */
@@ -767,16 +762,15 @@ ast_for_decorators(struct compiling *c, const node *n)
767762
int i;
768763

769764
REQ(n, decorators);
770-
771765
decorator_seq = asdl_seq_new(NCH(n), c->c_arena);
772766
if (!decorator_seq)
773767
return NULL;
774768

775769
for (i = 0; i < NCH(n); i++) {
776-
d = ast_for_decorator(c, CHILD(n, i));
777-
if (!d)
778-
return NULL;
779-
asdl_seq_APPEND(decorator_seq, d);
770+
d = ast_for_decorator(c, CHILD(n, i));
771+
if (!d)
772+
return NULL;
773+
asdl_seq_SET(decorator_seq, i, d);
780774
}
781775
return decorator_seq;
782776
}
@@ -993,21 +987,20 @@ ast_for_listcomp(struct compiling *c, const node *n)
993987
return NULL;
994988

995989
for (j = 0; j < n_ifs; j++) {
996-
REQ(ch, list_iter);
997-
998-
ch = CHILD(ch, 0);
999-
REQ(ch, list_if);
1000-
1001-
asdl_seq_APPEND(ifs, ast_for_expr(c, CHILD(ch, 1)));
1002-
if (NCH(ch) == 3)
1003-
ch = CHILD(ch, 2);
1004-
}
1005-
/* on exit, must guarantee that ch is a list_for */
1006-
if (TYPE(ch) == list_iter)
1007-
ch = CHILD(ch, 0);
990+
REQ(ch, list_iter);
991+
ch = CHILD(ch, 0);
992+
REQ(ch, list_if);
993+
994+
asdl_seq_SET(ifs, j, ast_for_expr(c, CHILD(ch, 1)));
995+
if (NCH(ch) == 3)
996+
ch = CHILD(ch, 2);
997+
}
998+
/* on exit, must guarantee that ch is a list_for */
999+
if (TYPE(ch) == list_iter)
1000+
ch = CHILD(ch, 0);
10081001
lc->ifs = ifs;
1009-
}
1010-
asdl_seq_APPEND(listcomps, lc);
1002+
}
1003+
asdl_seq_SET(listcomps, i, lc);
10111004
}
10121005

10131006
return ListComp(elt, listcomps, LINENO(n), c->c_arena);
@@ -1075,6 +1068,7 @@ count_gen_ifs(const node *n)
10751068
}
10761069
}
10771070

1071+
/* TODO(jhylton): Combine with list comprehension code? */
10781072
static expr_ty
10791073
ast_for_genexp(struct compiling *c, const node *n)
10801074
{
@@ -1146,7 +1140,7 @@ ast_for_genexp(struct compiling *c, const node *n)
11461140
expression = ast_for_expr(c, CHILD(ch, 1));
11471141
if (!expression)
11481142
return NULL;
1149-
asdl_seq_APPEND(ifs, expression);
1143+
asdl_seq_SET(ifs, j, expression);
11501144
if (NCH(ch) == 3)
11511145
ch = CHILD(ch, 2);
11521146
}
@@ -1155,7 +1149,7 @@ ast_for_genexp(struct compiling *c, const node *n)
11551149
ch = CHILD(ch, 0);
11561150
ge->ifs = ifs;
11571151
}
1158-
asdl_seq_APPEND(genexps, ge);
1152+
asdl_seq_SET(genexps, i, ge);
11591153
}
11601154

11611155
return GeneratorExp(elt, genexps, LINENO(n), c->c_arena);
@@ -1948,24 +1942,23 @@ ast_for_print_stmt(struct compiling *c, const node *n)
19481942
expr_ty dest = NULL, expression;
19491943
asdl_seq *seq;
19501944
bool nl;
1951-
int i, start = 1;
1945+
int i, j, start = 1;
19521946

19531947
REQ(n, print_stmt);
19541948
if (NCH(n) >= 2 && TYPE(CHILD(n, 1)) == RIGHTSHIFT) {
19551949
dest = ast_for_expr(c, CHILD(n, 2));
19561950
if (!dest)
19571951
return NULL;
1958-
start = 4;
1952+
start = 4;
19591953
}
19601954
seq = asdl_seq_new((NCH(n) + 1 - start) / 2, c->c_arena);
19611955
if (!seq)
1962-
return NULL;
1963-
for (i = start; i < NCH(n); i += 2) {
1956+
return NULL;
1957+
for (i = start, j = 0; i < NCH(n); i += 2, ++j) {
19641958
expression = ast_for_expr(c, CHILD(n, i));
19651959
if (!expression)
19661960
return NULL;
1967-
1968-
asdl_seq_APPEND(seq, expression);
1961+
asdl_seq_SET(seq, j, expression);
19691962
}
19701963
nl = (TYPE(CHILD(n, NCH(n) - 1)) == COMMA) ? false : true;
19711964
return Print(dest, seq, nl, LINENO(n), c->c_arena);
@@ -2252,14 +2245,15 @@ ast_for_import_stmt(struct compiling *c, const node *n)
22522245
alias_ty import_alias = alias_for_import_name(c, n);
22532246
if (!import_alias)
22542247
return NULL;
2255-
asdl_seq_APPEND(aliases, import_alias);
2248+
asdl_seq_SET(aliases, 0, import_alias);
22562249
}
2257-
2258-
for (i = 0; i < NCH(n); i += 2) {
2259-
alias_ty import_alias = alias_for_import_name(c, CHILD(n, i));
2260-
if (!import_alias)
2261-
return NULL;
2262-
asdl_seq_APPEND(aliases, import_alias);
2250+
else {
2251+
for (i = 0; i < NCH(n); i += 2) {
2252+
alias_ty import_alias = alias_for_import_name(c, CHILD(n, i));
2253+
if (!import_alias)
2254+
return NULL;
2255+
asdl_seq_SET(aliases, i / 2, import_alias);
2256+
}
22632257
}
22642258
if (mod != NULL)
22652259
modname = mod->name;

0 commit comments

Comments
 (0)