qt5_qml.patch

From: Christian Prochaska <christian.prochaska@genode-labs.com>


---
 qtdeclarative/src/qml/qml/qqmlimport.cpp           |    9 
 qtdeclarative/src/qml/qml/v8/qv8qobjectwrapper.cpp |    4 
 qtdeclarative/src/qml/types/qqmldelegatemodel_p.h  |    2 
 qtjsbackend/src/3rdparty/v8/src/platform-genode.cc |  701 ++++++++++++++++++++
 qtjsbackend/src/v8/v8.pri                          |    2 
 5 files changed, 716 insertions(+), 2 deletions(-)
 create mode 100644 qtjsbackend/src/3rdparty/v8/src/platform-genode.cc

diff --git a/qtdeclarative/src/qml/qml/qqmlimport.cpp b/qtdeclarative/src/qml/qml/qqmlimport.cpp
index 2fbb614..5816e9a 100644
--- a/qtdeclarative/src/qml/qml/qqmlimport.cpp
+++ b/qtdeclarative/src/qml/qml/qqmlimport.cpp
@@ -1463,6 +1463,14 @@ QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader,
                                                   const QString &qmldirPath, const QString &qmldirPluginPath,
                                                   const QString &baseName)
 {
+#if defined(Q_OS_GENODE)
+
+    return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName,
+                         QStringList() << QLatin1String(".lib.so"),
+                         QLatin1String("qt5_"));
+
+#else
+
 #if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
     return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName,
                          QStringList()
@@ -1512,6 +1520,7 @@ QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader,
 # endif
 
 #endif
+#endif
 }
 
 /*!
diff --git a/qtdeclarative/src/qml/qml/v8/qv8qobjectwrapper.cpp b/qtdeclarative/src/qml/qml/v8/qv8qobjectwrapper.cpp
index 53f70ad..0b31aa6 100644
--- a/qtdeclarative/src/qml/qml/v8/qv8qobjectwrapper.cpp
+++ b/qtdeclarative/src/qml/qml/v8/qv8qobjectwrapper.cpp
@@ -973,6 +973,8 @@ v8::Local<v8::Object> QQmlPropertyCache::newQObject(QObject *object, QV8Engine *
         if (checkForDuplicates)
             uniqueHash.reserve(stringCache.count());
 
+/* disabling this code seems to avoid crashes on 32-bit Linux and NOVA */
+#if 0
         // XXX TODO: Enables fast property accessors.  These more than double the property access 
         // performance, but the  cost of setting up this structure hasn't been measured so 
         // its not guaranteed that this is a win overall.  We need to try and measure the cost.
@@ -1032,7 +1034,7 @@ v8::Local<v8::Object> QQmlPropertyCache::newQObject(QObject *object, QV8Engine *
                                                     v8::External::New(property));
             }
         }
