blob: 184ff82fa1b5f2f3c938dd8c3995c6c4f34b5429 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
Dan Sinclairf766ad22016-03-14 13:51:24 -04007#include "fpdfsdk/javascript/JS_Value.h"
Tom Sepez37458412015-10-06 11:33:46 -07008
Tom Sepez39bfe122015-09-17 15:25:23 -07009#include <time.h>
Dan Sinclair3ebd1212016-03-09 09:59:23 -050010
Tom Sepezbd932572016-01-29 09:10:41 -080011#include <algorithm>
Tom Sepez39bfe122015-09-17 15:25:23 -070012#include <cmath>
13#include <limits>
Dan Sinclair3ebd1212016-03-09 09:59:23 -050014#include <vector>
Tom Sepez39bfe122015-09-17 15:25:23 -070015
Dan Sinclairf766ad22016-03-14 13:51:24 -040016#include "fpdfsdk/javascript/Document.h"
17#include "fpdfsdk/javascript/JS_Define.h"
18#include "fpdfsdk/javascript/JS_Object.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070019
tsepezfbf52c22016-07-25 11:17:07 -070020namespace {
21
22const uint32_t g_nan[2] = {0, 0x7FF80000};
23
24double GetNan() {
Tom Sepez39bfe122015-09-17 15:25:23 -070025 return *(double*)g_nan;
26}
27
tsepezfbf52c22016-07-25 11:17:07 -070028double
29MakeDate(int year, int mon, int day, int hour, int min, int sec, int ms) {
30 return JS_MakeDate(JS_MakeDay(year, mon, day),
31 JS_MakeTime(hour, min, sec, ms));
32}
33
Lei Zhangab5939e2017-06-16 02:23:18 -070034double GetLocalTZA() {
35 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
36 return 0;
37 time_t t = 0;
38 time(&t);
39 localtime(&t);
Tom Sepeza2da7c52017-08-03 13:34:08 -070040#if defined(_MSC_VER)
41 // In gcc 'timezone' is a global variable declared in time.h. In VC++, that
42 // variable was removed in VC++ 2015, with _get_timezone replacing it.
Lei Zhangab5939e2017-06-16 02:23:18 -070043 long timezone = 0;
44 _get_timezone(&timezone);
45#endif
46 return (double)(-(timezone * 1000));
47}
48
49int GetDaylightSavingTA(double d) {
50 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
51 return 0;
52 time_t t = (time_t)(d / 1000);
53 struct tm* tmp = localtime(&t);
54 if (!tmp)
55 return 0;
56 if (tmp->tm_isdst > 0)
57 // One hour.
58 return (int)60 * 60 * 1000;
59 return 0;
60}
61
62double Mod(double x, double y) {
63 double r = fmod(x, y);
64 if (r < 0)
65 r += y;
66 return r;
67}
68
69int IsFinite(double v) {
Tom Sepeza2da7c52017-08-03 13:34:08 -070070#if defined(_MSC_VER)
Lei Zhangab5939e2017-06-16 02:23:18 -070071 return ::_finite(v);
72#else
73 return std::fabs(v) < std::numeric_limits<double>::max();
74#endif
75}
76
77double ToInteger(double n) {
78 return (n >= 0) ? floor(n) : -floor(-n);
79}
80
81bool IsLeapYear(int year) {
82 return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
83}
84
85int DayFromYear(int y) {
86 return (int)(365 * (y - 1970.0) + floor((y - 1969.0) / 4) -
87 floor((y - 1901.0) / 100) + floor((y - 1601.0) / 400));
88}
89
90double TimeFromYear(int y) {
91 return 86400000.0 * DayFromYear(y);
92}
93
94static const uint16_t daysMonth[12] = {0, 31, 59, 90, 120, 151,
95 181, 212, 243, 273, 304, 334};
96static const uint16_t leapDaysMonth[12] = {0, 31, 60, 91, 121, 152,
97 182, 213, 244, 274, 305, 335};
98
99double TimeFromYearMonth(int y, int m) {
100 const uint16_t* pMonth = IsLeapYear(y) ? leapDaysMonth : daysMonth;
101 return TimeFromYear(y) + ((double)pMonth[m]) * 86400000;
102}
103
104int Day(double t) {
105 return (int)floor(t / 86400000);
106}
107
108int YearFromTime(double t) {
109 // estimate the time.
110 int y = 1970 + static_cast<int>(t / (365.2425 * 86400000));
111 if (TimeFromYear(y) <= t) {
112 while (TimeFromYear(y + 1) <= t)
113 y++;
114 } else {
115 while (TimeFromYear(y) > t)
116 y--;
117 }
118 return y;
119}
120
121int DayWithinYear(double t) {
122 int year = YearFromTime(t);
123 int day = Day(t);
124 return day - DayFromYear(year);
125}
126
127int MonthFromTime(double t) {
128 int day = DayWithinYear(t);
129 int year = YearFromTime(t);
130 if (0 <= day && day < 31)
131 return 0;
132 if (31 <= day && day < 59 + IsLeapYear(year))
133 return 1;
134 if ((59 + IsLeapYear(year)) <= day && day < (90 + IsLeapYear(year)))
135 return 2;
136 if ((90 + IsLeapYear(year)) <= day && day < (120 + IsLeapYear(year)))
137 return 3;
138 if ((120 + IsLeapYear(year)) <= day && day < (151 + IsLeapYear(year)))
139 return 4;
140 if ((151 + IsLeapYear(year)) <= day && day < (181 + IsLeapYear(year)))
141 return 5;
142 if ((181 + IsLeapYear(year)) <= day && day < (212 + IsLeapYear(year)))
143 return 6;
144 if ((212 + IsLeapYear(year)) <= day && day < (243 + IsLeapYear(year)))
145 return 7;
146 if ((243 + IsLeapYear(year)) <= day && day < (273 + IsLeapYear(year)))
147 return 8;
148 if ((273 + IsLeapYear(year)) <= day && day < (304 + IsLeapYear(year)))
149 return 9;
150 if ((304 + IsLeapYear(year)) <= day && day < (334 + IsLeapYear(year)))
151 return 10;
152 if ((334 + IsLeapYear(year)) <= day && day < (365 + IsLeapYear(year)))
153 return 11;
154
155 return -1;
156}
157
158int DateFromTime(double t) {
159 int day = DayWithinYear(t);
160 int year = YearFromTime(t);
161 int leap = IsLeapYear(year);
162 int month = MonthFromTime(t);
163 switch (month) {
164 case 0:
165 return day + 1;
166 case 1:
167 return day - 30;
168 case 2:
169 return day - 58 - leap;
170 case 3:
171 return day - 89 - leap;
172 case 4:
173 return day - 119 - leap;
174 case 5:
175 return day - 150 - leap;
176 case 6:
177 return day - 180 - leap;
178 case 7:
179 return day - 211 - leap;
180 case 8:
181 return day - 242 - leap;
182 case 9:
183 return day - 272 - leap;
184 case 10:
185 return day - 303 - leap;
186 case 11:
187 return day - 333 - leap;
188 default:
189 return 0;
190 }
191}
192
tsepezfbf52c22016-07-25 11:17:07 -0700193} // namespace
194
tsepezf3dc8c62016-08-10 06:29:29 -0700195CJS_Value::CJS_Value(CJS_Runtime* pRuntime) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700196
tsepez40faa792016-07-15 17:58:02 -0700197CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue)
tsepezf3dc8c62016-08-10 06:29:29 -0700198 : m_pValue(pValue) {}
Tom Sepez67fd5df2015-10-08 12:24:19 -0700199
200CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const int& iValue)
tsepezb4694242016-08-15 16:44:55 -0700201 : m_pValue(pRuntime->NewNumber(iValue)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700202
Tom Sepez67fd5df2015-10-08 12:24:19 -0700203CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const bool& bValue)
tsepezb4694242016-08-15 16:44:55 -0700204 : m_pValue(pRuntime->NewBoolean(bValue)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700205
Tom Sepez67fd5df2015-10-08 12:24:19 -0700206CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const float& fValue)
tsepezb4694242016-08-15 16:44:55 -0700207 : m_pValue(pRuntime->NewNumber(fValue)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700208
Tom Sepez67fd5df2015-10-08 12:24:19 -0700209CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const double& dValue)
tsepezb4694242016-08-15 16:44:55 -0700210 : m_pValue(pRuntime->NewNumber(dValue)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700211
tsepezf3dc8c62016-08-10 06:29:29 -0700212CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pObj) {
213 if (pObj)
214 m_pValue = pObj->ToV8Object();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700215}
216
Dan Sinclair812e96c2017-03-13 16:43:37 -0400217CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const wchar_t* pWstr)
tsepezb4694242016-08-15 16:44:55 -0700218 : m_pValue(pRuntime->NewString(pWstr)) {}
Tom Sepezf79a69c2014-10-30 13:23:42 -0700219
Dan Sinclair812e96c2017-03-13 16:43:37 -0400220CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const char* pStr)
tsepezb4694242016-08-15 16:44:55 -0700221 : m_pValue(pRuntime->NewString(CFX_WideString::FromLocal(pStr).c_str())) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700222
tsepeze5aff742016-08-08 09:49:42 -0700223CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const CJS_Array& array)
tsepezb4694242016-08-15 16:44:55 -0700224 : m_pValue(array.ToV8Array(pRuntime)) {}
tsepezf3dc8c62016-08-10 06:29:29 -0700225
226CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const CJS_Date& date)
tsepezb4694242016-08-15 16:44:55 -0700227 : m_pValue(date.ToV8Date(pRuntime)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700228
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700229CJS_Value::~CJS_Value() {}
230
weili625ad662016-06-15 11:21:33 -0700231CJS_Value::CJS_Value(const CJS_Value& other) = default;
232
tsepez40faa792016-07-15 17:58:02 -0700233void CJS_Value::Attach(v8::Local<v8::Value> pValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700234 m_pValue = pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700235}
236
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237void CJS_Value::Detach() {
238 m_pValue = v8::Local<v8::Value>();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700239}
240
tsepezb4694242016-08-15 16:44:55 -0700241int CJS_Value::ToInt(CJS_Runtime* pRuntime) const {
242 return pRuntime->ToInt32(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700243}
244
tsepezb4694242016-08-15 16:44:55 -0700245bool CJS_Value::ToBool(CJS_Runtime* pRuntime) const {
246 return pRuntime->ToBoolean(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700247}
248
tsepezb4694242016-08-15 16:44:55 -0700249double CJS_Value::ToDouble(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800250 return pRuntime->ToDouble(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700251}
252
tsepezb4694242016-08-15 16:44:55 -0700253float CJS_Value::ToFloat(CJS_Runtime* pRuntime) const {
254 return (float)ToDouble(pRuntime);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700255}
256
tsepezb4694242016-08-15 16:44:55 -0700257CJS_Object* CJS_Value::ToCJSObject(CJS_Runtime* pRuntime) const {
258 v8::Local<v8::Object> pObj = pRuntime->ToObject(m_pValue);
259 return static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(pObj));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700260}
261
tsepezb4694242016-08-15 16:44:55 -0700262v8::Local<v8::Object> CJS_Value::ToV8Object(CJS_Runtime* pRuntime) const {
263 return pRuntime->ToObject(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700264}
265
tsepezb4694242016-08-15 16:44:55 -0700266CFX_WideString CJS_Value::ToCFXWideString(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800267 return pRuntime->ToWideString(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700268}
269
tsepezb4694242016-08-15 16:44:55 -0700270CFX_ByteString CJS_Value::ToCFXByteString(CJS_Runtime* pRuntime) const {
271 return CFX_ByteString::FromUnicode(ToCFXWideString(pRuntime));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700272}
273
tsepezb4694242016-08-15 16:44:55 -0700274v8::Local<v8::Value> CJS_Value::ToV8Value(CJS_Runtime* pRuntime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275 return m_pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700276}
277
tsepezb4694242016-08-15 16:44:55 -0700278v8::Local<v8::Array> CJS_Value::ToV8Array(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800279 return pRuntime->ToArray(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700280}
281
tsepezf3dc8c62016-08-10 06:29:29 -0700282void CJS_Value::SetNull(CJS_Runtime* pRuntime) {
tsepezb4694242016-08-15 16:44:55 -0700283 m_pValue = pRuntime->NewNull();
tsepezf3dc8c62016-08-10 06:29:29 -0700284}
285
tsepezb4694242016-08-15 16:44:55 -0700286void CJS_Value::MaybeCoerceToNumber(CJS_Runtime* pRuntime) {
Tom Sepez4246b002016-01-20 11:48:29 -0800287 bool bAllowNaN = false;
tsepez40faa792016-07-15 17:58:02 -0700288 if (GetType() == VT_string) {
tsepezb4694242016-08-15 16:44:55 -0700289 CFX_ByteString bstr = ToCFXByteString(pRuntime);
Tom Sepez4246b002016-01-20 11:48:29 -0800290 if (bstr.GetLength() == 0)
291 return;
292 if (bstr == "NaN")
293 bAllowNaN = true;
294 }
tsepezb4694242016-08-15 16:44:55 -0700295 v8::Isolate* pIsolate = pRuntime->GetIsolate();
tsepezf3dc8c62016-08-10 06:29:29 -0700296 v8::TryCatch try_catch(pIsolate);
Tom Sepez4246b002016-01-20 11:48:29 -0800297 v8::MaybeLocal<v8::Number> maybeNum =
tsepezf3dc8c62016-08-10 06:29:29 -0700298 m_pValue->ToNumber(pIsolate->GetCurrentContext());
Tom Sepez4246b002016-01-20 11:48:29 -0800299 if (maybeNum.IsEmpty())
300 return;
301 v8::Local<v8::Number> num = maybeNum.ToLocalChecked();
302 if (std::isnan(num->Value()) && !bAllowNaN)
303 return;
304 m_pValue = num;
Tom Sepez4246b002016-01-20 11:48:29 -0800305}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700306
tsepez40faa792016-07-15 17:58:02 -0700307// static
308CJS_Value::Type CJS_Value::GetValueType(v8::Local<v8::Value> value) {
309 if (value.IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310 return VT_unknown;
tsepez40faa792016-07-15 17:58:02 -0700311 if (value->IsString())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700312 return VT_string;
tsepez40faa792016-07-15 17:58:02 -0700313 if (value->IsNumber())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700314 return VT_number;
tsepez40faa792016-07-15 17:58:02 -0700315 if (value->IsBoolean())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700316 return VT_boolean;
tsepez40faa792016-07-15 17:58:02 -0700317 if (value->IsDate())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700318 return VT_date;
tsepez40faa792016-07-15 17:58:02 -0700319 if (value->IsObject())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700320 return VT_object;
tsepez40faa792016-07-15 17:58:02 -0700321 if (value->IsNull())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700322 return VT_null;
tsepez40faa792016-07-15 17:58:02 -0700323 if (value->IsUndefined())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700324 return VT_undefined;
325 return VT_unknown;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700326}
327
tsepezf3dc8c62016-08-10 06:29:29 -0700328bool CJS_Value::IsArrayObject() const {
329 return !m_pValue.IsEmpty() && m_pValue->IsArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700330}
331
tsepezf3dc8c62016-08-10 06:29:29 -0700332bool CJS_Value::IsDateObject() const {
333 return !m_pValue.IsEmpty() && m_pValue->IsDate();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700334}
335
tsepezb4694242016-08-15 16:44:55 -0700336bool CJS_Value::ConvertToArray(CJS_Runtime* pRuntime, CJS_Array& array) const {
tsepezf3dc8c62016-08-10 06:29:29 -0700337 if (!IsArrayObject())
338 return false;
tsepezb4694242016-08-15 16:44:55 -0700339 array.Attach(pRuntime->ToArray(m_pValue));
tsepezf3dc8c62016-08-10 06:29:29 -0700340 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700341}
342
tsepezb4694242016-08-15 16:44:55 -0700343bool CJS_Value::ConvertToDate(CJS_Runtime* pRuntime, CJS_Date& date) const {
tsepezf3dc8c62016-08-10 06:29:29 -0700344 if (!IsDateObject())
345 return false;
346 v8::Local<v8::Value> mutable_value = m_pValue;
347 date.Attach(mutable_value.As<v8::Date>());
348 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700349}
350
Tom Sepez67fd5df2015-10-08 12:24:19 -0700351CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime)
tsepezf3dc8c62016-08-10 06:29:29 -0700352 : m_bIsSetting(0), m_Value(pRuntime), m_pJSRuntime(pRuntime) {}
353
354CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime, const CJS_Value& value)
355 : m_bIsSetting(0), m_Value(value), m_pJSRuntime(pRuntime) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700356
Dan Sinclairf766ad22016-03-14 13:51:24 -0400357CJS_PropValue::~CJS_PropValue() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700358
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700359void CJS_PropValue::operator<<(int iValue) {
360 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700361 m_Value = CJS_Value(m_pJSRuntime.Get(), iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700362}
363
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700364void CJS_PropValue::operator>>(int& iValue) const {
365 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700366 iValue = m_Value.ToInt(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700367}
368
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700369void CJS_PropValue::operator<<(bool bValue) {
370 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700371 m_Value = CJS_Value(m_pJSRuntime.Get(), bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700372}
373
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700374void CJS_PropValue::operator>>(bool& bValue) const {
375 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700376 bValue = m_Value.ToBool(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700377}
378
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700379void CJS_PropValue::operator<<(double dValue) {
380 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700381 m_Value = CJS_Value(m_pJSRuntime.Get(), dValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700382}
383
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700384void CJS_PropValue::operator>>(double& dValue) const {
385 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700386 dValue = m_Value.ToDouble(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700387}
388
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700389void CJS_PropValue::operator<<(CJS_Object* pObj) {
390 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700391 m_Value = CJS_Value(m_pJSRuntime.Get(), pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700392}
393
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700394void CJS_PropValue::operator>>(CJS_Object*& ppObj) const {
395 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700396 ppObj = m_Value.ToCJSObject(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700397}
398
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700399void CJS_PropValue::operator<<(CJS_Document* pJsDoc) {
400 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700401 m_Value = CJS_Value(m_pJSRuntime.Get(), pJsDoc);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700402}
403
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700404void CJS_PropValue::operator>>(CJS_Document*& ppJsDoc) const {
405 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700406 ppJsDoc = static_cast<CJS_Document*>(m_Value.ToCJSObject(m_pJSRuntime.Get()));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700407}
408
Tom Sepez808a99e2015-09-10 12:28:37 -0700409void CJS_PropValue::operator<<(v8::Local<v8::Object> pObj) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700410 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700411 m_Value = CJS_Value(m_pJSRuntime.Get(), pObj);
JUN FANG33f6f0d2015-04-06 12:39:51 -0700412}
413
Tom Sepez808a99e2015-09-10 12:28:37 -0700414void CJS_PropValue::operator>>(v8::Local<v8::Object>& ppObj) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700415 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700416 ppObj = m_Value.ToV8Object(m_pJSRuntime.Get());
JUN FANG33f6f0d2015-04-06 12:39:51 -0700417}
418
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500419void CJS_PropValue::operator<<(CFX_ByteString str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700420 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700421 m_Value = CJS_Value(m_pJSRuntime.Get(), str.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700422}
423
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500424void CJS_PropValue::operator>>(CFX_ByteString& str) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700425 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700426 str = m_Value.ToCFXByteString(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700427}
428
Dan Sinclair812e96c2017-03-13 16:43:37 -0400429void CJS_PropValue::operator<<(const wchar_t* str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700430 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700431 m_Value = CJS_Value(m_pJSRuntime.Get(), str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700432}
433
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700434void CJS_PropValue::operator>>(CFX_WideString& wide_string) const {
435 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700436 wide_string = m_Value.ToCFXWideString(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700437}
438
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700439void CJS_PropValue::operator<<(CFX_WideString wide_string) {
440 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700441 m_Value = CJS_Value(m_pJSRuntime.Get(), wide_string.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700442}
443
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700444void CJS_PropValue::operator>>(CJS_Array& array) const {
445 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700446 m_Value.ConvertToArray(m_pJSRuntime.Get(), array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700447}
448
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700449void CJS_PropValue::operator<<(CJS_Array& array) {
450 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700451 m_Value = CJS_Value(m_pJSRuntime.Get(), array.ToV8Array(m_pJSRuntime.Get()));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700452}
453
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700454void CJS_PropValue::operator>>(CJS_Date& date) const {
455 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700456 m_Value.ConvertToDate(m_pJSRuntime.Get(), date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700457}
458
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700459void CJS_PropValue::operator<<(CJS_Date& date) {
460 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700461 m_Value = CJS_Value(m_pJSRuntime.Get(), date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700462}
463
tsepeze5aff742016-08-08 09:49:42 -0700464CJS_Array::CJS_Array() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700465
weili625ad662016-06-15 11:21:33 -0700466CJS_Array::CJS_Array(const CJS_Array& other) = default;
467
tsepeze5aff742016-08-08 09:49:42 -0700468CJS_Array::~CJS_Array() {}
469
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700470void CJS_Array::Attach(v8::Local<v8::Array> pArray) {
471 m_pArray = pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700472}
473
tsepezb4694242016-08-15 16:44:55 -0700474void CJS_Array::GetElement(CJS_Runtime* pRuntime,
tsepeze5aff742016-08-08 09:49:42 -0700475 unsigned index,
476 CJS_Value& value) const {
477 if (!m_pArray.IsEmpty())
tsepezb4694242016-08-15 16:44:55 -0700478 value.Attach(pRuntime->GetArrayElement(m_pArray, index));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700479}
480
tsepezb4694242016-08-15 16:44:55 -0700481void CJS_Array::SetElement(CJS_Runtime* pRuntime,
tsepeze5aff742016-08-08 09:49:42 -0700482 unsigned index,
483 const CJS_Value& value) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700484 if (m_pArray.IsEmpty())
tsepezb4694242016-08-15 16:44:55 -0700485 m_pArray = pRuntime->NewArray();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700486
tsepezb4694242016-08-15 16:44:55 -0700487 pRuntime->PutArrayElement(m_pArray, index, value.ToV8Value(pRuntime));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700488}
489
tsepezb4694242016-08-15 16:44:55 -0700490int CJS_Array::GetLength(CJS_Runtime* pRuntime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700491 if (m_pArray.IsEmpty())
492 return 0;
tsepezb4694242016-08-15 16:44:55 -0700493 return pRuntime->GetArrayLength(m_pArray);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700494}
495
tsepezb4694242016-08-15 16:44:55 -0700496v8::Local<v8::Array> CJS_Array::ToV8Array(CJS_Runtime* pRuntime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700497 if (m_pArray.IsEmpty())
tsepezb4694242016-08-15 16:44:55 -0700498 m_pArray = pRuntime->NewArray();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700499
500 return m_pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700501}
502
tsepezf3c88322016-08-09 07:30:38 -0700503CJS_Date::CJS_Date() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700504
tsepezb4694242016-08-15 16:44:55 -0700505CJS_Date::CJS_Date(CJS_Runtime* pRuntime, double dMsecTime)
506 : m_pDate(pRuntime->NewDate(dMsecTime)) {}
Tom Sepez67fd5df2015-10-08 12:24:19 -0700507
tsepezb4694242016-08-15 16:44:55 -0700508CJS_Date::CJS_Date(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700509 int year,
510 int mon,
511 int day,
512 int hour,
513 int min,
Tom Sepez67fd5df2015-10-08 12:24:19 -0700514 int sec)
tsepezb4694242016-08-15 16:44:55 -0700515 : m_pDate(pRuntime->NewDate(MakeDate(year, mon, day, hour, min, sec, 0))) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700516
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700517CJS_Date::~CJS_Date() {}
518
tsepezb4694242016-08-15 16:44:55 -0700519bool CJS_Date::IsValidDate(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800520 return !m_pDate.IsEmpty() && !JS_PortIsNan(pRuntime->ToDouble(m_pDate));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700521}
522
tsepez135b9982016-08-05 09:32:50 -0700523void CJS_Date::Attach(v8::Local<v8::Date> pDate) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700524 m_pDate = pDate;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700525}
526
tsepezb4694242016-08-15 16:44:55 -0700527int CJS_Date::GetYear(CJS_Runtime* pRuntime) const {
528 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700529 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700530
tsepeze6cf0132017-01-18 14:38:18 -0800531 return JS_GetYearFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700532}
533
tsepezb4694242016-08-15 16:44:55 -0700534void CJS_Date::SetYear(CJS_Runtime* pRuntime, int iYear) {
535 m_pDate = pRuntime->NewDate(
536 MakeDate(iYear, GetMonth(pRuntime), GetDay(pRuntime), GetHours(pRuntime),
537 GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700538}
539
tsepezb4694242016-08-15 16:44:55 -0700540int CJS_Date::GetMonth(CJS_Runtime* pRuntime) const {
541 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700542 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700543
tsepeze6cf0132017-01-18 14:38:18 -0800544 return JS_GetMonthFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700545}
546
tsepezb4694242016-08-15 16:44:55 -0700547void CJS_Date::SetMonth(CJS_Runtime* pRuntime, int iMonth) {
548 m_pDate = pRuntime->NewDate(
549 MakeDate(GetYear(pRuntime), iMonth, GetDay(pRuntime), GetHours(pRuntime),
550 GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700551}
552
tsepezb4694242016-08-15 16:44:55 -0700553int CJS_Date::GetDay(CJS_Runtime* pRuntime) const {
554 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700555 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700556
tsepeze6cf0132017-01-18 14:38:18 -0800557 return JS_GetDayFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700558}
559
tsepezb4694242016-08-15 16:44:55 -0700560void CJS_Date::SetDay(CJS_Runtime* pRuntime, int iDay) {
561 m_pDate = pRuntime->NewDate(
562 MakeDate(GetYear(pRuntime), GetMonth(pRuntime), iDay, GetHours(pRuntime),
563 GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700564}
565
tsepezb4694242016-08-15 16:44:55 -0700566int CJS_Date::GetHours(CJS_Runtime* pRuntime) const {
567 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700568 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700569
tsepeze6cf0132017-01-18 14:38:18 -0800570 return JS_GetHourFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700571}
572
tsepezb4694242016-08-15 16:44:55 -0700573void CJS_Date::SetHours(CJS_Runtime* pRuntime, int iHours) {
574 m_pDate = pRuntime->NewDate(
575 MakeDate(GetYear(pRuntime), GetMonth(pRuntime), GetDay(pRuntime), iHours,
576 GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700577}
578
tsepezb4694242016-08-15 16:44:55 -0700579int CJS_Date::GetMinutes(CJS_Runtime* pRuntime) const {
580 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700581 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700582
tsepeze6cf0132017-01-18 14:38:18 -0800583 return JS_GetMinFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700584}
585
tsepezb4694242016-08-15 16:44:55 -0700586void CJS_Date::SetMinutes(CJS_Runtime* pRuntime, int minutes) {
587 m_pDate = pRuntime->NewDate(MakeDate(GetYear(pRuntime), GetMonth(pRuntime),
588 GetDay(pRuntime), GetHours(pRuntime),
589 minutes, GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700590}
591
tsepezb4694242016-08-15 16:44:55 -0700592int CJS_Date::GetSeconds(CJS_Runtime* pRuntime) const {
593 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700594 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700595
tsepeze6cf0132017-01-18 14:38:18 -0800596 return JS_GetSecFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700597}
598
tsepezb4694242016-08-15 16:44:55 -0700599void CJS_Date::SetSeconds(CJS_Runtime* pRuntime, int seconds) {
600 m_pDate = pRuntime->NewDate(MakeDate(GetYear(pRuntime), GetMonth(pRuntime),
601 GetDay(pRuntime), GetHours(pRuntime),
602 GetMinutes(pRuntime), seconds, 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700603}
604
tsepezb4694242016-08-15 16:44:55 -0700605double CJS_Date::ToDouble(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800606 return !m_pDate.IsEmpty() ? pRuntime->ToDouble(m_pDate) : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700607}
608
tsepezb4694242016-08-15 16:44:55 -0700609CFX_WideString CJS_Date::ToString(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800610 return !m_pDate.IsEmpty() ? pRuntime->ToWideString(m_pDate)
611 : CFX_WideString();
tsepezf3c88322016-08-09 07:30:38 -0700612}
tsepezfbf52c22016-07-25 11:17:07 -0700613
tsepezb4694242016-08-15 16:44:55 -0700614v8::Local<v8::Date> CJS_Date::ToV8Date(CJS_Runtime* pRuntime) const {
tsepezf3c88322016-08-09 07:30:38 -0700615 return m_pDate;
Tom Sepez39bfe122015-09-17 15:25:23 -0700616}
617
Tom Sepez39bfe122015-09-17 15:25:23 -0700618double JS_GetDateTime() {
619 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
620 return 0;
thestig1cd352e2016-06-07 17:53:06 -0700621 time_t t = time(nullptr);
Tom Sepez39bfe122015-09-17 15:25:23 -0700622 struct tm* pTm = localtime(&t);
623
624 int year = pTm->tm_year + 1900;
Lei Zhangab5939e2017-06-16 02:23:18 -0700625 double t1 = TimeFromYear(year);
Tom Sepez39bfe122015-09-17 15:25:23 -0700626
627 return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
628 pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
629}
630
631int JS_GetYearFromTime(double dt) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700632 return YearFromTime(dt);
Tom Sepez39bfe122015-09-17 15:25:23 -0700633}
634
635int JS_GetMonthFromTime(double dt) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700636 return MonthFromTime(dt);
Tom Sepez39bfe122015-09-17 15:25:23 -0700637}
638
639int JS_GetDayFromTime(double dt) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700640 return DateFromTime(dt);
Tom Sepez39bfe122015-09-17 15:25:23 -0700641}
642
643int JS_GetHourFromTime(double dt) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700644 return (int)Mod(floor(dt / (60 * 60 * 1000)), 24);
Tom Sepez39bfe122015-09-17 15:25:23 -0700645}
646
647int JS_GetMinFromTime(double dt) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700648 return (int)Mod(floor(dt / (60 * 1000)), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700649}
650
651int JS_GetSecFromTime(double dt) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700652 return (int)Mod(floor(dt / 1000), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700653}
654
tsepez018935c2016-04-15 13:15:12 -0700655double JS_DateParse(const CFX_WideString& str) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700656 v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
657 v8::Isolate::Scope isolate_scope(pIsolate);
658 v8::HandleScope scope(pIsolate);
659
660 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
661
662 // Use the built-in object method.
663 v8::Local<v8::Value> v =
664 context->Global()
665 ->Get(context, v8::String::NewFromUtf8(pIsolate, "Date",
666 v8::NewStringType::kNormal)
667 .ToLocalChecked())
668 .ToLocalChecked();
669 if (v->IsObject()) {
670 v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
671 v = o->Get(context, v8::String::NewFromUtf8(pIsolate, "parse",
672 v8::NewStringType::kNormal)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400673 .ToLocalChecked())
674 .ToLocalChecked();
Tom Sepez39bfe122015-09-17 15:25:23 -0700675 if (v->IsFunction()) {
676 v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);
Tom Sepez39bfe122015-09-17 15:25:23 -0700677 const int argc = 1;
Tom Sepezc6dc69f2017-02-23 09:53:09 -0800678 v8::Local<v8::Value> timeStr =
679 CJS_Runtime::CurrentRuntimeFromIsolate(pIsolate)->NewString(
680 str.AsStringC());
Tom Sepez39bfe122015-09-17 15:25:23 -0700681 v8::Local<v8::Value> argv[argc] = {timeStr};
682 v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
683 if (v->IsNumber()) {
684 double date = v->ToNumber(context).ToLocalChecked()->Value();
Lei Zhangab5939e2017-06-16 02:23:18 -0700685 if (!IsFinite(date))
Tom Sepez39bfe122015-09-17 15:25:23 -0700686 return date;
tsepez86a61dc2016-03-25 10:00:11 -0700687 return JS_LocalTime(date);
Tom Sepez39bfe122015-09-17 15:25:23 -0700688 }
689 }
690 }
691 return 0;
692}
693
694double JS_MakeDay(int nYear, int nMonth, int nDate) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700695 if (!IsFinite(nYear) || !IsFinite(nMonth) || !IsFinite(nDate))
Tom Sepez39bfe122015-09-17 15:25:23 -0700696 return GetNan();
Lei Zhangab5939e2017-06-16 02:23:18 -0700697 double y = ToInteger(nYear);
698 double m = ToInteger(nMonth);
699 double dt = ToInteger(nDate);
Dan Sinclair669a4182017-04-03 14:51:45 -0400700 double ym = y + floor((double)m / 12);
Lei Zhangab5939e2017-06-16 02:23:18 -0700701 double mn = Mod(m, 12);
Tom Sepez39bfe122015-09-17 15:25:23 -0700702
Lei Zhangab5939e2017-06-16 02:23:18 -0700703 double t = TimeFromYearMonth((int)ym, (int)mn);
Tom Sepez39bfe122015-09-17 15:25:23 -0700704
Lei Zhangab5939e2017-06-16 02:23:18 -0700705 if (YearFromTime(t) != ym || MonthFromTime(t) != mn || DateFromTime(t) != 1)
Tom Sepez39bfe122015-09-17 15:25:23 -0700706 return GetNan();
Lei Zhangab5939e2017-06-16 02:23:18 -0700707 return Day(t) + dt - 1;
Tom Sepez39bfe122015-09-17 15:25:23 -0700708}
709
710double JS_MakeTime(int nHour, int nMin, int nSec, int nMs) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700711 if (!IsFinite(nHour) || !IsFinite(nMin) || !IsFinite(nSec) || !IsFinite(nMs))
Tom Sepez39bfe122015-09-17 15:25:23 -0700712 return GetNan();
713
Lei Zhangab5939e2017-06-16 02:23:18 -0700714 double h = ToInteger(nHour);
715 double m = ToInteger(nMin);
716 double s = ToInteger(nSec);
717 double milli = ToInteger(nMs);
Tom Sepez39bfe122015-09-17 15:25:23 -0700718
719 return h * 3600000 + m * 60000 + s * 1000 + milli;
720}
721
722double JS_MakeDate(double day, double time) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700723 if (!IsFinite(day) || !IsFinite(time))
Tom Sepez39bfe122015-09-17 15:25:23 -0700724 return GetNan();
725
726 return day * 86400000 + time;
727}
728
729bool JS_PortIsNan(double d) {
730 return d != d;
731}
732
733double JS_LocalTime(double d) {
Lei Zhangab5939e2017-06-16 02:23:18 -0700734 return d + GetLocalTZA() + GetDaylightSavingTA(d);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700735}
Tom Sepezbd932572016-01-29 09:10:41 -0800736
737std::vector<CJS_Value> JS_ExpandKeywordParams(
738 CJS_Runtime* pRuntime,
739 const std::vector<CJS_Value>& originals,
740 size_t nKeywords,
741 ...) {
742 ASSERT(nKeywords);
743
744 std::vector<CJS_Value> result(nKeywords, CJS_Value(pRuntime));
745 size_t size = std::min(originals.size(), nKeywords);
746 for (size_t i = 0; i < size; ++i)
747 result[i] = originals[i];
748
749 if (originals.size() != 1 || originals[0].GetType() != CJS_Value::VT_object ||
750 originals[0].IsArrayObject()) {
751 return result;
752 }
tsepezb4694242016-08-15 16:44:55 -0700753 v8::Local<v8::Object> pObj = originals[0].ToV8Object(pRuntime);
Tom Sepezbd932572016-01-29 09:10:41 -0800754 result[0] = CJS_Value(pRuntime); // Make unknown.
755
756 va_list ap;
757 va_start(ap, nKeywords);
Wei Li89409932016-03-28 10:33:33 -0700758 for (size_t i = 0; i < nKeywords; ++i) {
Tom Sepezbd932572016-01-29 09:10:41 -0800759 const wchar_t* property = va_arg(ap, const wchar_t*);
tsepezb4694242016-08-15 16:44:55 -0700760 v8::Local<v8::Value> v8Value = pRuntime->GetObjectProperty(pObj, property);
Tom Sepezbd932572016-01-29 09:10:41 -0800761 if (!v8Value->IsUndefined())
tsepez40faa792016-07-15 17:58:02 -0700762 result[i] = CJS_Value(pRuntime, v8Value);
Tom Sepezbd932572016-01-29 09:10:41 -0800763 }
764 va_end(ap);
765 return result;
766}