Commit Graph

268 Commits

Author SHA1 Message Date
Damien George
adaf0d865c py: Combine 3 comprehension opcodes (list/dict/set) into 1.
With the previous patch combining 3 emit functions into 1, it now makes
sense to also combine the corresponding VM opcodes, which is what this
patch does.  This eliminates 2 opcodes which simplifies the VM and reduces
code size, in bytes: bare-arm:44, minimal:64, unix(NDEBUG,x86-64):272,
stmhal:92, esp8266:200.  Profiling (with a simple script that creates many
list/dict/set comprehensions) shows no measurable change in performance.
2016-09-19 12:28:03 +10:00
Damien George
581a59a456 py: Rename struct mp_code_state to mp_code_state_t.
Also at _t to mp_exc_stack pre-declaration in struct typedef.
2016-08-27 23:21:00 +10:00
Damien George
4cec63a9db py: Implement a simple global interpreter lock.
This makes the VM/runtime thread safe, at the cost of not being able to
run code in parallel.
2016-06-28 11:28:50 +01:00
Paul Sokolovsky
eff85bb1dc py/vm: "yield from" didn't handle MP_OBJ_STOP_ITERATION optimization.
E.g. crashed when yielding from already stopped generators.
2016-04-28 02:08:43 +03:00
Damien George
40d8430ee3 py/vm: Add macros to hook into various points in the VM.
These can be used to insert arbitrary checks, polling, etc into the VM.
They are left general because the VM is a highly tuned loop and it should
be up to a given port how that port wants to modify the VM internals.

One common use would be to insert a polling check, but only done after
a certain number of opcodes were executed, so as not to slow down the VM
too much.  For example:

 #define MICROPY_VM_HOOK_COUNT (30)
 #define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT
 #define MICROPY_VM_HOOK_POLL if (--vm_hook_divisor == 0) { \
     vm_hook_divisor = MICROPY_VM_HOOK_COUNT;
     extern void vm_hook_function(void);
     vm_hook_function();
 }
 #define MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_POLL
 #define MICROPY_VM_HOOK_RETURN MICROPY_VM_HOOK_POLL
2016-02-17 09:02:19 +00:00
Damien George
93bb7dffd2 py/vm: Fix popping of exception block in UNWIND_JUMP opcode.
Fixes issue #1812.
2016-02-01 16:07:21 +00:00
Damien George
3d2daa2d03 py: Change exception traceback data to use size_t instead of mp_uint_t.
The traceback array stores qstrs and line numbers.  qstrs are typed as
size_t, and line numbers should safely fit in size_t as well.
2016-01-02 22:04:12 +00:00
Damien George
8047340d75 py: Handle case of return within the finally block of try-finally.
Addresses issue #1636.
2015-12-24 12:47:39 +00:00
Damien George
7a30e87d2b py: Fix MICROPY_STACKLESS mode to compile with MICROPY_OBJ_REPR_D. 2015-12-17 12:32:41 +00:00
Damien George
bdbe8c9ae2 py: Make UNARY_OP_NOT a first-class op, to agree with Py not semantics.
Fixes #1684 and makes "not" match Python semantics.  The code is also
simplified (the separate MP_BC_NOT opcode is removed) and the patch saves
68 bytes for bare-arm/ and 52 bytes for minimal/.

Previously "not x" was implemented as !mp_unary_op(x, MP_UNARY_OP_BOOL),
so any given object only needs to implement MP_UNARY_OP_BOOL (and the VM
had a special opcode to do the ! bit).

With this patch "not x" is implemented as mp_unary_op(x, MP_UNARY_OP_NOT),
but this operation is caught at the start of mp_unary_op and dispatched as
!mp_obj_is_true(x).  mp_obj_is_true has special logic to test for
truthness, and is the correct way to handle the not operation.
2015-12-10 22:19:48 +00:00
Damien George
999cedb90f py: Wrap all obj-ptr conversions in MP_OBJ_TO_PTR/MP_OBJ_FROM_PTR.
This allows the mp_obj_t type to be configured to something other than a
pointer-sized primitive type.

