// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../../core/include/fxcrt/fx_basic.h"
#include "../../../core/include/fxcrt/fx_ext.h"
#include "../../include/jsapi/fxjs_v8.h"
#include "../../include/fsdk_define.h"
#include "time.h"
#include <cmath>
#include <limits>

#define VALUE_NAME_STRING L"string"
#define VALUE_NAME_NUMBER L"number"
#define VALUE_NAME_BOOLEAN L"boolean"
#define VALUE_NAME_DATE L"date"
#define VALUE_NAME_OBJECT L"object"
#define VALUE_NAME_FXOBJ L"fxobj"
#define VALUE_NAME_NULL L"null"
#define VALUE_NAME_UNDEFINED L"undefined"

const static FX_DWORD g_nan[2] = {0, 0x7FF80000};
static double GetNan() {
  return *(double*)g_nan;
}
static unsigned int g_embedderDataSlot = 0u;

class CJS_PrivateData {
 public:
  CJS_PrivateData() : ObjDefID(-1), pPrivate(NULL) {}
  int ObjDefID;
  void* pPrivate;
};

class CJS_ObjDefintion {
 public:
  CJS_ObjDefintion(v8::Isolate* isolate,
                   const wchar_t* sObjName,
                   FXJSOBJTYPE eObjType,
                   LP_CONSTRUCTOR pConstructor,
                   LP_DESTRUCTOR pDestructor)
      : objName(sObjName),
        objType(eObjType),
        m_pConstructor(pConstructor),
        m_pDestructor(pDestructor),
        m_bSetAsGlobalObject(FALSE) {
    v8::Isolate::Scope isolate_scope(isolate);
    v8::HandleScope handle_scope(isolate);

    v8::Local<v8::ObjectTemplate> objTemplate =
        v8::ObjectTemplate::New(isolate);
    objTemplate->SetInternalFieldCount(2);
    m_objTemplate.Reset(isolate, objTemplate);

    // Document as the global object.
    if (FXSYS_wcscmp(sObjName, L"Document") == 0) {
      m_bSetAsGlobalObject = TRUE;
    }
  }
  ~CJS_ObjDefintion() {
    m_objTemplate.Reset();
    m_StaticObj.Reset();
  }

 public:
  const wchar_t* objName;
  FXJSOBJTYPE objType;
  LP_CONSTRUCTOR m_pConstructor;
  LP_DESTRUCTOR m_pDestructor;
  FX_BOOL m_bSetAsGlobalObject;

  v8::Global<v8::ObjectTemplate> m_objTemplate;
  v8::Global<v8::Object> m_StaticObj;
};

int JS_DefineObj(v8::Isolate* pIsolate,
                 const wchar_t* sObjName,
                 FXJSOBJTYPE eObjType,
                 LP_CONSTRUCTOR pConstructor,
                 LP_DESTRUCTOR pDestructor) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope handle_scope(pIsolate);
  CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot);
  if (!pArray) {
    pArray = new CFX_PtrArray();
    pIsolate->SetData(g_embedderDataSlot, pArray);
  }
  CJS_ObjDefintion* pObjDef = new CJS_ObjDefintion(pIsolate, sObjName, eObjType,
                                                   pConstructor, pDestructor);
  pArray->Add(pObjDef);
  return pArray->GetSize() - 1;
}

int JS_DefineObjMethod(v8::Isolate* pIsolate,
                       int nObjDefnID,
                       const wchar_t* sMethodName,
                       v8::FunctionCallback pMethodCall) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope handle_scope(pIsolate);

  CFX_WideString ws = CFX_WideString(sMethodName);
  CFX_ByteString bsMethodName = ws.UTF8Encode();

  CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot);
  if (!pArray)
    return 0;

  if (nObjDefnID < 0 || nObjDefnID >= pArray->GetSize())
    return 0;
  CJS_ObjDefintion* pObjDef = (CJS_ObjDefintion*)pArray->GetAt(nObjDefnID);
  v8::Local<v8::ObjectTemplate> objTemp =
      v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate);
  objTemp->Set(
      v8::String::NewFromUtf8(pIsolate, bsMethodName.c_str(),
                              v8::NewStringType::kNormal).ToLocalChecked(),
      v8::FunctionTemplate::New(pIsolate, pMethodCall), v8::ReadOnly);
  pObjDef->m_objTemplate.Reset(pIsolate, objTemp);
  return 0;
}

int JS_DefineObjProperty(v8::Isolate* pIsolate,
                         int nObjDefnID,
                         const wchar_t* sPropName,
                         v8::AccessorGetterCallback pPropGet,
                         v8::AccessorSetterCallback pPropPut) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope handle_scope(pIsolate);

  CFX_WideString ws = CFX_WideString(sPropName);
  CFX_ByteString bsPropertyName = ws.UTF8Encode();

  CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot);
  if (!pArray)
    return 0;

  if (nObjDefnID < 0 || nObjDefnID >= pArray->GetSize())
    return 0;
  CJS_ObjDefintion* pObjDef = (CJS_ObjDefintion*)pArray->GetAt(nObjDefnID);
  v8::Local<v8::ObjectTemplate> objTemp =
      v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate);
  objTemp->SetAccessor(
      v8::String::NewFromUtf8(pIsolate, bsPropertyName.c_str(),
                              v8::NewStringType::kNormal).ToLocalChecked(),
      pPropGet, pPropPut);
  pObjDef->m_objTemplate.Reset(pIsolate, objTemp);
  return 0;
}

