3434#include "lexerunix.h"
3535#include "parse.h"
3636#include "obj.h"
37+ #include "objfun.h"
3738#include "parsehelper.h"
3839#include "compile.h"
3940#include "runtime0.h"
4041#include "runtime.h"
4142#include "builtin.h"
4243
43- STATIC mp_obj_t eval_exec_helper (mp_uint_t n_args , const mp_obj_t * args , mp_parse_input_kind_t parse_input_kind ) {
44+ #if MICROPY_PY_BUILTINS_COMPILE
45+
46+ typedef struct _mp_obj_code_t {
47+ mp_obj_base_t base ;
48+ mp_obj_t module_fun ;
49+ } mp_obj_code_t ;
50+
51+ STATIC const mp_obj_type_t mp_type_code = {
52+ { & mp_type_type },
53+ .name = MP_QSTR_code ,
54+ };
55+
56+ STATIC mp_obj_t code_execute (mp_obj_code_t * self , mp_obj_t globals , mp_obj_t locals ) {
57+ // save context and set new context
58+ mp_obj_dict_t * old_globals = mp_globals_get ();
59+ mp_obj_dict_t * old_locals = mp_locals_get ();
60+ mp_globals_set (globals );
61+ mp_locals_set (locals );
62+
63+ // a bit of a hack: fun_bc will re-set globals, so need to make sure it's
64+ // the correct one
65+ if (MP_OBJ_IS_TYPE (self -> module_fun , & mp_type_fun_bc )) {
66+ mp_obj_fun_bc_t * fun_bc = self -> module_fun ;
67+ fun_bc -> globals = globals ;
68+ }
69+
70+ // execute code
71+ nlr_buf_t nlr ;
72+ if (nlr_push (& nlr ) == 0 ) {
73+ mp_obj_t ret = mp_call_function_0 (self -> module_fun );
74+ nlr_pop ();
75+ mp_globals_set (old_globals );
76+ mp_locals_set (old_locals );
77+ return ret ;
78+ } else {
79+ // exception; restore context and re-raise same exception
80+ mp_globals_set (old_globals );
81+ mp_locals_set (old_locals );
82+ nlr_raise (nlr .ret_val );
83+ }
84+ }
85+
86+ STATIC mp_obj_t mp_builtin_compile (mp_uint_t n_args , const mp_obj_t * args ) {
87+ // get the source
4488 mp_uint_t str_len ;
4589 const char * str = mp_obj_str_get_data (args [0 ], & str_len );
4690
91+ // get the filename
92+ qstr filename = mp_obj_str_get_qstr (args [1 ]);
93+
4794 // create the lexer
48- mp_lexer_t * lex = mp_lexer_new_from_str_len (MP_QSTR__lt_string_gt_ , str , str_len , 0 );
95+ mp_lexer_t * lex = mp_lexer_new_from_str_len (filename , str , str_len , 0 );
96+
97+ // get the compile mode
98+ qstr mode = mp_obj_str_get_qstr (args [2 ]);
99+ mp_parse_input_kind_t parse_input_kind ;
100+ switch (mode ) {
101+ case MP_QSTR_single : parse_input_kind = MP_PARSE_SINGLE_INPUT ; break ;
102+ case MP_QSTR_exec : parse_input_kind = MP_PARSE_FILE_INPUT ; break ;
103+ case MP_QSTR_eval : parse_input_kind = MP_PARSE_EVAL_INPUT ; break ;
104+ default :
105+ nlr_raise (mp_obj_new_exception_msg (& mp_type_ValueError , "bad compile mode" ));
106+ }
107+
108+ mp_obj_code_t * code = m_new_obj (mp_obj_code_t );
109+ code -> base .type = & mp_type_code ;
110+ code -> module_fun = mp_parse_compile_execute (lex , parse_input_kind , NULL , NULL );
111+ return code ;
112+ }
113+ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN (mp_builtin_compile_obj , 3 , 6 , mp_builtin_compile );
114+
115+ #endif // MICROPY_PY_BUILTINS_COMPILE
49116
117+ STATIC mp_obj_t eval_exec_helper (mp_uint_t n_args , const mp_obj_t * args , mp_parse_input_kind_t parse_input_kind ) {
50118 // work out the context
51119 mp_obj_dict_t * globals = mp_globals_get ();
52120 mp_obj_dict_t * locals = mp_locals_get ();
@@ -59,6 +127,18 @@ STATIC mp_obj_t eval_exec_helper(mp_uint_t n_args, const mp_obj_t *args, mp_pars
59127 }
60128 }
61129
130+ #if MICROPY_PY_BUILTINS_COMPILE
131+ if (MP_OBJ_IS_TYPE (args [0 ], & mp_type_code )) {
132+ return code_execute (args [0 ], globals , locals );
133+ }
134+ #endif
135+
136+ mp_uint_t str_len ;
137+ const char * str = mp_obj_str_get_data (args [0 ], & str_len );
138+
139+ // create the lexer
140+ mp_lexer_t * lex = mp_lexer_new_from_str_len (MP_QSTR__lt_string_gt_ , str , str_len , 0 );
141+
62142 return mp_parse_compile_execute (lex , parse_input_kind , globals , locals );
63143}
64144
0 commit comments