diff options
author | Damien <damien.p.george@gmail.com> | 2013-12-21 18:17:45 +0000 |
---|---|---|
committer | Damien <damien.p.george@gmail.com> | 2013-12-21 18:17:45 +0000 |
commit | d99b05282d14ceb0163cbcd059aa37bdb415af43 (patch) | |
tree | 978135f9fe83d3c4d5b3c95f84cb104c0092936a /unix | |
parent | e2880aa2fdc75298df487df7519d483acb03959c (diff) |
Change object representation from 1 big union to individual structs.
A big change. Micro Python objects are allocated as individual structs
with the first element being a pointer to the type information (which
is itself an object). This scheme follows CPython. Much more flexible,
not necessarily slower, uses same heap memory, and can allocate objects
statically.
Also change name prefix, from py_ to mp_ (mp for Micro Python).
Diffstat (limited to 'unix')
-rw-r--r-- | unix/Makefile | 25 | ||||
-rw-r--r-- | unix/lexerunix.c | 10 | ||||
-rw-r--r-- | unix/lexerunix.h | 4 | ||||
-rw-r--r-- | unix/main.c | 114 | ||||
-rw-r--r-- | unix/mpconfig.h (renamed from unix/mpyconfig.h) | 1 |
5 files changed, 99 insertions, 55 deletions
diff --git a/unix/Makefile b/unix/Makefile index 76cc0a385..463f6b170 100644 --- a/unix/Makefile +++ b/unix/Makefile @@ -31,6 +31,25 @@ PY_O = \ runtime.o \ map.o \ obj.o \ + objbool.o \ + objboundmeth.o \ + objcell.o \ + objclass.o \ + objclosure.o \ + objcomplex.o \ + objdict.o \ + objexcept.o \ + objfloat.o \ + objfun.o \ + objgenerator.o \ + objinstance.o \ + objlist.o \ + objnone.o \ + objrange.o \ + objset.o \ + objstr.o \ + objtuple.o \ + objtype.o \ builtin.o \ vm.o \ showbc.o \ @@ -42,6 +61,8 @@ PROG = py $(PROG): $(BUILD) $(OBJ) $(CC) -o $@ $(OBJ) $(LIB) $(LDFLAGS) + strip $(PROG) + size $(PROG) $(BUILD): mkdir $@ @@ -52,7 +73,7 @@ $(BUILD)/%.o: %.c $(BUILD)/%.o: $(PYSRC)/%.s $(AS) -o $@ $< -$(BUILD)/%.o: $(PYSRC)/%.c mpyconfig.h +$(BUILD)/%.o: $(PYSRC)/%.c mpconfig.h $(CC) $(CFLAGS) -c -o $@ $< $(BUILD)/emitnx64.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h @@ -65,7 +86,7 @@ $(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h $(BUILD)/vm.o: $(PYSRC)/vm.c $(CC) $(CFLAGS) -O3 -c -o $@ $< -$(BUILD)/main.o: mpyconfig.h +$(BUILD)/main.o: mpconfig.h $(BUILD)/parse.o: $(PYSRC)/grammar.h $(BUILD)/compile.o: $(PYSRC)/grammar.h $(BUILD)/emitcpy.o: $(PYSRC)/emit.h diff --git a/unix/lexerunix.c b/unix/lexerunix.c index e76d7f2c2..ac07781b5 100644 --- a/unix/lexerunix.c +++ b/unix/lexerunix.c @@ -17,7 +17,7 @@ unichar str_buf_next_char(str_buf_t *sb) { if (sb->src_cur < sb->src_end) { return *sb->src_cur++; } else { - return PY_LEXER_CHAR_EOF; + return MP_LEXER_CHAR_EOF; } } @@ -30,16 +30,16 @@ void str_buf_free(str_buf_t *sb) { } } -py_lexer_t *py_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str) { +mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str) { str_buf_t *sb = m_new(str_buf_t, 1); sb->free = free_str; sb->src_beg = str; sb->src_cur = str; sb->src_end = str + len; - return py_lexer_new(src_name, sb, (py_lexer_stream_next_char_t)str_buf_next_char, (py_lexer_stream_close_t)str_buf_free); + return mp_lexer_new(src_name, sb, (mp_lexer_stream_next_char_t)str_buf_next_char, (mp_lexer_stream_close_t)str_buf_free); } -py_lexer_t *py_lexer_new_from_file(const char *filename) { +mp_lexer_t *mp_lexer_new_from_file(const char *filename) { int fd = open(filename, O_RDONLY); if (fd < 0) { printf("cannot open file %s\n", filename); @@ -51,5 +51,5 @@ py_lexer_t *py_lexer_new_from_file(const char *filename) { read(fd, data, size); close(fd); - return py_lexer_new_from_str_len(filename, data, size, true); + return mp_lexer_new_from_str_len(filename, data, size, true); } diff --git a/unix/lexerunix.h b/unix/lexerunix.h index aa7631cb0..d86f202d5 100644 --- a/unix/lexerunix.h +++ b/unix/lexerunix.h @@ -1,2 +1,2 @@ -py_lexer_t *py_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str); -py_lexer_t *py_lexer_new_from_file(const char *filename); +mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str); +mp_lexer_t *mp_lexer_new_from_file(const char *filename); diff --git a/unix/main.c b/unix/main.c index e5aa9de15..295e82d26 100644 --- a/unix/main.c +++ b/unix/main.c @@ -4,18 +4,19 @@ #include "nlr.h" #include "misc.h" -#include "mpyconfig.h" +#include "mpconfig.h" #include "lexer.h" #include "lexerunix.h" #include "parse.h" #include "compile.h" -#include "runtime.h" #include "obj.h" +#include "runtime0.h" +#include "runtime.h" #include "repl.h" #include <readline/readline.h> -char *str_join(const char *s1, int sep_char, const char *s2) { +static char *str_join(const char *s1, int sep_char, const char *s2) { int l1 = strlen(s1); int l2 = strlen(s2); char *s = m_new(char, l1 + l2 + 2); @@ -29,14 +30,14 @@ char *str_join(const char *s1, int sep_char, const char *s2) { return s; } -void do_repl(void) { +static void do_repl(void) { for (;;) { char *line = readline(">>> "); if (line == NULL) { // EOF return; } - if (py_repl_is_compound_stmt(line)) { + if (mp_repl_is_compound_stmt(line)) { for (;;) { char *line2 = readline("... "); if (line2 == NULL || strlen(line2) == 0) { @@ -49,23 +50,23 @@ void do_repl(void) { } } - py_lexer_t *lex = py_lexer_new_from_str_len("<stdin>", line, strlen(line), false); - py_parse_node_t pn = py_parse(lex, PY_PARSE_SINGLE_INPUT); - py_lexer_free(lex); + mp_lexer_t *lex = mp_lexer_new_from_str_len("<stdin>", line, strlen(line), false); + mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT); + mp_lexer_free(lex); - if (pn != PY_PARSE_NODE_NULL) { - //py_parse_node_show(pn, 0); - bool comp_ok = py_compile(pn, true); + if (pn != MP_PARSE_NODE_NULL) { + //mp_parse_node_show(pn, 0); + bool comp_ok = mp_compile(pn, true); if (comp_ok) { - py_obj_t module_fun = rt_make_function_from_id(1); - if (module_fun != py_const_none) { + mp_obj_t module_fun = rt_make_function_from_id(1); + if (module_fun != mp_const_none) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { rt_call_function_0(module_fun); nlr_pop(); } else { // uncaught exception - py_obj_print((py_obj_t)nlr.ret_val); + mp_obj_print((mp_obj_t)nlr.ret_val); printf("\n"); } } @@ -75,32 +76,32 @@ void do_repl(void) { } void do_file(const char *file) { - py_lexer_t *lex = py_lexer_new_from_file(file); + mp_lexer_t *lex = mp_lexer_new_from_file(file); //const char *pysrc = "def f():\n x=x+1\n print(42)\n"; - //py_lexer_t *lex = py_lexer_from_str_len("<>", pysrc, strlen(pysrc), false); + //mp_lexer_t *lex = mp_lexer_from_str_len("<>", pysrc, strlen(pysrc), false); if (lex == NULL) { return; } if (0) { // just tokenise - while (!py_lexer_is_kind(lex, PY_TOKEN_END)) { - py_token_show(py_lexer_cur(lex)); - py_lexer_to_next(lex); + while (!mp_lexer_is_kind(lex, MP_TOKEN_END)) { + mp_token_show(mp_lexer_cur(lex)); + mp_lexer_to_next(lex); } - py_lexer_free(lex); + mp_lexer_free(lex); } else { // compile - py_parse_node_t pn = py_parse(lex, PY_PARSE_FILE_INPUT); - py_lexer_free(lex); + mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT); + mp_lexer_free(lex); - if (pn != PY_PARSE_NODE_NULL) { + if (pn != MP_PARSE_NODE_NULL) { //printf("----------------\n"); //parse_node_show(pn, 0); //printf("----------------\n"); - bool comp_ok = py_compile(pn, false); + bool comp_ok = mp_compile(pn, false); //printf("----------------\n"); #if MICROPY_EMIT_CPYTHON @@ -110,19 +111,19 @@ void do_file(const char *file) { #else if (1 && comp_ok) { // execute it - py_obj_t module_fun = rt_make_function_from_id(1); - if (module_fun != py_const_none) { + mp_obj_t module_fun = rt_make_function_from_id(1); + if (module_fun != mp_const_none) { nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { - py_obj_t ret = rt_call_function_0(module_fun); + mp_obj_t ret = rt_call_function_0(module_fun); printf("done! got: "); - py_obj_print(ret); + mp_obj_print(ret); printf("\n"); nlr_pop(); } else { // uncaught exception printf("exception: "); - py_obj_print((py_obj_t)nlr.ret_val); + mp_obj_print((mp_obj_t)nlr.ret_val); printf("\n"); } } @@ -132,37 +133,58 @@ void do_file(const char *file) { } } -void test_print(py_obj_t o_in) { - printf("<test>"); +typedef struct _test_obj_t { + mp_obj_base_t base; + bool value; +} test_obj_t; + +static void test_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) { + test_obj_t *self = self_in; + print(env, "<test %d>", self->value); } -py_obj_t test_get(py_obj_t o_in) { - py_obj_t d1; - py_obj_t d2; - py_user_get_data(o_in, (machine_uint_t*)&d1, (machine_uint_t*)&d2); - return d1; +static mp_obj_t test_get(mp_obj_t self_in) { + test_obj_t *self = self_in; + return mp_obj_new_int(self->value); } -py_obj_t test_set(py_obj_t o_in, py_obj_t arg) { - py_user_set_data(o_in, (machine_uint_t)arg, (machine_uint_t)arg); - return py_const_none; +static mp_obj_t test_set(mp_obj_t self_in, mp_obj_t arg) { + test_obj_t *self = self_in; + self->value = mp_obj_get_int(arg); + return mp_const_none; } -const py_user_info_t test_obj_info = { +static MP_DEFINE_CONST_FUN_OBJ_1(test_get_obj, test_get); +static MP_DEFINE_CONST_FUN_OBJ_2(test_set_obj, test_set); + +static const mp_obj_type_t test_type = { + { &mp_const_type }, "Test", - test_print, - { - { "get", 0, test_get }, - { "set", 1, test_set }, - { NULL, 0, NULL }, + test_print, // print + NULL, // call_n + NULL, // unary_op + NULL, // binary_op + NULL, // getiter + NULL, // iternext + { // method list + { "get", &test_get_obj }, + { "set", &test_set_obj }, + { NULL, NULL }, } }; +mp_obj_t test_obj_new(int value) { + test_obj_t *o = m_new_obj(test_obj_t); + o->base.type = &test_type; + o->value = value; + return o; +} + int main(int argc, char **argv) { qstr_init(); rt_init(); - rt_store_name(qstr_from_str_static("test"), py_obj_new_user(&test_obj_info, (machine_uint_t)py_obj_new_int(42), 0)); + rt_store_name(qstr_from_str_static("test"), test_obj_new(42)); if (argc == 1) { do_repl(); diff --git a/unix/mpyconfig.h b/unix/mpconfig.h index f187cbb4e..a358d7db8 100644 --- a/unix/mpyconfig.h +++ b/unix/mpconfig.h @@ -13,6 +13,7 @@ typedef int64_t machine_int_t; // must be pointer size typedef uint64_t machine_uint_t; // must be pointer size typedef void *machine_ptr_t; // must be of pointer size +typedef const void *machine_const_ptr_t; // must be of pointer size typedef double machine_float_t; machine_float_t machine_sqrt(machine_float_t x); |