blob: ab81aa0b465bca5a2f385d34237555c1fc7b40df [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
tsepez40faa792016-07-15 17:58:02 -070036CJS_Value::CJS_Value(CJS_Runtime* pRuntime) : m_pJSRuntime(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)
39 : m_pValue(pValue), m_pJSRuntime(pRuntime) {}
Tom Sepez67fd5df2015-10-08 12:24:19 -070040
41CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const int& iValue)
42 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070043 operator=(iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070044}
45
Tom Sepez67fd5df2015-10-08 12:24:19 -070046CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const bool& bValue)
47 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070048 operator=(bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070049}
50
Tom Sepez67fd5df2015-10-08 12:24:19 -070051CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const float& fValue)
52 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070053 operator=(fValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070054}
55
Tom Sepez67fd5df2015-10-08 12:24:19 -070056CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const double& dValue)
57 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070058 operator=(dValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070059}
60
Tom Sepez67fd5df2015-10-08 12:24:19 -070061CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pJsObj)
62 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063 operator=(pJsObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070064}
65
Tom Sepez67fd5df2015-10-08 12:24:19 -070066CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_WCHAR* pWstr)
67 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070068 operator=(pWstr);
Tom Sepezf79a69c2014-10-30 13:23:42 -070069}
70
Tom Sepez67fd5df2015-10-08 12:24:19 -070071CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_CHAR* pStr)
72 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070073 operator=(pStr);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070074}
75
tsepeze5aff742016-08-08 09:49:42 -070076CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const CJS_Array& array)
77 : m_pValue(array.ToV8Array(pRuntime->GetIsolate())),
78 m_pJSRuntime(pRuntime) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070079
Nico Weber9d8ec5a2015-08-04 13:00:21 -070080CJS_Value::~CJS_Value() {}
81
weili625ad662016-06-15 11:21:33 -070082CJS_Value::CJS_Value(const CJS_Value& other) = default;
83
tsepez40faa792016-07-15 17:58:02 -070084void CJS_Value::Attach(v8::Local<v8::Value> pValue) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070085 m_pValue = pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070086}
87
Nico Weber9d8ec5a2015-08-04 13:00:21 -070088void CJS_Value::Detach() {
89 m_pValue = v8::Local<v8::Value>();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070090}
91
Nico Weber9d8ec5a2015-08-04 13:00:21 -070092int CJS_Value::ToInt() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -070093 return FXJS_ToInt32(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070094}
95
Nico Weber9d8ec5a2015-08-04 13:00:21 -070096bool CJS_Value::ToBool() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -070097 return FXJS_ToBoolean(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070098}
99
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100double CJS_Value::ToDouble() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700101 return FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700102}
103
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104float CJS_Value::ToFloat() const {
105 return (float)ToDouble();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700106}
107
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700108CJS_Object* CJS_Value::ToCJSObject() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700109 v8::Local<v8::Object> pObj =
110 FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue);
111 return (CJS_Object*)FXJS_GetPrivate(m_pJSRuntime->GetIsolate(), pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700112}
113
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700114v8::Local<v8::Object> CJS_Value::ToV8Object() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700115 return FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700116}
117
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700118CFX_WideString CJS_Value::ToCFXWideString() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700119 return FXJS_ToString(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700120}
121
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700122CFX_ByteString CJS_Value::ToCFXByteString() const {
123 return CFX_ByteString::FromUnicode(ToCFXWideString());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700124}
125
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126v8::Local<v8::Value> CJS_Value::ToV8Value() const {
127 return m_pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700128}
129
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130v8::Local<v8::Array> CJS_Value::ToV8Array() const {
131 if (IsArrayObject())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700132 return v8::Local<v8::Array>::Cast(
133 FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134 return v8::Local<v8::Array>();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700135}
136
Tom Sepez4246b002016-01-20 11:48:29 -0800137void CJS_Value::MaybeCoerceToNumber() {
138 bool bAllowNaN = false;
tsepez40faa792016-07-15 17:58:02 -0700139 if (GetType() == VT_string) {
Tom Sepez4246b002016-01-20 11:48:29 -0800140 CFX_ByteString bstr = ToCFXByteString();
141 if (bstr.GetLength() == 0)
142 return;
143 if (bstr == "NaN")
144 bAllowNaN = true;
145 }
etiennebb2f6f912016-04-27 09:10:09 -0700146 v8::TryCatch try_catch(m_pJSRuntime->GetIsolate());
Tom Sepez4246b002016-01-20 11:48:29 -0800147 v8::MaybeLocal<v8::Number> maybeNum =
148 m_pValue->ToNumber(m_pJSRuntime->GetIsolate()->GetCurrentContext());
149 if (maybeNum.IsEmpty())
150 return;
151 v8::Local<v8::Number> num = maybeNum.ToLocalChecked();
152 if (std::isnan(num->Value()) && !bAllowNaN)
153 return;
154 m_pValue = num;
Tom Sepez4246b002016-01-20 11:48:29 -0800155}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156
157void CJS_Value::operator=(int iValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700158 m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700159}
160
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700161void CJS_Value::operator=(bool bValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700162 m_pValue = FXJS_NewBoolean(m_pJSRuntime->GetIsolate(), bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700163}
164
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700165void CJS_Value::operator=(double dValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700166 m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), dValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700167}
168
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700169void CJS_Value::operator=(float fValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700170 m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), fValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700171}
172
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173void CJS_Value::operator=(v8::Local<v8::Object> pObj) {
tsepez88b66862016-07-14 12:07:48 -0700174 m_pValue = pObj;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700175}
176
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700177void CJS_Value::operator=(CJS_Object* pObj) {
178 if (pObj)
Tom Sepez116e4ad2015-09-21 09:22:05 -0700179 operator=(pObj->ToV8Object());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700180}
181
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182void CJS_Value::operator=(const FX_WCHAR* pWstr) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700183 m_pValue = FXJS_NewString(m_pJSRuntime->GetIsolate(), (wchar_t*)pWstr);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700184}
185
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700186void CJS_Value::SetNull() {
tsepez88b66862016-07-14 12:07:48 -0700187 m_pValue = FXJS_NewNull(m_pJSRuntime->GetIsolate());
JUN FANG33f6f0d2015-04-06 12:39:51 -0700188}
189
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700190void CJS_Value::operator=(const FX_CHAR* pStr) {
191 operator=(CFX_WideString::FromLocal(pStr).c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700192}
193
tsepezfbf52c22016-07-25 11:17:07 -0700194void CJS_Value::operator=(const CJS_Date& date) {
195 ASSERT(m_pJSRuntime == date.GetJSRuntime());
196 m_pValue = FXJS_NewDate(m_pJSRuntime->GetIsolate(), date.ToDouble());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700197}
198
tsepezfbf52c22016-07-25 11:17:07 -0700199void CJS_Value::operator=(const CJS_Value& value) {
200 ASSERT(m_pJSRuntime == value.m_pJSRuntime);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700201 m_pValue = value.ToV8Value();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700202}
203
tsepez40faa792016-07-15 17:58:02 -0700204// static
205CJS_Value::Type CJS_Value::GetValueType(v8::Local<v8::Value> value) {
206 if (value.IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700207 return VT_unknown;
tsepez40faa792016-07-15 17:58:02 -0700208 if (value->IsString())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700209 return VT_string;
tsepez40faa792016-07-15 17:58:02 -0700210 if (value->IsNumber())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700211 return VT_number;
tsepez40faa792016-07-15 17:58:02 -0700212 if (value->IsBoolean())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 return VT_boolean;
tsepez40faa792016-07-15 17:58:02 -0700214 if (value->IsDate())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700215 return VT_date;
tsepez40faa792016-07-15 17:58:02 -0700216 if (value->IsObject())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217 return VT_object;
tsepez40faa792016-07-15 17:58:02 -0700218 if (value->IsNull())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700219 return VT_null;
tsepez40faa792016-07-15 17:58:02 -0700220 if (value->IsUndefined())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700221 return VT_undefined;
222 return VT_unknown;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700223}
224
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225FX_BOOL CJS_Value::IsArrayObject() const {
226 if (m_pValue.IsEmpty())
227 return FALSE;
228 return m_pValue->IsArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700229}
230
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700231FX_BOOL CJS_Value::IsDateObject() const {
232 if (m_pValue.IsEmpty())
233 return FALSE;
234 return m_pValue->IsDate();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700235}
236
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700237// CJS_Value::operator CJS_Array()
238FX_BOOL CJS_Value::ConvertToArray(CJS_Array& array) const {
239 if (IsArrayObject()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700240 array.Attach(FXJS_ToArray(m_pJSRuntime->GetIsolate(), m_pValue));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241 return TRUE;
242 }
243
244 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700245}
246
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700247FX_BOOL CJS_Value::ConvertToDate(CJS_Date& date) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700248 if (IsDateObject()) {
tsepez135b9982016-08-05 09:32:50 -0700249 v8::Local<v8::Value> mutable_value = m_pValue;
250 date.Attach(mutable_value.As<v8::Date>());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700251 return TRUE;
252 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700253
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700255}
256
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257CJS_PropValue::CJS_PropValue(const CJS_Value& value)
258 : CJS_Value(value), m_bIsSetting(0) {}
259
Tom Sepez67fd5df2015-10-08 12:24:19 -0700260CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400261 : CJS_Value(pRuntime), m_bIsSetting(0) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700262
Dan Sinclairf766ad22016-03-14 13:51:24 -0400263CJS_PropValue::~CJS_PropValue() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700264
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700265void CJS_PropValue::operator<<(int iValue) {
266 ASSERT(!m_bIsSetting);
267 CJS_Value::operator=(iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700268}
269
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270void CJS_PropValue::operator>>(int& iValue) const {
271 ASSERT(m_bIsSetting);
272 iValue = CJS_Value::ToInt();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700273}
274
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700275void CJS_PropValue::operator<<(bool bValue) {
276 ASSERT(!m_bIsSetting);
277 CJS_Value::operator=(bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700278}
279
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700280void CJS_PropValue::operator>>(bool& bValue) const {
281 ASSERT(m_bIsSetting);
282 bValue = CJS_Value::ToBool();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700283}
284
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700285void CJS_PropValue::operator<<(double dValue) {
286 ASSERT(!m_bIsSetting);
287 CJS_Value::operator=(dValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700288}
289
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700290void CJS_PropValue::operator>>(double& dValue) const {
291 ASSERT(m_bIsSetting);
292 dValue = CJS_Value::ToDouble();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700293}
294
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700295void CJS_PropValue::operator<<(CJS_Object* pObj) {
296 ASSERT(!m_bIsSetting);
297 CJS_Value::operator=(pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700298}
299
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300void CJS_PropValue::operator>>(CJS_Object*& ppObj) const {
301 ASSERT(m_bIsSetting);
302 ppObj = CJS_Value::ToCJSObject();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700303}
304
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700305void CJS_PropValue::operator<<(CJS_Document* pJsDoc) {
306 ASSERT(!m_bIsSetting);
307 CJS_Value::operator=(pJsDoc);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700308}
309
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310void CJS_PropValue::operator>>(CJS_Document*& ppJsDoc) const {
311 ASSERT(m_bIsSetting);
312 ppJsDoc = static_cast<CJS_Document*>(CJS_Value::ToCJSObject());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700313}
314
Tom Sepez808a99e2015-09-10 12:28:37 -0700315void CJS_PropValue::operator<<(v8::Local<v8::Object> pObj) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700316 ASSERT(!m_bIsSetting);
317 CJS_Value::operator=(pObj);
JUN FANG33f6f0d2015-04-06 12:39:51 -0700318}
319
Tom Sepez808a99e2015-09-10 12:28:37 -0700320void CJS_PropValue::operator>>(v8::Local<v8::Object>& ppObj) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700321 ASSERT(m_bIsSetting);
322 ppObj = CJS_Value::ToV8Object();
JUN FANG33f6f0d2015-04-06 12:39:51 -0700323}
324
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500325void CJS_PropValue::operator<<(CFX_ByteString str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700326 ASSERT(!m_bIsSetting);
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500327 CJS_Value::operator=(str.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700328}
329
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500330void CJS_PropValue::operator>>(CFX_ByteString& str) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700331 ASSERT(m_bIsSetting);
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500332 str = CJS_Value::ToCFXByteString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700333}
334
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700335void CJS_PropValue::operator<<(const FX_WCHAR* c_string) {
336 ASSERT(!m_bIsSetting);
337 CJS_Value::operator=(c_string);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700338}
339
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700340void CJS_PropValue::operator>>(CFX_WideString& wide_string) const {
341 ASSERT(m_bIsSetting);
342 wide_string = CJS_Value::ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700343}
344
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700345void CJS_PropValue::operator<<(CFX_WideString wide_string) {
346 ASSERT(!m_bIsSetting);
347 CJS_Value::operator=(wide_string.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700348}
349
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700350void CJS_PropValue::operator>>(CJS_Array& array) const {
351 ASSERT(m_bIsSetting);
352 ConvertToArray(array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700353}
354
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700355void CJS_PropValue::operator<<(CJS_Array& array) {
356 ASSERT(!m_bIsSetting);
tsepeze5aff742016-08-08 09:49:42 -0700357 m_pValue = array.ToV8Array(m_pJSRuntime->GetIsolate());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700358}
359
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700360void CJS_PropValue::operator>>(CJS_Date& date) const {
361 ASSERT(m_bIsSetting);
362 ConvertToDate(date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700363}
364
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700365void CJS_PropValue::operator<<(CJS_Date& date) {
366 ASSERT(!m_bIsSetting);
367 CJS_Value::operator=(date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700368}
369
tsepeze5aff742016-08-08 09:49:42 -0700370CJS_Array::CJS_Array() {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700371
weili625ad662016-06-15 11:21:33 -0700372CJS_Array::CJS_Array(const CJS_Array& other) = default;
373
tsepeze5aff742016-08-08 09:49:42 -0700374CJS_Array::~CJS_Array() {}
375
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700376void CJS_Array::Attach(v8::Local<v8::Array> pArray) {
377 m_pArray = pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700378}
379
tsepeze5aff742016-08-08 09:49:42 -0700380void CJS_Array::GetElement(v8::Isolate* pIsolate,
381 unsigned index,
382 CJS_Value& value) const {
383 if (!m_pArray.IsEmpty())
384 value.Attach(FXJS_GetArrayElement(pIsolate, m_pArray, index));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700385}
386
tsepeze5aff742016-08-08 09:49:42 -0700387void CJS_Array::SetElement(v8::Isolate* pIsolate,
388 unsigned index,
389 const CJS_Value& value) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700390 if (m_pArray.IsEmpty())
tsepeze5aff742016-08-08 09:49:42 -0700391 m_pArray = FXJS_NewArray(pIsolate);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700392
tsepeze5aff742016-08-08 09:49:42 -0700393 FXJS_PutArrayElement(pIsolate, m_pArray, index, value.ToV8Value());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700394}
395
tsepezfbf52c22016-07-25 11:17:07 -0700396int CJS_Array::GetLength() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700397 if (m_pArray.IsEmpty())
398 return 0;
Tom Sepez39bfe122015-09-17 15:25:23 -0700399 return FXJS_GetArrayLength(m_pArray);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700400}
401
tsepeze5aff742016-08-08 09:49:42 -0700402v8::Local<v8::Array> CJS_Array::ToV8Array(v8::Isolate* pIsolate) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700403 if (m_pArray.IsEmpty())
tsepeze5aff742016-08-08 09:49:42 -0700404 m_pArray = FXJS_NewArray(pIsolate);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700405
406 return m_pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700407}
408
Dan Sinclairf766ad22016-03-14 13:51:24 -0400409CJS_Date::CJS_Date(CJS_Runtime* pRuntime) : m_pJSRuntime(pRuntime) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700410
Tom Sepez67fd5df2015-10-08 12:24:19 -0700411CJS_Date::CJS_Date(CJS_Runtime* pRuntime, double dMsecTime)
412 : m_pJSRuntime(pRuntime) {
413 m_pDate = FXJS_NewDate(pRuntime->GetIsolate(), dMsecTime);
414}
415
416CJS_Date::CJS_Date(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700417 int year,
418 int mon,
419 int day,
420 int hour,
421 int min,
Tom Sepez67fd5df2015-10-08 12:24:19 -0700422 int sec)
423 : m_pJSRuntime(pRuntime) {
424 m_pDate = FXJS_NewDate(pRuntime->GetIsolate(),
425 MakeDate(year, mon, day, hour, min, sec, 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700426}
427
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700428CJS_Date::~CJS_Date() {}
429
tsepezfbf52c22016-07-25 11:17:07 -0700430bool CJS_Date::IsValidDate() const {
431 return !m_pDate.IsEmpty() &&
432 !JS_PortIsNan(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700433}
434
tsepez135b9982016-08-05 09:32:50 -0700435void CJS_Date::Attach(v8::Local<v8::Date> pDate) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700436 m_pDate = pDate;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700437}
438
tsepezfbf52c22016-07-25 11:17:07 -0700439int CJS_Date::GetYear() const {
440 if (!IsValidDate())
441 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700442
tsepezfbf52c22016-07-25 11:17:07 -0700443 return JS_GetYearFromTime(
444 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700445}
446
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700447void CJS_Date::SetYear(int iYear) {
448 double date = MakeDate(iYear, GetMonth(), GetDay(), GetHours(), GetMinutes(),
449 GetSeconds(), 0);
tsepez135b9982016-08-05 09:32:50 -0700450 m_pDate = FXJS_NewDate(m_pJSRuntime->GetIsolate(), date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700451}
452
tsepezfbf52c22016-07-25 11:17:07 -0700453int CJS_Date::GetMonth() const {
454 if (!IsValidDate())
455 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700456
tsepezfbf52c22016-07-25 11:17:07 -0700457 return JS_GetMonthFromTime(
458 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700459}
460
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700461void CJS_Date::SetMonth(int iMonth) {
462 double date = MakeDate(GetYear(), iMonth, GetDay(), GetHours(), GetMinutes(),
463 GetSeconds(), 0);
tsepez135b9982016-08-05 09:32:50 -0700464 m_pDate = FXJS_NewDate(m_pJSRuntime->GetIsolate(), date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700465}
466
tsepezfbf52c22016-07-25 11:17:07 -0700467int CJS_Date::GetDay() const {
468 if (!IsValidDate())
469 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700470
tsepezfbf52c22016-07-25 11:17:07 -0700471 return JS_GetDayFromTime(
472 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700473}
474
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700475void CJS_Date::SetDay(int iDay) {
476 double date = MakeDate(GetYear(), GetMonth(), iDay, GetHours(), GetMinutes(),
477 GetSeconds(), 0);
tsepez135b9982016-08-05 09:32:50 -0700478 m_pDate = FXJS_NewDate(m_pJSRuntime->GetIsolate(), date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700479}
480
tsepezfbf52c22016-07-25 11:17:07 -0700481int CJS_Date::GetHours() const {
482 if (!IsValidDate())
483 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700484
tsepezfbf52c22016-07-25 11:17:07 -0700485 return JS_GetHourFromTime(
486 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700487}
488
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700489void CJS_Date::SetHours(int iHours) {
490 double date = MakeDate(GetYear(), GetMonth(), GetDay(), iHours, GetMinutes(),
491 GetSeconds(), 0);
tsepez135b9982016-08-05 09:32:50 -0700492 m_pDate = FXJS_NewDate(m_pJSRuntime->GetIsolate(), date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700493}
494
tsepezfbf52c22016-07-25 11:17:07 -0700495int CJS_Date::GetMinutes() const {
496 if (!IsValidDate())
497 return 0;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700498
tsepezfbf52c22016-07-25 11:17:07 -0700499 return JS_GetMinFromTime(
500 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700501}
502
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700503void CJS_Date::SetMinutes(int minutes) {
504 double date = MakeDate(GetYear(), GetMonth(), GetDay(), GetHours(), minutes,
505 GetSeconds(), 0);
tsepez135b9982016-08-05 09:32:50 -0700506 m_pDate = FXJS_NewDate(m_pJSRuntime->GetIsolate(), date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700507}
508
tsepezfbf52c22016-07-25 11:17:07 -0700509int CJS_Date::GetSeconds() const {
510 if (!IsValidDate())
511 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700512
tsepezfbf52c22016-07-25 11:17:07 -0700513 return JS_GetSecFromTime(
514 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700515}
516
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700517void CJS_Date::SetSeconds(int seconds) {
518 double date = MakeDate(GetYear(), GetMonth(), GetDay(), GetHours(),
519 GetMinutes(), seconds, 0);
tsepez135b9982016-08-05 09:32:50 -0700520 m_pDate = FXJS_NewDate(m_pJSRuntime->GetIsolate(), date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700521}
522
tsepezfbf52c22016-07-25 11:17:07 -0700523double CJS_Date::ToDouble() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700524 if (m_pDate.IsEmpty())
525 return 0.0;
tsepezfbf52c22016-07-25 11:17:07 -0700526
Tom Sepez67fd5df2015-10-08 12:24:19 -0700527 return FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700528}
529
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700530CFX_WideString CJS_Date::ToString() const {
531 if (m_pDate.IsEmpty())
532 return L"";
tsepezfbf52c22016-07-25 11:17:07 -0700533
Tom Sepez67fd5df2015-10-08 12:24:19 -0700534 return FXJS_ToString(m_pJSRuntime->GetIsolate(), m_pDate);
Tom Sepez39bfe122015-09-17 15:25:23 -0700535}
536
537double _getLocalTZA() {
538 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
539 return 0;
540 time_t t = 0;
541 time(&t);
542 localtime(&t);
543#if _MSC_VER >= 1900
544 // In gcc and in Visual Studio prior to VS 2015 'timezone' is a global
545 // variable declared in time.h. That variable was deprecated and in VS 2015
546 // is removed, with _get_timezone replacing it.
547 long timezone = 0;
548 _get_timezone(&timezone);
549#endif
550 return (double)(-(timezone * 1000));
551}
552
553int _getDaylightSavingTA(double d) {
554 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
555 return 0;
556 time_t t = (time_t)(d / 1000);
557 struct tm* tmp = localtime(&t);
Lei Zhang412e9082015-12-14 18:34:00 -0800558 if (!tmp)
Tom Sepez39bfe122015-09-17 15:25:23 -0700559 return 0;
560 if (tmp->tm_isdst > 0)
561 // One hour.
562 return (int)60 * 60 * 1000;
563 return 0;
564}
565
566double _Mod(double x, double y) {
567 double r = fmod(x, y);
568 if (r < 0)
569 r += y;
570 return r;
571}
572
573int _isfinite(double v) {
574#if _MSC_VER
575 return ::_finite(v);
576#else
577 return std::fabs(v) < std::numeric_limits<double>::max();
578#endif
579}
580
581double _toInteger(double n) {
582 return (n >= 0) ? FXSYS_floor(n) : -FXSYS_floor(-n);
583}
584
585bool _isLeapYear(int year) {
586 return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
587}
588
589int _DayFromYear(int y) {
590 return (int)(365 * (y - 1970.0) + FXSYS_floor((y - 1969.0) / 4) -
591 FXSYS_floor((y - 1901.0) / 100) +
592 FXSYS_floor((y - 1601.0) / 400));
593}
594
595double _TimeFromYear(int y) {
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800596 return 86400000.0 * _DayFromYear(y);
Tom Sepez39bfe122015-09-17 15:25:23 -0700597}
598
Tom Sepez4161c5c2016-03-21 12:26:54 -0700599static const uint16_t daysMonth[12] = {0, 31, 59, 90, 120, 151,
600 181, 212, 243, 273, 304, 334};
601static const uint16_t leapDaysMonth[12] = {0, 31, 60, 91, 121, 152,
602 182, 213, 244, 274, 305, 335};
603
Tom Sepez39bfe122015-09-17 15:25:23 -0700604double _TimeFromYearMonth(int y, int m) {
Tom Sepez4161c5c2016-03-21 12:26:54 -0700605 const uint16_t* pMonth = _isLeapYear(y) ? leapDaysMonth : daysMonth;
Tom Sepez39bfe122015-09-17 15:25:23 -0700606 return _TimeFromYear(y) + ((double)pMonth[m]) * 86400000;
607}
608
609int _Day(double t) {
610 return (int)FXSYS_floor(t / 86400000);
611}
612
613int _YearFromTime(double t) {
614 // estimate the time.
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800615 int y = 1970 + static_cast<int>(t / (365.2425 * 86400000));
Tom Sepez39bfe122015-09-17 15:25:23 -0700616 if (_TimeFromYear(y) <= t) {
617 while (_TimeFromYear(y + 1) <= t)
618 y++;
Dan Sinclair738b08c2016-03-01 14:45:20 -0500619 } else {
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800620 while (_TimeFromYear(y) > t)
Tom Sepez39bfe122015-09-17 15:25:23 -0700621 y--;
Dan Sinclair738b08c2016-03-01 14:45:20 -0500622 }
Tom Sepez39bfe122015-09-17 15:25:23 -0700623 return y;
624}
625
626int _DayWithinYear(double t) {
627 int year = _YearFromTime(t);
628 int day = _Day(t);
629 return day - _DayFromYear(year);
630}
631
632int _MonthFromTime(double t) {
633 int day = _DayWithinYear(t);
634 int year = _YearFromTime(t);
635 if (0 <= day && day < 31)
636 return 0;
637 if (31 <= day && day < 59 + _isLeapYear(year))
638 return 1;
639 if ((59 + _isLeapYear(year)) <= day && day < (90 + _isLeapYear(year)))
640 return 2;
641 if ((90 + _isLeapYear(year)) <= day && day < (120 + _isLeapYear(year)))
642 return 3;
643 if ((120 + _isLeapYear(year)) <= day && day < (151 + _isLeapYear(year)))
644 return 4;
645 if ((151 + _isLeapYear(year)) <= day && day < (181 + _isLeapYear(year)))
646 return 5;
647 if ((181 + _isLeapYear(year)) <= day && day < (212 + _isLeapYear(year)))
648 return 6;
649 if ((212 + _isLeapYear(year)) <= day && day < (243 + _isLeapYear(year)))
650 return 7;
651 if ((243 + _isLeapYear(year)) <= day && day < (273 + _isLeapYear(year)))
652 return 8;
653 if ((273 + _isLeapYear(year)) <= day && day < (304 + _isLeapYear(year)))
654 return 9;
655 if ((304 + _isLeapYear(year)) <= day && day < (334 + _isLeapYear(year)))
656 return 10;
657 if ((334 + _isLeapYear(year)) <= day && day < (365 + _isLeapYear(year)))
658 return 11;
659
660 return -1;
661}
662
663int _DateFromTime(double t) {
664 int day = _DayWithinYear(t);
665 int year = _YearFromTime(t);
weili12367cb2016-06-03 11:22:16 -0700666 int leap = _isLeapYear(year);
Tom Sepez39bfe122015-09-17 15:25:23 -0700667 int month = _MonthFromTime(t);
668 switch (month) {
669 case 0:
670 return day + 1;
671 case 1:
672 return day - 30;
673 case 2:
674 return day - 58 - leap;
675 case 3:
676 return day - 89 - leap;
677 case 4:
678 return day - 119 - leap;
679 case 5:
680 return day - 150 - leap;
681 case 6:
682 return day - 180 - leap;
683 case 7:
684 return day - 211 - leap;
685 case 8:
686 return day - 242 - leap;
687 case 9:
688 return day - 272 - leap;
689 case 10:
690 return day - 303 - leap;
691 case 11:
692 return day - 333 - leap;
693 default:
694 return 0;
695 }
696}
697
698double JS_GetDateTime() {
699 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
700 return 0;
thestig1cd352e2016-06-07 17:53:06 -0700701 time_t t = time(nullptr);
Tom Sepez39bfe122015-09-17 15:25:23 -0700702 struct tm* pTm = localtime(&t);
703
704 int year = pTm->tm_year + 1900;
705 double t1 = _TimeFromYear(year);
706
707 return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
708 pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
709}
710
711int JS_GetYearFromTime(double dt) {
712 return _YearFromTime(dt);
713}
714
715int JS_GetMonthFromTime(double dt) {
716 return _MonthFromTime(dt);
717}
718
719int JS_GetDayFromTime(double dt) {
720 return _DateFromTime(dt);
721}
722
723int JS_GetHourFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700724 return (int)_Mod(floor(dt / (60 * 60 * 1000)), 24);
Tom Sepez39bfe122015-09-17 15:25:23 -0700725}
726
727int JS_GetMinFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700728 return (int)_Mod(floor(dt / (60 * 1000)), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700729}
730
731int JS_GetSecFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700732 return (int)_Mod(floor(dt / 1000), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700733}
734
tsepez018935c2016-04-15 13:15:12 -0700735double JS_DateParse(const CFX_WideString& str) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700736 v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
737 v8::Isolate::Scope isolate_scope(pIsolate);
738 v8::HandleScope scope(pIsolate);
739
740 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
741
742 // Use the built-in object method.
743 v8::Local<v8::Value> v =
744 context->Global()
745 ->Get(context, v8::String::NewFromUtf8(pIsolate, "Date",
746 v8::NewStringType::kNormal)
747 .ToLocalChecked())
748 .ToLocalChecked();
749 if (v->IsObject()) {
750 v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
751 v = o->Get(context, v8::String::NewFromUtf8(pIsolate, "parse",
752 v8::NewStringType::kNormal)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400753 .ToLocalChecked())
754 .ToLocalChecked();
Tom Sepez39bfe122015-09-17 15:25:23 -0700755 if (v->IsFunction()) {
756 v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);
Tom Sepez39bfe122015-09-17 15:25:23 -0700757 const int argc = 1;
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500758 v8::Local<v8::String> timeStr = FXJS_WSToJSString(pIsolate, str);
Tom Sepez39bfe122015-09-17 15:25:23 -0700759 v8::Local<v8::Value> argv[argc] = {timeStr};
760 v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
761 if (v->IsNumber()) {
762 double date = v->ToNumber(context).ToLocalChecked()->Value();
763 if (!_isfinite(date))
764 return date;
tsepez86a61dc2016-03-25 10:00:11 -0700765 return JS_LocalTime(date);
Tom Sepez39bfe122015-09-17 15:25:23 -0700766 }
767 }
768 }
769 return 0;
770}
771
772double JS_MakeDay(int nYear, int nMonth, int nDate) {
773 if (!_isfinite(nYear) || !_isfinite(nMonth) || !_isfinite(nDate))
774 return GetNan();
775 double y = _toInteger(nYear);
776 double m = _toInteger(nMonth);
777 double dt = _toInteger(nDate);
778 double ym = y + FXSYS_floor((double)m / 12);
779 double mn = _Mod(m, 12);
780
781 double t = _TimeFromYearMonth((int)ym, (int)mn);
782
783 if (_YearFromTime(t) != ym || _MonthFromTime(t) != mn ||
784 _DateFromTime(t) != 1)
785 return GetNan();
786 return _Day(t) + dt - 1;
787}
788
789double JS_MakeTime(int nHour, int nMin, int nSec, int nMs) {
790 if (!_isfinite(nHour) || !_isfinite(nMin) || !_isfinite(nSec) ||
791 !_isfinite(nMs))
792 return GetNan();
793
794 double h = _toInteger(nHour);
795 double m = _toInteger(nMin);
796 double s = _toInteger(nSec);
797 double milli = _toInteger(nMs);
798
799 return h * 3600000 + m * 60000 + s * 1000 + milli;
800}
801
802double JS_MakeDate(double day, double time) {
803 if (!_isfinite(day) || !_isfinite(time))
804 return GetNan();
805
806 return day * 86400000 + time;
807}
808
809bool JS_PortIsNan(double d) {
810 return d != d;
811}
812
813double JS_LocalTime(double d) {
tsepez86a61dc2016-03-25 10:00:11 -0700814 return d + _getLocalTZA() + _getDaylightSavingTA(d);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700815}
Tom Sepezbd932572016-01-29 09:10:41 -0800816
817std::vector<CJS_Value> JS_ExpandKeywordParams(
818 CJS_Runtime* pRuntime,
819 const std::vector<CJS_Value>& originals,
820 size_t nKeywords,
821 ...) {
822 ASSERT(nKeywords);
823
824 std::vector<CJS_Value> result(nKeywords, CJS_Value(pRuntime));
825 size_t size = std::min(originals.size(), nKeywords);
826 for (size_t i = 0; i < size; ++i)
827 result[i] = originals[i];
828
829 if (originals.size() != 1 || originals[0].GetType() != CJS_Value::VT_object ||
830 originals[0].IsArrayObject()) {
831 return result;
832 }
833 v8::Local<v8::Object> pObj = originals[0].ToV8Object();
834 result[0] = CJS_Value(pRuntime); // Make unknown.
835
836 va_list ap;
837 va_start(ap, nKeywords);
Wei Li89409932016-03-28 10:33:33 -0700838 for (size_t i = 0; i < nKeywords; ++i) {
Tom Sepezbd932572016-01-29 09:10:41 -0800839 const wchar_t* property = va_arg(ap, const wchar_t*);
840 v8::Local<v8::Value> v8Value =
841 FXJS_GetObjectElement(pRuntime->GetIsolate(), pObj, property);
842 if (!v8Value->IsUndefined())
tsepez40faa792016-07-15 17:58:02 -0700843 result[i] = CJS_Value(pRuntime, v8Value);
Tom Sepezbd932572016-01-29 09:10:41 -0800844 }
845 va_end(ap);
846 return result;
847}