py: Add option to compiler to specify default code emitter.
Also add command line option to unix port to select emitter.
This commit is contained in:
parent
deed087e2c
commit
65cad12d38
@ -33,7 +33,7 @@ STATIC mp_obj_t parse_compile_execute(mp_obj_t o_in, mp_parse_input_kind_t parse
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compile the string
|
// compile the string
|
||||||
mp_obj_t module_fun = mp_compile(pn, source_name, false);
|
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false);
|
||||||
mp_parse_node_free(pn);
|
mp_parse_node_free(pn);
|
||||||
|
|
||||||
if (module_fun == mp_const_none) {
|
if (module_fun == mp_const_none) {
|
||||||
|
@ -103,7 +103,7 @@ void do_load(mp_obj_t module_obj, vstr_t *file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compile the imported script
|
// compile the imported script
|
||||||
mp_obj_t module_fun = mp_compile(pn, source_name, false);
|
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false);
|
||||||
mp_parse_node_free(pn);
|
mp_parse_node_free(pn);
|
||||||
|
|
||||||
if (module_fun == mp_const_none) {
|
if (module_fun == mp_const_none) {
|
||||||
|
30
py/compile.c
30
py/compile.c
@ -36,12 +36,6 @@ typedef enum {
|
|||||||
#define EMIT_INLINE_ASM(fun) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm))
|
#define EMIT_INLINE_ASM(fun) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm))
|
||||||
#define EMIT_INLINE_ASM_ARG(fun, ...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, __VA_ARGS__))
|
#define EMIT_INLINE_ASM_ARG(fun, ...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, __VA_ARGS__))
|
||||||
|
|
||||||
#define EMIT_OPT_NONE (0)
|
|
||||||
#define EMIT_OPT_BYTE_CODE (1)
|
|
||||||
#define EMIT_OPT_NATIVE_PYTHON (2)
|
|
||||||
#define EMIT_OPT_VIPER (3)
|
|
||||||
#define EMIT_OPT_ASM_THUMB (4)
|
|
||||||
|
|
||||||
typedef struct _compiler_t {
|
typedef struct _compiler_t {
|
||||||
qstr source_file;
|
qstr source_file;
|
||||||
bool is_repl;
|
bool is_repl;
|
||||||
@ -1000,16 +994,16 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_
|
|||||||
|
|
||||||
qstr attr = MP_PARSE_NODE_LEAF_ARG(name_nodes[1]);
|
qstr attr = MP_PARSE_NODE_LEAF_ARG(name_nodes[1]);
|
||||||
if (attr == MP_QSTR_byte_code) {
|
if (attr == MP_QSTR_byte_code) {
|
||||||
*emit_options = EMIT_OPT_BYTE_CODE;
|
*emit_options = MP_EMIT_OPT_BYTE_CODE;
|
||||||
#if MICROPY_EMIT_NATIVE
|
#if MICROPY_EMIT_NATIVE
|
||||||
} else if (attr == MP_QSTR_native) {
|
} else if (attr == MP_QSTR_native) {
|
||||||
*emit_options = EMIT_OPT_NATIVE_PYTHON;
|
*emit_options = MP_EMIT_OPT_NATIVE_PYTHON;
|
||||||
} else if (attr == MP_QSTR_viper) {
|
} else if (attr == MP_QSTR_viper) {
|
||||||
*emit_options = EMIT_OPT_VIPER;
|
*emit_options = MP_EMIT_OPT_VIPER;
|
||||||
#endif
|
#endif
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_THUMB
|
||||||
} else if (attr == MP_QSTR_asm_thumb) {
|
} else if (attr == MP_QSTR_asm_thumb) {
|
||||||
*emit_options = EMIT_OPT_ASM_THUMB;
|
*emit_options = MP_EMIT_OPT_ASM_THUMB;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
compile_syntax_error(comp, "invalid micropython decorator");
|
compile_syntax_error(comp, "invalid micropython decorator");
|
||||||
@ -1601,7 +1595,7 @@ void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
// this bit optimises: for <x> in range(...), turning it into an explicitly incremented variable
|
// this bit optimises: for <x> in range(...), turning it into an explicitly incremented variable
|
||||||
// this is actually slower, but uses no heap memory
|
// this is actually slower, but uses no heap memory
|
||||||
// for viper it will be much, much faster
|
// for viper it will be much, much faster
|
||||||
if (/*comp->scope_cur->emit_options == EMIT_OPT_VIPER &&*/ MP_PARSE_NODE_IS_ID(pns->nodes[0]) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_power)) {
|
if (/*comp->scope_cur->emit_options == MP_EMIT_OPT_VIPER &&*/ MP_PARSE_NODE_IS_ID(pns->nodes[0]) && MP_PARSE_NODE_IS_STRUCT_KIND(pns->nodes[1], PN_power)) {
|
||||||
mp_parse_node_struct_t *pns_it = (mp_parse_node_struct_t*)pns->nodes[1];
|
mp_parse_node_struct_t *pns_it = (mp_parse_node_struct_t*)pns->nodes[1];
|
||||||
if (MP_PARSE_NODE_IS_ID(pns_it->nodes[0])
|
if (MP_PARSE_NODE_IS_ID(pns_it->nodes[0])
|
||||||
&& MP_PARSE_NODE_LEAF_ARG(pns_it->nodes[0]) == MP_QSTR_range
|
&& MP_PARSE_NODE_LEAF_ARG(pns_it->nodes[0]) == MP_QSTR_range
|
||||||
@ -3187,7 +3181,7 @@ void compile_scope_compute_things(compiler_t *comp, scope_t *scope) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) {
|
mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is_repl) {
|
||||||
compiler_t *comp = m_new(compiler_t, 1);
|
compiler_t *comp = m_new(compiler_t, 1);
|
||||||
|
|
||||||
comp->source_file = source_file;
|
comp->source_file = source_file;
|
||||||
@ -3208,7 +3202,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) {
|
|||||||
pn = fold_constants(pn);
|
pn = fold_constants(pn);
|
||||||
|
|
||||||
// set the outer scope
|
// set the outer scope
|
||||||
scope_t *module_scope = scope_new_and_link(comp, SCOPE_MODULE, pn, EMIT_OPT_NONE);
|
scope_t *module_scope = scope_new_and_link(comp, SCOPE_MODULE, pn, emit_opt);
|
||||||
|
|
||||||
// compile pass 1
|
// compile pass 1
|
||||||
comp->emit = emit_pass1_new();
|
comp->emit = emit_pass1_new();
|
||||||
@ -3219,7 +3213,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) {
|
|||||||
for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
|
for (scope_t *s = comp->scope_head; s != NULL && !comp->had_error; s = s->next) {
|
||||||
if (false) {
|
if (false) {
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_THUMB
|
||||||
} else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
|
} else if (s->emit_options == MP_EMIT_OPT_ASM_THUMB) {
|
||||||
compile_scope_inline_asm(comp, s, PASS_1);
|
compile_scope_inline_asm(comp, s, PASS_1);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@ -3255,7 +3249,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) {
|
|||||||
// dummy
|
// dummy
|
||||||
|
|
||||||
#if MICROPY_EMIT_INLINE_THUMB
|
#if MICROPY_EMIT_INLINE_THUMB
|
||||||
} else if (s->emit_options == EMIT_OPT_ASM_THUMB) {
|
} else if (s->emit_options == MP_EMIT_OPT_ASM_THUMB) {
|
||||||
// inline assembly for thumb
|
// inline assembly for thumb
|
||||||
if (emit_inline_thumb == NULL) {
|
if (emit_inline_thumb == NULL) {
|
||||||
emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
|
emit_inline_thumb = emit_inline_thumb_new(max_num_labels);
|
||||||
@ -3279,8 +3273,8 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) {
|
|||||||
switch (s->emit_options) {
|
switch (s->emit_options) {
|
||||||
|
|
||||||
#if MICROPY_EMIT_NATIVE
|
#if MICROPY_EMIT_NATIVE
|
||||||
case EMIT_OPT_NATIVE_PYTHON:
|
case MP_EMIT_OPT_NATIVE_PYTHON:
|
||||||
case EMIT_OPT_VIPER:
|
case MP_EMIT_OPT_VIPER:
|
||||||
#if MICROPY_EMIT_X64
|
#if MICROPY_EMIT_X64
|
||||||
if (emit_native == NULL) {
|
if (emit_native == NULL) {
|
||||||
emit_native = emit_native_x64_new(max_num_labels);
|
emit_native = emit_native_x64_new(max_num_labels);
|
||||||
@ -3293,7 +3287,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl) {
|
|||||||
comp->emit_method_table = &emit_native_thumb_method_table;
|
comp->emit_method_table = &emit_native_thumb_method_table;
|
||||||
#endif
|
#endif
|
||||||
comp->emit = emit_native;
|
comp->emit = emit_native;
|
||||||
comp->emit_method_table->set_native_types(comp->emit, s->emit_options == EMIT_OPT_VIPER);
|
comp->emit_method_table->set_native_types(comp->emit, s->emit_options == MP_EMIT_OPT_VIPER);
|
||||||
break;
|
break;
|
||||||
#endif // MICROPY_EMIT_NATIVE
|
#endif // MICROPY_EMIT_NATIVE
|
||||||
|
|
||||||
|
10
py/compile.h
10
py/compile.h
@ -1 +1,9 @@
|
|||||||
mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, bool is_repl);
|
enum {
|
||||||
|
MP_EMIT_OPT_NONE,
|
||||||
|
MP_EMIT_OPT_BYTE_CODE,
|
||||||
|
MP_EMIT_OPT_NATIVE_PYTHON,
|
||||||
|
MP_EMIT_OPT_VIPER,
|
||||||
|
MP_EMIT_OPT_ASM_THUMB,
|
||||||
|
};
|
||||||
|
|
||||||
|
mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is_repl);
|
||||||
|
@ -142,7 +142,7 @@ bool parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bo
|
|||||||
|
|
||||||
mp_lexer_free(lex);
|
mp_lexer_free(lex);
|
||||||
|
|
||||||
mp_obj_t module_fun = mp_compile(pn, source_name, is_repl);
|
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, is_repl);
|
||||||
mp_parse_node_free(pn);
|
mp_parse_node_free(pn);
|
||||||
|
|
||||||
if (module_fun == mp_const_none) {
|
if (module_fun == mp_const_none) {
|
||||||
|
@ -44,7 +44,7 @@ bool parse_compile_execute(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, bo
|
|||||||
|
|
||||||
mp_lexer_free(lex);
|
mp_lexer_free(lex);
|
||||||
|
|
||||||
mp_obj_t module_fun = mp_compile(pn, source_name, is_repl);
|
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, is_repl);
|
||||||
mp_parse_node_free(pn);
|
mp_parse_node_free(pn);
|
||||||
|
|
||||||
if (module_fun == mp_const_none) {
|
if (module_fun == mp_const_none) {
|
||||||
|
@ -359,7 +359,7 @@ bool do_file(const char *filename) {
|
|||||||
|
|
||||||
mp_lexer_free(lex);
|
mp_lexer_free(lex);
|
||||||
|
|
||||||
mp_obj_t module_fun = mp_compile(pn, source_name, false);
|
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false);
|
||||||
mp_parse_node_free(pn);
|
mp_parse_node_free(pn);
|
||||||
|
|
||||||
if (module_fun == mp_const_none) {
|
if (module_fun == mp_const_none) {
|
||||||
@ -422,7 +422,7 @@ void do_repl(void) {
|
|||||||
} else {
|
} else {
|
||||||
// parse okay
|
// parse okay
|
||||||
mp_lexer_free(lex);
|
mp_lexer_free(lex);
|
||||||
mp_obj_t module_fun = mp_compile(pn, source_name, true);
|
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true);
|
||||||
if (module_fun != mp_const_none) {
|
if (module_fun != mp_const_none) {
|
||||||
nlr_buf_t nlr;
|
nlr_buf_t nlr;
|
||||||
uint32_t start = micros();
|
uint32_t start = micros();
|
||||||
|
15
unix/main.c
15
unix/main.c
@ -28,6 +28,9 @@
|
|||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Default emit options
|
||||||
|
uint emit_opt = MP_EMIT_OPT_NONE;
|
||||||
|
|
||||||
#if MICROPY_ENABLE_GC
|
#if MICROPY_ENABLE_GC
|
||||||
// Heap size of GC heap (if enabled)
|
// Heap size of GC heap (if enabled)
|
||||||
// Make it larger on a 64 bit machine, because pointers are larger.
|
// Make it larger on a 64 bit machine, because pointers are larger.
|
||||||
@ -76,7 +79,7 @@ STATIC void execute_from_lexer(mp_lexer_t *lex, mp_parse_input_kind_t input_kind
|
|||||||
printf("----------------\n");
|
printf("----------------\n");
|
||||||
*/
|
*/
|
||||||
|
|
||||||
mp_obj_t module_fun = mp_compile(pn, source_name, is_repl);
|
mp_obj_t module_fun = mp_compile(pn, source_name, emit_opt, is_repl);
|
||||||
|
|
||||||
if (module_fun == mp_const_none) {
|
if (module_fun == mp_const_none) {
|
||||||
// compile error
|
// compile error
|
||||||
@ -221,6 +224,10 @@ int usage(char **argv) {
|
|||||||
"Implementation specific options:\n", argv[0]
|
"Implementation specific options:\n", argv[0]
|
||||||
);
|
);
|
||||||
int impl_opts_cnt = 0;
|
int impl_opts_cnt = 0;
|
||||||
|
printf(
|
||||||
|
" emit={bytecode,native,viper} -- set the default code emitter\n"
|
||||||
|
);
|
||||||
|
impl_opts_cnt++;
|
||||||
#if MICROPY_ENABLE_GC
|
#if MICROPY_ENABLE_GC
|
||||||
printf(
|
printf(
|
||||||
" heapsize=<n> -- set the heap size for the GC\n"
|
" heapsize=<n> -- set the heap size for the GC\n"
|
||||||
@ -265,6 +272,12 @@ void pre_process_options(int argc, char **argv) {
|
|||||||
exit(usage(argv));
|
exit(usage(argv));
|
||||||
}
|
}
|
||||||
if (0) {
|
if (0) {
|
||||||
|
} else if (strcmp(argv[a + 1], "emit=bytecode") == 0) {
|
||||||
|
emit_opt = MP_EMIT_OPT_BYTE_CODE;
|
||||||
|
} else if (strcmp(argv[a + 1], "emit=native") == 0) {
|
||||||
|
emit_opt = MP_EMIT_OPT_NATIVE_PYTHON;
|
||||||
|
} else if (strcmp(argv[a + 1], "emit=viper") == 0) {
|
||||||
|
emit_opt = MP_EMIT_OPT_VIPER;
|
||||||
#if MICROPY_ENABLE_GC
|
#if MICROPY_ENABLE_GC
|
||||||
} else if (strncmp(argv[a + 1], "heapsize=", sizeof("heapsize=") - 1) == 0) {
|
} else if (strncmp(argv[a + 1], "heapsize=", sizeof("heapsize=") - 1) == 0) {
|
||||||
heap_size = strtol(argv[a + 1] + sizeof("heapsize=") - 1, NULL, 0);
|
heap_size = strtol(argv[a + 1] + sizeof("heapsize=") - 1, NULL, 0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user