@@ -51,11 +51,17 @@ struct PyCompileInput {
5151 metas : Vec < Meta > ,
5252}
5353
54+ struct PyCompileResult {
55+ code_obj : CodeObject ,
56+ lazy_static : bool ,
57+ }
58+
5459impl PyCompileInput {
55- fn compile ( & self ) -> Result < CodeObject , Diagnostic > {
60+ fn compile ( & self ) -> Result < PyCompileResult , Diagnostic > {
5661 let mut source_path = None ;
5762 let mut mode = None ;
5863 let mut source: Option < CompilationSource > = None ;
64+ let mut lazy_static = false ;
5965
6066 fn assert_source_empty ( source : & Option < CompilationSource > ) -> Result < ( ) , Diagnostic > {
6167 if let Some ( source) = source {
@@ -108,11 +114,16 @@ impl PyCompileInput {
108114 } ) ;
109115 }
110116 }
117+ Meta :: Word ( ident) => {
118+ if ident == "lazy_static" {
119+ lazy_static = true ;
120+ }
121+ }
111122 _ => { }
112123 }
113124 }
114125
115- source
126+ let code_obj = source
116127 . ok_or_else ( || {
117128 Diagnostic :: span_error (
118129 self . span . clone ( ) ,
@@ -122,7 +133,12 @@ impl PyCompileInput {
122133 . compile (
123134 & mode. unwrap_or ( compile:: Mode :: Exec ) ,
124135 source_path. unwrap_or_else ( || "frozen" . to_string ( ) ) ,
125- )
136+ ) ?;
137+
138+ Ok ( PyCompileResult {
139+ code_obj,
140+ lazy_static,
141+ } )
126142 }
127143}
128144
@@ -140,16 +156,32 @@ impl Parse for PyCompileInput {
140156pub fn impl_py_compile_bytecode ( input : TokenStream2 ) -> Result < TokenStream2 , Diagnostic > {
141157 let input: PyCompileInput = parse2 ( input) ?;
142158
143- let code_obj = input. compile ( ) ?;
159+ let PyCompileResult {
160+ code_obj,
161+ lazy_static,
162+ } = input. compile ( ) ?;
163+
144164 let bytes = bincode:: serialize ( & code_obj) . expect ( "Failed to serialize" ) ;
145165 let bytes = LitByteStr :: new ( & bytes, Span :: call_site ( ) ) ;
146166
147167 let output = quote ! {
148168 ( {
149- use bincode;
150- bincode:: deserialize( #bytes) . expect( "Deserializing CodeObject failed" )
169+ use :: bincode;
170+ bincode:: deserialize:: < :: rustpython_vm :: bytecode :: CodeObject > ( #bytes) . expect( "Deserializing CodeObject failed" )
151171 } )
152172 } ;
153173
154- Ok ( output)
174+ if lazy_static {
175+ Ok ( quote ! {
176+ ( {
177+ use :: lazy_static:: lazy_static;
178+ lazy_static! {
179+ static ref STATIC : :: rustpython_vm:: bytecode:: CodeObject = #output;
180+ }
181+ & * STATIC
182+ } )
183+ } )
184+ } else {
185+ Ok ( output)
186+ }
155187}
0 commit comments