int JS_DefineObjAllProperties(v8::Isolate* pIsolate,
                              int nObjDefnID,
                              v8::NamedPropertyQueryCallback pPropQurey,
                              v8::NamedPropertyGetterCallback pPropGet,
                              v8::NamedPropertySetterCallback pPropPut,
                              v8::NamedPropertyDeleterCallback pPropDel) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope handle_scope(pIsolate);

  CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot);
  if (!pArray)
    return 0;

  if (nObjDefnID < 0 || nObjDefnID >= pArray->GetSize())
    return 0;
  CJS_ObjDefintion* pObjDef = (CJS_ObjDefintion*)pArray->GetAt(nObjDefnID);
  v8::Local<v8::ObjectTemplate> objTemp =
      v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate);
  objTemp->SetNamedPropertyHandler(pPropGet, pPropPut, pPropQurey, pPropDel);
  pObjDef->m_objTemplate.Reset(pIsolate, objTemp);
  return 0;
}

int JS_DefineObjConst(v8::Isolate* pIsolate,
                      int nObjDefnID,
                      const wchar_t* sConstName,
                      v8::Local<v8::Value> pDefault) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope handle_scope(pIsolate);

  CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot);
  if (!pArray)
    return 0;

  CFX_WideString ws = CFX_WideString(sConstName);
  CFX_ByteString bsConstName = ws.UTF8Encode();

  if (nObjDefnID < 0 || nObjDefnID >= pArray->GetSize())
    return 0;
  CJS_ObjDefintion* pObjDef = (CJS_ObjDefintion*)pArray->GetAt(nObjDefnID);
  v8::Local<v8::ObjectTemplate> objTemp =
      v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate);
  objTemp->Set(pIsolate, bsConstName.c_str(), pDefault);
  pObjDef->m_objTemplate.Reset(pIsolate, objTemp);
  return 0;
}

static v8::Global<v8::ObjectTemplate>& _getGlobalObjectTemplate(
    v8::Isolate* pIsolate) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope handle_scope(pIsolate);

  CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot);
  ASSERT(pArray != NULL);
  for (int i = 0; i < pArray->GetSize(); i++) {
    CJS_ObjDefintion* pObjDef = (CJS_ObjDefintion*)pArray->GetAt(i);
    if (pObjDef->m_bSetAsGlobalObject)
      return pObjDef->m_objTemplate;
  }
  static v8::Global<v8::ObjectTemplate> gloabalObjectTemplate;
  return gloabalObjectTemplate;
}

int JS_DefineGlobalMethod(v8::Isolate* pIsolate,
                          const wchar_t* sMethodName,
                          v8::FunctionCallback pMethodCall) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope handle_scope(pIsolate);

  CFX_WideString ws = CFX_WideString(sMethodName);
  CFX_ByteString bsMethodName = ws.UTF8Encode();

  v8::Local<v8::FunctionTemplate> funTempl =
      v8::FunctionTemplate::New(pIsolate, pMethodCall);
  v8::Local<v8::ObjectTemplate> objTemp;

  v8::Global<v8::ObjectTemplate>& globalObjTemp =
      _getGlobalObjectTemplate(pIsolate);
  if (globalObjTemp.IsEmpty())
    objTemp = v8::ObjectTemplate::New(pIsolate);
  else
    objTemp = v8::Local<v8::ObjectTemplate>::New(pIsolate, globalObjTemp);
  objTemp->Set(
      v8::String::NewFromUtf8(pIsolate, bsMethodName.c_str(),
                              v8::NewStringType::kNormal).ToLocalChecked(),
      funTempl, v8::ReadOnly);

  globalObjTemp.Reset(pIsolate, objTemp);

  return 0;
}

int JS_DefineGlobalConst(v8::Isolate* pIsolate,
                         const wchar_t* sConstName,
                         v8::Local<v8::Value> pDefault) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope handle_scope(pIsolate);

  CFX_WideString ws = CFX_WideString(sConstName);
  CFX_ByteString bsConst = ws.UTF8Encode();

  v8::Local<v8::ObjectTemplate> objTemp;

  v8::Global<v8::ObjectTemplate>& globalObjTemp =
      _getGlobalObjectTemplate(pIsolate);
  if (globalObjTemp.IsEmpty())
    objTemp = v8::ObjectTemplate::New(pIsolate);
  else
    objTemp = v8::Local<v8::ObjectTemplate>::New(pIsolate, globalObjTemp);
  objTemp->Set(
      v8::String::NewFromUtf8(pIsolate, bsConst.c_str(),
                              v8::NewStringType::kNormal).ToLocalChecked(),
      pDefault, v8::ReadOnly);

  globalObjTemp.Reset(pIsolate, objTemp);

  return 0;
}