This patch also includes additional changes to allow the code to compile
when sizeof(mp_uint_t) != sizeof(void*), such as using size_t instead of
mp_uint_t, and various casts.
2015-11-29 14:25:35 +00:00
Damien George
c8e9c0d89a py: Add MICROPY_PERSISTENT_CODE so code can persist beyond the runtime.
Main changes when MICROPY_PERSISTENT_CODE is enabled are:

- qstrs are encoded as 2-byte fixed width in the bytecode
- all pointers are removed from bytecode and put in const_table (this
  includes const objects and raw code pointers)

Ultimately this option will enable persistence for not just bytecode but
also native code.
2015-11-13 12:49:18 +00:00
Damien George
4bf3f2d3c0 py: Fix with+for+return bug by popping for-iter when unwinding exc stack.
Addresses issue #1182.
2015-10-15 17:48:28 +01:00
Paul Sokolovsky
2ff2ea5f3b vm: Handle "raise X from Y" statements the best way we can.
By issuing a warning that exception chaining is not supported, and ignoring
"from Y" argument.
2015-09-01 10:39:04 +03:00
Damien George
59fba2d6ea py: Remove mp_load_const_bytes and instead load precreated bytes object.
Previous to this patch each time a bytes object was referenced a new
instance (with the same data) was created.  With this patch a single
bytes object is created in the compiler and is loaded directly at execute
time as a true constant (similar to loading bignum and float objects).
This saves on allocating RAM and means that bytes objects can now be
used when the memory manager is locked (eg in interrupts).

The MP_BC_LOAD_CONST_BYTES bytecode was removed as part of this.

Generated bytecode is slightly larger due to storing a pointer to the
bytes object instead of the qstr identifier.

Code size is reduced by about 60 bytes on Thumb2 architectures.
2015-06-25 14:42:13 +00:00
Damien George
ed570e4b2a py: Remove mp_load_const_str and replace uses with inlined version. 2015-06-25 13:58:41 +00:00
Damien George
c5029bcbf3 py: Add MP_BINARY_OP_DIVMOD to simplify and consolidate divmod builtin. 2015-06-13 23:36:30 +01:00
Damien George
c2a4e4effc py: Convert hash API to use MP_UNARY_OP_HASH instead of ad-hoc function.
Hashing is now done using mp_unary_op function with MP_UNARY_OP_HASH as
the operator argument.  Hashing for int, str and bytes still go via
fast-path in mp_unary_op since they are the most common objects which
need to be hashed.

This lead to quite a bit of code cleanup, and should be more efficient
if anything.  It saves 176 bytes code space on Thumb2, and 360 bytes on
x86.

The only loss is that the error message "unhashable type" is now the
more generic "unsupported type for __hash__".
2015-05-12 22:46:02 +01:00
Paul Sokolovsky
6738c1dded vm: Properly handle StopIteration raised in user instance iterator.
I.e. in bytecode Python functions.
2015-05-11 23:57:42 +01:00
Paul Sokolovsky
a7c02c4538 vm: Null pointer test when checking for StopIteration optimizations.
When generator raises exception, it is automatically terminated (by setting
its code_state.ip to 0), which interferes with this check.

