summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--unix/gccollect.c8
-rw-r--r--windows/Makefile2
-rw-r--r--windows/bss.c74
-rw-r--r--windows/init.c3
-rw-r--r--windows/mpconfigport.h19
-rw-r--r--windows/msvc/common.props3
-rw-r--r--windows/msvc/sources.props2
7 files changed, 107 insertions, 4 deletions
diff --git a/unix/gccollect.c b/unix/gccollect.c
index 1014a2629b..f24cc52495 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**)&regs, ((machine_uint_t)stack_top - (machine_uint_t)&regs) / sizeof(machine_uint_t));
+ void **regs_ptr = (void**)(void*)&regs;
+ gc_collect_root(regs_ptr, ((machine_uint_t)stack_top - (machine_uint_t)&regs) / sizeof(machine_uint_t));
gc_collect_end();
//printf("-----\n");
diff --git a/windows/Makefile b/windows/Makefile
index a188979bd5..e3085ff23b 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 0000000000..b860c4ee85
--- /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 <windows.h>
+
+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 a370c464e8..57f349ef89 100644
--- a/windows/init.c
+++ b/windows/init.c
@@ -28,9 +28,12 @@
#include <stdio.h>
#include <windows.h>
+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 b9a50b0841..c930fe95e8 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 <stddef.h> //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 300de46a53..b6f22c6151 100644
--- a/windows/msvc/common.props
+++ b/windows/msvc/common.props
@@ -16,7 +16,8 @@
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
+ <GenerateMapFile>true</GenerateMapFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup />
-</Project> \ No newline at end of file
+</Project>
diff --git a/windows/msvc/sources.props b/windows/msvc/sources.props
index 8af03e7563..6fd3306b92 100644
--- a/windows/msvc/sources.props
+++ b/windows/msvc/sources.props
@@ -5,7 +5,7 @@
</PropertyGroup>
<ItemGroup>
<ClCompile Include="$(PyBaseDir)py\*.c" />
- <ClCompile Include="$(PyBaseDir)unix\*.c" Exclude="$(PyBaseDir)unix\modffi.c;$(PyBaseDir)unix\modsocket.c" />
+ <ClCompile Include="$(PyBaseDir)unix\*.c" Exclude="$(PyBaseDir)unix\modffi.c;$(PyBaseDir)unix\modsocket.c;$(PyBaseDir)unix\seg_helpers.c" />
<ClCompile Include="$(PyBaseDir)windows\*.c" />
<ClCompile Include="$(PyBaseDir)windows\msvc\*.c" />
</ItemGroup>