-
+#endif
         if (ft.IsEmpty()) {
             constructor = qPersistentNew<v8::Function>(engine->qobjectWrapper()->m_constructor);
         } else {
diff --git a/qtdeclarative/src/qml/types/qqmldelegatemodel_p.h b/qtdeclarative/src/qml/types/qqmldelegatemodel_p.h
index 5702c59..3d616b5 100644
--- a/qtdeclarative/src/qml/types/qqmldelegatemodel_p.h
+++ b/qtdeclarative/src/qml/types/qqmldelegatemodel_p.h
@@ -52,6 +52,8 @@
 #include <private/qv8engine_p.h>
 #include <private/qqmlglobal_p.h>
 
+#include <QtQml/QQmlParserStatus>
+
 Q_DECLARE_METATYPE(QModelIndex)
 
 QT_BEGIN_NAMESPACE
diff --git a/qtjsbackend/src/3rdparty/v8/src/platform-genode.cc b/qtjsbackend/src/3rdparty/v8/src/platform-genode.cc
new file mode 100644
index 0000000..3a8cf90
--- /dev/null
+++ b/qtjsbackend/src/3rdparty/v8/src/platform-genode.cc
@@ -0,0 +1,701 @@
+// Copyright 2012 the V8 project authors. 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 Google Inc. 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.
+
+// Platform specific code for Genode goes here
+
+// Minimal include to get access to abort, fprintf and friends for bootstrapping
+// messages.
+
+#include <base/printf.h>
+#include <rm_session/connection.h>
+#include <util/avl_tree.h>
+
+#include <errno.h>
+#include <pthread.h>
+#include <semaphore.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+#include "v8.h"
+
+#include "platform-posix.h"
+#include "platform.h"
+#include "vm-state-inl.h"
+
+
+namespace v8 {
+namespace internal {
+
+static const bool verbose = false;
+
+static const pthread_t kNoThread = (pthread_t) 0;
+
+#undef UNIMPLEMENTED
+#define UNIMPLEMENTED(...) PDBG("UNIMPLEMENTED")
+
+
+double ceiling(double x) {
+  return ceil(x);
+}
+
+
+// Initialize OS class early in the V8 startup.
+void OS::SetUp() {
+  // Seed the random number generator.
+  UNIMPLEMENTED();
+}
+
+
+void OS::PostSetUp() {
+  POSIXPostSetUp();
+}
+
+
+void OS::TearDown() {
+  UNIMPLEMENTED();
+}
+
+int OS::ActivationFrameAlignment() {
+#ifdef V8_TARGET_ARCH_ARM
+  // On EABI ARM targets this is required for fp correctness in the
+  // runtime system.
+  return 8;
+#elif V8_TARGET_ARCH_MIPS
+  return 8;
+#endif
+  // With gcc 4.4 the tree vectorization optimizer can generate code
+  // that requires 16 byte alignment such as movdqa on x86.
+  return 16;
+}
+
+
+void OS::ReleaseStore(volatile AtomicWord* ptr, AtomicWord value) {
+#if (defined(V8_TARGET_ARCH_ARM) && defined(__arm__)) || \
+    (defined(V8_TARGET_ARCH_MIPS) && defined(__mips__))
+  // Only use on ARM or MIPS hardware.
+  MemoryBarrier();
+#else
+  __asm__ __volatile__("" : : : "memory");
+  // An x86 store acts as a release barrier.
+#endif
+  *ptr = value;
+}
+
+
+// Returns a string identifying the current timezone taking into
+// account daylight saving.
+const char* OS::LocalTimezone(double time) {
+  UNIMPLEMENTED();
+  return "<none>";
+}
+
+
+// Returns the local time offset in milliseconds east of UTC without
+// taking daylight savings time into account.
+double OS::LocalTimeOffset() {
+  UNIMPLEMENTED();
+  return 0;
+}
+
+
+uint64_t OS::CpuFeaturesImpliedByPlatform() {
+  return 0;
+}
+
+#if 0
+CpuImplementer OS::GetCpuImplementer() {
+  UNIMPLEMENTED();
+}
+
+
+bool OS::ArmCpuHasFeature(CpuFeature feature) {
+  UNIMPLEMENTED();
+}
+
+
+bool OS::ArmUsingHardFloat() {
+  UNIMPLEMENTED();
+}
+#endif
+
+bool OS::IsOutsideAllocatedSpace(void* address) {
+  UNIMPLEMENTED();
+  return false;
+}
+
+#if 0
+size_t OS::AllocateAlignment() {
+  UNIMPLEMENTED();
+  return 0;
+}
+#endif
+
+void* OS::Allocate(const size_t requested,
+                   size_t* allocated,
+                   bool executable) {
+  //UNIMPLEMENTED();
+  *allocated = requested;
+  return malloc(requested);
+}
+
+#if 0
+void OS::Free(void* buf, const size_t length) {
+  // TODO(1240712): potential system call return value which is ignored here.
+  UNIMPLEMENTED();
+}
+
+
+void OS::Guard(void* address, const size_t size) {
+  UNIMPLEMENTED();
+}
+#endif
+
+void OS::Sleep(int milliseconds) {
+  UNIMPLEMENTED();
+}
+
+
+void OS::Abort() {
+  // Minimalistic implementation for bootstrapping.
+  abort();
+}
+
+#if 0
+void OS::DebugBreak() {
+  UNIMPLEMENTED();
+}
+#endif
+
+OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+
+#if 0
+OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
+    void* initial) {
+  UNIMPLEMENTED();
+  return NULL;
+}
+#endif
+
+void OS::LogSharedLibraryAddresses() {
+  UNIMPLEMENTED();
+}
+
+
+void OS::SignalCodeMovingGC() {
+  UNIMPLEMENTED();
+}
+
+#if 0
+int OS::StackWalk(Vector<OS::StackFrame> frames) {
+  UNIMPLEMENTED();
+  return 0;
+}
+#endif
+
+/* --- */
+
+class Attached_rm_connection : public Genode::Rm_connection,
+                               public Genode::Avl_node<Attached_rm_connection>
+{
+
+	private:
+
+		Genode::Dataspace_capability _ds_cap;
+
+		size_t    _size;
+		Genode::addr_t _base_addr;
+
+	public:
+
+		Attached_rm_connection(size_t size, size_t alignment = 0)
+		: Genode::Rm_connection(0, size),
+		  _ds_cap(dataspace()),
+		  _size(size)
+		{
+			if (alignment == 0) {
+				_base_addr = Genode::env()->rm_session()->attach(_ds_cap);
+			} else {
+				for (_base_addr = alignment;
+				     _base_addr != 0; /* wrap-around */
+				     _base_addr += alignment) {
+					try {
+						Genode::env()->rm_session()->attach_at(_ds_cap, _base_addr);
+						return;
+					} catch (Genode::Rm_connection::Region_conflict) {
+						if (verbose)
+							PDBG("could not attach at address 0x%lx", _base_addr);
+					}
+				}
+				throw Rm_connection::Region_conflict();
+			}
+		}
+
+		~Attached_rm_connection()
+		{
+			Genode::env()->rm_session()->detach(_base_addr);
+		}
+
+		size_t size() const { return _size; }
+
+		void *base_addr() const { return (void*)_base_addr; }
+
+		void attach(Genode::Dataspace_capability ds_cap, Genode::addr_t addr,
+		            bool executable)
+		{
+			Genode::Rm_connection::attach(ds_cap, 0, 0, true,
+			                              (void*)(addr - _base_addr),
+			                              executable);
+		}
+
+		Attached_rm_connection *find_by_addr(Genode::addr_t addr)
+		{
+			if (verbose)
+				PDBG("addr = 0x%lx, _base_addr = 0x%lx, _end_addr = 0x%lx",
+				     addr, _base_addr, _base_addr + _size);
+			if ((addr >= _base_addr) && (addr < _base_addr + _size))
+				return this;
+
+			Attached_rm_connection *next = child(addr > _base_addr);
+			return next ? next->find_by_addr(addr) : 0;
+		}
+
+		/**
+		  * Avl_node interface
+		  */
+		bool higher(Attached_rm_connection *other)
+		{
+			return ((Genode::addr_t)other->base_addr() > _base_addr);
+		}
+};
+
+
+static Genode::Avl_tree<Attached_rm_connection> &vm_registry()
+{
+	static Genode::Avl_tree<Attached_rm_connection> _vm_registry;
+	return _vm_registry;
+}
+
+
+static void *reserve_region(size_t size, size_t alignment = 0)
+{
+  Attached_rm_connection *rm;
+  try {
+    rm = new Attached_rm_connection(size, alignment);
+  } catch (Attached_rm_connection::Region_conflict) {
+	PDBG("could not reserve region");
+	return 0;
+  }
+  vm_registry().insert(rm);
+  if (verbose)
+    PDBG("base_addr = 0x%p", rm->base_addr());
+  return rm->base_addr();
+}
+
+/* --- */
+
+VirtualMemory::VirtualMemory() : address_(NULL), size_(0) { }
+
+
+VirtualMemory::VirtualMemory(size_t size) {
+  if (verbose)
+    PDBG("size = 0x%zx", size);
+  address_ = ReserveRegion(size);
+  size_ = size;
+}
+
+
+VirtualMemory::VirtualMemory(size_t size, size_t alignment) {
+  if (verbose)
+    PDBG("size = 0x%zx, alignment = 0x%zx", size, alignment);
+  address_ = reserve_region(size, alignment);
+  size_ = size;
+}
+
+
+VirtualMemory::~VirtualMemory() {
+  if (IsReserved()) {
+    bool result = ReleaseRegion(address(), size());
+    ASSERT(result);
+    USE(result);
+  }
+}
+
+
+bool VirtualMemory::IsReserved() {
+  return address_ != NULL;
+}
+
+
+void VirtualMemory::Reset() {
+  address_ = NULL;
+  size_ = 0;
+}
+
+
+bool VirtualMemory::Commit(void* address, size_t size, bool is_executable) {
+  return CommitRegion(address, size, is_executable);
+}
+
+
+
+bool VirtualMemory::Uncommit(void* address, size_t size) {
+  return UncommitRegion(address, size);
+}
+
+
+bool VirtualMemory::Guard(void* address) {
+  UNIMPLEMENTED();
+  return true;
+}
+
+
+void* VirtualMemory::ReserveRegion(size_t size) {
+  return reserve_region(size);
+}
+
+
+bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
+  if (verbose)
+    PDBG("base = 0x%p, size = 0x%zx", base, size);
+  Attached_rm_connection *rm = vm_registry().first();
+  rm = rm->find_by_addr((Genode::addr_t)base);
+  if (!rm) {
+    if (verbose)
+      PDBG("could not find RM connection");
+    return false;
+  }
+
+  Genode::Ram_dataspace_capability ds_cap =
+    Genode::env()->ram_session()->alloc(size);
+
+  try {
+	  rm->attach(ds_cap, (Genode::addr_t)base, is_executable);
+  } catch (Genode::Rm_session::Region_conflict) {
+	return false;
+  }
+
+  return true;
+}
+
+
+bool VirtualMemory::UncommitRegion(void* base, size_t size) {
+  UNIMPLEMENTED();
+  if (verbose)
+    PDBG("base = 0x%p, size = 0x%zx", base, size);
+  return false;
+}
+
+
+bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
+
+  UNIMPLEMENTED();
+
+#if 0
+  /*
+   * FIXME
+   * 
+   * Unmapping of managed dataspaces is not supported on all platforms.
+   * To make it still work, all dataspaces attached to the sub RM session must
+   * be detached before detaching the sub RM session.
+   */
+
+  if (verbose)
+    PDBG("base = 0x%p, size = 0x%zx", base, size);
+  Attached_rm_connection *rm = vm_registry().first();
+  /* XXX: also pass the size for checking? */
+  rm = rm->find_by_addr((Genode::addr_t)base);
+  if (!rm)
+    return false;
+
+  vm_registry().remove(rm);
+
+  delete rm;
+#endif
+
+  return true;
+}
+
+
+bool VirtualMemory::HasLazyCommits() {
+  // TODO(alph): implement for the platform.
+  return false;
+}
+
+
+class Thread::PlatformData : public Malloced {
+ public:
+  PlatformData() : thread_(kNoThread) {}
+
+  pthread_t thread_;  // Thread handle for pthread.
+};
+
+
+Thread::Thread(const Options& options)
+    : data_(new PlatformData()),
+      stack_size_(options.stack_size()) {
+  set_name(options.name());
+}
+
+
+Thread::~Thread() {
+  delete data_;
+}
+
+
+static void* ThreadEntry(void* arg) {
+  Thread* thread = reinterpret_cast<Thread*>(arg);
+  // This is also initialized by the first argument to pthread_create() but we
+  // don't know which thread will run first (the original thread or the new
+  // one) so we initialize it here too.
+#ifdef PR_SET_NAME
+  prctl(PR_SET_NAME,
+        reinterpret_cast<unsigned long>(thread->name()),  // NOLINT
+        0, 0, 0);
+#endif
+  thread->data()->thread_ = pthread_self();
+  ASSERT(thread->data()->thread_ != kNoThread);
+  thread->Run();
+  return NULL;
+}
+
+
+void Thread::set_name(const char* name) {
+  strncpy(name_, name, sizeof(name_));
+  name_[sizeof(name_) - 1] = '\0';
+}
+
+
+void Thread::Start() {
+  pthread_attr_t* attr_ptr = NULL;
+  pthread_attr_t attr;
+  if (stack_size_ > 0) {
+    pthread_attr_init(&attr);
+    pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
+    attr_ptr = &attr;
+  }
+  int result = pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this);
+  CHECK_EQ(0, result);
+  ASSERT(data_->thread_ != kNoThread);
+}
+
+
+void Thread::Join() {
+  pthread_join(data_->thread_, NULL);
+}
+
+
+Thread::LocalStorageKey Thread::CreateThreadLocalKey() {
+  pthread_key_t key;
+  int result = pthread_key_create(&key, NULL);
+  USE(result);
+  ASSERT(result == 0);
+  return static_cast<LocalStorageKey>(key);
+}
+
+
+void Thread::DeleteThreadLocalKey(LocalStorageKey key) {
+  pthread_key_t pthread_key = static_cast<pthread_key_t>(key);
+  int result = pthread_key_delete(pthread_key);
+  USE(result);
+  ASSERT(result == 0);
+}
+
+
+void* Thread::GetThreadLocal(LocalStorageKey key) {
+  pthread_key_t pthread_key = static_cast<pthread_key_t>(key);
+  return pthread_getspecific(pthread_key);
+}
+
+
+void Thread::SetThreadLocal(LocalStorageKey key, void* value) {
+  pthread_key_t pthread_key = static_cast<pthread_key_t>(key);
+  pthread_setspecific(pthread_key, value);
+}
+
+
+void Thread::YieldCPU() {
+  UNIMPLEMENTED();
+}
+
+
+class GenodeMutex : public Mutex {
+ public:
+  GenodeMutex() {
+    pthread_mutexattr_t attrs;
+    int result = pthread_mutexattr_init(&attrs);
+    ASSERT(result == 0);
+    result = pthread_mutexattr_settype(&attrs, PTHREAD_MUTEX_RECURSIVE);
+    ASSERT(result == 0);
+    result = pthread_mutex_init(&mutex_, &attrs);
+    ASSERT(result == 0);
+    USE(result);
+  }
+
+  virtual ~GenodeMutex() { pthread_mutex_destroy(&mutex_); }
+
+  virtual int Lock() {
+    int result = pthread_mutex_lock(&mutex_);
+    return result;
+  }
+
+  virtual int Unlock() {
+    int result = pthread_mutex_unlock(&mutex_);
+    return result;
+  }
+
+  virtual bool TryLock() {
+    int result = pthread_mutex_trylock(&mutex_);
+    // Return false if the lock is busy and locking failed.
+    if (result == EBUSY) {
+      return false;
+    }
+    ASSERT(result == 0);  // Verify no other errors.
+    return true;
+  }
+
+ private:
+  pthread_mutex_t mutex_;   // Pthread mutex for POSIX platforms.
+};
+
+
+Mutex* OS::CreateMutex() {
+  return new GenodeMutex();
+}
+
+
+class GenodeSemaphore : public Semaphore {
+ public:
+  explicit GenodeSemaphore(int count) {  sem_init(&sem_, 0, count); }
+  virtual ~GenodeSemaphore() { sem_destroy(&sem_); }
+
+  virtual void Wait();
+  virtual bool Wait(int timeout);
+  virtual void Signal() { sem_post(&sem_); }
+ private:
+  sem_t sem_;
+};
+
+
+void GenodeSemaphore::Wait() {
+  while (true) {
+    int result = sem_wait(&sem_);
+    if (result == 0) return;  // Successfully got semaphore.
+    CHECK(result == -1 && errno == EINTR);  // Signal caused spurious wakeup.
+  }
+}
+
+
+#ifndef TIMEVAL_TO_TIMESPEC
+#define TIMEVAL_TO_TIMESPEC(tv, ts) do {                            \
+    (ts)->tv_sec = (tv)->tv_sec;                                    \
+    (ts)->tv_nsec = (tv)->tv_usec * 1000;                           \
+} while (false)
+#endif
+
+
+bool GenodeSemaphore::Wait(int timeout) {
+  const long kOneSecondMicros = 1000000;  // NOLINT
+
+  // Split timeout into second and nanosecond parts.
+  struct timeval delta;
+  delta.tv_usec = timeout % kOneSecondMicros;
+  delta.tv_sec = timeout / kOneSecondMicros;
+
+  struct timeval current_time;
+  // Get the current time.
+  if (gettimeofday(&current_time, NULL) == -1) {
+    return false;
+  }
+
+  // Calculate time for end of timeout.
+  struct timeval end_time;
+  timeradd(&current_time, &delta, &end_time);
+
+  struct timespec ts;
+  TIMEVAL_TO_TIMESPEC(&end_time, &ts);
+  // Wait for semaphore signalled or timeout.
+  while (true) {
+    int result = sem_timedwait(&sem_, &ts);
+    if (result == 0) return true;  // Successfully got semaphore.
+    if (result > 0) {
+      // For glibc prior to 2.3.4 sem_timedwait returns the error instead of -1.
+      errno = result;
+      result = -1;
+    }
+    if (result == -1 && errno == ETIMEDOUT) return false;  // Timeout.
+    CHECK(result == -1 && errno == EINTR);  // Signal caused spurious wakeup.
+  }
+}
+
+
+Semaphore* OS::CreateSemaphore(int count) {
+  return new GenodeSemaphore(count);
+}
+
+
+class Sampler::PlatformData  : public Malloced {
+ public:
+  PlatformData() {
+    UNIMPLEMENTED();
+  }
+};
+
+
+Sampler::Sampler(Isolate *isolate, int interval)
+    : isolate_(isolate),
+      interval_(interval),
+      profiling_(false),
+      active_(false),
+      samples_taken_(0) {
+  UNIMPLEMENTED();
+  // Shared setup follows.
+  data_ = new PlatformData;
+}
+
+
+Sampler::~Sampler() {
+  UNIMPLEMENTED();
+  // Shared tear down follows.
+  delete data_;
+}
+
+
+void Sampler::Start() {
+  UNIMPLEMENTED();
+}
+
+
+void Sampler::Stop() {
+  UNIMPLEMENTED();
+}
+
+
+} }  // namespace v8::internal
diff --git a/qtjsbackend/src/v8/v8.pri b/qtjsbackend/src/v8/v8.pri
index 3a563ff..6a83034 100644
--- a/qtjsbackend/src/v8/v8.pri
+++ b/qtjsbackend/src/v8/v8.pri
@@ -265,7 +265,7 @@ SOURCES += \
 LIBS += -lexecinfo
 } else:unix:!qnx {
 SOURCES += \
-    $$V8SRC/platform-linux.cc \
+    $$V8SRC/platform-genode.cc \
     $$V8SRC/platform-posix.cc
 }
 
