summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorHierophect <hierophect@gmail.com>2019-12-05 14:25:39 -0500
committerHierophect <hierophect@gmail.com>2019-12-05 14:25:39 -0500
commit9b43d5ced4d41b58209cc37434543bd990cced8f (patch)
treee20cf5c6d22da140c16a6810011dd3ea0d4af443 /py
parent0d8eb3cfb4ef0e2a01a657752603a4c259423e46 (diff)
parent12f64c7c16377c0600d7b09e7848474254e46d1e (diff)
Merge remote-tracking branch 'upstream/master' into stm32-blackpill
Diffstat (limited to 'py')
-rw-r--r--py/circuitpy_mpconfig.h13
-rw-r--r--py/circuitpy_mpconfig.mk4
-rw-r--r--py/compile.c13
-rwxr-xr-xpy/gc.c10
-rw-r--r--py/gc.h11
-rwxr-xr-xpy/gc_long_lived.c5
-rw-r--r--py/makeqstrdata.py39
-rw-r--r--py/runtime.c2
8 files changed, 54 insertions, 43 deletions
diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h
index b1e7bc05a..3e83d0c51 100644
--- a/py/circuitpy_mpconfig.h
+++ b/py/circuitpy_mpconfig.h
@@ -28,11 +28,12 @@
// sure that the same feature set and settings are used, such as in atmel-samd
// and nrf.
-#include <stdint.h>
-
#ifndef __INCLUDED_MPCONFIG_CIRCUITPY_H
#define __INCLUDED_MPCONFIG_CIRCUITPY_H
+#include <stdint.h>
+#include <stdatomic.h>
+
// This is CircuitPython.
#define CIRCUITPY 1
@@ -652,14 +653,14 @@ extern const struct _mp_obj_module_t ustack_module;
FLASH_ROOT_POINTERS \
NETWORK_ROOT_POINTERS \
-void run_background_tasks(void);
-#define RUN_BACKGROUND_TASKS (run_background_tasks())
+void supervisor_run_background_tasks_if_tick(void);
+#define RUN_BACKGROUND_TASKS (supervisor_run_background_tasks_if_tick())
// TODO: Used in wiznet5k driver, but may not be needed in the long run.
#define MICROPY_THREAD_YIELD()
-#define MICROPY_VM_HOOK_LOOP run_background_tasks();
-#define MICROPY_VM_HOOK_RETURN run_background_tasks();
+#define MICROPY_VM_HOOK_LOOP RUN_BACKGROUND_TASKS;
+#define MICROPY_VM_HOOK_RETURN RUN_BACKGROUND_TASKS;
#define CIRCUITPY_AUTORELOAD_DELAY_MS 500
#define CIRCUITPY_FILESYSTEM_FLUSH_INTERVAL_MS 1000
diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk
index c1199571b..241fa1017 100644
--- a/py/circuitpy_mpconfig.mk
+++ b/py/circuitpy_mpconfig.mk
@@ -53,7 +53,7 @@ ifndef CIRCUITPY_DEFAULT_BUILD
endif
# Some features have no unique HAL component, and thus there's never
-# a reason to not include them.
+# a reason to not include them.
ifndef CIRCUITPY_ALWAYS_BUILD
CIRCUITPY_ALWAYS_BUILD = 1
endif
@@ -170,7 +170,7 @@ CIRCUITPY_NEOPIXEL_WRITE = $(CIRCUITPY_DEFAULT_BUILD)
endif
CFLAGS += -DCIRCUITPY_NEOPIXEL_WRITE=$(CIRCUITPY_NEOPIXEL_WRITE)
-# Only certain boards support NETWORK (Ethernet)
+# Enabled on SAMD51. Won't fit on SAMD21 builds. Not tested on nRF or STM32F4 builds.
ifndef CIRCUITPY_NETWORK
CIRCUITPY_NETWORK = 0
endif
diff --git a/py/compile.c b/py/compile.c
index 8b17935bd..77715d3fe 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -775,13 +775,22 @@ STATIC bool compile_built_in_decorator(compiler_t *comp, int name_len, mp_parse_
qstr attr = MP_PARSE_NODE_LEAF_ARG(name_nodes[1]);
if (attr == MP_QSTR_bytecode) {
*emit_options = MP_EMIT_OPT_BYTECODE;
-#if MICROPY_EMIT_NATIVE
+ // @micropython.native decorator.
} else if (attr == MP_QSTR_native) {
+ // Different from MicroPython: native doesn't raise SyntaxError if native support isn't
+ // compiled, it just passes through the function unmodified.
+ #if MICROPY_EMIT_NATIVE
*emit_options = MP_EMIT_OPT_NATIVE_PYTHON;
+ #else
+ return true;
+ #endif
+ #if MICROPY_EMIT_NATIVE
+ // @micropython.viper decorator.
} else if (attr == MP_QSTR_viper) {
*emit_options = MP_EMIT_OPT_VIPER;
-#endif
+ #endif
#if MICROPY_EMIT_INLINE_ASM
+ // @micropython.asm_thumb decorator.
} else if (attr == ASM_DECORATOR_QSTR) {
*emit_options = MP_EMIT_OPT_ASM;
#endif
diff --git a/py/gc.c b/py/gc.c
index ac584d5d2..a8a5fde12 100755
--- a/py/gc.c
+++ b/py/gc.c
@@ -53,9 +53,6 @@
// detect untraced object still in use
#define CLEAR_ON_SWEEP (0)
-#define WORDS_PER_BLOCK ((MICROPY_BYTES_PER_GC_BLOCK) / BYTES_PER_WORD)
-#define BYTES_PER_BLOCK (MICROPY_BYTES_PER_GC_BLOCK)
-
// ATB = allocation table byte
// 0b00 = FREE -- free block
// 0b01 = HEAD -- head of a chain of blocks
@@ -209,13 +206,6 @@ bool gc_is_locked(void) {
return MP_STATE_MEM(gc_lock_depth) != 0;
}
-// ptr should be of type void*
-#define VERIFY_PTR(ptr) ( \
- ((uintptr_t)(ptr) & (BYTES_PER_BLOCK - 1)) == 0 /* must be aligned on a block */ \
- && ptr >= (void*)MP_STATE_MEM(gc_pool_start) /* must be above start of pool */ \
- && ptr < (void*)MP_STATE_MEM(gc_pool_end) /* must be below end of pool */ \
- )
-
#ifndef TRACE_MARK
#if DEBUG_PRINT
#define TRACE_MARK(block, ptr) DEBUG_printf("gc_mark(%p)\n", ptr)
diff --git a/py/gc.h b/py/gc.h
index 02bf45158..cd63ba94c 100644
--- a/py/gc.h
+++ b/py/gc.h
@@ -29,8 +29,19 @@
#include <stdint.h>
#include "py/mpconfig.h"
+#include "py/mpstate.h"
#include "py/misc.h"
+#define WORDS_PER_BLOCK ((MICROPY_BYTES_PER_GC_BLOCK) / BYTES_PER_WORD)
+#define BYTES_PER_BLOCK (MICROPY_BYTES_PER_GC_BLOCK)
+
+// ptr should be of type void*
+#define VERIFY_PTR(ptr) ( \
+ ((uintptr_t)(ptr) & (BYTES_PER_BLOCK - 1)) == 0 /* must be aligned on a block */ \
+ && ptr >= (void*)MP_STATE_MEM(gc_pool_start) /* must be above start of pool */ \
+ && ptr < (void*)MP_STATE_MEM(gc_pool_end) /* must be below end of pool */ \
+ )
+
void gc_init(void *start, void *end);
void gc_deinit(void);
diff --git a/py/gc_long_lived.c b/py/gc_long_lived.c
index 49bf1fcd7..01c22a7af 100755
--- a/py/gc_long_lived.c
+++ b/py/gc_long_lived.c
@@ -126,6 +126,11 @@ mp_obj_t make_obj_long_lived(mp_obj_t obj, uint8_t max_depth){
if (obj == NULL) {
return obj;
}
+ // If not in the GC pool, do nothing. This can happen (at least) when
+ // there are frozen mp_type_bytes objects in ROM.
+ if (!VERIFY_PTR((void *)obj)) {
+ return obj;
+ }
if (MP_OBJ_IS_TYPE(obj, &mp_type_fun_bc)) {
mp_obj_fun_bc_t *fun_bc = MP_OBJ_TO_PTR(obj);
return MP_OBJ_FROM_PTR(make_fun_bc_long_lived(fun_bc, max_depth));
diff --git a/py/makeqstrdata.py b/py/makeqstrdata.py
index 8e3835d86..0d667959d 100644
--- a/py/makeqstrdata.py
+++ b/py/makeqstrdata.py
@@ -103,14 +103,10 @@ def compute_huffman_coding(translations, qstrs, compression_filename):
# go through each qstr and print it out
for _, _, qstr in qstrs.values():
all_strings.append(qstr)
- all_strings_concat = "".join(all_strings).encode("utf-8")
+ all_strings_concat = "".join(all_strings)
counts = collections.Counter(all_strings_concat)
- # add other values
- for i in range(256):
- if i not in counts:
- counts[i] = 0
cb = huffman.codebook(counts.items())
- values = bytearray()
+ values = []
length_count = {}
renumbered = 0
last_l = None
@@ -124,26 +120,27 @@ def compute_huffman_coding(translations, qstrs, compression_filename):
if last_l:
renumbered <<= (l - last_l)
canonical[ch] = '{0:0{width}b}'.format(renumbered, width=l)
- if chr(ch) in C_ESCAPES:
- s = C_ESCAPES[chr(ch)]
- else:
- s = chr(ch)
- print("//", ch, s, counts[ch], canonical[ch], renumbered)
+ s = C_ESCAPES.get(ch, ch)
+ print("//", ord(ch), s, counts[ch], canonical[ch], renumbered)
renumbered += 1
last_l = l
lengths = bytearray()
- for i in range(1, max(length_count) + 1):
+ print("// length count", length_count)
+ for i in range(1, max(length_count) + 2):
lengths.append(length_count.get(i, 0))
+ print("// values", values, "lengths", len(lengths), lengths)
+ print("// estimated total memory size", len(lengths) + 2*len(values) + sum(len(cb[u]) for u in all_strings_concat))
print("//", values, lengths)
+ values_type = "uint16_t" if max(ord(u) for u in values) > 255 else "uint8_t"
with open(compression_filename, "w") as f:
f.write("const uint8_t lengths[] = {{ {} }};\n".format(", ".join(map(str, lengths))))
- f.write("const uint8_t values[256] = {{ {} }};\n".format(", ".join(map(str, values))))
+ f.write("const {} values[] = {{ {} }};\n".format(values_type, ", ".join(str(ord(u)) for u in values)))
return values, lengths
def decompress(encoding_table, length, encoded):
values, lengths = encoding_table
#print(l, encoded)
- dec = bytearray(length)
+ dec = []
this_byte = 0
this_bit = 7
b = encoded[this_byte]
@@ -173,14 +170,14 @@ def decompress(encoding_table, length, encoded):
searched_length += lengths[bit_length]
v = values[searched_length + bits - max_code]
- dec[i] = v
- return dec
+ dec.append(v)
+ return ''.join(dec)
def compress(encoding_table, decompressed):
- if not isinstance(decompressed, bytes):
+ if not isinstance(decompressed, str):
raise TypeError()
values, lengths = encoding_table
- enc = bytearray(len(decompressed) * 2)
+ enc = bytearray(len(decompressed) * 3)
#print(decompressed)
#print(lengths)
current_bit = 7
@@ -228,7 +225,7 @@ def compress(encoding_table, decompressed):
if current_bit != 7:
current_byte += 1
if current_byte > len(decompressed):
- print("Note: compression increased length", repr(decompressed.decode('utf-8')), len(decompressed), current_byte, file=sys.stderr)
+ print("Note: compression increased length", repr(decompressed), len(decompressed), current_byte, file=sys.stderr)
return enc[:current_byte]
def qstr_escape(qst):
@@ -347,9 +344,9 @@ def print_qstr_data(encoding_table, qcfgs, qstrs, i18ns):
total_text_compressed_size = 0
for original, translation in i18ns:
translation_encoded = translation.encode("utf-8")
- compressed = compress(encoding_table, translation_encoded)
+ compressed = compress(encoding_table, translation)
total_text_compressed_size += len(compressed)
- decompressed = decompress(encoding_table, len(translation_encoded), compressed).decode("utf-8")
+ decompressed = decompress(encoding_table, len(translation_encoded), compressed)
for c in C_ESCAPES:
decompressed = decompressed.replace(c, C_ESCAPES[c])
print("TRANSLATION(\"{}\", {}, {{ {} }}) // {}".format(original, len(translation_encoded)+1, ", ".join(["0x{:02x}".format(x) for x in compressed]), decompressed))
diff --git a/py/runtime.c b/py/runtime.c
index 9968f26e0..a786619bf 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -31,8 +31,6 @@
#include "extmod/vfs.h"
-// #include "py/mpstate.h"
-// #include "py/nlr.h"
#include "py/parsenum.h"
#include "py/compile.h"
#include "py/objstr.h"