blob: 9b295d0a39ee04a634d3878ff1795ee57a6b49b2 [file] [log] [blame]
Lei Zhang72e8b692019-02-05 19:16:52 +00001// Copyright 2019 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "testing/v8_initializer.h"
6
Felix Kauselmann5fe85692019-02-11 20:55:52 +00007#include <cstring>
8
Lei Zhangb6992dd2019-02-05 23:30:20 +00009#include "public/fpdfview.h"
10#include "testing/utils/file_util.h"
Lei Zhang72e8b692019-02-05 19:16:52 +000011#include "testing/utils/path_service.h"
12#include "v8/include/libplatform/libplatform.h"
13#include "v8/include/v8.h"
14
Tom Sepez30eddfa2021-02-16 19:24:00 +000015#ifdef PDF_ENABLE_XFA
16#include "v8/include/cppgc/platform.h"
17#endif
18
Lei Zhang72e8b692019-02-05 19:16:52 +000019namespace {
20
21#ifdef V8_USE_EXTERNAL_STARTUP_DATA
22// Returns the full path for an external V8 data file based on either
23// the currect exectuable path or an explicit override.
24std::string GetFullPathForSnapshotFile(const std::string& exe_path,
25 const std::string& bin_dir,
26 const std::string& filename) {
27 std::string result;
28 if (!bin_dir.empty()) {
29 result = bin_dir;
30 if (*bin_dir.rbegin() != PATH_SEPARATOR) {
31 result += PATH_SEPARATOR;
32 }
33 } else if (!exe_path.empty()) {
34 size_t last_separator = exe_path.rfind(PATH_SEPARATOR);
35 if (last_separator != std::string::npos) {
36 result = exe_path.substr(0, last_separator + 1);
37 }
38 }
39 result += filename;
40 return result;
41}
42
43bool GetExternalData(const std::string& exe_path,
44 const std::string& bin_dir,
45 const std::string& filename,
46 v8::StartupData* result_data) {
47 std::string full_path =
48 GetFullPathForSnapshotFile(exe_path, bin_dir, filename);
49 size_t data_length = 0;
50 std::unique_ptr<char, pdfium::FreeDeleter> data_buffer =
51 GetFileContents(full_path.c_str(), &data_length);
52 if (!data_buffer)
53 return false;
54
55 result_data->data = data_buffer.release();
56 result_data->raw_size = data_length;
57 return true;
58}
59#endif // V8_USE_EXTERNAL_STARTUP_DATA
60
Tom Sepeze0d3c502020-08-11 23:51:10 +000061std::unique_ptr<v8::Platform> InitializeV8Common(const std::string& exe_path,
62 const std::string& js_flags) {
Lei Zhang72e8b692019-02-05 19:16:52 +000063 v8::V8::InitializeICUDefaultLocation(exe_path.c_str());
64
65 std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform();
66 v8::V8::InitializePlatform(platform.get());
Tom Sepez30eddfa2021-02-16 19:24:00 +000067#ifdef PDF_ENABLE_XFA
68 cppgc::InitializeProcess(platform->GetPageAllocator());
69#endif
Lei Zhang72e8b692019-02-05 19:16:52 +000070
71 const char* recommended_v8_flags = FPDF_GetRecommendedV8Flags();
Lei Zhang06d1acb2019-05-04 07:40:40 +000072 v8::V8::SetFlagsFromString(recommended_v8_flags);
Lei Zhang72e8b692019-02-05 19:16:52 +000073
Tom Sepeze0d3c502020-08-11 23:51:10 +000074 if (!js_flags.empty())
75 v8::V8::SetFlagsFromString(js_flags.c_str());
76
Lei Zhang72e8b692019-02-05 19:16:52 +000077 // By enabling predictable mode, V8 won't post any background tasks.
78 // By enabling GC, it makes it easier to chase use-after-free.
79 static const char kAdditionalV8Flags[] = "--predictable --expose-gc";
Lei Zhang06d1acb2019-05-04 07:40:40 +000080 v8::V8::SetFlagsFromString(kAdditionalV8Flags);
Lei Zhang72e8b692019-02-05 19:16:52 +000081
82 v8::V8::Initialize();
83 return platform;
84}
85
86} // namespace
87
88#ifdef V8_USE_EXTERNAL_STARTUP_DATA
89std::unique_ptr<v8::Platform> InitializeV8ForPDFiumWithStartupData(
90 const std::string& exe_path,
Tom Sepeze0d3c502020-08-11 23:51:10 +000091 const std::string& js_flags,
Lei Zhang72e8b692019-02-05 19:16:52 +000092 const std::string& bin_dir,
Lei Zhang72e8b692019-02-05 19:16:52 +000093 v8::StartupData* snapshot_blob) {
Tom Sepeze0d3c502020-08-11 23:51:10 +000094 std::unique_ptr<v8::Platform> platform =
95 InitializeV8Common(exe_path, js_flags);
Lei Zhanga8e8baf2019-10-08 17:53:04 +000096 if (snapshot_blob) {
Lei Zhang72e8b692019-02-05 19:16:52 +000097 if (!GetExternalData(exe_path, bin_dir, "snapshot_blob.bin", snapshot_blob))
98 return nullptr;
Lei Zhang72e8b692019-02-05 19:16:52 +000099 v8::V8::SetSnapshotDataBlob(snapshot_blob);
100 }
101 return platform;
102}
103#else // V8_USE_EXTERNAL_STARTUP_DATA
104std::unique_ptr<v8::Platform> InitializeV8ForPDFium(
Tom Sepeze0d3c502020-08-11 23:51:10 +0000105 const std::string& exe_path,
106 const std::string& js_flags) {
107 return InitializeV8Common(exe_path, js_flags);
Lei Zhang72e8b692019-02-05 19:16:52 +0000108}
109#endif // V8_USE_EXTERNAL_STARTUP_DATA
Tom Sepez30eddfa2021-02-16 19:24:00 +0000110
111void ShutdownV8ForPDFium() {
112#ifdef PDF_ENABLE_XFA
113 cppgc::ShutdownProcess();
114#endif
Tom Sepeze506d562022-01-24 20:52:53 +0000115 v8::V8::Dispose();
Alan Screen5e30ae82021-12-01 23:08:27 +0000116 v8::V8::DisposePlatform();
Tom Sepez30eddfa2021-02-16 19:24:00 +0000117}