// 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(IJS_Runtime* pJSRuntime,
                 const wchar_t* sObjName,
                 FXJSOBJTYPE eObjType,
                 LP_CONSTRUCTOR pConstructor,
                 LP_DESTRUCTOR pDestructor) {
  v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
  v8::Isolate::Scope isolate_scope(isolate);
  v8::HandleScope handle_scope(isolate);
  CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->GetData(g_embedderDataSlot);
  if (!pArray) {
    pArray = new CFX_PtrArray();
    isolate->SetData(g_embedderDataSlot, pArray);
  }
  CJS_ObjDefintion* pObjDef = new CJS_ObjDefintion(isolate, sObjName, eObjType,
                                                   pConstructor, pDestructor);
  pArray->Add(pObjDef);
  return pArray->GetSize() - 1;
}

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

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

  CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->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(isolate, pObjDef->m_objTemplate);
  objTemp->Set(v8::String::NewFromUtf8(isolate, bsMethodName.c_str(),
                                       v8::NewStringType::kNormal)
                   .ToLocalChecked(),
               v8::FunctionTemplate::New(isolate, pMethodCall), v8::ReadOnly);
  pObjDef->m_objTemplate.Reset(isolate, objTemp);
  return 0;
}

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

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

  CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->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(isolate, pObjDef->m_objTemplate);
  objTemp->SetAccessor(v8::String::NewFromUtf8(isolate, bsPropertyName.c_str(),
                                               v8::NewStringType::kNormal)
                           .ToLocalChecked(),
                       pPropGet, pPropPut);
  pObjDef->m_objTemplate.Reset(isolate, objTemp);
  return 0;
}

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

  CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->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(isolate, pObjDef->m_objTemplate);
  objTemp->SetNamedPropertyHandler(pPropGet, pPropPut, pPropQurey, pPropDel);
  pObjDef->m_objTemplate.Reset(isolate, objTemp);
  return 0;
}

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

  CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->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(isolate, pObjDef->m_objTemplate);
  objTemp->Set(isolate, bsConstName.c_str(), pDefault);
  pObjDef->m_objTemplate.Reset(isolate, objTemp);
  return 0;
}

static v8::Global<v8::ObjectTemplate>& _getGlobalObjectTemplate(
    IJS_Runtime* pJSRuntime) {
  v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
  v8::Isolate::Scope isolate_scope(isolate);
  v8::HandleScope handle_scope(isolate);

  CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->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(IJS_Runtime* pJSRuntime,
                          const wchar_t* sMethodName,
                          v8::FunctionCallback pMethodCall) {
  v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
  v8::Isolate::Scope isolate_scope(isolate);
  v8::HandleScope handle_scope(isolate);

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

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

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

  globalObjTemp.Reset(isolate, objTemp);

  return 0;
}

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

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

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

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

  globalObjTemp.Reset(isolate, objTemp);

  return 0;
}

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

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

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

  CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->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(isolate, 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(pJSRuntime, context, i);
      v8Context->Global()->Set(v8Context, objName, obj).FromJust();
      pObjDef->m_StaticObj.Reset(isolate, obj);
    }
  }
  v8PersistentContext.Reset(isolate, v8Context);
}

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

  CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->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(isolate, pObjDef->m_StaticObj);
      if (pObjDef->m_pDestructor)
        pObjDef->m_pDestructor(pObj);
      JS_FreePrivate(pObj);
    }
    delete pObjDef;
  }
  delete pArray;
  isolate->SetData(g_embedderDataSlot, NULL);
}

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

