[modules] Disallow throwing in import.meta callback
... via a comment in the API and a CHECK in Isolate::RunHostInitializeImportMetaObjectCallback. Also restructure things a little bit such that this function really just runs the callback and doesn't deal with module internals. Memoization now happens in the SourceTextModule class. Bug: v8:7044 Change-Id: I5b850ae629c3638c4b30dfdeaa996642a33d14dc Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2190413 Reviewed-by: Sathya Gunasekaran <gsathya@chromium.org> Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Toon Verwaest <verwaest@chromium.org> Auto-Submit: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#67682}
This commit is contained in:
parent
b1a0dd8503
commit
5bf4772878
@ -7219,7 +7219,8 @@ typedef MaybeLocal<Promise> (*HostImportModuleDynamicallyCallback)(
|
||||
|
||||
/**
|
||||
* HostInitializeImportMetaObjectCallback is called the first time import.meta
|
||||
* is accessed for a module. Subsequent access will reuse the same value.
|
||||
* is accessed for a module. Subsequent access will reuse the same value. The
|
||||
* callback must not throw.
|
||||
*
|
||||
* The method combines two implementation-defined abstract operations into one:
|
||||
* HostGetImportMetaProperties and HostFinalizeImportMeta.
|
||||
|
@ -3952,19 +3952,17 @@ void Isolate::SetHostImportModuleDynamicallyCallback(
|
||||
|
||||
Handle<JSObject> Isolate::RunHostInitializeImportMetaObjectCallback(
|
||||
Handle<SourceTextModule> module) {
|
||||
Handle<HeapObject> host_meta(module->import_meta(), this);
|
||||
if (host_meta->IsTheHole(this)) {
|
||||
host_meta = factory()->NewJSObjectWithNullProto();
|
||||
if (host_initialize_import_meta_object_callback_ != nullptr) {
|
||||
v8::Local<v8::Context> api_context =
|
||||
v8::Utils::ToLocal(Handle<Context>(native_context()));
|
||||
host_initialize_import_meta_object_callback_(
|
||||
api_context, Utils::ToLocal(Handle<Module>::cast(module)),
|
||||
v8::Local<v8::Object>::Cast(v8::Utils::ToLocal(host_meta)));
|
||||
}
|
||||
module->set_import_meta(*host_meta);
|
||||
CHECK(module->import_meta().IsTheHole(this));
|
||||
Handle<JSObject> import_meta = factory()->NewJSObjectWithNullProto();
|
||||
if (host_initialize_import_meta_object_callback_ != nullptr) {
|
||||
v8::Local<v8::Context> api_context =
|
||||
v8::Utils::ToLocal(Handle<Context>(native_context()));
|
||||
host_initialize_import_meta_object_callback_(
|
||||
api_context, Utils::ToLocal(Handle<Module>::cast(module)),
|
||||
v8::Local<v8::Object>::Cast(v8::Utils::ToLocal(import_meta)));
|
||||
CHECK(!has_scheduled_exception());
|
||||
}
|
||||
return Handle<JSObject>::cast(host_meta);
|
||||
return import_meta;
|
||||
}
|
||||
|
||||
void Isolate::SetHostInitializeImportMetaObjectCallback(
|
||||
|
@ -583,6 +583,16 @@ Handle<JSModuleNamespace> SourceTextModule::GetModuleNamespace(
|
||||
return Module::GetModuleNamespace(isolate, requested_module);
|
||||
}
|
||||
|
||||
Handle<JSObject> SourceTextModule::GetImportMeta(
|
||||
Isolate* isolate, Handle<SourceTextModule> module) {
|
||||
Handle<HeapObject> import_meta(module->import_meta(), isolate);
|
||||
if (import_meta->IsTheHole(isolate)) {
|
||||
import_meta = isolate->RunHostInitializeImportMetaObjectCallback(module);
|
||||
module->set_import_meta(*import_meta);
|
||||
}
|
||||
return Handle<JSObject>::cast(import_meta);
|
||||
}
|
||||
|
||||
MaybeHandle<Object> SourceTextModule::EvaluateMaybeAsync(
|
||||
Isolate* isolate, Handle<SourceTextModule> module) {
|
||||
// In the event of errored evaluation, return a rejected promise.
|
||||
|
@ -59,6 +59,11 @@ class SourceTextModule
|
||||
static Handle<JSModuleNamespace> GetModuleNamespace(
|
||||
Isolate* isolate, Handle<SourceTextModule> module, int module_request);
|
||||
|
||||
// Get the import.meta object of [module]. If it doesn't exist yet, it is
|
||||
// created and passed to the embedder callback for initialization.
|
||||
V8_EXPORT_PRIVATE static Handle<JSObject> GetImportMeta(
|
||||
Isolate* isolate, Handle<SourceTextModule> module);
|
||||
|
||||
using BodyDescriptor =
|
||||
SubclassBodyDescriptor<Module::BodyDescriptor,
|
||||
FixedBodyDescriptor<kCodeOffset, kSize, kSize>>;
|
||||
|
@ -41,7 +41,7 @@ RUNTIME_FUNCTION(Runtime_GetImportMetaObject) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(0, args.length());
|
||||
Handle<SourceTextModule> module(isolate->context().module(), isolate);
|
||||
return *isolate->RunHostInitializeImportMetaObjectCallback(module);
|
||||
return *SourceTextModule::GetImportMeta(isolate, module);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
@ -25760,7 +25760,6 @@ void HostInitializeImportMetaObjectCallbackStatic(Local<Context> context,
|
||||
Local<Module> module,
|
||||
Local<Object> meta) {
|
||||
CHECK(!module.IsEmpty());
|
||||
|
||||
meta->CreateDataProperty(context, v8_str("foo"), v8_str("bar")).ToChecked();
|
||||
}
|
||||
|
||||
@ -25784,10 +25783,9 @@ TEST(ImportMeta) {
|
||||
v8::ScriptCompiler::Source source(source_text, origin);
|
||||
Local<Module> module =
|
||||
v8::ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
|
||||
i::Handle<i::Object> meta =
|
||||
i_isolate->RunHostInitializeImportMetaObjectCallback(
|
||||
i::Handle<i::SourceTextModule>::cast(v8::Utils::OpenHandle(*module)));
|
||||
CHECK(meta->IsJSObject());
|
||||
i::Handle<i::JSObject> meta = i::SourceTextModule::GetImportMeta(
|
||||
i_isolate,
|
||||
i::Handle<i::SourceTextModule>::cast(v8::Utils::OpenHandle(*module)));
|
||||
Local<Object> meta_obj = Local<Object>::Cast(v8::Utils::ToLocal(meta));
|
||||
CHECK(meta_obj->Get(context.local(), v8_str("foo"))
|
||||
.ToLocalChecked()
|
||||
|
Loading…
Reference in New Issue
Block a user