@@ -60,10 +60,10 @@ fn warn_explicit(
6060 Ok ( ( ) )
6161}
6262
63- // filename, module, and registry are new refs, globals is borrowed
64- // Returns 0 on error (no new refs), 1 on success
63+ /// filename, module, and registry are new refs, globals is borrowed
64+ /// Returns `Ok` on success, or `Err` on error (no new refs)
6565fn setup_context (
66- _stack_level : isize ,
66+ mut stack_level : isize ,
6767 vm : & VirtualMachine ,
6868) -> PyResult <
6969 // filename, lineno, module, registry
@@ -72,32 +72,38 @@ fn setup_context(
7272 let __warningregistry__ = "__warningregistry__" ;
7373 let __name__ = "__name__" ;
7474
75- // Setup globals, filename and lineno.
76- let frame = vm. current_frame ( ) ;
75+ let mut f = vm. current_frame ( ) . as_deref ( ) . cloned ( ) ;
7776
78- // PyThreadState *tstate = _PyThreadState_GET();
79- // PyFrameObject *f = PyThreadState_GetFrame(tstate);
80- // // Stack level comparisons to Python code is off by one as there is no
81- // // warnings-related stack level to avoid.
82- // if (stack_level <= 0 || is_internal_frame(f)) {
83- // while (--stack_level > 0 && f != NULL) {
84- // PyFrameObject *back = PyFrame_GetBack(f);
85- // Py_DECREF(f);
86- // f = back;
87- // }
88- // }
89- // else {
90- // while (--stack_level > 0 && f != NULL) {
91- // f = next_external_frame(f);
92- // }
93- // }
77+ // Stack level comparisons to Python code is off by one as there is no
78+ // warnings-related stack level to avoid.
79+ if stack_level <= 0 || f. as_ref ( ) . map_or ( false , |frame| frame. is_internal_frame ( ) ) {
80+ loop {
81+ stack_level -= 1 ;
82+ if stack_level <= 0 {
83+ break ;
84+ }
85+ if let Some ( tmp) = f {
86+ f = tmp. f_back ( vm) ;
87+ } else {
88+ break ;
89+ }
90+ }
91+ } else {
92+ loop {
93+ stack_level -= 1 ;
94+ if stack_level <= 0 {
95+ break ;
96+ }
97+ if let Some ( tmp) = f {
98+ f = tmp. next_external_frame ( vm) ;
99+ } else {
100+ break ;
101+ }
102+ }
103+ }
94104
95- let ( globals, filename, lineno) = if let Some ( f) = frame {
96- // TODO:
97- let lineno = 1 ;
98- // *lineno = PyFrame_GetLineNumber(f);
99- // *filename = code->co_filename;
100- ( f. globals . clone ( ) , f. code . source_path , lineno)
105+ let ( globals, filename, lineno) = if let Some ( f) = f {
106+ ( f. globals . clone ( ) , f. code . source_path , f. f_lineno ( ) )
101107 } else {
102108 ( vm. current_globals ( ) . clone ( ) , vm. ctx . intern_str ( "sys" ) , 1 )
103109 } ;
0 commit comments