📄 platform-win32.cc.svn-base
字号:
// Copyright 2006-2008 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 Win32.#ifndef WIN32_LEAN_AND_MEAN// WIN32_LEAN_AND_MEAN implies NOCRYPT and NOGDI.#define WIN32_LEAN_AND_MEAN#endif#ifndef NOMINMAX#define NOMINMAX#endif#ifndef NOKERNEL#define NOKERNEL#endif#ifndef NOUSER#define NOUSER#endif#ifndef NOSERVICE#define NOSERVICE#endif#ifndef NOSOUND#define NOSOUND#endif#ifndef NOMCX#define NOMCX#endif#include <windows.h>#include <mmsystem.h> // For timeGetTime().#include <dbghelp.h> // For SymLoadModule64 and al.#include <tlhelp32.h> // For Module32First and al.// These aditional WIN32 includes have to be right here as the #undef's below// makes it impossible to have them elsewhere.#include <winsock2.h>#include <process.h> // for _beginthreadex()#include <stdlib.h>#pragma comment(lib, "winmm.lib") // force linkage with winmm.#undef VOID#undef DELETE#undef IN#undef THIS#undef CONST#undef NAN#undef GetObject#undef CreateMutex#undef CreateSemaphore#include "v8.h"#include "platform.h"// Extra POSIX/ANSI routines for Win32. Please refer to The Open Group Base// Specification for specification of the correct semantics for these// functions.// (http://www.opengroup.org/onlinepubs/000095399/)// Test for finite value - usually defined in math.hnamespace v8 {namespace internal {int isfinite(double x) { return _finite(x);}} // namespace v8} // namespace internal// Test for a NaN (not a number) value - usually defined in math.hint isnan(double x) { return _isnan(x);}// Test for infinity - usually defined in math.hint isinf(double x) { return (_fpclass(x) & (_FPCLASS_PINF | _FPCLASS_NINF)) != 0;}// Test if x is less than y and both nominal - usually defined in math.hint isless(double x, double y) { return isnan(x) || isnan(y) ? 0 : x < y;}// Test if x is greater than y and both nominal - usually defined in math.hint isgreater(double x, double y) { return isnan(x) || isnan(y) ? 0 : x > y;}// Classify floating point number - usually defined in math.hint fpclassify(double x) { // Use the MS-specific _fpclass() for classification. int flags = _fpclass(x); // Determine class. We cannot use a switch statement because // the _FPCLASS_ constants are defined as flags. if (flags & (_FPCLASS_PN | _FPCLASS_NN)) return FP_NORMAL; if (flags & (_FPCLASS_PZ | _FPCLASS_NZ)) return FP_ZERO; if (flags & (_FPCLASS_PD | _FPCLASS_ND)) return FP_SUBNORMAL; if (flags & (_FPCLASS_PINF | _FPCLASS_NINF)) return FP_INFINITE; // All cases should be covered by the code above. ASSERT(flags & (_FPCLASS_SNAN | _FPCLASS_QNAN)); return FP_NAN;}// Test sign - usually defined in math.hint signbit(double x) { // We need to take care of the special case of both positive // and negative versions of zero. if (x == 0) return _fpclass(x) & _FPCLASS_NZ; else return x < 0;}// Generate a pseudo-random number in the range 0-2^31-1. Usually// defined in stdlib.hint random() { return rand();}// Case-insensitive string comparisons. Use stricmp() on Win32. Usually defined// in strings.h.int strcasecmp(const char* s1, const char* s2) { return _stricmp(s1, s2);}// Case-insensitive bounded string comparisons. Use stricmp() on Win32. Usually// defined in strings.h.int strncasecmp(const char* s1, const char* s2, int n) { return _strnicmp(s1, s2, n);}namespace v8 { namespace internal {double ceiling(double x) { return ceil(x);}// ----------------------------------------------------------------------------// The Time class represents time on win32. A timestamp is represented as// a 64-bit integer in 100 nano-seconds since January 1, 1601 (UTC). JavaScript// timestamps are represented as a doubles in milliseconds since 00:00:00 UTC,// January 1, 1970.class Time { public: // Constructors. Time(); explicit Time(double jstime); Time(int year, int mon, int day, int hour, int min, int sec); // Convert timestamp to JavaScript representation. double ToJSTime(); // Set timestamp to current time. void SetToCurrentTime(); // Returns the local timezone offset in milliseconds east of UTC. This is // the number of milliseconds you must add to UTC to get local time, i.e. // LocalOffset(CET) = 3600000 and LocalOffset(PST) = -28800000. This // routine also takes into account whether daylight saving is effect // at the time. int64_t LocalOffset(); // Returns the daylight savings time offset for the time in milliseconds. int64_t DaylightSavingsOffset(); // Returns a string identifying the current timezone for the // timestamp taking into account daylight saving. char* LocalTimezone(); private: // Constants for time conversion. static const int64_t kTimeEpoc = 116444736000000000; static const int64_t kTimeScaler = 10000; static const int64_t kMsPerMinute = 60000; // Constants for timezone information. static const int kTzNameSize = 128; static const bool kShortTzNames = false; // Timezone information. We need to have static buffers for the // timezone names because we return pointers to these in // LocalTimezone(). static bool tz_initialized_; static TIME_ZONE_INFORMATION tzinfo_; static char std_tz_name_[kTzNameSize]; static char dst_tz_name_[kTzNameSize]; // Initialize the timezone information (if not already done). static void TzSet(); // Guess the name of the timezone from the bias. static const char* GuessTimezoneNameFromBias(int bias); // Return whether or not daylight savings time is in effect at this time. bool InDST(); // Return the difference (in milliseconds) between this timestamp and // another timestamp. int64_t Diff(Time* other); // Accessor for FILETIME representation. FILETIME& ft() { return time_.ft_; } // Accessor for integer representation. int64_t& t() { return time_.t_; } // Although win32 uses 64-bit integers for representing timestamps, // these are packed into a FILETIME structure. The FILETIME structure // is just a struct representing a 64-bit integer. The TimeStamp union // allows access to both a FILETIME and an integer representation of // the timestamp. union TimeStamp { FILETIME ft_; int64_t t_; }; TimeStamp time_;};// Static variables.bool Time::tz_initialized_ = false;TIME_ZONE_INFORMATION Time::tzinfo_;char Time::std_tz_name_[kTzNameSize];char Time::dst_tz_name_[kTzNameSize];// Initialize timestamp to start of epoc.Time::Time() { t() = 0;}// Initialize timestamp from a JavaScript timestamp.Time::Time(double jstime) { t() = static_cast<uint64_t>(jstime) * kTimeScaler + kTimeEpoc;}// Initialize timestamp from date/time components.Time::Time(int year, int mon, int day, int hour, int min, int sec) { SYSTEMTIME st; st.wYear = year; st.wMonth = mon; st.wDay = day; st.wHour = hour; st.wMinute = min; st.wSecond = sec; st.wMilliseconds = 0; SystemTimeToFileTime(&st, &ft());}// Convert timestamp to JavaScript timestamp.double Time::ToJSTime() { return static_cast<double>((t() - kTimeEpoc) / kTimeScaler);}// Guess the name of the timezone from the bias.// The guess is very biased towards the northern hemisphere.const char* Time::GuessTimezoneNameFromBias(int bias) { static const int kHour = 60; switch (-bias) { case -9*kHour: return "Alaska"; case -8*kHour: return "Pacific"; case -7*kHour: return "Mountain"; case -6*kHour: return "Central"; case -5*kHour: return "Eastern"; case -4*kHour: return "Atlantic"; case 0*kHour: return "GMT"; case +1*kHour: return "Central Europe"; case +2*kHour: return "Eastern Europe"; case +3*kHour: return "Russia"; case +5*kHour + 30: return "India"; case +8*kHour: return "China"; case +9*kHour: return "Japan"; case +12*kHour: return "New Zealand"; default: return "Local"; }}// Initialize timezone information. The timezone information is obtained from// windows. If we cannot get the timezone information we fall back to CET.// Please notice that this code is not thread-safe.void Time::TzSet() { // Just return if timezone information has already been initialized. if (tz_initialized_) return; // Obtain timezone information from operating system. memset(&tzinfo_, 0, sizeof(tzinfo_)); if (GetTimeZoneInformation(&tzinfo_) == TIME_ZONE_ID_INVALID) { // If we cannot get timezone information we fall back to CET. tzinfo_.Bias = -60; tzinfo_.StandardDate.wMonth = 10; tzinfo_.StandardDate.wDay = 5; tzinfo_.StandardDate.wHour = 3; tzinfo_.StandardBias = 0; tzinfo_.DaylightDate.wMonth = 3; tzinfo_.DaylightDate.wDay = 5; tzinfo_.DaylightDate.wHour = 2; tzinfo_.DaylightBias = -60; } // Make standard and DST timezone names. OS::SNPrintF(Vector<char>(std_tz_name_, kTzNameSize), "%S", tzinfo_.StandardName); std_tz_name_[kTzNameSize - 1] = '\0'; OS::SNPrintF(Vector<char>(dst_tz_name_, kTzNameSize), "%S", tzinfo_.DaylightName); dst_tz_name_[kTzNameSize - 1] = '\0'; // If OS returned empty string or resource id (like "@tzres.dll,-211") // simply guess the name from the UTC bias of the timezone. // To properly resolve the resource identifier requires a library load, // which is not possible in a sandbox. if (std_tz_name_[0] == '\0' || std_tz_name_[0] == '@') { OS::SNPrintF(Vector<char>(std_tz_name_, kTzNameSize - 1), "%s Standard Time", GuessTimezoneNameFromBias(tzinfo_.Bias)); } if (dst_tz_name_[0] == '\0' || dst_tz_name_[0] == '@') { OS::SNPrintF(Vector<char>(dst_tz_name_, kTzNameSize - 1), "%s Daylight Time", GuessTimezoneNameFromBias(tzinfo_.Bias)); } // Timezone information initialized. tz_initialized_ = true;}// Return the difference in milliseconds between this and another timestamp.int64_t Time::Diff(Time* other) { return (t() - other->t()) / kTimeScaler;}// Set timestamp to current time.void Time::SetToCurrentTime() { // The default GetSystemTimeAsFileTime has a ~15.5ms resolution. // Because we're fast, we like fast timers which have at least a // 1ms resolution. // // timeGetTime() provides 1ms granularity when combined with // timeBeginPeriod(). If the host application for v8 wants fast // timers, it can use timeBeginPeriod to increase the resolution. // // Using timeGetTime() has a drawback because it is a 32bit value // and hence rolls-over every ~49days. // // To use the clock, we use GetSystemTimeAsFileTime as our base; // and then use timeGetTime to extrapolate current time from the // start time. To deal with rollovers, we resync the clock // any time when more than kMaxClockElapsedTime has passed or // whenever timeGetTime creates a rollover.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -