Skip to content

Commit 26cc01c

Browse files
committed
gh-153569: keep persistent scanner positions as source offsets
1 parent adcb999 commit 26cc01c

18 files changed

Lines changed: 118 additions & 237 deletions

Makefile.pre.in

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,6 @@ PEGEN_OBJS= \
394394
Parser/peg_api.o
395395

396396
TOKENIZER_OBJS= \
397-
Parser/lexer/buffer.o \
398397
Parser/lexer/lexer.o \
399398
Parser/lexer/number.o \
400399
Parser/lexer/state.o \
@@ -412,7 +411,6 @@ PEGEN_HEADERS= \
412411
$(srcdir)/Parser/string_parser.h
413412

414413
TOKENIZER_HEADERS= \
415-
Parser/lexer/buffer.h \
416414
Parser/lexer/lexer.h \
417415
Parser/lexer/lexer_internal.h \
418416
Parser/lexer/state.h \

PCbuild/_freeze_module.vcxproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,6 @@
181181
<ClCompile Include="..\Parser\action_helpers.c" />
182182
<ClCompile Include="..\Parser\string_parser.c" />
183183
<ClCompile Include="..\Parser\token.c" />
184-
<ClCompile Include="..\Parser\lexer\buffer.c" />
185184
<ClCompile Include="..\Parser\lexer\state.c" />
186185
<ClCompile Include="..\Parser\lexer\lexer.c" />
187186
<ClCompile Include="..\Parser\lexer\number.c" />

PCbuild/_freeze_module.vcxproj.filters

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -469,9 +469,6 @@
469469
<ClCompile Include="..\Parser\lexer\string.c">
470470
<Filter>Source Files</Filter>
471471
</ClCompile>
472-
<ClCompile Include="..\Parser\lexer\buffer.c">
473-
<Filter>Source Files</Filter>
474-
</ClCompile>
475472
<ClCompile Include="..\Parser\lexer\state.c">
476473
<Filter>Source Files</Filter>
477474
</ClCompile>

PCbuild/pythoncore.vcxproj

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,6 @@
423423
<ClInclude Include="..\Parser\lexer\state.h" />
424424
<ClInclude Include="..\Parser\lexer\lexer.h" />
425425
<ClInclude Include="..\Parser\lexer\lexer_internal.h" />
426-
<ClInclude Include="..\Parser\lexer\buffer.h" />
427426
<ClInclude Include="..\Parser\tokenizer\cursor.h" />
428427
<ClInclude Include="..\Parser\tokenizer\reader.h" />
429428
<ClInclude Include="..\Parser\tokenizer\reader_internal.h" />
@@ -594,7 +593,6 @@
594593
<ClCompile Include="..\Parser\lexer\lexer.c" />
595594
<ClCompile Include="..\Parser\lexer\number.c" />
596595
<ClCompile Include="..\Parser\lexer\string.c" />
597-
<ClCompile Include="..\Parser\lexer\buffer.c" />
598596
<ClCompile Include="..\Parser\tokenizer\cursor.c" />
599597
<ClCompile Include="..\Parser\tokenizer\source.c" />
600598
<ClCompile Include="..\Parser\tokenizer\decoder.c" />

PCbuild/pythoncore.vcxproj.filters

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,6 @@
330330
<ClInclude Include="..\Parser\lexer\lexer_internal.h">
331331
<Filter>Parser</Filter>
332332
</ClInclude>
333-
<ClInclude Include="..\Parser\lexer\buffer.h">
334-
<Filter>Parser</Filter>
335-
</ClInclude>
336333
<ClInclude Include="..\Parser\tokenizer\cursor.h">
337334
<Filter>Parser</Filter>
338335
</ClInclude>
@@ -1364,9 +1361,6 @@
13641361
<ClCompile Include="..\Parser\lexer\state.c">
13651362
<Filter>Parser</Filter>
13661363
</ClCompile>
1367-
<ClCompile Include="..\Parser\lexer\buffer.c">
1368-
<Filter>Parser</Filter>
1369-
</ClCompile>
13701364
<ClCompile Include="..\Parser\tokenizer\cursor.c">
13711365
<Filter>Parser</Filter>
13721366
</ClCompile>