Triggered in particular by CPython's test_pep380.py.
2015-05-10 17:20:46 +03:00
Damien George
8872abcbc4 py: Remove LOAD_CONST_ELLIPSIS bytecode, use LOAD_CONST_OBJ instead.
Ellipsis constant is rarely used so no point having an extra bytecode
for it.
2015-05-05 22:15:42 +01:00
Paul Sokolovsky
ae2c81ff38 vm: On exiting except block, clear sys.exc_info() value.
This doesn't handle case fo enclosed except blocks, but once again,
sys.exc_info() support is a workaround for software which uses it
instead of properly catching exceptions via variable in except clause.
2015-04-26 01:40:37 +03:00
Paul Sokolovsky
8b85d14b92 modsys: Add basic sys.exc_info() implementation.
The implementation is very basic and non-compliant and provided solely for
CPython compatibility. The function itself is bad Python2 heritage, its
usage is discouraged.
2015-04-25 03:49:23 +03:00
Damien George
8c1d23a0e2 py: Modify bytecode "with" behaviour so it doesn't use any heap.
Before this patch a "with" block needed to create a bound method object
on the heap for the __exit__ call.  Now it doesn't because we use
load_method instead of load_attr, and save the method+self on the stack.
2015-04-24 01:52:28 +01:00
Damien George
b1bbe966c4 py: Combine load_attr and store_attr type methods into one (attr).
This simplifies the API for objects and reduces code size (by around 400
bytes on Thumb2, and around 2k on x86).  Performance impact was measured
with Pystone score, but change was barely noticeable.
2015-04-11 16:54:37 +01:00
Damien George
4dea922610 py: Adjust some spaces in code style/format, purely for consistency. 2015-04-09 15:29:54 +00:00
stijn
36cc84a2a9 py: Fix msvc warning '*/ found outside of comment'
Also prevents some of the weaker syntax parsers out there treating the whole
'*/*const*/' part as a comment
2015-04-09 12:40:38 +02:00
Damien George
12a5e17afb py: Add finer configuration of static funcs when not in stackless mode.
Also rename call_args_t to mp_call_args_t.
2015-04-02 22:56:58 +01:00
Paul Sokolovsky
7f1c98177b vm: Support strict stackless mode, with proper exception reporting.
I.e. in this mode, C stack will never be used to call a Python function,
but if there's no free heap for a call, it will be reported as
RuntimeError (as expected), not MemoryError.
2015-04-03 00:26:47 +03:00
Paul Sokolovsky
f0a8f21190 vm: Implement stackless for CALL_FUNCTION_VAR_KW & CALL_METHOD_VAR_KW. 2015-04-03 00:03:07 +03:00
Paul Sokolovsky
390e92688c vm: Stackless support for MP_BC_CALL_METHOD. 2015-04-03 00:03:07 +03:00
Paul Sokolovsky
332a909d44 vm: If there's no heap to call function in stackless manner, call via C stack. 2015-04-03 00:03:07 +03:00
Paul Sokolovsky
2039757b85 vm: Initial support for calling bytecode functions w/o C stack ("stackless"). 2015-04-03 00:03:07 +03:00
stijn
28fa84b445 py: Add optional support for descriptors' __get__ and __set__ methods.
Disabled by default.  Enabled on unix and windows ports.
2015-03-26 23:55:14 +00:00
Damien George
5e1d993f54 py: Clean up some logic in VM to remove assert(0)'s.
Saves around 30 bytes code on Thumb2 archs.
2015-03-25 22:20:37 +00:00
Damien George
12d6d777e1 py: Small optimisation of logic flow in BC_WITH_CLEANUP bytecode.
Slightly smaller code, and does not need to use C stack to save
temporaries.
2015-02-26 17:54:50 +00:00
Damien George
596f41da04 py: Reuse value stack in VM WITH_CLEANUP opcode to reduce C-stack size.
Saves 8 bytes C-stack on stmhal and 16 bytes on unix x86.
2015-02-10 13:21:42 +00:00
Damien George
7d414a1b52 py: Parse big-int/float/imag constants directly in parser.
Previous to this patch, a big-int, float or imag constant was interned
(made into a qstr) and then parsed at runtime to create an object each
time it was needed.  This is wasteful in RAM and not efficient.  Now,
these constants are parsed straight away in the parser and turned into
objects.  This allows constants with large numbers of digits (so
addresses issue #1103) and takes us a step closer to #722.
2015-02-08 01:57:40 +00:00
Damien George
dab1385177 py: Add load_const_obj to emitter, add LOAD_CONST_OBJ to bytecode.
This allows to directly load a Python object to the Python stack.  See
issue #722 for background.
2015-01-13 15:55:54 +00:00
Damien George
7ee91cf861 py: Add option to cache map lookup results in bytecode.
This is a simple optimisation inspired by JITing technology: we cache in
the bytecode (using 1 byte) the offset of the last successful lookup in
a map. This allows us next time round to check in that location in the
hash table (mp_map_t) for the desired entry, and if it's there use that
entry straight away.  Otherwise fallback to a normal map lookup.

Works for LOAD_NAME, LOAD_GLOBAL, LOAD_ATTR and STORE_ATTR opcodes.

On a few tests it gives >90% cache hit and greatly improves speed of
code.

Disabled by default.  Enabled for unix and stmhal ports.
2015-01-07 21:07:23 +00:00
Damien George
b4b10fd350 py: Put all global state together in state structures.
This patch consolidates all global variables in py/ core into one place,
in a global structure.  Root pointers are all located together to make
GC tracing easier and more efficient.
2015-01-07 20:33:00 +00:00
Damien George
51dfcb4bb7 py: Move to guarded includes, everywhere in py/ core.
Addresses issue #1022.
2015-01-01 20:32:09 +00:00
Damien George
f89d659e3b py: In VM, for selective ip saving, store 1 byte past last opcode.
This is for efficiency, so we don't need to subtract 1 from the ip
before storing it to code_state->ip.  It saves a lot of ROM bytes on
unix and stmhal.
2014-12-29 00:29:59 +00:00
Paul Sokolovsky
749575097f vm: Record exception ip only for instructions where exceptions may happen.
Mirroring ip to a volatile memory variable for each opcode is an expensive
operation. For quite a lot of often executed opcodes like stack manipulation
or jumps, exceptions cannot actually happen. So, record ip only for opcode
where that's possible.
2014-12-28 07:37:04 +02:00
Damien George
74eb44c392 py: Reduce size of VM exception stack element by 1 machine word.
This optimisation reduces the VM exception stack element (mp_exc_stack_t)
by 1 word, by using bit 1 of a pointer to store whether the opcode was a
FINALLY or WITH opcode.  This optimisation was pending, waiting for
maturity of the exception handling code, which has now proven itself.

Saves 1 machine word RAM for each exception (4->3 words per exception).
Increases stmhal code by 4 bytes, and decreases unix x64 code by 32
bytes.
2014-12-22 12:49:57 +00:00
Damien George
7764f163fa py: Fix label printing in showbc; print sp in vm trace. 2014-12-12 17:18:56 +00:00
Damien George
cd97a43f8d py, vm: Make unum a local variable for each opcode that uses it.
This makes no change to the generated code, but it's now easier to
understand since unum is not a "global" variable anymore.
2014-12-02 19:25:10 +00:00
Damien George
b0b0012fd8 py: Fix VM dispatch following a pending exception check. 2014-10-26 00:33:23 +01:00
Damien George
124df6f8d0 py: Add mp_pending_exception global variable, for VM soft interrupt.
This allows to implement KeyboardInterrupt on unix, and a much safer
ctrl-C in stmhal port.  First ctrl-C is a soft one, with hope that VM
will notice it; second ctrl-C is a hard one that kills anything (for
both unix and stmhal).

One needs to check for a pending exception in the VM only for jump
opcodes.  Others can't produce an infinite loop (infinite recursion is
caught by stack check).
2014-10-25 23:37:57 +01:00
Damien George
8456cc017b py: Compress load-int, load-fast, store-fast, unop, binop bytecodes.
There is a lot potential in compress bytecodes and make more use of the
coding space.  This patch introduces "multi" bytecodes which have their
argument included in the bytecode (by addition).

