Skip to content

Commit 4145377

Browse files
committed
py: Add MICROPY_USE_SMALL_HEAP_COMPILER option, disabled by default.
This new option allows the original and new parser/compiler to coexist.
1 parent 39b465c commit 4145377

File tree

10 files changed

+48
-14
lines changed

10 files changed

+48
-14
lines changed

py/compile.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
#include "py/runtime.h"
3737
#include "py/asmbase.h"
3838

39-
#if MICROPY_ENABLE_COMPILER
39+
#if MICROPY_ENABLE_COMPILER && !MICROPY_USE_SMALL_HEAP_COMPILER
4040

4141
// TODO need to mangle __attr names
4242

@@ -3514,4 +3514,4 @@ mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, uint emit_opt
35143514
return mp_make_function_from_raw_code(rc, MP_OBJ_NULL, MP_OBJ_NULL);
35153515
}
35163516

3517-
#endif // MICROPY_ENABLE_COMPILER
3517+
#endif // MICROPY_ENABLE_COMPILER && !MICROPY_USE_SMALL_HEAP_COMPILER

py/compile2.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
#include "py/compile.h"
3636
#include "py/runtime.h"
3737

38-
#if MICROPY_ENABLE_COMPILER
38+
#if MICROPY_ENABLE_COMPILER && MICROPY_USE_SMALL_HEAP_COMPILER
3939

4040
#if MICROPY_PY_ASYNC_AWAIT
4141
#error "async/await syntax not implemented with this parser/compiler"
@@ -3476,4 +3476,4 @@ mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, uint emit_opt
34763476
return mp_make_function_from_raw_code(rc, MP_OBJ_NULL, MP_OBJ_NULL);
34773477
}
34783478

3479-
#endif // MICROPY_ENABLE_COMPILER
3479+
#endif // MICROPY_ENABLE_COMPILER && MICROPY_USE_SMALL_HEAP_COMPILER

py/mpconfig.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,14 @@
358358
#define MICROPY_COMP_RETURN_IF_EXPR (0)
359359
#endif
360360

361+
// Whether to use an alternate parser and compiler optimised for small heaps.
362+
// This parser/compiler uses more code space but a lot less heap when building
363+
// the parse tree. But it has the disadvantage that the entire parse tree must
364+
// fit in a contiguous chunk of memory on the heap.
365+
#ifndef MICROPY_USE_SMALL_HEAP_COMPILER
366+
#define MICROPY_USE_SMALL_HEAP_COMPILER (0)
367+
#endif
368+
361369
/*****************************************************************************/
362370
/* Internal debugging stuff */
363371

@@ -678,7 +686,7 @@ typedef double mp_float_t;
678686

679687
// Support for async/await/async for/async with
680688
#ifndef MICROPY_PY_ASYNC_AWAIT
681-
#define MICROPY_PY_ASYNC_AWAIT (1)
689+
#define MICROPY_PY_ASYNC_AWAIT (!MICROPY_USE_SMALL_HEAP_COMPILER)
682690
#endif
683691

684692
// Issue a warning when comparing str and bytes objects

py/parse.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
#include "py/objstr.h"
4242
#include "py/builtin.h"
4343

44-
#if MICROPY_ENABLE_COMPILER
44+
#if MICROPY_ENABLE_COMPILER && !MICROPY_USE_SMALL_HEAP_COMPILER
4545

4646
#define RULE_ACT_ARG_MASK (0x0f)
4747
#define RULE_ACT_KIND_MASK (0x30)
@@ -1081,4 +1081,4 @@ void mp_parse_tree_clear(mp_parse_tree_t *tree) {
10811081
}
10821082
}
10831083

1084-
#endif // MICROPY_ENABLE_COMPILER
1084+
#endif // MICROPY_ENABLE_COMPILER && !MICROPY_USE_SMALL_HEAP_COMPILER

py/parse.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,17 @@
2323
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2424
* THE SOFTWARE.
2525
*/
26-
#include "py/parse2.h"
2726
#ifndef MICROPY_INCLUDED_PY_PARSE_H
2827
#define MICROPY_INCLUDED_PY_PARSE_H
2928

3029
#include <stddef.h>
3130
#include <stdint.h>
3231

32+
#include "py/parse2.h"
3333
#include "py/obj.h"
3434

35+
#if !MICROPY_USE_SMALL_HEAP_COMPILER
36+
3537
struct _mp_lexer_t;
3638

3739
// a mp_parse_node_t is:
@@ -105,4 +107,6 @@ typedef struct _mp_parse_t {
105107
mp_parse_tree_t mp_parse(struct _mp_lexer_t *lex, mp_parse_input_kind_t input_kind);
106108
void mp_parse_tree_clear(mp_parse_tree_t *tree);
107109

110+
#endif // !MICROPY_USE_SMALL_HEAP_COMPILER
111+
108112
#endif // MICROPY_INCLUDED_PY_PARSE_H

py/parse2.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
#include "py/parsenum.h"
3737
#include "py/smallint.h"
3838

39+
#if MICROPY_ENABLE_COMPILER && MICROPY_USE_SMALL_HEAP_COMPILER
40+
3941
#define RULE_ACT_ARG_MASK (0x0f)
4042
#define RULE_ACT_KIND_MASK (0x30)
4143
#define RULE_ACT_ALLOW_IDENT (0x40)
@@ -1445,3 +1447,5 @@ void mp_parse_tree_clear(mp_parse_tree_t *tree) {
14451447
chunk = next;
14461448
}
14471449
}
1450+
1451+
#endif // MICROPY_ENABLE_COMPILER && MICROPY_USE_SMALL_HEAP_COMPILER

