Explorar o código

[增加] :新版本miropython中py文件夹下增加的文件。

SummerGift %!s(int64=8) %!d(string=hai) anos
pai
achega
9c8cfbacdd
Modificáronse 5 ficheiros con 391 adicións e 0 borrados
  1. 51 0
      py/nlr.c
  2. 44 0
      py/objnamedtuple.h
  3. 56 0
      py/pystack.c
  4. 123 0
      py/pystack.h
  5. 117 0
      py/scheduler.c

+ 51 - 0
py/nlr.c

@@ -0,0 +1,51 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013-2017 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.
+ */
+
+#include "py/mpstate.h"
+
+#if !MICROPY_NLR_SETJMP
+// When not using setjmp, nlr_push_tail is called from inline asm so needs special care
+#if MICROPY_NLR_X86 && MICROPY_NLR_OS_WINDOWS
+// On these 32-bit platforms make sure nlr_push_tail doesn't have a leading underscore
+unsigned int nlr_push_tail(nlr_buf_t *nlr) asm("nlr_push_tail");
+#else
+// LTO can't see inside inline asm functions so explicitly mark nlr_push_tail as used
+__attribute__((used)) unsigned int nlr_push_tail(nlr_buf_t *nlr);
+#endif
+#endif
+
+unsigned int nlr_push_tail(nlr_buf_t *nlr) {
+    nlr_buf_t **top = &MP_STATE_THREAD(nlr_top);
+    nlr->prev = *top;
+    MP_NLR_SAVE_PYSTACK(nlr);
+    *top = nlr;
+    return 0; // normal return
+}
+
+void nlr_pop(void) {
+    nlr_buf_t **top = &MP_STATE_THREAD(nlr_top);
+    *top = (*top)->prev;
+}

+ 44 - 0
py/objnamedtuple.h

@@ -0,0 +1,44 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014-2017 Paul Sokolovsky
+ *
+ * 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_OBJNAMEDTUPLE_H
+#define MICROPY_INCLUDED_PY_OBJNAMEDTUPLE_H
+
+#include "py/objtuple.h"
+
+typedef struct _mp_obj_namedtuple_type_t {
+    mp_obj_type_t base;
+    size_t n_fields;
+    qstr fields[];
+} mp_obj_namedtuple_type_t;
+
+typedef struct _mp_obj_namedtuple_t {
+    mp_obj_tuple_t tuple;
+} mp_obj_namedtuple_t;
+
+size_t mp_obj_namedtuple_find_field(const mp_obj_namedtuple_type_t *type, qstr name);
+mp_obj_namedtuple_type_t *mp_obj_new_namedtuple_base(size_t n_fields, mp_obj_t *fields);
+
+#endif // MICROPY_INCLUDED_PY_OBJNAMEDTUPLE_H

+ 56 - 0
py/pystack.c

@@ -0,0 +1,56 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 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.
+ */
+
+#include <stdio.h>
+
+#include "py/runtime.h"
+
+#if MICROPY_ENABLE_PYSTACK
+
+void mp_pystack_init(void *start, void *end) {
+    MP_STATE_THREAD(pystack_start) = start;
+    MP_STATE_THREAD(pystack_end) = end;
+    MP_STATE_THREAD(pystack_cur) = start;
+}
+
+void *mp_pystack_alloc(size_t n_bytes) {
+    n_bytes = (n_bytes + (MICROPY_PYSTACK_ALIGN - 1)) & ~(MICROPY_PYSTACK_ALIGN - 1);
+    #if MP_PYSTACK_DEBUG
+    n_bytes += MICROPY_PYSTACK_ALIGN;
+    #endif
+    if (MP_STATE_THREAD(pystack_cur) + n_bytes > MP_STATE_THREAD(pystack_end)) {
+        // out of memory in the pystack
+        mp_raise_recursion_depth();
+    }
+    void *ptr = MP_STATE_THREAD(pystack_cur);
+    MP_STATE_THREAD(pystack_cur) += n_bytes;
+    #if MP_PYSTACK_DEBUG
+    *(size_t*)(MP_STATE_THREAD(pystack_cur) - MICROPY_PYSTACK_ALIGN) = n_bytes;
+    #endif
+    return ptr;
+}
+
+#endif

