summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
authorScott Shawcroft <scott.shawcroft@gmail.com>2016-11-21 14:30:57 -0800
committerGitHub <noreply@github.com>2016-11-21 14:30:57 -0800
commit3b1109c47bf645109294f7a79dcbfed8cd4c780f (patch)
tree743fef26c6176aca6582b92a85829a565e60c414 /py
parentceeac4791e84607a3f1211310d5f4070205db478 (diff)
parentccbb5e84f980e252f7380d96fcc5c417a8a64523 (diff)
Merge pull request #50 from tannewt/microcontroller
Introduce shared APIs: nativeio, microcontroller and board modules. These are the only hardware API on the atmel-samd port.
Diffstat (limited to 'py')
-rw-r--r--py/argcheck.c2
-rw-r--r--py/gc.c13
-rw-r--r--py/gc.h3
-rw-r--r--py/modbuiltins.c4
-rw-r--r--py/modmath.c2
-rw-r--r--py/mpstate.h4
-rw-r--r--py/nlr.h1
-rw-r--r--py/obj.h2
-rw-r--r--py/objcomplex.c5
-rw-r--r--py/objfloat.c5
-rw-r--r--py/objmodule.c4
-rw-r--r--py/objproperty.c6
-rw-r--r--py/objproperty.h40
-rw-r--r--py/objtype.c5
-rw-r--r--py/parse.c3
-rw-r--r--py/runtime.c48
-rw-r--r--py/runtime0.h2
17 files changed, 132 insertions, 17 deletions
diff --git a/py/argcheck.c b/py/argcheck.c
index 8cef10b16..e12800a36 100644
--- a/py/argcheck.c
+++ b/py/argcheck.c
@@ -134,7 +134,7 @@ void mp_arg_parse_all_kw_array(size_t n_pos, size_t n_kw, const mp_obj_t *args,
mp_arg_parse_all(n_pos, args, &kw_args, n_allowed, allowed, out_vals);
}
-#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE || _MSC_VER
+#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE || defined(_MSC_VER)
NORETURN void mp_arg_error_terse_mismatch(void) {
mp_raise_msg(&mp_type_TypeError, "argument num/types mismatch");
}
diff --git a/py/gc.c b/py/gc.c
index 7ed53cfc7..f883a724e 100644
--- a/py/gc.c
+++ b/py/gc.c
@@ -392,6 +392,16 @@ void gc_info(gc_info_t *info) {
GC_EXIT();
}
+void gc_mark_block(void * ptr) {
+ if (VERIFY_PTR(ptr)) {
+ size_t _block = BLOCK_FROM_PTR(ptr);
+ if (ATB_GET_KIND(_block) == AT_HEAD) {
+ /* an unmarked head, mark it, and push it on gc stack */
+ ATB_HEAD_TO_MARK(_block);
+ }
+ }
+}
+
void *gc_alloc(size_t n_bytes, bool has_finaliser) {
size_t n_blocks = ((n_bytes + BYTES_PER_BLOCK - 1) & (~(BYTES_PER_BLOCK - 1))) / BYTES_PER_BLOCK;
DEBUG_printf("gc_alloc(" UINT_FMT " bytes -> " UINT_FMT " blocks)\n", n_bytes, n_blocks);
@@ -833,7 +843,10 @@ void gc_dump_alloc_table(void) {
*/
/* this prints the uPy object type of the head block */
case AT_HEAD: {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
void **ptr = (void**)(MP_STATE_MEM(gc_pool_start) + bl * BYTES_PER_BLOCK);
+#pragma GCC diagnostic pop
if (*ptr == &mp_type_tuple) { c = 'T'; }
else if (*ptr == &mp_type_list) { c = 'L'; }
else if (*ptr == &mp_type_dict) { c = 'D'; }
diff --git a/py/gc.h b/py/gc.h
index 7d8fe2bf8..64c478996 100644
--- a/py/gc.h
+++ b/py/gc.h
@@ -45,6 +45,9 @@ void gc_collect_start(void);
void gc_collect_root(void **ptrs, size_t len);
void gc_collect_end(void);
+// During a collect, use this to mark blocks used in C but allocated using gc_alloc.
+void gc_mark_block(void * ptr);
+
void *gc_alloc(size_t n_bytes, bool has_finaliser);
void gc_free(void *ptr); // does not call finaliser
size_t gc_nbytes(const void *ptr);
diff --git a/py/modbuiltins.c b/py/modbuiltins.c
index cbdcc9aae..401d9f541 100644
--- a/py/modbuiltins.c
+++ b/py/modbuiltins.c
@@ -470,9 +470,9 @@ STATIC mp_obj_t mp_builtin_round(size_t n_args, const mp_obj_t *args) {
mp_float_t rounded = MICROPY_FLOAT_C_FUN(round)(val);
mp_int_t r = rounded;
// make rounded value even if it was halfway between ints
- if (val - rounded == 0.5) {
+ if (val - rounded >= 0.5) {
r = (r + 1) & (~1);
- } else if (val - rounded == -0.5) {
+ } else if (val - rounded <= -0.5) {
r &= ~1;
}
if (n_args > 1) {
diff --git a/py/modmath.c b/py/modmath.c
index 7c51eab03..7b67751bc 100644
--- a/py/modmath.c
+++ b/py/modmath.c
@@ -70,7 +70,7 @@ STATIC NORETURN void math_error(void) {
} \
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_math_## py_name ## _obj, mp_math_ ## py_name);
-#if MP_NEED_LOG2
+#ifdef MP_NEED_LOG2
// 1.442695040888963407354163704 is 1/_M_LN2
#define log2(x) (log(x) * 1.442695040888963407354163704)
#endif
diff --git a/py/mpstate.h b/py/mpstate.h
index 439ed6606..66504b527 100644
--- a/py/mpstate.h
+++ b/py/mpstate.h
@@ -146,12 +146,12 @@ typedef struct _mp_state_vm_t {
// root pointers for extmod
- #if MICROPY_PY_OS_DUPTERM
+ #ifdef MICROPY_PY_OS_DUPTERM
mp_obj_t term_obj;
mp_obj_t dupterm_arr_obj;
#endif
- #if MICROPY_PY_LWIP_SLIP
+ #ifdef MICROPY_PY_LWIP_SLIP
mp_obj_t lwip_slip_stream;
#endif
diff --git a/py/nlr.h b/py/nlr.h
index 6c86fc26c..225d200cb 100644
--- a/py/nlr.h
+++ b/py/nlr.h
@@ -41,6 +41,7 @@ struct _nlr_buf_t {
nlr_buf_t *prev;
void *ret_val; // always a concrete object (an exception instance)
#if !defined(MICROPY_NLR_SETJMP) || !MICROPY_NLR_SETJMP
+#define MICROPY_NLR_SETJMP (0)
#if defined(__i386__)
void *regs[6];
#elif defined(__x86_64__)
diff --git a/py/obj.h b/py/obj.h
index 61db65a9a..1da8f3e5a 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -513,8 +513,6 @@ struct _mp_obj_type_t {
extern const mp_obj_type_t mp_type_type;
extern const mp_obj_type_t mp_type_object;
extern const mp_obj_type_t mp_type_NoneType;
-extern const mp_obj_type_t mp_type_bool;
-extern const mp_obj_type_t mp_type_int;
extern const mp_obj_type_t mp_type_str;
extern const mp_obj_type_t mp_type_bytes;
extern const mp_obj_type_t mp_type_bytearray;
diff --git a/py/objcomplex.c b/py/objcomplex.c
index 96be25255..b302b1d56 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -39,6 +39,9 @@
#include <math.h>
#include "py/formatfloat.h"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+
typedef struct _mp_obj_complex_t {
mp_obj_base_t base;
mp_float_t real;
@@ -248,4 +251,6 @@ mp_obj_t mp_obj_complex_binary_op(mp_uint_t op, mp_float_t lhs_real, mp_float_t
return mp_obj_new_complex(lhs_real, lhs_imag);
}
+#pragma GCC diagnostic pop
+
#endif
diff --git a/py/objfloat.c b/py/objfloat.c
index 73d07feac..4a32a9e96 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -39,6 +39,9 @@
#include <math.h>
#include "py/formatfloat.h"
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wfloat-equal"
+
#if MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_C && MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_D
// M_E and M_PI are not part of the math.h standard and may not be defined
@@ -252,4 +255,6 @@ mp_obj_t mp_obj_float_binary_op(mp_uint_t op, mp_float_t lhs_val, mp_obj_t rhs_i
return mp_obj_new_float(lhs_val);
}
+#pragma GCC diagnostic pop
+
#endif // MICROPY_PY_BUILTINS_FLOAT
diff --git a/py/objmodule.c b/py/objmodule.c
index 9b06e3b7b..7ed3175c0 100644
--- a/py/objmodule.c
+++ b/py/objmodule.c
@@ -201,13 +201,13 @@ STATIC const mp_rom_map_elem_t mp_builtin_module_table[] = {
#if MICROPY_PY_USSL
{ MP_ROM_QSTR(MP_QSTR_ussl), MP_ROM_PTR(&mp_module_ussl) },
#endif
-#if MICROPY_PY_LWIP
+#ifdef MICROPY_PY_LWIP
{ MP_ROM_QSTR(MP_QSTR_lwip), MP_ROM_PTR(&mp_module_lwip) },
#endif
#if MICROPY_PY_WEBSOCKET
{ MP_ROM_QSTR(MP_QSTR_websocket), MP_ROM_PTR(&mp_module_websocket) },
#endif
-#if MICROPY_PY_WEBREPL
+#ifdef MICROPY_PY_WEBREPL
{ MP_ROM_QSTR(MP_QSTR__webrepl), MP_ROM_PTR(&mp_module_webrepl) },
#endif
#if MICROPY_PY_FRAMEBUF
diff --git a/py/objproperty.c b/py/objproperty.c
index 8189935d2..e7e5cd986 100644
--- a/py/objproperty.c
+++ b/py/objproperty.c
@@ -28,15 +28,11 @@
#include <assert.h>
#include "py/nlr.h"
+#include "py/objproperty.h"
#include "py/runtime.h"
#if MICROPY_PY_BUILTINS_PROPERTY
-typedef struct _mp_obj_property_t {
- mp_obj_base_t base;
- mp_obj_t proxy[3]; // getter, setter, deleter
-} mp_obj_property_t;
-
STATIC mp_obj_t property_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
enum { ARG_fget, ARG_fset, ARG_fdel, ARG_doc };
static const mp_arg_t allowed_args[] = {
diff --git a/py/objproperty.h b/py/objproperty.h
new file mode 100644
index 000000000..1852e6b6e
--- /dev/null
+++ b/py/objproperty.h
@@ -0,0 +1,40 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013, 2014 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef __MICROPY_INCLUDED_PY_OBJPROPERTY_H__
+#define __MICROPY_INCLUDED_PY_OBJPROPERTY_H__
+
+#include "py/obj.h"
+
+#if MICROPY_PY_BUILTINS_PROPERTY
+
+typedef struct _mp_obj_property_t {
+ mp_obj_base_t base;
+ mp_obj_t proxy[3]; // getter, setter, deleter
+} mp_obj_property_t;
+
+#endif // MICROPY_PY_BUILTINS_PROPERTY
+
+#endif // __MICROPY_INCLUDED_PY_OBJPROPERTY_H__
diff --git a/py/objtype.c b/py/objtype.c
index 8b46c5400..0fbc597cd 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -110,7 +110,10 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_
// this should not be applied to class types, as will result in extra
// lookup either.
if (lookup->meth_offset != 0 && mp_obj_is_native_type(type)) {
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
if (*(void**)((char*)type + lookup->meth_offset) != NULL) {
+#pragma GCC diagnostic pop
DEBUG_printf("mp_obj_class_lookup: matched special meth slot for %s\n", qstr_str(lookup->attr));
lookup->dest[0] = MP_OBJ_SENTINEL;
return;
@@ -368,7 +371,7 @@ STATIC mp_obj_t instance_unary_op(mp_uint_t op, mp_obj_t self_in) {
if (member[0] == MP_OBJ_NULL) {
// https://docs.python.org/3/reference/datamodel.html#object.__hash__
// "User-defined classes have __eq__() and __hash__() methods by default;
- // with them, all objects compare unequal (except with themselves) and
+ // with them, all objects compare unequal (except with themselves) and
// x.__hash__() returns an appropriate value such that x == y implies
// both that x is y and hash(x) == hash(y)."
return MP_OBJ_NEW_SMALL_INT((mp_uint_t)self_in);
diff --git a/py/parse.c b/py/parse.c
index 397d46d9f..1787265b3 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -152,6 +152,8 @@ typedef struct _parser_t {
#endif
} parser_t;
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-align"
STATIC void *parser_alloc(parser_t *parser, size_t num_bytes) {
// use a custom memory allocator to store parse nodes sequentially in large chunks
@@ -192,6 +194,7 @@ STATIC void *parser_alloc(parser_t *parser, size_t num_bytes) {
chunk->union_.used += num_bytes;
return ret;
}
+#pragma GCC diagnostic pop
STATIC void push_rule(parser_t *parser, size_t src_line, const rule_t *rule, size_t arg_i) {
if (parser->parse_error) {
diff --git a/py/runtime.c b/py/runtime.c
index c25557464..f48a52755 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -34,6 +34,7 @@
#include "py/compile.h"
#include "py/objstr.h"
#include "py/objtuple.h"
+#include "py/objtype.h"
#include "py/objlist.h"
#include "py/objmodule.h"
#include "py/objgenerator.h"
@@ -102,7 +103,7 @@ void mp_deinit(void) {
//mp_obj_dict_free(&dict_main);
mp_module_deinit();
- // call port specific deinitialization if any
+ // call port specific deinitialization if any
#ifdef MICROPY_PORT_INIT_FUNC
MICROPY_PORT_DEINIT_FUNC;
#endif
@@ -989,6 +990,22 @@ void mp_convert_member_lookup(mp_obj_t self, const mp_obj_type_t *type, mp_obj_t
dest[0] = member;
dest[1] = self;
}
+ #if MICROPY_PY_BUILTINS_PROPERTY
+ } else if (MP_OBJ_IS_TYPE(member, &mp_type_property) && mp_obj_is_native_type(type)) {
+ // object member is a property; delegate the load to the property
+ // Note: This is an optimisation for code size and execution time.
+ // The proper way to do it is have the functionality just below
+ // in a __get__ method of the property object, and then it would
+ // be called by the descriptor code down below. But that way
+ // requires overhead for the nested mp_call's and overhead for
+ // the code.
+ const mp_obj_t *proxy = mp_obj_property_get(member);
+ if (proxy[0] == mp_const_none) {
+ mp_raise_msg(&mp_type_AttributeError, "unreadable attribute");
+ } else {
+ dest[0] = mp_call_function_n_kw(proxy[0], 1, 0, &self);
+ }
+ #endif
} else {
// class member is a value, so just return that value
dest[0] = member;
@@ -1068,6 +1085,35 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) {
// success
return;
}
+ #if MICROPY_PY_BUILTINS_PROPERTY
+ } else if (type->locals_dict != NULL) {
+ // generic method lookup
+ // this is a lookup in the object (ie not class or type)
+ assert(type->locals_dict->base.type == &mp_type_dict); // Micro Python restriction, for now
+ mp_map_t *locals_map = &type->locals_dict->map;
+ mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
+ if (elem != NULL && MP_OBJ_IS_TYPE(elem->value, &mp_type_property)) {
+ // attribute exists and is a property; delegate the store/delete
+ // Note: This is an optimisation for code size and execution time.
+ // The proper way to do it is have the functionality just below in
+ // a __set__/__delete__ method of the property object, and then it
+ // would be called by the descriptor code down below. But that way
+ // requires overhead for the nested mp_call's and overhead for
+ // the code.
+ const mp_obj_t *proxy = mp_obj_property_get(elem->value);
+ mp_obj_t dest[2] = {base, value};
+ if (value == MP_OBJ_NULL) {
+ // delete attribute
+ if (proxy[2] != mp_const_none) {
+ mp_call_function_n_kw(proxy[2], 1, 0, dest);
+ return;
+ }
+ } else if (proxy[1] != mp_const_none) {
+ mp_call_function_n_kw(proxy[1], 2, 0, dest);
+ return;
+ }
+ }
+ #endif
}
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
mp_raise_msg(&mp_type_AttributeError, "no such attribute");
diff --git a/py/runtime0.h b/py/runtime0.h
index 8d62403a7..a803c3665 100644
--- a/py/runtime0.h
+++ b/py/runtime0.h
@@ -26,6 +26,8 @@
#ifndef __MICROPY_INCLUDED_PY_RUNTIME0_H__
#define __MICROPY_INCLUDED_PY_RUNTIME0_H__
+#include "mpconfig.h"
+
// These must fit in 8 bits; see scope.h
#define MP_SCOPE_FLAG_VARARGS (0x01)
#define MP_SCOPE_FLAG_VARKEYWORDS (0x02)