From 7e3954b815b5ba05e7db7a82db641ea34b69ee27 Mon Sep 17 00:00:00 2001 From: Andreas Holzammer Date: Thu, 28 Feb 2013 22:18:40 +0100 Subject: [V8] Port to Windows Embedded Compact 7 Reviewed-by: Lars Knoll Change-Id: I75a29824920af7a6aa35d38a1a5a5826145a21d1 Reviewed-by: Lars Knoll --- src/3rdparty/v8/src/arm/constants-arm.h | 10 +- src/3rdparty/v8/src/arm/cpu-arm.cc | 7 +- src/3rdparty/v8/src/atomicops.h | 2 +- src/3rdparty/v8/src/atomicops_internals_x86_msvc.h | 6 ++ src/3rdparty/v8/src/globals.h | 4 +- src/3rdparty/v8/src/misc-intrinsics.h | 2 +- src/3rdparty/v8/src/platform-tls-win32.h | 2 +- src/3rdparty/v8/src/platform-win32.cc | 114 +++++++++++++++++++-- src/3rdparty/v8/src/unicode.h | 2 + src/3rdparty/v8/src/v8utils.cc | 6 ++ src/3rdparty/v8/src/win32-headers.h | 23 ++++- 11 files changed, 154 insertions(+), 24 deletions(-) diff --git a/src/3rdparty/v8/src/arm/constants-arm.h b/src/3rdparty/v8/src/arm/constants-arm.h index 004165a..841df92 100644 --- a/src/3rdparty/v8/src/arm/constants-arm.h +++ b/src/3rdparty/v8/src/arm/constants-arm.h @@ -29,14 +29,14 @@ #define V8_ARM_CONSTANTS_ARM_H_ // ARM EABI is required. -#if defined(__arm__) && !defined(__ARM_EABI__) +#if defined(__arm__) && !defined(__ARM_EABI__) && !defined(_WIN32_WCE) #error ARM EABI support is required. #endif // This means that interwork-compatible jump instructions are generated. We // want to generate them on the simulator too so it makes snapshots that can // be used on real hardware. -#if defined(__THUMB_INTERWORK__) || !defined(__arm__) +#if defined(__THUMB_INTERWORK__) || !defined(__arm__) || defined(_WIN32_WCE) # define USE_THUMB_INTERWORK 1 #endif @@ -65,8 +65,10 @@ #endif // Simulator should support ARM5 instructions and unaligned access by default. -#if !defined(__arm__) -# define CAN_USE_ARMV5_INSTRUCTIONS 1 +#if !defined(__arm__) || defined(_WIN32_WCE) +# if !defined(_WIN32_WCE) +# define CAN_USE_ARMV5_INSTRUCTIONS 1 +# endif # define CAN_USE_THUMB_INSTRUCTIONS 1 # ifndef CAN_USE_UNALIGNED_ACCESSES diff --git a/src/3rdparty/v8/src/arm/cpu-arm.cc b/src/3rdparty/v8/src/arm/cpu-arm.cc index f7da6c3..bed9503 100644 --- a/src/3rdparty/v8/src/arm/cpu-arm.cc +++ b/src/3rdparty/v8/src/arm/cpu-arm.cc @@ -29,7 +29,7 @@ #include "v8.h" -#if defined(__arm__) +#if defined(__arm__) && !defined(_WIN32_WCE) #if !defined(__QNXNTO__) #include // for cache flushing. #else @@ -73,6 +73,11 @@ void CPU::FlushICache(void* start, size_t size) { // The QNX kernel does not expose the symbol __ARM_NR_cacheflush so we // use the msync system call instead of the approach used on Linux msync(start, size, MS_SYNC|MS_INVALIDATE_ICACHE); +#elif defined(_WIN32_WCE) + // Windows CE compiler does not support the asm command, nor does it expose + // __ARM_NR_cacheflush. As well as Windows CE does not support to flush a + // region, so we need to flush the whole process. + FlushInstructionCache(GetCurrentProcess(), NULL, NULL); #else // Ideally, we would call // syscall(__ARM_NR_cacheflush, start, diff --git a/src/3rdparty/v8/src/atomicops.h b/src/3rdparty/v8/src/atomicops.h index 5e5323a..d4fe042 100644 --- a/src/3rdparty/v8/src/atomicops.h +++ b/src/3rdparty/v8/src/atomicops.h @@ -154,7 +154,7 @@ Atomic64 Release_Load(volatile const Atomic64* ptr); #if defined(THREAD_SANITIZER) #include "atomicops_internals_tsan.h" #elif defined(_MSC_VER) && \ - (defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_X64)) + (defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_X64) || defined(_WIN32_WCE)) #include "atomicops_internals_x86_msvc.h" #elif defined(__APPLE__) && \ (defined(V8_HOST_ARCH_IA32) || defined(V8_HOST_ARCH_X64)) diff --git a/src/3rdparty/v8/src/atomicops_internals_x86_msvc.h b/src/3rdparty/v8/src/atomicops_internals_x86_msvc.h index fcf6a65..6677e64 100644 --- a/src/3rdparty/v8/src/atomicops_internals_x86_msvc.h +++ b/src/3rdparty/v8/src/atomicops_internals_x86_msvc.h @@ -69,10 +69,16 @@ inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr, #if !(defined(_MSC_VER) && _MSC_VER >= 1400) #error "We require at least vs2005 for MemoryBarrier" #endif +// For Windows CE there is no MemoryBarrier needed +#ifdef _WIN32_WCE +inline void MemoryBarrier() { +} +#else inline void MemoryBarrier() { // We use MemoryBarrier from WinNT.h ::MemoryBarrier(); } +#endif inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr, Atomic32 old_value, diff --git a/src/3rdparty/v8/src/globals.h b/src/3rdparty/v8/src/globals.h index d869af6..7205361 100644 --- a/src/3rdparty/v8/src/globals.h +++ b/src/3rdparty/v8/src/globals.h @@ -74,7 +74,7 @@ namespace internal { #define V8_HOST_ARCH_IA32 1 #define V8_HOST_ARCH_32_BIT 1 #define V8_HOST_CAN_READ_UNALIGNED 1 -#elif defined(__ARMEL__) +#elif defined(__ARMEL__) || defined(_M_ARM) #define V8_HOST_ARCH_ARM 1 #define V8_HOST_ARCH_32_BIT 1 // Some CPU-OS combinations allow unaligned access on ARM. We assume @@ -128,7 +128,7 @@ namespace internal { // Setting USE_SIMULATOR explicitly from the build script will force // the use of a simulated environment. #if !defined(USE_SIMULATOR) -#if (defined(V8_TARGET_ARCH_ARM) && !defined(V8_HOST_ARCH_ARM)) +#if (defined(V8_TARGET_ARCH_ARM) && !defined(V8_HOST_ARCH_ARM) && !defined(_WIN32_WCE)) #define USE_SIMULATOR 1 #endif #if (defined(V8_TARGET_ARCH_MIPS) && !defined(V8_HOST_ARCH_MIPS)) diff --git a/src/3rdparty/v8/src/misc-intrinsics.h b/src/3rdparty/v8/src/misc-intrinsics.h index 5393de2..c1da8a9 100644 --- a/src/3rdparty/v8/src/misc-intrinsics.h +++ b/src/3rdparty/v8/src/misc-intrinsics.h @@ -45,7 +45,7 @@ inline int IntegerLog2(uint32_t value) { return 31 - __builtin_clz(value); } -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) && !defined(_WIN32_WCE) #pragma intrinsic(_BitScanReverse) diff --git a/src/3rdparty/v8/src/platform-tls-win32.h b/src/3rdparty/v8/src/platform-tls-win32.h index 4056e8c..a981d18 100644 --- a/src/3rdparty/v8/src/platform-tls-win32.h +++ b/src/3rdparty/v8/src/platform-tls-win32.h @@ -35,7 +35,7 @@ namespace v8 { namespace internal { -#if defined(_WIN32) && !defined(_WIN64) +#if defined(_WIN32) && !defined(_WIN64) && !defined(_WIN32_WCE) #define V8_FAST_TLS_SUPPORTED 1 diff --git a/src/3rdparty/v8/src/platform-win32.cc b/src/3rdparty/v8/src/platform-win32.cc index b91f2a6..1022e50 100644 --- a/src/3rdparty/v8/src/platform-win32.cc +++ b/src/3rdparty/v8/src/platform-win32.cc @@ -58,6 +58,20 @@ int strncasecmp(const char* s1, const char* s2, int n) { #endif // _MSC_VER +#ifdef _WIN32_WCE +// Convert a Latin1 string into a utf16 string +wchar_t* wce_mbtowc(const char* a) { + int length = strlen(a); + wchar_t *wbuf = new wchar_t[length]; + + for (int i = 0; i < length; ++i) + wbuf[i] = (wchar_t)a[i]; + + return wbuf; +} +#endif // _WIN32_WCE + + // Extra functions for MinGW. Most of these are the _s functions which are in // the Microsoft Visual Studio C++ CRT. #ifdef __MINGW32__ @@ -162,6 +176,13 @@ void OS::MemCopy(void* dest, const void* src, size_t size) { } #endif // V8_TARGET_ARCH_IA32 +#ifdef _WIN32_WCE +// TODO: Implement +CpuImplementer OS::GetCpuImplementer() { + return UNKNOWN_IMPLEMENTER; +} +#endif // _WIN32_WCE + #ifdef _WIN64 typedef double (*ModuloFunction)(double, double); static ModuloFunction modulo_function = NULL; @@ -386,7 +407,9 @@ void Time::TzSet() { if (tz_initialized_) return; // Initialize POSIX time zone data. +#ifndef _WIN32_WCE _tzset(); +#endif // _WIN32_WCE // Obtain timezone information from operating system. memset(&tzinfo_, 0, sizeof(tzinfo_)); if (GetTimeZoneInformation(&tzinfo_) == TIME_ZONE_ID_INVALID) { @@ -498,6 +521,7 @@ void Time::SetToCurrentTime() { // Also, adding the time-zone offset to the input must not overflow. // The function EquivalentTime() in date.js guarantees this. int64_t Time::LocalOffset() { +#ifndef _WIN32_WCE // Initialize timezone information, if needed. TzSet(); @@ -528,6 +552,11 @@ int64_t Time::LocalOffset() { } else { return tzinfo_.Bias * -kMsPerMinute; } +#else + // Windows CE has a different handling of Timezones. + // TODO: Adapt this for Windows CE + return 0; +#endif } @@ -579,6 +608,14 @@ void OS::PostSetUp() { #endif } +#ifdef V8_TARGET_ARCH_ARM +// TODO: Implement +// Windows CE is the only platform right now that supports ARM. +bool OS::ArmCpuHasFeature(CpuFeature feature) { + return false; +} +#endif // V8_TARGET_ARCH_ARM + // Returns the accumulated user time for thread. int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) { @@ -673,6 +710,7 @@ static OutputMode output_mode = UNKNOWN; // Current output mode. static bool HasConsole() { // Only check the first time. Eventual race conditions are not a problem, // because all threads will eventually determine the same mode. +#ifndef _WIN32_WCE if (output_mode == UNKNOWN) { // We cannot just check that the standard output is attached to a console // because this would fail if output is redirected to a file. Therefore we @@ -685,6 +723,10 @@ static bool HasConsole() { output_mode = ODS; } return output_mode == CONSOLE; +#else + // Windows CE has no shell enabled in the standard BSP + return false; +#endif // _WIN32_WCE } @@ -697,7 +739,14 @@ static void VPrintHelper(FILE* stream, const char* format, va_list args) { // does not crash. EmbeddedVector buffer; OS::VSNPrintF(buffer, format, args); +#ifdef _WIN32_WCE + wchar_t wbuf[4096]; + for (int i = 0; i < 4096; ++i) + wbuf[i] = (wchar_t)buffer.start()[i]; + OutputDebugStringW(wbuf); +#else OutputDebugStringA(buffer.start()); +#endif // _WIN32_WCE } } @@ -713,23 +762,30 @@ FILE* OS::FOpen(const char* path, const char* mode) { bool OS::Remove(const char* path) { +#ifndef _WIN32_WCE return (DeleteFileA(path) != 0); +#else + wchar_t *wpath = wce_mbtowc(path); + bool ret = (DeleteFileW(wpath) != 0); + delete wpath; + return ret; +#endif // _WIN32_WCE } FILE* OS::OpenTemporaryFile() { // tmpfile_s tries to use the root dir, don't use it. - char tempPathBuffer[MAX_PATH]; + wchar_t tempPathBuffer[MAX_PATH]; DWORD path_result = 0; - path_result = GetTempPathA(MAX_PATH, tempPathBuffer); + path_result = GetTempPathW(MAX_PATH, tempPathBuffer); if (path_result > MAX_PATH || path_result == 0) return NULL; UINT name_result = 0; - char tempNameBuffer[MAX_PATH]; - name_result = GetTempFileNameA(tempPathBuffer, "", 0, tempNameBuffer); + wchar_t tempNameBuffer[MAX_PATH]; + name_result = GetTempFileNameW(tempPathBuffer, L"", 0, tempNameBuffer); if (name_result == 0) return NULL; - FILE* result = FOpen(tempNameBuffer, "w+"); // Same mode as tmpfile uses. + FILE* result = _wfopen(tempNameBuffer, L"w+"); // Same mode as tmpfile uses. if (result != NULL) { - Remove(tempNameBuffer); // Delete on close. + DeleteFileW(tempNameBuffer); // Delete on close. } return result; } @@ -990,7 +1046,11 @@ void OS::Abort() { DebugBreak(); } else { // Make the MSVCRT do a silent abort. +#ifndef _WIN32_WCE raise(SIGABRT); +#else + exit(3); +#endif // _WIN32_WCE } } @@ -1032,8 +1092,15 @@ class Win32MemoryMappedFile : public OS::MemoryMappedFile { OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { // Open a physical file +#ifndef _WIN32_WCE HANDLE file = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); +#else + wchar_t *wname = wce_mbtowc(name); + HANDLE file = CreateFileW(wname, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + delete wname; +#endif // _WIN32_WCE if (file == INVALID_HANDLE_VALUE) return NULL; int size = static_cast(GetFileSize(file, NULL)); @@ -1052,8 +1119,15 @@ OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) { OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size, void* initial) { // Open a physical file +#ifndef _WIN32_WCE HANDLE file = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL); +#else + wchar_t *wname = wce_mbtowc(name); + HANDLE file = CreateFileW(wname, GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, 0, NULL); + delete wname; +#endif // _WIN32_WCE if (file == NULL) return NULL; // Create a file mapping for the physical file HANDLE file_mapping = CreateFileMapping(file, NULL, @@ -1115,8 +1189,8 @@ Win32MemoryMappedFile::~Win32MemoryMappedFile() { #define VOID void #endif -// DbgHelp isn't supported on MinGW yet -#ifndef __MINGW32__ +// DbgHelp isn't supported on MinGW yet, nor does Windows CE have it +#if !defined(__MINGW32__) && !defined(_WIN32_WCE) // DbgHelp.h functions. typedef BOOL (__stdcall *DLL_FUNC_TYPE(SymInitialize))(IN HANDLE hProcess, IN PSTR UserSearchPath, @@ -1645,6 +1719,7 @@ Thread::~Thread() { // the Win32 function CreateThread(), because the CreateThread() does not // initialize thread specific structures in the C runtime library. void Thread::Start() { +#ifndef _WIN32_WCE data_->thread_ = reinterpret_cast( _beginthreadex(NULL, static_cast(stack_size_), @@ -1652,6 +1727,18 @@ void Thread::Start() { this, 0, &data_->thread_id_)); +#else + unsigned initflag = 0; + if (stack_size_ > 0) + initflag |= STACK_SIZE_PARAM_IS_A_RESERVATION; + data_->thread_ = reinterpret_cast( + CreateThread( NULL, + static_cast(stack_size_), + (LPTHREAD_START_ROUTINE)ThreadEntry, + this, + initflag, + (LPDWORD)&data_->thread_id_)); +#endif // _WIN32_WCE } @@ -1746,7 +1833,7 @@ Mutex* OS::CreateMutex() { class Win32Semaphore : public Semaphore { public: explicit Win32Semaphore(int count) { - sem = ::CreateSemaphoreA(NULL, count, 0x7fffffff, NULL); + sem = ::CreateSemaphoreW(NULL, count, 0x7fffffff, NULL); } ~Win32Semaphore() { @@ -2078,10 +2165,17 @@ class SamplerThread : public Thread { sample->pc = reinterpret_cast
(context.Rip); sample->sp = reinterpret_cast
(context.Rsp); sample->fp = reinterpret_cast
(context.Rbp); -#else +#elif V8_HOST_ARCH_IA32 sample->pc = reinterpret_cast
(context.Eip); sample->sp = reinterpret_cast
(context.Esp); sample->fp = reinterpret_cast
(context.Ebp); +#elif V8_HOST_ARCH_ARM + // Taken from http://msdn.microsoft.com/en-us/library/aa448762.aspx + sample->pc = reinterpret_cast
(context.Pc); + sample->sp = reinterpret_cast
(context.Sp); + sample->fp = reinterpret_cast
(context.R11); +#else +#error This Platform is not supported. #endif sampler->SampleStack(sample); sampler->Tick(sample); diff --git a/src/3rdparty/v8/src/unicode.h b/src/3rdparty/v8/src/unicode.h index f8a1f60..550b04a 100644 --- a/src/3rdparty/v8/src/unicode.h +++ b/src/3rdparty/v8/src/unicode.h @@ -28,7 +28,9 @@ #ifndef V8_UNICODE_H_ #define V8_UNICODE_H_ +#ifndef _WIN32_WCE #include +#endif #include /** * \file diff --git a/src/3rdparty/v8/src/v8utils.cc b/src/3rdparty/v8/src/v8utils.cc index d2b28bd..2dfc1ea 100644 --- a/src/3rdparty/v8/src/v8utils.cc +++ b/src/3rdparty/v8/src/v8utils.cc @@ -31,7 +31,9 @@ #include "platform.h" +#ifndef _WIN32_WCE #include "sys/stat.h" +#endif namespace v8 { namespace internal { @@ -133,7 +135,11 @@ char* ReadCharsFromFile(FILE* file, // Get the size of the file and rewind it. *size = ftell(file); +#ifdef _WIN32_WCE + fseek(file, 0, SEEK_SET); +#else rewind(file); +#endif // _WIN32_WCE char* result = NewArray(*size + extra_space); for (int i = 0; i < *size && feof(file) == 0;) { diff --git a/src/3rdparty/v8/src/win32-headers.h b/src/3rdparty/v8/src/win32-headers.h index 62f0063..b476efe 100644 --- a/src/3rdparty/v8/src/win32-headers.h +++ b/src/3rdparty/v8/src/win32-headers.h @@ -56,7 +56,9 @@ #include #ifdef V8_WIN32_HEADERS_FULL +#ifndef _WIN32_WCE #include // For raise(). +#endif // _WIN32_WCE #include // For LocalOffset() implementation. #include // For timeGetTime(). #ifdef __MINGW32__ @@ -65,10 +67,10 @@ #undef _WIN32_WINNT #define _WIN32_WINNT 0x501 #endif // __MINGW32__ -#if !defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR) +#if (!defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR)) && !defined(_WIN32_WCE) #include // For SymLoadModule64 and al. #include // For STRUNCATE -#endif // !defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR) +#endif // !defined(__MINGW32__) || defined(__MINGW64_VERSION_MAJOR) && !defined(_WIN32_WCE) #include // For INT_MAX and al. #include // For Module32First and al. @@ -76,13 +78,26 @@ // makes it impossible to have them elsewhere. #include #include -#ifndef __MINGW32__ +#if !defined(__MINGW32__) && !defined(_WIN32_WCE) #include -#endif // __MINGW32__ +#endif // __MINGW32__ && !defined(_WIN32_WCE) +#ifndef _WIN32_WCE #include // For _beginthreadex(). +#endif #include #endif // V8_WIN32_HEADERS_FULL +#ifdef _WIN32_WCE +#ifdef DebugBreak +#undef DebugBreak +inline void DebugBreak() { __debugbreak(); }; +#endif // DebugBreak + +#ifndef _IOFBF +#define _IOFBF 0x0000 +#endif +#endif + #undef VOID #undef DELETE #undef IN -- cgit v1.2.1