UNARY_OP and BINARY_OP now no longer take a 1 byte argument for the
opcode.  Rather, the opcode is included in the first byte itself.

LOAD_FAST_[0,1,2] and STORE_FAST_[0,1,2] are removed in favour of their
multi versions, which can take an argument between 0 and 15 inclusive.
The majority of LOAD_FAST/STORE_FAST codes fit in this range and so this
saves a byte for each of these.

LOAD_CONST_SMALL_INT_MULTI is used to load small ints between -16 and 47
inclusive.  Such ints are quite common and now only need 1 byte to
store, and now have much faster decoding.

In all this patch saves about 2% RAM for typically bytecode (1.8% on
64-bit test, 2.5% on pyboard test).  It also reduces the binary size
(because bytecodes are simplified) and doesn't harm performance.
2014-10-25 20:23:13 +01:00
Damien George
b534e1b9f1 py: Use variable length encoded uints in more places in bytecode.
Code-info size, block name, source name, n_state and n_exc_stack now use
variable length encoded uints.  This saves 7-9 bytes per bytecode
function for most functions.
2014-09-04 14:44:01 +01:00
Damien George
b427d6ae86 py: Fix line number printing for file with 1 line.
With a file with 1 line (and an error on that line), used to show the
line as number 0.  Now shows it correctly as line number 1.

