[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.h",
|
||||
"src/builtins/builtins-weak-refs.cc",
|
||||
"src/builtins/builtins-web-snapshots.cc",
|
||||
"src/builtins/builtins.cc",
|
||||
"src/builtins/builtins.h",
|
||||
"src/builtins/constants-table-builder.cc",
|
||||
@ -2207,8 +2206,6 @@ filegroup(
|
||||
"src/utils/utils.h",
|
||||
"src/utils/version.cc",
|
||||
"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.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-typed-array.cc",
|
||||
"src/builtins/builtins-weak-refs.cc",
|
||||
"src/builtins/builtins-web-snapshots.cc",
|
||||
"src/builtins/builtins.cc",
|
||||
"src/builtins/constants-table-builder.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/utils.cc",
|
||||
"src/utils/version.cc",
|
||||
"src/web-snapshot/web-snapshot.cc",
|
||||
"src/web-snapshot/web-snapshot.h",
|
||||
"src/zone/accounting-allocator.cc",
|
||||
"src/zone/type-stats.cc",
|
||||
"src/zone/zone-segment.cc",
|
||||
|
@ -128,7 +128,6 @@
|
||||
#include "src/tracing/trace-event.h"
|
||||
#include "src/utils/detachable-vector.h"
|
||||
#include "src/utils/version.h"
|
||||
#include "src/web-snapshot/web-snapshot.h"
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
#include "src/trap-handler/trap-handler.h"
|
||||
@ -2225,22 +2224,6 @@ MaybeLocal<Value> Script::Run(Local<Context> context,
|
||||
}
|
||||
#endif
|
||||
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();
|
||||
// TODO(cbruni, chromium:1244145): Remove once migrated to the context.
|
||||
i::Handle<i::Object> options(
|
||||
|
@ -626,10 +626,6 @@ namespace internal {
|
||||
CPP(JsonRawJson) \
|
||||
CPP(JsonIsRawJson) \
|
||||
\
|
||||
/* Web snapshots */ \
|
||||
CPP(WebSnapshotSerialize) \
|
||||
CPP(WebSnapshotDeserialize) \
|
||||
\
|
||||
/* ICs */ \
|
||||
TFH(LoadIC, 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/snapshot/code-serializer.h"
|
||||
#include "src/utils/ostreams.h"
|
||||
#include "src/web-snapshot/web-snapshot.h"
|
||||
#include "src/zone/zone-list-inl.h" // crbug.com/v8/8816
|
||||
|
||||
#ifdef V8_ENABLE_MAGLEV
|
||||
@ -3451,29 +3450,6 @@ MaybeHandle<SharedFunctionInfo> GetSharedFunctionInfoForScriptImpl(
|
||||
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);
|
||||
CompilationCache* compilation_cache = isolate->compilation_cache();
|
||||
|
||||
@ -3801,30 +3777,6 @@ Compiler::GetSharedFunctionInfoForStreamedScript(
|
||||
return maybe_result;
|
||||
} // 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
|
||||
template <typename IsolateT>
|
||||
Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfo(
|
||||
|
@ -224,9 +224,6 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
|
||||
Isolate* isolate, Handle<String> source,
|
||||
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
|
||||
// node (the code may be lazily compiled).
|
||||
template <typename IsolateT>
|
||||
|
@ -709,10 +709,7 @@ namespace internal {
|
||||
T(OptionalChainingNoSuper, "Invalid optional chain from super property") \
|
||||
T(OptionalChainingNoTemplate, "Invalid tagged template on optional chain") \
|
||||
/* AggregateError */ \
|
||||
T(AllPromisesRejected, "All promises were rejected") \
|
||||
/* Web snapshots */ \
|
||||
T(WebSnapshotError, "Web snapshot failed: %")
|
||||
|
||||
T(AllPromisesRejected, "All promises were rejected")
|
||||
enum class MessageTemplate {
|
||||
#define TEMPLATE(NAME, STRING) k##NAME,
|
||||
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/utils/ostreams.h"
|
||||
#include "src/utils/utils.h"
|
||||
#include "src/web-snapshot/web-snapshot.h"
|
||||
|
||||
#if V8_OS_POSIX
|
||||
#include <signal.h>
|
||||
@ -914,52 +913,6 @@ bool Shell::ExecuteString(Isolate* isolate, Local<String> source,
|
||||
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 {
|
||||
|
||||
bool IsAbsolutePath(const std::string& path) {
|
||||
@ -1499,44 +1452,6 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Shell::ExecuteWebSnapshot(Isolate* isolate, const char* file_name) {
|
||||
HandleScope handle_scope(isolate);
|
||||
|
||||
PerIsolateData* data = PerIsolateData::Get(isolate);
|
||||
Local<Context> realm = data->realms_[data->realm_current_].Get(isolate);
|
||||
Context::Scope context_scope(realm);
|
||||
|
||||
std::string absolute_path = NormalizePath(file_name, GetWorkingDirectory());
|
||||
|
||||
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.
|
||||
bool Shell::LoadJSON(Isolate* isolate, const char* file_name) {
|
||||
HandleScope handle_scope(isolate);
|
||||
@ -1579,10 +1494,6 @@ PerIsolateData::PerIsolateData(Isolate* isolate)
|
||||
async_hooks_wrapper_ = new AsyncHooks(isolate);
|
||||
}
|
||||
ignore_unhandled_promises_ = false;
|
||||
// TODO(v8:11525): Use methods on global Snapshot objects with
|
||||
// signature checks.
|
||||
HandleScope scope(isolate);
|
||||
Shell::CreateSnapshotTemplate(isolate);
|
||||
}
|
||||
|
||||
PerIsolateData::~PerIsolateData() {
|
||||
@ -1678,14 +1589,6 @@ void PerIsolateData::SetTestApiObjectCtor(Local<FunctionTemplate> 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 {
|
||||
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);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
@ -3569,21 +3378,9 @@ Local<ObjectTemplate> Shell::CreateRealmTemplate(Isolate* isolate) {
|
||||
FunctionTemplate::New(isolate, RealmEval));
|
||||
realm_template->SetAccessor(String::NewFromUtf8Literal(isolate, "shared"),
|
||||
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;
|
||||
}
|
||||
|
||||
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> d8_template = ObjectTemplate::New(isolate);
|
||||
{
|
||||
@ -4464,15 +4261,6 @@ bool SourceGroup::Execute(Isolate* isolate) {
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
} else if (strcmp(arg, "--web-snapshot") == 0 && i + 1 < end_offset_) {
|
||||
// Treat the next file as a web snapshot.
|
||||
arg = argv_[++i];
|
||||
Shell::set_script_executed();
|
||||
if (!Shell::ExecuteWebSnapshot(isolate, arg)) {
|
||||
success = false;
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
} else if (strcmp(arg, "--json") == 0 && i + 1 < end_offset_) {
|
||||
// Treat the next file as a JSON file.
|
||||
arg = argv_[++i];
|
||||
@ -4505,13 +4293,6 @@ bool SourceGroup::Execute(Isolate* isolate) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!success) {
|
||||
return false;
|
||||
}
|
||||
if (Shell::options.web_snapshot_config ||
|
||||
Shell::options.web_snapshot_output) {
|
||||
success = Shell::TakeWebSnapshot(isolate);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@ -5067,15 +4848,6 @@ bool Shell::SetOptions(int argc, char* argv[]) {
|
||||
} else if (strcmp(argv[i], "--stress-deserialize") == 0) {
|
||||
options.stress_deserialize = true;
|
||||
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) {
|
||||
options.compile_only = true;
|
||||
argv[i] = nullptr;
|
||||
@ -5154,12 +4926,11 @@ bool Shell::SetOptions(int argc, char* argv[]) {
|
||||
const char* usage =
|
||||
"Synopsis:\n"
|
||||
" shell [options] [--shell] [<file>...]\n"
|
||||
" d8 [options] [-e <string>] [--shell] [[--module|--web-snapshot]"
|
||||
" d8 [options] [-e <string>] [--shell] [--module|]"
|
||||
" <file>...]\n\n"
|
||||
" -e execute a string in V8\n"
|
||||
" --shell run an interactive JavaScript shell\n"
|
||||
" --module execute a file as a JavaScript module\n"
|
||||
" --web-snapshot execute a file as a web snapshot\n\n";
|
||||
" --module execute a file as a JavaScript module\n";
|
||||
using HelpOptions = i::FlagList::HelpOptions;
|
||||
i::v8_flags.abort_on_contradictory_flags = true;
|
||||
i::FlagList::SetFlagsFromCommandLine(&argc, argv, true,
|
||||
@ -5186,9 +4957,7 @@ bool Shell::SetOptions(int argc, char* argv[]) {
|
||||
current->End(i);
|
||||
current++;
|
||||
current->Begin(argv, i + 1);
|
||||
} else if (strcmp(str, "--module") == 0 ||
|
||||
strcmp(str, "--web-snapshot") == 0 ||
|
||||
strcmp(str, "--json") == 0) {
|
||||
} else if (strcmp(str, "--module") == 0 || strcmp(str, "--json") == 0) {
|
||||
// Pass on to SourceGroup, which understands these options.
|
||||
} else if (strncmp(str, "--", 2) == 0) {
|
||||
if (!i::v8_flags.correctness_fuzzer_suppressions) {
|
||||
@ -5222,7 +4991,6 @@ int Shell::RunMain(Isolate* isolate, bool last_run) {
|
||||
}
|
||||
HandleScope scope(isolate);
|
||||
Local<Context> context = CreateEvaluationContext(isolate);
|
||||
CreateSnapshotTemplate(isolate);
|
||||
bool use_existing_context = last_run && use_interactive_shell();
|
||||
if (use_existing_context) {
|
||||
// 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;
|
||||
void SetTestApiObjectCtor(Local<FunctionTemplate> ctor);
|
||||
|
||||
Local<FunctionTemplate> GetSnapshotObjectCtor() const;
|
||||
void SetSnapshotObjectCtor(Local<FunctionTemplate> ctor);
|
||||
|
||||
Local<FunctionTemplate> GetDomNodeCtor() const;
|
||||
void SetDomNodeCtor(Local<FunctionTemplate> ctor);
|
||||
|
||||
@ -344,7 +341,6 @@ class PerIsolateData {
|
||||
std::unordered_set<DynamicImportData*> import_data_;
|
||||
#endif
|
||||
Global<FunctionTemplate> test_api_object_ctor_;
|
||||
Global<FunctionTemplate> snapshot_object_ctor_;
|
||||
Global<FunctionTemplate> dom_node_ctor_;
|
||||
|
||||
int RealmIndexOrThrow(const v8::FunctionCallbackInfo<v8::Value>& args,
|
||||
@ -464,13 +460,7 @@ class ShellOptions {
|
||||
"enable-system-instrumentation", false};
|
||||
DisallowReassignment<bool> enable_etw_stack_walking = {
|
||||
"enable-etw-stack-walking", false};
|
||||
DisallowReassignment<const char*> web_snapshot_config = {
|
||||
"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.
|
||||
// Applies to JSON deserialization.
|
||||
DisallowReassignment<bool> stress_deserialize = {"stress-deserialize", false};
|
||||
DisallowReassignment<bool> compile_only = {"compile-only", false};
|
||||
DisallowReassignment<int> repeat_compile = {"repeat-compile", 1};
|
||||
@ -508,8 +498,6 @@ class Shell : public i::AllStatic {
|
||||
ReportExceptions report_exceptions,
|
||||
ProcessMessageQueue process_message_queue);
|
||||
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 void ReportException(Isolate* isolate, Local<Message> message,
|
||||
Local<Value> exception);
|
||||
@ -569,10 +557,6 @@ class Shell : public i::AllStatic {
|
||||
const PropertyCallbackInfo<Value>& info);
|
||||
static void RealmSharedSet(Local<String> property, Local<Value> value,
|
||||
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 TestVerifySourcePositions(
|
||||
@ -737,8 +721,6 @@ class Shell : public i::AllStatic {
|
||||
|
||||
static void PromiseRejectCallback(v8::PromiseRejectMessage reject_message);
|
||||
|
||||
static Local<FunctionTemplate> CreateSnapshotTemplate(Isolate* isolate);
|
||||
|
||||
private:
|
||||
static inline int DeserializationRunCount() {
|
||||
return options.stress_deserialize ? 1000 : 1;
|
||||
|
@ -1898,12 +1898,6 @@ void AllocationSite::AllocationSiteVerify(Isolate* isolate) {
|
||||
|
||||
void Script::ScriptVerify(Isolate* 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) {
|
||||
MaybeObject maybe_object = shared_function_infos().Get(i);
|
||||
HeapObject heap_object;
|
||||
|
@ -2374,9 +2374,6 @@ void Script::ScriptPrint(std::ostream& os) {
|
||||
os << "\n - eval from shared: " << Brief(eval_from_shared());
|
||||
} else if (is_wrapped()) {
|
||||
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();
|
||||
}
|
||||
|
@ -589,7 +589,6 @@ DEFINE_BOOL(trace_block_coverage, false,
|
||||
"trace collected block coverage information")
|
||||
DEFINE_BOOL(trace_protector_invalidation, false,
|
||||
"trace protector cell invalidations")
|
||||
DEFINE_BOOL(trace_web_snapshot, false, "trace web snapshot deserialization")
|
||||
|
||||
DEFINE_BOOL(feedback_normalization, false,
|
||||
"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, 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)
|
||||
DEFINE_BOOL(use_libm_trig_functions, true, "use libm trig functions")
|
||||
#endif
|
||||
|
@ -280,8 +280,8 @@ Handle<Script> FactoryBase<Impl>::NewScriptWithId(
|
||||
raw.set_context_data(roots.undefined_value(), SKIP_WRITE_BARRIER);
|
||||
raw.set_type(Script::TYPE_NORMAL);
|
||||
raw.set_line_ends(roots.undefined_value(), SKIP_WRITE_BARRIER);
|
||||
raw.set_eval_from_shared_or_wrapped_arguments_or_sfi_table(
|
||||
roots.undefined_value(), SKIP_WRITE_BARRIER);
|
||||
raw.set_eval_from_shared_or_wrapped_arguments(roots.undefined_value(),
|
||||
SKIP_WRITE_BARRIER);
|
||||
raw.set_eval_from_position(0);
|
||||
raw.set_shared_function_infos(roots.empty_weak_fixed_array(),
|
||||
SKIP_WRITE_BARRIER);
|
||||
|
@ -338,7 +338,6 @@ class FactoryBase : public TorqueGeneratedFactory<Impl> {
|
||||
AllocationType allocation);
|
||||
|
||||
private:
|
||||
friend class WebSnapshotDeserializer;
|
||||
Impl* impl() { return static_cast<Impl*>(this); }
|
||||
auto isolate() { return impl()->isolate(); }
|
||||
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_type(old_script.type());
|
||||
new_script.set_line_ends(*undefined_value(), SKIP_WRITE_BARRIER);
|
||||
new_script.set_eval_from_shared_or_wrapped_arguments_or_sfi_table(
|
||||
script->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());
|
||||
new_script.set_shared_function_infos(*empty_weak_fixed_array(),
|
||||
SKIP_WRITE_BARRIER);
|
||||
new_script.set_eval_from_position(old_script.eval_from_position());
|
||||
@ -3366,12 +3366,6 @@ Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForBuiltin(
|
||||
return shared;
|
||||
}
|
||||
|
||||
Handle<SharedFunctionInfo> Factory::NewSharedFunctionInfoForWebSnapshot() {
|
||||
return NewSharedFunctionInfo(empty_string(), MaybeHandle<InstructionStream>(),
|
||||
Builtin::kNoBuiltinId,
|
||||
FunctionKind::kNormalFunction);
|
||||
}
|
||||
|
||||
int Factory::NumberToStringCacheHash(Smi number) {
|
||||
int mask = (number_string_cache()->length() >> 1) - 1;
|
||||
return number.value() & mask;
|
||||
|
@ -809,8 +809,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
|
||||
MaybeHandle<String> name, Builtin builtin,
|
||||
FunctionKind kind = FunctionKind::kNormalFunction);
|
||||
|
||||
Handle<SharedFunctionInfo> NewSharedFunctionInfoForWebSnapshot();
|
||||
|
||||
static bool IsFunctionModeWithPrototype(FunctionMode function_mode) {
|
||||
return (function_mode & kWithPrototypeBits) != 0;
|
||||
}
|
||||
@ -1054,7 +1052,6 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
|
||||
|
||||
private:
|
||||
friend class FactoryBase<Factory>;
|
||||
friend class WebSnapshotDeserializer;
|
||||
|
||||
// ------
|
||||
// Customization points for FactoryBase
|
||||
|
@ -246,8 +246,6 @@ class Genesis {
|
||||
#undef DECLARE_FEATURE_INITIALIZATION
|
||||
void InitializeGlobal_regexp_linear_flag();
|
||||
|
||||
void InitializeGlobal_experimental_web_snapshots();
|
||||
|
||||
enum ArrayBufferKind { ARRAY_BUFFER, SHARED_ARRAY_BUFFER };
|
||||
Handle<JSFunction> CreateArrayBuffer(Handle<String> name,
|
||||
ArrayBufferKind array_buffer_kind);
|
||||
@ -4150,7 +4148,6 @@ void Genesis::InitializeExperimentalGlobal() {
|
||||
HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
|
||||
#undef FEATURE_INITIALIZE_GLOBAL
|
||||
InitializeGlobal_regexp_linear_flag();
|
||||
InitializeGlobal_experimental_web_snapshots();
|
||||
}
|
||||
|
||||
bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
|
||||
@ -5556,21 +5553,6 @@ void Genesis::InitializeGlobal_harmony_intl_number_format_v3() {
|
||||
|
||||
#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
|
||||
void Genesis::InitializeGlobal_harmony_intl_duration_format() {
|
||||
if (!v8_flags.harmony_intl_duration_format) return;
|
||||
|
@ -494,21 +494,6 @@ class RuntimeCallTimer final {
|
||||
V(TestCounter2) \
|
||||
V(TestCounter3) \
|
||||
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(WrappedFunctionNameGetter)
|
||||
|
||||
|
@ -73,9 +73,6 @@ void MutableBigInt_RightShiftAndCanonicalize(Address result_addr,
|
||||
class BigInt;
|
||||
class ValueDeserializer;
|
||||
class ValueSerializer;
|
||||
class WebSnapshotSerializerDeserializer;
|
||||
class WebSnapshotSerializer;
|
||||
class WebSnapshotDeserializer;
|
||||
|
||||
#include "torque-generated/src/objects/bigint-tq.inc"
|
||||
|
||||
@ -304,9 +301,6 @@ class BigInt : public BigIntBase {
|
||||
friend class StringToBigIntHelper;
|
||||
friend class ValueDeserializer;
|
||||
friend class ValueSerializer;
|
||||
friend class WebSnapshotSerializerDeserializer;
|
||||
friend class WebSnapshotSerializer;
|
||||
friend class WebSnapshotDeserializer;
|
||||
|
||||
// Special functions for StringToBigIntHelper:
|
||||
template <typename IsolateT>
|
||||
|
@ -233,7 +233,6 @@ class DescriptorArray
|
||||
using EntryValueField = TaggedField<MaybeObject, kEntryValueOffset>;
|
||||
|
||||
private:
|
||||
friend class WebSnapshotDeserializer;
|
||||
DECL_INT16_ACCESSORS(filler16bits)
|
||||
|
||||
inline void SetKey(InternalIndex descriptor_number, Name key);
|
||||
|
@ -391,7 +391,6 @@ class JSTypedArray
|
||||
template <typename IsolateT>
|
||||
friend class Deserializer;
|
||||
friend class Factory;
|
||||
friend class WebSnapshotDeserializer;
|
||||
|
||||
DECL_PRIMITIVE_SETTER(length, size_t)
|
||||
// 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,
|
||||
FunctionLiteral* function_literal) {
|
||||
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);
|
||||
// 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,
|
||||
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)
|
||||
: iterator_(isolate->heap()->script_list()) {}
|
||||
|
||||
|
@ -316,8 +316,6 @@ class ScopeInfo : public TorqueGeneratedScopeInfo<ScopeInfo, HeapObject> {
|
||||
V8_EXPORT_PRIVATE uint32_t Hash();
|
||||
|
||||
private:
|
||||
friend class WebSnapshotDeserializer;
|
||||
|
||||
int InlinedLocalNamesLookup(String name);
|
||||
|
||||
int ContextLocalNamesIndex() const;
|
||||
|
@ -25,7 +25,7 @@ NEVER_READ_ONLY_SPACE_IMPL(Script)
|
||||
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
ACCESSORS_CHECKED(Script, wasm_breakpoint_infos, FixedArray,
|
||||
kEvalFromSharedOrWrappedArgumentsOrSfiTableOffset,
|
||||
kEvalFromSharedOrWrappedArgumentsOffset,
|
||||
this->type() == TYPE_WASM)
|
||||
ACCESSORS_CHECKED(Script, wasm_managed_native_module, Object,
|
||||
kEvalFromPositionOffset, this->type() == TYPE_WASM)
|
||||
@ -37,8 +37,8 @@ ACCESSORS_CHECKED(Script, wasm_weak_instance_list, WeakArrayList,
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
|
||||
SMI_ACCESSORS(Script, type, kScriptTypeOffset)
|
||||
ACCESSORS_CHECKED(Script, eval_from_shared_or_wrapped_arguments_or_sfi_table,
|
||||
Object, kEvalFromSharedOrWrappedArgumentsOrSfiTableOffset,
|
||||
ACCESSORS_CHECKED(Script, eval_from_shared_or_wrapped_arguments, Object,
|
||||
kEvalFromSharedOrWrappedArgumentsOffset,
|
||||
CHECK_SCRIPT_NOT_WASM)
|
||||
SMI_ACCESSORS_CHECKED(Script, eval_from_position, kEvalFromPositionOffset,
|
||||
CHECK_SCRIPT_NOT_WASM)
|
||||
@ -48,51 +48,32 @@ ACCESSORS(Script, compiled_lazy_function_positions, Object,
|
||||
kCompiledLazyFunctionPositionsOffset)
|
||||
|
||||
bool Script::is_wrapped() const {
|
||||
return eval_from_shared_or_wrapped_arguments_or_sfi_table().IsFixedArray() &&
|
||||
type() != TYPE_WEB_SNAPSHOT;
|
||||
return eval_from_shared_or_wrapped_arguments().IsFixedArray();
|
||||
}
|
||||
|
||||
bool Script::has_eval_from_shared() const {
|
||||
return eval_from_shared_or_wrapped_arguments_or_sfi_table()
|
||||
.IsSharedFunctionInfo();
|
||||
return eval_from_shared_or_wrapped_arguments().IsSharedFunctionInfo();
|
||||
}
|
||||
|
||||
void Script::set_eval_from_shared(SharedFunctionInfo shared,
|
||||
WriteBarrierMode mode) {
|
||||
DCHECK(!is_wrapped());
|
||||
DCHECK_NE(type(), TYPE_WEB_SNAPSHOT);
|
||||
set_eval_from_shared_or_wrapped_arguments_or_sfi_table(shared, mode);
|
||||
set_eval_from_shared_or_wrapped_arguments(shared, mode);
|
||||
}
|
||||
|
||||
SharedFunctionInfo Script::eval_from_shared() const {
|
||||
DCHECK(has_eval_from_shared());
|
||||
return SharedFunctionInfo::cast(
|
||||
eval_from_shared_or_wrapped_arguments_or_sfi_table());
|
||||
return SharedFunctionInfo::cast(eval_from_shared_or_wrapped_arguments());
|
||||
}
|
||||
|
||||
void Script::set_wrapped_arguments(FixedArray value, WriteBarrierMode mode) {
|
||||
DCHECK(!has_eval_from_shared());
|
||||
DCHECK_NE(type(), TYPE_WEB_SNAPSHOT);
|
||||
set_eval_from_shared_or_wrapped_arguments_or_sfi_table(value, mode);
|
||||
set_eval_from_shared_or_wrapped_arguments(value, mode);
|
||||
}
|
||||
|
||||
FixedArray Script::wrapped_arguments() const {
|
||||
DCHECK(is_wrapped());
|
||||
return FixedArray::cast(eval_from_shared_or_wrapped_arguments_or_sfi_table());
|
||||
}
|
||||
|
||||
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());
|
||||
return FixedArray::cast(eval_from_shared_or_wrapped_arguments());
|
||||
}
|
||||
|
||||
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 {
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -46,8 +46,7 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
|
||||
#if V8_ENABLE_WEBASSEMBLY
|
||||
TYPE_WASM = 3,
|
||||
#endif // V8_ENABLE_WEBASSEMBLY
|
||||
TYPE_INSPECTOR = 4,
|
||||
TYPE_WEB_SNAPSHOT = 5
|
||||
TYPE_INSPECTOR = 4
|
||||
};
|
||||
|
||||
// Script compilation types.
|
||||
@ -62,7 +61,7 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
|
||||
// [type]: the script 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
|
||||
// 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.
|
||||
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.
|
||||
inline bool is_wrapped() const;
|
||||
|
||||
@ -221,14 +214,6 @@ class Script : public TorqueGeneratedScript<Script, Struct> {
|
||||
Handle<Script> script, IsolateT* isolate,
|
||||
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.
|
||||
class V8_EXPORT_PRIVATE Iterator {
|
||||
public:
|
||||
|
@ -42,10 +42,9 @@ extern class Script extends Struct {
|
||||
|
||||
// For scripts originating from eval: the SharedFunctionInfo contains the SFI
|
||||
// for the script. For scripts wrapped as functions: the FixedArray contains
|
||||
// the arguments. For web snapshots: the ObjectHashTable maps function start
|
||||
// position to SFI index in shared_function_infos.
|
||||
eval_from_shared_or_wrapped_arguments_or_sfi_table: SharedFunctionInfo|
|
||||
FixedArray|ObjectHashTable|Undefined;
|
||||
// the arguments.
|
||||
eval_from_shared_or_wrapped_arguments: SharedFunctionInfo|FixedArray|
|
||||
Undefined;
|
||||
eval_from_position: Smi|Foreign; // Smi or Managed<wasm::NativeModule>
|
||||
shared_function_infos: WeakFixedArray|WeakArrayList;
|
||||
|
||||
|
@ -689,8 +689,6 @@ class SharedFunctionInfo
|
||||
Isolate* isolate);
|
||||
|
||||
private:
|
||||
friend class WebSnapshotDeserializer;
|
||||
|
||||
#ifdef VERIFY_HEAP
|
||||
void SharedFunctionInfoVerify(ReadOnlyRoots roots);
|
||||
#endif
|
||||
|
@ -98,8 +98,6 @@ class ValueSerializer {
|
||||
void SetTreatArrayBufferViewsAsHostObjects(bool mode);
|
||||
|
||||
private:
|
||||
friend class WebSnapshotSerializer;
|
||||
|
||||
// Managing allocations of the internal buffer.
|
||||
Maybe<bool> ExpandBuffer(size_t required_capacity);
|
||||
|
||||
@ -249,8 +247,6 @@ class ValueDeserializer {
|
||||
bool ReadByte(uint8_t* value) V8_WARN_UNUSED_RESULT;
|
||||
|
||||
private:
|
||||
friend class WebSnapshotDeserializer;
|
||||
|
||||
// Reading the wire format.
|
||||
Maybe<SerializationTag> PeekTag() const V8_WARN_UNUSED_RESULT;
|
||||
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();
|
||||
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.
|
||||
info->set_function_name(ast_value_factory()->GetString(
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "src/profiler/heap-snapshot-generator.h"
|
||||
#include "src/regexp/regexp.h"
|
||||
#include "src/snapshot/snapshot.h"
|
||||
#include "src/web-snapshot/web-snapshot.h"
|
||||
|
||||
#ifdef V8_ENABLE_MAGLEV
|
||||
#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],
|
||||
'compiler/fast-api-helpers': [SKIP],
|
||||
'typedarray-helpers': [SKIP],
|
||||
'web-snapshot/web-snapshot-helpers': [SKIP],
|
||||
|
||||
# All tests in the bug directory are expected to 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/utils-unittest.cc",
|
||||
"utils/version-unittest.cc",
|
||||
"web-snapshot/web-snapshot-unittest.cc",
|
||||
"zone/zone-allocator-unittest.cc",
|
||||
"zone/zone-chunk-list-unittest.cc",
|
||||
"zone/zone-unittest.cc",
|
||||
|
@ -246,7 +246,6 @@
|
||||
'WeakMapsTest.WeakMapsWithChainedEntries': [SKIP],
|
||||
'WeakMapsTest.Weakness': [SKIP],
|
||||
'WeakSetsTest.WeakSet_Weakness': [SKIP],
|
||||
'WebSnapshotTest.SFIDeduplicationAfterBytecodeFlushing': [SKIP],
|
||||
|
||||
# CodeRange tests
|
||||
'CodePagesTest.LargeCodeObjectWithSignalHandler': [SKIP],
|
||||
@ -264,13 +263,6 @@
|
||||
'FactoryCodeBuilderOOMTest.Factory_CodeBuilder_TryBuildOOM': [SKIP],
|
||||
}], # third_party_heap
|
||||
|
||||
################################################################################
|
||||
['variant == always_sparkplug', {
|
||||
# SFI deduplication tests check compilation state, which always_sparkplug
|
||||
# can break.
|
||||
'WebSnapshotTest.SFIDeduplication*': [SKIP],
|
||||
}],
|
||||
|
||||
##############################################################################
|
||||
['byteorder == big', {
|
||||
# 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').entry(),
|
||||
Group.groups.get('javascript').entry(),
|
||||
Group.groups.get('websnapshot').entry(),
|
||||
Group.groups.get('runtime').entry(),
|
||||
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"));
|
||||
Group.add('javascript',
|
||||
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('blink',
|
||||
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', re.compile("GC_.*|AllocateInTargetSpace")),
|
||||
('Group-JavaScript', re.compile("JS_Execution")),
|
||||
('Group-WebSnapshot', re.compile("WebSnapshot.*")),
|
||||
('Group-Runtime', re.compile(".*"))]
|
||||
|
Loading…
Reference in New Issue
Block a user