blob: dba0b7611564ea7de4c5ac3e902b3ac54067bf1c [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
34} // namespace
35
tsepezf3dc8c62016-08-10 06:29:29 -070036CJS_Value::CJS_Value(CJS_Runtime* pRuntime) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -070037
tsepez40faa792016-07-15 17:58:02 -070038CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue)
tsepezf3dc8c62016-08-10 06:29:29 -070039 : m_pValue(pValue) {}
Tom Sepez67fd5df2015-10-08 12:24:19 -070040
41CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const int& iValue)
tsepezb4694242016-08-15 16:44:55 -070042 : m_pValue(pRuntime->NewNumber(iValue)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070043
Tom Sepez67fd5df2015-10-08 12:24:19 -070044CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const bool& bValue)
tsepezb4694242016-08-15 16:44:55 -070045 : m_pValue(pRuntime->NewBoolean(bValue)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070046
Tom Sepez67fd5df2015-10-08 12:24:19 -070047CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const float& fValue)
tsepezb4694242016-08-15 16:44:55 -070048 : m_pValue(pRuntime->NewNumber(fValue)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070049
Tom Sepez67fd5df2015-10-08 12:24:19 -070050CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const double& dValue)
tsepezb4694242016-08-15 16:44:55 -070051 : m_pValue(pRuntime->NewNumber(dValue)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070052
tsepezf3dc8c62016-08-10 06:29:29 -070053CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pObj) {
54 if (pObj)
55 m_pValue = pObj->ToV8Object();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070056}
57
Dan Sinclair812e96c2017-03-13 16:43:37 -040058CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const wchar_t* pWstr)
tsepezb4694242016-08-15 16:44:55 -070059 : m_pValue(pRuntime->NewString(pWstr)) {}
Tom Sepezf79a69c2014-10-30 13:23:42 -070060
Dan Sinclair812e96c2017-03-13 16:43:37 -040061CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const char* pStr)
tsepezb4694242016-08-15 16:44:55 -070062 : m_pValue(pRuntime->NewString(CFX_WideString::FromLocal(pStr).c_str())) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070063
tsepeze5aff742016-08-08 09:49:42 -070064CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const CJS_Array& array)
tsepezb4694242016-08-15 16:44:55 -070065 : m_pValue(array.ToV8Array(pRuntime)) {}
tsepezf3dc8c62016-08-10 06:29:29 -070066
67CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const CJS_Date& date)
tsepezb4694242016-08-15 16:44:55 -070068 : m_pValue(date.ToV8Date(pRuntime)) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070069
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070CJS_Value::~CJS_Value() {}
71
weili625ad662016-06-15 11:21:33 -070072CJS_Value::CJS_Value(const CJS_Value& other) = default;
73
tsepez40faa792016-07-15 17:58:02 -070074void CJS_Value::Attach(v8::Local<v8::Value> pValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075 m_pValue = pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070076}
77
Nico Weber9d8ec5a2015-08-04 13:00:21 -070078void CJS_Value::Detach() {
79 m_pValue = v8::Local<v8::Value>();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070080}
81
tsepezb4694242016-08-15 16:44:55 -070082int CJS_Value::ToInt(CJS_Runtime* pRuntime) const {
83 return pRuntime->ToInt32(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070084}
85
tsepezb4694242016-08-15 16:44:55 -070086bool CJS_Value::ToBool(CJS_Runtime* pRuntime) const {
87 return pRuntime->ToBoolean(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070088}
89
tsepezb4694242016-08-15 16:44:55 -070090double CJS_Value::ToDouble(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -080091 return pRuntime->ToDouble(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070092}
93
tsepezb4694242016-08-15 16:44:55 -070094float CJS_Value::ToFloat(CJS_Runtime* pRuntime) const {
95 return (float)ToDouble(pRuntime);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070096}
97
tsepezb4694242016-08-15 16:44:55 -070098CJS_Object* CJS_Value::ToCJSObject(CJS_Runtime* pRuntime) const {
99 v8::Local<v8::Object> pObj = pRuntime->ToObject(m_pValue);
100 return static_cast<CJS_Object*>(pRuntime->GetObjectPrivate(pObj));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700101}
102
tsepezb4694242016-08-15 16:44:55 -0700103v8::Local<v8::Object> CJS_Value::ToV8Object(CJS_Runtime* pRuntime) const {
104 return pRuntime->ToObject(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700105}
106
tsepezb4694242016-08-15 16:44:55 -0700107CFX_WideString CJS_Value::ToCFXWideString(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800108 return pRuntime->ToWideString(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700109}
110
tsepezb4694242016-08-15 16:44:55 -0700111CFX_ByteString CJS_Value::ToCFXByteString(CJS_Runtime* pRuntime) const {
112 return CFX_ByteString::FromUnicode(ToCFXWideString(pRuntime));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700113}
114
tsepezb4694242016-08-15 16:44:55 -0700115v8::Local<v8::Value> CJS_Value::ToV8Value(CJS_Runtime* pRuntime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116 return m_pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700117}
118
tsepezb4694242016-08-15 16:44:55 -0700119v8::Local<v8::Array> CJS_Value::ToV8Array(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800120 return pRuntime->ToArray(m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700121}
122
tsepezf3dc8c62016-08-10 06:29:29 -0700123void CJS_Value::SetNull(CJS_Runtime* pRuntime) {
tsepezb4694242016-08-15 16:44:55 -0700124 m_pValue = pRuntime->NewNull();
tsepezf3dc8c62016-08-10 06:29:29 -0700125}
126
tsepezb4694242016-08-15 16:44:55 -0700127void CJS_Value::MaybeCoerceToNumber(CJS_Runtime* pRuntime) {
Tom Sepez4246b002016-01-20 11:48:29 -0800128 bool bAllowNaN = false;
tsepez40faa792016-07-15 17:58:02 -0700129 if (GetType() == VT_string) {
tsepezb4694242016-08-15 16:44:55 -0700130 CFX_ByteString bstr = ToCFXByteString(pRuntime);
Tom Sepez4246b002016-01-20 11:48:29 -0800131 if (bstr.GetLength() == 0)
132 return;
133 if (bstr == "NaN")
134 bAllowNaN = true;
135 }
tsepezb4694242016-08-15 16:44:55 -0700136 v8::Isolate* pIsolate = pRuntime->GetIsolate();
tsepezf3dc8c62016-08-10 06:29:29 -0700137 v8::TryCatch try_catch(pIsolate);
Tom Sepez4246b002016-01-20 11:48:29 -0800138 v8::MaybeLocal<v8::Number> maybeNum =
tsepezf3dc8c62016-08-10 06:29:29 -0700139 m_pValue->ToNumber(pIsolate->GetCurrentContext());
Tom Sepez4246b002016-01-20 11:48:29 -0800140 if (maybeNum.IsEmpty())
141 return;
142 v8::Local<v8::Number> num = maybeNum.ToLocalChecked();
143 if (std::isnan(num->Value()) && !bAllowNaN)
144 return;
145 m_pValue = num;
Tom Sepez4246b002016-01-20 11:48:29 -0800146}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700147
tsepez40faa792016-07-15 17:58:02 -0700148// static
149CJS_Value::Type CJS_Value::GetValueType(v8::Local<v8::Value> value) {
150 if (value.IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700151 return VT_unknown;
tsepez40faa792016-07-15 17:58:02 -0700152 if (value->IsString())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153 return VT_string;
tsepez40faa792016-07-15 17:58:02 -0700154 if (value->IsNumber())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700155 return VT_number;
tsepez40faa792016-07-15 17:58:02 -0700156 if (value->IsBoolean())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157 return VT_boolean;
tsepez40faa792016-07-15 17:58:02 -0700158 if (value->IsDate())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 return VT_date;
tsepez40faa792016-07-15 17:58:02 -0700160 if (value->IsObject())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161 return VT_object;
tsepez40faa792016-07-15 17:58:02 -0700162 if (value->IsNull())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163 return VT_null;
tsepez40faa792016-07-15 17:58:02 -0700164 if (value->IsUndefined())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700165 return VT_undefined;
166 return VT_unknown;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700167}
168
tsepezf3dc8c62016-08-10 06:29:29 -0700169bool CJS_Value::IsArrayObject() const {
170 return !m_pValue.IsEmpty() && m_pValue->IsArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700171}
172
tsepezf3dc8c62016-08-10 06:29:29 -0700173bool CJS_Value::IsDateObject() const {
174 return !m_pValue.IsEmpty() && m_pValue->IsDate();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700175}
176
tsepezb4694242016-08-15 16:44:55 -0700177bool CJS_Value::ConvertToArray(CJS_Runtime* pRuntime, CJS_Array& array) const {
tsepezf3dc8c62016-08-10 06:29:29 -0700178 if (!IsArrayObject())
179 return false;
tsepezb4694242016-08-15 16:44:55 -0700180 array.Attach(pRuntime->ToArray(m_pValue));
tsepezf3dc8c62016-08-10 06:29:29 -0700181 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700182}
183
tsepezb4694242016-08-15 16:44:55 -0700184bool CJS_Value::ConvertToDate(CJS_Runtime* pRuntime, CJS_Date& date) const {
tsepezf3dc8c62016-08-10 06:29:29 -0700185 if (!IsDateObject())
186 return false;
187 v8::Local<v8::Value> mutable_value = m_pValue;
188 date.Attach(mutable_value.As<v8::Date>());
189 return true;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700190}
191
Tom Sepez67fd5df2015-10-08 12:24:19 -0700192CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime)
tsepezf3dc8c62016-08-10 06:29:29 -0700193 : m_bIsSetting(0), m_Value(pRuntime), m_pJSRuntime(pRuntime) {}
194
195CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime, const CJS_Value& value)
196 : m_bIsSetting(0), m_Value(value), m_pJSRuntime(pRuntime) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700197
Dan Sinclairf766ad22016-03-14 13:51:24 -0400198CJS_PropValue::~CJS_PropValue() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700199
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200void CJS_PropValue::operator<<(int iValue) {
201 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700202 m_Value = CJS_Value(m_pJSRuntime.Get(), iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700203}
204
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700205void CJS_PropValue::operator>>(int& iValue) const {
206 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700207 iValue = m_Value.ToInt(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700208}
209
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210void CJS_PropValue::operator<<(bool bValue) {
211 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700212 m_Value = CJS_Value(m_pJSRuntime.Get(), bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700213}
214
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700215void CJS_PropValue::operator>>(bool& bValue) const {
216 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700217 bValue = m_Value.ToBool(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700218}
219
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220void CJS_PropValue::operator<<(double dValue) {
221 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700222 m_Value = CJS_Value(m_pJSRuntime.Get(), dValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700223}
224
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225void CJS_PropValue::operator>>(double& dValue) const {
226 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700227 dValue = m_Value.ToDouble(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700228}
229
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230void CJS_PropValue::operator<<(CJS_Object* pObj) {
231 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700232 m_Value = CJS_Value(m_pJSRuntime.Get(), pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700233}
234
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235void CJS_PropValue::operator>>(CJS_Object*& ppObj) const {
236 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700237 ppObj = m_Value.ToCJSObject(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700238}
239
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700240void CJS_PropValue::operator<<(CJS_Document* pJsDoc) {
241 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700242 m_Value = CJS_Value(m_pJSRuntime.Get(), pJsDoc);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700243}
244
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700245void CJS_PropValue::operator>>(CJS_Document*& ppJsDoc) const {
246 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700247 ppJsDoc = static_cast<CJS_Document*>(m_Value.ToCJSObject(m_pJSRuntime.Get()));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700248}
249
Tom Sepez808a99e2015-09-10 12:28:37 -0700250void CJS_PropValue::operator<<(v8::Local<v8::Object> pObj) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700252 m_Value = CJS_Value(m_pJSRuntime.Get(), pObj);
JUN FANG33f6f0d2015-04-06 12:39:51 -0700253}
254
Tom Sepez808a99e2015-09-10 12:28:37 -0700255void CJS_PropValue::operator>>(v8::Local<v8::Object>& ppObj) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700256 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700257 ppObj = m_Value.ToV8Object(m_pJSRuntime.Get());
JUN FANG33f6f0d2015-04-06 12:39:51 -0700258}
259
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500260void CJS_PropValue::operator<<(CFX_ByteString str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700261 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700262 m_Value = CJS_Value(m_pJSRuntime.Get(), str.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700263}
264
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500265void CJS_PropValue::operator>>(CFX_ByteString& str) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700267 str = m_Value.ToCFXByteString(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700268}
269
Dan Sinclair812e96c2017-03-13 16:43:37 -0400270void CJS_PropValue::operator<<(const wchar_t* str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700271 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700272 m_Value = CJS_Value(m_pJSRuntime.Get(), str);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700273}
274
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275void CJS_PropValue::operator>>(CFX_WideString& wide_string) const {
276 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700277 wide_string = m_Value.ToCFXWideString(m_pJSRuntime.Get());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700278}
279
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280void CJS_PropValue::operator<<(CFX_WideString wide_string) {
281 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700282 m_Value = CJS_Value(m_pJSRuntime.Get(), wide_string.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700283}
284
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285void CJS_PropValue::operator>>(CJS_Array& array) const {
286 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700287 m_Value.ConvertToArray(m_pJSRuntime.Get(), array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700288}
289
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700290void CJS_PropValue::operator<<(CJS_Array& array) {
291 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700292 m_Value = CJS_Value(m_pJSRuntime.Get(), array.ToV8Array(m_pJSRuntime.Get()));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700293}
294
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700295void CJS_PropValue::operator>>(CJS_Date& date) const {
296 ASSERT(m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700297 m_Value.ConvertToDate(m_pJSRuntime.Get(), date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700298}
299
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300void CJS_PropValue::operator<<(CJS_Date& date) {
301 ASSERT(!m_bIsSetting);
Tom Sepez797ca5c2017-05-25 12:03:18 -0700302 m_Value = CJS_Value(m_pJSRuntime.Get(), date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700303}
304
tsepeze5aff742016-08-08 09:49:42 -0700305CJS_Array::CJS_Array() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700306
weili625ad662016-06-15 11:21:33 -0700307CJS_Array::CJS_Array(const CJS_Array& other) = default;
308
tsepeze5aff742016-08-08 09:49:42 -0700309CJS_Array::~CJS_Array() {}
310
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700311void CJS_Array::Attach(v8::Local<v8::Array> pArray) {
312 m_pArray = pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700313}
314
tsepezb4694242016-08-15 16:44:55 -0700315void CJS_Array::GetElement(CJS_Runtime* pRuntime,
tsepeze5aff742016-08-08 09:49:42 -0700316 unsigned index,
317 CJS_Value& value) const {
318 if (!m_pArray.IsEmpty())
tsepezb4694242016-08-15 16:44:55 -0700319 value.Attach(pRuntime->GetArrayElement(m_pArray, index));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700320}
321
tsepezb4694242016-08-15 16:44:55 -0700322void CJS_Array::SetElement(CJS_Runtime* pRuntime,
tsepeze5aff742016-08-08 09:49:42 -0700323 unsigned index,
324 const CJS_Value& value) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700325 if (m_pArray.IsEmpty())
tsepezb4694242016-08-15 16:44:55 -0700326 m_pArray = pRuntime->NewArray();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700327
tsepezb4694242016-08-15 16:44:55 -0700328 pRuntime->PutArrayElement(m_pArray, index, value.ToV8Value(pRuntime));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700329}
330
tsepezb4694242016-08-15 16:44:55 -0700331int CJS_Array::GetLength(CJS_Runtime* pRuntime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700332 if (m_pArray.IsEmpty())
333 return 0;
tsepezb4694242016-08-15 16:44:55 -0700334 return pRuntime->GetArrayLength(m_pArray);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700335}
336
tsepezb4694242016-08-15 16:44:55 -0700337v8::Local<v8::Array> CJS_Array::ToV8Array(CJS_Runtime* pRuntime) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700338 if (m_pArray.IsEmpty())
tsepezb4694242016-08-15 16:44:55 -0700339 m_pArray = pRuntime->NewArray();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700340
341 return m_pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700342}
343
tsepezf3c88322016-08-09 07:30:38 -0700344CJS_Date::CJS_Date() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700345
tsepezb4694242016-08-15 16:44:55 -0700346CJS_Date::CJS_Date(CJS_Runtime* pRuntime, double dMsecTime)
347 : m_pDate(pRuntime->NewDate(dMsecTime)) {}
Tom Sepez67fd5df2015-10-08 12:24:19 -0700348
tsepezb4694242016-08-15 16:44:55 -0700349CJS_Date::CJS_Date(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700350 int year,
351 int mon,
352 int day,
353 int hour,
354 int min,
Tom Sepez67fd5df2015-10-08 12:24:19 -0700355 int sec)
tsepezb4694242016-08-15 16:44:55 -0700356 : m_pDate(pRuntime->NewDate(MakeDate(year, mon, day, hour, min, sec, 0))) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700357
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700358CJS_Date::~CJS_Date() {}
359
tsepezb4694242016-08-15 16:44:55 -0700360bool CJS_Date::IsValidDate(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800361 return !m_pDate.IsEmpty() && !JS_PortIsNan(pRuntime->ToDouble(m_pDate));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700362}
363
tsepez135b9982016-08-05 09:32:50 -0700364void CJS_Date::Attach(v8::Local<v8::Date> pDate) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700365 m_pDate = pDate;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700366}
367
tsepezb4694242016-08-15 16:44:55 -0700368int CJS_Date::GetYear(CJS_Runtime* pRuntime) const {
369 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700370 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700371
tsepeze6cf0132017-01-18 14:38:18 -0800372 return JS_GetYearFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700373}
374
tsepezb4694242016-08-15 16:44:55 -0700375void CJS_Date::SetYear(CJS_Runtime* pRuntime, int iYear) {
376 m_pDate = pRuntime->NewDate(
377 MakeDate(iYear, GetMonth(pRuntime), GetDay(pRuntime), GetHours(pRuntime),
378 GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700379}
380
tsepezb4694242016-08-15 16:44:55 -0700381int CJS_Date::GetMonth(CJS_Runtime* pRuntime) const {
382 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700383 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700384
tsepeze6cf0132017-01-18 14:38:18 -0800385 return JS_GetMonthFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700386}
387
tsepezb4694242016-08-15 16:44:55 -0700388void CJS_Date::SetMonth(CJS_Runtime* pRuntime, int iMonth) {
389 m_pDate = pRuntime->NewDate(
390 MakeDate(GetYear(pRuntime), iMonth, GetDay(pRuntime), GetHours(pRuntime),
391 GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700392}
393
tsepezb4694242016-08-15 16:44:55 -0700394int CJS_Date::GetDay(CJS_Runtime* pRuntime) const {
395 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700396 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700397
tsepeze6cf0132017-01-18 14:38:18 -0800398 return JS_GetDayFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700399}
400
tsepezb4694242016-08-15 16:44:55 -0700401void CJS_Date::SetDay(CJS_Runtime* pRuntime, int iDay) {
402 m_pDate = pRuntime->NewDate(
403 MakeDate(GetYear(pRuntime), GetMonth(pRuntime), iDay, GetHours(pRuntime),
404 GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700405}
406
tsepezb4694242016-08-15 16:44:55 -0700407int CJS_Date::GetHours(CJS_Runtime* pRuntime) const {
408 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700409 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700410
tsepeze6cf0132017-01-18 14:38:18 -0800411 return JS_GetHourFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700412}
413
tsepezb4694242016-08-15 16:44:55 -0700414void CJS_Date::SetHours(CJS_Runtime* pRuntime, int iHours) {
415 m_pDate = pRuntime->NewDate(
416 MakeDate(GetYear(pRuntime), GetMonth(pRuntime), GetDay(pRuntime), iHours,
417 GetMinutes(pRuntime), GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700418}
419
tsepezb4694242016-08-15 16:44:55 -0700420int CJS_Date::GetMinutes(CJS_Runtime* pRuntime) const {
421 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700422 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700423
tsepeze6cf0132017-01-18 14:38:18 -0800424 return JS_GetMinFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700425}
426
tsepezb4694242016-08-15 16:44:55 -0700427void CJS_Date::SetMinutes(CJS_Runtime* pRuntime, int minutes) {
428 m_pDate = pRuntime->NewDate(MakeDate(GetYear(pRuntime), GetMonth(pRuntime),
429 GetDay(pRuntime), GetHours(pRuntime),
430 minutes, GetSeconds(pRuntime), 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700431}
432
tsepezb4694242016-08-15 16:44:55 -0700433int CJS_Date::GetSeconds(CJS_Runtime* pRuntime) const {
434 if (!IsValidDate(pRuntime))
tsepezfbf52c22016-07-25 11:17:07 -0700435 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700436
tsepeze6cf0132017-01-18 14:38:18 -0800437 return JS_GetSecFromTime(JS_LocalTime(pRuntime->ToDouble(m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700438}
439
tsepezb4694242016-08-15 16:44:55 -0700440void CJS_Date::SetSeconds(CJS_Runtime* pRuntime, int seconds) {
441 m_pDate = pRuntime->NewDate(MakeDate(GetYear(pRuntime), GetMonth(pRuntime),
442 GetDay(pRuntime), GetHours(pRuntime),
443 GetMinutes(pRuntime), seconds, 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700444}
445
tsepezb4694242016-08-15 16:44:55 -0700446double CJS_Date::ToDouble(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800447 return !m_pDate.IsEmpty() ? pRuntime->ToDouble(m_pDate) : 0.0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700448}
449
tsepezb4694242016-08-15 16:44:55 -0700450CFX_WideString CJS_Date::ToString(CJS_Runtime* pRuntime) const {
tsepeze6cf0132017-01-18 14:38:18 -0800451 return !m_pDate.IsEmpty() ? pRuntime->ToWideString(m_pDate)
452 : CFX_WideString();
tsepezf3c88322016-08-09 07:30:38 -0700453}
tsepezfbf52c22016-07-25 11:17:07 -0700454
tsepezb4694242016-08-15 16:44:55 -0700455v8::Local<v8::Date> CJS_Date::ToV8Date(CJS_Runtime* pRuntime) const {
tsepezf3c88322016-08-09 07:30:38 -0700456 return m_pDate;
Tom Sepez39bfe122015-09-17 15:25:23 -0700457}
458
459double _getLocalTZA() {
460 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
461 return 0;
462 time_t t = 0;
463 time(&t);
464 localtime(&t);
465#if _MSC_VER >= 1900
466 // In gcc and in Visual Studio prior to VS 2015 'timezone' is a global
467 // variable declared in time.h. That variable was deprecated and in VS 2015
468 // is removed, with _get_timezone replacing it.
469 long timezone = 0;
470 _get_timezone(&timezone);
471#endif
472 return (double)(-(timezone * 1000));
473}
474
475int _getDaylightSavingTA(double d) {
476 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
477 return 0;
478 time_t t = (time_t)(d / 1000);
479 struct tm* tmp = localtime(&t);
Lei Zhang412e9082015-12-14 18:34:00 -0800480 if (!tmp)
Tom Sepez39bfe122015-09-17 15:25:23 -0700481 return 0;
482 if (tmp->tm_isdst > 0)
483 // One hour.
484 return (int)60 * 60 * 1000;
485 return 0;
486}
487
488double _Mod(double x, double y) {
489 double r = fmod(x, y);
490 if (r < 0)
491 r += y;
492 return r;
493}
494
495int _isfinite(double v) {
496#if _MSC_VER
497 return ::_finite(v);
498#else
499 return std::fabs(v) < std::numeric_limits<double>::max();
500#endif
501}
502
503double _toInteger(double n) {
Dan Sinclair669a4182017-04-03 14:51:45 -0400504 return (n >= 0) ? floor(n) : -floor(-n);
Tom Sepez39bfe122015-09-17 15:25:23 -0700505}
506
507bool _isLeapYear(int year) {
508 return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
509}
510
511int _DayFromYear(int y) {
Dan Sinclair669a4182017-04-03 14:51:45 -0400512 return (int)(365 * (y - 1970.0) + floor((y - 1969.0) / 4) -
513 floor((y - 1901.0) / 100) + floor((y - 1601.0) / 400));
Tom Sepez39bfe122015-09-17 15:25:23 -0700514}
515
516double _TimeFromYear(int y) {
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800517 return 86400000.0 * _DayFromYear(y);
Tom Sepez39bfe122015-09-17 15:25:23 -0700518}
519
Tom Sepez4161c5c2016-03-21 12:26:54 -0700520static const uint16_t daysMonth[12] = {0, 31, 59, 90, 120, 151,
521 181, 212, 243, 273, 304, 334};
522static const uint16_t leapDaysMonth[12] = {0, 31, 60, 91, 121, 152,
523 182, 213, 244, 274, 305, 335};
524
Tom Sepez39bfe122015-09-17 15:25:23 -0700525double _TimeFromYearMonth(int y, int m) {
Tom Sepez4161c5c2016-03-21 12:26:54 -0700526 const uint16_t* pMonth = _isLeapYear(y) ? leapDaysMonth : daysMonth;
Tom Sepez39bfe122015-09-17 15:25:23 -0700527 return _TimeFromYear(y) + ((double)pMonth[m]) * 86400000;
528}
529
530int _Day(double t) {
Dan Sinclair669a4182017-04-03 14:51:45 -0400531 return (int)floor(t / 86400000);
Tom Sepez39bfe122015-09-17 15:25:23 -0700532}
533
534int _YearFromTime(double t) {
535 // estimate the time.
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800536 int y = 1970 + static_cast<int>(t / (365.2425 * 86400000));
Tom Sepez39bfe122015-09-17 15:25:23 -0700537 if (_TimeFromYear(y) <= t) {
538 while (_TimeFromYear(y + 1) <= t)
539 y++;
Dan Sinclair738b08c2016-03-01 14:45:20 -0500540 } else {
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800541 while (_TimeFromYear(y) > t)
Tom Sepez39bfe122015-09-17 15:25:23 -0700542 y--;
Dan Sinclair738b08c2016-03-01 14:45:20 -0500543 }
Tom Sepez39bfe122015-09-17 15:25:23 -0700544 return y;
545}
546
547int _DayWithinYear(double t) {
548 int year = _YearFromTime(t);
549 int day = _Day(t);
550 return day - _DayFromYear(year);
551}
552
553int _MonthFromTime(double t) {
554 int day = _DayWithinYear(t);
555 int year = _YearFromTime(t);
556 if (0 <= day && day < 31)
557 return 0;
558 if (31 <= day && day < 59 + _isLeapYear(year))
559 return 1;
560 if ((59 + _isLeapYear(year)) <= day && day < (90 + _isLeapYear(year)))
561 return 2;
562 if ((90 + _isLeapYear(year)) <= day && day < (120 + _isLeapYear(year)))
563 return 3;
564 if ((120 + _isLeapYear(year)) <= day && day < (151 + _isLeapYear(year)))
565 return 4;
566 if ((151 + _isLeapYear(year)) <= day && day < (181 + _isLeapYear(year)))
567 return 5;
568 if ((181 + _isLeapYear(year)) <= day && day < (212 + _isLeapYear(year)))
569 return 6;
570 if ((212 + _isLeapYear(year)) <= day && day < (243 + _isLeapYear(year)))
571 return 7;
572 if ((243 + _isLeapYear(year)) <= day && day < (273 + _isLeapYear(year)))
573 return 8;
574 if ((273 + _isLeapYear(year)) <= day && day < (304 + _isLeapYear(year)))
575 return 9;
576 if ((304 + _isLeapYear(year)) <= day && day < (334 + _isLeapYear(year)))
577 return 10;
578 if ((334 + _isLeapYear(year)) <= day && day < (365 + _isLeapYear(year)))
579 return 11;
580
581 return -1;
582}
583
584int _DateFromTime(double t) {
585 int day = _DayWithinYear(t);
586 int year = _YearFromTime(t);
weili12367cb2016-06-03 11:22:16 -0700587 int leap = _isLeapYear(year);
Tom Sepez39bfe122015-09-17 15:25:23 -0700588 int month = _MonthFromTime(t);
589 switch (month) {
590 case 0:
591 return day + 1;
592 case 1:
593 return day - 30;
594 case 2:
595 return day - 58 - leap;
596 case 3:
597 return day - 89 - leap;
598 case 4:
599 return day - 119 - leap;
600 case 5:
601 return day - 150 - leap;
602 case 6:
603 return day - 180 - leap;
604 case 7:
605 return day - 211 - leap;
606 case 8:
607 return day - 242 - leap;
608 case 9:
609 return day - 272 - leap;
610 case 10:
611 return day - 303 - leap;
612 case 11:
613 return day - 333 - leap;
614 default:
615 return 0;
616 }
617}
618
619double JS_GetDateTime() {
620 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
621 return 0;
thestig1cd352e2016-06-07 17:53:06 -0700622 time_t t = time(nullptr);
Tom Sepez39bfe122015-09-17 15:25:23 -0700623 struct tm* pTm = localtime(&t);
624
625 int year = pTm->tm_year + 1900;
626 double t1 = _TimeFromYear(year);
627
628 return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
629 pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
630}
631
632int JS_GetYearFromTime(double dt) {
633 return _YearFromTime(dt);
634}
635
636int JS_GetMonthFromTime(double dt) {
637 return _MonthFromTime(dt);
638}
639
640int JS_GetDayFromTime(double dt) {
641 return _DateFromTime(dt);
642}
643
644int JS_GetHourFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700645 return (int)_Mod(floor(dt / (60 * 60 * 1000)), 24);
Tom Sepez39bfe122015-09-17 15:25:23 -0700646}
647
648int JS_GetMinFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700649 return (int)_Mod(floor(dt / (60 * 1000)), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700650}
651
652int JS_GetSecFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700653 return (int)_Mod(floor(dt / 1000), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700654}
655
tsepez018935c2016-04-15 13:15:12 -0700656double JS_DateParse(const CFX_WideString& str) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700657 v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
658 v8::Isolate::Scope isolate_scope(pIsolate);
659 v8::HandleScope scope(pIsolate);
660
661 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
662
663 // Use the built-in object method.
664 v8::Local<v8::Value> v =
665 context->Global()
666 ->Get(context, v8::String::NewFromUtf8(pIsolate, "Date",
667 v8::NewStringType::kNormal)
668 .ToLocalChecked())
669 .ToLocalChecked();
670 if (v->IsObject()) {
671 v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
672 v = o->Get(context, v8::String::NewFromUtf8(pIsolate, "parse",
673 v8::NewStringType::kNormal)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400674 .ToLocalChecked())
675 .ToLocalChecked();
Tom Sepez39bfe122015-09-17 15:25:23 -0700676 if (v->IsFunction()) {
677 v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);
Tom Sepez39bfe122015-09-17 15:25:23 -0700678 const int argc = 1;
Tom Sepezc6dc69f2017-02-23 09:53:09 -0800679 v8::Local<v8::Value> timeStr =
680 CJS_Runtime::CurrentRuntimeFromIsolate(pIsolate)->NewString(
681 str.AsStringC());
Tom Sepez39bfe122015-09-17 15:25:23 -0700682 v8::Local<v8::Value> argv[argc] = {timeStr};
683 v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
684 if (v->IsNumber()) {
685 double date = v->ToNumber(context).ToLocalChecked()->Value();
686 if (!_isfinite(date))
687 return date;
tsepez86a61dc2016-03-25 10:00:11 -0700688 return JS_LocalTime(date);
Tom Sepez39bfe122015-09-17 15:25:23 -0700689 }
690 }
691 }
692 return 0;
693}
694
695double JS_MakeDay(int nYear, int nMonth, int nDate) {
696 if (!_isfinite(nYear) || !_isfinite(nMonth) || !_isfinite(nDate))
697 return GetNan();
698 double y = _toInteger(nYear);
699 double m = _toInteger(nMonth);
700 double dt = _toInteger(nDate);
Dan Sinclair669a4182017-04-03 14:51:45 -0400701 double ym = y + floor((double)m / 12);
Tom Sepez39bfe122015-09-17 15:25:23 -0700702 double mn = _Mod(m, 12);
703
704 double t = _TimeFromYearMonth((int)ym, (int)mn);
705
706 if (_YearFromTime(t) != ym || _MonthFromTime(t) != mn ||
707 _DateFromTime(t) != 1)
708 return GetNan();
709 return _Day(t) + dt - 1;
710}
711
712double JS_MakeTime(int nHour, int nMin, int nSec, int nMs) {
713 if (!_isfinite(nHour) || !_isfinite(nMin) || !_isfinite(nSec) ||
714 !_isfinite(nMs))
715 return GetNan();
716
717 double h = _toInteger(nHour);
718 double m = _toInteger(nMin);
719 double s = _toInteger(nSec);
720 double milli = _toInteger(nMs);
721
722 return h * 3600000 + m * 60000 + s * 1000 + milli;
723}
724
725double JS_MakeDate(double day, double time) {
726 if (!_isfinite(day) || !_isfinite(time))
727 return GetNan();
728
729 return day * 86400000 + time;
730}
731
732bool JS_PortIsNan(double d) {
733 return d != d;
734}
735
736double JS_LocalTime(double d) {
tsepez86a61dc2016-03-25 10:00:11 -0700737 return d + _getLocalTZA() + _getDaylightSavingTA(d);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700738}
Tom Sepezbd932572016-01-29 09:10:41 -0800739
740std::vector<CJS_Value> JS_ExpandKeywordParams(
741 CJS_Runtime* pRuntime,
742 const std::vector<CJS_Value>& originals,
743 size_t nKeywords,
744 ...) {
745 ASSERT(nKeywords);
746
747 std::vector<CJS_Value> result(nKeywords, CJS_Value(pRuntime));
748 size_t size = std::min(originals.size(), nKeywords);
749 for (size_t i = 0; i < size; ++i)
750 result[i] = originals[i];
751
752 if (originals.size() != 1 || originals[0].GetType() != CJS_Value::VT_object ||
753 originals[0].IsArrayObject()) {
754 return result;
755 }
tsepezb4694242016-08-15 16:44:55 -0700756 v8::Local<v8::Object> pObj = originals[0].ToV8Object(pRuntime);
Tom Sepezbd932572016-01-29 09:10:41 -0800757 result[0] = CJS_Value(pRuntime); // Make unknown.
758
759 va_list ap;
760 va_start(ap, nKeywords);
Wei Li89409932016-03-28 10:33:33 -0700761 for (size_t i = 0; i < nKeywords; ++i) {
Tom Sepezbd932572016-01-29 09:10:41 -0800762 const wchar_t* property = va_arg(ap, const wchar_t*);
tsepezb4694242016-08-15 16:44:55 -0700763 v8::Local<v8::Value> v8Value = pRuntime->GetObjectProperty(pObj, property);
Tom Sepezbd932572016-01-29 09:10:41 -0800764 if (!v8Value->IsUndefined())
tsepez40faa792016-07-15 17:58:02 -0700765 result[i] = CJS_Value(pRuntime, v8Value);
Tom Sepezbd932572016-01-29 09:10:41 -0800766 }
767 va_end(ap);
768 return result;
769}