void JS_InitialRuntime(v8::Isolate* pIsolate,
                       IFXJS_Runtime* pFXRuntime,
                       IFXJS_Context* context,
                       v8::Global<v8::Context>& v8PersistentContext) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope handle_scope(pIsolate);

  v8::Global<v8::ObjectTemplate>& globalObjTemp =
      _getGlobalObjectTemplate(pIsolate);
  v8::Local<v8::Context> v8Context = v8::Context::New(
      pIsolate, NULL,
      v8::Local<v8::ObjectTemplate>::New(pIsolate, globalObjTemp));
  v8::Context::Scope context_scope(v8Context);

  v8::Local<v8::External> ptr = v8::External::New(pIsolate, pFXRuntime);
  v8Context->SetEmbedderData(1, ptr);

  CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot);
  if (!pArray)
    return;

  for (int i = 0; i < pArray->GetSize(); i++) {
    CJS_ObjDefintion* pObjDef = (CJS_ObjDefintion*)pArray->GetAt(i);
    CFX_WideString ws = CFX_WideString(pObjDef->objName);
    CFX_ByteString bs = ws.UTF8Encode();
    v8::Local<v8::String> objName =
        v8::String::NewFromUtf8(pIsolate, bs.c_str(),
                                v8::NewStringType::kNormal,
                                bs.GetLength()).ToLocalChecked();

    if (pObjDef->objType == JS_DYNAMIC) {
      // Document is set as global object, need to construct it first.
      if (ws.Equal(L"Document")) {
        CJS_PrivateData* pPrivateData = new CJS_PrivateData;
        pPrivateData->ObjDefID = i;

        v8Context->Global()
            ->GetPrototype()
            ->ToObject(v8Context)
            .ToLocalChecked()
            ->SetAlignedPointerInInternalField(0, pPrivateData);

        if (pObjDef->m_pConstructor)
          pObjDef->m_pConstructor(context, v8Context->Global()
                                               ->GetPrototype()
                                               ->ToObject(v8Context)
                                               .ToLocalChecked(),
                                  v8Context->Global()
                                      ->GetPrototype()
                                      ->ToObject(v8Context)
                                      .ToLocalChecked());
      }
    } else {
      v8::Local<v8::Object> obj = JS_NewFxDynamicObj(pIsolate, context, i);
      v8Context->Global()->Set(v8Context, objName, obj).FromJust();
      pObjDef->m_StaticObj.Reset(pIsolate, obj);
    }
  }
  v8PersistentContext.Reset(pIsolate, v8Context);
}

void JS_ReleaseRuntime(v8::Isolate* pIsolate,
                       v8::Global<v8::Context>& v8PersistentContext) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope handle_scope(pIsolate);
  v8::Local<v8::Context> context =
      v8::Local<v8::Context>::New(pIsolate, v8PersistentContext);
  v8::Context::Scope context_scope(context);

  CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot);
  if (!pArray)
    return;

  for (int i = 0; i < pArray->GetSize(); i++) {
    CJS_ObjDefintion* pObjDef = (CJS_ObjDefintion*)pArray->GetAt(i);
    if (!pObjDef->m_StaticObj.IsEmpty()) {
      v8::Local<v8::Object> pObj =
          v8::Local<v8::Object>::New(pIsolate, pObjDef->m_StaticObj);
      if (pObjDef->m_pDestructor)
        pObjDef->m_pDestructor(pObj);
      JS_FreePrivate(pObj);
    }
    delete pObjDef;
  }
  delete pArray;
  pIsolate->SetData(g_embedderDataSlot, NULL);
}

void JS_Initial(unsigned int embedderDataSlot) {
  g_embedderDataSlot = embedderDataSlot;
}

void JS_Release() {
}

int JS_Execute(v8::Isolate* pIsolate,
               IFXJS_Context* pJSContext,
               const wchar_t* script,
               long length,
               FXJSErr* perror) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::TryCatch try_catch(pIsolate);

  CFX_WideString wsScript(script);
  CFX_ByteString bsScript = wsScript.UTF8Encode();

  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
  v8::Local<v8::Script> compiled_script;
  if (!v8::Script::Compile(
           context, v8::String::NewFromUtf8(
                        pIsolate, bsScript.c_str(), v8::NewStringType::kNormal,
                        bsScript.GetLength()).ToLocalChecked())
           .ToLocal(&compiled_script)) {
    v8::String::Utf8Value error(try_catch.Exception());
    return -1;
  }

  v8::Local<v8::Value> result;
  if (!compiled_script->Run(context).ToLocal(&result)) {
    v8::String::Utf8Value error(try_catch.Exception());
    return -1;
  }
  return 0;
}

