summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Sinclair <dsinclair@chromium.org>2017-12-06 03:12:09 +0000
committerChromium commit bot <commit-bot@chromium.org>2017-12-06 03:12:09 +0000
commit4bd2ad8cf901134cabae0c56524a05a542c118fd (patch)
tree08414ce353909c495b004c78fa3fca22132a65f9
parent6eda94d78313f18a8f0708c4492d0962649fa709 (diff)
downloadpdfium-4bd2ad8cf901134cabae0c56524a05a542c118fd.tar.xz
Move V8 helper methods to their own class.
This CL extracts the V8 helper methods from the CFXJS_Engine and places them in a CJS_V8 class which the engine inherits from. This will allow inheriting the CJS_V8 class into CFXJSE_Engine to share the helper methods. Change-Id: I58a7cd7ebac3af303ecbeee84c6940186a0f1dc6 Reviewed-on: https://pdfium-review.googlesource.com/20470 Commit-Queue: dsinclair <dsinclair@chromium.org> Reviewed-by: Tom Sepez <tsepez@chromium.org>
-rw-r--r--BUILD.gn2
-rw-r--r--fxjs/cjs_v8.cpp199
-rw-r--r--fxjs/cjs_v8.h82
-rw-r--r--fxjs/fxjs_v8.cpp332
-rw-r--r--fxjs/fxjs_v8.h50
5 files changed, 358 insertions, 307 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 65683f9646..0aa00e9533 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1262,6 +1262,8 @@ static_library("fxjs") {
"fxjs/cjs_timerobj.h",
"fxjs/cjs_util.cpp",
"fxjs/cjs_util.h",
+ "fxjs/cjs_v8.cpp",
+ "fxjs/cjs_v8.h",
"fxjs/cjs_zoomtype.cpp",
"fxjs/cjs_zoomtype.h",
"fxjs/fxjs_v8.cpp",
diff --git a/fxjs/cjs_v8.cpp b/fxjs/cjs_v8.cpp
new file mode 100644
index 0000000000..67f0cb52b1
--- /dev/null
+++ b/fxjs/cjs_v8.cpp
@@ -0,0 +1,199 @@
+// Copyright 2017 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 "fxjs/cjs_v8.h"
+
+CJS_V8::CJS_V8(v8::Isolate* isolate) : m_isolate(isolate) {}
+
+CJS_V8::~CJS_V8() {
+ m_V8PersistentContext.Reset();
+}
+
+v8::Local<v8::Value> CJS_V8::GetObjectProperty(
+ v8::Local<v8::Object> pObj,
+ const WideString& wsPropertyName) {
+ if (pObj.IsEmpty())
+ return v8::Local<v8::Value>();
+ v8::Local<v8::Value> val;
+ if (!pObj->Get(m_isolate->GetCurrentContext(),
+ NewString(wsPropertyName.AsStringView()))
+ .ToLocal(&val))
+ return v8::Local<v8::Value>();
+ return val;
+}
+
+std::vector<WideString> CJS_V8::GetObjectPropertyNames(
+ v8::Local<v8::Object> pObj) {
+ if (pObj.IsEmpty())
+ return std::vector<WideString>();
+
+ v8::Local<v8::Array> val;
+ v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
+ if (!pObj->GetPropertyNames(context).ToLocal(&val))
+ return std::vector<WideString>();
+
+ std::vector<WideString> result;
+ for (uint32_t i = 0; i < val->Length(); ++i) {
+ result.push_back(ToWideString(val->Get(context, i).ToLocalChecked()));
+ }
+
+ return result;
+}
+
+void CJS_V8::PutObjectProperty(v8::Local<v8::Object> pObj,
+ const WideString& wsPropertyName,
+ v8::Local<v8::Value> pPut) {
+ if (pObj.IsEmpty())
+ return;
+ pObj->Set(m_isolate->GetCurrentContext(),
+ NewString(wsPropertyName.AsStringView()), pPut)
+ .FromJust();
+}
+
+v8::Local<v8::Array> CJS_V8::NewArray() {
+ return v8::Array::New(m_isolate);
+}
+
+unsigned CJS_V8::PutArrayElement(v8::Local<v8::Array> pArray,
+ unsigned index,
+ v8::Local<v8::Value> pValue) {
+ if (pArray.IsEmpty())
+ return 0;
+ if (pArray->Set(m_isolate->GetCurrentContext(), index, pValue).IsNothing())
+ return 0;
+ return 1;
+}
+
+v8::Local<v8::Value> CJS_V8::GetArrayElement(v8::Local<v8::Array> pArray,
+ unsigned index) {
+ if (pArray.IsEmpty())
+ return v8::Local<v8::Value>();
+ v8::Local<v8::Value> val;
+ if (!pArray->Get(m_isolate->GetCurrentContext(), index).ToLocal(&val))
+ return v8::Local<v8::Value>();
+ return val;
+}
+
+unsigned CJS_V8::GetArrayLength(v8::Local<v8::Array> pArray) {
+ if (pArray.IsEmpty())
+ return 0;
+ return pArray->Length();
+}
+
+v8::Local<v8::Context> CJS_V8::NewLocalContext() {
+ return v8::Local<v8::Context>::New(m_isolate, m_V8PersistentContext);
+}
+
+v8::Local<v8::Context> CJS_V8::GetPersistentContext() {
+ return m_V8PersistentContext.Get(m_isolate);
+}
+
+v8::Local<v8::Number> CJS_V8::NewNumber(int number) {
+ return v8::Int32::New(m_isolate, number);
+}
+
+v8::Local<v8::Number> CJS_V8::NewNumber(double number) {
+ return v8::Number::New(m_isolate, number);
+}
+
+v8::Local<v8::Number> CJS_V8::NewNumber(float number) {
+ return v8::Number::New(m_isolate, (float)number);
+}
+
+v8::Local<v8::Boolean> CJS_V8::NewBoolean(bool b) {
+ return v8::Boolean::New(m_isolate, b);
+}
+
+v8::Local<v8::String> CJS_V8::NewString(const ByteStringView& str) {
+ v8::Isolate* pIsolate = m_isolate ? m_isolate : v8::Isolate::GetCurrent();
+ return v8::String::NewFromUtf8(pIsolate, str.unterminated_c_str(),
+ v8::NewStringType::kNormal, str.GetLength())
+ .ToLocalChecked();
+}
+
+v8::Local<v8::String> CJS_V8::NewString(const WideStringView& str) {
+ // 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.
+ return NewString(FX_UTF8Encode(str).AsStringView());
+}
+
+v8::Local<v8::Value> CJS_V8::NewNull() {
+ return v8::Null(m_isolate);
+}
+
+v8::Local<v8::Value> CJS_V8::NewUndefined() {
+ return v8::Undefined(m_isolate);
+}
+
+v8::Local<v8::Date> CJS_V8::NewDate(double d) {
+ return v8::Date::New(m_isolate->GetCurrentContext(), d)
+ .ToLocalChecked()
+ .As<v8::Date>();
+}
+
+int CJS_V8::ToInt32(v8::Local<v8::Value> pValue) {
+ if (pValue.IsEmpty())
+ return 0;
+ v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
+ v8::MaybeLocal<v8::Int32> maybe_int32 = pValue->ToInt32(context);
+ if (maybe_int32.IsEmpty())
+ return 0;
+ return maybe_int32.ToLocalChecked()->Value();
+}
+
+bool CJS_V8::ToBoolean(v8::Local<v8::Value> pValue) {
+ if (pValue.IsEmpty())
+ return false;
+ v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
+ v8::MaybeLocal<v8::Boolean> maybe_boolean = pValue->ToBoolean(context);
+ if (maybe_boolean.IsEmpty())
+ return false;
+ return maybe_boolean.ToLocalChecked()->Value();
+}
+
+double CJS_V8::ToDouble(v8::Local<v8::Value> pValue) {
+ if (pValue.IsEmpty())
+ return 0.0;
+ v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
+ v8::MaybeLocal<v8::Number> maybe_number = pValue->ToNumber(context);
+ if (maybe_number.IsEmpty())
+ return 0.0;
+ return maybe_number.ToLocalChecked()->Value();
+}
+
+WideString CJS_V8::ToWideString(v8::Local<v8::Value> pValue) {
+ if (pValue.IsEmpty())
+ return WideString();
+ v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
+ v8::MaybeLocal<v8::String> maybe_string = pValue->ToString(context);
+ if (maybe_string.IsEmpty())
+ return WideString();
+ v8::String::Utf8Value s(maybe_string.ToLocalChecked());
+ return WideString::FromUTF8(ByteStringView(*s, s.length()));
+}
+
+v8::Local<v8::Object> CJS_V8::ToObject(v8::Local<v8::Value> pValue) {
+ if (pValue.IsEmpty() || !pValue->IsObject())
+ return v8::Local<v8::Object>();
+ v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
+ return pValue->ToObject(context).ToLocalChecked();
+}
+
+v8::Local<v8::Array> CJS_V8::ToArray(v8::Local<v8::Value> pValue) {
+ if (pValue.IsEmpty() || !pValue->IsArray())
+ return v8::Local<v8::Array>();
+ v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
+ return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked());
+}
+
+void CJS_V8::SetConstArray(const WideString& name, v8::Local<v8::Array> array) {
+ m_ConstArrays[name] = v8::Global<v8::Array>(GetIsolate(), array);
+}
+
+v8::Local<v8::Array> CJS_V8::GetConstArray(const WideString& name) {
+ return v8::Local<v8::Array>::New(GetIsolate(), m_ConstArrays[name]);
+}
diff --git a/fxjs/cjs_v8.h b/fxjs/cjs_v8.h
new file mode 100644
index 0000000000..9060f019ab
--- /dev/null
+++ b/fxjs/cjs_v8.h
@@ -0,0 +1,82 @@
+// Copyright 2017 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
+
+#ifndef FXJS_CJS_V8_H_
+#define FXJS_CJS_V8_H_
+
+#include <v8-util.h>
+#include <v8.h>
+
+#include <map>
+#include <vector>
+
+#include "core/fxcrt/bytestring.h"
+#include "core/fxcrt/fx_string.h"
+#include "core/fxcrt/widestring.h"
+
+class CJS_V8 {
+ public:
+ explicit CJS_V8(v8::Isolate* pIsolate);
+ virtual ~CJS_V8();
+
+ v8::Isolate* GetIsolate() const { return m_isolate; }
+
+ v8::Local<v8::Context> NewLocalContext();
+ v8::Local<v8::Context> GetPersistentContext();
+
+ v8::Local<v8::Value> NewNull();
+ v8::Local<v8::Value> NewUndefined();
+ v8::Local<v8::Array> NewArray();
+ v8::Local<v8::Number> NewNumber(int number);
+ v8::Local<v8::Number> NewNumber(double number);
+ v8::Local<v8::Number> NewNumber(float number);
+ v8::Local<v8::Boolean> NewBoolean(bool b);
+ v8::Local<v8::String> NewString(const ByteStringView& str);
+ v8::Local<v8::String> NewString(const WideStringView& str);
+ v8::Local<v8::Date> NewDate(double d);
+
+ int ToInt32(v8::Local<v8::Value> pValue);
+ bool ToBoolean(v8::Local<v8::Value> pValue);
+ double ToDouble(v8::Local<v8::Value> pValue);
+ WideString ToWideString(v8::Local<v8::Value> pValue);
+ v8::Local<v8::Object> ToObject(v8::Local<v8::Value> pValue);
+ v8::Local<v8::Array> ToArray(v8::Local<v8::Value> pValue);
+
+ // Arrays.
+ unsigned GetArrayLength(v8::Local<v8::Array> pArray);
+ v8::Local<v8::Value> GetArrayElement(v8::Local<v8::Array> pArray,
+ unsigned index);
+ unsigned PutArrayElement(v8::Local<v8::Array> pArray,
+ unsigned index,
+ v8::Local<v8::Value> pValue);
+
+ void SetConstArray(const WideString& name, v8::Local<v8::Array> array);
+ v8::Local<v8::Array> GetConstArray(const WideString& name);
+
+ // Objects.
+ std::vector<WideString> GetObjectPropertyNames(v8::Local<v8::Object> pObj);
+ v8::Local<v8::Value> GetObjectProperty(v8::Local<v8::Object> pObj,
+ const WideString& PropertyName);
+ void PutObjectProperty(v8::Local<v8::Object> pObj,
+ const WideString& PropertyName,
+ v8::Local<v8::Value> pValue);
+
+ protected:
+ void SetIsolate(v8::Isolate* pIsolate) { m_isolate = pIsolate; }
+ void ClearConstArray() { m_ConstArrays.clear(); }
+
+ void ResetPersistentContext(v8::Local<v8::Context> context) {
+ m_V8PersistentContext.Reset(m_isolate, context);
+ }
+ void ReleasePersistentContext() { m_V8PersistentContext.Reset(); }
+
+ private:
+ v8::Isolate* m_isolate;
+ std::map<WideString, v8::Global<v8::Array>> m_ConstArrays;
+ v8::Global<v8::Context> m_V8PersistentContext;
+};
+
+#endif // FXJS_CJS_V8_H_
diff --git a/fxjs/fxjs_v8.cpp b/fxjs/fxjs_v8.cpp
index 441848205f..98f5ff720a 100644
--- a/fxjs/fxjs_v8.cpp
+++ b/fxjs/fxjs_v8.cpp
@@ -254,13 +254,11 @@ FXJS_PerIsolateData* FXJS_PerIsolateData::Get(v8::Isolate* pIsolate) {
FXJS_PerIsolateData::FXJS_PerIsolateData(v8::Isolate* pIsolate)
: m_pDynamicObjsMap(new V8TemplateMap(pIsolate)) {}
-CFXJS_Engine::CFXJS_Engine() : m_isolate(nullptr) {}
+CFXJS_Engine::CFXJS_Engine() : CJS_V8(nullptr) {}
-CFXJS_Engine::CFXJS_Engine(v8::Isolate* pIsolate) : m_isolate(pIsolate) {}
+CFXJS_Engine::CFXJS_Engine(v8::Isolate* pIsolate) : CJS_V8(pIsolate) {}
-CFXJS_Engine::~CFXJS_Engine() {
- m_V8PersistentContext.Reset();
-}
+CFXJS_Engine::~CFXJS_Engine() = default;
// static
CFXJS_Engine* CFXJS_Engine::CurrentEngineFromIsolate(v8::Isolate* pIsolate) {
@@ -292,23 +290,24 @@ int CFXJS_Engine::DefineObj(const char* sObjName,
FXJSOBJTYPE eObjType,
CFXJS_Engine::Constructor pConstructor,
CFXJS_Engine::Destructor pDestructor) {
- v8::Isolate::Scope isolate_scope(m_isolate);
- v8::HandleScope handle_scope(m_isolate);
- FXJS_PerIsolateData::SetUp(m_isolate);
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::HandleScope handle_scope(GetIsolate());
+ FXJS_PerIsolateData::SetUp(GetIsolate());
CFXJS_ObjDefinition* pObjDef = new CFXJS_ObjDefinition(
- m_isolate, sObjName, eObjType, pConstructor, pDestructor);
+ GetIsolate(), sObjName, eObjType, pConstructor, pDestructor);
return pObjDef->AssignID();
}
void CFXJS_Engine::DefineObjMethod(int nObjDefnID,
const char* sMethodName,
v8::FunctionCallback pMethodCall) {
- v8::Isolate::Scope isolate_scope(m_isolate);
- v8::HandleScope handle_scope(m_isolate);
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::HandleScope handle_scope(GetIsolate());
CFXJS_ObjDefinition* pObjDef =
- CFXJS_ObjDefinition::ForID(m_isolate, nObjDefnID);
+ CFXJS_ObjDefinition::ForID(GetIsolate(), nObjDefnID);
v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(
- m_isolate, pMethodCall, v8::Local<v8::Value>(), pObjDef->GetSignature());
+ GetIsolate(), pMethodCall, v8::Local<v8::Value>(),
+ pObjDef->GetSignature());
fun->RemovePrototype();
pObjDef->GetInstanceTemplate()->Set(NewString(sMethodName), fun,
v8::ReadOnly);
@@ -318,10 +317,10 @@ void CFXJS_Engine::DefineObjProperty(int nObjDefnID,
const char* sPropName,
v8::AccessorGetterCallback pPropGet,
v8::AccessorSetterCallback pPropPut) {
- v8::Isolate::Scope isolate_scope(m_isolate);
- v8::HandleScope handle_scope(m_isolate);
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::HandleScope handle_scope(GetIsolate());
CFXJS_ObjDefinition* pObjDef =
- CFXJS_ObjDefinition::ForID(m_isolate, nObjDefnID);
+ CFXJS_ObjDefinition::ForID(GetIsolate(), nObjDefnID);
pObjDef->GetInstanceTemplate()->SetAccessor(NewString(sPropName), pPropGet,
pPropPut);
}
@@ -332,10 +331,10 @@ void CFXJS_Engine::DefineObjAllProperties(
v8::NamedPropertyGetterCallback pPropGet,
v8::NamedPropertySetterCallback pPropPut,
v8::NamedPropertyDeleterCallback pPropDel) {
- v8::Isolate::Scope isolate_scope(m_isolate);
- v8::HandleScope handle_scope(m_isolate);
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::HandleScope handle_scope(GetIsolate());
CFXJS_ObjDefinition* pObjDef =
- CFXJS_ObjDefinition::ForID(m_isolate, nObjDefnID);
+ CFXJS_ObjDefinition::ForID(GetIsolate(), nObjDefnID);
pObjDef->GetInstanceTemplate()->SetNamedPropertyHandler(pPropGet, pPropPut,
pPropQurey, pPropDel);
}
@@ -343,56 +342,56 @@ void CFXJS_Engine::DefineObjAllProperties(
void CFXJS_Engine::DefineObjConst(int nObjDefnID,
const char* sConstName,
v8::Local<v8::Value> pDefault) {
- v8::Isolate::Scope isolate_scope(m_isolate);
- v8::HandleScope handle_scope(m_isolate);
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::HandleScope handle_scope(GetIsolate());
CFXJS_ObjDefinition* pObjDef =
- CFXJS_ObjDefinition::ForID(m_isolate, nObjDefnID);
- pObjDef->GetInstanceTemplate()->Set(m_isolate, sConstName, pDefault);
+ CFXJS_ObjDefinition::ForID(GetIsolate(), nObjDefnID);
+ pObjDef->GetInstanceTemplate()->Set(GetIsolate(), sConstName, pDefault);
}
void CFXJS_Engine::DefineGlobalMethod(const char* sMethodName,
v8::FunctionCallback pMethodCall) {
- v8::Isolate::Scope isolate_scope(m_isolate);
- v8::HandleScope handle_scope(m_isolate);
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::HandleScope handle_scope(GetIsolate());
v8::Local<v8::FunctionTemplate> fun =
- v8::FunctionTemplate::New(m_isolate, pMethodCall);
+ v8::FunctionTemplate::New(GetIsolate(), pMethodCall);
fun->RemovePrototype();
- GetGlobalObjectTemplate(m_isolate)->Set(NewString(sMethodName), fun,
- v8::ReadOnly);
+ GetGlobalObjectTemplate(GetIsolate())
+ ->Set(NewString(sMethodName), fun, v8::ReadOnly);
}
void CFXJS_Engine::DefineGlobalConst(const wchar_t* sConstName,
v8::FunctionCallback pConstGetter) {
- v8::Isolate::Scope isolate_scope(m_isolate);
- v8::HandleScope handle_scope(m_isolate);
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::HandleScope handle_scope(GetIsolate());
v8::Local<v8::FunctionTemplate> fun =
- v8::FunctionTemplate::New(m_isolate, pConstGetter);
+ v8::FunctionTemplate::New(GetIsolate(), pConstGetter);
fun->RemovePrototype();
- GetGlobalObjectTemplate(m_isolate)->SetAccessorProperty(NewString(sConstName),
- fun);
+ GetGlobalObjectTemplate(GetIsolate())
+ ->SetAccessorProperty(NewString(sConstName), fun);
}
void CFXJS_Engine::InitializeEngine() {
- if (m_isolate == g_isolate)
+ if (GetIsolate() == g_isolate)
++g_isolate_ref_count;
- v8::Isolate::Scope isolate_scope(m_isolate);
- v8::HandleScope handle_scope(m_isolate);
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::HandleScope handle_scope(GetIsolate());
// This has to happen before we call GetGlobalObjectTemplate because that
- // method gets the PerIsolateData from m_isolate.
- FXJS_PerIsolateData::SetUp(m_isolate);
+ // method gets the PerIsolateData from GetIsolate().
+ FXJS_PerIsolateData::SetUp(GetIsolate());
- v8::Local<v8::Context> v8Context =
- v8::Context::New(m_isolate, nullptr, GetGlobalObjectTemplate(m_isolate));
+ v8::Local<v8::Context> v8Context = v8::Context::New(
+ GetIsolate(), nullptr, GetGlobalObjectTemplate(GetIsolate()));
v8::Context::Scope context_scope(v8Context);
v8Context->SetAlignedPointerInEmbedderData(kPerContextDataIndex, this);
- int maxID = CFXJS_ObjDefinition::MaxID(m_isolate);
+ int maxID = CFXJS_ObjDefinition::MaxID(GetIsolate());
m_StaticObjects.resize(maxID + 1);
for (int i = 0; i < maxID; ++i) {
- CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(m_isolate, i);
+ CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(GetIsolate(), i);
if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) {
CFXJS_PerObjectData::SetInObject(new CFXJS_PerObjectData(i),
v8Context->Global()
@@ -410,36 +409,35 @@ void CFXJS_Engine::InitializeEngine() {
v8::Local<v8::Object> obj = NewFxDynamicObj(i, true);
if (!obj.IsEmpty()) {
v8Context->Global()->Set(v8Context, pObjName, obj).FromJust();
- m_StaticObjects[i] = new v8::Global<v8::Object>(m_isolate, obj);
+ m_StaticObjects[i] = new v8::Global<v8::Object>(GetIsolate(), obj);
} else {
m_StaticObjects[i] = nullptr;
}
}
}
- m_V8PersistentContext.Reset(m_isolate, v8Context);
+ ResetPersistentContext(v8Context);
}
void CFXJS_Engine::ReleaseEngine() {
- v8::Isolate::Scope isolate_scope(m_isolate);
- v8::HandleScope handle_scope(m_isolate);
- v8::Local<v8::Context> context =
- v8::Local<v8::Context>::New(m_isolate, m_V8PersistentContext);
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::HandleScope handle_scope(GetIsolate());
+ v8::Local<v8::Context> context = NewLocalContext();
v8::Context::Scope context_scope(context);
- FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(m_isolate);
+ FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(GetIsolate());
if (!pData)
return;
- m_ConstArrays.clear();
+ ClearConstArray();
- int maxID = CFXJS_ObjDefinition::MaxID(m_isolate);
+ int maxID = CFXJS_ObjDefinition::MaxID(GetIsolate());
for (int i = 0; i < maxID; ++i) {
- CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(m_isolate, i);
+ CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(GetIsolate(), i);
v8::Local<v8::Object> pObj;
if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) {
pObj =
context->Global()->GetPrototype()->ToObject(context).ToLocalChecked();
} else if (m_StaticObjects[i] && !m_StaticObjects[i]->IsEmpty()) {
- pObj = v8::Local<v8::Object>::New(m_isolate, *m_StaticObjects[i]);
+ pObj = v8::Local<v8::Object>::New(GetIsolate(), *m_StaticObjects[i]);
delete m_StaticObjects[i];
m_StaticObjects[i] = nullptr;
}
@@ -451,19 +449,19 @@ void CFXJS_Engine::ReleaseEngine() {
}
}
- m_V8PersistentContext.Reset();
+ ReleasePersistentContext();
- if (m_isolate == g_isolate && --g_isolate_ref_count > 0)
+ if (GetIsolate() == g_isolate && --g_isolate_ref_count > 0)
return;
delete pData;
- m_isolate->SetData(g_embedderDataSlot, nullptr);
+ GetIsolate()->SetData(g_embedderDataSlot, nullptr);
}
int CFXJS_Engine::Execute(const WideString& script, FXJSErr* pError) {
- v8::Isolate::Scope isolate_scope(m_isolate);
- v8::TryCatch try_catch(m_isolate);
- v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::TryCatch try_catch(GetIsolate());
+ v8::Local<v8::Context> context = GetIsolate()->GetCurrentContext();
v8::Local<v8::Script> compiled_script;
if (!v8::Script::Compile(context, NewString(script.AsStringView()))
.ToLocal(&compiled_script)) {
@@ -483,25 +481,26 @@ int CFXJS_Engine::Execute(const WideString& script, FXJSErr* pError) {
v8::Local<v8::Object> CFXJS_Engine::NewFxDynamicObj(int nObjDefnID,
bool bStatic) {
- v8::Isolate::Scope isolate_scope(m_isolate);
- v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::Local<v8::Context> context = GetIsolate()->GetCurrentContext();
if (nObjDefnID == -1) {
- v8::Local<v8::ObjectTemplate> objTempl = v8::ObjectTemplate::New(m_isolate);
+ v8::Local<v8::ObjectTemplate> objTempl =
+ v8::ObjectTemplate::New(GetIsolate());
v8::Local<v8::Object> obj;
if (!objTempl->NewInstance(context).ToLocal(&obj))
return v8::Local<v8::Object>();
return obj;
}
- FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(m_isolate);
+ FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(GetIsolate());
if (!pData)
return v8::Local<v8::Object>();
- if (nObjDefnID < 0 || nObjDefnID >= CFXJS_ObjDefinition::MaxID(m_isolate))
+ if (nObjDefnID < 0 || nObjDefnID >= CFXJS_ObjDefinition::MaxID(GetIsolate()))
return v8::Local<v8::Object>();
CFXJS_ObjDefinition* pObjDef =
- CFXJS_ObjDefinition::ForID(m_isolate, nObjDefnID);
+ CFXJS_ObjDefinition::ForID(GetIsolate(), nObjDefnID);
v8::Local<v8::Object> obj;
if (!pObjDef->GetInstanceTemplate()->NewInstance(context).ToLocal(&obj))
return v8::Local<v8::Object>();
@@ -511,24 +510,25 @@ v8::Local<v8::Object> CFXJS_Engine::NewFxDynamicObj(int nObjDefnID,
if (pObjDef->m_pConstructor)
pObjDef->m_pConstructor(this, obj);
- if (!bStatic && FXJS_PerIsolateData::Get(m_isolate)->m_pDynamicObjsMap)
- FXJS_PerIsolateData::Get(m_isolate)->m_pDynamicObjsMap->set(pObjData, obj);
+ if (!bStatic && FXJS_PerIsolateData::Get(GetIsolate())->m_pDynamicObjsMap)
+ FXJS_PerIsolateData::Get(GetIsolate())
+ ->m_pDynamicObjsMap->set(pObjData, obj);
return obj;
}
v8::Local<v8::Object> CFXJS_Engine::GetThisObj() {
- v8::Isolate::Scope isolate_scope(m_isolate);
- if (!FXJS_PerIsolateData::Get(m_isolate))
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ if (!FXJS_PerIsolateData::Get(GetIsolate()))
return v8::Local<v8::Object>();
// Return the global object.
- v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = GetIsolate()->GetCurrentContext();
return context->Global()->GetPrototype()->ToObject(context).ToLocalChecked();
}
void CFXJS_Engine::Error(const WideString& message) {
- m_isolate->ThrowException(NewString(message.AsStringView()));
+ GetIsolate()->ThrowException(NewString(message.AsStringView()));
}
void CFXJS_Engine::SetObjectPrivate(v8::Local<v8::Object> pObj, void* p) {
@@ -544,7 +544,7 @@ void* CFXJS_Engine::GetObjectPrivate(v8::Local<v8::Object> pObj) {
if (!pData && !pObj.IsEmpty()) {
// It could be a global proxy object.
v8::Local<v8::Value> v = pObj->GetPrototype();
- v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
+ v8::Local<v8::Context> context = GetIsolate()->GetCurrentContext();
if (v->IsObject()) {
pData = CFXJS_PerObjectData::GetFromObject(
v->ToObject(context).ToLocalChecked());
@@ -552,191 +552,3 @@ void* CFXJS_Engine::GetObjectPrivate(v8::Local<v8::Object> pObj) {
}
return pData ? pData->m_pPrivate : nullptr;
}
-
-v8::Local<v8::Value> CFXJS_Engine::GetObjectProperty(
- v8::Local<v8::Object> pObj,
- const WideString& wsPropertyName) {
- if (pObj.IsEmpty())
- return v8::Local<v8::Value>();
- v8::Local<v8::Value> val;
- if (!pObj->Get(m_isolate->GetCurrentContext(),
- NewString(wsPropertyName.AsStringView()))
- .ToLocal(&val))
- return v8::Local<v8::Value>();
- return val;
-}
-
-std::vector<WideString> CFXJS_Engine::GetObjectPropertyNames(
- v8::Local<v8::Object> pObj) {
- if (pObj.IsEmpty())
- return std::vector<WideString>();
-
- v8::Local<v8::Array> val;
- v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
- if (!pObj->GetPropertyNames(context).ToLocal(&val))
- return std::vector<WideString>();
-
- std::vector<WideString> result;
- for (uint32_t i = 0; i < val->Length(); ++i) {
- result.push_back(ToWideString(val->Get(context, i).ToLocalChecked()));
- }
-
- return result;
-}
-
-void CFXJS_Engine::PutObjectProperty(v8::Local<v8::Object> pObj,
- const WideString& wsPropertyName,
- v8::Local<v8::Value> pPut) {
- if (pObj.IsEmpty())
- return;
- pObj->Set(m_isolate->GetCurrentContext(),
- NewString(wsPropertyName.AsStringView()), pPut)
- .FromJust();
-}
-
-
-v8::Local<v8::Array> CFXJS_Engine::NewArray() {
- return v8::Array::New(m_isolate);
-}
-
-unsigned CFXJS_Engine::PutArrayElement(v8::Local<v8::Array> pArray,
- unsigned index,
- v8::Local<v8::Value> pValue) {
- if (pArray.IsEmpty())
- return 0;
- if (pArray->Set(m_isolate->GetCurrentContext(), index, pValue).IsNothing())
- return 0;
- return 1;
-}
-
-v8::Local<v8::Value> CFXJS_Engine::GetArrayElement(v8::Local<v8::Array> pArray,
- unsigned index) {
- if (pArray.IsEmpty())
- return v8::Local<v8::Value>();
- v8::Local<v8::Value> val;
- if (!pArray->Get(m_isolate->GetCurrentContext(), index).ToLocal(&val))
- return v8::Local<v8::Value>();
- return val;
-}
-
-unsigned CFXJS_Engine::GetArrayLength(v8::Local<v8::Array> pArray) {
- if (pArray.IsEmpty())
- return 0;
- return pArray->Length();
-}
-
-v8::Local<v8::Context> CFXJS_Engine::NewLocalContext() {
- return v8::Local<v8::Context>::New(m_isolate, m_V8PersistentContext);
-}
-
-v8::Local<v8::Context> CFXJS_Engine::GetPersistentContext() {
- return m_V8PersistentContext.Get(m_isolate);
-}
-
-v8::Local<v8::Number> CFXJS_Engine::NewNumber(int number) {
- return v8::Int32::New(m_isolate, number);
-}
-
-v8::Local<v8::Number> CFXJS_Engine::NewNumber(double number) {
- return v8::Number::New(m_isolate, number);
-}
-
-v8::Local<v8::Number> CFXJS_Engine::NewNumber(float number) {
- return v8::Number::New(m_isolate, (float)number);
-}
-
-v8::Local<v8::Boolean> CFXJS_Engine::NewBoolean(bool b) {
- return v8::Boolean::New(m_isolate, b);
-}
-
-v8::Local<v8::String> CFXJS_Engine::NewString(const ByteStringView& str) {
- v8::Isolate* pIsolate = m_isolate ? m_isolate : v8::Isolate::GetCurrent();
- return v8::String::NewFromUtf8(pIsolate, str.unterminated_c_str(),
- v8::NewStringType::kNormal, str.GetLength())
- .ToLocalChecked();
-}
-
-v8::Local<v8::String> CFXJS_Engine::NewString(const WideStringView& str) {
- // 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.
- return NewString(FX_UTF8Encode(str).AsStringView());
-}
-
-v8::Local<v8::Value> CFXJS_Engine::NewNull() {
- return v8::Null(m_isolate);
-}
-
-v8::Local<v8::Value> CFXJS_Engine::NewUndefined() {
- return v8::Undefined(m_isolate);
-}
-
-v8::Local<v8::Date> CFXJS_Engine::NewDate(double d) {
- return v8::Date::New(m_isolate->GetCurrentContext(), d)
- .ToLocalChecked()
- .As<v8::Date>();
-}
-
-int CFXJS_Engine::ToInt32(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty())
- return 0;
- v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
- v8::MaybeLocal<v8::Int32> maybe_int32 = pValue->ToInt32(context);
- if (maybe_int32.IsEmpty())
- return 0;
- return maybe_int32.ToLocalChecked()->Value();
-}
-
-bool CFXJS_Engine::ToBoolean(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty())
- return false;
- v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
- v8::MaybeLocal<v8::Boolean> maybe_boolean = pValue->ToBoolean(context);
- if (maybe_boolean.IsEmpty())
- return false;
- return maybe_boolean.ToLocalChecked()->Value();
-}
-
-double CFXJS_Engine::ToDouble(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty())
- return 0.0;
- v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
- v8::MaybeLocal<v8::Number> maybe_number = pValue->ToNumber(context);
- if (maybe_number.IsEmpty())
- return 0.0;
- return maybe_number.ToLocalChecked()->Value();
-}
-
-WideString CFXJS_Engine::ToWideString(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty())
- return WideString();
- v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
- v8::MaybeLocal<v8::String> maybe_string = pValue->ToString(context);
- if (maybe_string.IsEmpty())
- return WideString();
- v8::String::Utf8Value s(maybe_string.ToLocalChecked());
- return WideString::FromUTF8(ByteStringView(*s, s.length()));
-}
-
-v8::Local<v8::Object> CFXJS_Engine::ToObject(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty() || !pValue->IsObject())
- return v8::Local<v8::Object>();
- v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
- return pValue->ToObject(context).ToLocalChecked();
-}
-
-v8::Local<v8::Array> CFXJS_Engine::ToArray(v8::Local<v8::Value> pValue) {
- if (pValue.IsEmpty() || !pValue->IsArray())
- return v8::Local<v8::Array>();
- v8::Local<v8::Context> context = m_isolate->GetCurrentContext();
- return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked());
-}
-
-void CFXJS_Engine::SetConstArray(const WideString& name,
- v8::Local<v8::Array> array) {
- m_ConstArrays[name] = v8::Global<v8::Array>(GetIsolate(), array);
-}
-
-v8::Local<v8::Array> CFXJS_Engine::GetConstArray(const WideString& name) {
- return v8::Local<v8::Array>::New(GetIsolate(), m_ConstArrays[name]);
-}
diff --git a/fxjs/fxjs_v8.h b/fxjs/fxjs_v8.h
index eee85e031d..4575235755 100644
--- a/fxjs/fxjs_v8.h
+++ b/fxjs/fxjs_v8.h
@@ -22,6 +22,7 @@
#include <vector>
#include "core/fxcrt/fx_string.h"
+#include "fxjs/cjs_v8.h"
#ifdef PDF_ENABLE_XFA
// Header for CFXJSE_RuntimeData. FXJS_V8 doesn't interpret this class,
@@ -127,10 +128,10 @@ bool FXJS_GetIsolate(v8::Isolate** pResultIsolate);
// Get the global isolate's ref count.
size_t FXJS_GlobalIsolateRefCount();
-class CFXJS_Engine {
+class CFXJS_Engine : public CJS_V8 {
public:
explicit CFXJS_Engine(v8::Isolate* pIsolate);
- ~CFXJS_Engine();
+ ~CFXJS_Engine() override;
using Constructor = void (*)(CFXJS_Engine* pEngine,
v8::Local<v8::Object> obj);
@@ -139,8 +140,6 @@ class CFXJS_Engine {
static CFXJS_Engine* CurrentEngineFromIsolate(v8::Isolate* pIsolate);
static int GetObjDefnID(v8::Local<v8::Object> pObj);
- v8::Isolate* GetIsolate() const { return m_isolate; }
-
// Always returns a valid, newly-created objDefnID.
int DefineObj(const char* sObjName,
FXJSOBJTYPE eObjType,
@@ -174,66 +173,23 @@ class CFXJS_Engine {
// Called after FXJS_InitializeEngine call made.
int Execute(const WideString& script, FXJSErr* perror);
- v8::Local<v8::Context> NewLocalContext();
- v8::Local<v8::Context> GetPersistentContext();
v8::Local<v8::Object> GetThisObj();
- v8::Local<v8::Value> NewNull();
- v8::Local<v8::Value> NewUndefined();
- v8::Local<v8::Array> NewArray();
- v8::Local<v8::Number> NewNumber(int number);
- v8::Local<v8::Number> NewNumber(double number);
- v8::Local<v8::Number> NewNumber(float number);
- v8::Local<v8::Boolean> NewBoolean(bool b);
- v8::Local<v8::String> NewString(const ByteStringView& str);
- v8::Local<v8::String> NewString(const WideStringView& str);
- v8::Local<v8::Date> NewDate(double d);
v8::Local<v8::Object> NewFxDynamicObj(int nObjDefnID, bool bStatic = false);
- int ToInt32(v8::Local<v8::Value> pValue);
- bool ToBoolean(v8::Local<v8::Value> pValue);
- double ToDouble(v8::Local<v8::Value> pValue);
- WideString ToWideString(v8::Local<v8::Value> pValue);
- v8::Local<v8::Object> ToObject(v8::Local<v8::Value> pValue);
- v8::Local<v8::Array> ToArray(v8::Local<v8::Value> pValue);
-
- // Arrays.
- unsigned GetArrayLength(v8::Local<v8::Array> pArray);
- v8::Local<v8::Value> GetArrayElement(v8::Local<v8::Array> pArray,
- unsigned index);
- unsigned PutArrayElement(v8::Local<v8::Array> pArray,
- unsigned index,
- v8::Local<v8::Value> pValue);
-
- // Objects.
- std::vector<WideString> GetObjectPropertyNames(v8::Local<v8::Object> pObj);
- v8::Local<v8::Value> GetObjectProperty(v8::Local<v8::Object> pObj,
- const WideString& PropertyName);
- void PutObjectProperty(v8::Local<v8::Object> pObj,
- const WideString& PropertyName,
- v8::Local<v8::Value> pValue);
-
// Native object binding.
void SetObjectPrivate(v8::Local<v8::Object> pObj, void* p);
void* GetObjectPrivate(v8::Local<v8::Object> pObj);
static void FreeObjectPrivate(void* p);
static void FreeObjectPrivate(v8::Local<v8::Object> pObj);
- void SetConstArray(const WideString& name, v8::Local<v8::Array> array);
- v8::Local<v8::Array> GetConstArray(const WideString& name);
-
void Error(const WideString& message);
protected:
CFXJS_Engine();
- void SetIsolate(v8::Isolate* pIsolate) { m_isolate = pIsolate; }
-
private:
- v8::Isolate* m_isolate;
- v8::Global<v8::Context> m_V8PersistentContext;
std::vector<v8::Global<v8::Object>*> m_StaticObjects;
- std::map<WideString, v8::Global<v8::Array>> m_ConstArrays;
};
#endif // FXJS_FXJS_V8_H_