But, when line numbers are disabled, it now prints line number 1 for any
line that has an error (instead of 0 as previously).  This might end up
being confusing, but requires extra RAM and/or hack logic to make it
print something special in the case of no line numbers.
2014-08-26 23:35:57 +01:00
Damien George
4747becc64 py: Improve encoding scheme for line-number to bytecode map.
Reduces by about a factor of 10 on average the amount of RAM needed to
store the line-number to bytecode map in the bytecode prelude.

Using CPython3.4's stdlib for statistics: previously, an average of
13 bytes were used per (bytecode offset, line-number offset) pair, and
now with this improvement, that's down to 1.3 bytes on average.

Large RAM usage before was due to some very large steps in line numbers,
both from the start of the first line in a function way down in the
file, and also functions that have big comments and/or big strings in
them (both cases were significant).

Although the savings are large on average for the CPython stdlib, it
won't have such a big effect for small scripts used in embedded
programming.

Addresses issue #648.
2014-07-31 16:12:01 +00:00
Damien George
40f3c02682 Rename machine_(u)int_t to mp_(u)int_t.
See discussion in issue #50.
2014-07-03 13:25:24 +01:00
Damien George
df896eceef Merge branch 'alloca' of github.com:marcusva/micropython into marcusva-alloca 2014-06-08 13:18:14 +01:00
Damien George
aabd83ea20 py: Merge mp_execute_bytecode into fun_bc_call.
This reduces stack usage by 16 words (64 bytes) for stmhal/ port.

See issue #640.
2014-06-07 14:16:08 +01:00
Marcus von Appen
0c90eb1658 - FreeBSD provides alloca() via stdlib.h, in contrast to Linux and Windows
- Move the includes for alloca() intp mpconfigport.h
2014-06-07 09:36:04 +02:00
Paul Sokolovsky
411732e93b vm: If there's no lineno info, set lineno in traceback to 0, not 1.
To clearly signify that lineno is not known.
2014-06-03 12:32:59 +03:00
Damien George
3ebd4d0cae py: Add option to disable set() object (enabled by default). 2014-06-01 13:46:47 +01:00
Damien George
fb510b3bf9 Rename bultins config variables to MICROPY_PY_BUILTINS_*.
This renames:
MICROPY_PY_FROZENSET -> MICROPY_PY_BUILTINS_FROZENSET
MICROPY_PY_PROPERTY -> MICROPY_PY_BUILTINS_PROPERTY
MICROPY_PY_SLICE -> MICROPY_PY_BUILTINS_SLICE
MICROPY_ENABLE_FLOAT -> MICROPY_PY_BUILTINS_FLOAT

