3131
3232// These variables and functions glue the code emitters to the runtime.
3333
34+ // Used with mp_raw_code_t::proto_fun_indicator to detect if a mp_proto_fun_t is a
35+ // mp_raw_code_t struct or a direct pointer to bytecode.
36+ #define MP_PROTO_FUN_INDICATOR_RAW_CODE_0 (0)
37+ #define MP_PROTO_FUN_INDICATOR_RAW_CODE_1 (0)
38+
3439// These must fit in 8 bits; see scope.h
3540enum {
3641 MP_EMIT_OPT_NONE ,
@@ -49,14 +54,25 @@ typedef enum {
4954 MP_CODE_NATIVE_ASM ,
5055} mp_raw_code_kind_t ;
5156
52- // This mp_raw_code_t struct holds static information about a non-instantiated function.
57+ // An mp_proto_fun_t points to static information about a non-instantiated function.
5358// A function object is created from this information, and that object can then be executed.
54- //
55- // This struct appears in the following places:
59+ // It points either to bytecode, or an mp_raw_code_t struct.
60+ typedef const void * mp_proto_fun_t ;
61+
62+ // Bytecode is distinguished from an mp_raw_code_t struct by the first two bytes: bytecode
63+ // is guaranteed to have either its first or second byte non-zero. So if both bytes are
64+ // zero then the mp_proto_fun_t pointer must be an mp_raw_code_t.
65+ static inline bool mp_proto_fun_is_bytecode (mp_proto_fun_t proto_fun ) {
66+ const uint8_t * header = proto_fun ;
67+ return (header [0 ] | (header [1 ] << 8 )) != (MP_PROTO_FUN_INDICATOR_RAW_CODE_0 | (MP_PROTO_FUN_INDICATOR_RAW_CODE_1 << 8 ));
68+ }
69+
70+ // The mp_raw_code_t struct appears in the following places:
5671// compiled bytecode: instance in RAM, referenced by outer scope, usually freed after first (and only) use
5772// mpy file: instance in RAM, created when .mpy file is loaded (same comments as above)
5873// frozen: instance in ROM
5974typedef struct _mp_raw_code_t {
75+ uint8_t proto_fun_indicator [2 ];
6076 uint8_t kind ; // of type mp_raw_code_kind_t; only 3 bits used
6177 bool is_generator ;
6278 const void * fun_data ;
@@ -88,6 +104,7 @@ typedef struct _mp_raw_code_t {
88104// only needed when the kind is MP_CODE_NATIVE_ASM. So this struct can be used when the
89105// kind is MP_CODE_BYTECODE, MP_CODE_NATIVE_PY or MP_CODE_NATIVE_VIPER, to reduce its size.
90106typedef struct _mp_raw_code_truncated_t {
107+ uint8_t proto_fun_indicator [2 ];
91108 uint8_t kind ;
92109 bool is_generator ;
93110 const void * fun_data ;
@@ -127,7 +144,7 @@ void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, void
127144 #endif
128145 uint16_t scope_flags , uint32_t asm_n_pos_args , uint32_t asm_type_sig );
129146
130- mp_obj_t mp_make_function_from_raw_code ( const mp_raw_code_t * rc , const mp_module_context_t * context , const mp_obj_t * def_args );
131- mp_obj_t mp_make_closure_from_raw_code ( const mp_raw_code_t * rc , const mp_module_context_t * context , mp_uint_t n_closed_over , const mp_obj_t * args );
147+ mp_obj_t mp_make_function_from_proto_fun ( mp_proto_fun_t proto_fun , const mp_module_context_t * context , const mp_obj_t * def_args );
148+ mp_obj_t mp_make_closure_from_proto_fun ( mp_proto_fun_t proto_fun , const mp_module_context_t * context , mp_uint_t n_closed_over , const mp_obj_t * args );
132149
133150#endif // MICROPY_INCLUDED_PY_EMITGLUE_H
0 commit comments