@@ -56,7 +56,14 @@ struct _emit_t {
5656 mp_uint_t bytecode_offset ;
5757 mp_uint_t bytecode_size ;
5858 byte * code_base ; // stores both byte code and code info
59+
60+ #if MICROPY_PERSISTENT_CODE
61+ uint16_t ct_cur_obj ;
62+ uint16_t ct_num_obj ;
63+ uint16_t ct_cur_raw_code ;
64+ #endif
5965 mp_uint_t * const_table ;
66+
6067 // Accessed as mp_uint_t, so must be aligned as such
6168 byte dummy_data [DUMMY_DATA_SIZE ];
6269};
@@ -108,10 +115,6 @@ STATIC byte *emit_get_cur_to_write_code_info(emit_t *emit, int num_bytes_to_writ
108115 }
109116}
110117
111- STATIC void emit_align_code_info_to_machine_word (emit_t * emit ) {
112- emit -> code_info_offset = (emit -> code_info_offset + sizeof (mp_uint_t ) - 1 ) & (~(sizeof (mp_uint_t ) - 1 ));
113- }
114-
115118STATIC void emit_write_code_info_byte (emit_t * emit , byte val ) {
116119 * emit_get_cur_to_write_code_info (emit , 1 ) = val ;
117120}
@@ -121,7 +124,14 @@ STATIC void emit_write_code_info_uint(emit_t* emit, mp_uint_t val) {
121124}
122125
123126STATIC void emit_write_code_info_qstr (emit_t * emit , qstr qst ) {
127+ #if MICROPY_PERSISTENT_CODE
128+ assert ((qst >> 16 ) == 0 );
129+ byte * c = emit_get_cur_to_write_code_info (emit , 2 );
130+ c [0 ] = qst ;
131+ c [1 ] = qst >> 8 ;
132+ #else
124133 emit_write_uint (emit , emit_get_cur_to_write_code_info , qst );
134+ #endif
125135}
126136
127137#if MICROPY_ENABLE_SOURCE_LINE
@@ -163,10 +173,6 @@ STATIC byte *emit_get_cur_to_write_bytecode(emit_t *emit, int num_bytes_to_write
163173 }
164174}
165175
166- STATIC void emit_align_bytecode_to_machine_word (emit_t * emit ) {
167- emit -> bytecode_offset = (emit -> bytecode_offset + sizeof (mp_uint_t ) - 1 ) & (~(sizeof (mp_uint_t ) - 1 ));
168- }
169-
170176STATIC void emit_write_bytecode_byte (emit_t * emit , byte b1 ) {
171177 byte * c = emit_get_cur_to_write_bytecode (emit , 1 );
172178 c [0 ] = b1 ;
@@ -211,18 +217,55 @@ STATIC void emit_write_bytecode_byte_uint(emit_t *emit, byte b, mp_uint_t val) {
211217 emit_write_uint (emit , emit_get_cur_to_write_bytecode , val );
212218}
213219
214- // aligns the pointer so it is friendly to GC
220+ #if MICROPY_PERSISTENT_CODE
221+ STATIC void emit_write_bytecode_byte_const (emit_t * emit , byte b , mp_uint_t n , mp_uint_t c ) {
222+ if (emit -> pass == MP_PASS_EMIT ) {
223+ emit -> const_table [n ] = c ;
224+ }
225+ emit_write_bytecode_byte_uint (emit , b , n );
226+ }
227+ #else
215228STATIC void emit_write_bytecode_byte_ptr (emit_t * emit , byte b , void * ptr ) {
229+ // aligns the pointer so it is friendly to GC
216230 emit_write_bytecode_byte (emit , b );
217- emit_align_bytecode_to_machine_word ( emit );
231+ emit -> bytecode_offset = ( mp_uint_t ) MP_ALIGN ( emit -> bytecode_offset , sizeof ( mp_uint_t ) );
218232 mp_uint_t * c = (mp_uint_t * )emit_get_cur_to_write_bytecode (emit , sizeof (mp_uint_t ));
219233 // Verify thar c is already uint-aligned
220234 assert (c == MP_ALIGN (c , sizeof (mp_uint_t )));
221235 * c = (mp_uint_t )ptr ;
222236}
237+ #endif
223238
224239STATIC void emit_write_bytecode_byte_qstr (emit_t * emit , byte b , qstr qst ) {
240+ #if MICROPY_PERSISTENT_CODE
241+ assert ((qst >> 16 ) == 0 );
242+ byte * c = emit_get_cur_to_write_bytecode (emit , 3 );
243+ c [0 ] = b ;
244+ c [1 ] = qst ;
245+ c [2 ] = qst >> 8 ;
246+ #else
225247 emit_write_bytecode_byte_uint (emit , b , qst );
248+ #endif
249+ }
250+
251+ STATIC void emit_write_bytecode_byte_obj (emit_t * emit , byte b , void * ptr ) {
252+ #if MICROPY_PERSISTENT_CODE
253+ emit_write_bytecode_byte_const (emit , b ,
254+ emit -> scope -> num_pos_args + emit -> scope -> num_kwonly_args
255+ + emit -> ct_cur_obj ++ , (mp_uint_t )ptr );
256+ #else
257+ emit_write_bytecode_byte_ptr (emit , b , ptr );
258+ #endif
259+ }
260+
261+ STATIC void emit_write_bytecode_byte_raw_code (emit_t * emit , byte b , mp_raw_code_t * rc ) {
262+ #if MICROPY_PERSISTENT_CODE
263+ emit_write_bytecode_byte_const (emit , b ,
264+ emit -> scope -> num_pos_args + emit -> scope -> num_kwonly_args
265+ + emit -> ct_num_obj + emit -> ct_cur_raw_code ++ , (mp_uint_t )rc );
266+ #else
267+ emit_write_bytecode_byte_ptr (emit , b , rc );
268+ #endif
226269}
227270
228271// unsigned labels are relative to ip following this instruction, stored as 16 bits
@@ -318,6 +361,11 @@ void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
318361 }
319362 emit_write_bytecode_byte (emit , 255 ); // end of list sentinel
320363
364+ #if MICROPY_PERSISTENT_CODE
365+ emit -> ct_cur_obj = 0 ;
366+ emit -> ct_cur_raw_code = 0 ;
367+ #endif
368+
321369 if (pass == MP_PASS_EMIT ) {
322370 // Write argument names (needed to resolve positional args passed as
323371 // keywords). We store them as full word-sized objects for efficient access
@@ -360,16 +408,30 @@ void mp_emit_bc_end_pass(emit_t *emit) {
360408
361409 emit_write_code_info_byte (emit , 0 ); // end of line number info
362410
411+ #if MICROPY_PERSISTENT_CODE
412+ assert (emit -> pass <= MP_PASS_STACK_SIZE || (emit -> ct_num_obj == emit -> ct_cur_obj ));
413+ emit -> ct_num_obj = emit -> ct_cur_obj ;
414+ #endif
415+
363416 if (emit -> pass == MP_PASS_CODE_SIZE ) {
417+ #if !MICROPY_PERSISTENT_CODE
364418 // so bytecode is aligned
365- emit_align_code_info_to_machine_word (emit );
419+ emit -> code_info_offset = (mp_uint_t )MP_ALIGN (emit -> code_info_offset , sizeof (mp_uint_t ));
420+ #endif
366421
367422 // calculate size of total code-info + bytecode, in bytes
368423 emit -> code_info_size = emit -> code_info_offset ;
369424 emit -> bytecode_size = emit -> bytecode_offset ;
370425 emit -> code_base = m_new0 (byte , emit -> code_info_size + emit -> bytecode_size );
371426
372- emit -> const_table = m_new0 (mp_uint_t , emit -> scope -> num_pos_args + emit -> scope -> num_kwonly_args );
427+ #if MICROPY_PERSISTENT_CODE
428+ emit -> const_table = m_new0 (mp_uint_t ,
429+ emit -> scope -> num_pos_args + emit -> scope -> num_kwonly_args
430+ + emit -> ct_cur_obj + emit -> ct_cur_raw_code );
431+ #else
432+ emit -> const_table = m_new0 (mp_uint_t ,
433+ emit -> scope -> num_pos_args + emit -> scope -> num_kwonly_args );
434+ #endif
373435
374436 } else if (emit -> pass == MP_PASS_EMIT ) {
375437 mp_emit_glue_assign_bytecode (emit -> scope -> raw_code , emit -> code_base ,
@@ -457,7 +519,7 @@ void mp_emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
457519 case MP_TOKEN_KW_NONE : emit_write_bytecode_byte (emit , MP_BC_LOAD_CONST_NONE ); break ;
458520 case MP_TOKEN_KW_TRUE : emit_write_bytecode_byte (emit , MP_BC_LOAD_CONST_TRUE ); break ;
459521 no_other_choice :
460- case MP_TOKEN_ELLIPSIS : emit_write_bytecode_byte_ptr (emit , MP_BC_LOAD_CONST_OBJ , (void * )& mp_const_ellipsis_obj ); break ;
522+ case MP_TOKEN_ELLIPSIS : emit_write_bytecode_byte_obj (emit , MP_BC_LOAD_CONST_OBJ , (void * )& mp_const_ellipsis_obj ); break ;
461523 default : assert (0 ); goto no_other_choice ; // to help flow control analysis
462524 }
463525}
@@ -478,7 +540,7 @@ void mp_emit_bc_load_const_str(emit_t *emit, qstr qst) {
478540
479541void mp_emit_bc_load_const_obj (emit_t * emit , void * obj ) {
480542 emit_bc_pre (emit , 1 );
481- emit_write_bytecode_byte_ptr (emit , MP_BC_LOAD_CONST_OBJ , obj );
543+ emit_write_bytecode_byte_obj (emit , MP_BC_LOAD_CONST_OBJ , obj );
482544}
483545
484546void mp_emit_bc_load_null (emit_t * emit ) {
@@ -821,22 +883,22 @@ void mp_emit_bc_unpack_ex(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right) {
821883void mp_emit_bc_make_function (emit_t * emit , scope_t * scope , mp_uint_t n_pos_defaults , mp_uint_t n_kw_defaults ) {
822884 if (n_pos_defaults == 0 && n_kw_defaults == 0 ) {
823885 emit_bc_pre (emit , 1 );
824- emit_write_bytecode_byte_ptr (emit , MP_BC_MAKE_FUNCTION , scope -> raw_code );
886+ emit_write_bytecode_byte_raw_code (emit , MP_BC_MAKE_FUNCTION , scope -> raw_code );
825887 } else {
826888 emit_bc_pre (emit , -1 );
827- emit_write_bytecode_byte_ptr (emit , MP_BC_MAKE_FUNCTION_DEFARGS , scope -> raw_code );
889+ emit_write_bytecode_byte_raw_code (emit , MP_BC_MAKE_FUNCTION_DEFARGS , scope -> raw_code );
828890 }
829891}
830892
831893void mp_emit_bc_make_closure (emit_t * emit , scope_t * scope , mp_uint_t n_closed_over , mp_uint_t n_pos_defaults , mp_uint_t n_kw_defaults ) {
832894 if (n_pos_defaults == 0 && n_kw_defaults == 0 ) {
833895 emit_bc_pre (emit , - n_closed_over + 1 );
834- emit_write_bytecode_byte_ptr (emit , MP_BC_MAKE_CLOSURE , scope -> raw_code );
896+ emit_write_bytecode_byte_raw_code (emit , MP_BC_MAKE_CLOSURE , scope -> raw_code );
835897 emit_write_bytecode_byte (emit , n_closed_over );
836898 } else {
837899 assert (n_closed_over <= 255 );
838900 emit_bc_pre (emit , -2 - n_closed_over + 1 );
839- emit_write_bytecode_byte_ptr (emit , MP_BC_MAKE_CLOSURE_DEFARGS , scope -> raw_code );
901+ emit_write_bytecode_byte_raw_code (emit , MP_BC_MAKE_CLOSURE_DEFARGS , scope -> raw_code );
840902 emit_write_bytecode_byte (emit , n_closed_over );
841903 }
842904}
0 commit comments