See issue #35 for discussion.
2014-06-01 13:32:54 +01:00
Damien George
c60a261ef0 py, vm: Replace save_ip, save_sp with code_state->{ip, sp}.
This may seem a bit of a risky change, in that it may introduce crazy
bugs with respect to volatile variables in the VM loop.  But, I think it
should be fine: code_state points to some external memory, so the
compiler should always read/write to that memory when accessing the
ip/sp variables (ie not put them in registers).

Anyway, it passes all tests and improves on all efficiency fronts: about
2-4% faster (64-bit unix), 16 bytes less stack space per call (64-bit
unix) and slightly less executable size (unix and stmhal).

The reason it's more efficient is save_ip and save_sp were volatile
variables, so were anyway stored on the stack (in memory, not regs).
Thus converting them to code_state->{ip, sp} doesn't cost an extra
memory dereference (except maybe to get code_state, but that can be put
in a register and then made more efficient for other uses of it).
2014-06-01 12:32:28 +01:00
Damien George
1b87d1098a Merge branch 'vm-alloca' of github.com:pfalcon/micropython into pfalcon-vm-alloca
Conflicts:
	py/vm.c

Fixed stack underflow check.  Use UINT_FMT/INT_FMT where necessary.
Specify maximum VM-stack byte size by multiple of machine word size, so
that on 64 bit machines it has same functionality as 32 bit.
2014-06-01 12:06:17 +01:00
Damien George
5b5562c1d1 py: Fix stack underflow with optimised for loop. 2014-05-31 17:59:11 +01:00
Paul Sokolovsky
b4ebad3310 vm: Factor out structure with code execution state and pass it around.
This improves stack usage in callers to mp_execute_bytecode2, and is step
forward towards unifying execution interface for function and generators
(which is important because generators don't even support full forms
of arguments passing (keywords, etc.)).
2014-05-31 18:22:01 +03:00
Paul Sokolovsky
b16523aa95 vm: Don't unconditionally allocate state on stack, do that only if needed.
This makes sure that only as much stack allocated as actually used, reducing
stack usage for each Python function call.
2014-05-31 18:19:33 +03:00
Paul Sokolovsky
ff8da0b835 vm: Detect stack underflow in addition to overflow. 2014-05-31 18:14:54 +03:00
Paul Sokolovsky
1f07b7e3c3 py: Reformat few long functions argument lists for clarity. 2014-05-31 03:36:37 +03:00
Damien George
25c84643b6 py: Fix break from within a for loop.
Needed to pop the iterator object when breaking out of a for loop.  Need
also to be careful to unwind exception handler before popping iterator.

Addresses issue #635.
2014-05-30 15:20:41 +01:00
Damien George
503d611033 py: Implement long int parsing in int(...).
Addresses issue #627.
2014-05-28 14:07:21 +01:00
Damien George
d8675541a9 py, vm: Where possible, make variables local to each opcode.
This helps the compiler do its optimisation, makes it clear which
variables are local per opcode and which global, and makes it consistent
when extra variables are needed in an opcode (in addition to old obj1,
obj2 pair, for example).

Could also make unum local, but that's for another time.
2014-05-25 22:58:04 +01:00
Paul Sokolovsky
afaaf535e6 objslice: Support arbitrary objects start, stop, and step.
Older int-only encoding is not expressive enough to support arbitrary slice
assignment operations.
2014-05-25 01:42:24 +03:00
Damien George
ee3fd46f13 Rename configuration variables controling Python features.
Now of the form MICROPY_PY_*.  See issue #35.
2014-05-24 23:03:12 +01:00
Damien George
58ebde4664 Tidy up some configuration options.
MP_ALLOC_* -> MICROPY_ALLOC_*
MICROPY_PATH_MAX -> MICROPY_ALLOC_PATH_MAX
MICROPY_ENABLE_REPL_HELPERS -> MICROPY_HELPER_REPL
MICROPY_ENABLE_LEXER_UNIX -> MICROPY_HELPER_LEXER_UNIX
MICROPY_EXTRA_* -> MICROPY_PORT_*

See issue #35.
2014-05-21 20:32:59 +01:00
Paul Sokolovsky
da9f0924ef py, unix: Add copyright for modules I worked closely on. 2014-05-13 18:41:25 +03:00
Paul Sokolovsky
c48d6f7add py: Don't expect that type->getiter() always returns iterator, check for NULL.
This is better than forcing each getiter() implementation to raise exception.
2014-05-11 20:51:31 +03:00
Damien George
3417bc2f25 py: Rename byte_code to bytecode everywhere.
bytecode is the more widely used.  See issue #590.
2014-05-10 10:36:38 +01:00
Damien George
a32c1e41cc py: Improve native emitter; now supports more opcodes. 2014-05-07 18:30:52 +01:00
Damien George
04b9147e15 Add license header to (almost) all files.
Blanket wide to all .c and .h files.  Some files originating from ST are
difficult to deal with (license wise) so it was left out of those.

Also merged modpyb.h, modos.h, modstm.h and modtime.h in stmhal/.
2014-05-03 23:27:38 +01:00
Paul Sokolovsky
f54bcbf099 py, unix: Make "mpconfig.h" be first included, as other headers depend on it.
Specifically, nlr.h does.
2014-05-02 17:48:40 +03:00
Damien George
968bf34c4c py: Remove unnecessary LOAD_CONST_ID bytecode.
It's the same as LOAD_CONST_STR.
2014-04-27 19:12:05 +01:00
Damien George
db12891918 py: Eliminate 'op' variable in VM dispatch loop.
Remembering the last op is rarely needed, and when it is, can simply use
*save_ip.
2014-04-27 18:19:06 +01:00
Damien George
c0dc7c3dfa py, vm: Fix recent bug where state is freed too early. 2014-04-24 15:42:05 +01:00
Damien George
d5e8482c4a py, vm: Free heap-allocated state if it was allocated on the heap. 2014-04-24 13:52:06 +01:00
Paul Sokolovsky
c5e32c6995 vm: Add rudimentary bytecode execution tracing capability. 2014-04-23 03:46:00 +03:00
Damien George
5f6a25fc50 py: Wrap #if's around emitter functions that are used only by emitcpy.
3 emitter functions are needed only for emitcpy, and so we can #if them
out when compiling with emitcpy support.

Also remove unused SETUP_LOOP bytecode.
2014-04-20 18:02:27 +01:00
Damien George
3558f62fb5 py: Making closures now passes pointer to stack, not a tuple for vars.
Closed over variables are now passed on the stack, instead of creating a
tuple and passing that.  This way memory for the closed over variables
can be allocated within the closure object itself.  See issue #510 for
background.
2014-04-20 17:50:40 +01:00
Damien George
5b65f0c7d3 py: Rename USE_COMPUTED_GOTOS to USE_COMPUTED_GOTO and enable on stmhal.
On stmhal, computed gotos make the binary about 1k bigger, but makes it
run faster, and we have the room, so why not.  All tests pass on
pyboard using computed gotos.
2014-04-17 23:24:13 +01:00
Damien George
ea8d06c39d py: Add MP_OBJ_STOP_ITERATION and make good use of it.
Also make consistent use of MP_OBJ_NOT_SUPPORTED and MP_OBJ_NULL.
This helps a lot in debugging and understanding of function API.
2014-04-17 23:19:36 +01:00
Damien George
729f7b42d6 py: Merge BINARY_OP_SUBSCR and store_subscr (w/ delete) into subscr.
mp_obj_t->subscr now does load/store/delete.
2014-04-17 22:10:53 +01:00
Damien George
66ae8c9f49 py: Tidy up variables in VM, probably fixes subtle bugs.
Things get tricky when using the nlr code to catch exceptions.  Need to
ensure that the variables (stack layout) in the exception handler are
the same as in the bit protected by the exception handler.

