summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2015-01-14 00:20:28 +0000
committerDamien George <damien.p.george@gmail.com>2015-01-14 00:20:28 +0000
commit1e1779eacf4da5cd8699bee26a02eed4eda10101 (patch)
treeaac00790c5ae0b2fbd0848b595c3273c7c674fce
parent2127e9a844ae46cb2149e7c38eb9f4345075f6e4 (diff)
downloadmicropython-1e1779eacf4da5cd8699bee26a02eed4eda10101.tar.gz
micropython-1e1779eacf4da5cd8699bee26a02eed4eda10101.zip
py: Reluctantly add an extra pass to bytecode compiler.
Bytecode also needs a pass to compute the stack size. This is because the state size of the bytecode function is encoded as a variable uint, so we must know the value of this uint before we encode it (otherwise the size of the generated code changes from one pass to the next). Having an entire pass for this seems wasteful (in time). Alternative is to allocate fixed space for the state size (would need 3-4 bytes to be general, when 1 byte is usually sufficient) which uses a bit of extra RAM per bytecode function, and makes the code less elegant in places where this uint is encoded/decoded. So, for now, opt for an extra pass.
-rw-r--r--py/compile.c7
-rw-r--r--tests/basics/fun_largestate.py133
2 files changed, 136 insertions, 4 deletions
diff --git a/py/compile.c b/py/compile.c
index 2b56d83e74..48b1079a10 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -3729,10 +3729,6 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
#endif
comp->emit = emit_native;
EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_ENABLE, s->emit_options == MP_EMIT_OPT_VIPER, 0);
-
- // native emitters need an extra pass to compute stack size
- compile_scope(comp, s, MP_PASS_STACK_SIZE);
-
break;
#endif // MICROPY_EMIT_NATIVE
@@ -3746,6 +3742,9 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
}
#endif // !MICROPY_EMIT_CPYTHON
+ // need a pass to compute stack size
+ compile_scope(comp, s, MP_PASS_STACK_SIZE);
+
// second last pass: compute code size
if (comp->compile_error == MP_OBJ_NULL) {
compile_scope(comp, s, MP_PASS_CODE_SIZE);
diff --git a/tests/basics/fun_largestate.py b/tests/basics/fun_largestate.py
new file mode 100644
index 0000000000..c83f730dcb
--- /dev/null
+++ b/tests/basics/fun_largestate.py
@@ -0,0 +1,133 @@
+# test large function (stack) state
+
+def f():
+ x0 = 1
+ x1 = 1
+ x2 = 1
+ x3 = 1
+ x4 = 1
+ x5 = 1
+ x6 = 1
+ x7 = 1
+ x8 = 1
+ x9 = 1
+ x10 = 1
+ x11 = 1
+ x12 = 1
+ x13 = 1
+ x14 = 1
+ x15 = 1
+ x16 = 1
+ x17 = 1
+ x18 = 1
+ x19 = 1
+ x20 = 1
+ x21 = 1
+ x22 = 1
+ x23 = 1
+ x24 = 1
+ x25 = 1
+ x26 = 1
+ x27 = 1
+ x28 = 1
+ x29 = 1
+ x30 = 1
+ x31 = 1
+ x32 = 1
+ x33 = 1
+ x34 = 1
+ x35 = 1
+ x36 = 1
+ x37 = 1
+ x38 = 1
+ x39 = 1
+ x40 = 1
+ x41 = 1
+ x42 = 1
+ x43 = 1
+ x44 = 1
+ x45 = 1
+ x46 = 1
+ x47 = 1
+ x48 = 1
+ x49 = 1
+ x50 = 1
+ x51 = 1
+ x52 = 1
+ x53 = 1
+ x54 = 1
+ x55 = 1
+ x56 = 1
+ x57 = 1
+ x58 = 1
+ x59 = 1
+ x60 = 1
+ x61 = 1
+ x62 = 1
+ x63 = 1
+ x64 = 1
+ x65 = 1
+ x66 = 1
+ x67 = 1
+ x68 = 1
+ x69 = 1
+ x70 = 1
+ x71 = 1
+ x72 = 1
+ x73 = 1
+ x74 = 1
+ x75 = 1
+ x76 = 1
+ x77 = 1
+ x78 = 1
+ x79 = 1
+ x80 = 1
+ x81 = 1
+ x82 = 1
+ x83 = 1
+ x84 = 1
+ x85 = 1
+ x86 = 1
+ x87 = 1
+ x88 = 1
+ x89 = 1
+ x90 = 1
+ x91 = 1
+ x92 = 1
+ x93 = 1
+ x94 = 1
+ x95 = 1
+ x96 = 1
+ x97 = 1
+ x98 = 1
+ x99 = 1
+ x100 = 1
+ x101 = 1
+ x102 = 1
+ x103 = 1
+ x104 = 1
+ x105 = 1
+ x106 = 1
+ x107 = 1
+ x108 = 1
+ x109 = 1
+ x110 = 1
+ x111 = 1
+ x112 = 1
+ x113 = 1
+ x114 = 1
+ x115 = 1
+ x116 = 1
+ x117 = 1
+ x118 = 1
+ x119 = 1
+ x120 = 1
+ x121 = 1
+ x122 = 1
+ x123 = 1
+ x124 = 1
+ x125 = 1
+ x126 = 1
+
+def g():
+ x = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,]