[web snapshots] Remove web snapshots
Bug: v8:11525 Change-Id: I0931408eefa4f55b0c9e8c0973787edfb903083a Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4205917 Commit-Queue: Marja Hölttä <marja@chromium.org> Reviewed-by: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/main@{#85559}
This commit is contained in:
parent
9bc6586712
commit
1f349da554
@ -1164,7 +1164,6 @@ filegroup(
|
|||||||
"src/builtins/builtins-utils-inl.h",
|
"src/builtins/builtins-utils-inl.h",
|
||||||
"src/builtins/builtins-utils.h",
|
"src/builtins/builtins-utils.h",
|
||||||
"src/builtins/builtins-weak-refs.cc",
|
"src/builtins/builtins-weak-refs.cc",
|
||||||
"src/builtins/builtins-web-snapshots.cc",
|
|
||||||
"src/builtins/builtins.cc",
|
"src/builtins/builtins.cc",
|
||||||
"src/builtins/builtins.h",
|
"src/builtins/builtins.h",
|
||||||
"src/builtins/constants-table-builder.cc",
|
"src/builtins/constants-table-builder.cc",
|
||||||
@ -2207,8 +2206,6 @@ filegroup(
|
|||||||
"src/utils/utils.h",
|
"src/utils/utils.h",
|
||||||
"src/utils/version.cc",
|
"src/utils/version.cc",
|
||||||
"src/utils/version.h",
|
"src/utils/version.h",
|
||||||
"src/web-snapshot/web-snapshot.h",
|
|
||||||
"src/web-snapshot/web-snapshot.cc",
|
|
||||||
"src/zone/accounting-allocator.cc",
|
"src/zone/accounting-allocator.cc",
|
||||||
"src/zone/accounting-allocator.h",
|
"src/zone/accounting-allocator.h",
|
||||||
"src/zone/compressed-zone-ptr.h",
|
"src/zone/compressed-zone-ptr.h",
|
||||||
|
3
BUILD.gn
3
BUILD.gn
@ -4562,7 +4562,6 @@ v8_source_set("v8_base_without_compiler") {
|
|||||||
"src/builtins/builtins-trace.cc",
|
"src/builtins/builtins-trace.cc",
|
||||||
"src/builtins/builtins-typed-array.cc",
|
"src/builtins/builtins-typed-array.cc",
|
||||||
"src/builtins/builtins-weak-refs.cc",
|
"src/builtins/builtins-weak-refs.cc",
|
||||||
"src/builtins/builtins-web-snapshots.cc",
|
|
||||||
"src/builtins/builtins.cc",
|
"src/builtins/builtins.cc",
|
||||||
"src/builtins/constants-table-builder.cc",
|
"src/builtins/constants-table-builder.cc",
|
||||||
"src/codegen/aligned-slot-allocator.cc",
|
"src/codegen/aligned-slot-allocator.cc",
|
||||||
@ -4955,8 +4954,6 @@ v8_source_set("v8_base_without_compiler") {
|
|||||||
"src/utils/sha-256.cc",
|
"src/utils/sha-256.cc",
|
||||||
"src/utils/utils.cc",
|
"src/utils/utils.cc",
|
||||||
"src/utils/version.cc",
|
"src/utils/version.cc",
|
||||||
"src/web-snapshot/web-snapshot.cc",
|
|
||||||
"src/web-snapshot/web-snapshot.h",
|
|
||||||
"src/zone/accounting-allocator.cc",
|
"src/zone/accounting-allocator.cc",
|
||||||
"src/zone/type-stats.cc",
|
"src/zone/type-stats.cc",
|
||||||
"src/zone/zone-segment.cc",
|
"src/zone/zone-segment.cc",
|
||||||
|
@ -128,7 +128,6 @@
|
|||||||
#include "src/tracing/trace-event.h"
|
#include "src/tracing/trace-event.h"
|
||||||
#include "src/utils/detachable-vector.h"
|
#include "src/utils/detachable-vector.h"
|
||||||
#include "src/utils/version.h"
|
#include "src/utils/version.h"
|
||||||
#include "src/web-snapshot/web-snapshot.h"
|
|
||||||
|
|
||||||
#if V8_ENABLE_WEBASSEMBLY
|
#if V8_ENABLE_WEBASSEMBLY
|
||||||
#include "src/trap-handler/trap-handler.h"
|
#include "src/trap-handler/trap-handler.h"
|
||||||
@ -2225,22 +2224,6 @@ MaybeLocal<Value> Script::Run(Local<Context> context,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
|
auto fun = i::Handle<i::JSFunction>::cast(Utils::OpenHandle(this));
|
||||||
|
|
||||||
if (V8_UNLIKELY(i::v8_flags.experimental_web_snapshots)) {
|
|
||||||
i::Handle<i::HeapObject> maybe_script =
|
|
||||||
handle(fun->shared().script(), i_isolate);
|
|
||||||
if (maybe_script->IsScript() &&
|
|
||||||
i::Script::cast(*maybe_script).type() == i::Script::TYPE_WEB_SNAPSHOT) {
|
|
||||||
i::WebSnapshotDeserializer deserializer(
|
|
||||||
reinterpret_cast<i::Isolate*>(v8_isolate),
|
|
||||||
i::Handle<i::Script>::cast(maybe_script));
|
|
||||||
deserializer.Deserialize();
|
|
||||||
RETURN_ON_FAILED_EXECUTION(Value);
|
|
||||||
Local<Value> result = v8::Undefined(v8_isolate);
|
|
||||||
RETURN_ESCAPED(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i::Handle<i::Object> receiver = i_isolate->global_proxy();
|
i::Handle<i::Object> receiver = i_isolate->global_proxy();
|
||||||
// TODO(cbruni, chromium:1244145): Remove once migrated to the context.
|
// TODO(cbruni, chromium:1244145): Remove once migrated to the context.
|
||||||
i::Handle<i::Object> options(
|
i::Handle<i::Object> options(
|
||||||
|
@ -626,10 +626,6 @@ namespace internal {
|
|||||||
CPP(JsonRawJson) \
|
CPP(JsonRawJson) \
|
||||||
CPP(JsonIsRawJson) \
|
CPP(JsonIsRawJson) \
|
||||||
\
|
\
|
||||||
/* Web snapshots */ \
|
|
||||||
CPP(WebSnapshotSerialize) \
|
|
||||||
CPP(WebSnapshotDeserialize) \
|
|
||||||
\
|
|
||||||
/* ICs */ \
|
/* ICs */ \
|
||||||
TFH(LoadIC, LoadWithVector) \
|
TFH(LoadIC, LoadWithVector) \
|
||||||
TFH(LoadIC_Megamorphic, LoadWithVector) \
|
TFH(LoadIC_Megamorphic, LoadWithVector) \
|
||||||
|
@ -1,119 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#include "src/builtins/builtins-utils-inl.h"
|
|
||||||
#include "src/builtins/builtins.h"
|
|
||||||
#include "src/logging/counters.h"
|
|
||||||
#include "src/objects/js-array-buffer-inl.h"
|
|
||||||
#include "src/objects/js-array-inl.h"
|
|
||||||
#include "src/objects/objects-inl.h"
|
|
||||||
#include "src/web-snapshot/web-snapshot.h"
|
|
||||||
|
|
||||||
namespace v8 {
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
BUILTIN(WebSnapshotSerialize) {
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
if (args.length() < 2 || args.length() > 3) {
|
|
||||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
|
||||||
isolate, NewTypeError(MessageTemplate::kInvalidArgument));
|
|
||||||
}
|
|
||||||
Handle<Object> object = args.at(1);
|
|
||||||
Handle<FixedArray> block_list = isolate->factory()->empty_fixed_array();
|
|
||||||
Handle<JSArray> block_list_js_array;
|
|
||||||
if (args.length() == 3) {
|
|
||||||
if (!args[2].IsJSArray()) {
|
|
||||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
|
||||||
isolate, NewTypeError(MessageTemplate::kInvalidArgument));
|
|
||||||
}
|
|
||||||
block_list_js_array = args.at<JSArray>(2);
|
|
||||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
|
||||||
isolate, block_list,
|
|
||||||
JSReceiver::GetOwnValues(isolate, block_list_js_array,
|
|
||||||
PropertyFilter::ENUMERABLE_STRINGS));
|
|
||||||
}
|
|
||||||
|
|
||||||
auto snapshot_data = std::make_shared<WebSnapshotData>();
|
|
||||||
WebSnapshotSerializer serializer(isolate);
|
|
||||||
if (!serializer.TakeSnapshot(object, block_list, *snapshot_data)) {
|
|
||||||
DCHECK(isolate->has_pending_exception());
|
|
||||||
return ReadOnlyRoots(isolate).exception();
|
|
||||||
}
|
|
||||||
if (!block_list_js_array.is_null() &&
|
|
||||||
static_cast<uint32_t>(block_list->length()) <
|
|
||||||
serializer.external_object_count()) {
|
|
||||||
Handle<FixedArray> externals = serializer.GetExternals();
|
|
||||||
Handle<Map> map = JSObject::GetElementsTransitionMap(block_list_js_array,
|
|
||||||
PACKED_ELEMENTS);
|
|
||||||
block_list_js_array->set_elements(*externals);
|
|
||||||
block_list_js_array->set_length(Smi::FromInt(externals->length()));
|
|
||||||
block_list_js_array->set_map(*map);
|
|
||||||
}
|
|
||||||
|
|
||||||
MaybeHandle<JSArrayBuffer> maybe_result =
|
|
||||||
isolate->factory()->NewJSArrayBufferAndBackingStore(
|
|
||||||
snapshot_data->buffer_size, InitializedFlag::kUninitialized);
|
|
||||||
Handle<JSArrayBuffer> result;
|
|
||||||
if (!maybe_result.ToHandle(&result)) {
|
|
||||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
|
||||||
isolate, NewTypeError(MessageTemplate::kOutOfMemory,
|
|
||||||
isolate->factory()->NewStringFromAsciiChecked(
|
|
||||||
"WebSnapshotSerialize")));
|
|
||||||
}
|
|
||||||
uint8_t* data =
|
|
||||||
reinterpret_cast<uint8_t*>(result->GetBackingStore()->buffer_start());
|
|
||||||
memcpy(data, snapshot_data->buffer, snapshot_data->buffer_size);
|
|
||||||
|
|
||||||
return *result;
|
|
||||||
}
|
|
||||||
|
|
||||||
BUILTIN(WebSnapshotDeserialize) {
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
if (args.length() < 2 || args.length() > 3) {
|
|
||||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
|
||||||
isolate, NewTypeError(MessageTemplate::kInvalidArgument));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!args[1].IsJSArrayBuffer()) {
|
|
||||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
|
||||||
isolate, NewTypeError(MessageTemplate::kInvalidArgument));
|
|
||||||
}
|
|
||||||
auto buffer = args.at<JSArrayBuffer>(1);
|
|
||||||
std::shared_ptr<BackingStore> backing_store = buffer->GetBackingStore();
|
|
||||||
if (backing_store.get() == nullptr) {
|
|
||||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
|
||||||
isolate, NewTypeError(MessageTemplate::kInvalidArgument));
|
|
||||||
}
|
|
||||||
const uint8_t* data =
|
|
||||||
reinterpret_cast<uint8_t*>(backing_store->buffer_start());
|
|
||||||
|
|
||||||
Handle<FixedArray> injected_references =
|
|
||||||
isolate->factory()->empty_fixed_array();
|
|
||||||
if (args.length() == 3) {
|
|
||||||
if (!args[2].IsJSArray()) {
|
|
||||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
|
||||||
isolate, NewTypeError(MessageTemplate::kInvalidArgument));
|
|
||||||
}
|
|
||||||
auto js_array = args.at<JSArray>(2);
|
|
||||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
|
||||||
isolate, injected_references,
|
|
||||||
JSReceiver::GetOwnValues(isolate, js_array,
|
|
||||||
PropertyFilter::ENUMERABLE_STRINGS));
|
|
||||||
}
|
|
||||||
|
|
||||||
WebSnapshotDeserializer deserializer(reinterpret_cast<v8::Isolate*>(isolate),
|
|
||||||
data, backing_store->byte_length());
|
|
||||||
if (!deserializer.Deserialize(injected_references)) {
|
|
||||||
DCHECK(isolate->has_pending_exception());
|
|
||||||
return ReadOnlyRoots(isolate).exception();
|
|
||||||
}
|
|
||||||
Handle<Object> object;
|
|
||||||
if (!deserializer.value().ToHandle(&object)) {
|
|
||||||
return ReadOnlyRoots(isolate).undefined_value();
|
|
||||||
}
|
|
||||||
return *object;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace v8
|
|
@ -62,7 +62,6 @@
|
|||||||
#include "src/parsing/scanner-character-streams.h"
|
#include "src/parsing/scanner-character-streams.h"
|
||||||
#include "src/snapshot/code-serializer.h"
|
#include "src/snapshot/code-serializer.h"
|
||||||
#include "src/utils/ostreams.h"
|
#include "src/utils/ostreams.h"
|
||||||
#include "src/web-snapshot/web-snapshot.h"
|
|
||||||
#include "src/zone/zone-list-inl.h" // crbug.com/v8/8816
|
#include "src/zone/zone-list-inl.h" // crbug.com/v8/8816
|
||||||
|
|
||||||
#ifdef V8_ENABLE_MAGLEV
|
#ifdef V8_ENABLE_MAGLEV
|
||||||
@ -3451,29 +3450,6 @@ MaybeHandle<SharedFunctionInfo> GetSharedFunctionInfoForScriptImpl(
|
|||||||
DCHECK_NULL(deserialize_task);
|
DCHECK_NULL(deserialize_task);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (V8_UNLIKELY(
|
|
||||||
v8_flags.experimental_web_snapshots &&
|
|
||||||
(source->IsExternalOneByteString() || source->IsSeqOneByteString() ||
|
|
||||||
source->IsExternalTwoByteString() || source->IsSeqTwoByteString()) &&
|
|
||||||
source->length() > 4)) {
|
|
||||||
// Experimental: Treat the script as a web snapshot if it starts with the
|
|
||||||
// magic byte sequence. TODO(v8:11525): Remove this once proper embedder
|
|
||||||
// integration is done.
|
|
||||||
bool magic_matches = true;
|
|
||||||
for (size_t i = 0;
|
|
||||||
i < sizeof(WebSnapshotSerializerDeserializer::kMagicNumber); ++i) {
|
|
||||||
if (source->Get(static_cast<int>(i)) !=
|
|
||||||
WebSnapshotSerializerDeserializer::kMagicNumber[i]) {
|
|
||||||
magic_matches = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (magic_matches) {
|
|
||||||
return Compiler::GetSharedFunctionInfoForWebSnapshot(
|
|
||||||
isolate, source, script_details.name_obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LanguageMode language_mode = construct_language_mode(v8_flags.use_strict);
|
LanguageMode language_mode = construct_language_mode(v8_flags.use_strict);
|
||||||
CompilationCache* compilation_cache = isolate->compilation_cache();
|
CompilationCache* compilation_cache = isolate->compilation_cache();
|
||||||
|
|
||||||
@ -3801,30 +3777,6 @@ Compiler::GetSharedFunctionInfoForStreamedScript(
|
|||||||
return maybe_result;
|
return maybe_result;
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
// static
|
|
||||||
Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForWebSnapshot(
|
|
||||||
Isolate* isolate, Handle<String> source,
|
|
||||||
MaybeHandle<Object> maybe_script_name) {
|
|
||||||
// This script won't hold the functions created from the web snapshot;
|
|
||||||
// reserving space only for the top-level SharedFunctionInfo is enough.
|
|
||||||
Handle<WeakFixedArray> shared_function_infos =
|
|
||||||
isolate->factory()->NewWeakFixedArray(1, AllocationType::kOld);
|
|
||||||
Handle<Script> script = isolate->factory()->NewScript(source);
|
|
||||||
script->set_type(Script::TYPE_WEB_SNAPSHOT);
|
|
||||||
script->set_shared_function_infos(*shared_function_infos);
|
|
||||||
Handle<Object> script_name;
|
|
||||||
if (maybe_script_name.ToHandle(&script_name) && script_name->IsString()) {
|
|
||||||
script->set_name(String::cast(*script_name));
|
|
||||||
} else {
|
|
||||||
script->set_name(*isolate->factory()->empty_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle<SharedFunctionInfo> shared =
|
|
||||||
isolate->factory()->NewSharedFunctionInfoForWebSnapshot();
|
|
||||||
shared->SetScript(isolate->factory()->read_only_roots(), *script, 0, false);
|
|
||||||
return shared;
|
|
||||||
}
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
template <typename IsolateT>
|
template <typename IsolateT>
|
||||||
Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||||
|
@ -224,9 +224,6 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
|
|||||||
Isolate* isolate, Handle<String> source,
|
Isolate* isolate, Handle<String> source,
|
||||||
const ScriptDetails& script_details, ScriptStreamingData* streaming_data);
|
const ScriptDetails& script_details, ScriptStreamingData* streaming_data);
|
||||||
|
|
||||||
static Handle<SharedFunctionInfo> GetSharedFunctionInfoForWebSnapshot(
|
|
||||||
Isolate* isolate, Handle<String> source, MaybeHandle<Object> script_name);
|
|
||||||
|
|
||||||
// Create a shared function info object for the given function literal
|
// Create a shared function info object for the given function literal
|
||||||
// node (the code may be lazily compiled).
|
// node (the code may be lazily compiled).
|
||||||
template <typename IsolateT>
|
template <typename IsolateT>
|
||||||
|
@ -709,10 +709,7 @@ namespace internal {
|
|||||||
T(OptionalChainingNoSuper, "Invalid optional chain from super property") \
|
T(OptionalChainingNoSuper, "Invalid optional chain from super property") \
|
||||||
T(OptionalChainingNoTemplate, "Invalid tagged template on optional chain") \
|
T(OptionalChainingNoTemplate, "Invalid tagged template on optional chain") \
|
||||||
/* AggregateError */ \
|
/* AggregateError */ \
|
||||||
T(AllPromisesRejected, "All promises were rejected") \
|
T(AllPromisesRejected, "All promises were rejected")
|
||||||
/* Web snapshots */ \
|
|
||||||
T(WebSnapshotError, "Web snapshot failed: %")
|
|
||||||
|
|
||||||
enum class MessageTemplate {
|
enum class MessageTemplate {
|
||||||
#define TEMPLATE(NAME, STRING) k##NAME,
|
#define TEMPLATE(NAME, STRING) k##NAME,
|
||||||
MESSAGE_TEMPLATES(TEMPLATE)
|
MESSAGE_TEMPLATES(TEMPLATE)
|
||||||
|
238
src/d8/d8.cc
238
src/d8/d8.cc
@ -69,7 +69,6 @@
|
|||||||
#include "src/tasks/cancelable-task.h"
|
#include "src/tasks/cancelable-task.h"
|
||||||
#include "src/utils/ostreams.h"
|
#include "src/utils/ostreams.h"
|
||||||
#include "src/utils/utils.h"
|
#include "src/utils/utils.h"
|
||||||
#include "src/web-snapshot/web-snapshot.h"
|
|
||||||
|
|
||||||
#if V8_OS_POSIX
|
#if V8_OS_POSIX
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -914,52 +913,6 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
|
|||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Shell::TakeWebSnapshot(Isolate* isolate) {
|
|
||||||
PerIsolateData* data = PerIsolateData::Get(isolate);
|
|
||||||
Local<Context> realm =
|
|
||||||
Local<Context>::New(isolate, data->realms_[data->realm_current_]);
|
|
||||||
Context::Scope context_scope(realm);
|
|
||||||
Local<Context> context(isolate->GetCurrentContext());
|
|
||||||
|
|
||||||
v8::TryCatch try_catch(isolate);
|
|
||||||
try_catch.SetVerbose(true);
|
|
||||||
const char* web_snapshot_output_file_name = "web.snap";
|
|
||||||
if (options.web_snapshot_output) {
|
|
||||||
web_snapshot_output_file_name = options.web_snapshot_output;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!options.web_snapshot_config) {
|
|
||||||
isolate->ThrowError(
|
|
||||||
"Web snapshots: --web-snapshot-config is needed when "
|
|
||||||
"--web-snapshot-output is passed");
|
|
||||||
CHECK(try_catch.HasCaught());
|
|
||||||
ReportException(isolate, &try_catch);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MaybeLocal<PrimitiveArray> maybe_exports =
|
|
||||||
ReadLines(isolate, options.web_snapshot_config);
|
|
||||||
Local<PrimitiveArray> exports;
|
|
||||||
if (!maybe_exports.ToLocal(&exports)) {
|
|
||||||
isolate->ThrowError("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_snapshot_output_file_name, snapshot_data.buffer,
|
|
||||||
snapshot_data.buffer_size);
|
|
||||||
} else {
|
|
||||||
CHECK(try_catch.HasCaught());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
bool IsAbsolutePath(const std::string& path) {
|
bool IsAbsolutePath(const std::string& path) {
|
||||||
@ -1499,44 +1452,6 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
|
|||||||
return true;
|
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());
|
|
||||||
|
|
||||||
int length = 0;
|
|
||||||
std::unique_ptr<uint8_t[]> snapshot_data(
|
|
||||||
reinterpret_cast<uint8_t*>(ReadChars(absolute_path.c_str(), &length)));
|
|
||||||
if (length == 0) {
|
|
||||||
TryCatch try_catch(isolate);
|
|
||||||
isolate->ThrowError("Could not read the web snapshot file");
|
|
||||||
CHECK(try_catch.HasCaught());
|
|
||||||
ReportException(isolate, &try_catch);
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
for (int r = 0; r < DeserializationRunCount(); ++r) {
|
|
||||||
bool skip_exports = r > 0;
|
|
||||||
i::WebSnapshotDeserializer deserializer(isolate, snapshot_data.get(),
|
|
||||||
static_cast<size_t>(length));
|
|
||||||
if (!deserializer.Deserialize({}, skip_exports)) {
|
|
||||||
// d8 is calling into the internal APIs which won't do
|
|
||||||
// ReportPendingMessages in all error paths (it's supposed to be done at
|
|
||||||
// the API boundary). Call it here.
|
|
||||||
auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
|
||||||
if (i_isolate->has_pending_exception()) {
|
|
||||||
i_isolate->ReportPendingMessages();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Treat every line as a JSON value and parse it.
|
// Treat every line as a JSON value and parse it.
|
||||||
bool Shell::LoadJSON(Isolate* isolate, const char* file_name) {
|
bool Shell::LoadJSON(Isolate* isolate, const char* file_name) {
|
||||||
HandleScope handle_scope(isolate);
|
HandleScope handle_scope(isolate);
|
||||||
@ -1579,10 +1494,6 @@ PerIsolateData::PerIsolateData(Isolate* isolate)
|
|||||||
async_hooks_wrapper_ = new AsyncHooks(isolate);
|
async_hooks_wrapper_ = new AsyncHooks(isolate);
|
||||||
}
|
}
|
||||||
ignore_unhandled_promises_ = false;
|
ignore_unhandled_promises_ = false;
|
||||||
// TODO(v8:11525): Use methods on global Snapshot objects with
|
|
||||||
// signature checks.
|
|
||||||
HandleScope scope(isolate);
|
|
||||||
Shell::CreateSnapshotTemplate(isolate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PerIsolateData::~PerIsolateData() {
|
PerIsolateData::~PerIsolateData() {
|
||||||
@ -1678,14 +1589,6 @@ void PerIsolateData::SetTestApiObjectCtor(Local<FunctionTemplate> ctor) {
|
|||||||
test_api_object_ctor_.Reset(isolate_, ctor);
|
test_api_object_ctor_.Reset(isolate_, ctor);
|
||||||
}
|
}
|
||||||
|
|
||||||
Local<FunctionTemplate> PerIsolateData::GetSnapshotObjectCtor() const {
|
|
||||||
return snapshot_object_ctor_.Get(isolate_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PerIsolateData::SetSnapshotObjectCtor(Local<FunctionTemplate> ctor) {
|
|
||||||
snapshot_object_ctor_.Reset(isolate_, ctor);
|
|
||||||
}
|
|
||||||
|
|
||||||
Local<FunctionTemplate> PerIsolateData::GetDomNodeCtor() const {
|
Local<FunctionTemplate> PerIsolateData::GetDomNodeCtor() const {
|
||||||
return dom_node_ctor_.Get(isolate_);
|
return dom_node_ctor_.Get(isolate_);
|
||||||
}
|
}
|
||||||
@ -2168,100 +2071,6 @@ void Shell::RealmSharedSet(Local<String> property, Local<Value> value,
|
|||||||
data->realm_shared_.Reset(isolate, value);
|
data->realm_shared_.Reset(isolate, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Realm.takeWebSnapshot(index, exports) takes a snapshot of the list of exports
|
|
||||||
// in the realm with the specified index and returns the result.
|
|
||||||
void Shell::RealmTakeWebSnapshot(
|
|
||||||
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
||||||
Isolate* isolate = args.GetIsolate();
|
|
||||||
if (args.Length() < 2 || !args[1]->IsArray()) {
|
|
||||||
isolate->ThrowError("Invalid argument");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PerIsolateData* data = PerIsolateData::Get(isolate);
|
|
||||||
int index = data->RealmIndexOrThrow(args, 0);
|
|
||||||
if (index == -1) return;
|
|
||||||
// Create a Local<PrimitiveArray> from the exports array.
|
|
||||||
Local<Context> current_context = isolate->GetCurrentContext();
|
|
||||||
Local<Array> exports_array = args[1].As<Array>();
|
|
||||||
int length = exports_array->Length();
|
|
||||||
Local<PrimitiveArray> exports = PrimitiveArray::New(isolate, length);
|
|
||||||
for (int i = 0; i < length; ++i) {
|
|
||||||
Local<Value> value;
|
|
||||||
Local<String> str;
|
|
||||||
if (!exports_array->Get(current_context, i).ToLocal(&value) ||
|
|
||||||
!value->ToString(current_context).ToLocal(&str) || str.IsEmpty()) {
|
|
||||||
isolate->ThrowError("Invalid argument");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
exports->Set(isolate, i, str);
|
|
||||||
}
|
|
||||||
// Take the snapshot in the specified Realm.
|
|
||||||
auto snapshot_data_shared = std::make_shared<i::WebSnapshotData>();
|
|
||||||
{
|
|
||||||
TryCatch try_catch(isolate);
|
|
||||||
try_catch.SetVerbose(true);
|
|
||||||
PerIsolateData::ExplicitRealmScope realm_scope(data, index);
|
|
||||||
i::WebSnapshotSerializer serializer(isolate);
|
|
||||||
if (!serializer.TakeSnapshot(realm_scope.context(), exports,
|
|
||||||
*snapshot_data_shared)) {
|
|
||||||
CHECK(try_catch.HasCaught());
|
|
||||||
args.GetReturnValue().Set(Undefined(isolate));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Create a snapshot object and store the WebSnapshotData as an embedder
|
|
||||||
// field. TODO(v8:11525): Use methods on global Snapshot objects with
|
|
||||||
// signature checks.
|
|
||||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
|
||||||
i::Handle<i::Object> snapshot_data_managed =
|
|
||||||
i::Managed<i::WebSnapshotData>::FromSharedPtr(
|
|
||||||
i_isolate, snapshot_data_shared->buffer_size, snapshot_data_shared);
|
|
||||||
v8::Local<v8::Value> shapshot_data = Utils::ToLocal(snapshot_data_managed);
|
|
||||||
Local<ObjectTemplate> snapshot_template =
|
|
||||||
data->GetSnapshotObjectCtor()->InstanceTemplate();
|
|
||||||
Local<Object> snapshot_instance =
|
|
||||||
snapshot_template->NewInstance(isolate->GetCurrentContext())
|
|
||||||
.ToLocalChecked();
|
|
||||||
snapshot_instance->SetInternalField(0, shapshot_data);
|
|
||||||
args.GetReturnValue().Set(snapshot_instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Realm.useWebSnapshot(index, snapshot) deserializes the snapshot in the realm
|
|
||||||
// with the specified index.
|
|
||||||
void Shell::RealmUseWebSnapshot(
|
|
||||||
const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|
||||||
Isolate* isolate = args.GetIsolate();
|
|
||||||
if (args.Length() < 2 || !args[1]->IsObject()) {
|
|
||||||
isolate->ThrowError("Invalid argument");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PerIsolateData* data = PerIsolateData::Get(isolate);
|
|
||||||
int index = data->RealmIndexOrThrow(args, 0);
|
|
||||||
if (index == -1) return;
|
|
||||||
// Restore the snapshot data from the snapshot object.
|
|
||||||
Local<Object> snapshot_instance = args[1].As<Object>();
|
|
||||||
Local<FunctionTemplate> snapshot_template = data->GetSnapshotObjectCtor();
|
|
||||||
if (!snapshot_template->HasInstance(snapshot_instance)) {
|
|
||||||
isolate->ThrowError("Invalid argument");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
v8::Local<v8::Value> snapshot_data = snapshot_instance->GetInternalField(0);
|
|
||||||
i::Handle<i::Object> snapshot_data_handle = Utils::OpenHandle(*snapshot_data);
|
|
||||||
auto snapshot_data_managed =
|
|
||||||
i::Handle<i::Managed<i::WebSnapshotData>>::cast(snapshot_data_handle);
|
|
||||||
std::shared_ptr<i::WebSnapshotData> snapshot_data_shared =
|
|
||||||
snapshot_data_managed->get();
|
|
||||||
// Deserialize the snapshot in the specified Realm.
|
|
||||||
{
|
|
||||||
PerIsolateData::ExplicitRealmScope realm_scope(data, index);
|
|
||||||
i::WebSnapshotDeserializer deserializer(isolate,
|
|
||||||
snapshot_data_shared->buffer,
|
|
||||||
snapshot_data_shared->buffer_size);
|
|
||||||
bool success = deserializer.Deserialize();
|
|
||||||
args.GetReturnValue().Set(success);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Shell::LogGetAndStop(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
void Shell::LogGetAndStop(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||||
Isolate* isolate = args.GetIsolate();
|
Isolate* isolate = args.GetIsolate();
|
||||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||||
@ -3569,21 +3378,9 @@ Local<ObjectTemplate> Shell::CreateRealmTemplate(Isolate* isolate) {
|
|||||||
FunctionTemplate::New(isolate, RealmEval));
|
FunctionTemplate::New(isolate, RealmEval));
|
||||||
realm_template->SetAccessor(String::NewFromUtf8Literal(isolate, "shared"),
|
realm_template->SetAccessor(String::NewFromUtf8Literal(isolate, "shared"),
|
||||||
RealmSharedGet, RealmSharedSet);
|
RealmSharedGet, RealmSharedSet);
|
||||||
if (options.d8_web_snapshot_api) {
|
|
||||||
realm_template->Set(isolate, "takeWebSnapshot",
|
|
||||||
FunctionTemplate::New(isolate, RealmTakeWebSnapshot));
|
|
||||||
realm_template->Set(isolate, "useWebSnapshot",
|
|
||||||
FunctionTemplate::New(isolate, RealmUseWebSnapshot));
|
|
||||||
}
|
|
||||||
return realm_template;
|
return realm_template;
|
||||||
}
|
}
|
||||||
|
|
||||||
Local<FunctionTemplate> Shell::CreateSnapshotTemplate(Isolate* isolate) {
|
|
||||||
Local<FunctionTemplate> snapshot_template = FunctionTemplate::New(isolate);
|
|
||||||
snapshot_template->InstanceTemplate()->SetInternalFieldCount(1);
|
|
||||||
PerIsolateData::Get(isolate)->SetSnapshotObjectCtor(snapshot_template);
|
|
||||||
return snapshot_template;
|
|
||||||
}
|
|
||||||
Local<ObjectTemplate> Shell::CreateD8Template(Isolate* isolate) {
|
Local<ObjectTemplate> Shell::CreateD8Template(Isolate* isolate) {
|
||||||
Local<ObjectTemplate> d8_template = ObjectTemplate::New(isolate);
|
Local<ObjectTemplate> d8_template = ObjectTemplate::New(isolate);
|
||||||
{
|
{
|
||||||
@ -4464,15 +4261,6 @@ bool SourceGroup::Execute(Isolate* isolate) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
continue;
|
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 (strcmp(arg, "--json") == 0 && i + 1 < end_offset_) {
|
} else if (strcmp(arg, "--json") == 0 && i + 1 < end_offset_) {
|
||||||
// Treat the next file as a JSON file.
|
// Treat the next file as a JSON file.
|
||||||
arg = argv_[++i];
|
arg = argv_[++i];
|
||||||
@ -4505,13 +4293,6 @@ bool SourceGroup::Execute(Isolate* isolate) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!success) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (Shell::options.web_snapshot_config ||
|
|
||||||
Shell::options.web_snapshot_output) {
|
|
||||||
success = Shell::TakeWebSnapshot(isolate);
|
|
||||||
}
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5067,15 +4848,6 @@ bool Shell::SetOptions(int argc, char* argv[]) {
|
|||||||
} else if (strcmp(argv[i], "--stress-deserialize") == 0) {
|
} else if (strcmp(argv[i], "--stress-deserialize") == 0) {
|
||||||
options.stress_deserialize = true;
|
options.stress_deserialize = true;
|
||||||
argv[i] = nullptr;
|
argv[i] = nullptr;
|
||||||
} else if (strncmp(argv[i], "--web-snapshot-config=", 22) == 0) {
|
|
||||||
options.web_snapshot_config = argv[i] + 22;
|
|
||||||
argv[i] = nullptr;
|
|
||||||
} else if (strncmp(argv[i], "--web-snapshot-output=", 22) == 0) {
|
|
||||||
options.web_snapshot_output = argv[i] + 22;
|
|
||||||
argv[i] = nullptr;
|
|
||||||
} else if (strcmp(argv[i], "--experimental-d8-web-snapshot-api") == 0) {
|
|
||||||
options.d8_web_snapshot_api = true;
|
|
||||||
argv[i] = nullptr;
|
|
||||||
} else if (strcmp(argv[i], "--compile-only") == 0) {
|
} else if (strcmp(argv[i], "--compile-only") == 0) {
|
||||||
options.compile_only = true;
|
options.compile_only = true;
|
||||||
argv[i] = nullptr;
|
argv[i] = nullptr;
|
||||||
@ -5154,12 +4926,11 @@ bool Shell::SetOptions(int argc, char* argv[]) {
|
|||||||
const char* usage =
|
const char* usage =
|
||||||
"Synopsis:\n"
|
"Synopsis:\n"
|
||||||
" shell [options] [--shell] [<file>...]\n"
|
" shell [options] [--shell] [<file>...]\n"
|
||||||
" d8 [options] [-e <string>] [--shell] [[--module|--web-snapshot]"
|
" d8 [options] [-e <string>] [--shell] [--module|]"
|
||||||
" <file>...]\n\n"
|
" <file>...]\n\n"
|
||||||
" -e execute a string in V8\n"
|
" -e execute a string in V8\n"
|
||||||
" --shell run an interactive JavaScript shell\n"
|
" --shell run an interactive JavaScript shell\n"
|
||||||
" --module execute a file as a JavaScript module\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;
|
using HelpOptions = i::FlagList::HelpOptions;
|
||||||
i::v8_flags.abort_on_contradictory_flags = true;
|
i::v8_flags.abort_on_contradictory_flags = true;
|
||||||
i::FlagList::SetFlagsFromCommandLine(&argc, argv, true,
|
i::FlagList::SetFlagsFromCommandLine(&argc, argv, true,
|
||||||
@ -5186,9 +4957,7 @@ bool Shell::SetOptions(int argc, char* argv[]) {
|
|||||||
current->End(i);
|
current->End(i);
|
||||||
current++;
|
current++;
|
||||||
current->Begin(argv, i + 1);
|
current->Begin(argv, i + 1);
|
||||||
} else if (strcmp(str, "--module") == 0 ||
|
} else if (strcmp(str, "--module") == 0 || strcmp(str, "--json") == 0) {
|
||||||
strcmp(str, "--web-snapshot") == 0 ||
|
|
||||||
strcmp(str, "--json") == 0) {
|
|
||||||
// Pass on to SourceGroup, which understands these options.
|
// Pass on to SourceGroup, which understands these options.
|
||||||
} else if (strncmp(str, "--", 2) == 0) {
|
} else if (strncmp(str, "--", 2) == 0) {
|
||||||
if (!i::v8_flags.correctness_fuzzer_suppressions) {
|
if (!i::v8_flags.correctness_fuzzer_suppressions) {
|
||||||
@ -5222,7 +4991,6 @@ int Shell::RunMain(Isolate* isolate, bool last_run) {
|
|||||||
}
|
}
|
||||||
HandleScope scope(isolate);
|
HandleScope scope(isolate);
|
||||||
Local<Context> context = CreateEvaluationContext(isolate);
|
Local<Context> context = CreateEvaluationContext(isolate);
|
||||||
CreateSnapshotTemplate(isolate);
|
|
||||||
bool use_existing_context = last_run && use_interactive_shell();
|
bool use_existing_context = last_run && use_interactive_shell();
|
||||||
if (use_existing_context) {
|
if (use_existing_context) {
|
||||||
// Keep using the same context in the interactive shell.
|
// Keep using the same context in the interactive shell.
|
||||||
|
20
src/d8/d8.h
20
src/d8/d8.h
@ -319,9 +319,6 @@ class PerIsolateData {
|
|||||||
Local<FunctionTemplate> GetTestApiObjectCtor() const;
|
Local<FunctionTemplate> GetTestApiObjectCtor() const;
|
||||||
void SetTestApiObjectCtor(Local<FunctionTemplate> ctor);
|
void SetTestApiObjectCtor(Local<FunctionTemplate> ctor);
|
||||||
|
|
||||||
Local<FunctionTemplate> GetSnapshotObjectCtor() const;
|
|
||||||
void SetSnapshotObjectCtor(Local<FunctionTemplate> ctor);
|
|
||||||
|
|
||||||
Local<FunctionTemplate> GetDomNodeCtor() const;
|
Local<FunctionTemplate> GetDomNodeCtor() const;
|
||||||
void SetDomNodeCtor(Local<FunctionTemplate> ctor);
|
void SetDomNodeCtor(Local<FunctionTemplate> ctor);
|
||||||
|
|
||||||
@ -344,7 +341,6 @@ class PerIsolateData {
|
|||||||
std::unordered_set<DynamicImportData*> import_data_;
|
std::unordered_set<DynamicImportData*> import_data_;
|
||||||
#endif
|
#endif
|
||||||
Global<FunctionTemplate> test_api_object_ctor_;
|
Global<FunctionTemplate> test_api_object_ctor_;
|
||||||
Global<FunctionTemplate> snapshot_object_ctor_;
|
|
||||||
Global<FunctionTemplate> dom_node_ctor_;
|
Global<FunctionTemplate> dom_node_ctor_;
|
||||||
|
|
||||||
int RealmIndexOrThrow(const v8::FunctionCallbackInfo<v8::Value>& args,
|
int RealmIndexOrThrow(const v8::FunctionCallbackInfo<v8::Value>& args,
|
||||||
@ -464,13 +460,7 @@ class ShellOptions {
|
|||||||
"enable-system-instrumentation", false};
|
"enable-system-instrumentation", false};
|
||||||
DisallowReassignment<bool> enable_etw_stack_walking = {
|
DisallowReassignment<bool> enable_etw_stack_walking = {
|
||||||
"enable-etw-stack-walking", false};
|
"enable-etw-stack-walking", false};
|
||||||
DisallowReassignment<const char*> web_snapshot_config = {
|
// Applies to JSON deserialization.
|
||||||
"web-snapshot-config", nullptr};
|
|
||||||
DisallowReassignment<const char*> web_snapshot_output = {
|
|
||||||
"web-snapshot-output", nullptr};
|
|
||||||
DisallowReassignment<bool> d8_web_snapshot_api = {
|
|
||||||
"experimental-d8-web-snapshot-api", false};
|
|
||||||
// Applies to web snapshot and JSON deserialization.
|
|
||||||
DisallowReassignment<bool> stress_deserialize = {"stress-deserialize", false};
|
DisallowReassignment<bool> stress_deserialize = {"stress-deserialize", false};
|
||||||
DisallowReassignment<bool> compile_only = {"compile-only", false};
|
DisallowReassignment<bool> compile_only = {"compile-only", false};
|
||||||
DisallowReassignment<int> repeat_compile = {"repeat-compile", 1};
|
DisallowReassignment<int> repeat_compile = {"repeat-compile", 1};
|
||||||
@ -508,8 +498,6 @@ class Shell : public i::AllStatic {
|
|||||||
ReportExceptions report_exceptions,
|
ReportExceptions report_exceptions,
|
||||||
ProcessMessageQueue process_message_queue);
|
ProcessMessageQueue process_message_queue);
|
||||||
static bool ExecuteModule(Isolate* isolate, const char* file_name);
|
static bool ExecuteModule(Isolate* isolate, const char* file_name);
|
||||||
static bool TakeWebSnapshot(Isolate* isolate);
|
|
||||||
static bool ExecuteWebSnapshot(Isolate* isolate, const char* file_name);
|
|
||||||
static bool LoadJSON(Isolate* isolate, const char* file_name);
|
static bool LoadJSON(Isolate* isolate, const char* file_name);
|
||||||
static void ReportException(Isolate* isolate, Local<Message> message,
|
static void ReportException(Isolate* isolate, Local<Message> message,
|
||||||
Local<Value> exception);
|
Local<Value> exception);
|
||||||
@ -569,10 +557,6 @@ class Shell : public i::AllStatic {
|
|||||||
const PropertyCallbackInfo<Value>& info);
|
const PropertyCallbackInfo<Value>& info);
|
||||||
static void RealmSharedSet(Local<String> property, Local<Value> value,
|
static void RealmSharedSet(Local<String> property, Local<Value> value,
|
||||||
const PropertyCallbackInfo<void>& info);
|
const PropertyCallbackInfo<void>& info);
|
||||||
static void RealmTakeWebSnapshot(
|
|
||||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
||||||
static void RealmUseWebSnapshot(
|
|
||||||
const v8::FunctionCallbackInfo<v8::Value>& args);
|
|
||||||
|
|
||||||
static void LogGetAndStop(const v8::FunctionCallbackInfo<v8::Value>& args);
|
static void LogGetAndStop(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||||
static void TestVerifySourcePositions(
|
static void TestVerifySourcePositions(
|
||||||
@ -737,8 +721,6 @@ class Shell : public i::AllStatic {
|
|||||||
|
|
||||||
static void PromiseRejectCallback(v8::PromiseRejectMessage reject_message);
|
static void PromiseRejectCallback(v8::PromiseRejectMessage reject_message);
|
||||||
|
|
||||||
static Local<FunctionTemplate> CreateSnapshotTemplate(Isolate* isolate);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static inline int DeserializationRunCount() {
|
static inline int DeserializationRunCount() {
|
||||||
return options.stress_deserialize ? 1000 : 1;
|
return options.stress_deserialize ? 1000 : 1;
|
||||||
|
@ -1898,12 +1898,6 @@ void AllocationSite::AllocationSiteVerify(Isolate* isolate) {
|
|||||||
|
|
||||||
void Script::ScriptVerify(Isolate* isolate) {
|
void Script::ScriptVerify(Isolate* isolate) {
|
||||||
TorqueGeneratedClassVerifiers::ScriptVerify(*this, isolate);
|
TorqueGeneratedClassVerifiers::ScriptVerify(*this, isolate);
|
||||||
if (V8_UNLIKELY(type() == Script::TYPE_WEB_SNAPSHOT)) {
|
|
||||||
CHECK_LE(shared_function_info_count(), shared_function_infos().length());
|
|
||||||
} else {
|
|
||||||
// No overallocating shared_function_infos.
|
|
||||||
CHECK_EQ(shared_function_info_count(), shared_function_infos().length());
|
|
||||||
}
|
|
||||||
for (int i = 0; i < shared_function_info_count(); ++i) {
|
for (int i = 0; i < shared_function_info_count(); ++i) {
|
||||||
MaybeObject maybe_object = shared_function_infos().Get(i);
|
MaybeObject maybe_object = shared_function_infos().Get(i);
|
||||||
HeapObject heap_object;
|
HeapObject heap_object;
|
||||||
|
@ -2374,9 +2374,6 @@ void Script::ScriptPrint(std::ostream& os) {
|
|||||||
os << "\n - eval from shared: " << Brief(eval_from_shared());
|
os << "\n - eval from shared: " << Brief(eval_from_shared());
|
||||||
} else if (is_wrapped()) {
|
} else if (is_wrapped()) {
|
||||||
os << "\n - wrapped arguments: " << Brief(wrapped_arguments());
|
os << "\n - wrapped arguments: " << Brief(wrapped_arguments());
|
||||||
} else if (type() == TYPE_WEB_SNAPSHOT) {
|
|
||||||
os << "\n - shared function info table: "
|
|
||||||
<< Brief(shared_function_info_table());
|
|
||||||
}
|
}
|
||||||
os << "\n - eval from position: " << eval_from_position();
|
os << "\n - eval from position: " << eval_from_position();
|
||||||
}
|
}
|
||||||
|
@ -589,7 +589,6 @@ DEFINE_BOOL(trace_block_coverage, false,
|
|||||||
"trace collected block coverage information")
|
"trace collected block coverage information")
|
||||||
DEFINE_BOOL(trace_protector_invalidation, false,
|
DEFINE_BOOL(trace_protector_invalidation, false,
|
||||||
"trace protector cell invalidations")
|
"trace protector cell invalidations")
|
||||||
DEFINE_BOOL(trace_web_snapshot, false, "trace web snapshot deserialization")
|
|
||||||
|
|
||||||
DEFINE_BOOL(feedback_normalization, false,
|
DEFINE_BOOL(feedback_normalization, false,
|
||||||
"feed back normalization to constructors")
|
"feed back normalization to constructors")
|
||||||
@ -2392,12 +2391,6 @@ DEFINE_NEG_IMPLICATION(single_threaded_gc, concurrent_array_buffer_sweeping)
|
|||||||
DEFINE_NEG_IMPLICATION(single_threaded_gc, stress_concurrent_allocation)
|
DEFINE_NEG_IMPLICATION(single_threaded_gc, stress_concurrent_allocation)
|
||||||
DEFINE_NEG_IMPLICATION(single_threaded_gc, cppheap_concurrent_marking)
|
DEFINE_NEG_IMPLICATION(single_threaded_gc, cppheap_concurrent_marking)
|
||||||
|
|
||||||
// Web snapshots: 1) expose WebSnapshot.* API 2) interpret scripts as web
|
|
||||||
// snapshots if they start with a magic number.
|
|
||||||
// TODO(v8:11525): Remove this flag once proper embedder integration is done.
|
|
||||||
DEFINE_BOOL(experimental_web_snapshots, false, "enable Web Snapshots")
|
|
||||||
DEFINE_NEG_IMPLICATION(experimental_web_snapshots, script_streaming)
|
|
||||||
|
|
||||||
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
#if defined(V8_USE_LIBM_TRIG_FUNCTIONS)
|
||||||
DEFINE_BOOL(use_libm_trig_functions, true, "use libm trig functions")
|
DEFINE_BOOL(use_libm_trig_functions, true, "use libm trig functions")
|
||||||
#endif
|
#endif
|
||||||
|
@ -280,8 +280,8 @@ Handle<Script> FactoryBase<Impl>::NewScriptWithId(
|
|||||||
raw.set_context_data(roots.undefined_value(), SKIP_WRITE_BARRIER);
|
raw.set_context_data(roots.undefined_value(), SKIP_WRITE_BARRIER);
|
||||||
raw.set_type(Script::TYPE_NORMAL);
|
raw.set_type(Script::TYPE_NORMAL);
|
||||||
raw.set_line_ends(roots.undefined_value(), SKIP_WRITE_BARRIER);
|
raw.set_line_ends(roots.undefined_value(), SKIP_WRITE_BARRIER);
|
||||||
raw.set_eval_from_shared_or_wrapped_arguments_or_sfi_table(
|
raw.set_eval_from_shared_or_wrapped_arguments(roots.undefined_value(),
|
||||||
roots.undefined_value(), SKIP_WRITE_BARRIER);
|
SKIP_WRITE_BARRIER);
|
||||||
raw.set_eval_from_position(0);
|
raw.set_eval_from_position(0);
|
||||||
raw.set_shared_function_infos(roots.empty_weak_fixed_array(),
|
raw.set_shared_function_infos(roots.empty_weak_fixed_array(),
|
||||||
SKIP_WRITE_BARRIER);
|
SKIP_WRITE_BARRIER);
|
||||||
|
@ -338,7 +338,6 @@ class FactoryBase : public TorqueGeneratedFactory<Impl> {
|
|||||||
AllocationType allocation);
|
AllocationType allocation);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class WebSnapshotDeserializer;
|
|
||||||
Impl* impl() { return static_cast<Impl*>(this); }
|
Impl* impl() { return static_cast<Impl*>(this); }
|
||||||
auto isolate() { return impl()->isolate(); }
|
auto isolate() { return impl()->isolate(); }
|
||||||
ReadOnlyRoots read_only_roots() { return impl()->read_only_roots(); }
|
ReadOnlyRoots read_only_roots() { return impl()->read_only_roots(); }
|
||||||
|
@ -1512,8 +1512,8 @@ Handle<Script> Factory::CloneScript(Handle<Script> script) {
|
|||||||
new_script.set_context_data(old_script.context_data());
|
new_script.set_context_data(old_script.context_data());
|
||||||
new_script.set_type(old_script.type());
|
new_script.set_type(old_script.type());
|
||||||
new_script.set_line_ends(*undefined_value(), SKIP_WRITE_BARRIER);
|
new_script.set_line_ends(*undefined_value(), SKIP_WRITE_BARRIER);
|
||||||
new_script.set_eval_from_shared_or_wrapped_arguments_or_sfi_table(
|
new_script.set_eval_from_shared_or_wrapped_arguments(
|
||||||
script->eval_from_shared_or_wrapped_arguments_or_sfi_table());
|
script->eval_from_shared_or_wrapped_arguments());
|
||||||
new_script.set_shared_function_infos(*empty_weak_fixed_array(),
|
new_script.set_shared_function_infos(*empty_weak_fixed_array(),
|
||||||
SKIP_WRITE_BARRIER);
|
SKIP_WRITE_BARRIER);
|
||||||
new_script.set_eval_from_position(old_script.eval_from_position());
|
new_script.set_eval_from_position(old_script.eval_from_position());
|
||||||
@ -3366,12 +3366,6 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForBuiltin(
|
|||||||
return shared;
|
return shared;
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForWebSnapshot() {
|
|
||||||
return NewSharedFunctionInfo(empty_string(), MaybeHandle<InstructionStream>(),
|
|
||||||
Builtin::kNoBuiltinId,
|
|
||||||
FunctionKind::kNormalFunction);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Factory::NumberToStringCacheHash(Smi number) {
|
int Factory::NumberToStringCacheHash(Smi number) {
|
||||||
int mask = (number_string_cache()->length() >> 1) - 1;
|
int mask = (number_string_cache()->length() >> 1) - 1;
|
||||||
return number.value() & mask;
|
return number.value() & mask;
|
||||||
|
@ -809,8 +809,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
|
|||||||
MaybeHandle<String> name, Builtin builtin,
|
MaybeHandle<String> name, Builtin builtin,
|
||||||
FunctionKind kind = FunctionKind::kNormalFunction);
|
FunctionKind kind = FunctionKind::kNormalFunction);
|
||||||
|
|
||||||
Handle<SharedFunctionInfo> NewSharedFunctionInfoForWebSnapshot();
|
|
||||||
|
|
||||||
static bool IsFunctionModeWithPrototype(FunctionMode function_mode) {
|
static bool IsFunctionModeWithPrototype(FunctionMode function_mode) {
|
||||||
return (function_mode & kWithPrototypeBits) != 0;
|
return (function_mode & kWithPrototypeBits) != 0;
|
||||||
}
|
}
|
||||||
@ -1054,7 +1052,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
friend class FactoryBase<Factory>;
|
friend class FactoryBase<Factory>;
|
||||||
friend class WebSnapshotDeserializer;
|
|
||||||
|
|
||||||
// ------
|
// ------
|
||||||
// Customization points for FactoryBase
|
// Customization points for FactoryBase
|
||||||
|
@ -246,8 +246,6 @@ class Genesis {
|
|||||||
#undef DECLARE_FEATURE_INITIALIZATION
|
#undef DECLARE_FEATURE_INITIALIZATION
|
||||||
void InitializeGlobal_regexp_linear_flag();
|
void InitializeGlobal_regexp_linear_flag();
|
||||||
|
|
||||||
void InitializeGlobal_experimental_web_snapshots();
|
|
||||||
|
|
||||||
enum ArrayBufferKind { ARRAY_BUFFER, SHARED_ARRAY_BUFFER };
|
enum ArrayBufferKind { ARRAY_BUFFER, SHARED_ARRAY_BUFFER };
|
||||||
Handle<JSFunction> CreateArrayBuffer(Handle<String> name,
|
Handle<JSFunction> CreateArrayBuffer(Handle<String> name,
|
||||||
ArrayBufferKind array_buffer_kind);
|
ArrayBufferKind array_buffer_kind);
|
||||||
@ -4150,7 +4148,6 @@ void Genesis::InitializeExperimentalGlobal() {
|
|||||||
HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
|
HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
|
||||||
#undef FEATURE_INITIALIZE_GLOBAL
|
#undef FEATURE_INITIALIZE_GLOBAL
|
||||||
InitializeGlobal_regexp_linear_flag();
|
InitializeGlobal_regexp_linear_flag();
|
||||||
InitializeGlobal_experimental_web_snapshots();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
|
bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
|
||||||
@ -5556,21 +5553,6 @@ void Genesis::InitializeGlobal_harmony_intl_number_format_v3() {
|
|||||||
|
|
||||||
#endif // V8_INTL_SUPPORT
|
#endif // V8_INTL_SUPPORT
|
||||||
|
|
||||||
void Genesis::InitializeGlobal_experimental_web_snapshots() {
|
|
||||||
if (!v8_flags.experimental_web_snapshots) return;
|
|
||||||
|
|
||||||
Handle<JSGlobalObject> global(native_context()->global_object(), isolate());
|
|
||||||
Handle<JSObject> web_snapshot_object =
|
|
||||||
factory()->NewJSObject(isolate_->object_function(), AllocationType::kOld);
|
|
||||||
JSObject::AddProperty(isolate_, global, "WebSnapshot", web_snapshot_object,
|
|
||||||
DONT_ENUM);
|
|
||||||
InstallToStringTag(isolate_, web_snapshot_object, "WebSnapshot");
|
|
||||||
SimpleInstallFunction(isolate_, web_snapshot_object, "serialize",
|
|
||||||
Builtin::kWebSnapshotSerialize, 2, false);
|
|
||||||
SimpleInstallFunction(isolate_, web_snapshot_object, "deserialize",
|
|
||||||
Builtin::kWebSnapshotDeserialize, 2, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef V8_INTL_SUPPORT
|
#ifdef V8_INTL_SUPPORT
|
||||||
void Genesis::InitializeGlobal_harmony_intl_duration_format() {
|
void Genesis::InitializeGlobal_harmony_intl_duration_format() {
|
||||||
if (!v8_flags.harmony_intl_duration_format) return;
|
if (!v8_flags.harmony_intl_duration_format) return;
|
||||||
|
@ -494,21 +494,6 @@ class RuntimeCallTimer final {
|
|||||||
V(TestCounter2) \
|
V(TestCounter2) \
|
||||||
V(TestCounter3) \
|
V(TestCounter3) \
|
||||||
V(UpdateProtector) \
|
V(UpdateProtector) \
|
||||||
V(WebSnapshotDeserialize) \
|
|
||||||
V(WebSnapshotDeserialize_Arrays) \
|
|
||||||
V(WebSnapshotDeserialize_ArrayBuffers) \
|
|
||||||
V(WebSnapshotDeserialize_BigInts) \
|
|
||||||
V(WebSnapshotDeserialize_BuiltinObjects) \
|
|
||||||
V(WebSnapshotDeserialize_Classes) \
|
|
||||||
V(WebSnapshotDeserialize_Contexts) \
|
|
||||||
V(WebSnapshotDeserialize_DataViews) \
|
|
||||||
V(WebSnapshotDeserialize_Exports) \
|
|
||||||
V(WebSnapshotDeserialize_Functions) \
|
|
||||||
V(WebSnapshotDeserialize_Maps) \
|
|
||||||
V(WebSnapshotDeserialize_Objects) \
|
|
||||||
V(WebSnapshotDeserialize_Strings) \
|
|
||||||
V(WebSnapshotDeserialize_Symbols) \
|
|
||||||
V(WebSnapshotDeserialize_TypedArrays) \
|
|
||||||
V(WrappedFunctionLengthGetter) \
|
V(WrappedFunctionLengthGetter) \
|
||||||
V(WrappedFunctionNameGetter)
|
V(WrappedFunctionNameGetter)
|
||||||
|
|
||||||
|
@ -73,9 +73,6 @@ void MutableBigInt_RightShiftAndCanonicalize(Address result_addr,
|
|||||||
class BigInt;
|
class BigInt;
|
||||||
class ValueDeserializer;
|
class ValueDeserializer;
|
||||||
class ValueSerializer;
|
class ValueSerializer;
|
||||||
class WebSnapshotSerializerDeserializer;
|
|
||||||
class WebSnapshotSerializer;
|
|
||||||
class WebSnapshotDeserializer;
|
|
||||||
|
|
||||||
#include "torque-generated/src/objects/bigint-tq.inc"
|
#include "torque-generated/src/objects/bigint-tq.inc"
|
||||||
|
|
||||||
@ -304,9 +301,6 @@ class BigInt : public BigIntBase {
|
|||||||
friend class StringToBigIntHelper;
|
friend class StringToBigIntHelper;
|
||||||
friend class ValueDeserializer;
|
friend class ValueDeserializer;
|
||||||
friend class ValueSerializer;
|
friend class ValueSerializer;
|
||||||
friend class WebSnapshotSerializerDeserializer;
|
|
||||||
friend class WebSnapshotSerializer;
|
|
||||||
friend class WebSnapshotDeserializer;
|
|
||||||
|
|
||||||
// Special functions for StringToBigIntHelper:
|
// Special functions for StringToBigIntHelper:
|
||||||
template <typename IsolateT>
|
template <typename IsolateT>
|
||||||
|
@ -233,7 +233,6 @@ class DescriptorArray
|
|||||||
using EntryValueField = TaggedField<MaybeObject, kEntryValueOffset>;
|
using EntryValueField = TaggedField<MaybeObject, kEntryValueOffset>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class WebSnapshotDeserializer;
|
|
||||||
DECL_INT16_ACCESSORS(filler16bits)
|
DECL_INT16_ACCESSORS(filler16bits)
|
||||||
|
|
||||||
inline void SetKey(InternalIndex descriptor_number, Name key);
|
inline void SetKey(InternalIndex descriptor_number, Name key);
|
||||||
|
@ -391,7 +391,6 @@ class JSTypedArray
|
|||||||
template <typename IsolateT>
|
template <typename IsolateT>
|
||||||
friend class Deserializer;
|
friend class Deserializer;
|
||||||
friend class Factory;
|
friend class Factory;
|
||||||
friend class WebSnapshotDeserializer;
|
|
||||||
|
|
||||||
DECL_PRIMITIVE_SETTER(length, size_t)
|
DECL_PRIMITIVE_SETTER(length, size_t)
|
||||||
// Reads the "length" field, doesn't assert the TypedArray is not RAB / GSAB
|
// Reads the "length" field, doesn't assert the TypedArray is not RAB / GSAB
|
||||||
|
@ -5123,11 +5123,6 @@ MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
|
|||||||
Handle<Script> script, IsolateT* isolate,
|
Handle<Script> script, IsolateT* isolate,
|
||||||
FunctionLiteral* function_literal) {
|
FunctionLiteral* function_literal) {
|
||||||
int function_literal_id = function_literal->function_literal_id();
|
int function_literal_id = function_literal->function_literal_id();
|
||||||
if (V8_UNLIKELY(script->type() == Script::TYPE_WEB_SNAPSHOT &&
|
|
||||||
function_literal_id >=
|
|
||||||
script->shared_function_info_count())) {
|
|
||||||
return FindWebSnapshotSharedFunctionInfo(script, isolate, function_literal);
|
|
||||||
}
|
|
||||||
|
|
||||||
CHECK_NE(function_literal_id, kFunctionLiteralIdInvalid);
|
CHECK_NE(function_literal_id, kFunctionLiteralIdInvalid);
|
||||||
// If this check fails, the problem is most probably the function id
|
// If this check fails, the problem is most probably the function id
|
||||||
@ -5149,77 +5144,6 @@ template MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
|
|||||||
Handle<Script> script, LocalIsolate* isolate,
|
Handle<Script> script, LocalIsolate* isolate,
|
||||||
FunctionLiteral* function_literal);
|
FunctionLiteral* function_literal);
|
||||||
|
|
||||||
MaybeHandle<SharedFunctionInfo> Script::FindWebSnapshotSharedFunctionInfo(
|
|
||||||
Handle<Script> script, Isolate* isolate,
|
|
||||||
FunctionLiteral* function_literal) {
|
|
||||||
// We might be able to de-dupe the SFI against a SFI that was
|
|
||||||
// created when deserializing the snapshot (or when calling a function which
|
|
||||||
// was included in the snapshot). In that case, we can find it based on the
|
|
||||||
// start position in shared_function_info_table.
|
|
||||||
Handle<ObjectHashTable> shared_function_info_table = handle(
|
|
||||||
ObjectHashTable::cast(script->shared_function_info_table()), isolate);
|
|
||||||
{
|
|
||||||
DisallowHeapAllocation no_gc;
|
|
||||||
Object index_object = shared_function_info_table->Lookup(
|
|
||||||
handle(Smi::FromInt(function_literal->start_position()), isolate));
|
|
||||||
if (!index_object.IsTheHole()) {
|
|
||||||
int index = Smi::cast(index_object).value();
|
|
||||||
DCHECK_LT(index, script->shared_function_info_count());
|
|
||||||
MaybeObject maybe_shared = script->shared_function_infos().Get(index);
|
|
||||||
HeapObject heap_object;
|
|
||||||
if (!maybe_shared->GetHeapObject(&heap_object)) {
|
|
||||||
// We found the correct location but it's not filled in (e.g., the weak
|
|
||||||
// pointer to the SharedFunctionInfo has been cleared). Record the
|
|
||||||
// location in the FunctionLiteral, so that it will be refilled later.
|
|
||||||
// SharedFunctionInfo::SetScript will write the SharedFunctionInfo in
|
|
||||||
// the shared_function_infos.
|
|
||||||
function_literal->set_function_literal_id(index);
|
|
||||||
return MaybeHandle<SharedFunctionInfo>();
|
|
||||||
}
|
|
||||||
SharedFunctionInfo shared = SharedFunctionInfo::cast(heap_object);
|
|
||||||
DCHECK_EQ(shared.StartPosition(), function_literal->start_position());
|
|
||||||
DCHECK_EQ(shared.EndPosition(), function_literal->end_position());
|
|
||||||
return handle(shared, isolate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// It's possible that FunctionLiterals which were processed before this one
|
|
||||||
// were deduplicated against existing ones. Decrease function_literal_id to
|
|
||||||
// avoid holes in shared_function_infos.
|
|
||||||
int old_length = script->shared_function_info_count();
|
|
||||||
int function_literal_id = old_length;
|
|
||||||
function_literal->set_function_literal_id(function_literal_id);
|
|
||||||
|
|
||||||
// Also add to shared_function_info_table.
|
|
||||||
shared_function_info_table = ObjectHashTable::Put(
|
|
||||||
shared_function_info_table,
|
|
||||||
handle(Smi::FromInt(function_literal->start_position()), isolate),
|
|
||||||
handle(Smi::FromInt(function_literal_id), isolate));
|
|
||||||
script->set_shared_function_info_table(*shared_function_info_table);
|
|
||||||
|
|
||||||
// Grow shared_function_infos if needed (we don't know the correct amount of
|
|
||||||
// space needed upfront).
|
|
||||||
int new_length = old_length + 1;
|
|
||||||
Handle<WeakFixedArray> old_infos =
|
|
||||||
handle(script->shared_function_infos(), isolate);
|
|
||||||
if (new_length > old_infos->length()) {
|
|
||||||
int capacity = WeakArrayList::CapacityForLength(new_length);
|
|
||||||
Handle<WeakFixedArray> new_infos(
|
|
||||||
isolate->factory()->NewWeakFixedArray(capacity, AllocationType::kOld));
|
|
||||||
new_infos->CopyElements(isolate, 0, *old_infos, 0, old_length,
|
|
||||||
WriteBarrierMode::UPDATE_WRITE_BARRIER);
|
|
||||||
script->set_shared_function_infos(*new_infos);
|
|
||||||
}
|
|
||||||
return MaybeHandle<SharedFunctionInfo>();
|
|
||||||
}
|
|
||||||
|
|
||||||
MaybeHandle<SharedFunctionInfo> Script::FindWebSnapshotSharedFunctionInfo(
|
|
||||||
Handle<Script> script, LocalIsolate* isolate,
|
|
||||||
FunctionLiteral* function_literal) {
|
|
||||||
// Off-thread serialization of web snapshots is not implemented.
|
|
||||||
UNREACHABLE();
|
|
||||||
}
|
|
||||||
|
|
||||||
Script::Iterator::Iterator(Isolate* isolate)
|
Script::Iterator::Iterator(Isolate* isolate)
|
||||||
: iterator_(isolate->heap()->script_list()) {}
|
: iterator_(isolate->heap()->script_list()) {}
|
||||||
|
|
||||||
|
@ -316,8 +316,6 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> {
|
|||||||
V8_EXPORT_PRIVATE uint32_t Hash();
|
V8_EXPORT_PRIVATE uint32_t Hash();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class WebSnapshotDeserializer;
|
|
||||||
|
|
||||||
int InlinedLocalNamesLookup(String name);
|
int InlinedLocalNamesLookup(String name);
|
||||||
|
|
||||||
int ContextLocalNamesIndex() const;
|
int ContextLocalNamesIndex() const;
|
||||||
|
@ -25,7 +25,7 @@ NEVER_READ_ONLY_SPACE_IMPL(Script)
|
|||||||
|
|
||||||
#if V8_ENABLE_WEBASSEMBLY
|
#if V8_ENABLE_WEBASSEMBLY
|
||||||
ACCESSORS_CHECKED(Script, wasm_breakpoint_infos, FixedArray,
|
ACCESSORS_CHECKED(Script, wasm_breakpoint_infos, FixedArray,
|
||||||
kEvalFromSharedOrWrappedArgumentsOrSfiTableOffset,
|
kEvalFromSharedOrWrappedArgumentsOffset,
|
||||||
this->type() == TYPE_WASM)
|
this->type() == TYPE_WASM)
|
||||||
ACCESSORS_CHECKED(Script, wasm_managed_native_module, Object,
|
ACCESSORS_CHECKED(Script, wasm_managed_native_module, Object,
|
||||||
kEvalFromPositionOffset, this->type() == TYPE_WASM)
|
kEvalFromPositionOffset, this->type() == TYPE_WASM)
|
||||||
@ -37,8 +37,8 @@ ACCESSORS_CHECKED(Script, wasm_weak_instance_list, WeakArrayList,
|
|||||||
#endif // V8_ENABLE_WEBASSEMBLY
|
#endif // V8_ENABLE_WEBASSEMBLY
|
||||||
|
|
||||||
SMI_ACCESSORS(Script, type, kScriptTypeOffset)
|
SMI_ACCESSORS(Script, type, kScriptTypeOffset)
|
||||||
ACCESSORS_CHECKED(Script, eval_from_shared_or_wrapped_arguments_or_sfi_table,
|
ACCESSORS_CHECKED(Script, eval_from_shared_or_wrapped_arguments, Object,
|
||||||
Object, kEvalFromSharedOrWrappedArgumentsOrSfiTableOffset,
|
kEvalFromSharedOrWrappedArgumentsOffset,
|
||||||
CHECK_SCRIPT_NOT_WASM)
|
CHECK_SCRIPT_NOT_WASM)
|
||||||
SMI_ACCESSORS_CHECKED(Script, eval_from_position, kEvalFromPositionOffset,
|
SMI_ACCESSORS_CHECKED(Script, eval_from_position, kEvalFromPositionOffset,
|
||||||
CHECK_SCRIPT_NOT_WASM)
|
CHECK_SCRIPT_NOT_WASM)
|
||||||
@ -48,51 +48,32 @@ ACCESSORS(Script, compiled_lazy_function_positions, Object,
|
|||||||
kCompiledLazyFunctionPositionsOffset)
|
kCompiledLazyFunctionPositionsOffset)
|
||||||
|
|
||||||
bool Script::is_wrapped() const {
|
bool Script::is_wrapped() const {
|
||||||
return eval_from_shared_or_wrapped_arguments_or_sfi_table().IsFixedArray() &&
|
return eval_from_shared_or_wrapped_arguments().IsFixedArray();
|
||||||
type() != TYPE_WEB_SNAPSHOT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Script::has_eval_from_shared() const {
|
bool Script::has_eval_from_shared() const {
|
||||||
return eval_from_shared_or_wrapped_arguments_or_sfi_table()
|
return eval_from_shared_or_wrapped_arguments().IsSharedFunctionInfo();
|
||||||
.IsSharedFunctionInfo();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::set_eval_from_shared(SharedFunctionInfo shared,
|
void Script::set_eval_from_shared(SharedFunctionInfo shared,
|
||||||
WriteBarrierMode mode) {
|
WriteBarrierMode mode) {
|
||||||
DCHECK(!is_wrapped());
|
DCHECK(!is_wrapped());
|
||||||
DCHECK_NE(type(), TYPE_WEB_SNAPSHOT);
|
set_eval_from_shared_or_wrapped_arguments(shared, mode);
|
||||||
set_eval_from_shared_or_wrapped_arguments_or_sfi_table(shared, mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedFunctionInfo Script::eval_from_shared() const {
|
SharedFunctionInfo Script::eval_from_shared() const {
|
||||||
DCHECK(has_eval_from_shared());
|
DCHECK(has_eval_from_shared());
|
||||||
return SharedFunctionInfo::cast(
|
return SharedFunctionInfo::cast(eval_from_shared_or_wrapped_arguments());
|
||||||
eval_from_shared_or_wrapped_arguments_or_sfi_table());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Script::set_wrapped_arguments(FixedArray value, WriteBarrierMode mode) {
|
void Script::set_wrapped_arguments(FixedArray value, WriteBarrierMode mode) {
|
||||||
DCHECK(!has_eval_from_shared());
|
DCHECK(!has_eval_from_shared());
|
||||||
DCHECK_NE(type(), TYPE_WEB_SNAPSHOT);
|
set_eval_from_shared_or_wrapped_arguments(value, mode);
|
||||||
set_eval_from_shared_or_wrapped_arguments_or_sfi_table(value, mode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedArray Script::wrapped_arguments() const {
|
FixedArray Script::wrapped_arguments() const {
|
||||||
DCHECK(is_wrapped());
|
DCHECK(is_wrapped());
|
||||||
return FixedArray::cast(eval_from_shared_or_wrapped_arguments_or_sfi_table());
|
return FixedArray::cast(eval_from_shared_or_wrapped_arguments());
|
||||||
}
|
|
||||||
|
|
||||||
void Script::set_shared_function_info_table(ObjectHashTable value,
|
|
||||||
WriteBarrierMode mode) {
|
|
||||||
DCHECK(!has_eval_from_shared());
|
|
||||||
DCHECK(!is_wrapped());
|
|
||||||
DCHECK_EQ(type(), TYPE_WEB_SNAPSHOT);
|
|
||||||
set_eval_from_shared_or_wrapped_arguments_or_sfi_table(value, mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectHashTable Script::shared_function_info_table() const {
|
|
||||||
DCHECK_EQ(type(), TYPE_WEB_SNAPSHOT);
|
|
||||||
return ObjectHashTable::cast(
|
|
||||||
eval_from_shared_or_wrapped_arguments_or_sfi_table());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEF_GETTER(Script, shared_function_infos, WeakFixedArray) {
|
DEF_GETTER(Script, shared_function_infos, WeakFixedArray) {
|
||||||
@ -114,11 +95,6 @@ void Script::set_shared_function_infos(WeakFixedArray value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Script::shared_function_info_count() const {
|
int Script::shared_function_info_count() const {
|
||||||
if (V8_UNLIKELY(type() == TYPE_WEB_SNAPSHOT)) {
|
|
||||||
// +1 because the 0th element in shared_function_infos is reserved for the
|
|
||||||
// top-level SharedFunctionInfo which doesn't exist.
|
|
||||||
return shared_function_info_table().NumberOfElements() + 1;
|
|
||||||
}
|
|
||||||
return shared_function_infos().length();
|
return shared_function_infos().length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +46,7 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
|
|||||||
#if V8_ENABLE_WEBASSEMBLY
|
#if V8_ENABLE_WEBASSEMBLY
|
||||||
TYPE_WASM = 3,
|
TYPE_WASM = 3,
|
||||||
#endif // V8_ENABLE_WEBASSEMBLY
|
#endif // V8_ENABLE_WEBASSEMBLY
|
||||||
TYPE_INSPECTOR = 4,
|
TYPE_INSPECTOR = 4
|
||||||
TYPE_WEB_SNAPSHOT = 5
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Script compilation types.
|
// Script compilation types.
|
||||||
@ -62,7 +61,7 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
|
|||||||
// [type]: the script type.
|
// [type]: the script type.
|
||||||
DECL_INT_ACCESSORS(type)
|
DECL_INT_ACCESSORS(type)
|
||||||
|
|
||||||
DECL_ACCESSORS(eval_from_shared_or_wrapped_arguments_or_sfi_table, Object)
|
DECL_ACCESSORS(eval_from_shared_or_wrapped_arguments, Object)
|
||||||
|
|
||||||
// [eval_from_shared]: for eval scripts the shared function info for the
|
// [eval_from_shared]: for eval scripts the shared function info for the
|
||||||
// function from which eval was called.
|
// function from which eval was called.
|
||||||
@ -71,12 +70,6 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
|
|||||||
// [wrapped_arguments]: for the list of arguments in a wrapped script.
|
// [wrapped_arguments]: for the list of arguments in a wrapped script.
|
||||||
DECL_ACCESSORS(wrapped_arguments, FixedArray)
|
DECL_ACCESSORS(wrapped_arguments, FixedArray)
|
||||||
|
|
||||||
// For web snapshots: a hash table mapping function positions to indices in
|
|
||||||
// shared_function_infos.
|
|
||||||
// TODO(v8:11525): Replace with a more efficient data structure mapping
|
|
||||||
// function positions to weak pointers to SharedFunctionInfos directly.
|
|
||||||
DECL_ACCESSORS(shared_function_info_table, ObjectHashTable)
|
|
||||||
|
|
||||||
// Whether the script is implicitly wrapped in a function.
|
// Whether the script is implicitly wrapped in a function.
|
||||||
inline bool is_wrapped() const;
|
inline bool is_wrapped() const;
|
||||||
|
|
||||||
@ -221,14 +214,6 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
|
|||||||
Handle<Script> script, IsolateT* isolate,
|
Handle<Script> script, IsolateT* isolate,
|
||||||
FunctionLiteral* function_literal);
|
FunctionLiteral* function_literal);
|
||||||
|
|
||||||
static MaybeHandle<SharedFunctionInfo> FindWebSnapshotSharedFunctionInfo(
|
|
||||||
Handle<Script> script, Isolate* isolate,
|
|
||||||
FunctionLiteral* function_literal);
|
|
||||||
|
|
||||||
static MaybeHandle<SharedFunctionInfo> FindWebSnapshotSharedFunctionInfo(
|
|
||||||
Handle<Script> script, LocalIsolate* isolate,
|
|
||||||
FunctionLiteral* function_literal);
|
|
||||||
|
|
||||||
// Iterate over all script objects on the heap.
|
// Iterate over all script objects on the heap.
|
||||||
class V8_EXPORT_PRIVATE Iterator {
|
class V8_EXPORT_PRIVATE Iterator {
|
||||||
public:
|
public:
|
||||||
|
@ -42,10 +42,9 @@ extern class Script extends Struct {
|
|||||||
|
|
||||||
// For scripts originating from eval: the SharedFunctionInfo contains the SFI
|
// For scripts originating from eval: the SharedFunctionInfo contains the SFI
|
||||||
// for the script. For scripts wrapped as functions: the FixedArray contains
|
// for the script. For scripts wrapped as functions: the FixedArray contains
|
||||||
// the arguments. For web snapshots: the ObjectHashTable maps function start
|
// the arguments.
|
||||||
// position to SFI index in shared_function_infos.
|
eval_from_shared_or_wrapped_arguments: SharedFunctionInfo|FixedArray|
|
||||||
eval_from_shared_or_wrapped_arguments_or_sfi_table: SharedFunctionInfo|
|
Undefined;
|
||||||
FixedArray|ObjectHashTable|Undefined;
|
|
||||||
eval_from_position: Smi|Foreign; // Smi or Managed<wasm::NativeModule>
|
eval_from_position: Smi|Foreign; // Smi or Managed<wasm::NativeModule>
|
||||||
shared_function_infos: WeakFixedArray|WeakArrayList;
|
shared_function_infos: WeakFixedArray|WeakArrayList;
|
||||||
|
|
||||||
|
@ -689,8 +689,6 @@ class SharedFunctionInfo
|
|||||||
Isolate* isolate);
|
Isolate* isolate);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class WebSnapshotDeserializer;
|
|
||||||
|
|
||||||
#ifdef VERIFY_HEAP
|
#ifdef VERIFY_HEAP
|
||||||
void SharedFunctionInfoVerify(ReadOnlyRoots roots);
|
void SharedFunctionInfoVerify(ReadOnlyRoots roots);
|
||||||
#endif
|
#endif
|
||||||
|
@ -98,8 +98,6 @@ class ValueSerializer {
|
|||||||
void SetTreatArrayBufferViewsAsHostObjects(bool mode);
|
void SetTreatArrayBufferViewsAsHostObjects(bool mode);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class WebSnapshotSerializer;
|
|
||||||
|
|
||||||
// Managing allocations of the internal buffer.
|
// Managing allocations of the internal buffer.
|
||||||
Maybe<bool> ExpandBuffer(size_t required_capacity);
|
Maybe<bool> ExpandBuffer(size_t required_capacity);
|
||||||
|
|
||||||
@ -249,8 +247,6 @@ class ValueDeserializer {
|
|||||||
bool ReadByte(uint8_t* value) V8_WARN_UNUSED_RESULT;
|
bool ReadByte(uint8_t* value) V8_WARN_UNUSED_RESULT;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class WebSnapshotDeserializer;
|
|
||||||
|
|
||||||
// Reading the wire format.
|
// Reading the wire format.
|
||||||
Maybe<SerializationTag> PeekTag() const V8_WARN_UNUSED_RESULT;
|
Maybe<SerializationTag> PeekTag() const V8_WARN_UNUSED_RESULT;
|
||||||
void ConsumeTag(SerializationTag peeked_tag);
|
void ConsumeTag(SerializationTag peeked_tag);
|
||||||
|
@ -889,15 +889,6 @@ void Parser::ParseFunction(Isolate* isolate, ParseInfo* info,
|
|||||||
}
|
}
|
||||||
|
|
||||||
int function_literal_id = shared_info->function_literal_id();
|
int function_literal_id = shared_info->function_literal_id();
|
||||||
if (V8_UNLIKELY(script->type() == Script::TYPE_WEB_SNAPSHOT)) {
|
|
||||||
// Function literal IDs for inner functions haven't been allocated when
|
|
||||||
// deserializing. Put the inner function SFIs to the end of the list;
|
|
||||||
// they'll be deduplicated later (if the corresponding SFIs exist already)
|
|
||||||
// in Script::FindSharedFunctionInfo. (-1 here because function_literal_id
|
|
||||||
// is the parent's id. The inner function will get ids starting from
|
|
||||||
// function_literal_id + 1.)
|
|
||||||
function_literal_id = script->shared_function_info_count() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize parser state.
|
// Initialize parser state.
|
||||||
info->set_function_name(ast_value_factory()->GetString(
|
info->set_function_name(ast_value_factory()->GetString(
|
||||||
|
@ -36,7 +36,6 @@
|
|||||||
#include "src/profiler/heap-snapshot-generator.h"
|
#include "src/profiler/heap-snapshot-generator.h"
|
||||||
#include "src/regexp/regexp.h"
|
#include "src/regexp/regexp.h"
|
||||||
#include "src/snapshot/snapshot.h"
|
#include "src/snapshot/snapshot.h"
|
||||||
#include "src/web-snapshot/web-snapshot.h"
|
|
||||||
|
|
||||||
#ifdef V8_ENABLE_MAGLEV
|
#ifdef V8_ENABLE_MAGLEV
|
||||||
#include "src/maglev/maglev.h"
|
#include "src/maglev/maglev.h"
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,669 +0,0 @@
|
|||||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
#ifndef V8_WEB_SNAPSHOT_WEB_SNAPSHOT_H_
|
|
||||||
#define V8_WEB_SNAPSHOT_WEB_SNAPSHOT_H_
|
|
||||||
|
|
||||||
#include <queue>
|
|
||||||
|
|
||||||
#include "src/handles/handles.h"
|
|
||||||
#include "src/objects/bigint.h"
|
|
||||||
#include "src/objects/value-serializer.h"
|
|
||||||
#include "src/snapshot/serializer.h" // For ObjectCacheIndexMap
|
|
||||||
|
|
||||||
namespace v8 {
|
|
||||||
|
|
||||||
class Context;
|
|
||||||
class Isolate;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class Local;
|
|
||||||
|
|
||||||
namespace internal {
|
|
||||||
|
|
||||||
class Context;
|
|
||||||
class Map;
|
|
||||||
class Object;
|
|
||||||
class String;
|
|
||||||
|
|
||||||
struct WebSnapshotData : public std::enable_shared_from_this<WebSnapshotData> {
|
|
||||||
uint8_t* buffer = nullptr;
|
|
||||||
size_t buffer_size = 0;
|
|
||||||
WebSnapshotData() = default;
|
|
||||||
WebSnapshotData(const WebSnapshotData&) = delete;
|
|
||||||
WebSnapshotData& operator=(const WebSnapshotData&) = delete;
|
|
||||||
~WebSnapshotData() { free(buffer); }
|
|
||||||
};
|
|
||||||
|
|
||||||
class WebSnapshotSerializerDeserializer {
|
|
||||||
public:
|
|
||||||
inline bool has_error() const { return error_message_ != nullptr; }
|
|
||||||
const char* error_message() const { return error_message_; }
|
|
||||||
|
|
||||||
enum ValueType : uint8_t {
|
|
||||||
FALSE_CONSTANT,
|
|
||||||
TRUE_CONSTANT,
|
|
||||||
NULL_CONSTANT,
|
|
||||||
UNDEFINED_CONSTANT,
|
|
||||||
// It corresponds to the hole value.
|
|
||||||
NO_ELEMENT_CONSTANT,
|
|
||||||
INTEGER,
|
|
||||||
DOUBLE,
|
|
||||||
REGEXP,
|
|
||||||
STRING_ID,
|
|
||||||
ARRAY_ID,
|
|
||||||
OBJECT_ID,
|
|
||||||
FUNCTION_ID,
|
|
||||||
CLASS_ID,
|
|
||||||
SYMBOL_ID,
|
|
||||||
EXTERNAL_ID,
|
|
||||||
BUILTIN_OBJECT_ID,
|
|
||||||
IN_PLACE_STRING_ID,
|
|
||||||
ARRAY_BUFFER_ID,
|
|
||||||
TYPED_ARRAY_ID,
|
|
||||||
DATA_VIEW_ID,
|
|
||||||
BIGINT_ID
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SymbolType : uint8_t {
|
|
||||||
kNonGlobalNoDesription = 0,
|
|
||||||
kNonGlobal = 1,
|
|
||||||
kGlobal = 2
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ElementsType : uint8_t { kDense = 0, kSparse = 1 };
|
|
||||||
|
|
||||||
enum TypedArrayType : uint8_t {
|
|
||||||
kInt8Array,
|
|
||||||
kUint8Array,
|
|
||||||
kUint8ClampedArray,
|
|
||||||
kInt16Array,
|
|
||||||
kUint16Array,
|
|
||||||
kInt32Array,
|
|
||||||
kUint32Array,
|
|
||||||
kFloat32Array,
|
|
||||||
kFloat64Array,
|
|
||||||
kBigInt64Array,
|
|
||||||
kBigUint64Array,
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline ExternalArrayType TypedArrayTypeToExternalArrayType(
|
|
||||||
TypedArrayType type);
|
|
||||||
static inline TypedArrayType ExternalArrayTypeToTypedArrayType(
|
|
||||||
ExternalArrayType type);
|
|
||||||
|
|
||||||
static constexpr uint8_t kMagicNumber[4] = {'+', '+', '+', ';'};
|
|
||||||
|
|
||||||
enum ContextType : uint8_t { FUNCTION, BLOCK };
|
|
||||||
|
|
||||||
enum PropertyAttributesType : uint8_t { DEFAULT, CUSTOM };
|
|
||||||
|
|
||||||
uint8_t FunctionKindToFunctionFlags(FunctionKind kind);
|
|
||||||
FunctionKind FunctionFlagsToFunctionKind(uint8_t flags);
|
|
||||||
bool IsFunctionOrMethod(uint8_t flags);
|
|
||||||
bool IsConstructor(uint8_t flags);
|
|
||||||
|
|
||||||
uint8_t GetDefaultAttributeFlags();
|
|
||||||
uint8_t AttributesToFlags(PropertyDetails details);
|
|
||||||
PropertyAttributes FlagsToAttributes(uint8_t flags);
|
|
||||||
|
|
||||||
uint8_t ArrayBufferViewKindToFlags(
|
|
||||||
Handle<JSArrayBufferView> array_buffer_view);
|
|
||||||
|
|
||||||
uint8_t ArrayBufferKindToFlags(Handle<JSArrayBuffer> array_buffer);
|
|
||||||
|
|
||||||
uint32_t BigIntSignAndLengthToFlags(Handle<BigInt> bigint);
|
|
||||||
uint32_t BigIntFlagsToBitField(uint32_t flags);
|
|
||||||
// The maximum count of items for each value type (strings, objects etc.)
|
|
||||||
static constexpr uint32_t kMaxItemCount =
|
|
||||||
static_cast<uint32_t>(FixedArray::kMaxLength - 1);
|
|
||||||
// This ensures indices and lengths can be converted between uint32_t and int
|
|
||||||
// without problems:
|
|
||||||
static_assert(kMaxItemCount <
|
|
||||||
static_cast<uint32_t>(std::numeric_limits<int32_t>::max()));
|
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit WebSnapshotSerializerDeserializer(Isolate* isolate)
|
|
||||||
: isolate_(isolate) {}
|
|
||||||
// Not virtual, on purpose (because it doesn't need to be).
|
|
||||||
void Throw(const char* message);
|
|
||||||
|
|
||||||
void IterateBuiltinObjects(
|
|
||||||
std::function<void(Handle<String>, Handle<HeapObject>)> func);
|
|
||||||
|
|
||||||
static constexpr int kBuiltinObjectCount = 12;
|
|
||||||
|
|
||||||
inline Factory* factory() const { return isolate_->factory(); }
|
|
||||||
|
|
||||||
Isolate* isolate_;
|
|
||||||
const char* error_message_ = nullptr;
|
|
||||||
|
|
||||||
// Encode JSArrayBufferFlags, including was_detached, is_shared, is_resizable.
|
|
||||||
// DetachedBitField indicates whether the ArrayBuffer was detached.
|
|
||||||
using DetachedBitField = base::BitField<bool, 0, 1, uint8_t>;
|
|
||||||
// SharedBitField indicates whether the ArrayBuffer is SharedArrayBuffer.
|
|
||||||
using SharedBitField = DetachedBitField::Next<bool, 1>;
|
|
||||||
// ResizableBitField indicates whether the ArrayBuffer is ResizableArrayBuffer
|
|
||||||
// or GrowableSharedArrayBuffer.
|
|
||||||
using ResizableBitField = SharedBitField::Next<bool, 1>;
|
|
||||||
|
|
||||||
// Encode JSArrayBufferViewFlags, including is_length_tracking, see
|
|
||||||
// https://github.com/tc39/proposal-resizablearraybuffer.
|
|
||||||
// LengthTrackingBitField indicates whether the ArrayBufferView should track
|
|
||||||
// the length of the backing buffer, that is whether the ArrayBufferView is
|
|
||||||
// constructed without the specified length argument.
|
|
||||||
using LengthTrackingBitField = base::BitField<bool, 0, 1, uint8_t>;
|
|
||||||
|
|
||||||
// Encode BigInt's sign and digits length.
|
|
||||||
using BigIntSignBitField = base::BitField<bool, 0, 1>;
|
|
||||||
using BigIntLengthBitField =
|
|
||||||
BigIntSignBitField::Next<int, BigInt::kLengthFieldBits>;
|
|
||||||
static_assert(BigIntLengthBitField::kSize == BigInt::LengthBits::kSize);
|
|
||||||
|
|
||||||
private:
|
|
||||||
WebSnapshotSerializerDeserializer(const WebSnapshotSerializerDeserializer&) =
|
|
||||||
delete;
|
|
||||||
WebSnapshotSerializerDeserializer& operator=(
|
|
||||||
const WebSnapshotSerializerDeserializer&) = delete;
|
|
||||||
|
|
||||||
using AsyncFunctionBitField = base::BitField<bool, 0, 1, uint8_t>;
|
|
||||||
using GeneratorFunctionBitField = AsyncFunctionBitField::Next<bool, 1>;
|
|
||||||
using ArrowFunctionBitField = GeneratorFunctionBitField::Next<bool, 1>;
|
|
||||||
using MethodBitField = ArrowFunctionBitField::Next<bool, 1>;
|
|
||||||
using StaticBitField = MethodBitField::Next<bool, 1>;
|
|
||||||
using ClassConstructorBitField = StaticBitField::Next<bool, 1>;
|
|
||||||
using DefaultConstructorBitField = ClassConstructorBitField::Next<bool, 1>;
|
|
||||||
using DerivedConstructorBitField = DefaultConstructorBitField::Next<bool, 1>;
|
|
||||||
|
|
||||||
using ReadOnlyBitField = base::BitField<bool, 0, 1, uint8_t>;
|
|
||||||
using ConfigurableBitField = ReadOnlyBitField::Next<bool, 1>;
|
|
||||||
using EnumerableBitField = ConfigurableBitField::Next<bool, 1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
class V8_EXPORT WebSnapshotSerializer
|
|
||||||
: public WebSnapshotSerializerDeserializer {
|
|
||||||
public:
|
|
||||||
explicit WebSnapshotSerializer(v8::Isolate* isolate);
|
|
||||||
explicit WebSnapshotSerializer(Isolate* isolate);
|
|
||||||
|
|
||||||
~WebSnapshotSerializer();
|
|
||||||
|
|
||||||
bool TakeSnapshot(v8::Local<v8::Context> context,
|
|
||||||
v8::Local<v8::PrimitiveArray> exports,
|
|
||||||
WebSnapshotData& data_out);
|
|
||||||
bool TakeSnapshot(Handle<Object> object, MaybeHandle<FixedArray> block_list,
|
|
||||||
WebSnapshotData& data_out);
|
|
||||||
|
|
||||||
// For inspecting the state after taking a snapshot.
|
|
||||||
uint32_t string_count() const {
|
|
||||||
return static_cast<uint32_t>(string_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t symbol_count() const {
|
|
||||||
return static_cast<uint32_t>(symbol_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t bigint_count() const {
|
|
||||||
return static_cast<uint32_t>(bigint_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t map_count() const { return static_cast<uint32_t>(map_ids_.size()); }
|
|
||||||
|
|
||||||
uint32_t builtin_object_count() const {
|
|
||||||
return static_cast<uint32_t>(builtin_object_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t context_count() const {
|
|
||||||
return static_cast<uint32_t>(context_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t function_count() const {
|
|
||||||
return static_cast<uint32_t>(function_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t class_count() const {
|
|
||||||
return static_cast<uint32_t>(class_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t array_count() const {
|
|
||||||
return static_cast<uint32_t>(array_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t array_buffer_count() const {
|
|
||||||
return static_cast<uint32_t>(array_buffer_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t typed_array_count() const {
|
|
||||||
return static_cast<uint32_t>(typed_array_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t data_view_count() const {
|
|
||||||
return static_cast<uint32_t>(data_view_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t object_count() const {
|
|
||||||
return static_cast<uint32_t>(object_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t external_object_count() const {
|
|
||||||
return static_cast<uint32_t>(external_object_ids_.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle<FixedArray> GetExternals();
|
|
||||||
|
|
||||||
private:
|
|
||||||
WebSnapshotSerializer(const WebSnapshotSerializer&) = delete;
|
|
||||||
WebSnapshotSerializer& operator=(const WebSnapshotSerializer&) = delete;
|
|
||||||
|
|
||||||
enum class AllowInPlace {
|
|
||||||
No, // This reference cannot be replace with an in-place item.
|
|
||||||
Yes, // This reference can be replaced with an in-place item.
|
|
||||||
};
|
|
||||||
|
|
||||||
void SerializePendingItems();
|
|
||||||
void WriteSnapshot(uint8_t*& buffer, size_t& buffer_size);
|
|
||||||
void WriteObjects(ValueSerializer& destination, size_t count,
|
|
||||||
ValueSerializer& source, const char* name);
|
|
||||||
|
|
||||||
// Returns true if the object was already in the map, false if it was added.
|
|
||||||
bool InsertIntoIndexMap(ObjectCacheIndexMap& map, HeapObject heap_object,
|
|
||||||
uint32_t& id);
|
|
||||||
|
|
||||||
void ShallowDiscoverExternals(FixedArray externals);
|
|
||||||
void ShallowDiscoverBuiltinObjects(v8::Local<v8::Context> context);
|
|
||||||
void Discover(Handle<HeapObject> object);
|
|
||||||
void DiscoverString(Handle<String> string,
|
|
||||||
AllowInPlace can_be_in_place = AllowInPlace::No);
|
|
||||||
void DiscoverSymbol(Handle<Symbol> symbol);
|
|
||||||
void DiscoverBigInt(Handle<BigInt> bigint);
|
|
||||||
void DiscoverMap(Handle<Map> map, bool allow_property_in_descriptor = false);
|
|
||||||
void DiscoverPropertyKey(Handle<Name> key);
|
|
||||||
void DiscoverMapForFunction(Handle<JSFunction> function);
|
|
||||||
void DiscoverFunction(Handle<JSFunction> function);
|
|
||||||
void DiscoverClass(Handle<JSFunction> function);
|
|
||||||
void DiscoverContextAndPrototype(Handle<JSFunction> function);
|
|
||||||
void DiscoverContext(Handle<Context> context);
|
|
||||||
void DiscoverArray(Handle<JSArray> array);
|
|
||||||
void DiscoverTypedArray(Handle<JSTypedArray> typed_array);
|
|
||||||
void DiscoverDataView(Handle<JSDataView> data_view);
|
|
||||||
void DiscoverArrayBuffer(Handle<JSArrayBuffer> array_buffer);
|
|
||||||
void DiscoverElements(Handle<JSObject> object);
|
|
||||||
void DiscoverObject(Handle<JSObject> object);
|
|
||||||
bool DiscoverIfBuiltinObject(Handle<HeapObject> object);
|
|
||||||
void DiscoverSource(Handle<JSFunction> function);
|
|
||||||
template <typename T>
|
|
||||||
void DiscoverObjectPropertiesWithDictionaryMap(T dict);
|
|
||||||
bool ShouldBeSerialized(Handle<Name> key);
|
|
||||||
void ConstructSource();
|
|
||||||
|
|
||||||
void SerializeFunctionInfo(Handle<JSFunction> function,
|
|
||||||
ValueSerializer& serializer);
|
|
||||||
void SerializeFunctionProperties(Handle<JSFunction> function,
|
|
||||||
ValueSerializer& serializer);
|
|
||||||
void SerializeString(Handle<String> string, ValueSerializer& serializer);
|
|
||||||
void SerializeSymbol(Handle<Symbol> symbol);
|
|
||||||
void SerializeBigInt(Handle<BigInt> bigint);
|
|
||||||
void SerializeMap(Handle<Map> map);
|
|
||||||
void SerializeBuiltinObject(uint32_t name_id);
|
|
||||||
void SerializeObjectPrototype(Handle<Map> map, ValueSerializer& serializer);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void SerializeObjectPropertiesWithDictionaryMap(T dict);
|
|
||||||
void SerializeFunction(Handle<JSFunction> function);
|
|
||||||
void SerializeClass(Handle<JSFunction> function);
|
|
||||||
void SerializeContext(Handle<Context> context, uint32_t id);
|
|
||||||
void SerializeArray(Handle<JSArray> array);
|
|
||||||
void SerializeElements(Handle<JSObject> object, ValueSerializer& serializer,
|
|
||||||
Maybe<uint32_t> length);
|
|
||||||
void SerializeObject(Handle<JSObject> object);
|
|
||||||
void SerializeArrayBufferView(Handle<JSArrayBufferView> array_buffer_view,
|
|
||||||
ValueSerializer& serializer);
|
|
||||||
void SerializeArrayBuffer(Handle<JSArrayBuffer> array_buffer);
|
|
||||||
void SerializeTypedArray(Handle<JSTypedArray> typed_array);
|
|
||||||
void SerializeDataView(Handle<JSDataView> data_view);
|
|
||||||
|
|
||||||
void SerializeExport(Handle<Object> object, Handle<String> export_name);
|
|
||||||
void WriteValue(Handle<Object> object, ValueSerializer& serializer);
|
|
||||||
void WriteStringMaybeInPlace(Handle<String> string,
|
|
||||||
ValueSerializer& serializer);
|
|
||||||
void WriteStringId(Handle<String> string, ValueSerializer& serializer);
|
|
||||||
|
|
||||||
uint32_t GetStringId(Handle<String> string, bool& in_place);
|
|
||||||
uint32_t GetSymbolId(Symbol symbol);
|
|
||||||
uint32_t GetBigIntId(BigInt bigint);
|
|
||||||
uint32_t GetMapId(Map map);
|
|
||||||
uint32_t GetFunctionId(JSFunction function);
|
|
||||||
uint32_t GetClassId(JSFunction function);
|
|
||||||
uint32_t GetContextId(Context context);
|
|
||||||
uint32_t GetArrayId(JSArray array);
|
|
||||||
uint32_t GetTypedArrayId(JSTypedArray typed_array);
|
|
||||||
uint32_t GetDataViewId(JSDataView data_view);
|
|
||||||
uint32_t GetArrayBufferId(JSArrayBuffer array_buffer);
|
|
||||||
uint32_t GetObjectId(JSObject object);
|
|
||||||
bool GetExternalId(HeapObject object, uint32_t* id = nullptr);
|
|
||||||
// Returns index into builtin_object_name_strings_.
|
|
||||||
bool GetBuiltinObjectNameIndex(HeapObject object, uint32_t& index);
|
|
||||||
bool GetBuiltinObjectId(HeapObject object, uint32_t& id);
|
|
||||||
|
|
||||||
ValueSerializer string_serializer_;
|
|
||||||
ValueSerializer symbol_serializer_;
|
|
||||||
ValueSerializer bigint_serializer_;
|
|
||||||
ValueSerializer map_serializer_;
|
|
||||||
ValueSerializer builtin_object_serializer_;
|
|
||||||
ValueSerializer context_serializer_;
|
|
||||||
ValueSerializer function_serializer_;
|
|
||||||
ValueSerializer class_serializer_;
|
|
||||||
ValueSerializer array_serializer_;
|
|
||||||
ValueSerializer typed_array_serializer_;
|
|
||||||
ValueSerializer array_buffer_serializer_;
|
|
||||||
ValueSerializer data_view_serializer_;
|
|
||||||
ValueSerializer object_serializer_;
|
|
||||||
ValueSerializer export_serializer_;
|
|
||||||
|
|
||||||
// These are needed for being able to serialize items in order.
|
|
||||||
Handle<ArrayList> strings_;
|
|
||||||
Handle<ArrayList> symbols_;
|
|
||||||
Handle<ArrayList> bigints_;
|
|
||||||
Handle<ArrayList> maps_;
|
|
||||||
Handle<ArrayList> contexts_;
|
|
||||||
Handle<ArrayList> functions_;
|
|
||||||
Handle<ArrayList> classes_;
|
|
||||||
Handle<ArrayList> arrays_;
|
|
||||||
Handle<ArrayList> typed_arrays_;
|
|
||||||
Handle<ArrayList> array_buffers_;
|
|
||||||
Handle<ArrayList> data_views_;
|
|
||||||
Handle<ArrayList> objects_;
|
|
||||||
|
|
||||||
// IndexMap to keep track of explicitly blocked external objects and
|
|
||||||
// non-serializable/not-supported objects (e.g. API Objects).
|
|
||||||
ObjectCacheIndexMap external_object_ids_;
|
|
||||||
|
|
||||||
// ObjectCacheIndexMap implements fast lookup item -> id. Some items (context,
|
|
||||||
// function, class, array, object) can point to other items and we serialize
|
|
||||||
// them in the reverse order. This ensures that the items this item points to
|
|
||||||
// have a lower ID and will be deserialized first.
|
|
||||||
ObjectCacheIndexMap string_ids_;
|
|
||||||
ObjectCacheIndexMap symbol_ids_;
|
|
||||||
ObjectCacheIndexMap bigint_ids_;
|
|
||||||
ObjectCacheIndexMap map_ids_;
|
|
||||||
ObjectCacheIndexMap context_ids_;
|
|
||||||
ObjectCacheIndexMap function_ids_;
|
|
||||||
ObjectCacheIndexMap class_ids_;
|
|
||||||
ObjectCacheIndexMap array_ids_;
|
|
||||||
ObjectCacheIndexMap typed_array_ids_;
|
|
||||||
ObjectCacheIndexMap array_buffer_ids_;
|
|
||||||
ObjectCacheIndexMap data_view_ids_;
|
|
||||||
ObjectCacheIndexMap object_ids_;
|
|
||||||
uint32_t export_count_ = 0;
|
|
||||||
|
|
||||||
// For handling references to builtin objects:
|
|
||||||
// --------------------------------
|
|
||||||
// String objects for the names of all known builtins.
|
|
||||||
Handle<FixedArray> builtin_object_name_strings_;
|
|
||||||
|
|
||||||
// Map object -> index in builtin_name_strings_ for all known builtins.
|
|
||||||
ObjectCacheIndexMap builtin_object_to_name_;
|
|
||||||
|
|
||||||
// Map object -> index in builtins_. Includes only builtins which will be
|
|
||||||
// incluced in the snapshot.
|
|
||||||
ObjectCacheIndexMap builtin_object_ids_;
|
|
||||||
|
|
||||||
// For creating the Builtin wrappers in the snapshot. Includes only builtins
|
|
||||||
// which will be incluced in the snapshot. Each element is the id of the
|
|
||||||
// builtin name string in the snapshot.
|
|
||||||
std::vector<uint32_t> builtin_objects_;
|
|
||||||
// --------------------------------
|
|
||||||
|
|
||||||
std::queue<Handle<HeapObject>> discovery_queue_;
|
|
||||||
|
|
||||||
// For keeping track of which strings have exactly one reference. Strings are
|
|
||||||
// inserted here when the first reference is discovered, and never removed.
|
|
||||||
// Strings which have more than one reference get an ID and are inserted to
|
|
||||||
// strings_.
|
|
||||||
IdentityMap<int, base::DefaultAllocationPolicy> all_strings_;
|
|
||||||
|
|
||||||
// For constructing the minimal, "compacted", source string to cover all
|
|
||||||
// function bodies.
|
|
||||||
// --------------------------------
|
|
||||||
// Script id -> offset of the script source code in full_source_.
|
|
||||||
std::map<int, int> script_offsets_;
|
|
||||||
Handle<String> full_source_;
|
|
||||||
uint32_t source_id_;
|
|
||||||
// Ordered set of (start, end) pairs of all functions we've discovered.
|
|
||||||
std::set<std::pair<int, int>> source_intervals_;
|
|
||||||
// Maps function positions in the real source code into the function positions
|
|
||||||
// in the constructed source code (which we'll include in the web snapshot).
|
|
||||||
std::unordered_map<int, int> source_offset_to_compacted_source_offset_;
|
|
||||||
// --------------------------------
|
|
||||||
};
|
|
||||||
|
|
||||||
class V8_EXPORT WebSnapshotDeserializer
|
|
||||||
: public WebSnapshotSerializerDeserializer {
|
|
||||||
public:
|
|
||||||
WebSnapshotDeserializer(v8::Isolate* v8_isolate, const uint8_t* data,
|
|
||||||
size_t buffer_size);
|
|
||||||
WebSnapshotDeserializer(Isolate* isolate, Handle<Script> snapshot_as_script);
|
|
||||||
~WebSnapshotDeserializer();
|
|
||||||
bool Deserialize(MaybeHandle<FixedArray> external_references = {},
|
|
||||||
bool skip_exports = false);
|
|
||||||
|
|
||||||
// For inspecting the state after deserializing a snapshot.
|
|
||||||
uint32_t string_count() const { return string_count_; }
|
|
||||||
uint32_t symbol_count() const { return symbol_count_; }
|
|
||||||
uint32_t map_count() const { return map_count_; }
|
|
||||||
uint32_t builtin_object_count() const { return builtin_object_count_; }
|
|
||||||
uint32_t context_count() const { return context_count_; }
|
|
||||||
uint32_t function_count() const { return function_count_; }
|
|
||||||
uint32_t class_count() const { return class_count_; }
|
|
||||||
uint32_t array_count() const { return array_count_; }
|
|
||||||
uint32_t object_count() const { return object_count_; }
|
|
||||||
|
|
||||||
static void UpdatePointersCallback(v8::Isolate* isolate, v8::GCType type,
|
|
||||||
v8::GCCallbackFlags flags,
|
|
||||||
void* deserializer) {
|
|
||||||
reinterpret_cast<WebSnapshotDeserializer*>(deserializer)->UpdatePointers();
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdatePointers();
|
|
||||||
|
|
||||||
MaybeHandle<Object> value() const { return return_value_; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum class InternalizeStrings {
|
|
||||||
kNo,
|
|
||||||
kYes,
|
|
||||||
};
|
|
||||||
|
|
||||||
WebSnapshotDeserializer(Isolate* isolate, Handle<Object> script_name,
|
|
||||||
base::Vector<const uint8_t> buffer);
|
|
||||||
// Return value: {data, length, data_owned}.
|
|
||||||
std::tuple<const uint8_t*, uint32_t, bool> ExtractScriptBuffer(
|
|
||||||
Isolate* isolate, Handle<Script> snapshot_as_script);
|
|
||||||
bool DeserializeSnapshot(bool skip_exports);
|
|
||||||
void CollectBuiltinObjects();
|
|
||||||
bool DeserializeScript();
|
|
||||||
|
|
||||||
WebSnapshotDeserializer(const WebSnapshotDeserializer&) = delete;
|
|
||||||
WebSnapshotDeserializer& operator=(const WebSnapshotDeserializer&) = delete;
|
|
||||||
|
|
||||||
void DeserializeStrings();
|
|
||||||
void DeserializeSymbols();
|
|
||||||
void DeserializeBigInts();
|
|
||||||
void DeserializeMaps();
|
|
||||||
void DeserializeBuiltinObjects();
|
|
||||||
void DeserializeContexts();
|
|
||||||
Handle<ScopeInfo> CreateScopeInfo(uint32_t variable_count, bool has_parent,
|
|
||||||
ContextType context_type,
|
|
||||||
bool has_inlined_local_names);
|
|
||||||
Handle<JSFunction> CreateJSFunction(int index, uint32_t start,
|
|
||||||
uint32_t length, uint32_t parameter_count,
|
|
||||||
uint8_t flags, uint32_t context_id);
|
|
||||||
void DeserializeFunctionData(uint32_t count, uint32_t current_count);
|
|
||||||
void DeserializeFunctions();
|
|
||||||
void DeserializeClasses();
|
|
||||||
void DeserializeArrays();
|
|
||||||
void DeserializeArrayBuffers();
|
|
||||||
void DeserializeTypedArrays();
|
|
||||||
void DeserializeDataViews();
|
|
||||||
void DeserializeObjects();
|
|
||||||
void DeserializeObjectElements(Handle<JSObject> object,
|
|
||||||
bool map_from_snapshot);
|
|
||||||
void DeserializeExports(bool skip_exports);
|
|
||||||
void DeserializeObjectPrototype(Handle<Map> map);
|
|
||||||
Handle<Map> DeserializeObjectPrototypeAndCreateEmptyMap();
|
|
||||||
void DeserializeObjectPrototypeForFunction(Handle<JSFunction> function);
|
|
||||||
void SetPrototype(Handle<Map> map, Handle<Object> prototype);
|
|
||||||
void DeserializeFunctionProperties(Handle<JSFunction> function);
|
|
||||||
bool ReadCount(uint32_t& count);
|
|
||||||
|
|
||||||
bool IsInitialFunctionPrototype(Object prototype);
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void DeserializeObjectPropertiesWithDictionaryMap(
|
|
||||||
T dict, uint32_t property_count, bool has_custom_property_attributes);
|
|
||||||
|
|
||||||
Handle<PropertyArray> DeserializePropertyArray(
|
|
||||||
Handle<DescriptorArray> descriptors, int no_properties);
|
|
||||||
|
|
||||||
// Return value: (object, was_deferred)
|
|
||||||
std::tuple<Object, bool> ReadValue(
|
|
||||||
Handle<HeapObject> object_for_deferred_reference = Handle<HeapObject>(),
|
|
||||||
uint32_t index_for_deferred_reference = 0,
|
|
||||||
InternalizeStrings internalize_strings = InternalizeStrings::kNo);
|
|
||||||
|
|
||||||
Object ReadInteger();
|
|
||||||
Object ReadNumber();
|
|
||||||
String ReadString(
|
|
||||||
InternalizeStrings internalize_strings = InternalizeStrings::kNo);
|
|
||||||
String ReadInPlaceString(
|
|
||||||
InternalizeStrings internalize_strings = InternalizeStrings::kNo);
|
|
||||||
Object ReadSymbol();
|
|
||||||
Object ReadBigInt();
|
|
||||||
std::tuple<Object, bool> ReadArray(Handle<HeapObject> container,
|
|
||||||
uint32_t container_index);
|
|
||||||
std::tuple<Object, bool> ReadArrayBuffer(Handle<HeapObject> container,
|
|
||||||
uint32_t container_index);
|
|
||||||
std::tuple<Object, bool> ReadTypedArray(Handle<HeapObject> container,
|
|
||||||
uint32_t container_index);
|
|
||||||
std::tuple<Object, bool> ReadDataView(Handle<HeapObject> container,
|
|
||||||
uint32_t container_index);
|
|
||||||
std::tuple<Object, bool> ReadObject(Handle<HeapObject> container,
|
|
||||||
uint32_t container_index);
|
|
||||||
std::tuple<Object, bool> ReadFunction(Handle<HeapObject> container,
|
|
||||||
uint32_t container_index);
|
|
||||||
std::tuple<Object, bool> ReadClass(Handle<HeapObject> container,
|
|
||||||
uint32_t container_index);
|
|
||||||
Object ReadRegexp();
|
|
||||||
Object ReadBuiltinObjectReference();
|
|
||||||
Object ReadExternalReference();
|
|
||||||
bool ReadMapType();
|
|
||||||
std::tuple<Handle<FixedArrayBase>, ElementsKind, uint32_t>
|
|
||||||
DeserializeElements();
|
|
||||||
ElementsType ReadElementsType();
|
|
||||||
std::tuple<Handle<FixedArrayBase>, ElementsKind, uint32_t> ReadDenseElements(
|
|
||||||
uint32_t length);
|
|
||||||
std::tuple<Handle<FixedArrayBase>, ElementsKind, uint32_t> ReadSparseElements(
|
|
||||||
uint32_t length);
|
|
||||||
|
|
||||||
void ReadFunctionPrototype(Handle<JSFunction> function);
|
|
||||||
bool SetFunctionPrototype(JSFunction function, JSReceiver prototype);
|
|
||||||
|
|
||||||
HeapObject AddDeferredReference(Handle<HeapObject> container, uint32_t index,
|
|
||||||
ValueType target_type,
|
|
||||||
uint32_t target_object_index);
|
|
||||||
void ProcessDeferredReferences();
|
|
||||||
// Not virtual, on purpose (because it doesn't need to be).
|
|
||||||
void Throw(const char* message);
|
|
||||||
void VerifyObjects();
|
|
||||||
|
|
||||||
Handle<FixedArray> strings_handle_;
|
|
||||||
FixedArray strings_;
|
|
||||||
|
|
||||||
Handle<FixedArray> symbols_handle_;
|
|
||||||
FixedArray symbols_;
|
|
||||||
|
|
||||||
Handle<FixedArray> bigints_handle_;
|
|
||||||
FixedArray bigints_;
|
|
||||||
|
|
||||||
Handle<FixedArray> builtin_objects_handle_;
|
|
||||||
FixedArray builtin_objects_;
|
|
||||||
|
|
||||||
Handle<FixedArray> maps_handle_;
|
|
||||||
FixedArray maps_;
|
|
||||||
std::map<int, Handle<Map>> deserialized_function_maps_;
|
|
||||||
|
|
||||||
Handle<FixedArray> contexts_handle_;
|
|
||||||
FixedArray contexts_;
|
|
||||||
|
|
||||||
Handle<FixedArray> functions_handle_;
|
|
||||||
FixedArray functions_;
|
|
||||||
|
|
||||||
Handle<FixedArray> classes_handle_;
|
|
||||||
FixedArray classes_;
|
|
||||||
|
|
||||||
Handle<FixedArray> arrays_handle_;
|
|
||||||
FixedArray arrays_;
|
|
||||||
|
|
||||||
Handle<FixedArray> array_buffers_handle_;
|
|
||||||
FixedArray array_buffers_;
|
|
||||||
|
|
||||||
Handle<FixedArray> typed_arrays_handle_;
|
|
||||||
FixedArray typed_arrays_;
|
|
||||||
|
|
||||||
Handle<FixedArray> data_views_handle_;
|
|
||||||
FixedArray data_views_;
|
|
||||||
|
|
||||||
Handle<FixedArray> objects_handle_;
|
|
||||||
FixedArray objects_;
|
|
||||||
|
|
||||||
Handle<FixedArray> external_references_handle_;
|
|
||||||
FixedArray external_references_;
|
|
||||||
|
|
||||||
// Map: String -> builtin object.
|
|
||||||
Handle<ObjectHashTable> builtin_object_name_to_object_;
|
|
||||||
|
|
||||||
Handle<ArrayList> deferred_references_;
|
|
||||||
|
|
||||||
Handle<WeakFixedArray> shared_function_infos_handle_;
|
|
||||||
WeakFixedArray shared_function_infos_;
|
|
||||||
|
|
||||||
Handle<ObjectHashTable> shared_function_info_table_;
|
|
||||||
|
|
||||||
Handle<Script> script_;
|
|
||||||
Handle<Object> script_name_;
|
|
||||||
|
|
||||||
Handle<Object> return_value_;
|
|
||||||
|
|
||||||
uint32_t string_count_ = 0;
|
|
||||||
uint32_t symbol_count_ = 0;
|
|
||||||
uint32_t bigint_count_ = 0;
|
|
||||||
uint32_t map_count_ = 0;
|
|
||||||
uint32_t builtin_object_count_ = 0;
|
|
||||||
uint32_t context_count_ = 0;
|
|
||||||
uint32_t function_count_ = 0;
|
|
||||||
uint32_t current_function_count_ = 0;
|
|
||||||
uint32_t class_count_ = 0;
|
|
||||||
uint32_t current_class_count_ = 0;
|
|
||||||
uint32_t array_count_ = 0;
|
|
||||||
uint32_t current_array_count_ = 0;
|
|
||||||
uint32_t array_buffer_count_ = 0;
|
|
||||||
uint32_t current_array_buffer_count_ = 0;
|
|
||||||
uint32_t typed_array_count_ = 0;
|
|
||||||
uint32_t current_typed_array_count_ = 0;
|
|
||||||
uint32_t data_view_count_ = 0;
|
|
||||||
uint32_t current_data_view_count_ = 0;
|
|
||||||
uint32_t object_count_ = 0;
|
|
||||||
uint32_t current_object_count_ = 0;
|
|
||||||
|
|
||||||
std::unique_ptr<ValueDeserializer> deserializer_;
|
|
||||||
std::unique_ptr<const uint8_t[]> owned_data_;
|
|
||||||
ReadOnlyRoots roots_;
|
|
||||||
|
|
||||||
bool deserialized_ = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace internal
|
|
||||||
} // namespace v8
|
|
||||||
|
|
||||||
#endif // V8_WEB_SNAPSHOT_WEB_SNAPSHOT_H_
|
|
@ -39,7 +39,6 @@
|
|||||||
'wasm/wasm-module-builder': [SKIP],
|
'wasm/wasm-module-builder': [SKIP],
|
||||||
'compiler/fast-api-helpers': [SKIP],
|
'compiler/fast-api-helpers': [SKIP],
|
||||||
'typedarray-helpers': [SKIP],
|
'typedarray-helpers': [SKIP],
|
||||||
'web-snapshot/web-snapshot-helpers': [SKIP],
|
|
||||||
|
|
||||||
# All tests in the bug directory are expected to fail.
|
# All tests in the bug directory are expected to fail.
|
||||||
'bugs/*': [FAIL],
|
'bugs/*': [FAIL],
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --harmony-rab-gsab --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
|
|
||||||
(function TestSharedArrayBuffer() {
|
|
||||||
function createObjects() {
|
|
||||||
const growableArrayBuffer = new SharedArrayBuffer(5, { maxByteLength: 10 });
|
|
||||||
globalThis.growableArrayBuffer = growableArrayBuffer;
|
|
||||||
const array1 = new Uint8Array(growableArrayBuffer);
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
array1[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
const arrayBuffer = new SharedArrayBuffer(5);
|
|
||||||
globalThis.arrayBuffer = arrayBuffer;
|
|
||||||
const array2 = new Uint8Array(arrayBuffer);
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
array2[i] = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const { growableArrayBuffer, arrayBuffer } = takeAndUseWebSnapshot(createObjects, ['growableArrayBuffer', 'arrayBuffer']);
|
|
||||||
assertEquals(5, growableArrayBuffer.byteLength);
|
|
||||||
assertEquals(10, growableArrayBuffer.maxByteLength);
|
|
||||||
assertTrue(growableArrayBuffer.growable);
|
|
||||||
const array1 = new Uint8Array(growableArrayBuffer);
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
assertEquals(array1[i], i);
|
|
||||||
}
|
|
||||||
|
|
||||||
assertEquals(arrayBuffer.byteLength, 5);
|
|
||||||
assertEquals(arrayBuffer.maxByteLength, 5);
|
|
||||||
assertFalse(arrayBuffer.growable, false);
|
|
||||||
const array2 = new Uint8Array(arrayBuffer);
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
assertEquals(array2[i], i);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestArrayBuffer() {
|
|
||||||
function createObjects() {
|
|
||||||
const resizableArrayBuffer = new ArrayBuffer(5, {maxByteLength: 10});
|
|
||||||
globalThis.resizableArrayBuffer = resizableArrayBuffer;
|
|
||||||
const array1 = new Uint8Array(resizableArrayBuffer);
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
array1[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
const arrayBuffer = new ArrayBuffer(5);
|
|
||||||
globalThis.arrayBuffer = arrayBuffer;
|
|
||||||
const array2 = new Uint8Array(arrayBuffer);
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
array2[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
const detachedArrayBuffer = new ArrayBuffer(5);
|
|
||||||
%ArrayBufferDetach(detachedArrayBuffer);
|
|
||||||
globalThis.detachedArrayBuffer = detachedArrayBuffer;
|
|
||||||
}
|
|
||||||
const { resizableArrayBuffer, arrayBuffer, detachedArrayBuffer } = takeAndUseWebSnapshot(createObjects, ['resizableArrayBuffer', 'arrayBuffer', 'detachedArrayBuffer']);
|
|
||||||
assertEquals(5, resizableArrayBuffer.byteLength);
|
|
||||||
assertEquals(10, resizableArrayBuffer.maxByteLength);
|
|
||||||
assertTrue(resizableArrayBuffer.resizable)
|
|
||||||
const array1 = new Uint8Array(resizableArrayBuffer);
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
assertEquals(array1[i], i);
|
|
||||||
}
|
|
||||||
|
|
||||||
assertEquals(5, arrayBuffer.byteLength);
|
|
||||||
assertEquals(5, arrayBuffer.maxByteLength);
|
|
||||||
assertFalse(arrayBuffer.resizable)
|
|
||||||
const array2 = new Uint8Array(arrayBuffer);
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
assertEquals(array2[i], i);
|
|
||||||
}
|
|
||||||
|
|
||||||
assertEquals(0, detachedArrayBuffer.byteLength);
|
|
||||||
assertEquals(0, detachedArrayBuffer.maxByteLength);
|
|
||||||
})()
|
|
@ -1,133 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestArray() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
array: [5, 6, 7]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([5, 6, 7], foo.array);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestPackedDoubleElementsArray() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = [1.2, 2.3];
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([1.2, 2.3], foo);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestArrayContainingDoubleAndSmi() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = [1.2, 1];
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([1.2, 1], foo);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestArrayContainingDoubleAndObject() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = [1.2, {'key': 'value'}];
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([1.2, {'key': 'value'}], foo);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestEmptyArray() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
array: []
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(0, foo.array.length);
|
|
||||||
assertEquals([], foo.array);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestArrayContainingArray() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
array: [[2, 3], [4, 5]]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([[2, 3], [4, 5]], foo.array);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestArrayContainingObject() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
array: [{ a: 1 }, { b: 2 }]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(1, foo.array[0].a);
|
|
||||||
assertEquals(2, foo.array[1].b);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestArrayContainingFunction() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
array: [function () { return 5; }]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(5, foo.array[0]());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestInPlaceStringsInArray() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
array: ['foo', 'bar', 'baz']
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
// We cannot test that the strings are really in-place; that's covered by
|
|
||||||
// cctests.
|
|
||||||
assertEquals('foobarbaz', foo.array.join(''));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestRepeatedInPlaceStringsInArray() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
array: ['foo', 'bar', 'foo']
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
// We cannot test that the strings are really in-place; that's covered by
|
|
||||||
// cctests.
|
|
||||||
assertEquals('foobarfoo', foo.array.join(''));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestArrayWithSlackElements() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
array: [],
|
|
||||||
doubleArray: [],
|
|
||||||
objectArray: []
|
|
||||||
};
|
|
||||||
for (let i = 0; i < 100; ++i) {
|
|
||||||
globalThis.foo.array.push(i);
|
|
||||||
globalThis.foo.doubleArray.push(i + 0.1);
|
|
||||||
globalThis.foo.objectArray.push({});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(100, foo.array.length);
|
|
||||||
assertEquals(100, foo.doubleArray.length);
|
|
||||||
assertEquals(100, foo.objectArray.length);
|
|
||||||
for (let i = 0; i < 100; ++i){
|
|
||||||
assertEquals(i, foo.array[i]);
|
|
||||||
assertEquals(i + 0.1, foo.doubleArray[i]);
|
|
||||||
assertEquals({}, foo.objectArray[i]);
|
|
||||||
}
|
|
||||||
})();
|
|
@ -1,147 +0,0 @@
|
|||||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestMinimal() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
str: 'hello',
|
|
||||||
n: 42,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('hello', foo.str);
|
|
||||||
assertEquals(42, foo.n);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestEmptyObject() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([], Object.keys(foo));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestNumbers() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
a: 6,
|
|
||||||
b: -7,
|
|
||||||
c: 7.3,
|
|
||||||
d: NaN,
|
|
||||||
e: Number.POSITIVE_INFINITY,
|
|
||||||
f: Number.NEGATIVE_INFINITY,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(6, foo.a);
|
|
||||||
assertEquals(-7, foo.b);
|
|
||||||
assertEquals(7.3, foo.c);
|
|
||||||
assertEquals(NaN, foo.d);
|
|
||||||
assertEquals(Number.POSITIVE_INFINITY, foo.e);
|
|
||||||
assertEquals(Number.NEGATIVE_INFINITY, foo.f);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestTopLevelNumbers() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.a = 6;
|
|
||||||
globalThis.b = -7;
|
|
||||||
}
|
|
||||||
const { a, b } = takeAndUseWebSnapshot(createObjects, ['a', 'b']);
|
|
||||||
assertEquals(6, a);
|
|
||||||
assertEquals(-7, b);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestOddballs() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
a: true,
|
|
||||||
b: false,
|
|
||||||
c: null,
|
|
||||||
d: undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertTrue(foo.a);
|
|
||||||
assertFalse(foo.b);
|
|
||||||
assertEquals(null, foo.c);
|
|
||||||
assertEquals(undefined, foo.d);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestTopLevelOddballs() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.a = true;
|
|
||||||
globalThis.b = false;
|
|
||||||
}
|
|
||||||
const { a, b } = takeAndUseWebSnapshot(createObjects, ['a', 'b']);
|
|
||||||
assertTrue(a);
|
|
||||||
assertFalse(b);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestStringWithNull() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.s = 'l\0l';
|
|
||||||
}
|
|
||||||
const { s } = takeAndUseWebSnapshot(createObjects, ['s']);
|
|
||||||
assertEquals(108, s.charCodeAt(0));
|
|
||||||
assertEquals(0, s.charCodeAt(1));
|
|
||||||
assertEquals(108, s.charCodeAt(2));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestTwoByteString() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.s = '\u{1F600}';
|
|
||||||
}
|
|
||||||
const { s } = takeAndUseWebSnapshot(createObjects, ['s']);
|
|
||||||
assertEquals('\u{1F600}', s);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestTwoByteStringWithNull() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.s = 'l\0l\u{1F600}';
|
|
||||||
}
|
|
||||||
const { s } = takeAndUseWebSnapshot(createObjects, ['s']);
|
|
||||||
assertEquals(108, s.charCodeAt(0));
|
|
||||||
assertEquals(0, s.charCodeAt(1));
|
|
||||||
assertEquals(108, s.charCodeAt(2));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestRegExp() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
re: /ab+c/gi,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('/ab+c/gi', foo.re.toString());
|
|
||||||
assertTrue(foo.re.test('aBc'));
|
|
||||||
assertFalse(foo.re.test('ac'));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestRegExpNoFlags() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
re: /ab+c/,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('/ab+c/', foo.re.toString());
|
|
||||||
assertTrue(foo.re.test('abc'));
|
|
||||||
assertFalse(foo.re.test('ac'));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestTopLevelRegExp() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.re = /ab+c/gi;
|
|
||||||
}
|
|
||||||
const { re } = takeAndUseWebSnapshot(createObjects, ['re']);
|
|
||||||
assertEquals('/ab+c/gi', re.toString());
|
|
||||||
assertTrue(re.test('aBc'));
|
|
||||||
assertFalse(re.test('ac'));
|
|
||||||
})();
|
|
@ -1,122 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestBigInt() {
|
|
||||||
function createObjects() {
|
|
||||||
const b = 100n;
|
|
||||||
const c = 2n ** 222n;
|
|
||||||
globalThis.foo = { bar: b, bar1: c };
|
|
||||||
}
|
|
||||||
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(100n, foo.bar);
|
|
||||||
assertEquals(2n ** 222n , foo.bar1)
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestBigIntInArray() {
|
|
||||||
function createObjects() {
|
|
||||||
const b = 100n;
|
|
||||||
const c = 2n ** 222n;
|
|
||||||
globalThis.foo = [b, c];
|
|
||||||
}
|
|
||||||
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([100n, 2n ** 222n], foo)
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestBigIntInFunctionContext() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
key: (function () {
|
|
||||||
const b = 100n;
|
|
||||||
const c = 2n ** 222n;
|
|
||||||
function inner() {
|
|
||||||
return [b, c];
|
|
||||||
}
|
|
||||||
return inner;
|
|
||||||
})()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([100n, 2n**222n], foo.key());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestBigIntInFunctionContextWithParentContext() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
key: (function () {
|
|
||||||
const b = 100n;
|
|
||||||
function inner() {
|
|
||||||
const c = 2n ** 222n;
|
|
||||||
function innerinner() {
|
|
||||||
return [b, c]
|
|
||||||
}
|
|
||||||
return innerinner
|
|
||||||
}
|
|
||||||
return inner();
|
|
||||||
})()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([100n, 2n**222n], foo.key());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestBigIntInTopLevelFunctionWithContext() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = (function () {
|
|
||||||
const b = 100n;
|
|
||||||
const c = 2n ** 222n;
|
|
||||||
function inner() { return [b, c]; }
|
|
||||||
return inner;
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([100n, 2n**222n], foo());
|
|
||||||
})();
|
|
||||||
|
|
||||||
|
|
||||||
(function TestBigIntInClassStaticProperty() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = class Foo {
|
|
||||||
static b = 100n;
|
|
||||||
static c = 2n ** 222n;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo: Foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([100n, 2n**222n], [Foo.b, Foo.c]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestBigIntInClassWithConstructor() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = class Foo {
|
|
||||||
constructor() {
|
|
||||||
this.b = 100n;
|
|
||||||
this.c = 2n ** 222n;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo: Foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
const foo = new Foo()
|
|
||||||
assertEquals([100n, 2n**222n], [foo.b, foo.c]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(async function TestBigIntInClassWithMethods() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = class Foo {
|
|
||||||
b() {
|
|
||||||
return 100n;
|
|
||||||
}
|
|
||||||
async c() {
|
|
||||||
return 2n ** 222n;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo: Foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
const foo = new Foo()
|
|
||||||
assertEquals([100n, 2n**222n], [foo.b(), await foo.c()]);
|
|
||||||
})();
|
|
@ -1,39 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestBuiltin() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.obj1 = {'a': Error};
|
|
||||||
globalThis.obj2 = {'b': Error.prototype};
|
|
||||||
}
|
|
||||||
const realm = Realm.create();
|
|
||||||
const {obj1, obj2} = takeAndUseWebSnapshot(
|
|
||||||
createObjects, ['obj1', 'obj2'], realm);
|
|
||||||
assertSame(Realm.eval(realm, 'Error'), obj1.a);
|
|
||||||
assertSame(Realm.eval(realm, 'Error.prototype'), obj2.b);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestInheritFromBuiltin() {
|
|
||||||
function createObjects() {
|
|
||||||
function inherit(subclass, superclass) {
|
|
||||||
function middle() {}
|
|
||||||
middle.prototype = superclass.prototype;
|
|
||||||
subclass.prototype = new middle();
|
|
||||||
subclass.prototype.constructor = subclass;
|
|
||||||
};
|
|
||||||
function MyError() {}
|
|
||||||
inherit(MyError, Error);
|
|
||||||
globalThis.MyError = MyError;
|
|
||||||
}
|
|
||||||
const realm = Realm.create();
|
|
||||||
const {MyError} = takeAndUseWebSnapshot(createObjects, ['MyError'], realm);
|
|
||||||
const obj = new MyError();
|
|
||||||
assertSame(Realm.eval(realm, 'Error.prototype'), obj.__proto__.__proto__);
|
|
||||||
})();
|
|
@ -1,20 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestCircularObjectReference() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
bar: {}
|
|
||||||
};
|
|
||||||
globalThis.foo.bar.circular = globalThis.foo;
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertSame(foo, foo.bar.circular);
|
|
||||||
})();
|
|
@ -1,177 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestEmptyClass() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Foo = class Foo { };
|
|
||||||
}
|
|
||||||
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
|
|
||||||
const x = new Foo();
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestClassWithConstructor() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Foo = class {
|
|
||||||
constructor() {
|
|
||||||
this.n = 42;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
|
|
||||||
const x = new Foo(2);
|
|
||||||
assertEquals(42, x.n);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestClassWithMethods() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Foo = class {
|
|
||||||
f() { return 7; };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
|
|
||||||
const x = new Foo();
|
|
||||||
assertEquals(7, x.f());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestDerivedClass() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Base = class { f() { return 8; }};
|
|
||||||
globalThis.Foo = class extends Base { };
|
|
||||||
}
|
|
||||||
const realm = Realm.create();
|
|
||||||
const { Foo, Base } = takeAndUseWebSnapshot(createObjects, ['Foo', 'Base'], realm);
|
|
||||||
assertEquals(Base.prototype, Foo.prototype.__proto__);
|
|
||||||
assertEquals(Base, Foo.__proto__);
|
|
||||||
const x = new Foo();
|
|
||||||
assertEquals(8, x.f());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestDerivedClassWithConstructor() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Base = class { constructor() {this.m = 43;}};
|
|
||||||
globalThis.Foo = class extends Base{
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.n = 42;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
|
|
||||||
const x = new Foo();
|
|
||||||
assertEquals(42, x.n);
|
|
||||||
assertEquals(43, x.m);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(async function TestClassWithAsyncMethods() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Foo = class {
|
|
||||||
async g() { return 6; };
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
|
|
||||||
const x = new Foo();
|
|
||||||
assertEquals(6, await x.g());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestClassWithProperties() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Foo = class Foo { };
|
|
||||||
Foo.key1 = 'value1';
|
|
||||||
Foo.key2 = 1;
|
|
||||||
Foo.key3 = 2.2;
|
|
||||||
Foo.key4 = function key4() {
|
|
||||||
return 'key4';
|
|
||||||
}
|
|
||||||
Foo.key5 = [1, 2];
|
|
||||||
Foo.key6 = {'key':'value'}
|
|
||||||
}
|
|
||||||
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
|
|
||||||
assertEquals('value1', Foo.key1);
|
|
||||||
assertEquals(1, Foo.key2);
|
|
||||||
assertEquals(2.2, Foo.key3);
|
|
||||||
assertEquals('key4', Foo.key4());
|
|
||||||
assertEquals([1, 2], Foo.key5);
|
|
||||||
assertEquals({ 'key': 'value' }, Foo.key6 );
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestClassWithStaticProperties() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Foo = class Foo {
|
|
||||||
static key1 = 'value1';
|
|
||||||
static key2 = 1;
|
|
||||||
static key3 = 2.2;
|
|
||||||
static key4 = [1, 2];
|
|
||||||
static key5 = {'key':'value'}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
|
|
||||||
assertEquals('value1', Foo.key1);
|
|
||||||
assertEquals(1, Foo.key2);
|
|
||||||
assertEquals(2.2, Foo.key3);
|
|
||||||
assertEquals([1, 2], Foo.key4);
|
|
||||||
assertEquals({'key': 'value'}, Foo.key5);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestClassWithStaticMethods() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Foo = class Foo {
|
|
||||||
static foo() {
|
|
||||||
return 'foo'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
|
|
||||||
assertEquals('foo', Foo.foo());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(async function TestClassWithStaticAsyncMethods() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Foo = class Foo {
|
|
||||||
static async foo() {
|
|
||||||
await Promise.resolve(1);
|
|
||||||
return 'foo'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
|
|
||||||
assertEquals('foo', await Foo.foo());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestClassWithStaticGeneratorMethods() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Foo = class Foo {
|
|
||||||
static *foo() {
|
|
||||||
yield 'foo1'
|
|
||||||
return 'foo2'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
|
|
||||||
const foo = Foo.foo()
|
|
||||||
assertEquals('foo1', foo.next().value);
|
|
||||||
assertEquals('foo2', foo.next().value);
|
|
||||||
assertEquals(true, foo.next().done);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(async function TestClassWithStaticAsyncGeneratorMethods() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Foo = class Foo {
|
|
||||||
static async *foo() {
|
|
||||||
yield 'foo1'
|
|
||||||
return 'foo2'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { Foo } = takeAndUseWebSnapshot(createObjects, ['Foo']);
|
|
||||||
const foo = Foo.foo()
|
|
||||||
assertEquals('foo1', (await foo.next()).value);
|
|
||||||
assertEquals('foo2', (await foo.next()).value);
|
|
||||||
assertEquals(true, (await foo.next()).done);
|
|
||||||
})();
|
|
@ -1,127 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --harmony-rab-gsab --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestDataView() {
|
|
||||||
function createObjects() {
|
|
||||||
const buffer = new ArrayBuffer(10);
|
|
||||||
const array1 = new DataView(buffer, 0, 5);
|
|
||||||
const array2 = new DataView(buffer, 5, 5);
|
|
||||||
const array3 = new DataView(buffer, 2, 5);
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
array1.setUint8(i, i);
|
|
||||||
array2.setUint8(i, i);
|
|
||||||
}
|
|
||||||
globalThis.array1 = array1;
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
globalThis.array3 = array3;
|
|
||||||
}
|
|
||||||
const {array1, array2, array3} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array1',
|
|
||||||
'array2',
|
|
||||||
'array3'
|
|
||||||
]);
|
|
||||||
assertEquals(5, array1.byteLength);
|
|
||||||
assertEquals(0, array1.byteOffset);
|
|
||||||
assertEquals(5, array2.byteLength);
|
|
||||||
assertEquals(5, array2.byteOffset);
|
|
||||||
assertEquals(5, array3.byteLength);
|
|
||||||
assertEquals(2, array3.byteOffset);
|
|
||||||
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
assertEquals(i, array1.getUint8(i));
|
|
||||||
assertEquals(i, array2.getUint8(i));
|
|
||||||
}
|
|
||||||
assertSame(array1.buffer, array2.buffer);
|
|
||||||
assertSame(array1.buffer, array3.buffer);
|
|
||||||
|
|
||||||
new DataView(array1.buffer).setUint8(2, 10);
|
|
||||||
assertTrue(array1.getUint8(2) === 10);
|
|
||||||
assertTrue(array3.getUint8(0) === 10);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestResizableDataView() {
|
|
||||||
function createObjects() {
|
|
||||||
let resizableArrayBuffer = new ArrayBuffer(1024, {
|
|
||||||
maxByteLength: 1024 * 2,
|
|
||||||
});
|
|
||||||
// 0 offset, auto length
|
|
||||||
let array1 = new DataView(resizableArrayBuffer);
|
|
||||||
globalThis.array1 = array1;
|
|
||||||
|
|
||||||
// Non-0 offset, auto length
|
|
||||||
let array2 = new DataView(resizableArrayBuffer, 256);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
|
|
||||||
// Non-0 offset, fixed length
|
|
||||||
let array3 = new DataView(resizableArrayBuffer, 128, 4);
|
|
||||||
globalThis.array3 = array3;
|
|
||||||
}
|
|
||||||
const {array1, array2, array3} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array1',
|
|
||||||
'array2',
|
|
||||||
'array3',
|
|
||||||
]);
|
|
||||||
assertTrue(array1.buffer.resizable);
|
|
||||||
assertEquals(2048, array1.buffer.maxByteLength);
|
|
||||||
assertEquals(1024, array1.byteLength);
|
|
||||||
assertEquals(0, array1.byteOffset, 0);
|
|
||||||
assertEquals(768, array2.byteLength); // 1024 - 256
|
|
||||||
assertEquals(256, array2.byteOffset);
|
|
||||||
assertEquals(4, array3.byteLength);
|
|
||||||
assertEquals(128, array3.byteOffset);
|
|
||||||
|
|
||||||
array1.buffer.resize(1024 * 2);
|
|
||||||
assertEquals(2048, array1.byteLength);
|
|
||||||
assertEquals(1792, array2.byteLength); // 2048 - 256
|
|
||||||
assertEquals(4, array3.byteLength);
|
|
||||||
|
|
||||||
assertSame(array1.buffer, array2.buffer);
|
|
||||||
assertSame(array1.buffer, array3.buffer);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestGrowableDataView() {
|
|
||||||
function createObjects() {
|
|
||||||
let resizableArrayBuffer = new SharedArrayBuffer(1024, {
|
|
||||||
maxByteLength: 1024 * 2,
|
|
||||||
});
|
|
||||||
// 0 offset, auto length
|
|
||||||
let array1 = new DataView(resizableArrayBuffer);
|
|
||||||
globalThis.array1 = array1;
|
|
||||||
|
|
||||||
// Non-0 offset, auto length
|
|
||||||
let array2 = new DataView(resizableArrayBuffer, 256);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
|
|
||||||
// Non-0 offset, fixed length
|
|
||||||
let array3 = new DataView(resizableArrayBuffer, 128, 4);
|
|
||||||
globalThis.array3 = array3;
|
|
||||||
}
|
|
||||||
const {array1, array2, array3} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array1',
|
|
||||||
'array2',
|
|
||||||
'array3',
|
|
||||||
]);
|
|
||||||
assertTrue(array1.buffer.growable);
|
|
||||||
assertEquals(2048, array1.buffer.maxByteLength);
|
|
||||||
assertEquals(1024, array1.byteLength);
|
|
||||||
assertEquals(0, array1.byteOffset);
|
|
||||||
assertEquals(768, array2.byteLength); // 1024 - 256
|
|
||||||
assertEquals(256, array2.byteOffset);
|
|
||||||
assertEquals(4, array3.byteLength);
|
|
||||||
assertEquals(128, array3.byteOffset);
|
|
||||||
|
|
||||||
array1.buffer.grow(1024 * 2);
|
|
||||||
assertEquals(2048, array1.byteLength);
|
|
||||||
assertEquals(1792, array2.byteLength); // 2048 - 256
|
|
||||||
assertEquals(4, array3.byteLength);
|
|
||||||
|
|
||||||
assertSame(array1.buffer, array2.buffer);
|
|
||||||
assertSame(array1.buffer, array3.buffer);
|
|
||||||
})();
|
|
@ -1,80 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-web-snapshots --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
const external_1 = {external: 1};
|
|
||||||
const external_2 = {external: 2};
|
|
||||||
const object = {
|
|
||||||
a: [1,2],
|
|
||||||
b: external_1,
|
|
||||||
c: [external_1, external_2],
|
|
||||||
d: { d_a: external_2 }
|
|
||||||
};
|
|
||||||
|
|
||||||
(function testNoExternals() {
|
|
||||||
const snapshot = WebSnapshot.serialize(object);
|
|
||||||
const deserialized = WebSnapshot.deserialize(snapshot);
|
|
||||||
%HeapObjectVerify(deserialized);
|
|
||||||
assertEquals(object, deserialized);
|
|
||||||
assertEquals(external_1, deserialized.b);
|
|
||||||
assertNotSame(external_1, deserialized.b);
|
|
||||||
assertEquals(external_2, deserialized.d.d_a);
|
|
||||||
assertNotSame(external_2, deserialized.d.d_a);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function testOneExternals() {
|
|
||||||
const externals = [external_1];
|
|
||||||
const snapshot = WebSnapshot.serialize(object, externals);
|
|
||||||
const replaced_externals = [{replacement:1}]
|
|
||||||
const deserialized = WebSnapshot.deserialize(snapshot, replaced_externals);
|
|
||||||
%HeapObjectVerify(deserialized);
|
|
||||||
assertEquals(object.a, deserialized.a);
|
|
||||||
assertSame(replaced_externals[0], deserialized.b);
|
|
||||||
assertArrayEquals([replaced_externals[0], external_2], deserialized.c);
|
|
||||||
assertSame(replaced_externals[0], deserialized.c[0]);
|
|
||||||
assertNotSame(external_2, deserialized.c[1]);
|
|
||||||
assertEquals(external_2, deserialized.d.d_a);
|
|
||||||
assertNotSame(external_2, deserialized.d.d_a);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function testTwoExternals() {
|
|
||||||
const externals = [external_1, external_2];
|
|
||||||
const snapshot = WebSnapshot.serialize(object, externals);
|
|
||||||
const replaced_externals = [{replacement:1}, {replacement:2}]
|
|
||||||
const deserialized = WebSnapshot.deserialize(snapshot, replaced_externals);
|
|
||||||
%HeapObjectVerify(deserialized);
|
|
||||||
assertEquals(object.a, deserialized.a);
|
|
||||||
assertSame(deserialized.b, replaced_externals[0]);
|
|
||||||
assertArrayEquals(replaced_externals, deserialized.c);
|
|
||||||
assertSame(replaced_externals[0], deserialized.c[0]);
|
|
||||||
assertSame(replaced_externals[1], deserialized.c[1]);
|
|
||||||
assertSame(replaced_externals[1], deserialized.d.d_a);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function testApiObject() {
|
|
||||||
const api_object = new d8.dom.Div();
|
|
||||||
const source_1 = [{}, api_object];
|
|
||||||
assertThrows(() => WebSnapshot.serialize(source_1));
|
|
||||||
|
|
||||||
let externals = [external_1]
|
|
||||||
const source_2 = [{}, external_1, api_object, api_object];
|
|
||||||
const snapshot_2 = WebSnapshot.serialize(source_2, externals);
|
|
||||||
%HeapObjectVerify(externals);
|
|
||||||
// Check that the unhandled api object is added to the externals.
|
|
||||||
assertArrayEquals([external_1, api_object], externals);
|
|
||||||
|
|
||||||
assertThrows(() => WebSnapshot.deserialize(snapshot_2));
|
|
||||||
assertThrows(() => WebSnapshot.deserialize(snapshot_2, []));
|
|
||||||
assertThrows(() => WebSnapshot.deserialize(snapshot_2, [external_1]));
|
|
||||||
|
|
||||||
const result_2 = WebSnapshot.deserialize(snapshot_2, [external_1, api_object]);
|
|
||||||
%HeapObjectVerify(externals);
|
|
||||||
%HeapObjectVerify(result_2);
|
|
||||||
assertArrayEquals(source_2, result_2);
|
|
||||||
assertNotSame(source_2[0], result_2[0]);
|
|
||||||
assertSame(external_1, result_2[1]);
|
|
||||||
assertSame(api_object, result_2[2]);
|
|
||||||
assertSame(api_object, result_2[3]);
|
|
||||||
})();
|
|
@ -1,444 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestFunctionWithContext() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
key: (function () {
|
|
||||||
let result = 'bar';
|
|
||||||
function inner() { return result; }
|
|
||||||
return inner;
|
|
||||||
})(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('bar', foo.key());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestInnerFunctionWithContextAndParentContext() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
key: (function () {
|
|
||||||
let part1 = 'snap';
|
|
||||||
function inner() {
|
|
||||||
let part2 = 'shot';
|
|
||||||
function innerinner() {
|
|
||||||
return part1 + part2;
|
|
||||||
}
|
|
||||||
return innerinner;
|
|
||||||
}
|
|
||||||
return inner();
|
|
||||||
})()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('snapshot', foo.key());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestTopLevelFunctionWithContext() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = (function () {
|
|
||||||
let result = 'bar';
|
|
||||||
function inner() { return result; }
|
|
||||||
return inner;
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('bar', foo());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestContextTree() {
|
|
||||||
function createObjects() {
|
|
||||||
(function outer() {
|
|
||||||
let a = 10;
|
|
||||||
let b = 20;
|
|
||||||
(function inner1() {
|
|
||||||
let c = 5;
|
|
||||||
globalThis.f1 = function() { return a + b + c; };
|
|
||||||
})();
|
|
||||||
(function inner2() {
|
|
||||||
let d = 10;
|
|
||||||
globalThis.f2 = function() { return a - b - d; };
|
|
||||||
})();
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
const {f1, f2} = takeAndUseWebSnapshot(createObjects, ['f1', 'f2']);
|
|
||||||
assertEquals(35, f1());
|
|
||||||
assertEquals(-20, f2());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestContextReferringToFunction() {
|
|
||||||
function createObjects() {
|
|
||||||
(function outer() {
|
|
||||||
let a = function() { return 10; }
|
|
||||||
globalThis.f = function() { return a(); };
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
const {f} = takeAndUseWebSnapshot(createObjects, ['f']);
|
|
||||||
assertEquals(10, f());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestNonInlinedScopeInfoInContext() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.bar = (function() {
|
|
||||||
let a1 = 1;
|
|
||||||
let a2 = 1;
|
|
||||||
let a3 = 1;
|
|
||||||
let a4 = 1;
|
|
||||||
let a5 = 1;
|
|
||||||
let a6 = 1;
|
|
||||||
let a7 = 1;
|
|
||||||
let a8 = 1;
|
|
||||||
let a9 = 1;
|
|
||||||
let a10 = 1;
|
|
||||||
let a11 = 1;
|
|
||||||
let a12 = 1;
|
|
||||||
let a13 = 1;
|
|
||||||
let a14 = 1;
|
|
||||||
let a15 = 1;
|
|
||||||
let a16 = 1;
|
|
||||||
let a17 = 1;
|
|
||||||
let a18 = 1;
|
|
||||||
let a19 = 1;
|
|
||||||
let a20 = 1;
|
|
||||||
let a21 = 1;
|
|
||||||
let a22 = 1;
|
|
||||||
let a23 = 1;
|
|
||||||
let a24 = 1;
|
|
||||||
let a25 = 1;
|
|
||||||
let a26 = 1;
|
|
||||||
let a27 = 1;
|
|
||||||
let a28 = 1;
|
|
||||||
let a29 = 1;
|
|
||||||
let a30 = 1;
|
|
||||||
let a31 = 1;
|
|
||||||
let a32 = 1;
|
|
||||||
let a33 = 1;
|
|
||||||
let a34 = 1;
|
|
||||||
let a35 = 1;
|
|
||||||
let a36 = 1;
|
|
||||||
let a37 = 1;
|
|
||||||
let a38 = 1;
|
|
||||||
let a39 = 1;
|
|
||||||
let a40 = 1;
|
|
||||||
let a41 = 1;
|
|
||||||
let a42 = 1;
|
|
||||||
let a43 = 1;
|
|
||||||
let a44 = 1;
|
|
||||||
let a45 = 1;
|
|
||||||
let a46 = 1;
|
|
||||||
let a47 = 1;
|
|
||||||
let a48 = 1;
|
|
||||||
let a49 = 1;
|
|
||||||
let a50 = 1;
|
|
||||||
let a51 = 1;
|
|
||||||
let a52 = 1;
|
|
||||||
let a53 = 1;
|
|
||||||
let a54 = 1;
|
|
||||||
let a55 = 1;
|
|
||||||
let a56 = 1;
|
|
||||||
let a57 = 1;
|
|
||||||
let a58 = 1;
|
|
||||||
let a59 = 1;
|
|
||||||
let a60 = 1;
|
|
||||||
let a61 = 1;
|
|
||||||
let a62 = 1;
|
|
||||||
let a63 = 1;
|
|
||||||
let a64 = 1;
|
|
||||||
let a65 = 1;
|
|
||||||
let a66 = 1;
|
|
||||||
let a67 = 1;
|
|
||||||
let a68 = 1;
|
|
||||||
let a69 = 1;
|
|
||||||
let a70 = 1;
|
|
||||||
let a71 = 1;
|
|
||||||
let a72 = 1;
|
|
||||||
let a73 = 1;
|
|
||||||
let a74 = 1;
|
|
||||||
let a75 = 1;
|
|
||||||
function inner1() {
|
|
||||||
return a1;
|
|
||||||
}
|
|
||||||
function inner2() {
|
|
||||||
return a2;
|
|
||||||
}
|
|
||||||
function inner3() {
|
|
||||||
return a3;
|
|
||||||
}
|
|
||||||
function inner4() {
|
|
||||||
return a4;
|
|
||||||
}
|
|
||||||
function inner5() {
|
|
||||||
return a5;
|
|
||||||
}
|
|
||||||
function inner6() {
|
|
||||||
return a6;
|
|
||||||
}
|
|
||||||
function inner7() {
|
|
||||||
return a7;
|
|
||||||
}
|
|
||||||
function inner8() {
|
|
||||||
return a8;
|
|
||||||
}
|
|
||||||
function inner9() {
|
|
||||||
return a9;
|
|
||||||
}
|
|
||||||
function inner10() {
|
|
||||||
return a10;
|
|
||||||
}
|
|
||||||
function inner11() {
|
|
||||||
return a11;
|
|
||||||
}
|
|
||||||
function inner12() {
|
|
||||||
return a12;
|
|
||||||
}
|
|
||||||
function inner13() {
|
|
||||||
return a13;
|
|
||||||
}
|
|
||||||
function inner14() {
|
|
||||||
return a14;
|
|
||||||
}
|
|
||||||
function inner15() {
|
|
||||||
return a15;
|
|
||||||
}
|
|
||||||
function inner16() {
|
|
||||||
return a16;
|
|
||||||
}
|
|
||||||
function inner17() {
|
|
||||||
return a17;
|
|
||||||
}
|
|
||||||
function inner18() {
|
|
||||||
return a18;
|
|
||||||
}
|
|
||||||
function inner19() {
|
|
||||||
return a19;
|
|
||||||
}
|
|
||||||
function inner20() {
|
|
||||||
return a20;
|
|
||||||
}
|
|
||||||
function inner21() {
|
|
||||||
return a21;
|
|
||||||
}
|
|
||||||
function inner22() {
|
|
||||||
return a22;
|
|
||||||
}
|
|
||||||
function inner23() {
|
|
||||||
return a23;
|
|
||||||
}
|
|
||||||
function inner24() {
|
|
||||||
return a24;
|
|
||||||
}
|
|
||||||
function inner25() {
|
|
||||||
return a25;
|
|
||||||
}
|
|
||||||
function inner26() {
|
|
||||||
return a26;
|
|
||||||
}
|
|
||||||
function inner27() {
|
|
||||||
return a27;
|
|
||||||
}
|
|
||||||
function inner28() {
|
|
||||||
return a28;
|
|
||||||
}
|
|
||||||
function inner29() {
|
|
||||||
return a29;
|
|
||||||
}
|
|
||||||
function inner30() {
|
|
||||||
return a30;
|
|
||||||
}
|
|
||||||
function inner31() {
|
|
||||||
return a31;
|
|
||||||
}
|
|
||||||
function inner32() {
|
|
||||||
return a32;
|
|
||||||
}
|
|
||||||
function inner33() {
|
|
||||||
return a33;
|
|
||||||
}
|
|
||||||
function inner34() {
|
|
||||||
return a34;
|
|
||||||
}
|
|
||||||
function inner35() {
|
|
||||||
return a35;
|
|
||||||
}
|
|
||||||
function inner36() {
|
|
||||||
return a36;
|
|
||||||
}
|
|
||||||
function inner37() {
|
|
||||||
return a37;
|
|
||||||
}
|
|
||||||
function inner38() {
|
|
||||||
return a38;
|
|
||||||
}
|
|
||||||
function inner39() {
|
|
||||||
return a39;
|
|
||||||
}
|
|
||||||
function inner40() {
|
|
||||||
return a40;
|
|
||||||
}
|
|
||||||
function inner41() {
|
|
||||||
return a41;
|
|
||||||
}
|
|
||||||
function inner42() {
|
|
||||||
return a42;
|
|
||||||
}
|
|
||||||
function inner43() {
|
|
||||||
return a43;
|
|
||||||
}
|
|
||||||
function inner44() {
|
|
||||||
return a44;
|
|
||||||
}
|
|
||||||
function inner45() {
|
|
||||||
return a45;
|
|
||||||
}
|
|
||||||
function inner46() {
|
|
||||||
return a46;
|
|
||||||
}
|
|
||||||
function inner47() {
|
|
||||||
return a47;
|
|
||||||
}
|
|
||||||
function inner48() {
|
|
||||||
return a48;
|
|
||||||
}
|
|
||||||
function inner49() {
|
|
||||||
return a49;
|
|
||||||
}
|
|
||||||
function inner50() {
|
|
||||||
return a50;
|
|
||||||
}
|
|
||||||
function inner51() {
|
|
||||||
return a51;
|
|
||||||
}
|
|
||||||
function inner52() {
|
|
||||||
return a52;
|
|
||||||
}
|
|
||||||
function inner53() {
|
|
||||||
return a53;
|
|
||||||
}
|
|
||||||
function inner54() {
|
|
||||||
return a54;
|
|
||||||
}
|
|
||||||
function inner55() {
|
|
||||||
return a55;
|
|
||||||
}
|
|
||||||
function inner56() {
|
|
||||||
return a56;
|
|
||||||
}
|
|
||||||
function inner57() {
|
|
||||||
return a57;
|
|
||||||
}
|
|
||||||
function inner58() {
|
|
||||||
return a58;
|
|
||||||
}
|
|
||||||
function inner59() {
|
|
||||||
return a59;
|
|
||||||
}
|
|
||||||
function inner60() {
|
|
||||||
return a60;
|
|
||||||
}
|
|
||||||
function inner61() {
|
|
||||||
return a61;
|
|
||||||
}
|
|
||||||
function inner62() {
|
|
||||||
return a62;
|
|
||||||
}
|
|
||||||
function inner63() {
|
|
||||||
return a63;
|
|
||||||
}
|
|
||||||
function inner64() {
|
|
||||||
return a64;
|
|
||||||
}
|
|
||||||
function inner65() {
|
|
||||||
return a65;
|
|
||||||
}
|
|
||||||
function inner66() {
|
|
||||||
return a66;
|
|
||||||
}
|
|
||||||
function inner67() {
|
|
||||||
return a67;
|
|
||||||
}
|
|
||||||
function inner68() {
|
|
||||||
return a68;
|
|
||||||
}
|
|
||||||
function inner69() {
|
|
||||||
return a69;
|
|
||||||
}
|
|
||||||
function inner70() {
|
|
||||||
return a70;
|
|
||||||
}
|
|
||||||
function inner71() {
|
|
||||||
return a71;
|
|
||||||
}
|
|
||||||
function inner72() {
|
|
||||||
return a72;
|
|
||||||
}
|
|
||||||
function inner73() {
|
|
||||||
return a73;
|
|
||||||
}
|
|
||||||
function inner74() {
|
|
||||||
return a74;
|
|
||||||
}
|
|
||||||
function inner75() {
|
|
||||||
return a75;
|
|
||||||
}
|
|
||||||
return inner1;
|
|
||||||
})()
|
|
||||||
}
|
|
||||||
const {bar} = takeAndUseWebSnapshot(createObjects, ['bar']);
|
|
||||||
assertEquals(1, bar());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestMoreThanOneScopeLocalInContext() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = (function() {
|
|
||||||
let result = 'bar';
|
|
||||||
let a = '1';
|
|
||||||
function inner() {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
function inner2() {
|
|
||||||
return a;
|
|
||||||
}
|
|
||||||
return inner;
|
|
||||||
})();
|
|
||||||
}
|
|
||||||
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('bar', foo());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestContextReferencingArray() {
|
|
||||||
function createObjects() {
|
|
||||||
function outer() {
|
|
||||||
let o = [11525];
|
|
||||||
function inner() { return o; }
|
|
||||||
return inner;
|
|
||||||
}
|
|
||||||
globalThis.foo = {
|
|
||||||
func: outer()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(11525, foo.func()[0]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestContextReferencingObject() {
|
|
||||||
function createObjects() {
|
|
||||||
function outer() {
|
|
||||||
let o = { value: 11525 };
|
|
||||||
function inner() { return o; }
|
|
||||||
return inner;
|
|
||||||
}
|
|
||||||
globalThis.foo = {
|
|
||||||
func: outer()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(11525, foo.func().value);
|
|
||||||
})();
|
|
@ -1,270 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestFunction() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
key: function () { return 'bar'; },
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('bar', foo.key());
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestOptimizingFunctionFromSnapshot() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.f = function(a, b) { return a + b; }
|
|
||||||
}
|
|
||||||
const { f } = takeAndUseWebSnapshot(createObjects, ['f']);
|
|
||||||
%PrepareFunctionForOptimization(f);
|
|
||||||
assertEquals(3, f(1, 2));
|
|
||||||
%OptimizeFunctionOnNextCall(f);
|
|
||||||
assertEquals(4, f(1, 3));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestOptimizingConstructorFromSnapshot() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.C = class {
|
|
||||||
constructor(a, b) {
|
|
||||||
this.x = a + b;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const { C } = takeAndUseWebSnapshot(createObjects, ['C']);
|
|
||||||
%PrepareFunctionForOptimization(C);
|
|
||||||
assertEquals(3, new C(1, 2).x);
|
|
||||||
%OptimizeFunctionOnNextCall(C);
|
|
||||||
assertEquals(4, new C(1, 3).x);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestFunctionPrototype() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.F = function(p1, p2) {
|
|
||||||
this.x = p1 + p2;
|
|
||||||
}
|
|
||||||
globalThis.F.prototype.m = function(p1, p2) {
|
|
||||||
return this.x + p1 + p2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const { F } = takeAndUseWebSnapshot(createObjects, ['F']);
|
|
||||||
const o = new F(1, 2);
|
|
||||||
assertEquals(3, o.x);
|
|
||||||
assertEquals(10, o.m(3, 4));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestFunctionPrototypeBecomesProto() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.F = function() {}
|
|
||||||
globalThis.F.prototype.x = 100;
|
|
||||||
}
|
|
||||||
const { F } = takeAndUseWebSnapshot(createObjects, ['F']);
|
|
||||||
const o = new F();
|
|
||||||
assertEquals(100, Object.getPrototypeOf(o).x);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestFunctionCtorCallsFunctionInPrototype() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.F = function() {
|
|
||||||
this.fooCalled = false;
|
|
||||||
this.foo();
|
|
||||||
}
|
|
||||||
globalThis.F.prototype.foo = function() { this.fooCalled = true; };
|
|
||||||
}
|
|
||||||
const { F } = takeAndUseWebSnapshot(createObjects, ['F']);
|
|
||||||
const o = new F();
|
|
||||||
assertTrue(o.fooCalled);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestFunctionPrototypeConnectedToObjectPrototype() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.F = function() {}
|
|
||||||
}
|
|
||||||
const realm = Realm.create();
|
|
||||||
const { F } = takeAndUseWebSnapshot(createObjects, ['F'], realm);
|
|
||||||
const o = new F();
|
|
||||||
assertSame(Realm.eval(realm, 'Object.prototype'),
|
|
||||||
Object.getPrototypeOf(Object.getPrototypeOf(o)));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestFunctionInheritance() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.Super = function() {}
|
|
||||||
globalThis.Super.prototype.superfunc = function() { return 'superfunc'; };
|
|
||||||
globalThis.Sub = function() {}
|
|
||||||
globalThis.Sub.prototype = Object.create(Super.prototype);
|
|
||||||
globalThis.Sub.prototype.subfunc = function() { return 'subfunc'; };
|
|
||||||
}
|
|
||||||
const realm = Realm.create();
|
|
||||||
const { Sub, Super } =
|
|
||||||
takeAndUseWebSnapshot(createObjects, ['Sub', 'Super'], realm);
|
|
||||||
const o = new Sub();
|
|
||||||
assertEquals('superfunc', o.superfunc());
|
|
||||||
assertEquals('subfunc', o.subfunc());
|
|
||||||
assertSame(Super.prototype, Sub.prototype.__proto__);
|
|
||||||
const realmFunctionPrototype = Realm.eval(realm, 'Function.prototype');
|
|
||||||
assertSame(realmFunctionPrototype, Super.__proto__);
|
|
||||||
assertSame(realmFunctionPrototype, Sub.__proto__);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestFunctionKinds() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.normalFunction = function() {}
|
|
||||||
globalThis.asyncFunction = async function() {}
|
|
||||||
globalThis.generatorFunction = function*() {}
|
|
||||||
globalThis.asyncGeneratorFunction = async function*() {}
|
|
||||||
}
|
|
||||||
const realm = Realm.create();
|
|
||||||
const {normalFunction, asyncFunction, generatorFunction,
|
|
||||||
asyncGeneratorFunction} =
|
|
||||||
takeAndUseWebSnapshot(createObjects, ['normalFunction', 'asyncFunction',
|
|
||||||
'generatorFunction', 'asyncGeneratorFunction'], realm);
|
|
||||||
const newNormalFunction = Realm.eval(realm, 'f1 = function() {}');
|
|
||||||
const newAsyncFunction = Realm.eval(realm, 'f2 = async function() {}');
|
|
||||||
const newGeneratorFunction = Realm.eval(realm, 'f3 = function*() {}');
|
|
||||||
const newAsyncGeneratorFunction =
|
|
||||||
Realm.eval(realm, 'f4 = async function*() {}');
|
|
||||||
|
|
||||||
assertSame(newNormalFunction.__proto__, normalFunction.__proto__);
|
|
||||||
assertSame(newNormalFunction.prototype.__proto__,
|
|
||||||
normalFunction.prototype.__proto__);
|
|
||||||
|
|
||||||
assertSame(newAsyncFunction.__proto__, asyncFunction.__proto__);
|
|
||||||
assertEquals(undefined, asyncFunction.prototype);
|
|
||||||
assertEquals(undefined, newAsyncFunction.prototype);
|
|
||||||
|
|
||||||
assertSame(newGeneratorFunction.__proto__, generatorFunction.__proto__);
|
|
||||||
assertSame(newGeneratorFunction.prototype.__proto__,
|
|
||||||
generatorFunction.prototype.__proto__);
|
|
||||||
|
|
||||||
assertSame(newAsyncGeneratorFunction.__proto__,
|
|
||||||
asyncGeneratorFunction.__proto__);
|
|
||||||
assertSame(newAsyncGeneratorFunction.prototype.__proto__,
|
|
||||||
asyncGeneratorFunction.prototype.__proto__);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestFunctionWithProperties() {
|
|
||||||
function createObjects() {
|
|
||||||
function bar() { return 'bar'; };
|
|
||||||
bar.key1 = 'value1';
|
|
||||||
bar.key2 = 1;
|
|
||||||
bar.key3 = 2.2;
|
|
||||||
bar.key4 = function key4() {
|
|
||||||
return 'key4';
|
|
||||||
}
|
|
||||||
bar.key5 = [1, 2];
|
|
||||||
bar.key6 = {'key':'value'}
|
|
||||||
globalThis.foo = {
|
|
||||||
bar: bar,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('bar', foo.bar());
|
|
||||||
assertEquals('value1', foo.bar.key1);
|
|
||||||
assertEquals(1, foo.bar.key2);
|
|
||||||
assertEquals(2.2, foo.bar.key3);
|
|
||||||
assertEquals('key4', foo.bar.key4());
|
|
||||||
assertEquals([1, 2], foo.bar.key5);
|
|
||||||
assertEquals({ 'key': 'value' }, foo.bar.key6 );
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestAsyncFunctionWithProperties() {
|
|
||||||
function createObjects() {
|
|
||||||
async function bar() { return 'bar'; };
|
|
||||||
bar.key1 = 'value1';
|
|
||||||
bar.key2 = 1;
|
|
||||||
bar.key3 = 2.2;
|
|
||||||
bar.key4 = function key4() {
|
|
||||||
return 'key4';
|
|
||||||
}
|
|
||||||
bar.key5 = [1, 2];
|
|
||||||
bar.key6 = {'key':'value'}
|
|
||||||
globalThis.foo = {
|
|
||||||
bar: bar,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('value1', foo.bar.key1);
|
|
||||||
assertEquals(1, foo.bar.key2);
|
|
||||||
assertEquals(2.2, foo.bar.key3);
|
|
||||||
assertEquals('key4', foo.bar.key4());
|
|
||||||
assertEquals([1, 2], foo.bar.key5);
|
|
||||||
assertEquals({'key': 'value'}, foo.bar.key6 );
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestGeneratorFunctionWithProperties() {
|
|
||||||
function createObjects() {
|
|
||||||
function *bar() { return 'bar'; };
|
|
||||||
bar.key1 = 'value1';
|
|
||||||
bar.key2 = 1;
|
|
||||||
bar.key3 = 2.2;
|
|
||||||
bar.key4 = function key4() {
|
|
||||||
return 'key4';
|
|
||||||
};
|
|
||||||
bar.key5 = [1, 2];
|
|
||||||
bar.key6 = {'key':'value'};
|
|
||||||
globalThis.foo = {
|
|
||||||
bar: bar,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('value1', foo.bar.key1);
|
|
||||||
assertEquals(1, foo.bar.key2);
|
|
||||||
assertEquals(2.2, foo.bar.key3);
|
|
||||||
assertEquals('key4', foo.bar.key4());
|
|
||||||
assertEquals([1, 2], foo.bar.key5);
|
|
||||||
assertEquals({'key': 'value'}, foo.bar.key6 );
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestAsyncGeneratorFunctionWithProperties() {
|
|
||||||
function createObjects() {
|
|
||||||
async function *bar() { return 'bar'; };
|
|
||||||
bar.key1 = 'value1';
|
|
||||||
bar.key2 = 1;
|
|
||||||
bar.key3 = 2.2;
|
|
||||||
bar.key4 = function key4() {
|
|
||||||
return 'key4';
|
|
||||||
}
|
|
||||||
bar.key5 = [1, 2];
|
|
||||||
bar.key6 = {'key':'value'}
|
|
||||||
globalThis.foo = {
|
|
||||||
bar: bar,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('value1', foo.bar.key1);
|
|
||||||
assertEquals(1, foo.bar.key2);
|
|
||||||
assertEquals(2.2, foo.bar.key3);
|
|
||||||
assertEquals('key4', foo.bar.key4());
|
|
||||||
assertEquals([1, 2], foo.bar.key5);
|
|
||||||
assertEquals({'key': 'value'}, foo.bar.key6);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestFunctionsWithSameMap() {
|
|
||||||
function createObjects() {
|
|
||||||
function bar1() { return 'bar1'; };
|
|
||||||
bar1.key = 'value';
|
|
||||||
|
|
||||||
function bar2() {
|
|
||||||
return 'bar2';
|
|
||||||
}
|
|
||||||
bar2.key = 'value';
|
|
||||||
|
|
||||||
globalThis.foo = {
|
|
||||||
bar1: bar1,
|
|
||||||
bar2: bar2
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals('bar1', foo.bar1());
|
|
||||||
assertEquals('value', foo.bar1.key);
|
|
||||||
assertEquals('bar2', foo.bar2());
|
|
||||||
assertEquals('value', foo.bar2.key);
|
|
||||||
assertTrue(%HaveSameMap(foo.bar1, foo.bar2))
|
|
||||||
})();
|
|
@ -1,25 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
function use(exports) {
|
|
||||||
const result = Object.create(null);
|
|
||||||
exports.forEach(x => result[x] = globalThis[x]);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
function takeAndUseWebSnapshot(createObjects, exports, realmForDeserializing) {
|
|
||||||
// Take a snapshot in Realm r1.
|
|
||||||
const r1 = Realm.create();
|
|
||||||
Realm.eval(r1, createObjects, { type: 'function' });
|
|
||||||
const snapshot = Realm.takeWebSnapshot(r1, exports);
|
|
||||||
// Use the snapshot in Realm r2.
|
|
||||||
const r2 = realmForDeserializing != undefined ?
|
|
||||||
realmForDeserializing : Realm.create();
|
|
||||||
const success = Realm.useWebSnapshot(r2, snapshot);
|
|
||||||
assertTrue(success);
|
|
||||||
const result =
|
|
||||||
Realm.eval(r2, use, { type: 'function', arguments: [exports] });
|
|
||||||
%HeapObjectVerify(result);
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestHoleySmiElementsArray() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = [1,,2];
|
|
||||||
}
|
|
||||||
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([1,,2], foo);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestHoleyElementsArray() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = [1,,'123'];
|
|
||||||
}
|
|
||||||
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([1,,'123'], foo);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestHoleyArrayContainingDoubleAndSmi() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = [1.2, , 1];
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([1.2, , 1], foo);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestHoleyArrayContainingDoubleAndObject() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = [1.2, , {'key': 'value'}];
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([1.2, , {'key': 'value'}], foo);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestHoleyDoubleElementsArray() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = [1.2, , 2.3];
|
|
||||||
}
|
|
||||||
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals([1.2, , 2.3], foo);
|
|
||||||
})();
|
|
@ -1,204 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestObjectReferencingObject() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
bar: { baz: 11525 }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(11525, foo.bar.baz);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestInPlaceStringsInObject() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {a: 'foo', b: 'bar', c: 'baz'};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
// We cannot test that the strings are really in-place; that's covered by
|
|
||||||
// cctests.
|
|
||||||
assertEquals('foobarbaz', foo.a + foo.b + foo.c);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestRepeatedInPlaceStringsInObject() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {a: 'foo', b: 'bar', c: 'foo'};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
// We cannot test that the strings are really in-place; that's covered by
|
|
||||||
// cctests.
|
|
||||||
assertEquals('foobarfoo', foo.a + foo.b + foo.c);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectWithPackedElements() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
'0': 'zero', '1': 'one', '2': 'two', '3': 'three'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
// Objects always get HOLEY_ELEMENTS; no PACKED or SMI_ELEMENTS.
|
|
||||||
const elementsKindTest = {0: 0, 1: 1, 2: 2};
|
|
||||||
assertFalse(%HasPackedElements(elementsKindTest));
|
|
||||||
assertFalse(%HasSmiElements(elementsKindTest));
|
|
||||||
|
|
||||||
assertFalse(%HasPackedElements(foo));
|
|
||||||
assertFalse(%HasSmiElements(foo));
|
|
||||||
assertEquals('zeroonetwothree', foo[0] + foo[1] + foo[2] + foo[3]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectWithPackedSmiElements() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
'0': 0, '1': 1, '2': 2, '3': 3
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertFalse(%HasPackedElements(foo));
|
|
||||||
assertFalse(%HasSmiElements(foo));
|
|
||||||
assertEquals('0123', '' + foo[0] + foo[1] + foo[2] + foo[3]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectWithHoleyElements() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
'1': 'a', '11': 'b', '111': 'c'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertFalse(%HasPackedElements(foo));
|
|
||||||
assertFalse(%HasSmiElements(foo));
|
|
||||||
assertEquals('abc', foo[1] + foo[11] + foo[111]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectWithHoleySmiElements() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
'1': 0, '11': 1, '111': 2
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertFalse(%HasPackedElements(foo));
|
|
||||||
assertFalse(%HasSmiElements(foo));
|
|
||||||
assertEquals('012', '' + foo[1] + foo[11] + foo[111]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectWithPropertiesAndElements() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
'prop1': 'value1', '1': 'a', 'prop2': 'value2', '11': 'b', '111': 'c'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertFalse(%HasPackedElements(foo));
|
|
||||||
assertFalse(%HasSmiElements(foo));
|
|
||||||
assertEquals('abc', foo[1] + foo[11] + foo[111]);
|
|
||||||
assertEquals('value1value2', foo.prop1 + foo.prop2);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectsWithSamePropertiesButDifferentElementsKind() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
'prop1': 'value1', 'prop2': 'value2', '1': 'a', '11': 'b', '111': 'c'
|
|
||||||
};
|
|
||||||
globalThis.bar = {
|
|
||||||
'prop1': 'value1', 'prop2': 'value2', '0': 0, '1': 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const { foo, bar } = takeAndUseWebSnapshot(createObjects, ['foo', 'bar']);
|
|
||||||
assertFalse(%HasPackedElements(foo));
|
|
||||||
assertFalse(%HasSmiElements(foo));
|
|
||||||
assertEquals('abc', foo[1] + foo[11] + foo[111]);
|
|
||||||
assertEquals('value1value2', foo.prop1 + foo.prop2);
|
|
||||||
assertFalse(%HasPackedElements(bar));
|
|
||||||
assertFalse(%HasSmiElements(bar));
|
|
||||||
assertEquals('00', '' + bar[0] + bar[1]);
|
|
||||||
assertEquals('value1value2', bar.prop1 + bar.prop2);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectWithEmptyMap() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = [{a:1}, {}, {b: 2}];
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(1, foo[0].a);
|
|
||||||
assertEquals(2, foo[2].b);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectWithDictionaryMap() {
|
|
||||||
function createObjects() {
|
|
||||||
const obj = {};
|
|
||||||
// Create an object with dictionary map.
|
|
||||||
for (let i = 0; i < 2000; i++){
|
|
||||||
obj[`key${i}`] = `value${i}`;
|
|
||||||
}
|
|
||||||
globalThis.foo = obj;
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(2000, Object.keys(foo).length);
|
|
||||||
assertEquals(2000, Object.values(foo).length);
|
|
||||||
for (let i = 0; i < 2000; i++){
|
|
||||||
assertEquals(`value${i}`, foo[`key${i}`]);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TwoExportedObjects() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.one = {x: 1};
|
|
||||||
globalThis.two = {x: 2};
|
|
||||||
}
|
|
||||||
const { one, two } = takeAndUseWebSnapshot(createObjects, ['one', 'two']);
|
|
||||||
assertEquals(1, one.x);
|
|
||||||
assertEquals(2, two.x);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectWithDictionaryElements() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.obj = {
|
|
||||||
10: 1,
|
|
||||||
100: 2,
|
|
||||||
1000: 3,
|
|
||||||
10000: 4
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { obj } = takeAndUseWebSnapshot(createObjects, ['obj']);
|
|
||||||
assertEquals(['10', '100', '1000', '10000'], Object.getOwnPropertyNames(obj));
|
|
||||||
assertEquals[1, obj[10]];
|
|
||||||
assertEquals[2, obj[100]];
|
|
||||||
assertEquals[3, obj[1000]];
|
|
||||||
assertEquals[4, obj[10000]];
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectWithDictionaryElementsWithLargeIndex() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.obj = {};
|
|
||||||
globalThis.obj[4394967296] = 'lol';
|
|
||||||
}
|
|
||||||
const { obj } = takeAndUseWebSnapshot(createObjects, ['obj']);
|
|
||||||
assertEquals(['4394967296'], Object.getOwnPropertyNames(obj));
|
|
||||||
assertEquals['lol', obj[4394967296]];
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectWithSlackElements() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {};
|
|
||||||
globalThis.bar = {};
|
|
||||||
for (let i = 0; i < 100; ++i) {
|
|
||||||
globalThis.foo[i] = i;
|
|
||||||
globalThis.bar[i] = {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const { foo, bar } = takeAndUseWebSnapshot(createObjects, ['foo', 'bar']);
|
|
||||||
for (let i = 0; i < 100; ++i) {
|
|
||||||
assertEquals(i, foo[i]);
|
|
||||||
assertEquals({}, bar[i]);
|
|
||||||
}
|
|
||||||
})();
|
|
@ -1,105 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestObjectPrototype() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.obj = {a: 1, __proto__: {x: 1}};
|
|
||||||
}
|
|
||||||
const realm = Realm.create();
|
|
||||||
const {obj} = takeAndUseWebSnapshot(createObjects, ['obj'], realm);
|
|
||||||
assertEquals(1, obj.x);
|
|
||||||
assertEquals(1, obj.__proto__.x);
|
|
||||||
assertSame(Realm.eval(realm, 'Object.prototype'), obj.__proto__.__proto__);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestEmptyObjectPrototype() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.obj = {__proto__: {x: 1}};
|
|
||||||
}
|
|
||||||
const realm = Realm.create();
|
|
||||||
const {obj} = takeAndUseWebSnapshot(createObjects, ['obj'], realm);
|
|
||||||
assertEquals(1, obj.x);
|
|
||||||
assertEquals(1, obj.__proto__.x);
|
|
||||||
assertSame(Realm.eval(realm, 'Object.prototype'), obj.__proto__.__proto__);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestDictionaryObjectPrototype() {
|
|
||||||
function createObjects() {
|
|
||||||
const obj = {};
|
|
||||||
// Create an object with dictionary map.
|
|
||||||
for (let i = 0; i < 2000; i++){
|
|
||||||
obj[`key${i}`] = `value${i}`;
|
|
||||||
}
|
|
||||||
obj.__proto__ = {x: 1};
|
|
||||||
globalThis.foo = obj;
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(2000, Object.keys(foo).length);
|
|
||||||
assertEquals(2000, Object.values(foo).length);
|
|
||||||
for (let i = 0; i < 2000; i++){
|
|
||||||
assertEquals(`value${i}`, foo[`key${i}`]);
|
|
||||||
}
|
|
||||||
assertEquals(1, foo.x);
|
|
||||||
assertEquals(1, foo.__proto__.x);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestNullPrototype() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = Object.create(null);
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(null, Object.getPrototypeOf(foo));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestDefaultObjectProto() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
str: 'hello',
|
|
||||||
n: 42,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const realm = Realm.create();
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo'], realm);
|
|
||||||
assertSame(Realm.eval(realm, 'Object.prototype'), Object.getPrototypeOf(foo));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestEmptyObjectProto() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {};
|
|
||||||
}
|
|
||||||
const realm = Realm.create();
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo'], realm);
|
|
||||||
assertSame(Realm.eval(realm, 'Object.prototype'), Object.getPrototypeOf(foo));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectProto() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.foo = {
|
|
||||||
__proto__ : {x : 10},
|
|
||||||
y: 11
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertEquals(10, Object.getPrototypeOf(foo).x);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestObjectProtoInSnapshot() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.o1 = { x: 10};
|
|
||||||
globalThis.o2 = {
|
|
||||||
__proto__ : o1,
|
|
||||||
y: 11
|
|
||||||
};
|
|
||||||
}
|
|
||||||
const realm = Realm.create();
|
|
||||||
const { o1, o2 } = takeAndUseWebSnapshot(createObjects, ['o1', 'o2'], realm);
|
|
||||||
assertSame(o1, Object.getPrototypeOf(o2));
|
|
||||||
assertSame(Realm.eval(realm, 'Object.prototype'), Object.getPrototypeOf(o1));
|
|
||||||
})();
|
|
@ -1,99 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestDictionaryElementsArray() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = [];
|
|
||||||
// Add a large index to force dictionary elements.
|
|
||||||
array[2 ** 30] = 10;
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
array[i * 101] = i;
|
|
||||||
}
|
|
||||||
globalThis.foo = array;
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertTrue(%HasDictionaryElements(foo));
|
|
||||||
assertEquals(2 ** 30 + 1, foo.length);
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
assertEquals(i, foo[i * 101]);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestDictionaryElementsArrayContainingArray() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = [];
|
|
||||||
// Add a large index to force dictionary elements.
|
|
||||||
array[2 ** 30] = 10;
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
array[i * 101] = [i];
|
|
||||||
}
|
|
||||||
globalThis.foo = array;
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertTrue(%HasDictionaryElements(foo));
|
|
||||||
assertEquals(2 ** 30 + 1, foo.length);
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
assertEquals([i], foo[i * 101]);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestDictionaryElementsArrayContainingObject() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = [];
|
|
||||||
// Add a large index to force dictionary elements.
|
|
||||||
array[2 ** 30] = 10;
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
array[i * 101] = {i: i};
|
|
||||||
}
|
|
||||||
globalThis.foo = array;
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertTrue(%HasDictionaryElements(foo));
|
|
||||||
assertEquals(2 ** 30 + 1, foo.length);
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
assertEquals({i: i}, foo[i * 101]);
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestDictionaryElementsArrayContainingFunction() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = [];
|
|
||||||
// Add a large index to force dictionary elements.
|
|
||||||
array[2 ** 30] = 10;
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
array[i * 101] = function() { return i; };
|
|
||||||
}
|
|
||||||
globalThis.foo = array;
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertTrue(%HasDictionaryElements(foo));
|
|
||||||
assertEquals(2 ** 30 + 1, foo.length);
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
assertEquals(i, foo[i * 101]());
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestDictionaryElementsArrayContainingString() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = [];
|
|
||||||
// Add a large index to force dictionary elements.
|
|
||||||
array[2 ** 30] = 10;
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
array[i * 101] = `${i}`;
|
|
||||||
}
|
|
||||||
globalThis.foo = array;
|
|
||||||
}
|
|
||||||
const { foo } = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertTrue(%HasDictionaryElements(foo));
|
|
||||||
assertEquals(2 ** 30 + 1, foo.length);
|
|
||||||
for (let i = 0; i < 10; i++) {
|
|
||||||
assertEquals(`${i}`, foo[i * 101]);
|
|
||||||
}
|
|
||||||
})();
|
|
@ -1,47 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestNonGlobalSymbol() {
|
|
||||||
function createObjects() {
|
|
||||||
const s = Symbol('description');
|
|
||||||
globalThis.foo = {mySymbol: s, innerObject: { symbolHereToo: s}};
|
|
||||||
}
|
|
||||||
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertSame(foo.mySymbol, foo.innerObject.symbolHereToo);
|
|
||||||
assertEquals('description', foo.mySymbol.description);
|
|
||||||
assertNotEquals(foo.mySymbol, Symbol('description'));
|
|
||||||
assertNotEquals(foo.mySymbol, Symbol.for('description'));
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestGlobalSymbol() {
|
|
||||||
function createObjects() {
|
|
||||||
const s = Symbol.for('this is global');
|
|
||||||
globalThis.foo = {mySymbol: s, innerObject: { symbolHereToo: s}};
|
|
||||||
}
|
|
||||||
const {foo} = takeAndUseWebSnapshot(createObjects, ['foo']);
|
|
||||||
assertSame(foo.mySymbol, foo.innerObject.symbolHereToo);
|
|
||||||
assertEquals('this is global', foo.mySymbol.description);
|
|
||||||
assertEquals(Symbol.for('this is global'), foo.mySymbol);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestSymbolAsMapKey() {
|
|
||||||
function createObjects() {
|
|
||||||
globalThis.obj1 = {};
|
|
||||||
const global_symbol = Symbol.for('this is global');
|
|
||||||
obj1[global_symbol] = 'global symbol value';
|
|
||||||
globalThis.obj2 = {};
|
|
||||||
const nonglobal_symbol = Symbol('this is not global');
|
|
||||||
obj2[nonglobal_symbol] = 'nonglobal symbol value';
|
|
||||||
}
|
|
||||||
const {obj1, obj2} = takeAndUseWebSnapshot(createObjects, ['obj1', 'obj2']);
|
|
||||||
assertEquals('global symbol value', obj1[Symbol.for('this is global')]);
|
|
||||||
const nonglobal_symbol = Object.getOwnPropertySymbols(obj2)[0];
|
|
||||||
assertEquals('nonglobal symbol value', obj2[nonglobal_symbol]);
|
|
||||||
})();
|
|
@ -1,439 +0,0 @@
|
|||||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
// Flags: --experimental-d8-web-snapshot-api --allow-natives-syntax --harmony-rab-gsab --verify-heap
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
d8.file.execute('test/mjsunit/web-snapshot/web-snapshot-helpers.js');
|
|
||||||
|
|
||||||
(function TestTypedArray() {
|
|
||||||
function createObjects() {
|
|
||||||
const int8Array = new Int8Array(3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
int8Array[i] = i;
|
|
||||||
}
|
|
||||||
const uint8Array = new Uint8Array(3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
uint8Array[i] = i;
|
|
||||||
}
|
|
||||||
const uint8ClampedArray = new Uint8ClampedArray(3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
uint8ClampedArray[i] = i;
|
|
||||||
}
|
|
||||||
const int16Array = new Int16Array(3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
int16Array[i] = i;
|
|
||||||
}
|
|
||||||
const uint16Array = new Uint16Array(3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
uint16Array[i] = i;
|
|
||||||
}
|
|
||||||
const int32Array = new Int32Array(3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
int32Array[i] = i;
|
|
||||||
}
|
|
||||||
const uint32Array = new Uint32Array(3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
uint32Array[i] = i;
|
|
||||||
}
|
|
||||||
const float32Array = new Float32Array(3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
float32Array[i] = i + 0.2;
|
|
||||||
}
|
|
||||||
const float64Array = new Float64Array(3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
float64Array[i] = i + 0.2;
|
|
||||||
}
|
|
||||||
const bigInt64Array = new BigInt64Array(3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
bigInt64Array[i] = BigInt(i);
|
|
||||||
}
|
|
||||||
const bigUint64Array = new BigUint64Array(3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
bigUint64Array[i] = BigInt(i);
|
|
||||||
}
|
|
||||||
globalThis.int8Array = int8Array;
|
|
||||||
globalThis.uint8Array = uint8Array;
|
|
||||||
globalThis.uint8ClampedArray = uint8ClampedArray;
|
|
||||||
globalThis.int16Array = int16Array;
|
|
||||||
globalThis.uint16Array = uint16Array;
|
|
||||||
globalThis.int32Array = int32Array;
|
|
||||||
globalThis.uint32Array = uint32Array;
|
|
||||||
globalThis.float32Array = float32Array;
|
|
||||||
globalThis.float64Array = float64Array;
|
|
||||||
globalThis.bigInt64Array = bigInt64Array;
|
|
||||||
globalThis.bigUint64Array = bigUint64Array;
|
|
||||||
}
|
|
||||||
const {
|
|
||||||
int8Array,
|
|
||||||
uint8Array,
|
|
||||||
uint8ClampedArray,
|
|
||||||
int16Array,
|
|
||||||
uint16Array,
|
|
||||||
int32Array,
|
|
||||||
uint32Array,
|
|
||||||
float32Array,
|
|
||||||
float64Array,
|
|
||||||
bigInt64Array,
|
|
||||||
bigUint64Array,
|
|
||||||
} =
|
|
||||||
takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'int8Array',
|
|
||||||
'uint8Array',
|
|
||||||
'uint8ClampedArray',
|
|
||||||
'int16Array',
|
|
||||||
'uint16Array',
|
|
||||||
'int32Array',
|
|
||||||
'uint32Array',
|
|
||||||
'float32Array',
|
|
||||||
'float64Array',
|
|
||||||
'bigInt64Array',
|
|
||||||
'bigUint64Array',
|
|
||||||
]);
|
|
||||||
assertNotSame(globalThis.int8Array, int8Array);
|
|
||||||
assertEquals(int8Array.length, 3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
assertEquals(int8Array[i], i);
|
|
||||||
}
|
|
||||||
assertNotSame(globalThis.uint8Array, uint8Array);
|
|
||||||
assertEquals(uint8Array.length, 3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
assertEquals(uint8Array[i], i);
|
|
||||||
}
|
|
||||||
assertNotSame(globalThis.uint8ClampedArray, uint8ClampedArray);
|
|
||||||
assertEquals(uint8ClampedArray.length, 3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
assertEquals(uint8ClampedArray[i], i);
|
|
||||||
}
|
|
||||||
assertNotSame(globalThis.int16Array, int16Array);
|
|
||||||
assertEquals(int16Array.length, 3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
assertEquals(int16Array[i], i);
|
|
||||||
}
|
|
||||||
assertNotSame(globalThis.uint16Array, uint16Array);
|
|
||||||
assertEquals(uint16Array.length, 3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
assertEquals(uint16Array[i], i);
|
|
||||||
}
|
|
||||||
assertNotSame(globalThis.int32Array, int32Array);
|
|
||||||
assertEquals(int32Array.length, 3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
assertEquals(int32Array[i], i);
|
|
||||||
}
|
|
||||||
assertNotSame(globalThis.uint32Array, uint32Array);
|
|
||||||
assertEquals(uint32Array.length, 3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
assertEquals(uint32Array[i], i);
|
|
||||||
}
|
|
||||||
assertNotSame(globalThis.float32Array, float32Array);
|
|
||||||
assertEquals(float32Array.length, 3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
assertEqualsDelta(float32Array[i], i + 0.2);
|
|
||||||
}
|
|
||||||
assertNotSame(globalThis.float64Array, float64Array);
|
|
||||||
assertEquals(float64Array.length, 3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
assertEqualsDelta(float64Array[i], i + 0.2);
|
|
||||||
}
|
|
||||||
assertNotSame(globalThis.bigInt64Array, bigInt64Array);
|
|
||||||
assertEquals(bigInt64Array.length, 3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
assertEquals(bigInt64Array[i], BigInt(i));
|
|
||||||
}
|
|
||||||
assertNotSame(globalThis.bigUint64Array, bigUint64Array);
|
|
||||||
assertEquals(bigUint64Array.length, 3);
|
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
assertEquals(bigUint64Array[i], BigInt(i));
|
|
||||||
}
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestInt8Array() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = new Int8Array([-129, -128, 1, 127, 128]);
|
|
||||||
globalThis.array = array;
|
|
||||||
const array2 = new Int8Array(array.buffer, 1, 2);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
}
|
|
||||||
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array',
|
|
||||||
'array2',
|
|
||||||
]);
|
|
||||||
assertEquals(array.length, 5);
|
|
||||||
assertEquals(array[0], 127);
|
|
||||||
assertEquals(array[1], -128);
|
|
||||||
assertEquals(array[2], 1);
|
|
||||||
assertEquals(array[3], 127);
|
|
||||||
assertEquals(array[4], -128);
|
|
||||||
assertSame(array.buffer, array2.buffer);
|
|
||||||
assertEquals(array2.length, 2);
|
|
||||||
assertEquals(array2[0], array[1]);
|
|
||||||
assertEquals(array2[1], array[2]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestUint8Array() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = new Uint8Array([-1, 0, 2, 255, 256]);
|
|
||||||
globalThis.array = array;
|
|
||||||
const array2 = new Uint8Array(array.buffer, 1, 2);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
}
|
|
||||||
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array',
|
|
||||||
'array2',
|
|
||||||
]);
|
|
||||||
assertEquals(array.length, 5);
|
|
||||||
assertEquals(array[0], 255);
|
|
||||||
assertEquals(array[1], 0);
|
|
||||||
assertEquals(array[2], 2);
|
|
||||||
assertEquals(array[3], 255);
|
|
||||||
assertEquals(array[4], 0);
|
|
||||||
assertSame(array.buffer, array2.buffer);
|
|
||||||
assertEquals(array2.length, 2);
|
|
||||||
assertEquals(array2[0], array[1]);
|
|
||||||
assertEquals(array2[1], array[2]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestUint8ClampedArray() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = new Uint8ClampedArray([-1, 0, 2, 255, 256]);
|
|
||||||
globalThis.array = array;
|
|
||||||
const array2 = new Uint8ClampedArray(array.buffer, 1, 2);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
}
|
|
||||||
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array',
|
|
||||||
'array2',
|
|
||||||
]);
|
|
||||||
assertEquals(array.length, 5);
|
|
||||||
assertEquals(array[0], 0);
|
|
||||||
assertEquals(array[1], 0);
|
|
||||||
assertEquals(array[2], 2);
|
|
||||||
assertEquals(array[3], 255);
|
|
||||||
assertEquals(array[4], 255);
|
|
||||||
assertSame(array.buffer, array2.buffer);
|
|
||||||
assertEquals(array2.length, 2);
|
|
||||||
assertEquals(array2[0], array[1]);
|
|
||||||
assertEquals(array2[1], array[2]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestInt16Array() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = new Int16Array([-32769, -32768, 1, 32767, 32768]);
|
|
||||||
globalThis.array = array;
|
|
||||||
const array2 = new Int16Array(array.buffer, 2, 2);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
}
|
|
||||||
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array',
|
|
||||||
'array2',
|
|
||||||
]);
|
|
||||||
assertEquals(array.length, 5);
|
|
||||||
assertEquals(array[0], 32767);
|
|
||||||
assertEquals(array[1], -32768);
|
|
||||||
assertEquals(array[2], 1);
|
|
||||||
assertEquals(array[3], 32767);
|
|
||||||
assertEquals(array[4], -32768);
|
|
||||||
assertSame(array.buffer, array2.buffer);
|
|
||||||
assertEquals(array2.length, 2);
|
|
||||||
assertEquals(array2[0], array[1]);
|
|
||||||
assertEquals(array2[1], array[2]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestUint16Array() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = new Uint16Array([-1, 0, 2, 65535, 65536]);
|
|
||||||
globalThis.array = array;
|
|
||||||
const array2 = new Uint16Array(array.buffer, 2, 2);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
}
|
|
||||||
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array',
|
|
||||||
'array2',
|
|
||||||
]);
|
|
||||||
assertEquals(array.length, 5);
|
|
||||||
assertEquals(array[0], 65535);
|
|
||||||
assertEquals(array[1], 0);
|
|
||||||
assertEquals(array[2], 2);
|
|
||||||
assertEquals(array[3], 65535);
|
|
||||||
assertEquals(array[4], 0);
|
|
||||||
assertSame(array.buffer, array2.buffer);
|
|
||||||
assertEquals(array2.length, 2);
|
|
||||||
assertEquals(array2[0], array[1]);
|
|
||||||
assertEquals(array2[1], array[2]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestInt32Array() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = new Int32Array([
|
|
||||||
-2147483649,
|
|
||||||
-2147483648,
|
|
||||||
1,
|
|
||||||
2147483647,
|
|
||||||
2147483648,
|
|
||||||
]);
|
|
||||||
globalThis.array = array;
|
|
||||||
const array2 = new Int32Array(array.buffer, 4, 2);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
}
|
|
||||||
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array',
|
|
||||||
'array2',
|
|
||||||
]);
|
|
||||||
assertEquals(array.length, 5);
|
|
||||||
assertEquals(array[0], 2147483647);
|
|
||||||
assertEquals(array[1], -2147483648);
|
|
||||||
assertEquals(array[2], 1);
|
|
||||||
assertEquals(array[3], 2147483647);
|
|
||||||
assertEquals(array[4], -2147483648);
|
|
||||||
assertSame(array.buffer, array2.buffer);
|
|
||||||
assertEquals(array2.length, 2);
|
|
||||||
assertEquals(array2[0], array[1]);
|
|
||||||
assertEquals(array2[1], array[2]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestUint32Array() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = new Uint32Array([-1, 0, 2, 4294967295, 4294967296]);
|
|
||||||
globalThis.array = array;
|
|
||||||
const array2 = new Uint32Array(array.buffer, 4, 2);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
}
|
|
||||||
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array',
|
|
||||||
'array2',
|
|
||||||
]);
|
|
||||||
assertEquals(array.length, 5);
|
|
||||||
assertEquals(array[0], 4294967295);
|
|
||||||
assertEquals(array[1], 0);
|
|
||||||
assertEquals(array[2], 2);
|
|
||||||
assertEquals(array[3], 4294967295);
|
|
||||||
assertEquals(array[4], 0);
|
|
||||||
assertSame(array.buffer, array2.buffer);
|
|
||||||
assertEquals(array2.length, 2);
|
|
||||||
assertEquals(array2[0], array[1]);
|
|
||||||
assertEquals(array2[1], array[2]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestBigInt64Array() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = new BigInt64Array([
|
|
||||||
BigInt(-(2 ** 63)) - 1n,
|
|
||||||
BigInt(-(2 ** 63)),
|
|
||||||
1n,
|
|
||||||
BigInt(2 ** 63) - 1n,
|
|
||||||
BigInt(2 ** 63),
|
|
||||||
]);
|
|
||||||
globalThis.array = array;
|
|
||||||
const array2 = new BigInt64Array(array.buffer, 8, 2);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
}
|
|
||||||
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array',
|
|
||||||
'array2',
|
|
||||||
]);
|
|
||||||
assertEquals(array.length, 5);
|
|
||||||
assertEquals(array[0], BigInt(2 ** 63) - 1n);
|
|
||||||
assertEquals(array[1], BigInt(-(2 ** 63)));
|
|
||||||
assertEquals(array[2], 1n);
|
|
||||||
assertEquals(array[3], BigInt(2 ** 63) - 1n);
|
|
||||||
assertEquals(array[4], BigInt(-(2 ** 63)));
|
|
||||||
assertSame(array.buffer, array2.buffer);
|
|
||||||
assertEquals(array2.length, 2);
|
|
||||||
assertEquals(array2[0], array[1]);
|
|
||||||
assertEquals(array2[1], array[2]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestBigUint32Array() {
|
|
||||||
function createObjects() {
|
|
||||||
const array = new BigUint64Array([
|
|
||||||
-1n,
|
|
||||||
0n,
|
|
||||||
2n,
|
|
||||||
BigInt(2 ** 64) - 1n,
|
|
||||||
BigInt(2 ** 64),
|
|
||||||
]);
|
|
||||||
globalThis.array = array;
|
|
||||||
const array2 = new BigUint64Array(array.buffer, 8, 2);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
}
|
|
||||||
const {array, array2} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array',
|
|
||||||
'array2',
|
|
||||||
]);
|
|
||||||
assertEquals(array.length, 5);
|
|
||||||
assertEquals(array[0], BigInt(2 ** 64) - 1n);
|
|
||||||
assertEquals(array[1], 0n);
|
|
||||||
assertEquals(array[2], 2n);
|
|
||||||
assertEquals(array[3], BigInt(2 ** 64) - 1n);
|
|
||||||
assertEquals(array[4], 0n);
|
|
||||||
assertSame(array.buffer, array2.buffer);
|
|
||||||
assertEquals(array2.length, 2);
|
|
||||||
assertEquals(array2[0], array[1]);
|
|
||||||
assertEquals(array2[1], array[2]);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestResizableTypedArray() {
|
|
||||||
function createObjects() {
|
|
||||||
let resizableArrayBuffer = new ArrayBuffer(1024, {
|
|
||||||
maxByteLength: 1024 * 2,
|
|
||||||
});
|
|
||||||
// 0 offset, auto length
|
|
||||||
let array = new Uint32Array(resizableArrayBuffer);
|
|
||||||
globalThis.array = array;
|
|
||||||
|
|
||||||
// Non-0 offset, auto length
|
|
||||||
let array2 = new Uint32Array(resizableArrayBuffer, 256);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
|
|
||||||
// Non-0 offset, fixed length
|
|
||||||
let array3 = new Uint32Array(resizableArrayBuffer, 128, 4);
|
|
||||||
globalThis.array3 = array3;
|
|
||||||
}
|
|
||||||
const {array, array2, array3} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array',
|
|
||||||
'array2',
|
|
||||||
'array3',
|
|
||||||
]);
|
|
||||||
assertTrue(array.buffer.resizable);
|
|
||||||
assertEquals(array.length, 256); // (1024 - 0) / 4
|
|
||||||
assertEquals(array2.length, 192); // (1024 - 256) / 4
|
|
||||||
assertEquals(array3.length, 4);
|
|
||||||
array.buffer.resize(1024 * 2);
|
|
||||||
assertEquals(array.length, 512); // (2048 - 0) / 4
|
|
||||||
assertEquals(array2.length, 448); // (2048 - 256) / 4
|
|
||||||
assertEquals(array3.length, 4);
|
|
||||||
})();
|
|
||||||
|
|
||||||
(function TestGrowableTypedArray() {
|
|
||||||
function createObjects() {
|
|
||||||
let resizableArrayBuffer = new SharedArrayBuffer(1024, {
|
|
||||||
maxByteLength: 1024 * 2,
|
|
||||||
});
|
|
||||||
// 0 offset, auto length
|
|
||||||
let array = new Uint32Array(resizableArrayBuffer);
|
|
||||||
globalThis.array = array;
|
|
||||||
|
|
||||||
// Non-0 offset, auto length
|
|
||||||
let array2 = new Uint32Array(resizableArrayBuffer, 256);
|
|
||||||
globalThis.array2 = array2;
|
|
||||||
|
|
||||||
// Non-0 offset, fixed length
|
|
||||||
let array3 = new Uint32Array(resizableArrayBuffer, 128, 4);
|
|
||||||
globalThis.array3 = array3;
|
|
||||||
}
|
|
||||||
const {array, array2, array3} = takeAndUseWebSnapshot(createObjects, [
|
|
||||||
'array',
|
|
||||||
'array2',
|
|
||||||
'array3',
|
|
||||||
]);
|
|
||||||
assertTrue(array.buffer.growable);
|
|
||||||
assertEquals(array.length, 256); // (1024 - 0) / 4
|
|
||||||
assertEquals(array2.length, 192); // (1024 - 256) / 4
|
|
||||||
assertEquals(array3.length, 4);
|
|
||||||
array.buffer.grow(1024 * 2);
|
|
||||||
assertEquals(array.length, 512); // (2048 - 0) / 4
|
|
||||||
assertEquals(array2.length, 448); // (2048 - 256) / 4
|
|
||||||
assertEquals(array3.length, 4);
|
|
||||||
})();
|
|
@ -465,7 +465,6 @@ v8_source_set("unittests_sources") {
|
|||||||
"utils/sparse-bit-vector-unittest.cc",
|
"utils/sparse-bit-vector-unittest.cc",
|
||||||
"utils/utils-unittest.cc",
|
"utils/utils-unittest.cc",
|
||||||
"utils/version-unittest.cc",
|
"utils/version-unittest.cc",
|
||||||
"web-snapshot/web-snapshot-unittest.cc",
|
|
||||||
"zone/zone-allocator-unittest.cc",
|
"zone/zone-allocator-unittest.cc",
|
||||||
"zone/zone-chunk-list-unittest.cc",
|
"zone/zone-chunk-list-unittest.cc",
|
||||||
"zone/zone-unittest.cc",
|
"zone/zone-unittest.cc",
|
||||||
|
@ -246,7 +246,6 @@
|
|||||||
'WeakMapsTest.WeakMapsWithChainedEntries': [SKIP],
|
'WeakMapsTest.WeakMapsWithChainedEntries': [SKIP],
|
||||||
'WeakMapsTest.Weakness': [SKIP],
|
'WeakMapsTest.Weakness': [SKIP],
|
||||||
'WeakSetsTest.WeakSet_Weakness': [SKIP],
|
'WeakSetsTest.WeakSet_Weakness': [SKIP],
|
||||||
'WebSnapshotTest.SFIDeduplicationAfterBytecodeFlushing': [SKIP],
|
|
||||||
|
|
||||||
# CodeRange tests
|
# CodeRange tests
|
||||||
'CodePagesTest.LargeCodeObjectWithSignalHandler': [SKIP],
|
'CodePagesTest.LargeCodeObjectWithSignalHandler': [SKIP],
|
||||||
@ -264,13 +263,6 @@
|
|||||||
'FactoryCodeBuilderOOMTest.Factory_CodeBuilder_TryBuildOOM': [SKIP],
|
'FactoryCodeBuilderOOMTest.Factory_CodeBuilder_TryBuildOOM': [SKIP],
|
||||||
}], # third_party_heap
|
}], # third_party_heap
|
||||||
|
|
||||||
################################################################################
|
|
||||||
['variant == always_sparkplug', {
|
|
||||||
# SFI deduplication tests check compilation state, which always_sparkplug
|
|
||||||
# can break.
|
|
||||||
'WebSnapshotTest.SFIDeduplication*': [SKIP],
|
|
||||||
}],
|
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
['byteorder == big', {
|
['byteorder == big', {
|
||||||
# Peephole optimization not supported on big-endian machines.
|
# Peephole optimization not supported on big-endian machines.
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1945,7 +1945,6 @@ code is governed by a BSD-style license that can be found in the LICENSE file.
|
|||||||
Group.groups.get('gc-background').entry(),
|
Group.groups.get('gc-background').entry(),
|
||||||
Group.groups.get('gc').entry(),
|
Group.groups.get('gc').entry(),
|
||||||
Group.groups.get('javascript').entry(),
|
Group.groups.get('javascript').entry(),
|
||||||
Group.groups.get('websnapshot').entry(),
|
|
||||||
Group.groups.get('runtime').entry(),
|
Group.groups.get('runtime').entry(),
|
||||||
this.unclassified
|
this.unclassified
|
||||||
];
|
];
|
||||||
@ -2282,7 +2281,6 @@ code is governed by a BSD-style license that can be found in the LICENSE file.
|
|||||||
new Group('GC', /GC_.*|AllocateInTargetSpace|GC/, "#00799c"));
|
new Group('GC', /GC_.*|AllocateInTargetSpace|GC/, "#00799c"));
|
||||||
Group.add('javascript',
|
Group.add('javascript',
|
||||||
new Group('JavaScript', /JS_Execution|JavaScript/, "#DD4477"));
|
new Group('JavaScript', /JS_Execution|JavaScript/, "#DD4477"));
|
||||||
Group.add('websnapshot', new Group('WebSnapshot', /.*Web.*/, "#E8E11C"));
|
|
||||||
Group.add('runtime', new Group('V8 C++', /.*/, "#88BB00"));
|
Group.add('runtime', new Group('V8 C++', /.*/, "#88BB00"));
|
||||||
Group.add('blink',
|
Group.add('blink',
|
||||||
new Group('Blink RCS', /.*Blink_.*/, "#006600", false, false));
|
new Group('Blink RCS', /.*Blink_.*/, "#006600", false, false));
|
||||||
|
@ -19,5 +19,4 @@ RUNTIME_CALL_STATS_GROUPS = [
|
|||||||
('Group-GC-Background', re.compile(".*GC.*BACKGROUND.*")),
|
('Group-GC-Background', re.compile(".*GC.*BACKGROUND.*")),
|
||||||
('Group-GC', re.compile("GC_.*|AllocateInTargetSpace")),
|
('Group-GC', re.compile("GC_.*|AllocateInTargetSpace")),
|
||||||
('Group-JavaScript', re.compile("JS_Execution")),
|
('Group-JavaScript', re.compile("JS_Execution")),
|
||||||
('Group-WebSnapshot', re.compile("WebSnapshot.*")),
|
|
||||||
('Group-Runtime', re.compile(".*"))]
|
('Group-Runtime', re.compile(".*"))]
|
||||||
|
Loading…
Reference in New Issue
Block a user