v8::Local<v8::Object> JS_NewFxDynamicObj(v8::Isolate* pIsolate,
                                         IFXJS_Context* pJSContext,
                                         int nObjDefnID) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
  if (-1 == nObjDefnID) {
    v8::Local<v8::ObjectTemplate> objTempl = v8::ObjectTemplate::New(pIsolate);
    v8::Local<v8::Object> obj;
    if (objTempl->NewInstance(context).ToLocal(&obj))
      return obj;
    return v8::Local<v8::Object>();
  }

  CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot);
  if (!pArray)
    return v8::Local<v8::Object>();

  if (nObjDefnID < 0 || nObjDefnID >= pArray->GetSize())
    return v8::Local<v8::Object>();
  CJS_ObjDefintion* pObjDef = (CJS_ObjDefintion*)pArray->GetAt(nObjDefnID);

  v8::Local<v8::ObjectTemplate> objTemp =
      v8::Local<v8::ObjectTemplate>::New(pIsolate, pObjDef->m_objTemplate);
  v8::Local<v8::Object> obj;
  if (!objTemp->NewInstance(context).ToLocal(&obj))
    return v8::Local<v8::Object>();

  CJS_PrivateData* pPrivateData = new CJS_PrivateData;
  pPrivateData->ObjDefID = nObjDefnID;

  obj->SetAlignedPointerInInternalField(0, pPrivateData);
  if (pObjDef->m_pConstructor)
    pObjDef->m_pConstructor(
        pJSContext, obj,
        context->Global()->GetPrototype()->ToObject(context).ToLocalChecked());

  return obj;
}

v8::Local<v8::Object> JS_GetStaticObj(v8::Isolate* pIsolate, int nObjDefnID) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot);
  if (!pArray)
    return v8::Local<v8::Object>();

  if (nObjDefnID < 0 || nObjDefnID >= pArray->GetSize())
    return v8::Local<v8::Object>();
  CJS_ObjDefintion* pObjDef = (CJS_ObjDefintion*)pArray->GetAt(nObjDefnID);
  v8::Local<v8::Object> obj =
      v8::Local<v8::Object>::New(pIsolate, pObjDef->m_StaticObj);
  return obj;
}

v8::Local<v8::Object> JS_GetThisObj(v8::Isolate* pIsolate) {
  // Return the global object.
  v8::Isolate::Scope isolate_scope(pIsolate);
  CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot);
  if (!pArray)
    return v8::Local<v8::Object>();

  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
  return context->Global()->GetPrototype()->ToObject(context).ToLocalChecked();
}

int JS_GetObjDefnID(v8::Local<v8::Object> pObj) {
  if (pObj.IsEmpty() || !pObj->InternalFieldCount())
    return -1;
  CJS_PrivateData* pPrivateData =
      (CJS_PrivateData*)pObj->GetAlignedPointerFromInternalField(0);
  if (pPrivateData)
    return pPrivateData->ObjDefID;
  return -1;
}

v8::Isolate* JS_GetRuntime(v8::Local<v8::Object> pObj) {
  if (pObj.IsEmpty())
    return NULL;
  v8::Local<v8::Context> context = pObj->CreationContext();
  if (context.IsEmpty())
    return NULL;
  return context->GetIsolate();
}

int JS_GetObjDefnID(v8::Isolate* pIsolate, const wchar_t* pObjName) {
  v8::Isolate::Scope isolate_scope(pIsolate);
  CFX_PtrArray* pArray = (CFX_PtrArray*)pIsolate->GetData(g_embedderDataSlot);
  if (!pArray)
    return -1;

  for (int i = 0; i < pArray->GetSize(); i++) {
    CJS_ObjDefintion* pObjDef = (CJS_ObjDefintion*)pArray->GetAt(i);
    if (FXSYS_wcscmp(pObjDef->objName, pObjName) == 0)
      return i;
  }
  return -1;
}

void JS_Error(v8::Isolate* pIsolate, const CFX_WideString& message) {
  // Conversion from pdfium's wchar_t wide-strings to v8's uint16_t
  // wide-strings isn't handled by v8, so use UTF8 as a common
  // intermediate format.
  CFX_ByteString utf8_message = message.UTF8Encode();
  pIsolate->ThrowException(
      v8::String::NewFromUtf8(pIsolate, utf8_message.c_str(),
                              v8::NewStringType::kNormal).ToLocalChecked());
}

unsigned JS_CalcHash(const wchar_t* main, unsigned nLen) {
  return (unsigned)FX_HashCode_String_GetW(main, nLen);
}

unsigned JS_CalcHash(const wchar_t* main) {
  return (unsigned)FX_HashCode_String_GetW(main, FXSYS_wcslen(main));
}
const wchar_t* JS_GetTypeof(v8::Local<v8::Value> pObj) {
  if (pObj.IsEmpty())
    return NULL;
  if (pObj->IsString())
    return VALUE_NAME_STRING;
  if (pObj->IsNumber())
    return VALUE_NAME_NUMBER;
  if (pObj->IsBoolean())
    return VALUE_NAME_BOOLEAN;
  if (pObj->IsDate())
    return VALUE_NAME_DATE;
  if (pObj->IsObject())
    return VALUE_NAME_OBJECT;
  if (pObj->IsNull())
    return VALUE_NAME_NULL;
  if (pObj->IsUndefined())
    return VALUE_NAME_UNDEFINED;
  return NULL;
}
void JS_SetPrivate(v8::Local<v8::Object> pObj, void* p) {
  JS_SetPrivate(NULL, pObj, p);
}

void* JS_GetPrivate(v8::Local<v8::Object> pObj) {
  return JS_GetPrivate(NULL, pObj);
}

void JS_SetPrivate(v8::Isolate* pIsolate, v8::Local<v8::Object> pObj, void* p) {
  if (pObj.IsEmpty() || !pObj->InternalFieldCount())
    return;
  CJS_PrivateData* pPrivateData =
      (CJS_PrivateData*)pObj->GetAlignedPointerFromInternalField(0);
  if (!pPrivateData)
    return;
  pPrivateData->pPrivate = p;
}

void* JS_GetPrivate(v8::Isolate* pIsolate, v8::Local<v8::Object> pObj) {
  if (pObj.IsEmpty())
    return NULL;
  CJS_PrivateData* pPrivateData = NULL;
  if (pObj->InternalFieldCount())
    pPrivateData =
        (CJS_PrivateData*)pObj->GetAlignedPointerFromInternalField(0);
  else {
    // It could be a global proxy object.
    v8::Local<v8::Value> v = pObj->GetPrototype();
    v8::Isolate* isolate = (v8::Isolate*)pIsolate;
    v8::Local<v8::Context> context = isolate->GetCurrentContext();
    if (v->IsObject())
      pPrivateData = (CJS_PrivateData*)v->ToObject(context)
                         .ToLocalChecked()
                         ->GetAlignedPointerFromInternalField(0);
  }
  if (!pPrivateData)
    return NULL;
  return pPrivateData->pPrivate;
}

void JS_FreePrivate(void* pPrivateData) {
  delete (CJS_PrivateData*)pPrivateData;
}

void JS_FreePrivate(v8::Local<v8::Object> pObj) {
  if (pObj.IsEmpty() || !pObj->InternalFieldCount())
    return;
  JS_FreePrivate(pObj->GetAlignedPointerFromInternalField(0));
  pObj->SetAlignedPointerInInternalField(0, NULL);
}

v8::Local<v8::Value> JS_GetObjectValue(v8::Local<v8::Object> pObj) {
  return pObj;
}

v8::Local<v8::String> WSToJSString(v8::Isolate* pIsolate,
                                   const wchar_t* PropertyName,
                                   int Len = -1) {
  CFX_WideString ws = CFX_WideString(PropertyName, Len);
  CFX_ByteString bs = ws.UTF8Encode();
  if (!pIsolate)
    pIsolate = v8::Isolate::GetCurrent();
  return v8::String::NewFromUtf8(pIsolate, bs.c_str(),
                                 v8::NewStringType::kNormal).ToLocalChecked();
}

v8::Local<v8::Value> JS_GetObjectElement(v8::Isolate* pIsolate,
                                         v8::Local<v8::Object> pObj,
                                         const wchar_t* PropertyName) {
  if (pObj.IsEmpty())
    return v8::Local<v8::Value>();
  v8::Local<v8::Value> val;
  if (!pObj->Get(pIsolate->GetCurrentContext(),
                 WSToJSString(pIsolate, PropertyName)).ToLocal(&val))
    return v8::Local<v8::Value>();
  return val;
}

v8::Local<v8::Array> JS_GetObjectElementNames(v8::Isolate* pIsolate,
                                              v8::Local<v8::Object> pObj) {
  if (pObj.IsEmpty())
    return v8::Local<v8::Array>();
  v8::Local<v8::Array> val;
  if (!pObj->GetPropertyNames(pIsolate->GetCurrentContext()).ToLocal(&val))
    return v8::Local<v8::Array>();
  return val;
}

void JS_PutObjectString(v8::Isolate* pIsolate,
                        v8::Local<v8::Object> pObj,
                        const wchar_t* PropertyName,
                        const wchar_t* sValue)  // VT_string
{
  if (pObj.IsEmpty())
    return;
  pObj->Set(pIsolate->GetCurrentContext(), WSToJSString(pIsolate, PropertyName),
            WSToJSString(pIsolate, sValue)).FromJust();
}

void JS_PutObjectNumber(v8::Isolate* pIsolate,
                        v8::Local<v8::Object> pObj,
                        const wchar_t* PropertyName,
                        int nValue) {
  if (pObj.IsEmpty())
    return;
  pObj->Set(pIsolate->GetCurrentContext(), WSToJSString(pIsolate, PropertyName),
            v8::Int32::New(pIsolate, nValue)).FromJust();
}

void JS_PutObjectNumber(v8::Isolate* pIsolate,
                        v8::Local<v8::Object> pObj,
                        const wchar_t* PropertyName,
                        float fValue) {
  if (pObj.IsEmpty())
    return;
  pObj->Set(pIsolate->GetCurrentContext(), WSToJSString(pIsolate, PropertyName),
            v8::Number::New(pIsolate, (double)fValue)).FromJust();
}

void JS_PutObjectNumber(v8::Isolate* pIsolate,
                        v8::Local<v8::Object> pObj,
                        const wchar_t* PropertyName,
                        double dValue) {
  if (pObj.IsEmpty())
    return;
  pObj->Set(pIsolate->GetCurrentContext(), WSToJSString(pIsolate, PropertyName),
            v8::Number::New(pIsolate, (double)dValue)).FromJust();
}

