Return v8::Local<> from CFXJSE_Context::GetGlobalContext()
No reason to cobble together a CFXJSE_Value when a local would do.
-- requires moving some functionality into fxv8 that was formerly
part of CFXJSE_Value.
-- introduce a new scope in one place, which made a method no longer
be const (probably never was logically const to begin with).
Bug: pdfium:1610
Change-Id: Id7064cf802f47b52abc3bbb9a83ff0b9624cf447
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/76012
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Daniel Hosseinian <dhoss@chromium.org>
diff --git a/fxjs/fxv8.cpp b/fxjs/fxv8.cpp
index 65a0f51..6a952b0 100644
--- a/fxjs/fxv8.cpp
+++ b/fxjs/fxv8.cpp
@@ -213,6 +213,36 @@
return result;
}
+bool ReentrantHasObjectOwnPropertyHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName,
+ bool bUseTypeGetter) {
+ if (pObj.IsEmpty())
+ return false;
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::Local<v8::Context> pContext = pIsolate->GetCurrentContext();
+ v8::Local<v8::String> hKey =
+ fxv8::NewStringHelper(pIsolate, bsUTF8PropertyName);
+ return pObj->HasRealNamedProperty(pContext, hKey).FromJust() ||
+ (bUseTypeGetter &&
+ pObj->HasOwnProperty(pContext, hKey).FromMaybe(false));
+}
+
+bool ReentrantSetObjectOwnPropertyHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName,
+ v8::Local<v8::Value> pValue) {
+ ASSERT(!pValue.IsEmpty());
+ if (pObj.IsEmpty())
+ return false;
+
+ v8::TryCatch squash_exceptions(pIsolate);
+ v8::Local<v8::String> name = NewStringHelper(pIsolate, bsUTF8PropertyName);
+ return pObj->DefineOwnProperty(pIsolate->GetCurrentContext(), name, pValue)
+ .FromMaybe(false);
+}
+
bool ReentrantPutObjectPropertyHelper(v8::Isolate* pIsolate,
v8::Local<v8::Object> pObj,
ByteStringView bsUTF8PropertyName,
diff --git a/fxjs/fxv8.h b/fxjs/fxv8.h
index 0078c62..5e492c2 100644
--- a/fxjs/fxv8.h
+++ b/fxjs/fxv8.h
@@ -66,6 +66,14 @@
std::vector<WideString> ReentrantGetObjectPropertyNamesHelper(
v8::Isolate* pIsolate,
v8::Local<v8::Object> pObj);
+bool ReentrantHasObjectOwnPropertyHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName,
+ bool bUseTypeGetter);
+bool ReentrantSetObjectOwnPropertyHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Object> pObj,
+ ByteStringView bsUTF8PropertyName,
+ v8::Local<v8::Value> pValue);
bool ReentrantPutObjectPropertyHelper(v8::Isolate* pIsolate,
v8::Local<v8::Object> pObj,
ByteStringView bsUTF8PropertyName,
diff --git a/fxjs/xfa/cfxjse_context.cpp b/fxjs/xfa/cfxjse_context.cpp
index fb706fc..5de17cb 100644
--- a/fxjs/xfa/cfxjse_context.cpp
+++ b/fxjs/xfa/cfxjse_context.cpp
@@ -200,13 +200,14 @@
CFXJSE_Context::~CFXJSE_Context() = default;
-std::unique_ptr<CFXJSE_Value> CFXJSE_Context::GetGlobalObject() {
- CFXJSE_ScopeUtil_IsolateHandleContext scope(this);
+v8::Local<v8::Object> CFXJSE_Context::GetGlobalObject() {
+ v8::Isolate::Scope isolate_scope(GetIsolate());
+ v8::EscapableHandleScope handle_scope(GetIsolate());
v8::Local<v8::Context> hContext =
v8::Local<v8::Context>::New(GetIsolate(), m_hContext);
- v8::Local<v8::Object> hGlobalObject =
+ v8::Local<v8::Object> result =
hContext->Global()->GetPrototype().As<v8::Object>();
- return std::make_unique<CFXJSE_Value>(GetIsolate(), hGlobalObject);
+ return handle_scope.Escape(result);
}
v8::Local<v8::Context> CFXJSE_Context::GetContext() {
diff --git a/fxjs/xfa/cfxjse_context.h b/fxjs/xfa/cfxjse_context.h
index 876caa3..2724809 100644
--- a/fxjs/xfa/cfxjse_context.h
+++ b/fxjs/xfa/cfxjse_context.h
@@ -33,7 +33,8 @@
v8::Isolate* GetIsolate() const { return m_pIsolate.Get(); }
v8::Local<v8::Context> GetContext();
- std::unique_ptr<CFXJSE_Value> GetGlobalObject();
+ v8::Local<v8::Object> GetGlobalObject();
+
void AddClass(std::unique_ptr<CFXJSE_Class> pClass);
CFXJSE_Class* GetClassByName(ByteStringView szName) const;
void EnableCompatibleMode();
diff --git a/fxjs/xfa/cfxjse_engine.cpp b/fxjs/xfa/cfxjse_engine.cpp
index 93595ed..73f5dfd 100644
--- a/fxjs/xfa/cfxjse_engine.cpp
+++ b/fxjs/xfa/cfxjse_engine.cpp
@@ -582,41 +582,47 @@
CXFA_Node* variablesNode = pScriptNode->GetParent();
if (!variablesNode ||
- variablesNode->GetElementType() != XFA_Element::Variables)
+ variablesNode->GetElementType() != XFA_Element::Variables) {
return false;
+ }
auto it = m_mapVariableToContext.find(pScriptNode->JSObject());
if (it == m_mapVariableToContext.end() || !it->second)
return false;
CFXJSE_Context* pVariableContext = it->second.get();
- std::unique_ptr<CFXJSE_Value> pObject = pVariableContext->GetGlobalObject();
- auto hVariableValue = std::make_unique<CFXJSE_Value>();
+ v8::Local<v8::Object> pObject = pVariableContext->GetGlobalObject();
if (!bGetter) {
- pObject->SetObjectOwnProperty(GetIsolate(), szPropName, pValue);
+ fxv8::ReentrantSetObjectOwnPropertyHelper(GetIsolate(), pObject, szPropName,
+ pValue->GetValue(GetIsolate()));
return true;
}
- if (!pObject->HasObjectOwnProperty(GetIsolate(), szPropName, false))
+ if (!fxv8::ReentrantHasObjectOwnPropertyHelper(GetIsolate(), pObject,
+ szPropName, false)) {
return false;
+ }
- pObject->GetObjectProperty(GetIsolate(), szPropName, hVariableValue.get());
- if (hVariableValue->IsFunction(GetIsolate()))
- pValue->SetFunctionBind(GetIsolate(), hVariableValue.get(), pObject.get());
- else if (bGetter)
- pValue->Assign(GetIsolate(), hVariableValue.get());
- else
- hVariableValue.get()->Assign(GetIsolate(), pValue);
+ v8::Local<v8::Value> hVariableValue =
+ fxv8::ReentrantGetObjectPropertyHelper(GetIsolate(), pObject, szPropName);
+ if (fxv8::IsFunction(hVariableValue)) {
+ pValue->SetBoundFunction(GetIsolate(), hVariableValue.As<v8::Function>(),
+ pObject);
+ } else {
+ pValue->ForceSetValue(GetIsolate(), hVariableValue);
+ }
return true;
}
-void CFXJSE_Engine::RemoveBuiltInObjs(CFXJSE_Context* pContext) const {
+void CFXJSE_Engine::RemoveBuiltInObjs(CFXJSE_Context* pContext) {
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(this);
const ByteStringView kObjNames[2] = {"Number", "Date"};
- std::unique_ptr<CFXJSE_Value> pObject = pContext->GetGlobalObject();
- auto hProp = std::make_unique<CFXJSE_Value>();
- for (const auto& obj : kObjNames) {
- if (pObject->GetObjectProperty(GetIsolate(), obj, hProp.get()))
- pObject->DeleteObjectProperty(GetIsolate(), obj);
+ v8::Local<v8::Object> pObject = pContext->GetGlobalObject();
+ for (const auto& name : kObjNames) {
+ if (!fxv8::ReentrantGetObjectPropertyHelper(GetIsolate(), pObject, name)
+ .IsEmpty()) {
+ fxv8::ReentrantDeleteObjectPropertyHelper(GetIsolate(), pObject, name);
+ }
}
}
diff --git a/fxjs/xfa/cfxjse_engine.h b/fxjs/xfa/cfxjse_engine.h
index 24834e5..326aa9b 100644
--- a/fxjs/xfa/cfxjse_engine.h
+++ b/fxjs/xfa/cfxjse_engine.h
@@ -115,7 +115,7 @@
private:
CFXJSE_Context* CreateVariablesContext(CXFA_Node* pScriptNode,
CXFA_Node* pSubform);
- void RemoveBuiltInObjs(CFXJSE_Context* pContext) const;
+ void RemoveBuiltInObjs(CFXJSE_Context* pContext);
bool QueryNodeByFlag(CXFA_Node* refNode,
WideStringView propname,
CFXJSE_Value* pValue,
diff --git a/fxjs/xfa/cfxjse_value.cpp b/fxjs/xfa/cfxjse_value.cpp
index 4ea8209..54ca810 100644
--- a/fxjs/xfa/cfxjse_value.cpp
+++ b/fxjs/xfa/cfxjse_value.cpp
@@ -181,40 +181,27 @@
bool CFXJSE_Value::SetObjectOwnProperty(v8::Isolate* pIsolate,
ByteStringView szPropName,
- CFXJSE_Value* lpPropValue) {
- ASSERT(lpPropValue);
+ CFXJSE_Value* pPropValue) {
CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
v8::Local<v8::Value> hObject = v8::Local<v8::Value>::New(pIsolate, m_hValue);
if (!hObject->IsObject())
return false;
- v8::Local<v8::String> hPropName = fxv8::NewStringHelper(pIsolate, szPropName);
v8::Local<v8::Value> pValue =
- v8::Local<v8::Value>::New(pIsolate, lpPropValue->m_hValue);
- return hObject.As<v8::Object>()
- ->DefineOwnProperty(pIsolate->GetCurrentContext(), hPropName, pValue)
- .FromMaybe(false);
+ v8::Local<v8::Value>::New(pIsolate, pPropValue->m_hValue);
+ return fxv8::ReentrantSetObjectOwnPropertyHelper(
+ pIsolate, hObject.As<v8::Object>(), szPropName, pValue);
}
-bool CFXJSE_Value::SetFunctionBind(v8::Isolate* pIsolate,
- CFXJSE_Value* lpOldFunction,
- CFXJSE_Value* lpNewThis) {
- ASSERT(lpOldFunction);
- ASSERT(lpNewThis);
+bool CFXJSE_Value::SetBoundFunction(v8::Isolate* pIsolate,
+ v8::Local<v8::Function> hOldFunction,
+ v8::Local<v8::Object> hNewThis) {
+ ASSERT(!hOldFunction.IsEmpty());
+ ASSERT(!hNewThis.IsEmpty());
CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
v8::Local<v8::Value> rgArgs[2];
- v8::Local<v8::Value> hOldFunction =
- v8::Local<v8::Value>::New(pIsolate, lpOldFunction->DirectGetValue());
- if (!fxv8::IsFunction(hOldFunction))
- return false;
-
rgArgs[0] = hOldFunction;
- v8::Local<v8::Value> hNewThis =
- v8::Local<v8::Value>::New(pIsolate, lpNewThis->DirectGetValue());
- if (hNewThis.IsEmpty())
- return false;
-
rgArgs[1] = hNewThis;
v8::Local<v8::String> hBinderFuncSource =
fxv8::NewStringHelper(pIsolate,
diff --git a/fxjs/xfa/cfxjse_value.h b/fxjs/xfa/cfxjse_value.h
index 4029a4f..542b384 100644
--- a/fxjs/xfa/cfxjse_value.h
+++ b/fxjs/xfa/cfxjse_value.h
@@ -75,9 +75,9 @@
bool SetObjectOwnProperty(v8::Isolate* pIsolate,
ByteStringView szPropName,
CFXJSE_Value* lpPropValue);
- bool SetFunctionBind(v8::Isolate* pIsolate,
- CFXJSE_Value* lpOldFunction,
- CFXJSE_Value* lpNewThis);
+ bool SetBoundFunction(v8::Isolate* pIsolate,
+ v8::Local<v8::Function> hOldFunction,
+ v8::Local<v8::Object> lpNewThis);
v8::Local<v8::Value> GetValue(v8::Isolate* pIsolate) const;
const v8::Global<v8::Value>& DirectGetValue() const { return m_hValue; }