diff --git a/unix/gccollect.c b/unix/gccollect.c index 1014a2629..f24cc5249 100644 --- a/unix/gccollect.c +++ b/unix/gccollect.c @@ -130,8 +130,11 @@ void gc_collect(void) { gc_collect_start(); // this traces the .bss section -#ifdef __CYGWIN__ +#if defined( __CYGWIN__ ) #define BSS_START __bss_start__ +#elif defined( _MSC_VER ) || defined( __MINGW32__ ) +#define BSS_START *bss_start +#define _end *bss_end #else #define BSS_START __bss_start #endif @@ -141,7 +144,8 @@ void gc_collect(void) { regs_t regs; gc_helper_get_regs(regs); // GC stack (and regs because we captured them) - gc_collect_root((void**)®s, ((machine_uint_t)stack_top - (machine_uint_t)®s) / sizeof(machine_uint_t)); + void **regs_ptr = (void**)(void*)®s; + gc_collect_root(regs_ptr, ((machine_uint_t)stack_top - (machine_uint_t)®s) / sizeof(machine_uint_t)); gc_collect_end(); //printf("-----\n"); diff --git a/windows/Makefile b/windows/Makefile index a188979bd..e3085ff23 100644 --- a/windows/Makefile +++ b/windows/Makefile @@ -35,9 +35,11 @@ SRC_C = \ unix/file.c \ unix/input.c \ unix/modtime.c \ + unix/gccollect.c \ realpath.c \ init.c \ sleep.c \ + bss.c \ OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) diff --git a/windows/bss.c b/windows/bss.c new file mode 100644 index 000000000..b860c4ee8 --- /dev/null +++ b/windows/bss.c @@ -0,0 +1,74 @@ +/* +* 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. +*/ + +#include "mpconfig.h" +#include "misc.h" +#include "nlr.h" +#include "qstr.h" +#include "obj.h" +#include + +IMAGE_NT_HEADERS *header_from_memory(const char *module) { + BYTE *base_addr = (BYTE*)GetModuleHandleA(module); + IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER*)base_addr; + return (IMAGE_NT_HEADERS*)(base_addr + dos_header->e_lfanew); +} + +IMAGE_SECTION_HEADER *find_section(IMAGE_NT_HEADERS *nt_header, const char *name) { + int i; + IMAGE_SECTION_HEADER *section = IMAGE_FIRST_SECTION(nt_header); + for (i = 0; i < nt_header->FileHeader.NumberOfSections; ++i) { + if (strcmp((const char *)section->Name, name) == 0) { + return section; + } + ++section; + } + return NULL; +} + +void section_boundaries(IMAGE_NT_HEADERS *nt_header, IMAGE_SECTION_HEADER *section, char **start, char **end) { + if (section == NULL) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Could not lookup section boundaries")); + } + *start = (char*)(nt_header->OptionalHeader.ImageBase + section->VirtualAddress); + *end = *start + section->Misc.VirtualSize; +} + +void section_boundaries_from_module(const char *module, const char *section, char **start, char **end) { + IMAGE_NT_HEADERS *nt_header = header_from_memory(module); + IMAGE_SECTION_HEADER *dsection = find_section(nt_header, section); + section_boundaries(nt_header, dsection, start, end); +} + +char *bss_start = 0; +char *bss_end = 0; + +//MSVC has no __bss_start and _end but we can get accurate section info from the PE header. +//The standard .bss section is appended to the standard .data section however so it cannot +//be looked up by name. To deal with that we put all uPy static variables in a named section. +void getbss() { + section_boundaries_from_module(NULL, MICROPY_PORT_BSSSECTION, &bss_start, &bss_end); +} diff --git a/windows/init.c b/windows/init.c index a370c464e..57f349ef8 100644 --- a/windows/init.c +++ b/windows/init.c @@ -28,9 +28,12 @@ #include #include +extern void getbss(); + HANDLE hSleepEvent = NULL; void init() { + getbss(); hSleepEvent = CreateEvent(NULL, TRUE, FALSE, FALSE); #ifdef __MINGW32__ putenv("PRINTF_EXPONENT_DIGITS=2"); diff --git a/windows/mpconfigport.h b/windows/mpconfigport.h index b9a50b084..c930fe95e 100644 --- a/windows/mpconfigport.h +++ b/windows/mpconfigport.h @@ -43,6 +43,12 @@ #define MICROPY_PY_CMATH (1) #define MICROPY_PY_SYS_STDFILES (1) #define MICROPY_PY_SYS_EXIT (1) +#define MICROPY_ENABLE_GC (1) +#define MICROPY_ENABLE_FINALISER (1) +#define MICROPY_PY_GC_COLLECT_RETVAL (1) +#ifdef _MSC_VER +#define MICROPY_GCREGS_SETJMP (1) +#endif #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_DOUBLE) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ) #define MICROPY_PORT_INIT_FUNC init() @@ -113,6 +119,14 @@ void msec_sleep(double msec); #define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +// Put static/global variables in sections with a known name we can lookup for the GC +// For this to work this header must be included by all sources, which is the case normally +#define MICROPY_PORT_DATASECTION "upydata" +#define MICROPY_PORT_BSSSECTION "upybss" +#pragma data_seg(MICROPY_PORT_DATASECTION) +#pragma bss_seg(MICROPY_PORT_BSSSECTION) + + // System headers (needed e.g. for nlr.h) #include //for NULL @@ -122,3 +136,8 @@ void msec_sleep(double msec); int snprintf(char *dest, size_t count, const char *format, ...); #endif + +// MingW specifics +#ifdef __MINGW32__ +#define MICROPY_PORT_BSSSECTION ".bss" +#endif diff --git a/windows/msvc/common.props b/windows/msvc/common.props index 300de46a5..b6f22c615 100644 --- a/windows/msvc/common.props +++ b/windows/msvc/common.props @@ -16,7 +16,8 @@ true + true - \ No newline at end of file + diff --git a/windows/msvc/sources.props b/windows/msvc/sources.props index 8af03e756..6fd3306b9 100644 --- a/windows/msvc/sources.props +++ b/windows/msvc/sources.props @@ -5,7 +5,7 @@ - +