Commit c455da15 authored by Chun-wei Fan's avatar Chun-wei Fan

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
parent a76011f9
......@@ -967,8 +967,14 @@ bool GjsContextPrivate::eval_with_scope(JS::HandleObject scope_object,
JS::CompileOptions options(m_cx);
options.setFileAndLine(filename, start_line_number).setSourceIsLazy(true);
#if defined(G_OS_WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1900))
std::wstring wscript = gjs_win32_vc140_utf8_to_utf16(script);
std::u16string utf16_string(reinterpret_cast<const char16_t*>(wscript.c_str()));
#else
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
std::u16string utf16_string = convert.from_bytes(script);
#endif
JS::SourceBufferHolder buf(utf16_string.c_str(), utf16_string.size(),
JS::SourceBufferHolder::NoOwnership);
......
......@@ -34,6 +34,11 @@
#include <js/GCAPI.h>
#include <js/Printf.h>
#ifdef XP_WIN
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#endif
#include "gjs/context-private.h"
#include "gjs/jsapi-class.h"
#include "gjs/jsapi-util.h"
......@@ -660,3 +665,26 @@ gjs_strip_unix_shebang(const char *script,
return script;
}
#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
*/
std::wstring gjs_win32_vc140_utf8_to_utf16(const char* str) {
int len = MultiByteToWideChar(CP_UTF8, 0, str, -1, nullptr, 0);
if (len == 0)
return nullptr;
std::wstring wstr(len, 0);
int result = MultiByteToWideChar(CP_UTF8, 0, str, -1, &wstr[0], len);
if (result == 0)
return nullptr;
wstr.resize(strlen(str));
return wstr;
}
#endif
......@@ -363,4 +363,8 @@ GJS_USE std::string gjs_debug_id(jsid id);
GJS_USE
char* gjs_hyphen_to_underscore(const char* str);
#if defined(G_OS_WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1900))
GJS_USE std::wstring gjs_win32_vc140_utf8_to_utf16(const char* str);
#endif
#endif /* __GJS_JSAPI_UTIL_H__ */
......@@ -99,8 +99,15 @@ class GjsModule {
JS::CompileOptions options(cx);
options.setFileAndLine(filename, line_number);
#if defined(G_OS_WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1900))
std::wstring wscript = gjs_win32_vc140_utf8_to_utf16(script);
std::u16string utf16_string(
reinterpret_cast<const char16_t*>(wscript.c_str()));
#else
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
std::u16string utf16_string = convert.from_bytes(script);
#endif
JS::SourceBufferHolder buf(utf16_string.c_str(), utf16_string.size(),
JS::SourceBufferHolder::NoOwnership);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment