summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-03-29 01:26:02 +0000
committerDamien George <damien.p.george@gmail.com>2014-03-29 01:26:02 +0000
commitc47fd2da8ec705a3c6f51d1a09b7bf4a180a01ff (patch)
tree8304956bd360b2bda7a6f5ee8e9443111da183dd /py
parentbcc9298e5bd2049bbee8c1d00482d2695b8e0b70 (diff)
parent1d7553311c70810a6fea2d72b04403b93711389c (diff)
downloadmicropython-c47fd2da8ec705a3c6f51d1a09b7bf4a180a01ff.tar.gz
micropython-c47fd2da8ec705a3c6f51d1a09b7bf4a180a01ff.zip
Merge branch 'master' of github.com:micropython/micropython
Diffstat (limited to 'py')
-rw-r--r--py/emitglue.c17
-rw-r--r--py/obj.h1
-rw-r--r--py/objexcept.c6
-rw-r--r--py/objgenerator.c2
-rw-r--r--py/runtime.c14
-rw-r--r--py/showbc.c20
6 files changed, 43 insertions, 17 deletions
diff --git a/py/emitglue.c b/py/emitglue.c
index 0ab9090924..ed816a5161 100644
--- a/py/emitglue.c
+++ b/py/emitglue.c
@@ -1,6 +1,6 @@
// This code glues the code emitters to the runtime.
-#include <stdlib.h>
+#include <stdio.h>
#include <assert.h>
#include "misc.h"
@@ -10,6 +10,7 @@
#include "runtime0.h"
#include "runtime.h"
#include "emitglue.h"
+#include "bc.h"
#if 0 // print debugging info
#define DEBUG_PRINT (1)
@@ -51,13 +52,27 @@ STATIC machine_uint_t unique_codes_alloc = 0;
STATIC mp_code_t *unique_codes = NULL;
STATIC uint next_unique_code_id;
+#ifdef WRITE_CODE
+FILE *fp_write_code = NULL;
+#endif
+
void mp_emit_glue_init(void) {
next_unique_code_id = 0;
unique_codes_alloc = 0;
unique_codes = NULL;
+
+#ifdef WRITE_CODE
+ fp_write_code = fopen("out-code", "wb");
+#endif
}
void mp_emit_glue_deinit(void) {
+#ifdef WRITE_CODE
+ if (fp_write_code != NULL) {
+ fclose(fp_write_code);
+ }
+#endif
+
m_del(mp_code_t, unique_codes, unique_codes_alloc);
}
diff --git a/py/obj.h b/py/obj.h
index af38253c56..500ffbdc04 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -231,6 +231,7 @@ extern const mp_obj_t mp_const_false;
extern const mp_obj_t mp_const_true;
extern const mp_obj_t mp_const_empty_tuple;
extern const mp_obj_t mp_const_ellipsis;
+extern const mp_obj_t mp_const_GeneratorExit;
// General API for objects
diff --git a/py/objexcept.c b/py/objexcept.c
index 71874751b2..d4c4b12492 100644
--- a/py/objexcept.c
+++ b/py/objexcept.c
@@ -21,6 +21,12 @@ typedef struct mp_obj_exception_t {
mp_obj_tuple_t args;
} mp_obj_exception_t;
+// Instance of GeneratorExit exception - needed by generator.close()
+// This would belong to objgenerator.c, but to keep mp_obj_exception_t
+// definition module-private so far, have it here.
+STATIC mp_obj_exception_t GeneratorExit_obj = {{&mp_type_GeneratorExit}, MP_OBJ_NULL, NULL, {{&tuple_type}, 0}};
+const mp_obj_t mp_const_GeneratorExit = (mp_obj_t)&GeneratorExit_obj;
+
STATIC void mp_obj_exception_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t o_in, mp_print_kind_t kind) {
mp_obj_exception_t *o = o_in;
if (o->msg != NULL) {
diff --git a/py/objgenerator.c b/py/objgenerator.c
index aeb5f6219a..f6c7007a02 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -171,7 +171,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gen_instance_throw_obj, 2, 4, gen_ins
STATIC mp_obj_t gen_instance_close(mp_obj_t self_in) {
mp_obj_t ret;
- switch (mp_obj_gen_resume(self_in, mp_const_none, (mp_obj_t)&mp_type_GeneratorExit, &ret)) {
+ switch (mp_obj_gen_resume(self_in, mp_const_none, mp_const_GeneratorExit, &ret)) {
case MP_VM_RETURN_YIELD:
nlr_jump(mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit"));
diff --git a/py/runtime.c b/py/runtime.c
index 762924c20a..3f637a16f9 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -20,7 +20,6 @@
#if 0 // print debugging info
#define DEBUG_PRINT (1)
-#define WRITE_CODE (1)
#define DEBUG_printf DEBUG_printf
#define DEBUG_OP_printf(...) DEBUG_printf(__VA_ARGS__)
#else // don't print debugging info
@@ -33,10 +32,6 @@ STATIC mp_map_t *map_locals;
STATIC mp_map_t *map_globals;
STATIC mp_map_t map_builtins;
-#ifdef WRITE_CODE
-FILE *fp_write_code = NULL;
-#endif
-
// a good optimising compiler will inline this if necessary
STATIC void mp_map_add_qstr(mp_map_t *map, qstr qstr, mp_obj_t value) {
mp_map_lookup(map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = value;
@@ -68,18 +63,9 @@ void rt_init(void) {
// for efficiency, left to platform-specific startup code
//sys_path = mp_obj_new_list(0, NULL);
//rt_store_attr(m_sys, MP_QSTR_path, sys_path);
-
-#ifdef WRITE_CODE
- fp_write_code = fopen("out-code", "wb");
-#endif
}
void rt_deinit(void) {
-#ifdef WRITE_CODE
- if (fp_write_code != NULL) {
- fclose(fp_write_code);
- }
-#endif
mp_map_free(map_globals);
mp_map_deinit(&map_builtins);
mp_module_deinit();
diff --git a/py/showbc.c b/py/showbc.c
index eb743bd29e..12bd901185 100644
--- a/py/showbc.c
+++ b/py/showbc.c
@@ -30,7 +30,16 @@ void mp_byte_code_print(const byte *ip, int len) {
machine_uint_t code_info_size = ip[0] | (ip[1] << 8) | (ip[2] << 16) | (ip[3] << 24);
ip += code_info_size;
- // decode prelude
+ // bytecode prelude: state size and exception stack size; 16 bit uints
+ {
+ uint n_state = ip[0] | (ip[1] << 8);
+ uint n_exc_stack = ip[2] | (ip[3] << 8);
+ ip += 4;
+ printf("(N_STATE %u)\n", n_state);
+ printf("(N_EXC_STACK %u)\n", n_exc_stack);
+ }
+
+ // bytecode prelude: initialise closed over variables
{
uint n_local = *ip++;
printf("(NUM_LOCAL %u)\n", n_local);
@@ -244,6 +253,15 @@ void mp_byte_code_print(const byte *ip, int len) {
printf("SETUP_LOOP " UINT_FMT, ip + unum - ip_start);
break;
+ case MP_BC_SETUP_WITH:
+ DECODE_ULABEL; // loop-like labels are always forward
+ printf("SETUP_WITH " UINT_FMT, ip + unum - ip_start);
+ break;
+
+ case MP_BC_WITH_CLEANUP:
+ printf("WITH_CLEANUP");
+ break;
+
case MP_BC_UNWIND_JUMP:
DECODE_SLABEL;
printf("UNWIND_JUMP " UINT_FMT " %d", ip + unum - ip_start, *ip);