blob: c13d1d405e54a412d0a7ba135c52848bf226f8aa [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
tsepezc3255f52016-03-25 14:52:27 -070020static const uint32_t g_nan[2] = {0, 0x7FF80000};
Tom Sepez39bfe122015-09-17 15:25:23 -070021static double GetNan() {
22 return *(double*)g_nan;
23}
24
tsepez40faa792016-07-15 17:58:02 -070025CJS_Value::CJS_Value(CJS_Runtime* pRuntime) : m_pJSRuntime(pRuntime) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -070026
tsepez40faa792016-07-15 17:58:02 -070027CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue)
28 : m_pValue(pValue), m_pJSRuntime(pRuntime) {}
Tom Sepez67fd5df2015-10-08 12:24:19 -070029
30CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const int& iValue)
31 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070032 operator=(iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070033}
34
Tom Sepez67fd5df2015-10-08 12:24:19 -070035CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const bool& bValue)
36 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070037 operator=(bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070038}
39
Tom Sepez67fd5df2015-10-08 12:24:19 -070040CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const float& fValue)
41 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070042 operator=(fValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070043}
44
Tom Sepez67fd5df2015-10-08 12:24:19 -070045CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const double& dValue)
46 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070047 operator=(dValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070048}
49
Tom Sepez67fd5df2015-10-08 12:24:19 -070050CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Object* pJsObj)
51 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070052 operator=(pJsObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070053}
54
Tom Sepez67fd5df2015-10-08 12:24:19 -070055CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_WCHAR* pWstr)
56 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070057 operator=(pWstr);
Tom Sepezf79a69c2014-10-30 13:23:42 -070058}
59
Tom Sepez67fd5df2015-10-08 12:24:19 -070060CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_CHAR* pStr)
61 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070062 operator=(pStr);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070063}
64
Tom Sepez67fd5df2015-10-08 12:24:19 -070065CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Array& array)
66 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070067 operator=(array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070068}
69
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
Nico Weber9d8ec5a2015-08-04 13:00:21 -070082int CJS_Value::ToInt() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -070083 return FXJS_ToInt32(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070084}
85
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086bool CJS_Value::ToBool() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -070087 return FXJS_ToBoolean(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070088}
89
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090double CJS_Value::ToDouble() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -070091 return FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070092}
93
Nico Weber9d8ec5a2015-08-04 13:00:21 -070094float CJS_Value::ToFloat() const {
95 return (float)ToDouble();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070096}
97
Nico Weber9d8ec5a2015-08-04 13:00:21 -070098CJS_Object* CJS_Value::ToCJSObject() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -070099 v8::Local<v8::Object> pObj =
100 FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue);
101 return (CJS_Object*)FXJS_GetPrivate(m_pJSRuntime->GetIsolate(), pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700102}
103
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104v8::Local<v8::Object> CJS_Value::ToV8Object() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700105 return FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700106}
107
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700108CFX_WideString CJS_Value::ToCFXWideString() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700109 return FXJS_ToString(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700110}
111
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700112CFX_ByteString CJS_Value::ToCFXByteString() const {
113 return CFX_ByteString::FromUnicode(ToCFXWideString());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700114}
115
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116v8::Local<v8::Value> CJS_Value::ToV8Value() const {
117 return m_pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700118}
119
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700120v8::Local<v8::Array> CJS_Value::ToV8Array() const {
121 if (IsArrayObject())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700122 return v8::Local<v8::Array>::Cast(
123 FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700124 return v8::Local<v8::Array>();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700125}
126
Tom Sepez4246b002016-01-20 11:48:29 -0800127void CJS_Value::MaybeCoerceToNumber() {
128 bool bAllowNaN = false;
tsepez40faa792016-07-15 17:58:02 -0700129 if (GetType() == VT_string) {
Tom Sepez4246b002016-01-20 11:48:29 -0800130 CFX_ByteString bstr = ToCFXByteString();
131 if (bstr.GetLength() == 0)
132 return;
133 if (bstr == "NaN")
134 bAllowNaN = true;
135 }
etiennebb2f6f912016-04-27 09:10:09 -0700136 v8::TryCatch try_catch(m_pJSRuntime->GetIsolate());
Tom Sepez4246b002016-01-20 11:48:29 -0800137 v8::MaybeLocal<v8::Number> maybeNum =
138 m_pValue->ToNumber(m_pJSRuntime->GetIsolate()->GetCurrentContext());
139 if (maybeNum.IsEmpty())
140 return;
141 v8::Local<v8::Number> num = maybeNum.ToLocalChecked();
142 if (std::isnan(num->Value()) && !bAllowNaN)
143 return;
144 m_pValue = num;
Tom Sepez4246b002016-01-20 11:48:29 -0800145}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700146
147void CJS_Value::operator=(int iValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700148 m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700149}
150
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700151void CJS_Value::operator=(bool bValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700152 m_pValue = FXJS_NewBoolean(m_pJSRuntime->GetIsolate(), bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700153}
154
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700155void CJS_Value::operator=(double dValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700156 m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), dValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700157}
158
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159void CJS_Value::operator=(float fValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700160 m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), fValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700161}
162
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700163void CJS_Value::operator=(v8::Local<v8::Object> pObj) {
tsepez88b66862016-07-14 12:07:48 -0700164 m_pValue = pObj;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700165}
166
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700167void CJS_Value::operator=(CJS_Object* pObj) {
168 if (pObj)
Tom Sepez116e4ad2015-09-21 09:22:05 -0700169 operator=(pObj->ToV8Object());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700170}
171
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700172void CJS_Value::operator=(const FX_WCHAR* pWstr) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700173 m_pValue = FXJS_NewString(m_pJSRuntime->GetIsolate(), (wchar_t*)pWstr);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700174}
175
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176void CJS_Value::SetNull() {
tsepez88b66862016-07-14 12:07:48 -0700177 m_pValue = FXJS_NewNull(m_pJSRuntime->GetIsolate());
JUN FANG33f6f0d2015-04-06 12:39:51 -0700178}
179
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700180void CJS_Value::operator=(const FX_CHAR* pStr) {
181 operator=(CFX_WideString::FromLocal(pStr).c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700182}
183
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700184void CJS_Value::operator=(CJS_Array& array) {
tsepez88b66862016-07-14 12:07:48 -0700185 m_pValue = static_cast<v8::Local<v8::Array>>(array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700186}
187
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188void CJS_Value::operator=(CJS_Date& date) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700189 m_pValue = FXJS_NewDate(m_pJSRuntime->GetIsolate(), (double)date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700190}
191
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700192void CJS_Value::operator=(CJS_Value value) {
193 m_pValue = value.ToV8Value();
Tom Sepez67fd5df2015-10-08 12:24:19 -0700194 m_pJSRuntime = value.m_pJSRuntime;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700195}
196
tsepez40faa792016-07-15 17:58:02 -0700197// static
198CJS_Value::Type CJS_Value::GetValueType(v8::Local<v8::Value> value) {
199 if (value.IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200 return VT_unknown;
tsepez40faa792016-07-15 17:58:02 -0700201 if (value->IsString())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202 return VT_string;
tsepez40faa792016-07-15 17:58:02 -0700203 if (value->IsNumber())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700204 return VT_number;
tsepez40faa792016-07-15 17:58:02 -0700205 if (value->IsBoolean())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700206 return VT_boolean;
tsepez40faa792016-07-15 17:58:02 -0700207 if (value->IsDate())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208 return VT_date;
tsepez40faa792016-07-15 17:58:02 -0700209 if (value->IsObject())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210 return VT_object;
tsepez40faa792016-07-15 17:58:02 -0700211 if (value->IsNull())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700212 return VT_null;
tsepez40faa792016-07-15 17:58:02 -0700213 if (value->IsUndefined())
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700214 return VT_undefined;
215 return VT_unknown;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700216}
217
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700218FX_BOOL CJS_Value::IsArrayObject() const {
219 if (m_pValue.IsEmpty())
220 return FALSE;
221 return m_pValue->IsArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700222}
223
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700224FX_BOOL CJS_Value::IsDateObject() const {
225 if (m_pValue.IsEmpty())
226 return FALSE;
227 return m_pValue->IsDate();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700228}
229
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230// CJS_Value::operator CJS_Array()
231FX_BOOL CJS_Value::ConvertToArray(CJS_Array& array) const {
232 if (IsArrayObject()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700233 array.Attach(FXJS_ToArray(m_pJSRuntime->GetIsolate(), m_pValue));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700234 return TRUE;
235 }
236
237 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700238}
239
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700240FX_BOOL CJS_Value::ConvertToDate(CJS_Date& date) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700241 if (IsDateObject()) {
242 date.Attach(m_pValue);
243 return TRUE;
244 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700245
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700246 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700247}
248
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700249CJS_PropValue::CJS_PropValue(const CJS_Value& value)
250 : CJS_Value(value), m_bIsSetting(0) {}
251
Tom Sepez67fd5df2015-10-08 12:24:19 -0700252CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400253 : CJS_Value(pRuntime), m_bIsSetting(0) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700254
Dan Sinclairf766ad22016-03-14 13:51:24 -0400255CJS_PropValue::~CJS_PropValue() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700256
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700257void CJS_PropValue::operator<<(int iValue) {
258 ASSERT(!m_bIsSetting);
259 CJS_Value::operator=(iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700260}
261
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700262void CJS_PropValue::operator>>(int& iValue) const {
263 ASSERT(m_bIsSetting);
264 iValue = CJS_Value::ToInt();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700265}
266
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700267void CJS_PropValue::operator<<(bool bValue) {
268 ASSERT(!m_bIsSetting);
269 CJS_Value::operator=(bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700270}
271
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700272void CJS_PropValue::operator>>(bool& bValue) const {
273 ASSERT(m_bIsSetting);
274 bValue = CJS_Value::ToBool();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700275}
276
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277void CJS_PropValue::operator<<(double dValue) {
278 ASSERT(!m_bIsSetting);
279 CJS_Value::operator=(dValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700280}
281
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282void CJS_PropValue::operator>>(double& dValue) const {
283 ASSERT(m_bIsSetting);
284 dValue = CJS_Value::ToDouble();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700285}
286
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287void CJS_PropValue::operator<<(CJS_Object* pObj) {
288 ASSERT(!m_bIsSetting);
289 CJS_Value::operator=(pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700290}
291
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700292void CJS_PropValue::operator>>(CJS_Object*& ppObj) const {
293 ASSERT(m_bIsSetting);
294 ppObj = CJS_Value::ToCJSObject();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700295}
296
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700297void CJS_PropValue::operator<<(CJS_Document* pJsDoc) {
298 ASSERT(!m_bIsSetting);
299 CJS_Value::operator=(pJsDoc);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700300}
301
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700302void CJS_PropValue::operator>>(CJS_Document*& ppJsDoc) const {
303 ASSERT(m_bIsSetting);
304 ppJsDoc = static_cast<CJS_Document*>(CJS_Value::ToCJSObject());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700305}
306
Tom Sepez808a99e2015-09-10 12:28:37 -0700307void CJS_PropValue::operator<<(v8::Local<v8::Object> pObj) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700308 ASSERT(!m_bIsSetting);
309 CJS_Value::operator=(pObj);
JUN FANG33f6f0d2015-04-06 12:39:51 -0700310}
311
Tom Sepez808a99e2015-09-10 12:28:37 -0700312void CJS_PropValue::operator>>(v8::Local<v8::Object>& ppObj) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700313 ASSERT(m_bIsSetting);
314 ppObj = CJS_Value::ToV8Object();
JUN FANG33f6f0d2015-04-06 12:39:51 -0700315}
316
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700317void CJS_PropValue::StartSetting() {
318 m_bIsSetting = 1;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700319}
320
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700321void CJS_PropValue::StartGetting() {
322 m_bIsSetting = 0;
323}
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500324void CJS_PropValue::operator<<(CFX_ByteString str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700325 ASSERT(!m_bIsSetting);
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500326 CJS_Value::operator=(str.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700327}
328
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500329void CJS_PropValue::operator>>(CFX_ByteString& str) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700330 ASSERT(m_bIsSetting);
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500331 str = CJS_Value::ToCFXByteString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700332}
333
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700334void CJS_PropValue::operator<<(const FX_WCHAR* c_string) {
335 ASSERT(!m_bIsSetting);
336 CJS_Value::operator=(c_string);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700337}
338
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700339void CJS_PropValue::operator>>(CFX_WideString& wide_string) const {
340 ASSERT(m_bIsSetting);
341 wide_string = CJS_Value::ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700342}
343
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700344void CJS_PropValue::operator<<(CFX_WideString wide_string) {
345 ASSERT(!m_bIsSetting);
346 CJS_Value::operator=(wide_string.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700347}
348
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700349void CJS_PropValue::operator>>(CJS_Array& array) const {
350 ASSERT(m_bIsSetting);
351 ConvertToArray(array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700352}
353
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700354void CJS_PropValue::operator<<(CJS_Array& array) {
355 ASSERT(!m_bIsSetting);
356 CJS_Value::operator=(array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700357}
358
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700359void CJS_PropValue::operator>>(CJS_Date& date) const {
360 ASSERT(m_bIsSetting);
361 ConvertToDate(date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700362}
363
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700364void CJS_PropValue::operator<<(CJS_Date& date) {
365 ASSERT(!m_bIsSetting);
366 CJS_Value::operator=(date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700367}
368
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700369CJS_PropValue::operator v8::Local<v8::Value>() const {
370 return m_pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700371}
372
Dan Sinclairf766ad22016-03-14 13:51:24 -0400373CJS_Array::CJS_Array(CJS_Runtime* pRuntime) : m_pJSRuntime(pRuntime) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700374
375CJS_Array::~CJS_Array() {}
376
weili625ad662016-06-15 11:21:33 -0700377CJS_Array::CJS_Array(const CJS_Array& other) = default;
378
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700379void CJS_Array::Attach(v8::Local<v8::Array> pArray) {
380 m_pArray = pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700381}
382
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700383FX_BOOL CJS_Array::IsAttached() {
384 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700385}
386
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700387void CJS_Array::GetElement(unsigned index, CJS_Value& value) {
388 if (m_pArray.IsEmpty())
389 return;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700390 v8::Local<v8::Value> p =
391 FXJS_GetArrayElement(m_pJSRuntime->GetIsolate(), m_pArray, index);
tsepez40faa792016-07-15 17:58:02 -0700392 value.Attach(p);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700393}
394
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700395void CJS_Array::SetElement(unsigned index, CJS_Value value) {
396 if (m_pArray.IsEmpty())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700397 m_pArray = FXJS_NewArray(m_pJSRuntime->GetIsolate());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700398
Tom Sepez67fd5df2015-10-08 12:24:19 -0700399 FXJS_PutArrayElement(m_pJSRuntime->GetIsolate(), m_pArray, index,
400 value.ToV8Value());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700401}
402
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700403int CJS_Array::GetLength() {
404 if (m_pArray.IsEmpty())
405 return 0;
Tom Sepez39bfe122015-09-17 15:25:23 -0700406 return FXJS_GetArrayLength(m_pArray);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700407}
408
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700409CJS_Array::operator v8::Local<v8::Array>() {
410 if (m_pArray.IsEmpty())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700411 m_pArray = FXJS_NewArray(m_pJSRuntime->GetIsolate());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700412
413 return m_pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700414}
415
Dan Sinclairf766ad22016-03-14 13:51:24 -0400416CJS_Date::CJS_Date(CJS_Runtime* pRuntime) : m_pJSRuntime(pRuntime) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700417
Tom Sepez67fd5df2015-10-08 12:24:19 -0700418CJS_Date::CJS_Date(CJS_Runtime* pRuntime, double dMsecTime)
419 : m_pJSRuntime(pRuntime) {
420 m_pDate = FXJS_NewDate(pRuntime->GetIsolate(), dMsecTime);
421}
422
423CJS_Date::CJS_Date(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700424 int year,
425 int mon,
426 int day,
427 int hour,
428 int min,
Tom Sepez67fd5df2015-10-08 12:24:19 -0700429 int sec)
430 : m_pJSRuntime(pRuntime) {
431 m_pDate = FXJS_NewDate(pRuntime->GetIsolate(),
432 MakeDate(year, mon, day, hour, min, sec, 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700433}
434
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700435double CJS_Date::MakeDate(int year,
436 int mon,
437 int day,
438 int hour,
439 int min,
440 int sec,
441 int ms) {
442 return JS_MakeDate(JS_MakeDay(year, mon, day),
443 JS_MakeTime(hour, min, sec, ms));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700444}
445
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700446CJS_Date::~CJS_Date() {}
447
448FX_BOOL CJS_Date::IsValidDate() {
449 if (m_pDate.IsEmpty())
450 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700451 return !JS_PortIsNan(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700452}
453
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700454void CJS_Date::Attach(v8::Local<v8::Value> pDate) {
455 m_pDate = pDate;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700456}
457
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700458int CJS_Date::GetYear() {
459 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700460 return JS_GetYearFromTime(
461 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700462
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700463 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700464}
465
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700466void CJS_Date::SetYear(int iYear) {
467 double date = MakeDate(iYear, GetMonth(), GetDay(), GetHours(), GetMinutes(),
468 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700469 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700470}
471
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700472int CJS_Date::GetMonth() {
473 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700474 return JS_GetMonthFromTime(
475 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700476
477 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700478}
479
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700480void CJS_Date::SetMonth(int iMonth) {
481 double date = MakeDate(GetYear(), iMonth, GetDay(), GetHours(), GetMinutes(),
482 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700483 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700484}
485
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700486int CJS_Date::GetDay() {
487 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700488 return JS_GetDayFromTime(
489 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700490
491 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700492}
493
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700494void CJS_Date::SetDay(int iDay) {
495 double date = MakeDate(GetYear(), GetMonth(), iDay, GetHours(), GetMinutes(),
496 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700497 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700498}
499
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700500int CJS_Date::GetHours() {
501 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700502 return JS_GetHourFromTime(
503 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700504
505 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700506}
507
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700508void CJS_Date::SetHours(int iHours) {
509 double date = MakeDate(GetYear(), GetMonth(), GetDay(), iHours, GetMinutes(),
510 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700511 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700512}
513
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700514int CJS_Date::GetMinutes() {
515 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700516 return JS_GetMinFromTime(
517 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700518
519 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700520}
521
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700522void CJS_Date::SetMinutes(int minutes) {
523 double date = MakeDate(GetYear(), GetMonth(), GetDay(), GetHours(), minutes,
524 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700525 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700526}
527
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700528int CJS_Date::GetSeconds() {
529 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700530 return JS_GetSecFromTime(
531 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700532
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700533 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700534}
535
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700536void CJS_Date::SetSeconds(int seconds) {
537 double date = MakeDate(GetYear(), GetMonth(), GetDay(), GetHours(),
538 GetMinutes(), seconds, 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700539 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700540}
541
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700542CJS_Date::operator v8::Local<v8::Value>() {
543 return m_pDate;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700544}
545
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700546CJS_Date::operator double() const {
547 if (m_pDate.IsEmpty())
548 return 0.0;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700549 return FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700550}
551
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700552CFX_WideString CJS_Date::ToString() const {
553 if (m_pDate.IsEmpty())
554 return L"";
Tom Sepez67fd5df2015-10-08 12:24:19 -0700555 return FXJS_ToString(m_pJSRuntime->GetIsolate(), m_pDate);
Tom Sepez39bfe122015-09-17 15:25:23 -0700556}
557
558double _getLocalTZA() {
559 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
560 return 0;
561 time_t t = 0;
562 time(&t);
563 localtime(&t);
564#if _MSC_VER >= 1900
565 // In gcc and in Visual Studio prior to VS 2015 'timezone' is a global
566 // variable declared in time.h. That variable was deprecated and in VS 2015
567 // is removed, with _get_timezone replacing it.
568 long timezone = 0;
569 _get_timezone(&timezone);
570#endif
571 return (double)(-(timezone * 1000));
572}
573
574int _getDaylightSavingTA(double d) {
575 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
576 return 0;
577 time_t t = (time_t)(d / 1000);
578 struct tm* tmp = localtime(&t);
Lei Zhang412e9082015-12-14 18:34:00 -0800579 if (!tmp)
Tom Sepez39bfe122015-09-17 15:25:23 -0700580 return 0;
581 if (tmp->tm_isdst > 0)
582 // One hour.
583 return (int)60 * 60 * 1000;
584 return 0;
585}
586
587double _Mod(double x, double y) {
588 double r = fmod(x, y);
589 if (r < 0)
590 r += y;
591 return r;
592}
593
594int _isfinite(double v) {
595#if _MSC_VER
596 return ::_finite(v);
597#else
598 return std::fabs(v) < std::numeric_limits<double>::max();
599#endif
600}
601
602double _toInteger(double n) {
603 return (n >= 0) ? FXSYS_floor(n) : -FXSYS_floor(-n);
604}
605
606bool _isLeapYear(int year) {
607 return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
608}
609
610int _DayFromYear(int y) {
611 return (int)(365 * (y - 1970.0) + FXSYS_floor((y - 1969.0) / 4) -
612 FXSYS_floor((y - 1901.0) / 100) +
613 FXSYS_floor((y - 1601.0) / 400));
614}
615
616double _TimeFromYear(int y) {
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800617 return 86400000.0 * _DayFromYear(y);
Tom Sepez39bfe122015-09-17 15:25:23 -0700618}
619
Tom Sepez4161c5c2016-03-21 12:26:54 -0700620static const uint16_t daysMonth[12] = {0, 31, 59, 90, 120, 151,
621 181, 212, 243, 273, 304, 334};
622static const uint16_t leapDaysMonth[12] = {0, 31, 60, 91, 121, 152,
623 182, 213, 244, 274, 305, 335};
624
Tom Sepez39bfe122015-09-17 15:25:23 -0700625double _TimeFromYearMonth(int y, int m) {
Tom Sepez4161c5c2016-03-21 12:26:54 -0700626 const uint16_t* pMonth = _isLeapYear(y) ? leapDaysMonth : daysMonth;
Tom Sepez39bfe122015-09-17 15:25:23 -0700627 return _TimeFromYear(y) + ((double)pMonth[m]) * 86400000;
628}
629
630int _Day(double t) {
631 return (int)FXSYS_floor(t / 86400000);
632}
633
634int _YearFromTime(double t) {
635 // estimate the time.
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800636 int y = 1970 + static_cast<int>(t / (365.2425 * 86400000));
Tom Sepez39bfe122015-09-17 15:25:23 -0700637 if (_TimeFromYear(y) <= t) {
638 while (_TimeFromYear(y + 1) <= t)
639 y++;
Dan Sinclair738b08c2016-03-01 14:45:20 -0500640 } else {
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800641 while (_TimeFromYear(y) > t)
Tom Sepez39bfe122015-09-17 15:25:23 -0700642 y--;
Dan Sinclair738b08c2016-03-01 14:45:20 -0500643 }
Tom Sepez39bfe122015-09-17 15:25:23 -0700644 return y;
645}
646
647int _DayWithinYear(double t) {
648 int year = _YearFromTime(t);
649 int day = _Day(t);
650 return day - _DayFromYear(year);
651}
652
653int _MonthFromTime(double t) {
654 int day = _DayWithinYear(t);
655 int year = _YearFromTime(t);
656 if (0 <= day && day < 31)
657 return 0;
658 if (31 <= day && day < 59 + _isLeapYear(year))
659 return 1;
660 if ((59 + _isLeapYear(year)) <= day && day < (90 + _isLeapYear(year)))
661 return 2;
662 if ((90 + _isLeapYear(year)) <= day && day < (120 + _isLeapYear(year)))
663 return 3;
664 if ((120 + _isLeapYear(year)) <= day && day < (151 + _isLeapYear(year)))
665 return 4;
666 if ((151 + _isLeapYear(year)) <= day && day < (181 + _isLeapYear(year)))
667 return 5;
668 if ((181 + _isLeapYear(year)) <= day && day < (212 + _isLeapYear(year)))
669 return 6;
670 if ((212 + _isLeapYear(year)) <= day && day < (243 + _isLeapYear(year)))
671 return 7;
672 if ((243 + _isLeapYear(year)) <= day && day < (273 + _isLeapYear(year)))
673 return 8;
674 if ((273 + _isLeapYear(year)) <= day && day < (304 + _isLeapYear(year)))
675 return 9;
676 if ((304 + _isLeapYear(year)) <= day && day < (334 + _isLeapYear(year)))
677 return 10;
678 if ((334 + _isLeapYear(year)) <= day && day < (365 + _isLeapYear(year)))
679 return 11;
680
681 return -1;
682}
683
684int _DateFromTime(double t) {
685 int day = _DayWithinYear(t);
686 int year = _YearFromTime(t);
weili12367cb2016-06-03 11:22:16 -0700687 int leap = _isLeapYear(year);
Tom Sepez39bfe122015-09-17 15:25:23 -0700688 int month = _MonthFromTime(t);
689 switch (month) {
690 case 0:
691 return day + 1;
692 case 1:
693 return day - 30;
694 case 2:
695 return day - 58 - leap;
696 case 3:
697 return day - 89 - leap;
698 case 4:
699 return day - 119 - leap;
700 case 5:
701 return day - 150 - leap;
702 case 6:
703 return day - 180 - leap;
704 case 7:
705 return day - 211 - leap;
706 case 8:
707 return day - 242 - leap;
708 case 9:
709 return day - 272 - leap;
710 case 10:
711 return day - 303 - leap;
712 case 11:
713 return day - 333 - leap;
714 default:
715 return 0;
716 }
717}
718
719double JS_GetDateTime() {
720 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
721 return 0;
thestig1cd352e2016-06-07 17:53:06 -0700722 time_t t = time(nullptr);
Tom Sepez39bfe122015-09-17 15:25:23 -0700723 struct tm* pTm = localtime(&t);
724
725 int year = pTm->tm_year + 1900;
726 double t1 = _TimeFromYear(year);
727
728 return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
729 pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
730}
731
732int JS_GetYearFromTime(double dt) {
733 return _YearFromTime(dt);
734}
735
736int JS_GetMonthFromTime(double dt) {
737 return _MonthFromTime(dt);
738}
739
740int JS_GetDayFromTime(double dt) {
741 return _DateFromTime(dt);
742}
743
744int JS_GetHourFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700745 return (int)_Mod(floor(dt / (60 * 60 * 1000)), 24);
Tom Sepez39bfe122015-09-17 15:25:23 -0700746}
747
748int JS_GetMinFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700749 return (int)_Mod(floor(dt / (60 * 1000)), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700750}
751
752int JS_GetSecFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700753 return (int)_Mod(floor(dt / 1000), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700754}
755
tsepez018935c2016-04-15 13:15:12 -0700756double JS_DateParse(const CFX_WideString& str) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700757 v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
758 v8::Isolate::Scope isolate_scope(pIsolate);
759 v8::HandleScope scope(pIsolate);
760
761 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
762
763 // Use the built-in object method.
764 v8::Local<v8::Value> v =
765 context->Global()
766 ->Get(context, v8::String::NewFromUtf8(pIsolate, "Date",
767 v8::NewStringType::kNormal)
768 .ToLocalChecked())
769 .ToLocalChecked();
770 if (v->IsObject()) {
771 v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
772 v = o->Get(context, v8::String::NewFromUtf8(pIsolate, "parse",
773 v8::NewStringType::kNormal)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400774 .ToLocalChecked())
775 .ToLocalChecked();
Tom Sepez39bfe122015-09-17 15:25:23 -0700776 if (v->IsFunction()) {
777 v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);
Tom Sepez39bfe122015-09-17 15:25:23 -0700778 const int argc = 1;
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500779 v8::Local<v8::String> timeStr = FXJS_WSToJSString(pIsolate, str);
Tom Sepez39bfe122015-09-17 15:25:23 -0700780 v8::Local<v8::Value> argv[argc] = {timeStr};
781 v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
782 if (v->IsNumber()) {
783 double date = v->ToNumber(context).ToLocalChecked()->Value();
784 if (!_isfinite(date))
785 return date;
tsepez86a61dc2016-03-25 10:00:11 -0700786 return JS_LocalTime(date);
Tom Sepez39bfe122015-09-17 15:25:23 -0700787 }
788 }
789 }
790 return 0;
791}
792
793double JS_MakeDay(int nYear, int nMonth, int nDate) {
794 if (!_isfinite(nYear) || !_isfinite(nMonth) || !_isfinite(nDate))
795 return GetNan();
796 double y = _toInteger(nYear);
797 double m = _toInteger(nMonth);
798 double dt = _toInteger(nDate);
799 double ym = y + FXSYS_floor((double)m / 12);
800 double mn = _Mod(m, 12);
801
802 double t = _TimeFromYearMonth((int)ym, (int)mn);
803
804 if (_YearFromTime(t) != ym || _MonthFromTime(t) != mn ||
805 _DateFromTime(t) != 1)
806 return GetNan();
807 return _Day(t) + dt - 1;
808}
809
810double JS_MakeTime(int nHour, int nMin, int nSec, int nMs) {
811 if (!_isfinite(nHour) || !_isfinite(nMin) || !_isfinite(nSec) ||
812 !_isfinite(nMs))
813 return GetNan();
814
815 double h = _toInteger(nHour);
816 double m = _toInteger(nMin);
817 double s = _toInteger(nSec);
818 double milli = _toInteger(nMs);
819
820 return h * 3600000 + m * 60000 + s * 1000 + milli;
821}
822
823double JS_MakeDate(double day, double time) {
824 if (!_isfinite(day) || !_isfinite(time))
825 return GetNan();
826
827 return day * 86400000 + time;
828}
829
830bool JS_PortIsNan(double d) {
831 return d != d;
832}
833
834double JS_LocalTime(double d) {
tsepez86a61dc2016-03-25 10:00:11 -0700835 return d + _getLocalTZA() + _getDaylightSavingTA(d);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700836}
Tom Sepezbd932572016-01-29 09:10:41 -0800837
838std::vector<CJS_Value> JS_ExpandKeywordParams(
839 CJS_Runtime* pRuntime,
840 const std::vector<CJS_Value>& originals,
841 size_t nKeywords,
842 ...) {
843 ASSERT(nKeywords);
844
845 std::vector<CJS_Value> result(nKeywords, CJS_Value(pRuntime));
846 size_t size = std::min(originals.size(), nKeywords);
847 for (size_t i = 0; i < size; ++i)
848 result[i] = originals[i];
849
850 if (originals.size() != 1 || originals[0].GetType() != CJS_Value::VT_object ||
851 originals[0].IsArrayObject()) {
852 return result;
853 }
854 v8::Local<v8::Object> pObj = originals[0].ToV8Object();
855 result[0] = CJS_Value(pRuntime); // Make unknown.
856
857 va_list ap;
858 va_start(ap, nKeywords);
Wei Li89409932016-03-28 10:33:33 -0700859 for (size_t i = 0; i < nKeywords; ++i) {
Tom Sepezbd932572016-01-29 09:10:41 -0800860 const wchar_t* property = va_arg(ap, const wchar_t*);
861 v8::Local<v8::Value> v8Value =
862 FXJS_GetObjectElement(pRuntime->GetIsolate(), pObj, property);
863 if (!v8Value->IsUndefined())
tsepez40faa792016-07-15 17:58:02 -0700864 result[i] = CJS_Value(pRuntime, v8Value);
Tom Sepezbd932572016-01-29 09:10:41 -0800865 }
866 va_end(ap);
867 return result;
868}