From 6bb0b400835e3844aec6d696478aac73f5cbce33 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9rgio=20Martins?= <sergio.martins@kdab.com>
Date: Thu, 29 Aug 2013 15:21:40 +0100
Subject: [PATCH] wince: Build fix, NtCurrentTeb() is not available in this
 platform.

This was copied from qtscript's:
src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp

Change-Id: Iaa5549e6915aa4aa4bf532fbe7c9117a0858ff02
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
---
 src/qml/jsruntime/qv4mm.cpp | 65 +++++++++++++++++++++++++++++++++++++
 1 file changed, 65 insertions(+)

diff --git a/src/qml/jsruntime/qv4mm.cpp b/src/qml/jsruntime/qv4mm.cpp
index 0233af29b9..b7a206abdf 100644
--- a/src/qml/jsruntime/qv4mm.cpp
+++ b/src/qml/jsruntime/qv4mm.cpp
@@ -74,6 +74,63 @@ using namespace WTF;
 
 static const std::size_t CHUNK_SIZE = 1024*32;
 
+#if OS(WINCE)
+void* g_stackBase = 0;
+
+inline bool isPageWritable(void* page)
+{
+    MEMORY_BASIC_INFORMATION memoryInformation;
+    DWORD result = VirtualQuery(page, &memoryInformation, sizeof(memoryInformation));
+
+    // return false on error, including ptr outside memory
+    if (result != sizeof(memoryInformation))
+        return false;
+
+    DWORD protect = memoryInformation.Protect & ~(PAGE_GUARD | PAGE_NOCACHE);
+    return protect == PAGE_READWRITE
+        || protect == PAGE_WRITECOPY
+        || protect == PAGE_EXECUTE_READWRITE
+        || protect == PAGE_EXECUTE_WRITECOPY;
+}
+
+static void* getStackBase(void* previousFrame)
+{
+    // find the address of this stack frame by taking the address of a local variable
+    bool isGrowingDownward;
+    void* thisFrame = (void*)(&isGrowingDownward);
+
+    isGrowingDownward = previousFrame < &thisFrame;
+    static DWORD pageSize = 0;
+    if (!pageSize) {
+        SYSTEM_INFO systemInfo;
+        GetSystemInfo(&systemInfo);
+        pageSize = systemInfo.dwPageSize;
+    }
+
+    // scan all of memory starting from this frame, and return the last writeable page found
+    register char* currentPage = (char*)((DWORD)thisFrame & ~(pageSize - 1));
+    if (isGrowingDownward) {
+        while (currentPage > 0) {
+            // check for underflow
+            if (currentPage >= (char*)pageSize)
+                currentPage -= pageSize;
+            else
+                currentPage = 0;
+            if (!isPageWritable(currentPage))
+                return currentPage + pageSize;
+        }
+        return 0;
+    } else {
+        while (true) {
+            // guaranteed to complete because isPageWritable returns false at end of memory
+            currentPage += pageSize;
+            if (!isPageWritable(currentPage))
+                return currentPage;
+        }
+    }
+}
+#endif
+
 struct MemoryManager::Data
 {
     bool enableGC;
@@ -172,6 +229,14 @@ MemoryManager::MemoryManager()
 
     m_d->stackTop = static_cast<quintptr *>(stackBottom) + stackSize/sizeof(quintptr);
 #  endif
+#elif OS(WINCE)
+    if (false && g_stackBase) {
+        // This code path is disabled as we have no way of initializing it yet
+        m_d->stackTop = static_cast<quintptr *>(g_stackBase);
+    } else {
+        int dummy;
+        m_d->stackTop = static_cast<quintptr *>(getStackBase(&dummy));
+    }
 #elif OS(WINDOWS)
     PNT_TIB tib = (PNT_TIB)NtCurrentTeb();
     m_d->stackTop = static_cast<quintptr*>(tib->StackBase);
-- 
GitLab