[gjs/master.windows: 9/9] gjs: Work around Visual Studio 2017 bug
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gjs/master.windows: 9/9] gjs: Work around Visual Studio 2017 bug
- Date: Fri, 22 Feb 2019 11:16:13 +0000 (UTC)
commit e1aedb66a5ca798adcd5b49b8f05f5d1d2867d49
Author: Chun-wei Fan <fanchunwei src gnome org>
Date: Fri Feb 22 19:12:03 2019 +0800
gjs: Work around Visual Studio 2017 bug
It is known that codecvt_utf8_utf16 does not work when converting to
char16_t because the symbols are somehow missing from the C++ runtime
.lib. So, we use the Windows APIs to do that for us, and use the
Windows-specific std::u16string constructor using the wstring that we
obtain using the Windows APIs.
See:
https://social.msdn.microsoft.com/Forums/en-US/8f40dcd8-c67f-4eba-9134-a19b9178e481/vs-2015-rc-linker-stdcodecvt-error?forum=vcgeneral
gjs/context-private.h | 27 +++++++++++++++++++++++++++
gjs/context.cpp | 9 ++++++++-
gjs/module.cpp | 9 ++++++++-
3 files changed, 43 insertions(+), 2 deletions(-)
---
diff --git a/gjs/context-private.h b/gjs/context-private.h
index 566be990..a97dc0c8 100644
--- a/gjs/context-private.h
+++ b/gjs/context-private.h
@@ -36,6 +36,11 @@
#include "js/GCHashTable.h"
#include "js/SweepingAPI.h"
+#ifdef G_OS_WIN32
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
using JobQueue = JS::GCVector<JSObject*, 0, js::SystemAllocPolicy>;
using FundamentalTable =
JS::GCHashMap<void*, JS::Heap<JSObject*>, js::DefaultHasher<void*>,
@@ -172,4 +177,26 @@ class GjsContextPrivate {
void dispose(void);
};
+#if defined (G_OS_WIN32) && defined (_MSC_VER) && (_MSC_VER >= 1900)
+/* Unfortunately Visual Studio's C++ .lib somehow did not contain the right codecvt stuff
+ * that we need to convert from utf8 to utf16 (char16_t), so we need to work around this
+ * Visual Studio bug. Use Windows API MultiByteToWideChar() and obtain the std::u16string on
+ * the std::wstring we obtain from MultiByteToWideChar(). See:
+ *
https://social.msdn.microsoft.com/Forums/en-US/8f40dcd8-c67f-4eba-9134-a19b9178e481/vs-2015-rc-linker-stdcodecvt-error?forum=vcgeneral
+ */
+static std::u16string
+utf8_to_utf16 (std::string str)
+{
+ int len = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
+ if (len == 0)
+ return nullptr;
+
+ std::wstring wstr(str.length(), 0);
+ if (MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &wstr[0], len) == 0)
+ return nullptr;
+
+ std::u16string u16str(wstr.begin(), wstr.end());
+ return u16str;
+}
+#endif
#endif /* __GJS_CONTEXT_PRIVATE_H__ */
diff --git a/gjs/context.cpp b/gjs/context.cpp
index 211f6931..045978a2 100644
--- a/gjs/context.cpp
+++ b/gjs/context.cpp
@@ -965,8 +965,15 @@ bool GjsContextPrivate::eval_with_scope(JS::HandleObject scope_object,
JS::CompileOptions options(m_cx);
options.setFileAndLine(filename, start_line_number).setSourceIsLazy(true);
+ std::u16string utf16_string;
+
+#if !defined (_MSC_VER) || (_MSC_VER < 1900)
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
- std::u16string utf16_string = convert.from_bytes(script);
+ utf16_string = convert.from_bytes(script);
+#else
+ utf16_string = utf8_to_utf16 (script);
+#endif
+
JS::SourceBufferHolder buf(utf16_string.c_str(), utf16_string.size(),
JS::SourceBufferHolder::NoOwnership);
diff --git a/gjs/module.cpp b/gjs/module.cpp
index 258d9b1e..e5a73939 100644
--- a/gjs/module.cpp
+++ b/gjs/module.cpp
@@ -99,8 +99,15 @@ class GjsModule {
JS::CompileOptions options(cx);
options.setFileAndLine(filename, line_number);
+ std::u16string utf16_string;
+
+#if !defined (_MSC_VER) || (_MSC_VER < 1900)
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
- std::u16string utf16_string = convert.from_bytes(script);
+ utf16_string = convert.from_bytes(script);
+#else
+ utf16_string = utf8_to_utf16 (script);
+#endif
+
JS::SourceBufferHolder buf(utf16_string.c_str(), utf16_string.size(),
JS::SourceBufferHolder::NoOwnership);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]