4141# include "windows.h"
4242#endif
4343
44+ /* Firmament2 */
45+ #include "firmament2.h"
46+
4447/* Forward */
4548static void flush_io (void );
4649static PyObject * run_mod (mod_ty , PyObject * , PyObject * , PyObject * ,
@@ -1234,36 +1237,49 @@ _PyRun_StringFlagsWithName(const char *str, PyObject* name, int start,
12341237 int generate_new_source )
12351238{
12361239 PyObject * ret = NULL ;
1237- mod_ty mod ;
1238- PyArena * arena ;
1239-
1240- arena = _PyArena_New ();
1240+ PyArena * arena = _PyArena_New ();
12411241 if (arena == NULL )
12421242 return NULL ;
12431243
12441244 PyObject * source = NULL ;
12451245 _Py_DECLARE_STR (anon_string , "<string>" );
12461246
1247- if (name ) {
1247+ if (!name ) {
1248+ name = & _Py_STR (anon_string );
1249+ } else {
12481250 source = PyUnicode_FromString (str );
12491251 if (!source ) {
12501252 PyErr_Clear ();
12511253 }
1252- } else {
1253- name = & _Py_STR (anon_string );
12541254 }
12551255
1256- mod = _PyParser_ASTFromString (str , name , start , flags , arena );
1256+ /* Begin source scope before parsing so tokens are attributed correctly */
1257+ int began_scope = 0 ;
1258+ const char * fn_utf8 = NULL ;
1259+ if (_firm2_enabled ()) {
1260+ if (name && PyUnicode_Check (name )) {
1261+ fn_utf8 = PyUnicode_AsUTF8 (name );
1262+ }
1263+ _firm2_source_begin (fn_utf8 );
1264+ began_scope = 1 ;
1265+ }
1266+
1267+ mod_ty mod = _PyParser_ASTFromString (str , name , start , flags , arena );
12571268
1258- if (mod != NULL ) {
1259- ret = run_mod (mod , name , globals , locals , flags , arena , source , generate_new_source );
1269+ if (mod != NULL ) {
1270+ ret = run_mod (mod , name , globals , locals , flags , arena ,
1271+ source , generate_new_source );
12601272 }
1273+
1274+ if (began_scope ) {
1275+ _firm2_source_end ();
1276+ }
1277+
12611278 Py_XDECREF (source );
12621279 _PyArena_Free (arena );
12631280 return ret ;
12641281}
12651282
1266-
12671283PyObject *
12681284PyRun_StringFlags (const char * str , int start , PyObject * globals ,
12691285 PyObject * locals , PyCompilerFlags * flags ) {
@@ -1280,27 +1296,37 @@ pyrun_file(FILE *fp, PyObject *filename, int start, PyObject *globals,
12801296 return NULL ;
12811297 }
12821298
1283- mod_ty mod ;
1284- mod = _PyParser_ASTFromFile (fp , filename , NULL , start , NULL , NULL ,
1285- flags , NULL , arena );
1299+ /* Begin source scope before we tokenize/parse so tokens get filename/source_id */
1300+ int began_scope = 0 ;
1301+ const char * fn_utf8 = NULL ;
1302+ if (_firm2_enabled ()) {
1303+ if (filename && PyUnicode_Check (filename )) {
1304+ fn_utf8 = PyUnicode_AsUTF8 (filename );
1305+ }
1306+ _firm2_source_begin (fn_utf8 );
1307+ began_scope = 1 ;
1308+ }
1309+
1310+ mod_ty mod = _PyParser_ASTFromFile (fp , filename , NULL , start , NULL , NULL ,
1311+ flags , NULL , arena );
12861312
12871313 if (closeit ) {
12881314 fclose (fp );
12891315 }
12901316
1291- PyObject * ret ;
1317+ PyObject * ret = NULL ;
12921318 if (mod != NULL ) {
12931319 ret = run_mod (mod , filename , globals , locals , flags , arena , NULL , 0 );
12941320 }
1295- else {
1296- ret = NULL ;
1321+
1322+ if (began_scope ) {
1323+ _firm2_source_end ();
12971324 }
1298- _PyArena_Free (arena );
12991325
1326+ _PyArena_Free (arena );
13001327 return ret ;
13011328}
13021329
1303-
13041330PyObject *
13051331PyRun_FileExFlags (FILE * fp , const char * filename , int start , PyObject * globals ,
13061332 PyObject * locals , int closeit , PyCompilerFlags * flags )
@@ -1508,30 +1534,60 @@ PyObject *
15081534Py_CompileStringObject (const char * str , PyObject * filename , int start ,
15091535 PyCompilerFlags * flags , int optimize )
15101536{
1511- PyCodeObject * co ;
1512- mod_ty mod ;
1537+ PyObject * res = NULL ; /* return value: AST or PyCodeObject* */
1538+ mod_ty mod = NULL ;
15131539 PyArena * arena = _PyArena_New ();
1514- if (arena == NULL )
1540+ if (arena == NULL ) {
15151541 return NULL ;
1542+ }
1543+
1544+ /* ---- Firmament2 source scope: begin before tokenization ---- */
1545+ const char * fn_utf8 = NULL ;
1546+ int began_scope = 0 ;
1547+ if (_firm2_enabled ()) {
1548+ if (filename && PyUnicode_Check (filename )) {
1549+ fn_utf8 = PyUnicode_AsUTF8 (filename ); /* borrowed; may be NULL */
1550+ }
1551+ if (fn_utf8 == NULL ) {
1552+ /* Provide a stable label for string inputs if not a PyUnicode */
1553+ fn_utf8 = "<string>" ;
1554+ }
1555+ _firm2_source_begin (fn_utf8 );
1556+ began_scope = 1 ;
1557+ }
1558+ /* ------------------------------------------------------------ */
15161559
15171560 mod = _PyParser_ASTFromString (str , filename , start , flags , arena );
15181561 if (mod == NULL ) {
1519- _PyArena_Free (arena );
1520- return NULL ;
1562+ goto done ; /* arena freed + scope ended in done: block */
15211563 }
1564+
15221565 if (flags && (flags -> cf_flags & PyCF_ONLY_AST )) {
1523- int syntax_check_only = ((flags -> cf_flags & PyCF_OPTIMIZED_AST ) == PyCF_ONLY_AST ); /* unoptiomized AST */
1524- if (_PyCompile_AstPreprocess (mod , filename , flags , optimize , arena , syntax_check_only ) < 0 ) {
1525- _PyArena_Free (arena );
1526- return NULL ;
1566+ /* Return AST object (optionally preprocessed), not bytecode */
1567+ int syntax_check_only =
1568+ ((flags -> cf_flags & PyCF_OPTIMIZED_AST ) == PyCF_ONLY_AST ); /* unoptimized AST */
1569+ if (_PyCompile_AstPreprocess (mod , filename , flags , optimize , arena ,
1570+ syntax_check_only ) < 0 ) {
1571+ goto done ;
15271572 }
1528- PyObject * result = PyAST_mod2obj (mod );
1529- _PyArena_Free (arena );
1530- return result ;
1573+ res = PyAST_mod2obj (mod );
1574+ goto done ;
1575+ }
1576+
1577+ /* Compile to code object WITHOUT calling the public wrapper, so we
1578+ keep exactly one SOURCE_BEGIN/SOURCE_END from this scope. */
1579+ {
1580+ PyCodeObject * co = _PyAST_Compile (mod , filename , flags , optimize , arena );
1581+ res = (PyObject * )co ; /* may be NULL on error */
15311582 }
1532- co = _PyAST_Compile (mod , filename , flags , optimize , arena );
1583+
1584+ done :
15331585 _PyArena_Free (arena );
1534- return (PyObject * )co ;
1586+
1587+ if (began_scope ) {
1588+ _firm2_source_end ();
1589+ }
1590+ return res ;
15351591}
15361592
15371593PyObject *
0 commit comments