Prior to this patch there were a few bugs.  1) The constant
mp_const_MemoryError_obj was being preloaded to a specific location on
the stack at the start of the function.  But this location on the stack
was being overwritten in the opcode loop (since it didn't think that
variable would ever be referenced again), and so when an exception
occurred, the variable holding the address of MemoryError was corrupt.
2) The FOR_ITER opcode detection in the exception handler used sp, which
may or may not contain the right value coming out of the main opcode
loop.

With this patch there is a clear separation of variables used in the
opcode loop and in the exception handler (should fix issue (2) above).
Furthermore, nlr_raise is no longer used in the opcode loop.  Instead,
it jumps directly into the exception handler.  This tells the C compiler
more about the possible code flow, and means that it should have the
same stack layout for the exception handler.  This should fix issue (1)
above.  Indeed, the generated (ARM) assembler has been checked explicitly,
and with 'goto exception_handler', the problem with &MemoryError is
fixed.

This may now fix problems with rge-sm, and probably many other subtle
bugs yet to show themselves.  Incidentally, rge-sm now passes on
pyboard (with a reduced range of integration)!

Main lesson: nlr is tricky.  Don't use nlr_push unless you know what you
are doing!  Luckily, it's not used in many places.  Using nlr_raise/jump
is fine.
2014-04-17 16:50:23 +01:00
AZ Huang
9413ca02fb Rename header file. 2014-04-15 21:29:08 +08:00
AZ Huang
9309d9982f Move entry_table to separated header file. 2014-04-15 17:08:42 +08:00
Damien George
3bb8bd899b Make USE_COMPUTED_GOTO a config option in mpconfig.h.
Disabled by default.  Enabled in unix port.
2014-04-14 21:20:30 +01:00
AZ Huang
b1f692e82e Use computed goto instead of switching op-codes. 2014-04-15 02:40:28 +08:00
Damien George
df8127a17e py: Remove unique_codes from emitglue.c. Replace with pointers.
Attempt to address issue #386.  unique_code_id's have been removed and
replaced with a pointer to the "raw code" information.  This pointer is
stored in the actual byte code (aligned, so the GC can trace it), so
that raw code (ie byte code, native code and inline assembler) is kept
only for as long as it is needed.  In memory it's now like a tree: the
outer module's byte code points directly to its children's raw code.  So
when the outer code gets freed, if there are no remaining functions that
need the raw code, then the children's code gets freed as well.

This is pretty much like CPython does it, except that CPython stores
indexes in the byte code rather than machine pointers.  These indices
index the per-function constant table in order to find the relevant
code.
2014-04-13 11:04:33 +01:00
Damien George
6ce4277551 py: Make all LOAD_FAST ops check for unbound local.
This is necessary to catch all cases where locals are referenced before
assignment.  We still keep the _0, _1, _2 versions of LOAD_FAST to help
reduced the byte code size in RAM.

Addresses issue #457.
2014-04-12 18:20:40 +01:00
Damien George
69b89d21b2 py: Change compile order for default positional and keyword args.
This simplifies the compiler a little, since now it can do 1 pass over
a function declaration, to determine default arguments.  I would have
done this originally, but CPython 3.3 somehow had the default keyword
args compiled before the default position args (even though they appear
in the other order in the text of the script), and I thought it was
important to have the same order of execution when evaluating default
arguments.  CPython 3.4 has changed the order to the more obvious one,
so we can also change.
2014-04-11 13:38:30 +00:00
Damien George
a1ef441d18 py: Fix VM stack overflow detection. 2014-04-10 16:59:44 +00:00
Damien George
e90be0ddf5 py: Add option to VM to detect stack overflow. 2014-04-10 16:21:34 +00:00
Damien George
d99944acdd py: Clear state to MP_OBJ_NULL before executing byte code. 2014-04-09 19:53:31 +01:00