| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "platform/globals.h" | 5 #include "platform/globals.h" |
| 6 #if defined(HOST_OS_WINDOWS) | 6 #if defined(HOST_OS_WINDOWS) |
| 7 | 7 |
| 8 #include <errno.h> // NOLINT | 8 #include <errno.h> // NOLINT |
| 9 #include <time.h> // NOLINT | 9 #include <time.h> // NOLINT |
| 10 | 10 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { | 24 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { |
| 25 Log::PrintErr("FormatMessage failed for error code %d (error %d)\n", code, | 25 Log::PrintErr("FormatMessage failed for error code %d (error %d)\n", code, |
| 26 GetLastError()); | 26 GetLastError()); |
| 27 } | 27 } |
| 28 _snwprintf(buffer, buffer_length, L"OS Error %d", code); | 28 _snwprintf(buffer, buffer_length, L"OS Error %d", code); |
| 29 } | 29 } |
| 30 // Ensure string termination. | 30 // Ensure string termination. |
| 31 buffer[buffer_length - 1] = 0; | 31 buffer[buffer_length - 1] = 0; |
| 32 } | 32 } |
| 33 | 33 |
| 34 | |
| 35 OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) { | 34 OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) { |
| 36 set_code(GetLastError()); | 35 set_code(GetLastError()); |
| 37 | 36 |
| 38 static const int kMaxMessageLength = 256; | 37 static const int kMaxMessageLength = 256; |
| 39 wchar_t message[kMaxMessageLength]; | 38 wchar_t message[kMaxMessageLength]; |
| 40 FormatMessageIntoBuffer(code_, message, kMaxMessageLength); | 39 FormatMessageIntoBuffer(code_, message, kMaxMessageLength); |
| 41 char* utf8 = StringUtilsWin::WideToUtf8(message); | 40 char* utf8 = StringUtilsWin::WideToUtf8(message); |
| 42 SetMessage(utf8); | 41 SetMessage(utf8); |
| 43 } | 42 } |
| 44 | 43 |
| 45 | |
| 46 void OSError::SetCodeAndMessage(SubSystem sub_system, int code) { | 44 void OSError::SetCodeAndMessage(SubSystem sub_system, int code) { |
| 47 set_sub_system(sub_system); | 45 set_sub_system(sub_system); |
| 48 set_code(code); | 46 set_code(code); |
| 49 | 47 |
| 50 static const int kMaxMessageLength = 256; | 48 static const int kMaxMessageLength = 256; |
| 51 wchar_t message[kMaxMessageLength]; | 49 wchar_t message[kMaxMessageLength]; |
| 52 FormatMessageIntoBuffer(code_, message, kMaxMessageLength); | 50 FormatMessageIntoBuffer(code_, message, kMaxMessageLength); |
| 53 char* utf8 = StringUtilsWin::WideToUtf8(message); | 51 char* utf8 = StringUtilsWin::WideToUtf8(message); |
| 54 SetMessage(utf8); | 52 SetMessage(utf8); |
| 55 } | 53 } |
| 56 | 54 |
| 57 | |
| 58 char* StringUtils::ConsoleStringToUtf8(char* str, | 55 char* StringUtils::ConsoleStringToUtf8(char* str, |
| 59 intptr_t len, | 56 intptr_t len, |
| 60 intptr_t* result_len) { | 57 intptr_t* result_len) { |
| 61 int wide_len = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0); | 58 int wide_len = MultiByteToWideChar(CP_ACP, 0, str, len, NULL, 0); |
| 62 wchar_t* wide; | 59 wchar_t* wide; |
| 63 wide = | 60 wide = |
| 64 reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(wide_len * sizeof(*wide))); | 61 reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(wide_len * sizeof(*wide))); |
| 65 MultiByteToWideChar(CP_ACP, 0, str, len, wide, wide_len); | 62 MultiByteToWideChar(CP_ACP, 0, str, len, wide, wide_len); |
| 66 char* utf8 = StringUtilsWin::WideToUtf8(wide, wide_len, result_len); | 63 char* utf8 = StringUtilsWin::WideToUtf8(wide, wide_len, result_len); |
| 67 return utf8; | 64 return utf8; |
| 68 } | 65 } |
| 69 | 66 |
| 70 | |
| 71 char* StringUtils::Utf8ToConsoleString(char* utf8, | 67 char* StringUtils::Utf8ToConsoleString(char* utf8, |
| 72 intptr_t len, | 68 intptr_t len, |
| 73 intptr_t* result_len) { | 69 intptr_t* result_len) { |
| 74 intptr_t wide_len; | 70 intptr_t wide_len; |
| 75 wchar_t* wide = StringUtilsWin::Utf8ToWide(utf8, len, &wide_len); | 71 wchar_t* wide = StringUtilsWin::Utf8ToWide(utf8, len, &wide_len); |
| 76 int system_len = | 72 int system_len = |
| 77 WideCharToMultiByte(CP_ACP, 0, wide, wide_len, NULL, 0, NULL, NULL); | 73 WideCharToMultiByte(CP_ACP, 0, wide, wide_len, NULL, 0, NULL, NULL); |
| 78 char* ansi; | 74 char* ansi; |
| 79 ansi = | 75 ansi = |
| 80 reinterpret_cast<char*>(Dart_ScopeAllocate(system_len * sizeof(*ansi))); | 76 reinterpret_cast<char*>(Dart_ScopeAllocate(system_len * sizeof(*ansi))); |
| 81 if (ansi == NULL) { | 77 if (ansi == NULL) { |
| 82 return NULL; | 78 return NULL; |
| 83 } | 79 } |
| 84 WideCharToMultiByte(CP_ACP, 0, wide, wide_len, ansi, system_len, NULL, NULL); | 80 WideCharToMultiByte(CP_ACP, 0, wide, wide_len, ansi, system_len, NULL, NULL); |
| 85 if (result_len != NULL) { | 81 if (result_len != NULL) { |
| 86 *result_len = system_len; | 82 *result_len = system_len; |
| 87 } | 83 } |
| 88 return ansi; | 84 return ansi; |
| 89 } | 85 } |
| 90 | 86 |
| 91 | |
| 92 char* StringUtilsWin::WideToUtf8(wchar_t* wide, | 87 char* StringUtilsWin::WideToUtf8(wchar_t* wide, |
| 93 intptr_t len, | 88 intptr_t len, |
| 94 intptr_t* result_len) { | 89 intptr_t* result_len) { |
| 95 // If len is -1 then WideCharToMultiByte will include the terminating | 90 // If len is -1 then WideCharToMultiByte will include the terminating |
| 96 // NUL byte in the length. | 91 // NUL byte in the length. |
| 97 int utf8_len = | 92 int utf8_len = |
| 98 WideCharToMultiByte(CP_UTF8, 0, wide, len, NULL, 0, NULL, NULL); | 93 WideCharToMultiByte(CP_UTF8, 0, wide, len, NULL, 0, NULL, NULL); |
| 99 char* utf8; | 94 char* utf8; |
| 100 utf8 = reinterpret_cast<char*>(Dart_ScopeAllocate(utf8_len * sizeof(*utf8))); | 95 utf8 = reinterpret_cast<char*>(Dart_ScopeAllocate(utf8_len * sizeof(*utf8))); |
| 101 WideCharToMultiByte(CP_UTF8, 0, wide, len, utf8, utf8_len, NULL, NULL); | 96 WideCharToMultiByte(CP_UTF8, 0, wide, len, utf8, utf8_len, NULL, NULL); |
| 102 if (result_len != NULL) { | 97 if (result_len != NULL) { |
| 103 *result_len = utf8_len; | 98 *result_len = utf8_len; |
| 104 } | 99 } |
| 105 return utf8; | 100 return utf8; |
| 106 } | 101 } |
| 107 | 102 |
| 108 | |
| 109 wchar_t* StringUtilsWin::Utf8ToWide(char* utf8, | 103 wchar_t* StringUtilsWin::Utf8ToWide(char* utf8, |
| 110 intptr_t len, | 104 intptr_t len, |
| 111 intptr_t* result_len) { | 105 intptr_t* result_len) { |
| 112 // If len is -1 then MultiByteToWideChar will include the terminating | 106 // If len is -1 then MultiByteToWideChar will include the terminating |
| 113 // NUL byte in the length. | 107 // NUL byte in the length. |
| 114 int wide_len = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0); | 108 int wide_len = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0); |
| 115 wchar_t* wide; | 109 wchar_t* wide; |
| 116 wide = | 110 wide = |
| 117 reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(wide_len * sizeof(*wide))); | 111 reinterpret_cast<wchar_t*>(Dart_ScopeAllocate(wide_len * sizeof(*wide))); |
| 118 MultiByteToWideChar(CP_UTF8, 0, utf8, len, wide, wide_len); | 112 MultiByteToWideChar(CP_UTF8, 0, utf8, len, wide, wide_len); |
| 119 if (result_len != NULL) { | 113 if (result_len != NULL) { |
| 120 *result_len = wide_len; | 114 *result_len = wide_len; |
| 121 } | 115 } |
| 122 return wide; | 116 return wide; |
| 123 } | 117 } |
| 124 | 118 |
| 125 | |
| 126 const char* StringUtils::Utf8ToConsoleString(const char* utf8, | 119 const char* StringUtils::Utf8ToConsoleString(const char* utf8, |
| 127 intptr_t len, | 120 intptr_t len, |
| 128 intptr_t* result_len) { | 121 intptr_t* result_len) { |
| 129 return const_cast<const char*>(StringUtils::Utf8ToConsoleString( | 122 return const_cast<const char*>(StringUtils::Utf8ToConsoleString( |
| 130 const_cast<char*>(utf8), len, result_len)); | 123 const_cast<char*>(utf8), len, result_len)); |
| 131 } | 124 } |
| 132 | 125 |
| 133 | |
| 134 const char* StringUtils::ConsoleStringToUtf8(const char* str, | 126 const char* StringUtils::ConsoleStringToUtf8(const char* str, |
| 135 intptr_t len, | 127 intptr_t len, |
| 136 intptr_t* result_len) { | 128 intptr_t* result_len) { |
| 137 return const_cast<const char*>(StringUtils::ConsoleStringToUtf8( | 129 return const_cast<const char*>(StringUtils::ConsoleStringToUtf8( |
| 138 const_cast<char*>(str), len, result_len)); | 130 const_cast<char*>(str), len, result_len)); |
| 139 } | 131 } |
| 140 | 132 |
| 141 | |
| 142 const char* StringUtilsWin::WideToUtf8(const wchar_t* wide, | 133 const char* StringUtilsWin::WideToUtf8(const wchar_t* wide, |
| 143 intptr_t len, | 134 intptr_t len, |
| 144 intptr_t* result_len) { | 135 intptr_t* result_len) { |
| 145 return const_cast<const char*>( | 136 return const_cast<const char*>( |
| 146 StringUtilsWin::WideToUtf8(const_cast<wchar_t*>(wide), len, result_len)); | 137 StringUtilsWin::WideToUtf8(const_cast<wchar_t*>(wide), len, result_len)); |
| 147 } | 138 } |
| 148 | 139 |
| 149 | |
| 150 const wchar_t* StringUtilsWin::Utf8ToWide(const char* utf8, | 140 const wchar_t* StringUtilsWin::Utf8ToWide(const char* utf8, |
| 151 intptr_t len, | 141 intptr_t len, |
| 152 intptr_t* result_len) { | 142 intptr_t* result_len) { |
| 153 return const_cast<const wchar_t*>( | 143 return const_cast<const wchar_t*>( |
| 154 StringUtilsWin::Utf8ToWide(const_cast<char*>(utf8), len, result_len)); | 144 StringUtilsWin::Utf8ToWide(const_cast<char*>(utf8), len, result_len)); |
| 155 } | 145 } |
| 156 | 146 |
| 157 | |
| 158 char* StringUtils::StrNDup(const char* s, intptr_t n) { | 147 char* StringUtils::StrNDup(const char* s, intptr_t n) { |
| 159 intptr_t len = strlen(s); | 148 intptr_t len = strlen(s); |
| 160 if ((n < 0) || (len < 0)) { | 149 if ((n < 0) || (len < 0)) { |
| 161 return NULL; | 150 return NULL; |
| 162 } | 151 } |
| 163 if (n < len) { | 152 if (n < len) { |
| 164 len = n; | 153 len = n; |
| 165 } | 154 } |
| 166 char* result = reinterpret_cast<char*>(malloc(len + 1)); | 155 char* result = reinterpret_cast<char*>(malloc(len + 1)); |
| 167 if (result == NULL) { | 156 if (result == NULL) { |
| 168 return NULL; | 157 return NULL; |
| 169 } | 158 } |
| 170 result[len] = '\0'; | 159 result[len] = '\0'; |
| 171 return reinterpret_cast<char*>(memmove(result, s, len)); | 160 return reinterpret_cast<char*>(memmove(result, s, len)); |
| 172 } | 161 } |
| 173 | 162 |
| 174 | |
| 175 bool ShellUtils::GetUtf8Argv(int argc, char** argv) { | 163 bool ShellUtils::GetUtf8Argv(int argc, char** argv) { |
| 176 wchar_t* command_line = GetCommandLineW(); | 164 wchar_t* command_line = GetCommandLineW(); |
| 177 int unicode_argc; | 165 int unicode_argc; |
| 178 wchar_t** unicode_argv = CommandLineToArgvW(command_line, &unicode_argc); | 166 wchar_t** unicode_argv = CommandLineToArgvW(command_line, &unicode_argc); |
| 179 if (unicode_argv == NULL) { | 167 if (unicode_argv == NULL) { |
| 180 return false; | 168 return false; |
| 181 } | 169 } |
| 182 // The argc passed to main should have the same argc as we get here. | 170 // The argc passed to main should have the same argc as we get here. |
| 183 ASSERT(argc == unicode_argc); | 171 ASSERT(argc == unicode_argc); |
| 184 if (argc < unicode_argc) { | 172 if (argc < unicode_argc) { |
| 185 unicode_argc = argc; | 173 unicode_argc = argc; |
| 186 } | 174 } |
| 187 for (int i = 0; i < unicode_argc; i++) { | 175 for (int i = 0; i < unicode_argc; i++) { |
| 188 wchar_t* arg = unicode_argv[i]; | 176 wchar_t* arg = unicode_argv[i]; |
| 189 int arg_len = WideCharToMultiByte(CP_UTF8, 0, arg, -1, NULL, 0, NULL, NULL); | 177 int arg_len = WideCharToMultiByte(CP_UTF8, 0, arg, -1, NULL, 0, NULL, NULL); |
| 190 char* utf8_arg = reinterpret_cast<char*>(malloc(arg_len)); | 178 char* utf8_arg = reinterpret_cast<char*>(malloc(arg_len)); |
| 191 WideCharToMultiByte(CP_UTF8, 0, arg, -1, utf8_arg, arg_len, NULL, NULL); | 179 WideCharToMultiByte(CP_UTF8, 0, arg, -1, utf8_arg, arg_len, NULL, NULL); |
| 192 argv[i] = utf8_arg; | 180 argv[i] = utf8_arg; |
| 193 } | 181 } |
| 194 LocalFree(unicode_argv); | 182 LocalFree(unicode_argv); |
| 195 return true; | 183 return true; |
| 196 } | 184 } |
| 197 | 185 |
| 198 | |
| 199 // Although win32 uses 64-bit integers for representing timestamps, | 186 // Although win32 uses 64-bit integers for representing timestamps, |
| 200 // these are packed into a FILETIME structure. The FILETIME | 187 // these are packed into a FILETIME structure. The FILETIME |
| 201 // structure is just a struct representing a 64-bit integer. The | 188 // structure is just a struct representing a 64-bit integer. The |
| 202 // TimeStamp union allows access to both a FILETIME and an integer | 189 // TimeStamp union allows access to both a FILETIME and an integer |
| 203 // representation of the timestamp. The Windows timestamp is in | 190 // representation of the timestamp. The Windows timestamp is in |
| 204 // 100-nanosecond intervals since January 1, 1601. | 191 // 100-nanosecond intervals since January 1, 1601. |
| 205 union TimeStamp { | 192 union TimeStamp { |
| 206 FILETIME ft_; | 193 FILETIME ft_; |
| 207 int64_t t_; | 194 int64_t t_; |
| 208 }; | 195 }; |
| 209 | 196 |
| 210 | |
| 211 static int64_t GetCurrentTimeMicros() { | 197 static int64_t GetCurrentTimeMicros() { |
| 212 static const int64_t kTimeEpoc = 116444736000000000LL; | 198 static const int64_t kTimeEpoc = 116444736000000000LL; |
| 213 static const int64_t kTimeScaler = 10; // 100 ns to us. | 199 static const int64_t kTimeScaler = 10; // 100 ns to us. |
| 214 | 200 |
| 215 TimeStamp time; | 201 TimeStamp time; |
| 216 GetSystemTimeAsFileTime(&time.ft_); | 202 GetSystemTimeAsFileTime(&time.ft_); |
| 217 return (time.t_ - kTimeEpoc) / kTimeScaler; | 203 return (time.t_ - kTimeEpoc) / kTimeScaler; |
| 218 } | 204 } |
| 219 | 205 |
| 220 | |
| 221 static int64_t qpc_ticks_per_second = 0; | 206 static int64_t qpc_ticks_per_second = 0; |
| 222 | 207 |
| 223 void TimerUtils::InitOnce() { | 208 void TimerUtils::InitOnce() { |
| 224 LARGE_INTEGER ticks_per_sec; | 209 LARGE_INTEGER ticks_per_sec; |
| 225 if (!QueryPerformanceFrequency(&ticks_per_sec)) { | 210 if (!QueryPerformanceFrequency(&ticks_per_sec)) { |
| 226 qpc_ticks_per_second = 0; | 211 qpc_ticks_per_second = 0; |
| 227 } else { | 212 } else { |
| 228 qpc_ticks_per_second = static_cast<int64_t>(ticks_per_sec.QuadPart); | 213 qpc_ticks_per_second = static_cast<int64_t>(ticks_per_sec.QuadPart); |
| 229 } | 214 } |
| 230 } | 215 } |
| 231 | 216 |
| 232 | |
| 233 int64_t TimerUtils::GetCurrentMonotonicMillis() { | 217 int64_t TimerUtils::GetCurrentMonotonicMillis() { |
| 234 return GetCurrentMonotonicMicros() / 1000; | 218 return GetCurrentMonotonicMicros() / 1000; |
| 235 } | 219 } |
| 236 | 220 |
| 237 | |
| 238 int64_t TimerUtils::GetCurrentMonotonicMicros() { | 221 int64_t TimerUtils::GetCurrentMonotonicMicros() { |
| 239 if (qpc_ticks_per_second == 0) { | 222 if (qpc_ticks_per_second == 0) { |
| 240 // QueryPerformanceCounter not supported, fallback. | 223 // QueryPerformanceCounter not supported, fallback. |
| 241 return GetCurrentTimeMicros(); | 224 return GetCurrentTimeMicros(); |
| 242 } | 225 } |
| 243 // Grab performance counter value. | 226 // Grab performance counter value. |
| 244 LARGE_INTEGER now; | 227 LARGE_INTEGER now; |
| 245 QueryPerformanceCounter(&now); | 228 QueryPerformanceCounter(&now); |
| 246 int64_t qpc_value = static_cast<int64_t>(now.QuadPart); | 229 int64_t qpc_value = static_cast<int64_t>(now.QuadPart); |
| 247 // Convert to microseconds. | 230 // Convert to microseconds. |
| 248 int64_t seconds = qpc_value / qpc_ticks_per_second; | 231 int64_t seconds = qpc_value / qpc_ticks_per_second; |
| 249 int64_t leftover_ticks = qpc_value - (seconds * qpc_ticks_per_second); | 232 int64_t leftover_ticks = qpc_value - (seconds * qpc_ticks_per_second); |
| 250 int64_t result = seconds * kMicrosecondsPerSecond; | 233 int64_t result = seconds * kMicrosecondsPerSecond; |
| 251 result += ((leftover_ticks * kMicrosecondsPerSecond) / qpc_ticks_per_second); | 234 result += ((leftover_ticks * kMicrosecondsPerSecond) / qpc_ticks_per_second); |
| 252 return result; | 235 return result; |
| 253 } | 236 } |
| 254 | 237 |
| 255 | |
| 256 void TimerUtils::Sleep(int64_t millis) { | 238 void TimerUtils::Sleep(int64_t millis) { |
| 257 ::Sleep(millis); | 239 ::Sleep(millis); |
| 258 } | 240 } |
| 259 | 241 |
| 260 } // namespace bin | 242 } // namespace bin |
| 261 } // namespace dart | 243 } // namespace dart |
| 262 | 244 |
| 263 #endif // defined(HOST_OS_WINDOWS) | 245 #endif // defined(HOST_OS_WINDOWS) |
| OLD | NEW |