mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
deps: V8: cherry-pick cd10ad7cdbe5
Original commit message:
[compiler] reset script details in functions deserialized from code cache
During the serialization of the code cache, V8 would wipe out the
host-defined options, so after a script id deserialized from the
code cache, the host-defined options need to be reset on the script
using what's provided by the embedder when doing the deserializing
compilation, otherwise the HostImportModuleDynamically callbacks
can't get the data it needs to implement dynamic import().
Change-Id: I33cc6a5e43b6469d3527242e083f7ae6d8ed0c6a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5401780
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Joyee Cheung <joyee@igalia.com>
Cr-Commit-Position: refs/heads/main@{#93323}
Refs: cd10ad7cdb
PR-URL: https://github.com/nodejs/node/pull/52535
Refs: https://github.com/nodejs/node/issues/47472
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/52293
Reviewed-By: Moshe Atlow <moshe@atlow.co.il>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
This commit is contained in:
parent
826dda2659
commit
91661ec08b
@ -37,7 +37,7 @@
|
||||
|
||||
# Reset this number to 0 on major V8 upgrades.
|
||||
# Increment by one for each non-official patch applied to deps/v8.
|
||||
'v8_embedder_string': '-node.9',
|
||||
'v8_embedder_string': '-node.10',
|
||||
|
||||
##### V8 defaults for Node.js #####
|
||||
|
||||
|
19
deps/v8/src/codegen/compiler.cc
vendored
19
deps/v8/src/codegen/compiler.cc
vendored
@ -1720,10 +1720,8 @@ BackgroundCompileTask::BackgroundCompileTask(
|
||||
|
||||
BackgroundCompileTask::~BackgroundCompileTask() = default;
|
||||
|
||||
namespace {
|
||||
|
||||
void SetScriptFieldsFromDetails(Isolate* isolate, Tagged<Script> script,
|
||||
ScriptDetails script_details,
|
||||
const ScriptDetails& script_details,
|
||||
DisallowGarbageCollection* no_gc) {
|
||||
Handle<Object> script_name;
|
||||
if (script_details.name_obj.ToHandle(&script_name)) {
|
||||
@ -1749,6 +1747,8 @@ void SetScriptFieldsFromDetails(Isolate* isolate, Tagged<Script> script,
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
#ifdef ENABLE_SLOW_DCHECKS
|
||||
|
||||
// A class which traverses the object graph for a newly compiled Script and
|
||||
@ -2460,10 +2460,10 @@ void BackgroundDeserializeTask::MergeWithExistingScript() {
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> BackgroundDeserializeTask::Finish(
|
||||
Isolate* isolate, Handle<String> source,
|
||||
ScriptOriginOptions origin_options) {
|
||||
const ScriptDetails& script_details) {
|
||||
return CodeSerializer::FinishOffThreadDeserialize(
|
||||
isolate, std::move(off_thread_data_), &cached_data_, source,
|
||||
origin_options, &background_merge_task_);
|
||||
script_details, &background_merge_task_);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
@ -3640,8 +3640,8 @@ MaybeHandle<SharedFunctionInfo> GetSharedFunctionInfoForScriptImpl(
|
||||
"V8.CompileDeserialize");
|
||||
if (deserialize_task) {
|
||||
// If there's a cache consume task, finish it.
|
||||
maybe_result = deserialize_task->Finish(isolate, source,
|
||||
script_details.origin_options);
|
||||
maybe_result =
|
||||
deserialize_task->Finish(isolate, source, script_details);
|
||||
// It is possible at this point that there is a Script object for this
|
||||
// script in the compilation cache (held in the variable maybe_script),
|
||||
// which does not match maybe_result->script(). This could happen any of
|
||||
@ -3662,8 +3662,7 @@ MaybeHandle<SharedFunctionInfo> GetSharedFunctionInfoForScriptImpl(
|
||||
// would be non-trivial.
|
||||
} else {
|
||||
maybe_result = CodeSerializer::Deserialize(
|
||||
isolate, cached_data, source, script_details.origin_options,
|
||||
maybe_script);
|
||||
isolate, cached_data, source, script_details, maybe_script);
|
||||
}
|
||||
|
||||
bool consuming_code_cache_succeeded = false;
|
||||
@ -3839,7 +3838,7 @@ MaybeHandle<JSFunction> Compiler::GetWrappedFunction(
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
|
||||
"V8.CompileDeserialize");
|
||||
maybe_result = CodeSerializer::Deserialize(isolate, cached_data, source,
|
||||
script_details.origin_options);
|
||||
script_details);
|
||||
bool consuming_code_cache_succeeded = false;
|
||||
if (maybe_result.ToHandle(&result)) {
|
||||
is_compiled_scope = result->is_compiled_scope(isolate);
|
||||
|
2
deps/v8/src/codegen/compiler.h
vendored
2
deps/v8/src/codegen/compiler.h
vendored
@ -682,7 +682,7 @@ class V8_EXPORT_PRIVATE BackgroundDeserializeTask {
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> Finish(Isolate* isolate,
|
||||
Handle<String> source,
|
||||
ScriptOriginOptions origin_options);
|
||||
const ScriptDetails& script_details);
|
||||
|
||||
bool rejected() const { return cached_data_.rejected(); }
|
||||
|
||||
|
3
deps/v8/src/codegen/script-details.h
vendored
3
deps/v8/src/codegen/script-details.h
vendored
@ -35,6 +35,9 @@ struct ScriptDetails {
|
||||
const ScriptOriginOptions origin_options;
|
||||
};
|
||||
|
||||
void SetScriptFieldsFromDetails(Isolate* isolate, Tagged<Script> script,
|
||||
const ScriptDetails& script_details,
|
||||
DisallowGarbageCollection* no_gc);
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
34
deps/v8/src/snapshot/code-serializer.cc
vendored
34
deps/v8/src/snapshot/code-serializer.cc
vendored
@ -313,12 +313,12 @@ class StressOffThreadDeserializeThread final : public base::Thread {
|
||||
CodeSerializer::StartDeserializeOffThread(&local_isolate, cached_data_);
|
||||
}
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> Finalize(Isolate* isolate,
|
||||
Handle<String> source,
|
||||
ScriptOriginOptions origin_options) {
|
||||
MaybeHandle<SharedFunctionInfo> Finalize(
|
||||
Isolate* isolate, Handle<String> source,
|
||||
const ScriptDetails& script_details) {
|
||||
return CodeSerializer::FinishOffThreadDeserialize(
|
||||
isolate, std::move(off_thread_data_), cached_data_, source,
|
||||
origin_options);
|
||||
script_details);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -329,7 +329,8 @@ class StressOffThreadDeserializeThread final : public base::Thread {
|
||||
|
||||
void FinalizeDeserialization(Isolate* isolate,
|
||||
Handle<SharedFunctionInfo> result,
|
||||
const base::ElapsedTimer& timer) {
|
||||
const base::ElapsedTimer& timer,
|
||||
const ScriptDetails& script_details) {
|
||||
// Devtools can report time in this function as profiler overhead, since none
|
||||
// of the following tasks would need to happen normally.
|
||||
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
|
||||
@ -342,10 +343,16 @@ void FinalizeDeserialization(Isolate* isolate,
|
||||
log_code_creation);
|
||||
}
|
||||
|
||||
Handle<Script> script(Script::cast(result->script()), isolate);
|
||||
// Reset the script details, including host-defined options.
|
||||
{
|
||||
DisallowGarbageCollection no_gc;
|
||||
SetScriptFieldsFromDetails(isolate, *script, script_details, &no_gc);
|
||||
}
|
||||
|
||||
bool needs_source_positions = isolate->NeedsSourcePositions();
|
||||
if (!log_code_creation && !needs_source_positions) return;
|
||||
|
||||
Handle<Script> script(Script::cast(result->script()), isolate);
|
||||
if (needs_source_positions) {
|
||||
Script::InitLineEnds(isolate, script);
|
||||
}
|
||||
@ -429,13 +436,13 @@ const char* ToString(SerializedCodeSanityCheckResult result) {
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
|
||||
Isolate* isolate, AlignedCachedData* cached_data, Handle<String> source,
|
||||
ScriptOriginOptions origin_options,
|
||||
const ScriptDetails& script_details,
|
||||
MaybeHandle<Script> maybe_cached_script) {
|
||||
if (v8_flags.stress_background_compile) {
|
||||
StressOffThreadDeserializeThread thread(isolate, cached_data);
|
||||
CHECK(thread.Start());
|
||||
thread.Join();
|
||||
return thread.Finalize(isolate, source, origin_options);
|
||||
return thread.Finalize(isolate, source, script_details);
|
||||
// TODO(leszeks): Compare off-thread deserialized data to on-thread.
|
||||
}
|
||||
|
||||
@ -450,7 +457,7 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
|
||||
SerializedCodeSanityCheckResult::kSuccess;
|
||||
const SerializedCodeData scd = SerializedCodeData::FromCachedData(
|
||||
isolate, cached_data,
|
||||
SerializedCodeData::SourceHash(source, origin_options),
|
||||
SerializedCodeData::SourceHash(source, script_details.origin_options),
|
||||
&sanity_check_result);
|
||||
if (sanity_check_result != SerializedCodeSanityCheckResult::kSuccess) {
|
||||
if (v8_flags.profile_deserialization) {
|
||||
@ -497,7 +504,7 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::Deserialize(
|
||||
PrintF("[Deserializing from %d bytes took %0.3f ms]\n", length, ms);
|
||||
}
|
||||
|
||||
FinalizeDeserialization(isolate, result, timer);
|
||||
FinalizeDeserialization(isolate, result, timer, script_details);
|
||||
|
||||
return scope.CloseAndEscape(result);
|
||||
}
|
||||
@ -552,7 +559,7 @@ CodeSerializer::StartDeserializeOffThread(LocalIsolate* local_isolate,
|
||||
MaybeHandle<SharedFunctionInfo> CodeSerializer::FinishOffThreadDeserialize(
|
||||
Isolate* isolate, OffThreadDeserializeData&& data,
|
||||
AlignedCachedData* cached_data, Handle<String> source,
|
||||
ScriptOriginOptions origin_options,
|
||||
const ScriptDetails& script_details,
|
||||
BackgroundMergeTask* background_merge_task) {
|
||||
base::ElapsedTimer timer;
|
||||
if (v8_flags.profile_deserialization || v8_flags.log_function_events) {
|
||||
@ -568,7 +575,8 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::FinishOffThreadDeserialize(
|
||||
data.sanity_check_result;
|
||||
const SerializedCodeData scd =
|
||||
SerializedCodeData::FromPartiallySanityCheckedCachedData(
|
||||
cached_data, SerializedCodeData::SourceHash(source, origin_options),
|
||||
cached_data,
|
||||
SerializedCodeData::SourceHash(source, script_details.origin_options),
|
||||
&sanity_check_result);
|
||||
if (sanity_check_result != SerializedCodeSanityCheckResult::kSuccess) {
|
||||
// The only case where the deserialization result could exist despite a
|
||||
@ -641,7 +649,7 @@ MaybeHandle<SharedFunctionInfo> CodeSerializer::FinishOffThreadDeserialize(
|
||||
length, ms);
|
||||
}
|
||||
|
||||
FinalizeDeserialization(isolate, result, timer);
|
||||
FinalizeDeserialization(isolate, result, timer, script_details);
|
||||
|
||||
DCHECK(!background_merge_task ||
|
||||
!background_merge_task->HasPendingForegroundWork());
|
||||
|
5
deps/v8/src/snapshot/code-serializer.h
vendored
5
deps/v8/src/snapshot/code-serializer.h
vendored
@ -6,6 +6,7 @@
|
||||
#define V8_SNAPSHOT_CODE_SERIALIZER_H_
|
||||
|
||||
#include "src/base/macros.h"
|
||||
#include "src/codegen/script-details.h"
|
||||
#include "src/snapshot/serializer.h"
|
||||
#include "src/snapshot/snapshot-data.h"
|
||||
|
||||
@ -81,7 +82,7 @@ class CodeSerializer : public Serializer {
|
||||
|
||||
V8_WARN_UNUSED_RESULT static MaybeHandle<SharedFunctionInfo> Deserialize(
|
||||
Isolate* isolate, AlignedCachedData* cached_data, Handle<String> source,
|
||||
ScriptOriginOptions origin_options,
|
||||
const ScriptDetails& script_details,
|
||||
MaybeHandle<Script> maybe_cached_script = {});
|
||||
|
||||
V8_WARN_UNUSED_RESULT static OffThreadDeserializeData
|
||||
@ -92,7 +93,7 @@ class CodeSerializer : public Serializer {
|
||||
FinishOffThreadDeserialize(
|
||||
Isolate* isolate, OffThreadDeserializeData&& data,
|
||||
AlignedCachedData* cached_data, Handle<String> source,
|
||||
ScriptOriginOptions origin_options,
|
||||
const ScriptDetails& script_details,
|
||||
BackgroundMergeTask* background_merge_task = nullptr);
|
||||
|
||||
uint32_t source_hash() const { return source_hash_; }
|
||||
|
209
deps/v8/test/cctest/test-serialize.cc
vendored
209
deps/v8/test/cctest/test-serialize.cc
vendored
@ -5438,6 +5438,215 @@ TEST(WeakArraySerializationInCodeCache) {
|
||||
delete cache;
|
||||
}
|
||||
|
||||
v8::MaybeLocal<v8::Promise> TestHostDefinedOptionFromCachedScript(
|
||||
Local<v8::Context> context, Local<v8::Data> host_defined_options,
|
||||
Local<v8::Value> resource_name, Local<v8::String> specifier,
|
||||
Local<v8::FixedArray> import_attributes) {
|
||||
CHECK(host_defined_options->IsFixedArray());
|
||||
auto arr = host_defined_options.As<v8::FixedArray>();
|
||||
CHECK_EQ(arr->Length(), 1);
|
||||
v8::Local<v8::Symbol> expected =
|
||||
v8::Symbol::For(context->GetIsolate(), v8_str("hdo"));
|
||||
CHECK_EQ(arr->Get(context, 0), expected);
|
||||
CHECK(resource_name->Equals(context, v8_str("test_hdo")).FromJust());
|
||||
CHECK(specifier->Equals(context, v8_str("foo")).FromJust());
|
||||
|
||||
Local<v8::Promise::Resolver> resolver =
|
||||
v8::Promise::Resolver::New(context).ToLocalChecked();
|
||||
resolver->Resolve(context, v8_str("hello")).ToChecked();
|
||||
return resolver->GetPromise();
|
||||
}
|
||||
|
||||
TEST(CachedFunctionHostDefinedOption) {
|
||||
DisableAlwaysOpt();
|
||||
LocalContext env;
|
||||
v8::Isolate* isolate = env->GetIsolate();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
i_isolate->compilation_cache()
|
||||
->DisableScriptAndEval(); // Disable same-isolate code cache.
|
||||
isolate->SetHostImportModuleDynamicallyCallback(
|
||||
TestHostDefinedOptionFromCachedScript);
|
||||
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
v8::Local<v8::String> source = v8_str("return import(x)");
|
||||
v8::Local<v8::String> arg_str = v8_str("x");
|
||||
|
||||
v8::Local<v8::PrimitiveArray> hdo = v8::PrimitiveArray::New(isolate, 1);
|
||||
hdo->Set(isolate, 0, v8::Symbol::For(isolate, v8_str("hdo")));
|
||||
v8::ScriptOrigin origin(v8_str("test_hdo"), // resource_name
|
||||
0, // resource_line_offset
|
||||
0, // resource_column_offset
|
||||
false, // resource_is_shared_cross_origin
|
||||
-1, // script_id
|
||||
{}, // source_map_url
|
||||
false, // resource_is_opaque
|
||||
false, // is_wasm
|
||||
false, // is_module
|
||||
hdo // host_defined_options
|
||||
);
|
||||
ScriptCompiler::CachedData* cache;
|
||||
{
|
||||
v8::ScriptCompiler::Source script_source(source, origin);
|
||||
v8::Local<v8::Function> fun =
|
||||
v8::ScriptCompiler::CompileFunction(
|
||||
env.local(), &script_source, 1, &arg_str, 0, nullptr,
|
||||
v8::ScriptCompiler::kNoCompileOptions)
|
||||
.ToLocalChecked();
|
||||
cache = v8::ScriptCompiler::CreateCodeCacheForFunction(fun);
|
||||
}
|
||||
|
||||
{
|
||||
DisallowCompilation no_compile_expected(i_isolate);
|
||||
v8::ScriptCompiler::Source script_source(source, origin, cache);
|
||||
v8::Local<v8::Function> fun =
|
||||
v8::ScriptCompiler::CompileFunction(
|
||||
env.local(), &script_source, 1, &arg_str, 0, nullptr,
|
||||
v8::ScriptCompiler::kConsumeCodeCache)
|
||||
.ToLocalChecked();
|
||||
v8::Local<v8::Value> arg = v8_str("foo");
|
||||
v8::Local<v8::Value> result =
|
||||
fun->Call(env.local(), v8::Undefined(isolate), 1, &arg)
|
||||
.ToLocalChecked();
|
||||
CHECK(result->IsPromise());
|
||||
v8::Local<v8::Promise> promise = result.As<v8::Promise>();
|
||||
isolate->PerformMicrotaskCheckpoint();
|
||||
v8::Local<v8::Value> resolved = promise->Result();
|
||||
CHECK(resolved->IsString());
|
||||
CHECK(resolved.As<v8::String>()
|
||||
->Equals(env.local(), v8_str("hello"))
|
||||
.FromJust());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CachedUnboundScriptHostDefinedOption) {
|
||||
DisableAlwaysOpt();
|
||||
LocalContext env;
|
||||
v8::Isolate* isolate = env->GetIsolate();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
i_isolate->compilation_cache()
|
||||
->DisableScriptAndEval(); // Disable same-isolate code cache.
|
||||
isolate->SetHostImportModuleDynamicallyCallback(
|
||||
TestHostDefinedOptionFromCachedScript);
|
||||
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
v8::Local<v8::String> source = v8_str("globalThis.foo =import('foo')");
|
||||
|
||||
v8::Local<v8::PrimitiveArray> hdo = v8::PrimitiveArray::New(isolate, 1);
|
||||
hdo->Set(isolate, 0, v8::Symbol::For(isolate, v8_str("hdo")));
|
||||
v8::ScriptOrigin origin(v8_str("test_hdo"), // resource_name
|
||||
0, // resource_line_offset
|
||||
0, // resource_column_offset
|
||||
false, // resource_is_shared_cross_origin
|
||||
-1, // script_id
|
||||
{}, // source_map_url
|
||||
false, // resource_is_opaque
|
||||
false, // is_wasm
|
||||
false, // is_module
|
||||
hdo // host_defined_options
|
||||
);
|
||||
ScriptCompiler::CachedData* cache;
|
||||
{
|
||||
v8::ScriptCompiler::Source script_source(source, origin);
|
||||
v8::Local<v8::UnboundScript> script =
|
||||
v8::ScriptCompiler::CompileUnboundScript(
|
||||
isolate, &script_source, v8::ScriptCompiler::kNoCompileOptions)
|
||||
.ToLocalChecked();
|
||||
cache = v8::ScriptCompiler::CreateCodeCache(script);
|
||||
}
|
||||
|
||||
{
|
||||
DisallowCompilation no_compile_expected(i_isolate);
|
||||
v8::ScriptCompiler::Source script_source(source, origin, cache);
|
||||
v8::Local<v8::UnboundScript> script =
|
||||
v8::ScriptCompiler::CompileUnboundScript(
|
||||
isolate, &script_source, v8::ScriptCompiler::kConsumeCodeCache)
|
||||
.ToLocalChecked();
|
||||
v8::Local<v8::Script> bound = script->BindToCurrentContext();
|
||||
USE(bound->Run(env.local(), hdo).ToLocalChecked());
|
||||
v8::Local<v8::Value> result =
|
||||
env.local()->Global()->Get(env.local(), v8_str("foo")).ToLocalChecked();
|
||||
CHECK(result->IsPromise());
|
||||
v8::Local<v8::Promise> promise = result.As<v8::Promise>();
|
||||
isolate->PerformMicrotaskCheckpoint();
|
||||
v8::Local<v8::Value> resolved = promise->Result();
|
||||
CHECK(resolved->IsString());
|
||||
CHECK(resolved.As<v8::String>()
|
||||
->Equals(env.local(), v8_str("hello"))
|
||||
.FromJust());
|
||||
}
|
||||
}
|
||||
|
||||
v8::MaybeLocal<v8::Module> UnexpectedModuleResolveCallback(
|
||||
v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
|
||||
v8::Local<v8::FixedArray> import_attributes,
|
||||
v8::Local<v8::Module> referrer) {
|
||||
CHECK_WITH_MSG(false, "Unexpected call to resolve callback");
|
||||
}
|
||||
|
||||
TEST(CachedModuleScriptFunctionHostDefinedOption) {
|
||||
DisableAlwaysOpt();
|
||||
LocalContext env;
|
||||
v8::Isolate* isolate = env->GetIsolate();
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
i_isolate->compilation_cache()
|
||||
->DisableScriptAndEval(); // Disable same-isolate code cache.
|
||||
isolate->SetHostImportModuleDynamicallyCallback(
|
||||
TestHostDefinedOptionFromCachedScript);
|
||||
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
v8::Local<v8::String> source = v8_str("globalThis.foo = import('foo')");
|
||||
|
||||
v8::Local<v8::PrimitiveArray> hdo = v8::PrimitiveArray::New(isolate, 1);
|
||||
hdo->Set(isolate, 0, v8::Symbol::For(isolate, v8_str("hdo")));
|
||||
v8::ScriptOrigin origin(v8_str("test_hdo"), // resource_name
|
||||
0, // resource_line_offset
|
||||
0, // resource_column_offset
|
||||
false, // resource_is_shared_cross_origin
|
||||
-1, // script_id
|
||||
{}, // source_map_url
|
||||
false, // resource_is_opaque
|
||||
false, // is_wasm
|
||||
true, // is_module
|
||||
hdo // host_defined_options
|
||||
);
|
||||
ScriptCompiler::CachedData* cache;
|
||||
{
|
||||
v8::ScriptCompiler::Source script_source(source, origin);
|
||||
v8::Local<v8::Module> mod =
|
||||
v8::ScriptCompiler::CompileModule(isolate, &script_source,
|
||||
v8::ScriptCompiler::kNoCompileOptions)
|
||||
.ToLocalChecked();
|
||||
cache = v8::ScriptCompiler::CreateCodeCache(mod->GetUnboundModuleScript());
|
||||
}
|
||||
|
||||
{
|
||||
DisallowCompilation no_compile_expected(i_isolate);
|
||||
v8::ScriptCompiler::Source script_source(source, origin, cache);
|
||||
v8::Local<v8::Module> mod =
|
||||
v8::ScriptCompiler::CompileModule(isolate, &script_source,
|
||||
v8::ScriptCompiler::kConsumeCodeCache)
|
||||
.ToLocalChecked();
|
||||
mod->InstantiateModule(env.local(), UnexpectedModuleResolveCallback)
|
||||
.Check();
|
||||
v8::Local<v8::Value> evaluted = mod->Evaluate(env.local()).ToLocalChecked();
|
||||
CHECK(evaluted->IsPromise());
|
||||
CHECK_EQ(evaluted.As<v8::Promise>()->State(),
|
||||
v8::Promise::PromiseState::kFulfilled);
|
||||
v8::Local<v8::Value> result =
|
||||
env.local()->Global()->Get(env.local(), v8_str("foo")).ToLocalChecked();
|
||||
v8::Local<v8::Promise> promise = result.As<v8::Promise>();
|
||||
isolate->PerformMicrotaskCheckpoint();
|
||||
v8::Local<v8::Value> resolved = promise->Result();
|
||||
CHECK(resolved->IsString());
|
||||
CHECK(resolved.As<v8::String>()
|
||||
->Equals(env.local(), v8_str("hello"))
|
||||
.FromJust());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CachedCompileFunction) {
|
||||
DisableAlwaysOpt();
|
||||
LocalContext env;
|
||||
|
Loading…
Reference in New Issue
Block a user