Parser/lexer/buffer.c

Lines changed: 0 additions & 46 deletions
This file was deleted.

Parser/lexer/buffer.h

Lines changed: 0 additions & 22 deletions
This file was deleted.

Parser/lexer/lexer.c

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ _PyLexer_nextc(struct tok_state *tok)
3535
return EOF;
3636
}
3737
tok->col_offset++;
38-
return Py_CHARMASK(*tok->cur++); /* Fast path */
38+
return Py_CHARMASK(tok->source.bytes[tok->cur++ - tok->source.base_offset]); /* Fast path */
3939
}
4040
if (tok->done != E_OK) {
4141
return EOF;
@@ -44,7 +44,7 @@ _PyLexer_nextc(struct tok_state *tok)
4444
#if defined(Py_DEBUG)
4545
if (tok->debug) {
4646
fprintf(stderr, "line[%d] = ", tok->lineno);
47-
_PyTokenizer_print_escape(stderr, tok->cur, tok->inp - tok->cur);
47+
_PyTokenizer_print_escape(stderr, _PyLexer_BufferPointer(tok, tok->cur), tok->inp - tok->cur);
4848
fprintf(stderr, " tok->done = %d\n", tok->done);
4949
}
5050
#endif
@@ -54,7 +54,7 @@ _PyLexer_nextc(struct tok_state *tok)
5454
}
5555
tok->line_start = tok->cur;
5656