py/parse2.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@
2323
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2424
* THE SOFTWARE.
2525
*/
26-
#ifndef MICROPY_INCLUDED_PY_PARSE_H
27-
#define MICROPY_INCLUDED_PY_PARSE_H
26+
#ifndef MICROPY_INCLUDED_PY_PARSE2_H
27+
#define MICROPY_INCLUDED_PY_PARSE2_H
2828

2929
#include <stddef.h>
3030
#include <stdint.h>
3131

3232
#include "py/obj.h"
3333

34+
#if MICROPY_USE_SMALL_HEAP_COMPILER
35+
3436
struct _mp_lexer_t;
3537

3638
#define MP_PT_NULL (0)
@@ -42,6 +44,8 @@ struct _mp_lexer_t;
4244
#define MP_PT_ID_BASE (10) // +16
4345
#define MP_PT_RULE_BASE (26) // +173-ish
4446

47+
typedef const byte *mp_parse_node_t;
48+
4549
extern const byte pt_const_int0[];
4650

4751
static inline const byte *pt_tok_extract(const byte *p, byte *tok) {
@@ -130,4 +134,6 @@ typedef struct _mp_parse_t {
130134
mp_parse_tree_t mp_parse(struct _mp_lexer_t *lex, mp_parse_input_kind_t input_kind);
131135
void mp_parse_tree_clear(mp_parse_tree_t *tree);
132136

133-
#endif // MICROPY_INCLUDED_PY_PARSE_H
137+
#endif // MICROPY_USE_SMALL_HEAP_COMPILER
138+
139+
#endif // MICROPY_INCLUDED_PY_PARSE2_H

py/py.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,10 @@ PY_O_BASENAME = \
117117
mpz.o \
118118
reader.o \
119119
lexer.o \
120+
parse.o \
120121
parse2.o \
121122
scope.o \
123+
compile.o \
122124
compile2.o \
123125
emitcommon.o \
124126
emitbc.o \

py/scope.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,25 @@ STATIC const uint8_t scope_simple_name_table[] = {
4040
[SCOPE_GEN_EXPR] = MP_QSTR__lt_genexpr_gt_,
4141
};
4242

43-
scope_t *scope_new(scope_kind_t kind, const byte *pn, qstr source_file, mp_uint_t emit_options) {
43+
scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, mp_uint_t emit_options) {
4444
scope_t *scope = m_new0(scope_t, 1);
4545
scope->kind = kind;
4646
scope->pn = pn;
4747
scope->source_file = source_file;
4848
if (kind == SCOPE_FUNCTION || kind == SCOPE_CLASS) {
49+
#if MICROPY_USE_SMALL_HEAP_COMPILER
4950
qstr id;
5051
pt_extract_id(pn, &id); // function name
5152
scope->simple_name = id;
53+
#else
54+
scope->simple_name = MP_PARSE_NODE_LEAF_ARG(((mp_parse_node_struct_t*)pn)->nodes[0]);
55+
#endif
5256
} else {
5357
scope->simple_name = scope_simple_name_table[kind];
5458
}
59+
#if !MICROPY_USE_SMALL_HEAP_COMPILER
60+
scope->raw_code = mp_emit_glue_new_raw_code();
61+
#endif
5562
scope->emit_options = emit_options;
5663
scope->id_info_alloc = MICROPY_ALLOC_SCOPE_ID_INIT;
5764
scope->id_info = m_new(id_info_t, scope->id_info_alloc);

py/scope.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,10 @@ typedef enum {
6969
typedef struct _scope_t {
7070
scope_kind_t kind;
7171
struct _scope_t *parent;
72-
const byte *pn; // points to the node after the scope index node
72+
#if !MICROPY_USE_SMALL_HEAP_COMPILER
73+
struct _scope_t *next;
74+
#endif
75+
mp_parse_node_t pn; // for small-heap compiler, points to the node after the scope index node
7376
uint16_t source_file; // a qstr
7477
uint16_t simple_name; // a qstr
7578
mp_raw_code_t *raw_code;
@@ -86,7 +89,7 @@ typedef struct _scope_t {
8689
id_info_t *id_info;
8790
} scope_t;
8891

89-
scope_t *scope_new(scope_kind_t kind, const byte *pn, qstr source_file, mp_uint_t emit_options);
92+
scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, mp_uint_t emit_options);
9093
void scope_free(scope_t *scope);
9194
id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added);
9295
id_info_t *scope_find(scope_t *scope, qstr qstr);

0 commit comments

Comments
 (0)