+ 123 - 0
py/pystack.h

@@ -0,0 +1,123 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 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_PYSTACK_H
+#define MICROPY_INCLUDED_PY_PYSTACK_H
+
+#include "py/mpstate.h"
+
+// Enable this debugging option to check that the amount of memory freed is
+// consistent with amounts that were previously allocated.
+#define MP_PYSTACK_DEBUG (0)
+
+#if MICROPY_ENABLE_PYSTACK
+
+void mp_pystack_init(void *start, void *end);
+void *mp_pystack_alloc(size_t n_bytes);
+
+// This function can free multiple continuous blocks at once: just pass the
+// pointer to the block that was allocated first and it and all subsequently
+// allocated blocks will be freed.
+static inline void mp_pystack_free(void *ptr) {
+    assert((uint8_t*)ptr >= MP_STATE_THREAD(pystack_start));
+    assert((uint8_t*)ptr <= MP_STATE_THREAD(pystack_cur));
+    #if MP_PYSTACK_DEBUG
+    size_t n_bytes_to_free = MP_STATE_THREAD(pystack_cur) - (uint8_t*)ptr;
+    size_t n_bytes = *(size_t*)(MP_STATE_THREAD(pystack_cur) - MICROPY_PYSTACK_ALIGN);
+    while (n_bytes < n_bytes_to_free) {
+        n_bytes += *(size_t*)(MP_STATE_THREAD(pystack_cur) - n_bytes - MICROPY_PYSTACK_ALIGN);
+    }
+    if (n_bytes != n_bytes_to_free) {
+        mp_printf(&mp_plat_print, "mp_pystack_free() failed: %u != %u\n", (uint)n_bytes_to_free,
+            (uint)*(size_t*)(MP_STATE_THREAD(pystack_cur) - MICROPY_PYSTACK_ALIGN));
+        assert(0);
+    }
+    #endif
+    MP_STATE_THREAD(pystack_cur) = (uint8_t*)ptr;
+}
+
+static inline void mp_pystack_realloc(void *ptr, size_t n_bytes) {
+    mp_pystack_free(ptr);
+    mp_pystack_alloc(n_bytes);
+}
+
+static inline size_t mp_pystack_usage(void) {
+    return MP_STATE_THREAD(pystack_cur) - MP_STATE_THREAD(pystack_start);
+}
+
+static inline size_t mp_pystack_limit(void) {
+    return MP_STATE_THREAD(pystack_end) - MP_STATE_THREAD(pystack_start);
+}
+
+#endif
+
+#if !MICROPY_ENABLE_PYSTACK
+
+#define mp_local_alloc(n_bytes) alloca(n_bytes)
+
+static inline void mp_local_free(void *ptr) {
+    (void)ptr;
+}
+
+static inline void *mp_nonlocal_alloc(size_t n_bytes) {
+    return m_new(uint8_t, n_bytes);
+}
+
+static inline void *mp_nonlocal_realloc(void *ptr, size_t old_n_bytes, size_t new_n_bytes) {
+    return m_renew(uint8_t, ptr, old_n_bytes, new_n_bytes);
+}
+
+static inline void mp_nonlocal_free(void *ptr, size_t n_bytes) {
+    m_del(uint8_t, ptr, n_bytes);
+}
+
+#else
+
+static inline void *mp_local_alloc(size_t n_bytes) {
+    return mp_pystack_alloc(n_bytes);
+}
+
+static inline void mp_local_free(void *ptr) {
+    mp_pystack_free(ptr);
+}
+
+static inline void *mp_nonlocal_alloc(size_t n_bytes) {
+    return mp_pystack_alloc(n_bytes);
+}
+
+static inline void *mp_nonlocal_realloc(void *ptr, size_t old_n_bytes, size_t new_n_bytes) {
+    (void)old_n_bytes;
+    mp_pystack_realloc(ptr, new_n_bytes);
+    return ptr;
+}
+
+static inline void mp_nonlocal_free(void *ptr, size_t n_bytes) {
+    (void)n_bytes;
+    mp_pystack_free(ptr);
+}
+
+#endif
+
+#endif // MICROPY_INCLUDED_PY_PYSTACK_H

