Branch data Line data Source code
1 : : /*
2 : : * This file is part of the MicroPython project, http://micropython.org/
3 : : *
4 : : * The MIT License (MIT)
5 : : *
6 : : * Copyright (c) 2013, 2014 Damien P. George
7 : : *
8 : : * Permission is hereby granted, free of charge, to any person obtaining a copy
9 : : * of this software and associated documentation files (the "Software"), to deal
10 : : * in the Software without restriction, including without limitation the rights
11 : : * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 : : * copies of the Software, and to permit persons to whom the Software is
13 : : * furnished to do so, subject to the following conditions:
14 : : *
15 : : * The above copyright notice and this permission notice shall be included in
16 : : * all copies or substantial portions of the Software.
17 : : *
18 : : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 : : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 : : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 : : * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 : : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 : : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 : : * THE SOFTWARE.
25 : : */
26 : : #ifndef MICROPY_INCLUDED_PY_EMITGLUE_H
27 : : #define MICROPY_INCLUDED_PY_EMITGLUE_H
28 : :
29 : : #include "py/obj.h"
30 : : #include "py/bc.h"
31 : :
32 : : // These variables and functions glue the code emitters to the runtime.
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 : :
39 : : // These must fit in 8 bits; see scope.h
40 : : enum {
41 : : MP_EMIT_OPT_NONE,
42 : : MP_EMIT_OPT_BYTECODE,
43 : : MP_EMIT_OPT_NATIVE_PYTHON,
44 : : MP_EMIT_OPT_VIPER,
45 : : MP_EMIT_OPT_ASM,
46 : : };
47 : :
48 : : typedef enum {
49 : : MP_CODE_UNUSED,
50 : : MP_CODE_RESERVED,
51 : : MP_CODE_BYTECODE,
52 : : MP_CODE_NATIVE_PY,
53 : : MP_CODE_NATIVE_VIPER,
54 : : MP_CODE_NATIVE_ASM,
55 : : } mp_raw_code_kind_t;
56 : :
57 : : // An mp_proto_fun_t points to static information about a non-instantiated function.
58 : : // A function object is created from this information, and that object can then be executed.
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 : 18911 : static inline bool mp_proto_fun_is_bytecode(mp_proto_fun_t proto_fun) {
66 : 18911 : const uint8_t *header = (const uint8_t *)proto_fun;
67 [ + + ]: 18911 : 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:
71 : : // compiled bytecode: instance in RAM, referenced by outer scope, usually freed after first (and only) use
72 : : // mpy file: instance in RAM, created when .mpy file is loaded (same comments as above)
73 : : // frozen: instance in ROM
74 : : typedef struct _mp_raw_code_t {
75 : : uint8_t proto_fun_indicator[2];
76 : : uint8_t kind; // of type mp_raw_code_kind_t; only 3 bits used
77 : : bool is_generator;
78 : : const void *fun_data;
79 : : struct _mp_raw_code_t **children;
80 : : #if MICROPY_PERSISTENT_CODE_SAVE
81 : : uint32_t fun_data_len; // for mp_raw_code_save
82 : : uint16_t n_children;
83 : : #if MICROPY_EMIT_MACHINE_CODE
84 : : uint16_t prelude_offset;
85 : : #endif
86 : : #if MICROPY_PY_SYS_SETTRACE
87 : : // line_of_definition is a Python source line where the raw_code was
88 : : // created e.g. MP_BC_MAKE_FUNCTION. This is different from lineno info
89 : : // stored in prelude, which provides line number for first statement of
90 : : // a function. Required to properly implement "call" trace event.
91 : : uint32_t line_of_definition;
92 : : mp_bytecode_prelude_t prelude;
93 : : #endif
94 : : #endif
95 : : #if MICROPY_EMIT_INLINE_ASM
96 : : uint32_t asm_n_pos_args : 8;
97 : : uint32_t asm_type_sig : 24; // compressed as 2-bit types; ret is MSB, then arg0, arg1, etc
98 : : #endif
99 : : } mp_raw_code_t;
100 : :
101 : : // Version of mp_raw_code_t but without the asm_n_pos_args/asm_type_sig entries, which are
102 : : // only needed when the kind is MP_CODE_NATIVE_ASM. So this struct can be used when the
103 : : // kind is MP_CODE_BYTECODE, MP_CODE_NATIVE_PY or MP_CODE_NATIVE_VIPER, to reduce its size.
104 : : typedef struct _mp_raw_code_truncated_t {
105 : : uint8_t proto_fun_indicator[2];
106 : : uint8_t kind;
107 : : bool is_generator;
108 : : const void *fun_data;
109 : : struct _mp_raw_code_t **children;
110 : : #if MICROPY_PERSISTENT_CODE_SAVE
111 : : uint32_t fun_data_len;
112 : : uint16_t n_children;
113 : : #if MICROPY_EMIT_MACHINE_CODE
114 : : uint16_t prelude_offset;
115 : : #endif
116 : : #if MICROPY_PY_SYS_SETTRACE
117 : : uint32_t line_of_definition;
118 : : mp_bytecode_prelude_t prelude;
119 : : #endif
120 : : #endif
121 : : } mp_raw_code_truncated_t;
122 : :
123 : : mp_raw_code_t *mp_emit_glue_new_raw_code(void);
124 : :
125 : : void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code,
126 : : mp_raw_code_t **children,
127 : : #if MICROPY_PERSISTENT_CODE_SAVE
128 : : size_t len,
129 : : uint16_t n_children,
130 : : #endif
131 : : uint16_t scope_flags);
132 : :
133 : : void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, const void *fun_data, mp_uint_t fun_len,
134 : : mp_raw_code_t **children,
135 : : #if MICROPY_PERSISTENT_CODE_SAVE
136 : : uint16_t n_children,
137 : : uint16_t prelude_offset,
138 : : #endif
139 : : uint16_t scope_flags, uint32_t asm_n_pos_args, uint32_t asm_type_sig);
140 : :
141 : : 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);
142 : : 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);
143 : :
144 : : #endif // MICROPY_INCLUDED_PY_EMITGLUE_H
|