Add FPDF_GetArrayBufferAllocatorSharedInstance()
This is also an enabling step to call PumpMessageLoop()
from pdfium_test without changing other APIs since it
will own the isolate required for pumping.
-- use it under pdfium_test.cc
Bug: chromium:1091380
Change-Id: I3368987ed89f9ba8250caec2c40f759691aaf896
Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/70391
Commit-Queue: Tom Sepez <tsepez@chromium.org>
Reviewed-by: Lei Zhang <thestig@chromium.org>
diff --git a/fpdfsdk/fpdf_view.cpp b/fpdfsdk/fpdf_view.cpp
index 0eddaf8..7d74625 100644
--- a/fpdfsdk/fpdf_view.cpp
+++ b/fpdfsdk/fpdf_view.cpp
@@ -47,6 +47,11 @@
#include "third_party/base/ptr_util.h"
#include "third_party/base/span.h"
+#ifdef PDF_ENABLE_V8
+#include "fxjs/cfx_v8.h"
+#include "third_party/base/no_destructor.h"
+#endif
+
#ifdef PDF_ENABLE_XFA
#include "fpdfsdk/fpdfxfa/cpdfxfa_context.h"
#include "fpdfsdk/fpdfxfa/cpdfxfa_page.h"
@@ -989,6 +994,11 @@
// Use interpreted JS only to avoid RWX pages in our address space.
return "--no-expose-wasm --jitless";
}
+
+FPDF_EXPORT void* FPDF_CALLCONV FPDF_GetArrayBufferAllocatorSharedInstance() {
+ static pdfium::base::NoDestructor<CFX_V8ArrayBufferAllocator> allocator;
+ return allocator.get();
+}
#endif // PDF_ENABLE_V8
#ifdef PDF_ENABLE_XFA
diff --git a/fpdfsdk/fpdf_view_c_api_test.c b/fpdfsdk/fpdf_view_c_api_test.c
index 9ee6778..68189fc 100644
--- a/fpdfsdk/fpdf_view_c_api_test.c
+++ b/fpdfsdk/fpdf_view_c_api_test.c
@@ -413,6 +413,9 @@
CHK(FPDF_DestroyLibrary);
CHK(FPDF_DeviceToPage);
CHK(FPDF_DocumentHasValidCrossReferenceTable);
+#ifdef PDF_ENABLE_V8
+ CHK(FPDF_GetArrayBufferAllocatorSharedInstance);
+#endif
CHK(FPDF_GetDocPermissions);
CHK(FPDF_GetFileVersion);
CHK(FPDF_GetLastError);
diff --git a/public/fpdfview.h b/public/fpdfview.h
index bd8cbbe..079a856 100644
--- a/public/fpdfview.h
+++ b/public/fpdfview.h
@@ -1295,6 +1295,21 @@
// NUL-terminated string of the form "--flag1 --flag2".
// The caller must not attempt to modify or free the result.
FPDF_EXPORT const char* FPDF_CALLCONV FPDF_GetRecommendedV8Flags();
+
+// Experimental API.
+// Function: FPDF_GetArrayBufferAllocatorSharedInstance()
+// Helper function for initializing V8 isolates that will
+// use PDFium's internal memory management.
+// Parameters:
+// None.
+// Return Value:
+// Pointer to a suitable v8::ArrayBuffer::Allocator, returned
+// as void for C compatibility.
+// Notes:
+// Use is optional, but allows external creation of isolates
+// matching the ones PDFium will make when none is provided
+// via |FPDF_LIBRARY_CONFIG::m_pIsolate|.
+FPDF_EXPORT void* FPDF_CALLCONV FPDF_GetArrayBufferAllocatorSharedInstance();
#endif // PDF_ENABLE_V8
#ifdef PDF_ENABLE_XFA
diff --git a/samples/pdfium_test.cc b/samples/pdfium_test.cc
index d7f211c..d983526 100644
--- a/samples/pdfium_test.cc
+++ b/samples/pdfium_test.cc
@@ -229,6 +229,11 @@
}
#ifdef PDF_ENABLE_V8
+
+struct V8IsolateDeleter {
+ inline void operator()(v8::Isolate* ptr) { ptr->Dispose(); }
+};
+
// These example JS platform callback handlers are entirely optional,
// and exist here to show the flow of information from a document back
// to the embedder.
@@ -1125,26 +1130,33 @@
return 1;
}
-#ifdef PDF_ENABLE_V8
- std::unique_ptr<v8::Platform> platform;
-#ifdef V8_USE_EXTERNAL_STARTUP_DATA
- v8::StartupData snapshot;
- if (!options.disable_javascript) {
- platform = InitializeV8ForPDFiumWithStartupData(
- options.exe_path, options.bin_directory, &snapshot);
- }
-#else // V8_USE_EXTERNAL_STARTUP_DATA
- if (!options.disable_javascript)
- platform = InitializeV8ForPDFium(options.exe_path);
-#endif // V8_USE_EXTERNAL_STARTUP_DATA
-#endif // PDF_ENABLE_V8
-
FPDF_LIBRARY_CONFIG config;
config.version = 2;
config.m_pUserFontPaths = nullptr;
config.m_pIsolate = nullptr;
config.m_v8EmbedderSlot = 0;
+#ifdef PDF_ENABLE_V8
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ v8::StartupData snapshot;
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
+ std::unique_ptr<v8::Platform> platform;
+ std::unique_ptr<v8::Isolate, V8IsolateDeleter> isolate;
+ if (!options.disable_javascript) {
+#ifdef V8_USE_EXTERNAL_STARTUP_DATA
+ platform = InitializeV8ForPDFiumWithStartupData(
+ options.exe_path, options.bin_directory, &snapshot);
+#else // V8_USE_EXTERNAL_STARTUP_DATA
+ platform = InitializeV8ForPDFium(options.exe_path);
+#endif // V8_USE_EXTERNAL_STARTUP_DATA
+ v8::Isolate::CreateParams params;
+ params.array_buffer_allocator = static_cast<v8::ArrayBuffer::Allocator*>(
+ FPDF_GetArrayBufferAllocatorSharedInstance());
+ isolate.reset(v8::Isolate::New(params));
+ config.m_pIsolate = isolate.get();
+ }
+#endif // PDF_ENABLE_V8
+
const char* path_array[2] = {nullptr, nullptr};
Optional<const char*> custom_font_path = GetCustomFontPath(options);
if (custom_font_path.has_value()) {
@@ -1212,6 +1224,7 @@
#ifdef PDF_ENABLE_V8
if (!options.disable_javascript) {
+ isolate.reset();
v8::V8::ShutdownPlatform();
#ifdef V8_USE_EXTERNAL_STARTUP_DATA
free(const_cast<char*>(snapshot.data));