+ 117 - 0
py/scheduler.c

@@ -0,0 +1,117 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 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.
+ */
+
+#include <stdio.h>
+
+#include "py/runtime.h"
+
+#if MICROPY_ENABLE_SCHEDULER
+
+// A variant of this is inlined in the VM at the pending exception check
+void mp_handle_pending(void) {
+    if (MP_STATE_VM(sched_state) == MP_SCHED_PENDING) {
+        mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
+        mp_obj_t obj = MP_STATE_VM(mp_pending_exception);
+        if (obj != MP_OBJ_NULL) {
+            MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;
+            if (!mp_sched_num_pending()) {
+                MP_STATE_VM(sched_state) = MP_SCHED_IDLE;
+            }
+            MICROPY_END_ATOMIC_SECTION(atomic_state);
+            nlr_raise(obj);
+        }
+        mp_handle_pending_tail(atomic_state);
+    }
+}
+
+// This function should only be called be mp_sched_handle_pending,
+// or by the VM's inlined version of that function.
+void mp_handle_pending_tail(mp_uint_t atomic_state) {
+    MP_STATE_VM(sched_state) = MP_SCHED_LOCKED;
+    if (MP_STATE_VM(sched_sp) > 0) {
+        mp_sched_item_t item = MP_STATE_VM(sched_stack)[--MP_STATE_VM(sched_sp)];
+        MICROPY_END_ATOMIC_SECTION(atomic_state);
+        mp_call_function_1_protected(item.func, item.arg);
+    } else {
+        MICROPY_END_ATOMIC_SECTION(atomic_state);
+    }
+    mp_sched_unlock();
+}
+
+void mp_sched_lock(void) {
+    mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
+    if (MP_STATE_VM(sched_state) < 0) {
+        --MP_STATE_VM(sched_state);
+    } else {
+        MP_STATE_VM(sched_state) = MP_SCHED_LOCKED;
+    }
+    MICROPY_END_ATOMIC_SECTION(atomic_state);
+}
+
+void mp_sched_unlock(void) {
+    mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
+    if (++MP_STATE_VM(sched_state) == 0) {
+        // vm became unlocked
+        if (MP_STATE_VM(mp_pending_exception) != MP_OBJ_NULL || mp_sched_num_pending()) {
+            MP_STATE_VM(sched_state) = MP_SCHED_PENDING;
+        } else {
+            MP_STATE_VM(sched_state) = MP_SCHED_IDLE;
+        }
+    }
+    MICROPY_END_ATOMIC_SECTION(atomic_state);
+}
+
+bool mp_sched_schedule(mp_obj_t function, mp_obj_t arg) {
+    mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
+    bool ret;
+    if (MP_STATE_VM(sched_sp) < MICROPY_SCHEDULER_DEPTH) {
+        if (MP_STATE_VM(sched_state) == MP_SCHED_IDLE) {
+            MP_STATE_VM(sched_state) = MP_SCHED_PENDING;
+        }
+        MP_STATE_VM(sched_stack)[MP_STATE_VM(sched_sp)].func = function;
+        MP_STATE_VM(sched_stack)[MP_STATE_VM(sched_sp)].arg = arg;
+        ++MP_STATE_VM(sched_sp);
+        ret = true;
+    } else {
+        // schedule stack is full
+        ret = false;
+    }
+    MICROPY_END_ATOMIC_SECTION(atomic_state);
+    return ret;
+}
+
+#else // MICROPY_ENABLE_SCHEDULER
+
+// A variant of this is inlined in the VM at the pending exception check
+void mp_handle_pending(void) {
+    if (MP_STATE_VM(mp_pending_exception) != MP_OBJ_NULL) {
+        mp_obj_t obj = MP_STATE_VM(mp_pending_exception);
+        MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;
+        nlr_raise(obj);
+    }
+}
+
+#endif // MICROPY_ENABLE_SCHEDULER