@@ -30,7 +30,26 @@ struct Compiler<O: OutputStream = BasicOutputStream> {
3030 current_source_location : ast:: Location ,
3131 current_qualified_path : Option < String > ,
3232 ctx : CompileContext ,
33- optimize : u8 ,
33+ opts : CompileOpts ,
34+ }
35+
36+ #[ derive( Debug , Clone ) ]
37+ pub struct CompileOpts {
38+ /// How optimized the bytecode output should be; any optimize > 0 does
39+ /// not emit assert statements
40+ pub optimize : u8 ,
41+ /// Whether introspection on defined functions/other items should be allowed;
42+ /// e.g. when true, `func.__globals__` throws an error (where func is a function defined
43+ /// in an incognito context)
44+ pub incognito : bool ,
45+ }
46+ impl Default for CompileOpts {
47+ fn default ( ) -> Self {
48+ CompileOpts {
49+ optimize : 0 ,
50+ incognito : false ,
51+ }
52+ }
3453}
3554
3655#[ derive( Clone , Copy ) ]
@@ -60,31 +79,31 @@ pub fn compile(
6079 source : & str ,
6180 mode : Mode ,
6281 source_path : String ,
63- optimize : u8 ,
82+ opts : CompileOpts ,
6483) -> CompileResult < CodeObject > {
6584 match mode {
6685 Mode :: Exec => {
6786 let ast = parser:: parse_program ( source) ?;
68- compile_program ( ast, source_path, optimize )
87+ compile_program ( ast, source_path. clone ( ) , opts )
6988 }
7089 Mode :: Eval => {
7190 let statement = parser:: parse_statement ( source) ?;
72- compile_statement_eval ( statement, source_path, optimize )
91+ compile_statement_eval ( statement, source_path. clone ( ) , opts )
7392 }
7493 Mode :: Single => {
7594 let ast = parser:: parse_program ( source) ?;
76- compile_program_single ( ast, source_path, optimize )
95+ compile_program_single ( ast, source_path. clone ( ) , opts )
7796 }
7897 }
7998}
8099
81100/// A helper function for the shared code of the different compile functions
82101fn with_compiler (
83102 source_path : String ,
84- optimize : u8 ,
103+ opts : CompileOpts ,
85104 f : impl FnOnce ( & mut Compiler ) -> CompileResult < ( ) > ,
86105) -> CompileResult < CodeObject > {
87- let mut compiler = Compiler :: new ( optimize ) ;
106+ let mut compiler = Compiler :: new ( opts ) ;
88107 compiler. source_path = Some ( source_path) ;
89108 compiler. push_new_code_object ( "<module>" . to_owned ( ) ) ;
90109 f ( & mut compiler) ?;
@@ -97,9 +116,9 @@ fn with_compiler(
97116pub fn compile_program (
98117 ast : ast:: Program ,
99118 source_path : String ,
100- optimize : u8 ,
119+ opts : CompileOpts ,
101120) -> CompileResult < CodeObject > {
102- with_compiler ( source_path, optimize , |compiler| {
121+ with_compiler ( source_path, opts , |compiler| {
103122 let symbol_table = make_symbol_table ( & ast) ?;
104123 compiler. compile_program ( & ast, symbol_table)
105124 } )
@@ -109,9 +128,9 @@ pub fn compile_program(
109128pub fn compile_statement_eval (
110129 statement : Vec < ast:: Statement > ,
111130 source_path : String ,
112- optimize : u8 ,
131+ opts : CompileOpts ,
113132) -> CompileResult < CodeObject > {
114- with_compiler ( source_path, optimize , |compiler| {
133+ with_compiler ( source_path, opts , |compiler| {
115134 let symbol_table = statements_to_symbol_table ( & statement) ?;
116135 compiler. compile_statement_eval ( & statement, symbol_table)
117136 } )
@@ -121,9 +140,9 @@ pub fn compile_statement_eval(
121140pub fn compile_program_single (
122141 ast : ast:: Program ,
123142 source_path : String ,
124- optimize : u8 ,
143+ opts : CompileOpts ,
125144) -> CompileResult < CodeObject > {
126- with_compiler ( source_path, optimize , |compiler| {
145+ with_compiler ( source_path, opts , |compiler| {
127146 let symbol_table =
2358
make_symbol_table ( & ast) ?;
128147 compiler. compile_program_single ( & ast, symbol_table)
129148 } )
@@ -134,12 +153,12 @@ where
134153 O : OutputStream ,
135154{
136155 fn default ( ) -> Self {
137- Compiler :: new ( 0 )
156+ Compiler :: new ( CompileOpts :: default ( ) )
138157 }
139158}
140159
141160impl < O : OutputStream > Compiler < O > {
142- fn new ( optimize : u8 ) -> Self {
161+ fn new ( opts : CompileOpts ) -> Self {
143162 Compiler {
144163 output_stack : Vec :: new ( ) ,
145164 symbol_table_stack : Vec :: new ( ) ,
@@ -151,7 +170,7 @@ impl<O: OutputStream> Compiler<O> {
151170 in_loop : false ,
152171 func : FunctionContext :: NoFunction ,
153172 } ,
154- optimize ,
173+ opts ,
155174 }
156175 }
157176
@@ -167,7 +186,8 @@ impl<O: OutputStream> Compiler<O> {
167186 }
168187 }
169188
170- fn push_output ( & mut self , code : CodeObject ) {
189+ fn push_output ( & mut self , mut code : CodeObject ) {
190+ code. incognito = self . opts . incognito ;
171191 self . output_stack . push ( code. into ( ) ) ;
172192 }
173193
@@ -518,7 +538,7 @@ impl<O: OutputStream> Compiler<O> {
518538 } => self . compile_class_def ( name, body, bases, keywords, decorator_list) ?,
519539 Assert { test, msg } => {
520540 // if some flag, ignore all assert statements!
521- if self . optimize == 0 {
541+ if self . opts . optimize == 0 {
522542 let end_label = self . new_label ( ) ;
523543 self . compile_jump_if ( test, true , end_label) ?;
524544 self . emit ( Instruction :: LoadName {
0 commit comments