57-
if (contains_null_bytes(tok->line_start, tok->inp - tok->line_start)) {
57+
if (contains_null_bytes(_PyLexer_BufferPointer(tok, tok->line_start), tok->inp - tok->line_start)) {
5858
_PyTokenizer_syntaxerror(tok, "source code cannot contain null bytes");
5959
tok->cur = tok->inp;
6060
return EOF;
@@ -68,10 +68,10 @@ void
6868
_PyLexer_backup(struct tok_state *tok, int c)
6969
{
7070
if (c != EOF) {
71-
if (--tok->cur < tok->buf) {
71+
if (--tok->cur < tok->buf_offset) {
7272
Py_FatalError("tokenizer beginning of buffer");
7373
}
74-
if ((int)(unsigned char)*tok->cur != Py_CHARMASK(c)) {
74+
if ((int)(unsigned char)*_PyLexer_BufferPointer(tok, tok->cur) != Py_CHARMASK(c)) {
7575
Py_FatalError("tok_backup: wrong character");
7676
}
7777
tok->col_offset--;
@@ -90,7 +90,7 @@ verify_identifier(struct tok_state *tok)
9090
PyObject *s;
9191
if (tok->input_error)
9292
return 0;
93-
s = PyUnicode_DecodeUTF8(tok->start, tok->cur - tok->start, NULL);
93+
s = PyUnicode_DecodeUTF8(_PyLexer_BufferPointer(tok, tok->start), tok->cur - tok->start, NULL);
9494
if (s == NULL) {
9595
if (PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) {
9696
tok->done = E_DECODE;
@@ -115,7 +115,7 @@ verify_identifier(struct tok_state *tok)
115115
tok->done = E_ERROR;
116116
return 0;
117117
}
118-
tok->cur = (char *)tok->start + PyBytes_GET_SIZE(s);
118+
tok->cur = tok->start + PyBytes_GET_SIZE(s);
119119
}
120120
Py_DECREF(s);
121121
if (Py_UNICODE_ISPRINTABLE(ch)) {
@@ -161,10 +161,10 @@ _PyLexer_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, str
161161
int c;
162162
int blankline, nonascii;
163163

164-
const char *p_start = NULL;
165-
const char *p_end = NULL;
164+
_PyTok_Off p_start = -1;
165+
_PyTok_Off p_end = -1;
166166
nextline:
167-
tok->start = NULL;
167+
tok->start = -1;
168168
tok->starting_col_offset = -1;
169169
blankline = 0;
170170

@@ -283,7 +283,7 @@ _PyLexer_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, str
283283
}
284284
else {
285285
if (tok->tok_extra_tokens) {
286-
p_start = tok->buf;
286+
p_start = tok->buf_offset;
287287
p_end = tok->cur;
288288
}
289289
tok->pendin--;
@@ -296,14 +296,14 @@ _PyLexer_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, str
296296
tok_backup(tok, c);
297297

298298
again:
299-
tok->start = NULL;
299+
tok->start = -1;
300300
/* Skip spaces */
301301
do {
302302
c = tok_nextc(tok);
303303
} while (c == ' ' || c == '\t' || c == '\014');
304304

305305
/* Set start of current token */
306-
tok->start = tok->cur == NULL ? NULL : tok->cur - 1;
306+
tok->start = tok->cur - 1;
307307
tok->starting_col_offset = tok->col_offset - 1;
308308

309309
/* Skip comment, unless it's a type comment */
@@ -318,14 +318,14 @@ _PyLexer_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, str
318318
}
319319

320320
if (tok->tok_extra_tokens) {
321-
p = tok->start;
321+
p = _PyLexer_BufferPointer(tok, tok->start);
322322
}
323323

324324
if (tok->type_comments) {
325-
p = tok->start;
325+
p = _PyLexer_BufferPointer(tok, tok->start);
326326
current_starting_col_offset = tok->starting_col_offset;
327327
prefix = type_comment_prefix;
328-
while (*prefix && p < tok->cur) {
328+
while (*prefix && p < _PyLexer_BufferPointer(tok, tok->cur)) {
329329
if (*prefix == ' ') {
330330
while (*p == ' ' || *p == '\t') {
331331
p++;
@@ -354,24 +354,24 @@ _PyLexer_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, str
354354
/* A TYPE_IGNORE is "type: ignore" followed by the end of the token
355355
* or anything ASCII and non-alphanumeric. */
356356
is_type_ignore = (
357-
tok->cur >= ignore_end && memcmp(p, "ignore", 6) == 0
358-
&& !(tok->cur > ignore_end
357+
_PyLexer_BufferPointer(tok, tok->cur) >= ignore_end && memcmp(p, "ignore", 6) == 0
358+
&& !(_PyLexer_BufferPointer(tok, tok->cur) > ignore_end
359359
&& ((unsigned char)ignore_end[0] >= 128 || Py_ISALNUM(ignore_end[0]))));
360360

361361
int type = is_type_ignore ? TYPE_IGNORE : TYPE_COMMENT;
362362
int start_col_offset = is_type_ignore
363363
? ignore_end_col_offset : current_starting_col_offset;
364364
p_end = tok->cur;
365365
if (is_type_ignore) {
366-
p_start = ignore_end;
366+
p_start = _PyLexer_BufferOffset(tok, ignore_end);
367367

368368
/* If this type ignore is the only thing on the line, consume the newline also. */
369369
if (blankline) {
370370
tok_nextc(tok);
371371
tok->atbol = 1;
372372
}
373373
} else {
374-
p_start = type_start;
374+
p_start = _PyLexer_BufferOffset(tok, type_start);
375375
}
376376
_PyLexer_token_setup(tok, token, type, p_start, p_end);
377377
token->start_loc = (_PyTok_Loc){tok->lineno, start_col_offset};
@@ -381,7 +381,7 @@ _PyLexer_get_normal_mode(struct tok_state *tok, tokenizer_mode* current_tok, str
381381
}
382382
if (tok->tok_extra_tokens) {
383383
tok_backup(tok, c); /* don't eat the newline or EOF */
384-
p_start = p;
384+
p_start = _PyLexer_BufferOffset(tok, p);
385385
p_end = tok->cur;
386386
tok->comment_newline = blankline;
387387
return MAKE_TOKEN(COMMENT);

Parser/lexer/number.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ int
113113
_PyLexer_scan_number(struct tok_state *tok, struct token *token, int c,
114114
int leading_dot)
115115
{
116-
const char *p_start = NULL;
117-
const char *p_end = NULL;
116+
_PyTok_Off p_start = -1;
117+
_PyTok_Off p_end = -1;
118118

119119
if (leading_dot) {
120120
goto fraction;
@@ -214,7 +214,7 @@ _PyLexer_scan_number(struct tok_state *tok, struct token *token, int c,
214214
}
215215
c = tok_nextc(tok);
216216
}
217-
char* zeros_end = tok->cur;
217+
_PyTok_Off zeros_end = tok->cur;
218218
if (Py_ISDIGIT(c)) {
219219
nonzero = 1;
220220
c = tok_decimal_tail(tok);

Parser/lexer/state.c

Lines changed: 7 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,12 @@ _PyTokenizer_tok_new(void)
2121
return NULL;
2222
}
2323

24-
tok->buf = tok->cur = tok->inp = NULL;
24+
tok->cur = tok->inp = 0;
25+
tok->line_start = tok->multi_line_start = -1;
2526
tok->fp_interactive = 0;
2627
tok->interactive_src_start = NULL;
2728
tok->interactive_src_end = NULL;
28-
tok->start = NULL;
29+
tok->start = -1;
2930
tok->done = E_OK;
3031
tok->fp = NULL;
3132
tok->tabsize = TABSIZE;
@@ -108,38 +109,19 @@ _PyToken_Init(struct token *token) {
108109
token->metadata = NULL;
109110
}
110111

111-
static inline _PyTok_Span
112-
buffer_span(const struct tok_state *tok, const char *start, const char *end)
113-
{
114-
if (start == NULL) {
115-
assert(end == NULL);
116-
return (_PyTok_Span){-1, -1};
117-
}
118-
assert(end != NULL);
119-
const char *base = tok->buf;
120-
assert(base != NULL);
121-
assert(tok->inp >= base);
122-
Py_ssize_t start_offset = start - base;
123-
Py_ssize_t end_offset = end - base;
124-
assert(start_offset >= 0 && start_offset <= end_offset);
125-
assert(end_offset <= tok->inp - base);
126-
assert(tok->buf_offset <= PY_SSIZE_T_MAX - end_offset);
127-
return _PyTok_SpanFromBounds(
128-
tok->buf_offset + start_offset, tok->buf_offset + end_offset);
129-
}
130-
131112
int
132-
_PyLexer_token_setup(struct tok_state *tok, struct token *token, int type, const char *start, const char *end)
113+
_PyLexer_token_setup(struct tok_state *tok, struct token *token, int type, _PyTok_Off start, _PyTok_Off end)
133114
{
134115
token->level = tok->level;
135116
token->is_raw = ISSTRINGLIT(type)
136117
&& tok->tok_mode_stack[tok->tok_mode_stack_index].raw;
137-
token->span = buffer_span(tok, start, end);
118+
assert((start == -1 && end == -1) || (start >= 0 && end >= start));
119+
token->span = (_PyTok_Span){start, end};
138120
int lineno = ISSTRINGLIT(type) ? tok->first_lineno : tok->lineno;
139121
token->start_loc = (_PyTok_Loc){lineno, -1};
140122
token->end_loc = (_PyTok_Loc){tok->lineno, -1};
141123

142-
if (start != NULL && end != NULL) {
124+
if (start >= 0 && end >= 0) {
143125
token->start_loc.byte_col = tok->starting_col_offset;
144126
token->end_loc.byte_col = tok->col_offset;
145127
}

0 commit comments

Comments
 (0)