@@ -827,7 +827,11 @@ impl Compiler {
827827 Ok ( ( ) )
828828 }
829829
830- fn enter_function ( & mut self , name : & str , args : & ast:: Parameters ) -> CompileResult < ( ) > {
830+ fn enter_function (
831+ & mut self ,
832+ name : & str ,
833+ args : & ast:: Parameters ,
834+ ) -> CompileResult < bytecode:: MakeFunctionFlags > {
831835 let have_defaults = !args. defaults . is_empty ( ) ;
832836 if have_defaults {
833837 // Construct a tuple:
@@ -859,17 +863,17 @@ impl Compiler {
859863 } ) ;
860864 }
861865
862- let mut flags = bytecode:: CodeFlags :: NEW_LOCALS | bytecode :: CodeFlags :: IS_OPTIMIZED ;
866+ let mut funcflags = bytecode:: MakeFunctionFlags :: empty ( ) ;
863867 if have_defaults {
864- flags |= bytecode:: CodeFlags :: HAS_DEFAULTS ;
868+ funcflags |= bytecode:: MakeFunctionFlags :: DEFAULTS ;
865869 }
866870 if num_kw_only_defaults > 0 {
867- flags |= bytecode:: CodeFlags :: HAS_KW_ONLY_DEFAULTS ;
871+ funcflags |= bytecode:: MakeFunctionFlags :: KW_ONLY_DEFAULTS ;
868872 }
869873
870874 let line_number = self . get_source_line_number ( ) ;
871875 self . push_output ( CodeObject :: new (
872- flags ,
876+ bytecode :: CodeFlags :: NEW_LOCALS | bytecode :: CodeFlags :: IS_OPTIMIZED ,
873877 args. posonlyargs_count ,
874878 args. args . len ( ) ,
875879 args. kwonlyargs . len ( ) ,
@@ -896,7 +900,7 @@ impl Compiler {
896900 compile_varargs ( & args. vararg , bytecode:: CodeFlags :: HAS_VARARGS ) ;
897901 compile_varargs ( & args. kwarg , bytecode:: CodeFlags :: HAS_VARKEYWORDS ) ;
898902
899- Ok ( ( ) )
903+ Ok ( funcflags )
900904 }
901905
902906 fn prepare_decorators ( & mut self , decorator_list : & [ ast:: Expression ] ) -> CompileResult < ( ) > {
@@ -1037,7 +1041,7 @@ impl Compiler {
10371041 // Create bytecode for this function:
10381042
10391043 self . prepare_decorators ( decorator_list) ?;
1040- self . enter_function ( name, args) ?;
1044+ let mut funcflags = self . enter_function ( name, args) ?;
10411045
10421046 // remember to restore self.ctx.in_loop to the original after the function is compiled
10431047 let prev_ctx = self . ctx ;
@@ -1113,7 +1117,7 @@ impl Compiler {
11131117 }
11141118
11151119 if num_annotations > 0 {
1116- code . flags |= bytecode:: CodeFlags :: HAS_ANNOTATIONS ;
1120+ funcflags |= bytecode:: MakeFunctionFlags :: ANNOTATIONS ;
11171121 self . emit ( Instruction :: BuildMap {
11181122 size : num_annotations,
11191123 unpack : false ,
@@ -1125,7 +1129,9 @@ impl Compiler {
11251129 code. flags |= bytecode:: CodeFlags :: IS_COROUTINE ;
11261130 }
11271131
1128- self . build_closure ( & code) ;
1132+ if self . build_closure ( & code) {
1133+ funcflags |= bytecode:: MakeFunctionFlags :: CLOSURE ;
1134+ }
11291135
11301136 self . emit_constant ( ConstantData :: Code {
11311137 code : Box :: new ( code) ,
@@ -1135,7 +1141,7 @@ impl Compiler {
11351141 } ) ;
11361142
11371143 // Turn code object into function object:
1138- self . emit ( Instruction :: MakeFunction ) ;
1144+ self . emit ( Instruction :: MakeFunction ( funcflags ) ) ;
11391145
11401146 self . emit ( Instruction :: Duplicate ) ;
11411147 self . load_docstring ( doc_str) ;
@@ -1150,32 +1156,34 @@ impl Compiler {
11501156 Ok ( ( ) )
11511157 }
11521158
1153- fn build_closure ( & mut self , code : & CodeObject ) {
1154- if ! code. freevars . is_empty ( ) {
1155- for var in & * code . freevars {
1156- let table = self . symbol_table_stack . last ( ) . unwrap ( ) ;
1157- let symbol = table . lookup ( var ) . unwrap ( ) ;
1158- let parent_code = self . code_stack . last ( ) . unwrap ( ) ;
1159- let vars = match symbol . scope {
1160- SymbolScope :: Free => & parent_code . freevar_cache ,
1161- SymbolScope :: Cell => & parent_code . cellvar_cache ,
1162- _ if symbol . is_free_class => & parent_code. freevar_cache ,
1163- x => unreachable ! (
1164- "var {} in a {:?} should be free or cell but it's {:?}" ,
1165- var , table . typ , x
1166- ) ,
1167- } ;
1168- let mut idx = vars . get_index_of ( var ) . unwrap ( ) ;
1169- if let SymbolScope :: Free = symbol . scope {
1170- idx += parent_code . cellvar_cache . len ( ) ;
1171- }
1172- self . emit ( Instruction :: LoadClosure ( idx ) )
1159+ fn build_closure ( & mut self , code : & CodeObject ) -> bool {
1160+ if code. freevars . is_empty ( ) {
1161+ return false ;
1162+ }
1163+ for var in & * code . freevars {
1164+ let table = self . symbol_table_stack . last ( ) . unwrap ( ) ;
1165+ let symbol = table . lookup ( var ) . unwrap ( ) ;
1166+ let parent_code = self . code_stack . last ( ) . unwrap ( ) ;
1167+ let vars = match symbol . scope {
1168+ SymbolScope :: Free => & parent_code. freevar_cache ,
1169+ SymbolScope :: Cell => & parent_code . cellvar_cache ,
1170+ _ if symbol . is_free_class => & parent_code . freevar_cache ,
1171+ x => unreachable ! (
1172+ "var {} in a {:?} should be free or cell but it's {:?}" ,
1173+ var , table . typ , x
1174+ ) ,
1175+ } ;
1176+ let mut idx = vars . get_index_of ( var ) . unwrap ( ) ;
1177+ if let SymbolScope :: Free = symbol . scope {
1178+ idx += parent_code . cellvar_cache . len ( ) ;
11731179 }
1174- self . emit ( Instruction :: BuildTuple {
1175- size : code. freevars . len ( ) ,
1176- unpack : false ,
1177- } )
1180+ self . emit ( Instruction :: LoadClosure ( idx) )
11781181 }
1182+ self . emit ( Instruction :: BuildTuple {
1183+ size : code. freevars . len ( ) ,
1184+ unpack : false ,
1185+ } ) ;
1186+ true
11791187 }
11801188
11811189 fn find_ann ( & self , body : & [ ast:: Statement ] ) -> bool {
@@ -1312,7 +1320,11 @@ impl Compiler {
13121320 self . current_qualified_path = old_qualified_path;
13131321 self . ctx = prev_ctx;
13141322
1315- self . build_closure ( & code) ;
1323+ let mut funcflags = bytecode:: MakeFunctionFlags :: empty ( ) ;
1324+
1325+ if self . build_closure ( & code) {
1326+ funcflags |= bytecode:: MakeFunctionFlags :: CLOSURE ;
1327+ }
13161328
13171329 self . emit_constant ( ConstantData :: Code {
13181330 code : Box :: new ( code) ,
@@ -1322,7 +1334,7 @@ impl Compiler {
13221334 } ) ;
13231335
13241336 // Turn code object into function object:
1325- self . emit ( Instruction :: MakeFunction ) ;
1337+ self . emit ( Instruction :: MakeFunction ( funcflags ) ) ;
13261338
13271339 self . emit_constant ( ConstantData :: Str {
13281340 value : qualified_name,
@@ -2006,17 +2018,19 @@ impl Compiler {
20062018 } ;
20072019
20082020 let name = "<lambda>" . to_owned ( ) ;
2009- self . enter_function ( & name, args) ?;
2021+ let mut funcflags = self . enter_function ( & name, args) ?;
20102022 self . compile_expression ( body) ?;
20112023 self . emit ( Instruction :: ReturnValue ) ;
20122024 let code = self . pop_code_object ( ) ;
2013- self . build_closure ( & code) ;
2025+ if self . build_closure ( & code) {
2026+ funcflags |= bytecode:: MakeFunctionFlags :: CLOSURE ;
2027+ }
20142028 self . emit_constant ( ConstantData :: Code {
20152029 code : Box :: new ( code) ,
20162030 } ) ;
20172031 self . emit_constant ( ConstantData :: Str { value : name } ) ;
20182032 // Turn code object into function object:
2019- self . emit ( Instruction :: MakeFunction ) ;
2033+ self . emit ( Instruction :: MakeFunction ( funcflags ) ) ;
20202034
20212035 self . ctx = prev_ctx;
20222036 }
@@ -2320,7 +2334,10 @@ impl Compiler {
23202334
23212335 self . ctx = prev_ctx;
23222336
2323- self . build_closure ( & code) ;
2337+ let mut funcflags = bytecode:: MakeFunctionFlags :: empty ( ) ;
2338+ if self . build_closure ( & code) {
2339+ funcflags |= bytecode:: MakeFunctionFlags :: CLOSURE ;
2340+ }
23242341
23252342 // List comprehension code:
23262343 self . emit_constant ( ConstantData :: Code {
@@ -2331,7 +2348,7 @@ impl Compiler {
23312348 self . emit_constant ( ConstantData :: Str { value : name } ) ;
23322349
23332350 // Turn code object into function object:
2334- self . emit ( Instruction :: MakeFunction ) ;
2351+ self . emit ( Instruction :: MakeFunction ( funcflags ) ) ;
23352352
23362353 // Evaluate iterated item:
23372354 self . compile_expression ( & generators[ 0 ] . iter ) ?;
0 commit comments