[web snapshots] d8 support for the initial version

Bug: v8:11525
Change-Id: I3ef480e34fa005add44c927e82b50ec31581e632
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2759517
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Commit-Queue: Marja Hölttä <marja@chromium.org>
Cr-Commit-Position: refs/heads/master@{#73465}
This commit is contained in:
Marja Hölttä 2021-03-16 14:02:35 +01:00 committed by Commit Bot
parent 1e606cb6e9
commit 6d5e538d2b
5 changed files with 105 additions and 10 deletions

View File

@ -59,6 +59,7 @@
#include "src/trap-handler/trap-handler.h"
#include "src/utils/ostreams.h"
#include "src/utils/utils.h"
#include "src/web-snapshot/web-snapshot.h"
#ifdef V8_FUZZILLI
#include "src/d8/cov.h"
@ -723,6 +724,27 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
if (!HandleUnhandledPromiseRejections(isolate)) success = false;
}
data->realm_current_ = data->realm_switch_;
if (options.web_snapshot_config) {
std::vector<std::string> exports;
if (!ReadLines(options.web_snapshot_config, exports)) {
Throw(isolate, "Web snapshots: unable to read config");
CHECK(try_catch.HasCaught());
ReportException(isolate, &try_catch);
return false;
}
i::WebSnapshotSerializer serializer(isolate);
i::WebSnapshotData snapshot_data;
if (serializer.TakeSnapshot(context, exports, snapshot_data)) {
DCHECK_NOT_NULL(snapshot_data.buffer);
WriteChars("web.snap", snapshot_data.buffer, snapshot_data.buffer_size);
} else {
CHECK(try_catch.HasCaught());
ReportException(isolate, &try_catch);
return false;
}
}
}
Local<Value> result;
if (!maybe_result.ToLocal(&result)) {
@ -1321,6 +1343,37 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
return true;
}
bool Shell::ExecuteWebSnapshot(Isolate* isolate, const char* file_name) {
HandleScope handle_scope(isolate);
PerIsolateData* data = PerIsolateData::Get(isolate);
Local<Context> realm = data->realms_[data->realm_current_].Get(isolate);
Context::Scope context_scope(realm);
std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory());
TryCatch try_catch(isolate);
try_catch.SetVerbose(true);
int length = 0;
std::unique_ptr<uint8_t[]> snapshot_data(
reinterpret_cast<uint8_t*>(ReadChars(absolute_path.c_str(), &length)));
if (length == 0) {
Throw(isolate, "Error reading the web snapshot");
DCHECK(try_catch.HasCaught());
ReportException(isolate, &try_catch);
return false;
}
i::WebSnapshotDeserializer deserializer(isolate);
if (!deserializer.UseWebSnapshot(snapshot_data.get(),
static_cast<size_t>(length))) {
DCHECK(try_catch.HasCaught());
ReportException(isolate, &try_catch);
return false;
}
DCHECK(!try_catch.HasCaught());
return true;
}
PerIsolateData::PerIsolateData(Isolate* isolate)
: isolate_(isolate), realms_(nullptr) {
isolate->SetData(0, this);
@ -3058,9 +3111,9 @@ static FILE* FOpen(const char* path, const char* mode) {
#endif
}
static char* ReadChars(const char* name, int* size_out) {
if (Shell::options.read_from_tcp_port >= 0) {
return Shell::ReadCharsFromTcpPort(name, size_out);
char* Shell::ReadChars(const char* name, int* size_out) {
if (options.read_from_tcp_port >= 0) {
return ReadCharsFromTcpPort(name, size_out);
}
FILE* file = FOpen(name, "rb");
@ -3085,6 +3138,20 @@ static char* ReadChars(const char* name, int* size_out) {
return chars;
}
bool Shell::ReadLines(const char* name, std::vector<std::string>& lines) {
int length;
const char* data = reinterpret_cast<const char*>(ReadChars(name, &length));
if (data == nullptr) {
return false;
}
std::stringstream stream(data);
std::string line;
while (std::getline(stream, line, '\n')) {
lines.emplace_back(line);
}
return true;
}
void Shell::ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args) {
static_assert(sizeof(char) == sizeof(uint8_t),
"char and uint8_t should both have 1 byte");
@ -3135,6 +3202,13 @@ Local<String> Shell::ReadFile(Isolate* isolate, const char* name) {
return result;
}
void Shell::WriteChars(const char* name, uint8_t* buffer, size_t buffer_size) {
FILE* file = base::Fopen(name, "w");
if (file == nullptr) return;
fwrite(buffer, 1, buffer_size, file);
base::Fclose(file);
}
void Shell::RunShell(Isolate* isolate) {
HandleScope outer_scope(isolate);
v8::Local<v8::Context> context =
@ -3392,6 +3466,15 @@ bool SourceGroup::Execute(Isolate* isolate) {
break;
}
continue;
} else if (strcmp(arg, "--web-snapshot") == 0 && i + 1 < end_offset_) {
// Treat the next file as a web snapshot.
arg = argv_[++i];
Shell::set_script_executed();
if (!Shell::ExecuteWebSnapshot(isolate, arg)) {
success = false;
break;
}
continue;
} else if (arg[0] == '-') {
// Ignore other options. They have been parsed already.
continue;
@ -3944,6 +4027,9 @@ bool Shell::SetOptions(int argc, char* argv[]) {
options.cpu_profiler = true;
options.cpu_profiler_print = true;
argv[i] = nullptr;
} else if (strncmp(argv[i], "--web-snapshot-config=", 22) == 0) {
options.web_snapshot_config = argv[i] + 22;
argv[i] = nullptr;
#ifdef V8_FUZZILLI
} else if (strcmp(argv[i], "--no-fuzzilli-enable-builtins-coverage") == 0) {
options.fuzzilli_enable_builtins_coverage = false;
@ -3972,10 +4058,12 @@ bool Shell::SetOptions(int argc, char* argv[]) {
const char* usage =
"Synopsis:\n"
" shell [options] [--shell] [<file>...]\n"
" d8 [options] [-e <string>] [--shell] [[--module] <file>...]\n\n"
" d8 [options] [-e <string>] [--shell] [[--module|--web-snapshot]"
" <file>...]\n\n"
" -e execute a string in V8\n"
" --shell run an interactive JavaScript shell\n"
" --module execute a file as a JavaScript module\n\n";
" --module execute a file as a JavaScript module\n"
" --web-snapshot execute a file as a web snapshot\n\n";
using HelpOptions = i::FlagList::HelpOptions;
i::FLAG_abort_on_contradictory_flags = true;
i::FlagList::SetFlagsFromCommandLine(&argc, argv, true,
@ -3997,8 +4085,9 @@ bool Shell::SetOptions(int argc, char* argv[]) {
current->End(i);
current++;
current->Begin(argv, i + 1);
} else if (strcmp(str, "--module") == 0) {
// Pass on to SourceGroup, which understands this option.
} else if (strcmp(str, "--module") == 0 ||
strcmp(str, "--web-snapshot") == 0) {
// Pass on to SourceGroup, which understands these options.
} else if (strncmp(str, "--", 2) == 0) {
if (!i::FLAG_correctness_fuzzer_suppressions) {
printf("Warning: unknown flag %s.\nTry --help for options\n", str);

View File

@ -401,6 +401,8 @@ class ShellOptions {
"fuzzy-module-file-extensions", true};
DisallowReassignment<bool> enable_system_instrumentation = {
"enable-system-instrumentation", false};
DisallowReassignment<const char*> web_snapshot_config = {
"web-snapshot-config", nullptr};
};
class Shell : public i::AllStatic {
@ -420,6 +422,7 @@ class Shell : public i::AllStatic {
ReportExceptions report_exceptions,
ProcessMessageQueue process_message_queue);
static bool ExecuteModule(Isolate* isolate, const char* file_name);
static bool ExecuteWebSnapshot(Isolate* isolate, const char* file_name);
static void ReportException(Isolate* isolate, Local<Message> message,
Local<Value> exception);
static void ReportException(Isolate* isolate, TryCatch* try_catch);
@ -489,11 +492,14 @@ class Shell : public i::AllStatic {
static void Quit(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Version(const v8::FunctionCallbackInfo<v8::Value>& args);
static void Read(const v8::FunctionCallbackInfo<v8::Value>& args);
static char* ReadChars(const char* name, int* size_out);
static bool ReadLines(const char* name, std::vector<std::string>& lines);
static void ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& args);
static Local<String> ReadFromStdin(Isolate* isolate);
static void ReadLine(const v8::FunctionCallbackInfo<v8::Value>& args) {
args.GetReturnValue().Set(ReadFromStdin(args.GetIsolate()));
}
static void WriteChars(const char* name, uint8_t* buffer, size_t buffer_size);
static void Load(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SetTimeout(const v8::FunctionCallbackInfo<v8::Value>& args);
static void WorkerNew(const v8::FunctionCallbackInfo<v8::Value>& args);

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --stack-size=50
// Flags: --stack-size=100
function __f_3() {
try {

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --jitless --gc-interval=12 --stack-size=50
// Flags: --jitless --gc-interval=12 --stack-size=100
__f_0();
function __f_0() {

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --allow-natives-syntax --stack-size=50 --ignore-unhandled-promises
// Flags: --allow-natives-syntax --stack-size=100 --ignore-unhandled-promises
let i = 0;
function f() {