void JS_PutObjectBoolean(v8::Isolate* pIsolate,
                         v8::Local<v8::Object> pObj,
                         const wchar_t* PropertyName,
                         bool bValue) {
  if (pObj.IsEmpty())
    return;
  pObj->Set(pIsolate->GetCurrentContext(), WSToJSString(pIsolate, PropertyName),
            v8::Boolean::New(pIsolate, bValue)).FromJust();
}

void JS_PutObjectObject(v8::Isolate* pIsolate,
                        v8::Local<v8::Object> pObj,
                        const wchar_t* PropertyName,
                        v8::Local<v8::Object> pPut) {
  if (pObj.IsEmpty())
    return;
  pObj->Set(pIsolate->GetCurrentContext(), WSToJSString(pIsolate, PropertyName),
            pPut).FromJust();
}

void JS_PutObjectNull(v8::Isolate* pIsolate,
                      v8::Local<v8::Object> pObj,
                      const wchar_t* PropertyName) {
  if (pObj.IsEmpty())
    return;
  pObj->Set(pIsolate->GetCurrentContext(), WSToJSString(pIsolate, PropertyName),
            v8::Local<v8::Object>()).FromJust();
}

v8::Local<v8::Array> JS_NewArray(v8::Isolate* pIsolate) {
  return v8::Array::New(pIsolate);
}

unsigned JS_PutArrayElement(v8::Isolate* pIsolate,
                            v8::Local<v8::Array> pArray,
                            unsigned index,
                            v8::Local<v8::Value> pValue,
                            FXJSVALUETYPE eType) {
  if (pArray.IsEmpty())
    return 0;
  if (pArray->Set(pIsolate->GetCurrentContext(), index, pValue).IsNothing())
    return 0;
  return 1;
}

v8::Local<v8::Value> JS_GetArrayElement(v8::Isolate* pIsolate,
                                        v8::Local<v8::Array> pArray,
                                        unsigned index) {
  if (pArray.IsEmpty())
    return v8::Local<v8::Value>();
  v8::Local<v8::Value> val;
  if (!pArray->Get(pIsolate->GetCurrentContext(), index).ToLocal(&val))
    return v8::Local<v8::Value>();
  return val;
}

unsigned JS_GetArrayLength(v8::Local<v8::Array> pArray) {
  if (pArray.IsEmpty())
    return 0;
  return pArray->Length();
}

v8::Local<v8::Value> JS_NewNumber(v8::Isolate* pIsolate, int number) {
  return v8::Int32::New(pIsolate, number);
}

v8::Local<v8::Value> JS_NewNumber(v8::Isolate* pIsolate, double number) {
  return v8::Number::New(pIsolate, number);
}

v8::Local<v8::Value> JS_NewNumber(v8::Isolate* pIsolate, float number) {
  return v8::Number::New(pIsolate, (float)number);
}

v8::Local<v8::Value> JS_NewBoolean(v8::Isolate* pIsolate, bool b) {
  return v8::Boolean::New(pIsolate, b);
}

v8::Local<v8::Value> JS_NewObject(v8::Isolate* pIsolate,
                                  v8::Local<v8::Object> pObj) {
  if (pObj.IsEmpty())
    return v8::Local<v8::Value>();
  return pObj->Clone();
}

v8::Local<v8::Value> JS_NewObject2(v8::Isolate* pIsolate,
                                   v8::Local<v8::Array> pObj) {
  if (pObj.IsEmpty())
    return v8::Local<v8::Value>();
  return pObj->Clone();
}

v8::Local<v8::Value> JS_NewString(v8::Isolate* pIsolate,
                                  const wchar_t* string) {
  return WSToJSString(pIsolate, string);
}

v8::Local<v8::Value> JS_NewString(v8::Isolate* pIsolate,
                                  const wchar_t* string,
                                  unsigned nLen) {
  return WSToJSString(pIsolate, string, nLen);
}

v8::Local<v8::Value> JS_NewNull() {
  return v8::Local<v8::Value>();
}

v8::Local<v8::Value> JS_NewDate(v8::Isolate* pIsolate, double d) {
  return v8::Date::New(pIsolate->GetCurrentContext(), d).ToLocalChecked();
}

v8::Local<v8::Value> JS_NewValue(v8::Isolate* pIsolate) {
  return v8::Local<v8::Value>();
}

v8::Local<v8::Value> JS_GetListValue(v8::Isolate* pIsolate,
                                     v8::Local<v8::Value> pList,
                                     int index) {
  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
  if (!pList.IsEmpty() && pList->IsObject()) {
    v8::Local<v8::Object> obj;
    if (pList->ToObject(context).ToLocal(&obj)) {
      v8::Local<v8::Value> val;
      if (obj->Get(context, index).ToLocal(&val))
        return val;
    }
  }
  return v8::Local<v8::Value>();
}

int JS_ToInt32(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
  if (pValue.IsEmpty())
    return 0;
  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
  return pValue->ToInt32(context).ToLocalChecked()->Value();
}

bool JS_ToBoolean(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
  if (pValue.IsEmpty())
    return false;
  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
  return pValue->ToBoolean(context).ToLocalChecked()->Value();
}

double JS_ToNumber(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
  if (pValue.IsEmpty())
    return 0.0;
  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
  return pValue->ToNumber(context).ToLocalChecked()->Value();
}

v8::Local<v8::Object> JS_ToObject(v8::Isolate* pIsolate,
                                  v8::Local<v8::Value> pValue) {
  if (pValue.IsEmpty())
    return v8::Local<v8::Object>();
  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
  return pValue->ToObject(context).ToLocalChecked();
}

CFX_WideString JS_ToString(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
  if (pValue.IsEmpty())
    return L"";
  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
  v8::String::Utf8Value s(pValue->ToString(context).ToLocalChecked());
  return CFX_WideString::FromUTF8(*s, s.length());
}

v8::Local<v8::Array> JS_ToArray(v8::Isolate* pIsolate,
                                v8::Local<v8::Value> pValue) {
  if (pValue.IsEmpty())
    return v8::Local<v8::Array>();
  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
  return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked());
}

void JS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom) {
  pTo = pFrom;
}

// JavaScript time implement begin.

double _getLocalTZA() {
  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
    return 0;
  time_t t = 0;
  time(&t);
  localtime(&t);
#if _MSC_VER >= 1900
  // In gcc and in Visual Studio prior to VS 2015 'timezone' is a global
  // variable declared in time.h. That variable was deprecated and in VS 2015
  // is removed, with _get_timezone replacing it.
  long timezone = 0;
  _get_timezone(&timezone);
#endif
  return (double)(-(timezone * 1000));
}

int _getDaylightSavingTA(double d) {
  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
    return 0;
  time_t t = (time_t)(d / 1000);
  struct tm* tmp = localtime(&t);
  if (tmp == NULL)
    return 0;
  if (tmp->tm_isdst > 0)
    // One hour.
    return (int)60 * 60 * 1000;
  return 0;
}

double _Mod(double x, double y) {
  double r = fmod(x, y);
  if (r < 0)
    r += y;
  return r;
}

int _isfinite(double v) {
#if _MSC_VER
  return ::_finite(v);
#else
  return std::fabs(v) < std::numeric_limits<double>::max();
#endif
}

double _toInteger(double n) {
  return (n >= 0) ? FXSYS_floor(n) : -FXSYS_floor(-n);
}

bool _isLeapYear(int year) {
  return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 != 0));
}

int _DayFromYear(int y) {
  return (int)(365 * (y - 1970.0) + FXSYS_floor((y - 1969.0) / 4) -
               FXSYS_floor((y - 1901.0) / 100) +
               FXSYS_floor((y - 1601.0) / 400));
}

double _TimeFromYear(int y) {
  return ((double)86400000) * _DayFromYear(y);
}

double _TimeFromYearMonth(int y, int m) {
  static int daysMonth[12] = {0,   31,  59,  90,  120, 151,
                              181, 212, 243, 273, 304, 334};
  static int leapDaysMonth[12] = {0,   31,  60,  91,  121, 152,
                                  182, 213, 244, 274, 305, 335};
  int* pMonth = daysMonth;
  if (_isLeapYear(y))
    pMonth = leapDaysMonth;
  return _TimeFromYear(y) + ((double)pMonth[m]) * 86400000;
}

int _Day(double t) {
  return (int)FXSYS_floor(t / 86400000);
}

int _YearFromTime(double t) {
  // estimate the time.
  int y = 1970 + (int)(t / (365.0 * 86400000));
  if (_TimeFromYear(y) <= t) {
    while (_TimeFromYear(y + 1) <= t)
      y++;
  } else
    while (_TimeFromYear(y - 1) > t)
      y--;
  return y;
}

int _DayWithinYear(double t) {
  int year = _YearFromTime(t);
  int day = _Day(t);
  return day - _DayFromYear(year);
}

int _MonthFromTime(double t) {
  int day = _DayWithinYear(t);
  int year = _YearFromTime(t);
  if (0 <= day && day < 31)
    return 0;
  if (31 <= day && day < 59 + _isLeapYear(year))
    return 1;
  if ((59 + _isLeapYear(year)) <= day && day < (90 + _isLeapYear(year)))
    return 2;
  if ((90 + _isLeapYear(year)) <= day && day < (120 + _isLeapYear(year)))
    return 3;
  if ((120 + _isLeapYear(year)) <= day && day < (151 + _isLeapYear(year)))
    return 4;
  if ((151 + _isLeapYear(year)) <= day && day < (181 + _isLeapYear(year)))
    return 5;
  if ((181 + _isLeapYear(year)) <= day && day < (212 + _isLeapYear(year)))
    return 6;
  if ((212 + _isLeapYear(year)) <= day && day < (243 + _isLeapYear(year)))
    return 7;
  if ((243 + _isLeapYear(year)) <= day && day < (273 + _isLeapYear(year)))
    return 8;
  if ((273 + _isLeapYear(year)) <= day && day < (304 + _isLeapYear(year)))
    return 9;
  if ((304 + _isLeapYear(year)) <= day && day < (334 + _isLeapYear(year)))
    return 10;
  if ((334 + _isLeapYear(year)) <= day && day < (365 + _isLeapYear(year)))
    return 11;

  return -1;
}

