diff options
| author | Scott Shawcroft <scott.shawcroft@gmail.com> | 2016-11-21 14:30:57 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-11-21 14:30:57 -0800 |
| commit | 3b1109c47bf645109294f7a79dcbfed8cd4c780f (patch) | |
| tree | 743fef26c6176aca6582b92a85829a565e60c414 /py | |
| parent | ceeac4791e84607a3f1211310d5f4070205db478 (diff) | |
| parent | ccbb5e84f980e252f7380d96fcc5c417a8a64523 (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.c | 2 | ||||
| -rw-r--r-- | py/gc.c | 13 | ||||
| -rw-r--r-- | py/gc.h | 3 | ||||
| -rw-r--r-- | py/modbuiltins.c | 4 | ||||
| -rw-r--r-- | py/modmath.c | 2 | ||||
| -rw-r--r-- | py/mpstate.h | 4 | ||||
| -rw-r--r-- | py/nlr.h | 1 | ||||
| -rw-r--r-- | py/obj.h | 2 | ||||
| -rw-r--r-- | py/objcomplex.c | 5 | ||||
| -rw-r--r-- | py/objfloat.c | 5 | ||||
| -rw-r--r-- | py/objmodule.c | 4 | ||||
| -rw-r--r-- | py/objproperty.c | 6 | ||||
| -rw-r--r-- | py/objproperty.h | 40 | ||||
| -rw-r--r-- | py/objtype.c | 5 | ||||
| -rw-r--r-- | py/parse.c | 3 | ||||
| -rw-r--r-- | py/runtime.c | 48 | ||||
| -rw-r--r-- | py/runtime0.h | 2 |
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"); } @@ -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'; } @@ -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 @@ -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__) @@ -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) |
