Use v8::Global<> directly in CFXJSE_FormCalcContext and tests.
This is complicated by the need to have additional handle scopes
to permit the use of v8::Local<> in several places.
Bug: pdfium:1610
Change-Id: I60eebcc1eecd397efb1bd60bf2d62f1aa91fb869
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/75950
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 614a122..0f2c656 100644
--- a/fxjs/fxv8.cpp
+++ b/fxjs/fxv8.cpp
@@ -113,6 +113,11 @@
return pValue->BooleanValue(pIsolate);
}
+float ReentrantToFloatHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue) {
+ return static_cast<float>(ReentrantToDoubleHelper(pIsolate, pValue));
+}
+
double ReentrantToDoubleHelper(v8::Isolate* pIsolate,
v8::Local<v8::Value> pValue) {
if (pValue.IsEmpty())
diff --git a/fxjs/fxv8.h b/fxjs/fxv8.h
index b3c2649..d5c19fa 100644
--- a/fxjs/fxv8.h
+++ b/fxjs/fxv8.h
@@ -42,9 +42,12 @@
v8::Local<v8::Object> NewObjectHelper(v8::Isolate* pIsolate);
v8::Local<v8::Date> NewDateHelper(v8::Isolate* pIsolate, double d);
-int ReentrantToInt32Helper(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue);
+int32_t ReentrantToInt32Helper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue);
bool ReentrantToBooleanHelper(v8::Isolate* pIsolate,
v8::Local<v8::Value> pValue);
+float ReentrantToFloatHelper(v8::Isolate* pIsolate,
+ v8::Local<v8::Value> pValue);
double ReentrantToDoubleHelper(v8::Isolate* pIsolate,
v8::Local<v8::Value> pValue);
WideString ReentrantToWideStringHelper(v8::Isolate* pIsolate,
diff --git a/fxjs/xfa/cfxjse_formcalc_context.cpp b/fxjs/xfa/cfxjse_formcalc_context.cpp
index e2f30d7..0771d2d 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context.cpp
@@ -5766,11 +5766,13 @@
CFXJSE_Context* pScriptContext,
CXFA_Document* pDoc)
: m_pIsolate(pIsolate),
- m_pValue(std::make_unique<CFXJSE_Value>()),
m_pDocument(pDoc) {
- m_pValue->SetHostObject(
- pIsolate, this,
- CFXJSE_Class::Create(pScriptContext, &kFormCalcFM2JSDescriptor, false));
+ m_Value.Reset(
+ m_pIsolate,
+ NewBoundV8Object(
+ m_pIsolate,
+ CFXJSE_Class::Create(pScriptContext, &kFormCalcFM2JSDescriptor, false)
+ ->GetTemplate(m_pIsolate)));
}
CFXJSE_FormCalcContext::~CFXJSE_FormCalcContext() = default;
@@ -5780,7 +5782,8 @@
}
void CFXJSE_FormCalcContext::GlobalPropertyGetter(CFXJSE_Value* pValue) {
- pValue->Assign(GetIsolate(), m_pValue.get());
+ pValue->ForceSetValue(GetIsolate(),
+ v8::Local<v8::Value>::New(m_pIsolate, m_Value));
}
// static
diff --git a/fxjs/xfa/cfxjse_formcalc_context.h b/fxjs/xfa/cfxjse_formcalc_context.h
index 19b88ca..83f7790 100644
--- a/fxjs/xfa/cfxjse_formcalc_context.h
+++ b/fxjs/xfa/cfxjse_formcalc_context.h
@@ -329,8 +329,8 @@
void ThrowParamCountMismatchException(const WideString& method) const;
void ThrowException(const WideString& str) const;
- UnownedPtr<v8::Isolate> m_pIsolate;
- std::unique_ptr<CFXJSE_Value> m_pValue;
+ UnownedPtr<v8::Isolate> const m_pIsolate;
+ v8::Global<v8::Value> m_Value;
UnownedPtr<CXFA_Document> const m_pDocument;
};
diff --git a/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp b/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp
index ddd0eda..ad523a6 100644
--- a/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp
+++ b/fxjs/xfa/cfxjse_formcalc_context_embeddertest.cpp
@@ -4,6 +4,7 @@
#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_engine.h"
+#include "fxjs/xfa/cfxjse_isolatetracker.h"
#include "fxjs/xfa/cfxjse_value.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/xfa_js_embedder_test.h"
@@ -23,34 +24,40 @@
void ExecuteExpectNull(ByteStringView input) {
EXPECT_TRUE(Execute(input)) << "Program: " << input;
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNull(isolate())) << "Program: " << input;
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetScriptContext());
+ EXPECT_TRUE(fxv8::IsNull(GetValue())) << "Program: " << input;
}
void ExecuteExpectBool(ByteStringView input, bool expected) {
EXPECT_TRUE(Execute(input)) << "Program: " << input;
- CFXJSE_Value* value = GetValue();
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetScriptContext());
+ v8::Local<v8::Value> value = GetValue();
+
// Yes, bools might be integers, somehow.
- EXPECT_TRUE(value->IsBoolean(isolate()) || value->IsInteger(isolate()))
+ EXPECT_TRUE(fxv8::IsBoolean(value) || fxv8::IsInteger(value))
<< "Program: " << input;
- EXPECT_EQ(expected, value->ToBoolean(isolate())) << "Program: " << input;
+ EXPECT_EQ(expected, fxv8::ReentrantToBooleanHelper(isolate(), value))
+ << "Program: " << input;
}
void ExecuteExpectInt32(ByteStringView input, int32_t expected) {
EXPECT_TRUE(Execute(input)) << "Program: " << input;
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsInteger(isolate())) << "Program: " << input;
- EXPECT_EQ(expected, value->ToInteger(isolate())) << "Program: " << input;
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetScriptContext());
+ v8::Local<v8::Value> value = GetValue();
+ EXPECT_TRUE(fxv8::IsInteger(value)) << "Program: " << input;
+ EXPECT_EQ(expected, fxv8::ReentrantToInt32Helper(isolate(), value))
+ << "Program: " << input;
}
void ExecuteExpectFloat(ByteStringView input, float expected) {
EXPECT_TRUE(Execute(input)) << "Program: " << input;
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber(isolate())) << "Program: " << input;
- EXPECT_FLOAT_EQ(expected, value->ToFloat(isolate()))
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetScriptContext());
+ v8::Local<v8::Value> value = GetValue();
+ EXPECT_TRUE(fxv8::IsNumber(value));
+ EXPECT_FLOAT_EQ(expected, fxv8::ReentrantToFloatHelper(isolate(), value))
<< "Program: " << input;
}
@@ -59,18 +66,22 @@
float precision) {
EXPECT_TRUE(Execute(input)) << "Program: " << input;
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsNumber(isolate())) << "Program: " << input;
- EXPECT_NEAR(expected, value->ToFloat(isolate()), precision)
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetScriptContext());
+ v8::Local<v8::Value> value = GetValue();
+ EXPECT_TRUE(fxv8::IsNumber(value));
+ EXPECT_NEAR(expected, fxv8::ReentrantToFloatHelper(isolate(), value),
+ precision)
<< "Program: " << input;
}
void ExecuteExpectString(ByteStringView input, const char* expected) {
EXPECT_TRUE(Execute(input)) << "Program: " << input;
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString(isolate())) << "Program: " << input;
- EXPECT_STREQ(expected, value->ToString(isolate()).c_str())
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetScriptContext());
+ v8::Local<v8::Value> value = GetValue();
+ EXPECT_TRUE(fxv8::IsString(value));
+ EXPECT_STREQ(expected,
+ fxv8::ReentrantToByteStringHelper(isolate(), value).c_str())
<< "Program: " << input;
}
};
@@ -1103,8 +1114,9 @@
ASSERT_TRUE(OpenDocument("simple_xfa.pdf"));
EXPECT_TRUE(Execute("Uuid()"));
- CFXJSE_Value* value = GetValue();
- EXPECT_TRUE(value->IsString(isolate()));
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(GetScriptContext());
+ v8::Local<v8::Value> value = GetValue();
+ EXPECT_TRUE(fxv8::IsString(value));
}
TEST_F(CFXJSE_FormCalcContextEmbedderTest, Upper) {
diff --git a/testing/xfa_js_embedder_test.cpp b/testing/xfa_js_embedder_test.cpp
index c1a9b13..80defc8 100644
--- a/testing/xfa_js_embedder_test.cpp
+++ b/testing/xfa_js_embedder_test.cpp
@@ -8,7 +8,9 @@
#include "fpdfsdk/cpdfsdk_helpers.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
+#include "fxjs/fxv8.h"
#include "fxjs/xfa/cfxjse_engine.h"
+#include "fxjs/xfa/cfxjse_isolatetracker.h"
#include "fxjs/xfa/cfxjse_value.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -21,7 +23,7 @@
}
void XFAJSEmbedderTest::TearDown() {
- value_.reset();
+ value_.Reset();
script_context_ = nullptr;
JSEmbedderTest::TearDown();
@@ -39,6 +41,10 @@
return pContext->GetXFADoc()->GetXFADoc();
}
+v8::Local<v8::Value> XFAJSEmbedderTest::GetValue() const {
+ return v8::Local<v8::Value>::New(isolate(), value_);
+}
+
bool XFAJSEmbedderTest::OpenDocumentWithOptions(
const std::string& filename,
const char* password,
@@ -55,27 +61,38 @@
}
bool XFAJSEmbedderTest::Execute(ByteStringView input) {
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(script_context_->GetJseContext());
if (ExecuteHelper(input))
return true;
- CFXJSE_Value msg;
- value_->GetObjectPropertyByIdx(isolate(), 1, &msg);
fprintf(stderr, "FormCalc: %.*s\n", static_cast<int>(input.GetLength()),
input.unterminated_c_str());
- // If the parsing of the input fails, then v8 will not run, so there will be
- // no value here to print.
- if (msg.IsString(isolate()) && !msg.ToWideString(isolate()).IsEmpty())
- fprintf(stderr, "JS ERROR: %ls\n", msg.ToWideString(isolate()).c_str());
+
+ v8::Local<v8::Value> result = GetValue();
+ if (!fxv8::IsArray(result))
+ return false;
+
+ v8::Local<v8::Value> msg = fxv8::ReentrantGetArrayElementHelper(
+ isolate(), result.As<v8::Array>(), 1);
+ if (!fxv8::IsString(msg))
+ return false;
+
+ WideString str = fxv8::ReentrantToWideStringHelper(isolate(), msg);
+ if (!str.IsEmpty())
+ fprintf(stderr, "JS ERROR: %ls\n", str.c_str());
return false;
}
bool XFAJSEmbedderTest::ExecuteSilenceFailure(ByteStringView input) {
+ CFXJSE_ScopeUtil_IsolateHandleContext scope(script_context_->GetJseContext());
return ExecuteHelper(input);
}
bool XFAJSEmbedderTest::ExecuteHelper(ByteStringView input) {
- value_ = std::make_unique<CFXJSE_Value>();
- return script_context_->RunScript(CXFA_Script::Type::Formcalc,
- WideString::FromUTF8(input).AsStringView(),
- value_.get(), GetXFADocument()->GetRoot());
+ auto value = std::make_unique<CFXJSE_Value>();
+ bool ret = script_context_->RunScript(
+ CXFA_Script::Type::Formcalc, WideString::FromUTF8(input).AsStringView(),
+ value.get(), GetXFADocument()->GetRoot());
+ value_.Reset(isolate(), value->GetValue(isolate()));
+ return ret;
}
diff --git a/testing/xfa_js_embedder_test.h b/testing/xfa_js_embedder_test.h
index 0e47f34..3d223f7 100644
--- a/testing/xfa_js_embedder_test.h
+++ b/testing/xfa_js_embedder_test.h
@@ -10,9 +10,9 @@
#include "core/fxcrt/string_view_template.h"
#include "testing/js_embedder_test.h"
+#include "v8/include/v8.h"
class CFXJSE_Engine;
-class CFXJSE_Value;
class CXFA_Document;
class XFAJSEmbedderTest : public JSEmbedderTest {
@@ -30,7 +30,7 @@
CXFA_Document* GetXFADocument() const;
CFXJSE_Engine* GetScriptContext() const { return script_context_; }
- CFXJSE_Value* GetValue() const { return value_.get(); }
+ v8::Local<v8::Value> GetValue() const;
bool Execute(ByteStringView input);
bool ExecuteSilenceFailure(ByteStringView input);
@@ -38,7 +38,7 @@
private:
bool ExecuteHelper(ByteStringView input);
- std::unique_ptr<CFXJSE_Value> value_;
+ v8::Global<v8::Value> value_;
CFXJSE_Engine* script_context_ = nullptr;
};