void JS_Release() {
}

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

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

  v8::Local<v8::Context> context = isolate->GetCurrentContext();
  v8::Local<v8::Script> compiled_script;
  if (!v8::Script::Compile(context,
                           v8::String::NewFromUtf8(isolate, 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(IJS_Runtime* pJSRuntime,
                                         IFXJS_Context* pJSContext,
                                         int nObjDefnID) {
  v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
  v8::Isolate::Scope isolate_scope(isolate);
  v8::Local<v8::Context> context = isolate->GetCurrentContext();
  if (-1 == nObjDefnID) {
    v8::Local<v8::ObjectTemplate> objTempl = v8::ObjectTemplate::New(isolate);
    v8::Local<v8::Object> obj;
    if (objTempl->NewInstance(context).ToLocal(&obj))
      return obj;
    return v8::Local<v8::Object>();
  }

  CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->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(isolate, 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(IJS_Runtime* pJSRuntime, int nObjDefnID) {
  v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
  v8::Isolate::Scope isolate_scope(isolate);

  CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->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(isolate, pObjDef->m_StaticObj);
  return obj;
}

void JS_SetThisObj(IJS_Runtime* pJSRuntime, int nThisObjID) {
  // Do nothing.
}
v8::Local<v8::Object> JS_GetThisObj(IJS_Runtime* pJSRuntime) {
  // Return the global object.
  v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
  v8::Isolate::Scope isolate_scope(isolate);

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

  v8::Local<v8::Context> context = isolate->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;
}

IJS_Runtime* 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(IJS_Runtime* pJSRuntime, const wchar_t* pObjName) {
  v8::Isolate* isolate = (v8::Isolate*)pJSRuntime;
  v8::Isolate::Scope isolate_scope(isolate);

  CFX_PtrArray* pArray = (CFX_PtrArray*)isolate->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* isolate, 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();
  isolate->ThrowException(v8::String::NewFromUtf8(isolate, 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(IJS_Runtime* pJSRuntime,
                   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(IJS_Runtime* pJSRuntime, 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*)pJSRuntime;
    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(IJS_Runtime* pJSRuntime,
                                   const wchar_t* PropertyName,
                                   int Len = -1) {
  CFX_WideString ws = CFX_WideString(PropertyName, Len);
  CFX_ByteString bs = ws.UTF8Encode();
  if (!pJSRuntime)
    pJSRuntime = v8::Isolate::GetCurrent();
  return v8::String::NewFromUtf8(pJSRuntime, bs.c_str(),
                                 v8::NewStringType::kNormal)
      .ToLocalChecked();
}

v8::Local<v8::Value> JS_GetObjectElement(IJS_Runtime* pJSRuntime,
                                         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(pJSRuntime->GetCurrentContext(),
                 WSToJSString(pJSRuntime, PropertyName))
           .ToLocal(&val))
    return v8::Local<v8::Value>();
  return val;
}

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

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

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

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

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

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

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

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

v8::Local<v8::Array> JS_NewArray(IJS_Runtime* pJSRuntime) {
  return v8::Array::New(pJSRuntime);
}

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

v8::Local<v8::Value> JS_GetArrayElement(IJS_Runtime* pJSRuntime,
                                        v8::Local<v8::Array> pArray,
                                        unsigned index) {
  if (pArray.IsEmpty())
    return v8::Local<v8::Value>();
  v8::Local<v8::Value> val;
  if (!pArray->Get(pJSRuntime->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(IJS_Runtime* pJSRuntime, int number) {
  return v8::Int32::New(pJSRuntime, number);
}

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

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

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

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

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

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

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

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

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

v8::Local<v8::Value> JS_NewValue(IJS_Runtime* pJSRuntime) {
  return v8::Local<v8::Value>();
}

v8::Local<v8::Value> JS_GetListValue(IJS_Runtime* pJSRuntime,
                                     v8::Local<v8::Value> pList,
                                     int index) {
  v8::Local<v8::Context> context = pJSRuntime->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(IJS_Runtime* pJSRuntime, v8::Local<v8::Value> pValue) {
  if (pValue.IsEmpty())
    return 0;
  v8::Local<v8::Context> context = pJSRuntime->GetCurrentContext();
  return pValue->ToInt32(context).ToLocalChecked()->Value();
}

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

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

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

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

v8::Local<v8::Array> JS_ToArray(IJS_Runtime* pJSRuntime,
                                v8::Local<v8::Value> pValue) {
  if (pValue.IsEmpty())
    return v8::Local<v8::Array>();
  v8::Local<v8::Context> context = pJSRuntime->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.
