@@ -28,10 +28,7 @@ _PyTok_ReaderFree(struct tok_state *tok)
2828 }
2929 PyMem_Free (reader -> file_buffer );
3030 PyMem_Free (reader -> decoded );
31- if (reader -> kind != _PYTOK_READER_PREPARED ) {
32- PyMem_Free (tok -> buf );
33- tok -> buf = NULL ;
34- }
31+ tok -> buf = NULL ;
3532 PyMem_Free (reader );
3633 tok -> reader = NULL ;
3734}
@@ -534,13 +531,13 @@ _PyTok_ReaderUnderflow(struct tok_state *tok)
534531 int prepared = tok -> reader -> kind == _PYTOK_READER_PREPARED ;
535532 int reset_buffer = !prepared && tok -> start == NULL && !INSIDE_FSTRING (tok );
536533
537- if (reset_buffer && tok -> reader -> kind != _PYTOK_READER_INTERACTIVE ) {
538- tok -> cur = tok -> inp = tok -> buf ;
539- }
540-
541534 _PyTok_Chunk chunk ;
542535 _PyTok_ReadResult result = reader_next (tok , & chunk );
543536 if (result != _PYTOK_READ_LINE ) {
537+ if (reset_buffer &&
538+ tok -> reader -> kind != _PYTOK_READER_INTERACTIVE ) {
539+ tok -> cur = tok -> inp = tok -> buf ;
540+ }
544541 if (result == _PYTOK_READ_EOF ) {
545542 tok -> done = E_EOF ;
546543 }
@@ -564,27 +561,48 @@ _PyTok_ReaderUnderflow(struct tok_state *tok)
564561 return 0 ;
565562 }
566563
567- Py_ssize_t copy_len = chunk .len ;
564+ Py_ssize_t scan_len = chunk .len ;
568565 if (tok -> reader -> kind == _PYTOK_READER_INTERACTIVE &&
569566 chunk .implicit_newline ) {
570- copy_len -- ;
571- }
572- if (reset_buffer && tok -> reader -> kind == _PYTOK_READER_INTERACTIVE ) {
573- tok -> cur = tok -> inp = tok -> buf ;
574- }
575- if (!prepared && !_PyLexer_tok_reserve_buf (tok , copy_len + 1 )) {
576- _PyTok_ChunkClear (& chunk );
577- tok -> input_error = 1 ;
578- return 0 ;
579- }
580- if (tok -> reader -> kind == _PYTOK_READER_INTERACTIVE &&
581- _PyTok_SourceAppendLine (& tok -> source , chunk .data , chunk .len ,
582- chunk .implicit_newline ) < 0 ) {
583- _PyTok_ChunkClear (& chunk );
584- tok -> done = PyErr_ExceptionMatches (PyExc_MemoryError )
585- ? E_NOMEM : E_ERROR ;
586- tok -> input_error = 1 ;
587- return 0 ;
567+ scan_len -- ;
568+ }
569+ if (!prepared ) {
570+ int source_will_grow =
571+ chunk .len > tok -> source .cap - tok -> source .len - 1 ;
572+ _PyLexer_BufferSnapshot snapshot ;
573+ if (!reset_buffer && source_will_grow ) {
574+ _PyLexer_SnapshotBuffer (
575+ tok , tok -> source .bytes , & snapshot );
576+ }
577+ _PyTok_Off source_start = _PyTok_SourceAppendLine (
578+ & tok -> source , chunk .data , chunk .len ,
579+ chunk .implicit_newline );
580+ if (source_start < 0 ) {
581+ _PyTok_ChunkClear (& chunk );
582+ tok -> done = PyErr_ExceptionMatches (PyExc_MemoryError )
583+ ? E_NOMEM : E_ERROR ;
584+ tok -> input_error = 1 ;
585+ return 0 ;
586+ }
587+ if (reset_buffer ) {
588+ tok -> buf = tok -> cur = tok -> source .bytes + source_start ;
589+ tok -> line_start = tok -> buf ;
590+ tok -> start = NULL ;
591+ tok -> multi_line_start = NULL ;
592+ }
593+ else if (source_will_grow ) {
594+ _PyLexer_RestoreBuffer (
595+ tok , tok -> source .bytes , & snapshot );
596+ }
597+ tok -> inp = tok -> source .bytes + source_start + scan_len ;
598+ if (_PyTok_CursorSetLine (
599+ & tok -> reader_cursor , tok -> source .nlines ) < 0 ) {
600+ _PyTok_ChunkClear (& chunk );
601+ tok -> done = PyErr_ExceptionMatches (PyExc_MemoryError )
602+ ? E_NOMEM : E_ERROR ;
603+ tok -> input_error = 1 ;
604+ return 0 ;
605+ }
588606 }
589607 if (tok -> fp_interactive ) {
590608 tok -> interactive_src_start = tok -> source .bytes ;
@@ -596,11 +614,6 @@ _PyTok_ReaderUnderflow(struct tok_state *tok)
596614 }
597615 tok -> inp = chunk .data + chunk .len ;
598616 }
599- else {
600- memcpy (tok -> inp , chunk .data , (size_t )copy_len );
601- tok -> inp += copy_len ;
602- * tok -> inp = '\0' ;
603- }
604617 tok -> implicit_newline = chunk .implicit_newline ;
605618
606619 if (!prepared && tok -> tok_mode_stack_index &&
@@ -645,7 +658,9 @@ tokenizer_new_with_reader(_PyTok_ReaderKind kind)
645658 return NULL ;
646659 }
647660 tok -> cur = tok -> inp = tok -> buf ;
648- tok -> end = tok -> buf + BUFSIZ ;
661+ tok -> source .bytes = tok -> buf ;
662+ tok -> source .cap = BUFSIZ ;
663+ tok -> source .bytes [0 ] = '\0' ;
649664 return tok ;
650665}
651666
@@ -663,7 +678,6 @@ tokenizer_from_string(const char *input, int utf8_only, int exec_input,
663678 return NULL ;
664679 }
665680 tok -> buf = tok -> cur = tok -> inp = tok -> str ;
666- tok -> end = tok -> buf ;
667681 return tok ;
668682}
669683
0 commit comments