31
31
32
32
// These variables and functions glue the code emitters to the runtime.
33
33
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
+
34
39
// These must fit in 8 bits; see scope.h
35
40
enum {
36
41
MP_EMIT_OPT_NONE ,
@@ -49,14 +54,25 @@ typedef enum {
49
54
MP_CODE_NATIVE_ASM ,
50
55
} mp_raw_code_kind_t ;
51
56
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.
53
58
// 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:
56
71
// compiled bytecode: instance in RAM, referenced by outer scope, usually freed after first (and only) use
57
72
// mpy file: instance in RAM, created when .mpy file is loaded (same comments as above)
58
73
// frozen: instance in ROM
59
74
typedef struct _mp_raw_code_t {
75
+ uint8_t proto_fun_indicator [2 ];
60
76
uint8_t kind ; // of type mp_raw_code_kind_t; only 3 bits used
61
77
bool is_generator ;
62
78
const void * fun_data ;
@@ -88,6 +104,7 @@ typedef struct _mp_raw_code_t {
88
104
// only needed when the kind is MP_CODE_NATIVE_ASM. So this struct can be used when the
89
105
// kind is MP_CODE_BYTECODE, MP_CODE_NATIVE_PY or MP_CODE_NATIVE_VIPER, to reduce its size.
90
106
typedef struct _mp_raw_code_truncated_t {
107
+ uint8_t proto_fun_indicator [2 ];
91
108
uint8_t kind ;
92
109
bool is_generator ;
93
110
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
127
144
#endif
128
145
uint16_t scope_flags , uint32_t asm_n_pos_args , uint32_t asm_type_sig );
129
146
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 );
132
149
133
150
#endif // MICROPY_INCLUDED_PY_EMITGLUE_H
0 commit comments