From cea95f2cc443a5bee5cb69476ae73fd99d32fc0d Mon Sep 17 00:00:00 2001 From: Gabriel Dos Reis Date: Sun, 15 Jan 2017 09:14:39 -0800 Subject: Add s-expression parsing to libopen-axiom-core.a --- src/utils/Makefile.am | 3 +- src/utils/Makefile.in | 25 +--- src/utils/storage.cc | 314 -------------------------------------------------- src/utils/storage.cxx | 314 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 320 insertions(+), 336 deletions(-) delete mode 100644 src/utils/storage.cc create mode 100644 src/utils/storage.cxx (limited to 'src/utils') diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am index d2f49303..a4963851 100644 --- a/src/utils/Makefile.am +++ b/src/utils/Makefile.am @@ -37,10 +37,9 @@ hammer_LDADD = \ noinst_LIBRARIES = libOpenAxiom.a libOpenAxiom_a_SOURCES = \ - storage.cc string-pool.cc command.cc \ + string-pool.cc command.cc \ filesystem.cc \ ../io/Input.cc \ - ../syntax/sexpr.cc \ ../rt/vm.cc \ ../rt/Lisp.cc \ ../rt/Database.cc diff --git a/src/utils/Makefile.in b/src/utils/Makefile.in index 2e2d184c..7c6d5798 100644 --- a/src/utils/Makefile.in +++ b/src/utils/Makefile.in @@ -145,9 +145,8 @@ am__v_AR_1 = libOpenAxiom_a_AR = $(AR) $(ARFLAGS) libOpenAxiom_a_LIBADD = am__dirstamp = $(am__leading_dot)dirstamp -am_libOpenAxiom_a_OBJECTS = storage.$(OBJEXT) string-pool.$(OBJEXT) \ - command.$(OBJEXT) filesystem.$(OBJEXT) ../io/Input.$(OBJEXT) \ - ../syntax/sexpr.$(OBJEXT) ../rt/vm.$(OBJEXT) \ +am_libOpenAxiom_a_OBJECTS = string-pool.$(OBJEXT) command.$(OBJEXT) \ + filesystem.$(OBJEXT) ../io/Input.$(OBJEXT) ../rt/vm.$(OBJEXT) \ ../rt/Lisp.$(OBJEXT) ../rt/Database.$(OBJEXT) libOpenAxiom_a_OBJECTS = $(am_libOpenAxiom_a_OBJECTS) PROGRAMS = $(noinst_PROGRAMS) @@ -420,10 +419,9 @@ hammer_LDADD = \ noinst_LIBRARIES = libOpenAxiom.a libOpenAxiom_a_SOURCES = \ - storage.cc string-pool.cc command.cc \ + string-pool.cc command.cc \ filesystem.cc \ ../io/Input.cc \ - ../syntax/sexpr.cc \ ../rt/vm.cc \ ../rt/Lisp.cc \ ../rt/Database.cc @@ -483,14 +481,6 @@ clean-noinstLIBRARIES: @: > ../io/$(DEPDIR)/$(am__dirstamp) ../io/Input.$(OBJEXT): ../io/$(am__dirstamp) \ ../io/$(DEPDIR)/$(am__dirstamp) -../syntax/$(am__dirstamp): - @$(MKDIR_P) ../syntax - @: > ../syntax/$(am__dirstamp) -../syntax/$(DEPDIR)/$(am__dirstamp): - @$(MKDIR_P) ../syntax/$(DEPDIR) - @: > ../syntax/$(DEPDIR)/$(am__dirstamp) -../syntax/sexpr.$(OBJEXT): ../syntax/$(am__dirstamp) \ - ../syntax/$(DEPDIR)/$(am__dirstamp) ../rt/$(am__dirstamp): @$(MKDIR_P) ../rt @: > ../rt/$(am__dirstamp) @@ -526,7 +516,6 @@ mostlyclean-compile: -rm -f *.$(OBJEXT) -rm -f ../io/*.$(OBJEXT) -rm -f ../rt/*.$(OBJEXT) - -rm -f ../syntax/*.$(OBJEXT) distclean-compile: -rm -f *.tab.c @@ -535,11 +524,9 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@../rt/$(DEPDIR)/Database.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../rt/$(DEPDIR)/Lisp.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@../rt/$(DEPDIR)/vm.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@../syntax/$(DEPDIR)/sexpr.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/command.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filesystem.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hammer.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/storage.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/string-pool.Po@am__quote@ .cc.o: @@ -688,8 +675,6 @@ distclean-generic: -rm -f ../io/$(am__dirstamp) -rm -f ../rt/$(DEPDIR)/$(am__dirstamp) -rm -f ../rt/$(am__dirstamp) - -rm -f ../syntax/$(DEPDIR)/$(am__dirstamp) - -rm -f ../syntax/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -700,7 +685,7 @@ clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \ clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am - -rm -rf ../io/$(DEPDIR) ../rt/$(DEPDIR) ../syntax/$(DEPDIR) ./$(DEPDIR) + -rm -rf ../io/$(DEPDIR) ../rt/$(DEPDIR) ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -746,7 +731,7 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ../io/$(DEPDIR) ../rt/$(DEPDIR) ../syntax/$(DEPDIR) ./$(DEPDIR) + -rm -rf ../io/$(DEPDIR) ../rt/$(DEPDIR) ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/src/utils/storage.cc b/src/utils/storage.cc deleted file mode 100644 index 80cfea0d..00000000 --- a/src/utils/storage.cc +++ /dev/null @@ -1,314 +0,0 @@ -// Copyright (C) 2010-2013, Gabriel Dos Reis. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// - Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// -// - Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in -// the documentation and/or other materials provided with the -// distribution. -// -// - Neither the name of The Numerical Algorithms Group Ltd. nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS -// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER -// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --%: Gabriel Dos Reis. - -#include -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#include -#ifdef HAVE_FCNTL_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif -#ifdef HAVE_SYS_MMAN_H -# include -#endif -#ifdef OPENAXIOM_MS_WINDOWS_HOST -# include -#endif -#include -#include -#include - -namespace OpenAxiom { - // ---------------- - // -- SystemError -- - // ---------------- - SystemError::SystemError(const std::string& s) : text(s) { } - - SystemError::~SystemError() { } - - const std::string& - SystemError::message() const { - return text; - } - - void - filesystem_error(const std::string& s) { - throw SystemError(s); - } - - namespace Memory { - // Return storage page allocation unit in byte count. - size_t page_size() { -#if defined(OPENAXIOM_MS_WINDOWS_HOST) - SYSTEM_INFO si = { }; - GetSystemInfo(&si); - return si.dwPageSize; -#elif defined(HAVE_UNISTD_H) - return sysconf(_SC_PAGESIZE); -#else - // Well, we have to return a number. - return 4096; -#endif - } - - // Subroutine of os_acquire_raw_memory. Attempt to acquire - // storage from the host OS. Return null on failure. - static inline Pointer - os_allocate_read_write_raw_memory(size_t nbytes) { -#if defined(OPENAXIOM_MS_WINDOWS_HOST) - return VirtualAlloc(Pointer(), nbytes, - MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); -#elif defined(HAVE_SYS_MMAN_H) - Pointer p = mmap(Pointer(), nbytes, PROT_READ | PROT_WRITE, - MAP_PRIVATE | OPENAXIOM_MM_ANONYMOUS_MAP_FLAG, - -1, 0); - return p == MAP_FAILED ? Pointer() : p; -#else - return malloc(byte_count); -#endif - } - - Pointer - os_acquire_raw_memory(size_t nbytes) { - Pointer p = os_allocate_read_write_raw_memory(nbytes); - if (p == nullptr) - throw SystemError("cannot acquire more memory"); - return memset(p, nbytes, 0); - } - - void - os_release_raw_memory(Pointer p, size_t n) { -#if defined(OPENAXIOM_MS_WINDOWS_HOST) - VirtualFree(p, 0, MEM_RELEASE); -#elif defined(HAVE_SYS_MMAN_H) - munmap(p, n); -#else - free(p); -#endif - } - - // ------------- - // -- Storage -- - // ------------- - struct Storage::Handle { - size_t extent; // count of allocated bytes - void* start; // beginning of usable address. - }; - - static inline Pointer - storage_end(Storage::Handle* h) { - return Storage::byte_address(h) + h->extent; - } - - // Acquire storage chunk of at least `n' bytes. - // The result is a pointer to a storage object. That object - // `result' is constructed such that `begin(result)' points - // to the next allocatable address. - template - static T* - acquire_storage_with_header(size_t n) { - n = Storage::round_up(n, page_size()); - T* h = static_cast(os_acquire_raw_memory(n)); - h->extent = n; - h->start = h + 1; - return h; - } - - void - Storage::release(Handle* h) { - os_release_raw_memory(h, h->extent); - } - - Pointer - Storage::begin(Handle* h) { - return h->start; - } - - // ------------------------- - // -- SinglyLinkedStorage -- - // ------------------------- - struct OneWayLinkHeader : Storage::Handle { - Handle* previous; - }; - - SinglyLinkedStorage::Handle*& - SinglyLinkedStorage::previous(Handle* h) { - return static_cast(h)->previous; - } - - // ------------------------- - // -- DoublyLinkedStorage -- - // ------------------------- - struct TwoWayLinkHeader : Storage::Handle { - Handle* previous; - Handle* next; - }; - - static inline TwoWayLinkHeader* - two_way_link(Storage::Handle* h) { - return static_cast(h); - } - - DoublyLinkedStorage::Handle*& - DoublyLinkedStorage::previous(Handle* h) { - return two_way_link(h)->previous; - } - - DoublyLinkedStorage::Handle*& - DoublyLinkedStorage::next(Handle* h) { - return two_way_link(h)->next; - } - - DoublyLinkedStorage::Handle* - DoublyLinkedStorage::acquire(size_t n, size_t a) { - // Add enough padding space for specified alignment. - const size_t overhead = round_up(sizeof (TwoWayLinkHeader), a); - TwoWayLinkHeader* h = - acquire_storage_with_header(overhead + n); - h->start = byte_address (h) + overhead; - h->previous = nullptr; - h->next = nullptr; - return h; - } - - // ------------------ - // -- BlockStorage -- - // ------------------ - struct BlockHeader : OneWayLinkHeader { - Byte* available; - }; - - static inline BlockHeader* - block_header(BlockStorage::Handle* h) { - return static_cast(h); - } - - BlockStorage::Handle* - BlockStorage::acquire(size_t n, size_t a) { - const size_t overhead = round_up(sizeof (BlockHeader), a); - BlockHeader* h = - acquire_storage_with_header(overhead + n); - // Remember the next available address to allocate from. - h->available = byte_address(h) + overhead; - // That is also where the actual object storage starts. - h->start = h->available; - h->previous = nullptr; - return h; - } - - Pointer - BlockStorage::next_address(Handle* h) { - return block_header(h)->available; - } - - size_t - BlockStorage::room(Handle* h) { - return byte_address(storage_end(h)) - block_header(h)->available; - } - - Pointer - BlockStorage::book(Handle* h, size_t n) { - BlockHeader* block = block_header(h); - void* const p = block->available; - block->available += n; - return p; - } - - - // ----------------- - // -- FileMapping -- - // ----------------- - FileMapping::FileMapping(std::string path) - : start(), extent() { -#if defined(OPENAXIOM_MS_WINDOWS_HOST) - HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, 0, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, 0); - if (file == INVALID_HANDLE_VALUE) - filesystem_error("could not access file " + path); - HANDLE mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, 0, 0); - if (mapping == 0) - filesystem_error("could not map file " + path); - start = static_cast - (MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0)); - extent = GetFileSize(file, 0); - CloseHandle(mapping); - CloseHandle(file); -#elif defined(HAVE_SYS_STAT_H) && defined(HAVE_SYS_MMAN_H) && defined(HAVE_FCNTL_H) - struct stat s; - errno = 0; - if (stat(path.c_str(), &s) < 0) - filesystem_error("could not access file " + path); - else if (!S_ISREG(s.st_mode)) - filesystem_error(path + " is not a regular file"); - int fd = open(path.c_str(), O_RDONLY); - if (fd < 0) - filesystem_error("could not open " + path); - start = static_cast - (mmap(Pointer(), s.st_size, PROT_READ, MAP_PRIVATE, fd, 0)); - close(fd); - if (start == MAP_FAILED) - filesystem_error("could not map file " + path); - extent = s.st_size; -#else -# error "Don't know how to map a file on this platform" -#endif // OPENAXIOM_MS_WINDOWS_HOST - } - - FileMapping::FileMapping(FileMapping&& f) - : start(f.start), extent(f.extent) { - f.start = nullptr; - f.extent = 0; - } - - FileMapping::~FileMapping() { - if (start != nullptr) { -#if defined(OPENAXIOM_MS_WINDOWS_HOST) - UnmapViewOfFile(start); -#elif defined(HAVE_SYS_MMAN_H) - munmap(start, extent); -#else -# error "Don't know how to unmap a file on this platform" -#endif - } - } - } -} diff --git a/src/utils/storage.cxx b/src/utils/storage.cxx new file mode 100644 index 00000000..80cfea0d --- /dev/null +++ b/src/utils/storage.cxx @@ -0,0 +1,314 @@ +// Copyright (C) 2010-2013, Gabriel Dos Reis. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// - Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// - Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in +// the documentation and/or other materials provided with the +// distribution. +// +// - Neither the name of The Numerical Algorithms Group Ltd. nor the +// names of its contributors may be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS +// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER +// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// --%: Gabriel Dos Reis. + +#include +#include +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_STAT_H +# include +#endif +#include +#ifdef HAVE_FCNTL_H +# include +#endif +#ifdef HAVE_UNISTD_H +# include +#endif +#ifdef HAVE_SYS_MMAN_H +# include +#endif +#ifdef OPENAXIOM_MS_WINDOWS_HOST +# include +#endif +#include +#include +#include + +namespace OpenAxiom { + // ---------------- + // -- SystemError -- + // ---------------- + SystemError::SystemError(const std::string& s) : text(s) { } + + SystemError::~SystemError() { } + + const std::string& + SystemError::message() const { + return text; + } + + void + filesystem_error(const std::string& s) { + throw SystemError(s); + } + + namespace Memory { + // Return storage page allocation unit in byte count. + size_t page_size() { +#if defined(OPENAXIOM_MS_WINDOWS_HOST) + SYSTEM_INFO si = { }; + GetSystemInfo(&si); + return si.dwPageSize; +#elif defined(HAVE_UNISTD_H) + return sysconf(_SC_PAGESIZE); +#else + // Well, we have to return a number. + return 4096; +#endif + } + + // Subroutine of os_acquire_raw_memory. Attempt to acquire + // storage from the host OS. Return null on failure. + static inline Pointer + os_allocate_read_write_raw_memory(size_t nbytes) { +#if defined(OPENAXIOM_MS_WINDOWS_HOST) + return VirtualAlloc(Pointer(), nbytes, + MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); +#elif defined(HAVE_SYS_MMAN_H) + Pointer p = mmap(Pointer(), nbytes, PROT_READ | PROT_WRITE, + MAP_PRIVATE | OPENAXIOM_MM_ANONYMOUS_MAP_FLAG, + -1, 0); + return p == MAP_FAILED ? Pointer() : p; +#else + return malloc(byte_count); +#endif + } + + Pointer + os_acquire_raw_memory(size_t nbytes) { + Pointer p = os_allocate_read_write_raw_memory(nbytes); + if (p == nullptr) + throw SystemError("cannot acquire more memory"); + return memset(p, nbytes, 0); + } + + void + os_release_raw_memory(Pointer p, size_t n) { +#if defined(OPENAXIOM_MS_WINDOWS_HOST) + VirtualFree(p, 0, MEM_RELEASE); +#elif defined(HAVE_SYS_MMAN_H) + munmap(p, n); +#else + free(p); +#endif + } + + // ------------- + // -- Storage -- + // ------------- + struct Storage::Handle { + size_t extent; // count of allocated bytes + void* start; // beginning of usable address. + }; + + static inline Pointer + storage_end(Storage::Handle* h) { + return Storage::byte_address(h) + h->extent; + } + + // Acquire storage chunk of at least `n' bytes. + // The result is a pointer to a storage object. That object + // `result' is constructed such that `begin(result)' points + // to the next allocatable address. + template + static T* + acquire_storage_with_header(size_t n) { + n = Storage::round_up(n, page_size()); + T* h = static_cast(os_acquire_raw_memory(n)); + h->extent = n; + h->start = h + 1; + return h; + } + + void + Storage::release(Handle* h) { + os_release_raw_memory(h, h->extent); + } + + Pointer + Storage::begin(Handle* h) { + return h->start; + } + + // ------------------------- + // -- SinglyLinkedStorage -- + // ------------------------- + struct OneWayLinkHeader : Storage::Handle { + Handle* previous; + }; + + SinglyLinkedStorage::Handle*& + SinglyLinkedStorage::previous(Handle* h) { + return static_cast(h)->previous; + } + + // ------------------------- + // -- DoublyLinkedStorage -- + // ------------------------- + struct TwoWayLinkHeader : Storage::Handle { + Handle* previous; + Handle* next; + }; + + static inline TwoWayLinkHeader* + two_way_link(Storage::Handle* h) { + return static_cast(h); + } + + DoublyLinkedStorage::Handle*& + DoublyLinkedStorage::previous(Handle* h) { + return two_way_link(h)->previous; + } + + DoublyLinkedStorage::Handle*& + DoublyLinkedStorage::next(Handle* h) { + return two_way_link(h)->next; + } + + DoublyLinkedStorage::Handle* + DoublyLinkedStorage::acquire(size_t n, size_t a) { + // Add enough padding space for specified alignment. + const size_t overhead = round_up(sizeof (TwoWayLinkHeader), a); + TwoWayLinkHeader* h = + acquire_storage_with_header(overhead + n); + h->start = byte_address (h) + overhead; + h->previous = nullptr; + h->next = nullptr; + return h; + } + + // ------------------ + // -- BlockStorage -- + // ------------------ + struct BlockHeader : OneWayLinkHeader { + Byte* available; + }; + + static inline BlockHeader* + block_header(BlockStorage::Handle* h) { + return static_cast(h); + } + + BlockStorage::Handle* + BlockStorage::acquire(size_t n, size_t a) { + const size_t overhead = round_up(sizeof (BlockHeader), a); + BlockHeader* h = + acquire_storage_with_header(overhead + n); + // Remember the next available address to allocate from. + h->available = byte_address(h) + overhead; + // That is also where the actual object storage starts. + h->start = h->available; + h->previous = nullptr; + return h; + } + + Pointer + BlockStorage::next_address(Handle* h) { + return block_header(h)->available; + } + + size_t + BlockStorage::room(Handle* h) { + return byte_address(storage_end(h)) - block_header(h)->available; + } + + Pointer + BlockStorage::book(Handle* h, size_t n) { + BlockHeader* block = block_header(h); + void* const p = block->available; + block->available += n; + return p; + } + + + // ----------------- + // -- FileMapping -- + // ----------------- + FileMapping::FileMapping(std::string path) + : start(), extent() { +#if defined(OPENAXIOM_MS_WINDOWS_HOST) + HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, 0, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, 0); + if (file == INVALID_HANDLE_VALUE) + filesystem_error("could not access file " + path); + HANDLE mapping = CreateFileMapping(file, 0, PAGE_READONLY, 0, 0, 0); + if (mapping == 0) + filesystem_error("could not map file " + path); + start = static_cast + (MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0)); + extent = GetFileSize(file, 0); + CloseHandle(mapping); + CloseHandle(file); +#elif defined(HAVE_SYS_STAT_H) && defined(HAVE_SYS_MMAN_H) && defined(HAVE_FCNTL_H) + struct stat s; + errno = 0; + if (stat(path.c_str(), &s) < 0) + filesystem_error("could not access file " + path); + else if (!S_ISREG(s.st_mode)) + filesystem_error(path + " is not a regular file"); + int fd = open(path.c_str(), O_RDONLY); + if (fd < 0) + filesystem_error("could not open " + path); + start = static_cast + (mmap(Pointer(), s.st_size, PROT_READ, MAP_PRIVATE, fd, 0)); + close(fd); + if (start == MAP_FAILED) + filesystem_error("could not map file " + path); + extent = s.st_size; +#else +# error "Don't know how to map a file on this platform" +#endif // OPENAXIOM_MS_WINDOWS_HOST + } + + FileMapping::FileMapping(FileMapping&& f) + : start(f.start), extent(f.extent) { + f.start = nullptr; + f.extent = 0; + } + + FileMapping::~FileMapping() { + if (start != nullptr) { +#if defined(OPENAXIOM_MS_WINDOWS_HOST) + UnmapViewOfFile(start); +#elif defined(HAVE_SYS_MMAN_H) + munmap(start, extent); +#else +# error "Don't know how to unmap a file on this platform" +#endif + } + } + } +} -- cgit v1.2.3