int _DateFromTime(double t) {
  int day = _DayWithinYear(t);
  int year = _YearFromTime(t);
  bool leap = _isLeapYear(year);
  int month = _MonthFromTime(t);
  switch (month) {
    case 0:
      return day + 1;
    case 1:
      return day - 30;
    case 2:
      return day - 58 - leap;
    case 3:
      return day - 89 - leap;
    case 4:
      return day - 119 - leap;
    case 5:
      return day - 150 - leap;
    case 6:
      return day - 180 - leap;
    case 7:
      return day - 211 - leap;
    case 8:
      return day - 242 - leap;
    case 9:
      return day - 272 - leap;
    case 10:
      return day - 303 - leap;
    case 11:
      return day - 333 - leap;
    default:
      return 0;
  }
}

double JS_GetDateTime() {
  if (!FSDK_IsSandBoxPolicyEnabled(FPDF_POLICY_MACHINETIME_ACCESS))
    return 0;
  time_t t = time(NULL);
  struct tm* pTm = localtime(&t);

  int year = pTm->tm_year + 1900;
  double t1 = _TimeFromYear(year);

  return t1 + pTm->tm_yday * 86400000.0 + pTm->tm_hour * 3600000.0 +
         pTm->tm_min * 60000.0 + pTm->tm_sec * 1000.0;
}

int JS_GetYearFromTime(double dt) {
  return _YearFromTime(dt);
}

int JS_GetMonthFromTime(double dt) {
  return _MonthFromTime(dt);
}

int JS_GetDayFromTime(double dt) {
  return _DateFromTime(dt);
}

int JS_GetHourFromTime(double dt) {
  return (int)_Mod(FXSYS_floor((double)(dt / (60 * 60 * 1000))), 24);
}

int JS_GetMinFromTime(double dt) {
  return (int)_Mod(FXSYS_floor((double)(dt / (60 * 1000))), 60);
}

int JS_GetSecFromTime(double dt) {
  return (int)_Mod(FXSYS_floor((double)(dt / 1000)), 60);
}

double JS_DateParse(const wchar_t* string) {
  v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
  v8::Isolate::Scope isolate_scope(pIsolate);
  v8::HandleScope scope(pIsolate);

  v8::Local<v8::Context> context = pIsolate->GetCurrentContext();

  // Use the built-in object method.
  v8::Local<v8::Value> v =
      context->Global()
          ->Get(context, v8::String::NewFromUtf8(pIsolate, "Date",
                                                 v8::NewStringType::kNormal)
                             .ToLocalChecked())
          .ToLocalChecked();
  if (v->IsObject()) {
    v8::Local<v8::Object> o = v->ToObject(context).ToLocalChecked();
    v = o->Get(context, v8::String::NewFromUtf8(pIsolate, "parse",
                                                v8::NewStringType::kNormal)
                            .ToLocalChecked())
            .ToLocalChecked();
    if (v->IsFunction()) {
      v8::Local<v8::Function> funC = v8::Local<v8::Function>::Cast(v);

      const int argc = 1;
      v8::Local<v8::String> timeStr = WSToJSString(pIsolate, string);
      v8::Local<v8::Value> argv[argc] = {timeStr};
      v = funC->Call(context, context->Global(), argc, argv).ToLocalChecked();
      if (v->IsNumber()) {
        double date = v->ToNumber(context).ToLocalChecked()->Value();
        if (!_isfinite(date))
          return date;
        return date + _getLocalTZA() + _getDaylightSavingTA(date);
      }
    }
  }
  return 0;
}

double JS_MakeDay(int nYear, int nMonth, int nDate) {
  if (!_isfinite(nYear) || !_isfinite(nMonth) || !_isfinite(nDate))
    return GetNan();
  double y = _toInteger(nYear);
  double m = _toInteger(nMonth);
  double dt = _toInteger(nDate);
  double ym = y + FXSYS_floor((double)m / 12);
  double mn = _Mod(m, 12);

  double t = _TimeFromYearMonth((int)ym, (int)mn);

  if (_YearFromTime(t) != ym || _MonthFromTime(t) != mn ||
      _DateFromTime(t) != 1)
    return GetNan();
  return _Day(t) + dt - 1;
}

double JS_MakeTime(int nHour, int nMin, int nSec, int nMs) {
  if (!_isfinite(nHour) || !_isfinite(nMin) || !_isfinite(nSec) ||
      !_isfinite(nMs))
    return GetNan();

  double h = _toInteger(nHour);
  double m = _toInteger(nMin);
  double s = _toInteger(nSec);
  double milli = _toInteger(nMs);

  return h * 3600000 + m * 60000 + s * 1000 + milli;
}

double JS_MakeDate(double day, double time) {
  if (!_isfinite(day) || !_isfinite(time))
    return GetNan();

  return day * 86400000 + time;
}

bool JS_PortIsNan(double d) {
  return d != d;
}

double JS_LocalTime(double d) {
  return JS_GetDateTime() + _getDaylightSavingTA(d);
}

// JavaScript time implement End.
