blob: 5e403a524b6170b95ce6d356caf2d362216a70b4 [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
Tom Sepez39bfe122015-09-17 15:25:23 -070020static const FX_DWORD g_nan[2] = {0, 0x7FF80000};
21static double GetNan() {
22 return *(double*)g_nan;
23}
24
Tom Sepez67fd5df2015-10-08 12:24:19 -070025CJS_Value::CJS_Value(CJS_Runtime* pRuntime)
Dan Sinclairf766ad22016-03-14 13:51:24 -040026 : m_eType(VT_unknown), m_pJSRuntime(pRuntime) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -070027
Tom Sepez67fd5df2015-10-08 12:24:19 -070028CJS_Value::CJS_Value(CJS_Runtime* pRuntime, v8::Local<v8::Value> pValue, Type t)
Dan Sinclairf766ad22016-03-14 13:51:24 -040029 : m_eType(t), m_pValue(pValue), m_pJSRuntime(pRuntime) {}
Tom Sepez67fd5df2015-10-08 12:24:19 -070030
31CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const int& iValue)
32 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070033 operator=(iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070034}
35
Tom Sepez67fd5df2015-10-08 12:24:19 -070036CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const bool& bValue)
37 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070038 operator=(bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070039}
40
Tom Sepez67fd5df2015-10-08 12:24:19 -070041CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const float& fValue)
42 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070043 operator=(fValue);
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 double& dValue)
47 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070048 operator=(dValue);
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, v8::Local<v8::Object> pJsObj)
52 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070053 operator=(pJsObj);
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, CJS_Object* pJsObj)
57 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070058 operator=(pJsObj);
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_Document* pJsDoc)
62 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063 m_eType = VT_object;
64 if (pJsDoc)
Tom Sepez116e4ad2015-09-21 09:22:05 -070065 m_pValue = pJsDoc->ToV8Object();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070066}
67
Tom Sepez67fd5df2015-10-08 12:24:19 -070068CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_WCHAR* pWstr)
69 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070070 operator=(pWstr);
Tom Sepezf79a69c2014-10-30 13:23:42 -070071}
72
Tom Sepez67fd5df2015-10-08 12:24:19 -070073CJS_Value::CJS_Value(CJS_Runtime* pRuntime, const FX_CHAR* pStr)
74 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075 operator=(pStr);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070076}
77
Tom Sepez67fd5df2015-10-08 12:24:19 -070078CJS_Value::CJS_Value(CJS_Runtime* pRuntime, CJS_Array& array)
79 : m_pJSRuntime(pRuntime) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070080 operator=(array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070081}
82
Nico Weber9d8ec5a2015-08-04 13:00:21 -070083CJS_Value::~CJS_Value() {}
84
Tom Sepez39bfe122015-09-17 15:25:23 -070085void CJS_Value::Attach(v8::Local<v8::Value> pValue, Type t) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086 m_pValue = pValue;
87 m_eType = t;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070088}
89
Nico Weber9d8ec5a2015-08-04 13:00:21 -070090void CJS_Value::Attach(CJS_Value* pValue) {
91 if (pValue)
92 Attach(pValue->ToV8Value(), pValue->GetType());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070093}
94
Nico Weber9d8ec5a2015-08-04 13:00:21 -070095void CJS_Value::Detach() {
96 m_pValue = v8::Local<v8::Value>();
97 m_eType = VT_unknown;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070098}
99
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100int CJS_Value::ToInt() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700101 return FXJS_ToInt32(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700102}
103
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104bool CJS_Value::ToBool() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700105 return FXJS_ToBoolean(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700106}
107
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700108double CJS_Value::ToDouble() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700109 return FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700110}
111
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700112float CJS_Value::ToFloat() const {
113 return (float)ToDouble();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700114}
115
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700116CJS_Object* CJS_Value::ToCJSObject() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700117 v8::Local<v8::Object> pObj =
118 FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue);
119 return (CJS_Object*)FXJS_GetPrivate(m_pJSRuntime->GetIsolate(), pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700120}
121
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700122v8::Local<v8::Object> CJS_Value::ToV8Object() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700123 return FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700124}
125
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126CFX_WideString CJS_Value::ToCFXWideString() const {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700127 return FXJS_ToString(m_pJSRuntime->GetIsolate(), m_pValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700128}
129
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700130CFX_ByteString CJS_Value::ToCFXByteString() const {
131 return CFX_ByteString::FromUnicode(ToCFXWideString());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700132}
133
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700134v8::Local<v8::Value> CJS_Value::ToV8Value() const {
135 return m_pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700136}
137
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700138v8::Local<v8::Array> CJS_Value::ToV8Array() const {
139 if (IsArrayObject())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700140 return v8::Local<v8::Array>::Cast(
141 FXJS_ToObject(m_pJSRuntime->GetIsolate(), m_pValue));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700142 return v8::Local<v8::Array>();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700143}
144
Tom Sepez4246b002016-01-20 11:48:29 -0800145void CJS_Value::MaybeCoerceToNumber() {
146 bool bAllowNaN = false;
147 if (m_eType == VT_string) {
148 CFX_ByteString bstr = ToCFXByteString();
149 if (bstr.GetLength() == 0)
150 return;
151 if (bstr == "NaN")
152 bAllowNaN = true;
153 }
154 v8::TryCatch(m_pJSRuntime->GetIsolate());
155 v8::MaybeLocal<v8::Number> maybeNum =
156 m_pValue->ToNumber(m_pJSRuntime->GetIsolate()->GetCurrentContext());
157 if (maybeNum.IsEmpty())
158 return;
159 v8::Local<v8::Number> num = maybeNum.ToLocalChecked();
160 if (std::isnan(num->Value()) && !bAllowNaN)
161 return;
162 m_pValue = num;
163 m_eType = VT_number;
164}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700165
166void CJS_Value::operator=(int iValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700167 m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), iValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700168 m_eType = VT_number;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700169}
170
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700171void CJS_Value::operator=(bool bValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700172 m_pValue = FXJS_NewBoolean(m_pJSRuntime->GetIsolate(), bValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700173 m_eType = VT_boolean;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700174}
175
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176void CJS_Value::operator=(double dValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700177 m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), dValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700178 m_eType = VT_number;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700179}
180
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700181void CJS_Value::operator=(float fValue) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700182 m_pValue = FXJS_NewNumber(m_pJSRuntime->GetIsolate(), fValue);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700183 m_eType = VT_number;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700184}
185
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700186void CJS_Value::operator=(v8::Local<v8::Object> pObj) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700187 m_pValue = FXJS_NewObject(m_pJSRuntime->GetIsolate(), pObj);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188 m_eType = VT_fxobject;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700189}
190
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700191void CJS_Value::operator=(CJS_Object* pObj) {
192 if (pObj)
Tom Sepez116e4ad2015-09-21 09:22:05 -0700193 operator=(pObj->ToV8Object());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700194}
195
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700196void CJS_Value::operator=(CJS_Document* pJsDoc) {
197 m_eType = VT_object;
198 if (pJsDoc) {
Tom Sepez116e4ad2015-09-21 09:22:05 -0700199 m_pValue = pJsDoc->ToV8Object();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700201}
202
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700203void CJS_Value::operator=(const FX_WCHAR* pWstr) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700204 m_pValue = FXJS_NewString(m_pJSRuntime->GetIsolate(), (wchar_t*)pWstr);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700205 m_eType = VT_string;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700206}
207
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700208void CJS_Value::SetNull() {
Tom Sepez39bfe122015-09-17 15:25:23 -0700209 m_pValue = FXJS_NewNull();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210 m_eType = VT_null;
JUN FANG33f6f0d2015-04-06 12:39:51 -0700211}
212
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213void CJS_Value::operator=(const FX_CHAR* pStr) {
214 operator=(CFX_WideString::FromLocal(pStr).c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700215}
216
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217void CJS_Value::operator=(CJS_Array& array) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700218 m_pValue =
219 FXJS_NewObject2(m_pJSRuntime->GetIsolate(), (v8::Local<v8::Array>)array);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220 m_eType = VT_object;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700221}
222
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700223void CJS_Value::operator=(CJS_Date& date) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700224 m_pValue = FXJS_NewDate(m_pJSRuntime->GetIsolate(), (double)date);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700225 m_eType = VT_date;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700226}
227
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700228void CJS_Value::operator=(CJS_Value value) {
229 m_pValue = value.ToV8Value();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700230 m_eType = value.m_eType;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700231 m_pJSRuntime = value.m_pJSRuntime;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700232}
233
Tom Sepez39bfe122015-09-17 15:25:23 -0700234CJS_Value::Type CJS_Value::GetType() const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700235 if (m_pValue.IsEmpty())
236 return VT_unknown;
237 if (m_pValue->IsString())
238 return VT_string;
239 if (m_pValue->IsNumber())
240 return VT_number;
241 if (m_pValue->IsBoolean())
242 return VT_boolean;
243 if (m_pValue->IsDate())
244 return VT_date;
245 if (m_pValue->IsObject())
246 return VT_object;
247 if (m_pValue->IsNull())
248 return VT_null;
249 if (m_pValue->IsUndefined())
250 return VT_undefined;
251 return VT_unknown;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700252}
253
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700254FX_BOOL CJS_Value::IsArrayObject() const {
255 if (m_pValue.IsEmpty())
256 return FALSE;
257 return m_pValue->IsArray();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700258}
259
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700260FX_BOOL CJS_Value::IsDateObject() const {
261 if (m_pValue.IsEmpty())
262 return FALSE;
263 return m_pValue->IsDate();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700264}
265
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700266// CJS_Value::operator CJS_Array()
267FX_BOOL CJS_Value::ConvertToArray(CJS_Array& array) const {
268 if (IsArrayObject()) {
Tom Sepez67fd5df2015-10-08 12:24:19 -0700269 array.Attach(FXJS_ToArray(m_pJSRuntime->GetIsolate(), m_pValue));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700270 return TRUE;
271 }
272
273 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700274}
275
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700276FX_BOOL CJS_Value::ConvertToDate(CJS_Date& date) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700277 if (IsDateObject()) {
278 date.Attach(m_pValue);
279 return TRUE;
280 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700281
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700282 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700283}
284
285/* ---------------------------- CJS_PropValue ---------------------------- */
286
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700287CJS_PropValue::CJS_PropValue(const CJS_Value& value)
288 : CJS_Value(value), m_bIsSetting(0) {}
289
Tom Sepez67fd5df2015-10-08 12:24:19 -0700290CJS_PropValue::CJS_PropValue(CJS_Runtime* pRuntime)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400291 : CJS_Value(pRuntime), m_bIsSetting(0) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700292
Dan Sinclairf766ad22016-03-14 13:51:24 -0400293CJS_PropValue::~CJS_PropValue() {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700294
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700295void CJS_PropValue::operator<<(int iValue) {
296 ASSERT(!m_bIsSetting);
297 CJS_Value::operator=(iValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700298}
299
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700300void CJS_PropValue::operator>>(int& iValue) const {
301 ASSERT(m_bIsSetting);
302 iValue = CJS_Value::ToInt();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700303}
304
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700305void CJS_PropValue::operator<<(bool bValue) {
306 ASSERT(!m_bIsSetting);
307 CJS_Value::operator=(bValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700308}
309
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700310void CJS_PropValue::operator>>(bool& bValue) const {
311 ASSERT(m_bIsSetting);
312 bValue = CJS_Value::ToBool();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700313}
314
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700315void CJS_PropValue::operator<<(double dValue) {
316 ASSERT(!m_bIsSetting);
317 CJS_Value::operator=(dValue);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700318}
319
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700320void CJS_PropValue::operator>>(double& dValue) const {
321 ASSERT(m_bIsSetting);
322 dValue = CJS_Value::ToDouble();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700323}
324
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700325void CJS_PropValue::operator<<(CJS_Object* pObj) {
326 ASSERT(!m_bIsSetting);
327 CJS_Value::operator=(pObj);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700328}
329
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700330void CJS_PropValue::operator>>(CJS_Object*& ppObj) const {
331 ASSERT(m_bIsSetting);
332 ppObj = CJS_Value::ToCJSObject();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700333}
334
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700335void CJS_PropValue::operator<<(CJS_Document* pJsDoc) {
336 ASSERT(!m_bIsSetting);
337 CJS_Value::operator=(pJsDoc);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700338}
339
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700340void CJS_PropValue::operator>>(CJS_Document*& ppJsDoc) const {
341 ASSERT(m_bIsSetting);
342 ppJsDoc = static_cast<CJS_Document*>(CJS_Value::ToCJSObject());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700343}
344
Tom Sepez808a99e2015-09-10 12:28:37 -0700345void CJS_PropValue::operator<<(v8::Local<v8::Object> pObj) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700346 ASSERT(!m_bIsSetting);
347 CJS_Value::operator=(pObj);
JUN FANG33f6f0d2015-04-06 12:39:51 -0700348}
349
Tom Sepez808a99e2015-09-10 12:28:37 -0700350void CJS_PropValue::operator>>(v8::Local<v8::Object>& ppObj) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700351 ASSERT(m_bIsSetting);
352 ppObj = CJS_Value::ToV8Object();
JUN FANG33f6f0d2015-04-06 12:39:51 -0700353}
354
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700355void CJS_PropValue::StartSetting() {
356 m_bIsSetting = 1;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700357}
358
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700359void CJS_PropValue::StartGetting() {
360 m_bIsSetting = 0;
361}
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500362void CJS_PropValue::operator<<(CFX_ByteString str) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700363 ASSERT(!m_bIsSetting);
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500364 CJS_Value::operator=(str.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700365}
366
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500367void CJS_PropValue::operator>>(CFX_ByteString& str) const {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700368 ASSERT(m_bIsSetting);
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500369 str = CJS_Value::ToCFXByteString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700370}
371
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700372void CJS_PropValue::operator<<(const FX_WCHAR* c_string) {
373 ASSERT(!m_bIsSetting);
374 CJS_Value::operator=(c_string);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700375}
376
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700377void CJS_PropValue::operator>>(CFX_WideString& wide_string) const {
378 ASSERT(m_bIsSetting);
379 wide_string = CJS_Value::ToCFXWideString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700380}
381
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700382void CJS_PropValue::operator<<(CFX_WideString wide_string) {
383 ASSERT(!m_bIsSetting);
384 CJS_Value::operator=(wide_string.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700385}
386
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700387void CJS_PropValue::operator>>(CJS_Array& array) const {
388 ASSERT(m_bIsSetting);
389 ConvertToArray(array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700390}
391
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700392void CJS_PropValue::operator<<(CJS_Array& array) {
393 ASSERT(!m_bIsSetting);
394 CJS_Value::operator=(array);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700395}
396
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700397void CJS_PropValue::operator>>(CJS_Date& date) const {
398 ASSERT(m_bIsSetting);
399 ConvertToDate(date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700400}
401
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700402void CJS_PropValue::operator<<(CJS_Date& date) {
403 ASSERT(!m_bIsSetting);
404 CJS_Value::operator=(date);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700405}
406
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700407CJS_PropValue::operator v8::Local<v8::Value>() const {
408 return m_pValue;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700409}
410
Dan Sinclairf766ad22016-03-14 13:51:24 -0400411CJS_Array::CJS_Array(CJS_Runtime* pRuntime) : m_pJSRuntime(pRuntime) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700412
413CJS_Array::~CJS_Array() {}
414
415void CJS_Array::Attach(v8::Local<v8::Array> pArray) {
416 m_pArray = pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700417}
418
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700419FX_BOOL CJS_Array::IsAttached() {
420 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700421}
422
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700423void CJS_Array::GetElement(unsigned index, CJS_Value& value) {
424 if (m_pArray.IsEmpty())
425 return;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700426 v8::Local<v8::Value> p =
427 FXJS_GetArrayElement(m_pJSRuntime->GetIsolate(), m_pArray, index);
Tom Sepez39bfe122015-09-17 15:25:23 -0700428 value.Attach(p, CJS_Value::VT_object);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700429}
430
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700431void CJS_Array::SetElement(unsigned index, CJS_Value value) {
432 if (m_pArray.IsEmpty())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700433 m_pArray = FXJS_NewArray(m_pJSRuntime->GetIsolate());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700434
Tom Sepez67fd5df2015-10-08 12:24:19 -0700435 FXJS_PutArrayElement(m_pJSRuntime->GetIsolate(), m_pArray, index,
436 value.ToV8Value());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700437}
438
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700439int CJS_Array::GetLength() {
440 if (m_pArray.IsEmpty())
441 return 0;
Tom Sepez39bfe122015-09-17 15:25:23 -0700442 return FXJS_GetArrayLength(m_pArray);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700443}
444
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700445CJS_Array::operator v8::Local<v8::Array>() {
446 if (m_pArray.IsEmpty())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700447 m_pArray = FXJS_NewArray(m_pJSRuntime->GetIsolate());
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700448
449 return m_pArray;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700450}
451
Dan Sinclairf766ad22016-03-14 13:51:24 -0400452CJS_Date::CJS_Date(CJS_Runtime* pRuntime) : m_pJSRuntime(pRuntime) {}
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700453
Tom Sepez67fd5df2015-10-08 12:24:19 -0700454CJS_Date::CJS_Date(CJS_Runtime* pRuntime, double dMsecTime)
455 : m_pJSRuntime(pRuntime) {
456 m_pDate = FXJS_NewDate(pRuntime->GetIsolate(), dMsecTime);
457}
458
459CJS_Date::CJS_Date(CJS_Runtime* pRuntime,
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700460 int year,
461 int mon,
462 int day,
463 int hour,
464 int min,
Tom Sepez67fd5df2015-10-08 12:24:19 -0700465 int sec)
466 : m_pJSRuntime(pRuntime) {
467 m_pDate = FXJS_NewDate(pRuntime->GetIsolate(),
468 MakeDate(year, mon, day, hour, min, sec, 0));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700469}
470
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700471double CJS_Date::MakeDate(int year,
472 int mon,
473 int day,
474 int hour,
475 int min,
476 int sec,
477 int ms) {
478 return JS_MakeDate(JS_MakeDay(year, mon, day),
479 JS_MakeTime(hour, min, sec, ms));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700480}
481
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700482CJS_Date::~CJS_Date() {}
483
484FX_BOOL CJS_Date::IsValidDate() {
485 if (m_pDate.IsEmpty())
486 return FALSE;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700487 return !JS_PortIsNan(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700488}
489
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700490void CJS_Date::Attach(v8::Local<v8::Value> pDate) {
491 m_pDate = pDate;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700492}
493
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700494int CJS_Date::GetYear() {
495 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700496 return JS_GetYearFromTime(
497 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700498
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700499 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700500}
501
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700502void CJS_Date::SetYear(int iYear) {
503 double date = MakeDate(iYear, GetMonth(), GetDay(), GetHours(), GetMinutes(),
504 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700505 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700506}
507
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700508int CJS_Date::GetMonth() {
509 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700510 return JS_GetMonthFromTime(
511 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700512
513 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700514}
515
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700516void CJS_Date::SetMonth(int iMonth) {
517 double date = MakeDate(GetYear(), iMonth, GetDay(), GetHours(), GetMinutes(),
518 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700519 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700520}
521
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700522int CJS_Date::GetDay() {
523 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700524 return JS_GetDayFromTime(
525 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700526
527 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700528}
529
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700530void CJS_Date::SetDay(int iDay) {
531 double date = MakeDate(GetYear(), GetMonth(), iDay, GetHours(), GetMinutes(),
532 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700533 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700534}
535
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700536int CJS_Date::GetHours() {
537 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700538 return JS_GetHourFromTime(
539 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700540
541 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700542}
543
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700544void CJS_Date::SetHours(int iHours) {
545 double date = MakeDate(GetYear(), GetMonth(), GetDay(), iHours, GetMinutes(),
546 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700547 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700548}
549
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700550int CJS_Date::GetMinutes() {
551 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700552 return JS_GetMinFromTime(
553 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700554
555 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700556}
557
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700558void CJS_Date::SetMinutes(int minutes) {
559 double date = MakeDate(GetYear(), GetMonth(), GetDay(), GetHours(), minutes,
560 GetSeconds(), 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700561 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700562}
563
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700564int CJS_Date::GetSeconds() {
565 if (IsValidDate())
Tom Sepez67fd5df2015-10-08 12:24:19 -0700566 return JS_GetSecFromTime(
567 JS_LocalTime(FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate)));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700568
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700569 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700570}
571
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700572void CJS_Date::SetSeconds(int seconds) {
573 double date = MakeDate(GetYear(), GetMonth(), GetDay(), GetHours(),
574 GetMinutes(), seconds, 0);
Tom Sepez67fd5df2015-10-08 12:24:19 -0700575 FXJS_ValueCopy(m_pDate, FXJS_NewDate(m_pJSRuntime->GetIsolate(), date));
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700576}
577
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700578CJS_Date::operator v8::Local<v8::Value>() {
579 return m_pDate;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700580}
581
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700582CJS_Date::operator double() const {
583 if (m_pDate.IsEmpty())
584 return 0.0;
Tom Sepez67fd5df2015-10-08 12:24:19 -0700585 return FXJS_ToNumber(m_pJSRuntime->GetIsolate(), m_pDate);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700586}
587
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700588CFX_WideString CJS_Date::ToString() const {
589 if (m_pDate.IsEmpty())
590 return L"";
Tom Sepez67fd5df2015-10-08 12:24:19 -0700591 return FXJS_ToString(m_pJSRuntime->GetIsolate(), m_pDate);
Tom Sepez39bfe122015-09-17 15:25:23 -0700592}
593
594double _getLocalTZA() {
595 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
596 return 0;
597 time_t t = 0;
598 time(&t);
599 localtime(&t);
600#if _MSC_VER >= 1900
601 // In gcc and in Visual Studio prior to VS 2015 'timezone' is a global
602 // variable declared in time.h. That variable was deprecated and in VS 2015
603 // is removed, with _get_timezone replacing it.
604 long timezone = 0;
605 _get_timezone(&timezone);
606#endif
607 return (double)(-(timezone * 1000));
608}
609
610int _getDaylightSavingTA(double d) {
611 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
612 return 0;
613 time_t t = (time_t)(d / 1000);
614 struct tm* tmp = localtime(&t);
Lei Zhang412e9082015-12-14 18:34:00 -0800615 if (!tmp)
Tom Sepez39bfe122015-09-17 15:25:23 -0700616 return 0;
617 if (tmp->tm_isdst > 0)
618 // One hour.
619 return (int)60 * 60 * 1000;
620 return 0;
621}
622
623double _Mod(double x, double y) {
624 double r = fmod(x, y);
625 if (r < 0)
626 r += y;
627 return r;
628}
629
630int _isfinite(double v) {
631#if _MSC_VER
632 return ::_finite(v);
633#else
634 return std::fabs(v) < std::numeric_limits<double>::max();
635#endif
636}
637
638double _toInteger(double n) {
639 return (n >= 0) ? FXSYS_floor(n) : -FXSYS_floor(-n);
640}
641
642bool _isLeapYear(int year) {
643 return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
644}
645
646int _DayFromYear(int y) {
647 return (int)(365 * (y - 1970.0) + FXSYS_floor((y - 1969.0) / 4) -
648 FXSYS_floor((y - 1901.0) / 100) +
649 FXSYS_floor((y - 1601.0) / 400));
650}
651
652double _TimeFromYear(int y) {
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800653 return 86400000.0 * _DayFromYear(y);
Tom Sepez39bfe122015-09-17 15:25:23 -0700654}
655
Tom Sepez4161c5c2016-03-21 12:26:54 -0700656static const uint16_t daysMonth[12] = {0, 31, 59, 90, 120, 151,
657 181, 212, 243, 273, 304, 334};
658static const uint16_t leapDaysMonth[12] = {0, 31, 60, 91, 121, 152,
659 182, 213, 244, 274, 305, 335};
660
Tom Sepez39bfe122015-09-17 15:25:23 -0700661double _TimeFromYearMonth(int y, int m) {
Tom Sepez4161c5c2016-03-21 12:26:54 -0700662 const uint16_t* pMonth = _isLeapYear(y) ? leapDaysMonth : daysMonth;
Tom Sepez39bfe122015-09-17 15:25:23 -0700663 return _TimeFromYear(y) + ((double)pMonth[m]) * 86400000;
664}
665
666int _Day(double t) {
667 return (int)FXSYS_floor(t / 86400000);
668}
669
670int _YearFromTime(double t) {
671 // estimate the time.
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800672 int y = 1970 + static_cast<int>(t / (365.2425 * 86400000));
Tom Sepez39bfe122015-09-17 15:25:23 -0700673 if (_TimeFromYear(y) <= t) {
674 while (_TimeFromYear(y + 1) <= t)
675 y++;
Dan Sinclair738b08c2016-03-01 14:45:20 -0500676 } else {
Lei Zhang1ac47eb2015-12-21 11:04:44 -0800677 while (_TimeFromYear(y) > t)
Tom Sepez39bfe122015-09-17 15:25:23 -0700678 y--;
Dan Sinclair738b08c2016-03-01 14:45:20 -0500679 }
Tom Sepez39bfe122015-09-17 15:25:23 -0700680 return y;
681}
682
683int _DayWithinYear(double t) {
684 int year = _YearFromTime(t);
685 int day = _Day(t);
686 return day - _DayFromYear(year);
687}
688
689int _MonthFromTime(double t) {
690 int day = _DayWithinYear(t);
691 int year = _YearFromTime(t);
692 if (0 <= day && day < 31)
693 return 0;
694 if (31 <= day && day < 59 + _isLeapYear(year))
695 return 1;
696 if ((59 + _isLeapYear(year)) <= day && day < (90 + _isLeapYear(year)))
697 return 2;
698 if ((90 + _isLeapYear(year)) <= day && day < (120 + _isLeapYear(year)))
699 return 3;
700 if ((120 + _isLeapYear(year)) <= day && day < (151 + _isLeapYear(year)))
701 return 4;
702 if ((151 + _isLeapYear(year)) <= day && day < (181 + _isLeapYear(year)))
703 return 5;
704 if ((181 + _isLeapYear(year)) <= day && day < (212 + _isLeapYear(year)))
705 return 6;
706 if ((212 + _isLeapYear(year)) <= day && day < (243 + _isLeapYear(year)))
707 return 7;
708 if ((243 + _isLeapYear(year)) <= day && day < (273 + _isLeapYear(year)))
709 return 8;
710 if ((273 + _isLeapYear(year)) <= day && day < (304 + _isLeapYear(year)))
711 return 9;
712 if ((304 + _isLeapYear(year)) <= day && day < (334 + _isLeapYear(year)))
713 return 10;
714 if ((334 + _isLeapYear(year)) <= day && day < (365 + _isLeapYear(year)))
715 return 11;
716
717 return -1;
718}
719
720int _DateFromTime(double t) {
721 int day = _DayWithinYear(t);
722 int year = _YearFromTime(t);
723 bool leap = _isLeapYear(year);
724 int month = _MonthFromTime(t);
725 switch (month) {
726 case 0:
727 return day + 1;
728 case 1:
729 return day - 30;
730 case 2:
731 return day - 58 - leap;
732 case 3:
733 return day - 89 - leap;
734 case 4:
735 return day - 119 - leap;
736 case 5:
737 return day - 150 - leap;
738 case 6:
739 return day - 180 - leap;
740 case 7:
741 return day - 211 - leap;
742 case 8:
743 return day - 242 - leap;
744 case 9:
745 return day - 272 - leap;
746 case 10:
747 return day - 303 - leap;
748 case 11:
749 return day - 333 - leap;
750 default:
751 return 0;
752 }
753}
754
755double JS_GetDateTime() {
756 if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
757 return 0;
758 time_t t = time(NULL);
759 struct tm* pTm = localtime(&t);
760
761 int year = pTm->tm_year + 1900;
762 double t1 = _TimeFromYear(year);
763
764 return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
765 pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
766}
767
768int JS_GetYearFromTime(double dt) {
769 return _YearFromTime(dt);
770}
771
772int JS_GetMonthFromTime(double dt) {
773 return _MonthFromTime(dt);
774}
775
776int JS_GetDayFromTime(double dt) {
777 return _DateFromTime(dt);
778}
779
780int JS_GetHourFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700781 return (int)_Mod(floor(dt / (60 * 60 * 1000)), 24);
Tom Sepez39bfe122015-09-17 15:25:23 -0700782}
783
784int JS_GetMinFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700785 return (int)_Mod(floor(dt / (60 * 1000)), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700786}
787
788int JS_GetSecFromTime(double dt) {
tsepez86a61dc2016-03-25 10:00:11 -0700789 return (int)_Mod(floor(dt / 1000), 60);
Tom Sepez39bfe122015-09-17 15:25:23 -0700790}
791
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500792double JS_DateParse(const wchar_t* str) {
Tom Sepez39bfe122015-09-17 15:25:23 -0700793 v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
794 v8::Isolate::Scope isolate_scope(pIsolate);
795 v8::HandleScope scope(pIsolate);
796
797 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
798
799 // Use the built-in object method.
800 v8::Local<v8::Value> v =
801 context->Global()
802 ->Get(context, v8::String::NewFromUtf8(pIsolate, "Date",
803 v8::NewStringType::kNormal)
804 .ToLocalChecked())
805 .ToLocalChecked();
806 if (v->IsObject()) {
807 v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
808 v = o->Get(context, v8::String::NewFromUtf8(pIsolate, "parse",
809 v8::NewStringType::kNormal)
Dan Sinclairf766ad22016-03-14 13:51:24 -0400810 .ToLocalChecked())
811 .ToLocalChecked();
Tom Sepez39bfe122015-09-17 15:25:23 -0700812 if (v->IsFunction()) {
813 v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);
814
815 const int argc = 1;
Dan Sinclair3ebd1212016-03-09 09:59:23 -0500816 v8::Local<v8::String> timeStr = FXJS_WSToJSString(pIsolate, str);
Tom Sepez39bfe122015-09-17 15:25:23 -0700817 v8::Local<v8::Value> argv[argc] = {timeStr};
818 v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
819 if (v->IsNumber()) {
820 double date = v->ToNumber(context).ToLocalChecked()->Value();
821 if (!_isfinite(date))
822 return date;
tsepez86a61dc2016-03-25 10:00:11 -0700823 return JS_LocalTime(date);
Tom Sepez39bfe122015-09-17 15:25:23 -0700824 }
825 }
826 }
827 return 0;
828}
829
830double JS_MakeDay(int nYear, int nMonth, int nDate) {
831 if (!_isfinite(nYear) || !_isfinite(nMonth) || !_isfinite(nDate))
832 return GetNan();
833 double y = _toInteger(nYear);
834 double m = _toInteger(nMonth);
835 double dt = _toInteger(nDate);
836 double ym = y + FXSYS_floor((double)m / 12);
837 double mn = _Mod(m, 12);
838
839 double t = _TimeFromYearMonth((int)ym, (int)mn);
840
841 if (_YearFromTime(t) != ym || _MonthFromTime(t) != mn ||
842 _DateFromTime(t) != 1)
843 return GetNan();
844 return _Day(t) + dt - 1;
845}
846
847double JS_MakeTime(int nHour, int nMin, int nSec, int nMs) {
848 if (!_isfinite(nHour) || !_isfinite(nMin) || !_isfinite(nSec) ||
849 !_isfinite(nMs))
850 return GetNan();
851
852 double h = _toInteger(nHour);
853 double m = _toInteger(nMin);
854 double s = _toInteger(nSec);
855 double milli = _toInteger(nMs);
856
857 return h * 3600000 + m * 60000 + s * 1000 + milli;
858}
859
860double JS_MakeDate(double day, double time) {
861 if (!_isfinite(day) || !_isfinite(time))
862 return GetNan();
863
864 return day * 86400000 + time;
865}
866
867bool JS_PortIsNan(double d) {
868 return d != d;
869}
870
871double JS_LocalTime(double d) {
tsepez86a61dc2016-03-25 10:00:11 -0700872 return d + _getLocalTZA() + _getDaylightSavingTA(d);
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700873}
Tom Sepezbd932572016-01-29 09:10:41 -0800874
875std::vector<CJS_Value> JS_ExpandKeywordParams(
876 CJS_Runtime* pRuntime,
877 const std::vector<CJS_Value>& originals,
878 size_t nKeywords,
879 ...) {
880 ASSERT(nKeywords);
881
882 std::vector<CJS_Value> result(nKeywords, CJS_Value(pRuntime));
883 size_t size = std::min(originals.size(), nKeywords);
884 for (size_t i = 0; i < size; ++i)
885 result[i] = originals[i];
886
887 if (originals.size() != 1 || originals[0].GetType() != CJS_Value::VT_object ||
888 originals[0].IsArrayObject()) {
889 return result;
890 }
891 v8::Local<v8::Object> pObj = originals[0].ToV8Object();
892 result[0] = CJS_Value(pRuntime); // Make unknown.
893
894 va_list ap;
895 va_start(ap, nKeywords);
896 for (int i = 0; i < nKeywords; ++i) {
897 const wchar_t* property = va_arg(ap, const wchar_t*);
898 v8::Local<v8::Value> v8Value =
899 FXJS_GetObjectElement(pRuntime->GetIsolate(), pObj, property);
900 if (!v8Value->IsUndefined())
901 result[i] = CJS_Value(pRuntime, v8Value, CJS_Value::VT_unknown);
902 }
903 va_end(ap);
904 return result;
905}