[api] Add a dedicated UnboundModuleScript type
Module and script SharedFunctionInfos can't be used interchangeably (e.g.: it should not be possible to bind a Module's SFI to a Context). The dedicated type disambiguates the two. This also adds an overload for CreateCodeCache which takes an unbound module script instead of an unbound script. Both are just a SFI underneath, so their behavior is identical. Bug: v8:7685 Cq-Include-Trybots: luci.chromium.try:linux_chromium_rel_ng Change-Id: Iab519d0d50b6b41c95abdb6397f5622e292da4d8 Reviewed-on: https://chromium-review.googlesource.com/1047107 Commit-Queue: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#53150}
This commit is contained in:
parent
fb4163e330
commit
8ec92f5118
19
include/v8.h
19
include/v8.h
@ -1212,6 +1212,13 @@ class V8_EXPORT UnboundScript {
|
||||
static const int kNoScriptId = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* A compiled JavaScript module, not yet tied to a Context.
|
||||
*/
|
||||
class V8_EXPORT UnboundModuleScript {
|
||||
// Only used as a container for code caching.
|
||||
};
|
||||
|
||||
/**
|
||||
* A location in JavaScript source.
|
||||
*/
|
||||
@ -1313,12 +1320,12 @@ class V8_EXPORT Module {
|
||||
Local<Value> GetModuleNamespace();
|
||||
|
||||
/**
|
||||
* Returns the corresponding context-unbound script.
|
||||
* Returns the corresponding context-unbound module script.
|
||||
*
|
||||
* The module must be unevaluated, i.e. its status must not be kEvaluating,
|
||||
* kEvaluated or kErrored.
|
||||
*/
|
||||
Local<UnboundScript> GetUnboundScript();
|
||||
Local<UnboundModuleScript> GetUnboundModuleScript();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1677,6 +1684,14 @@ class V8_EXPORT ScriptCompiler {
|
||||
*/
|
||||
static CachedData* CreateCodeCache(Local<UnboundScript> unbound_script);
|
||||
|
||||
/**
|
||||
* Creates and returns code cache for the specified unbound_module_script.
|
||||
* This will return nullptr if the script cannot be serialized. The
|
||||
* CachedData returned by this function should be owned by the caller.
|
||||
*/
|
||||
static CachedData* CreateCodeCache(
|
||||
Local<UnboundModuleScript> unbound_module_script);
|
||||
|
||||
V8_DEPRECATED("Source string is no longer required",
|
||||
static CachedData* CreateCodeCache(
|
||||
Local<UnboundScript> unbound_script, Local<String> source));
|
||||
|
14
src/api.cc
14
src/api.cc
@ -2323,12 +2323,12 @@ Local<Value> Module::GetModuleNamespace() {
|
||||
return ToApiHandle<Value>(module_namespace);
|
||||
}
|
||||
|
||||
Local<UnboundScript> Module::GetUnboundScript() {
|
||||
Local<UnboundModuleScript> Module::GetUnboundModuleScript() {
|
||||
Utils::ApiCheck(
|
||||
GetStatus() < kEvaluating, "v8::Module::GetUnboundScript",
|
||||
"v8::Module::GetUnboundScript must be used on an unevaluated module");
|
||||
i::Handle<i::Module> self = Utils::OpenHandle(this);
|
||||
return ToApiHandle<UnboundScript>(
|
||||
return ToApiHandle<UnboundModuleScript>(
|
||||
i::Handle<i::SharedFunctionInfo>(self->GetSharedFunctionInfo()));
|
||||
}
|
||||
|
||||
@ -2673,6 +2673,16 @@ ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
|
||||
return i::CodeSerializer::Serialize(shared);
|
||||
}
|
||||
|
||||
// static
|
||||
ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCache(
|
||||
Local<UnboundModuleScript> unbound_module_script) {
|
||||
i::Handle<i::SharedFunctionInfo> shared =
|
||||
i::Handle<i::SharedFunctionInfo>::cast(
|
||||
Utils::OpenHandle(*unbound_module_script));
|
||||
DCHECK(shared->is_toplevel());
|
||||
return i::CodeSerializer::Serialize(shared);
|
||||
}
|
||||
|
||||
ScriptCompiler::CachedData* ScriptCompiler::CreateCodeCacheForFunction(
|
||||
Local<Function> function, Local<String> source) {
|
||||
return CreateCodeCacheForFunction(function);
|
||||
|
@ -112,6 +112,7 @@ class RegisteredExtension {
|
||||
V(String, String) \
|
||||
V(Symbol, Symbol) \
|
||||
V(Script, JSFunction) \
|
||||
V(UnboundModuleScript, SharedFunctionInfo) \
|
||||
V(UnboundScript, SharedFunctionInfo) \
|
||||
V(Module, Module) \
|
||||
V(Function, JSReceiver) \
|
||||
|
@ -25636,6 +25636,55 @@ TEST(CodeCache) {
|
||||
isolate2->Dispose();
|
||||
}
|
||||
|
||||
v8::MaybeLocal<Module> UnexpectedModuleResolveCallback(Local<Context> context,
|
||||
Local<String> specifier,
|
||||
Local<Module> referrer) {
|
||||
CHECK_WITH_MSG(false, "Unexpected call to resolve callback");
|
||||
}
|
||||
|
||||
TEST(ModuleCodeCache) {
|
||||
v8::Isolate::CreateParams create_params;
|
||||
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
|
||||
|
||||
const char* origin = "code cache test";
|
||||
v8::ScriptCompiler::CachedData* cache;
|
||||
|
||||
v8::Isolate* isolate1 = v8::Isolate::New(create_params);
|
||||
{
|
||||
v8::Isolate::Scope iscope(isolate1);
|
||||
v8::HandleScope scope(isolate1);
|
||||
v8::Local<v8::Context> context = v8::Context::New(isolate1);
|
||||
v8::Context::Scope cscope(context);
|
||||
|
||||
Local<String> source_text = v8_str(
|
||||
"export default 5; export const a = 10; function f() { return 42; } "
|
||||
"(function() { return f(); })();");
|
||||
v8::ScriptOrigin script_origin(
|
||||
v8_str(origin), Local<v8::Integer>(), Local<v8::Integer>(),
|
||||
Local<v8::Boolean>(), Local<v8::Integer>(), Local<v8::Value>(),
|
||||
Local<v8::Boolean>(), Local<v8::Boolean>(), True(isolate1));
|
||||
v8::ScriptCompiler::Source source(source_text, script_origin);
|
||||
Local<Module> module =
|
||||
v8::ScriptCompiler::CompileModule(isolate1, &source).ToLocalChecked();
|
||||
module->InstantiateModule(context, UnexpectedModuleResolveCallback)
|
||||
.ToChecked();
|
||||
|
||||
// Fetch the shared function info before evaluation.
|
||||
Local<v8::UnboundModuleScript> unbound_module_script =
|
||||
module->GetUnboundModuleScript();
|
||||
|
||||
// Evaluate for possible lazy compilation.
|
||||
Local<Value> completion_value = module->Evaluate(context).ToLocalChecked();
|
||||
CHECK_EQ(42, completion_value->Int32Value(context).FromJust());
|
||||
|
||||
// Now create the cache.
|
||||
cache = v8::ScriptCompiler::CreateCodeCache(unbound_module_script);
|
||||
}
|
||||
isolate1->Dispose();
|
||||
|
||||
// TODO(jgruber,v8:7685): Test module code cache consumption once implemented.
|
||||
delete cache;
|
||||
}
|
||||
|
||||
void TestInvalidCacheData(v8::ScriptCompiler::CompileOptions option) {
|
||||
const char* garbage = "garbage garbage garbage garbage garbage garbage";
|
||||
@ -27370,12 +27419,6 @@ void HostInitializeImportMetaObjectCallbackStatic(Local<Context> context,
|
||||
meta->CreateDataProperty(context, v8_str("foo"), v8_str("bar")).ToChecked();
|
||||
}
|
||||
|
||||
v8::MaybeLocal<Module> UnexpectedModuleResolveCallback(Local<Context> context,
|
||||
Local<String> specifier,
|
||||
Local<Module> referrer) {
|
||||
CHECK_WITH_MSG(false, "Unexpected call to resolve callback");
|
||||
}
|
||||
|
||||
TEST(ImportMeta) {
|
||||
i::FLAG_harmony_dynamic_import = true;
|
||||
i::FLAG_harmony_import_meta = true;
|
||||
@ -27443,7 +27486,7 @@ TEST(GetModuleNamespace) {
|
||||
->StrictEquals(v8::Number::New(isolate, 10)));
|
||||
}
|
||||
|
||||
TEST(ModuleGetUnboundScript) {
|
||||
TEST(ModuleGetUnboundModuleScript) {
|
||||
LocalContext context;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
@ -27457,11 +27500,12 @@ TEST(ModuleGetUnboundScript) {
|
||||
v8::ScriptCompiler::Source source(source_text, origin);
|
||||
Local<Module> module =
|
||||
v8::ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
|
||||
Local<v8::UnboundScript> sfi_before_instantiation =
|
||||
module->GetUnboundScript();
|
||||
Local<v8::UnboundModuleScript> sfi_before_instantiation =
|
||||
module->GetUnboundModuleScript();
|
||||
module->InstantiateModule(context.local(), UnexpectedModuleResolveCallback)
|
||||
.ToChecked();
|
||||
Local<v8::UnboundScript> sfi_after_instantiation = module->GetUnboundScript();
|
||||
Local<v8::UnboundModuleScript> sfi_after_instantiation =
|
||||
module->GetUnboundModuleScript();
|
||||
|
||||
// Check object identity.
|
||||
{
|
||||
@ -27469,11 +27513,6 @@ TEST(ModuleGetUnboundScript) {
|
||||
i::Handle<i::Object> s2 = v8::Utils::OpenHandle(*sfi_after_instantiation);
|
||||
CHECK_EQ(*s1, *s2);
|
||||
}
|
||||
|
||||
// Check unbound script values.
|
||||
Local<v8::UnboundScript> sfi = sfi_after_instantiation;
|
||||
CHECK(ValueEqualsString(isolate, sfi->GetScriptName(), "www.google.com"));
|
||||
CHECK_EQ(0, sfi->GetLineNumber(0));
|
||||
}
|
||||
|
||||
TEST(GlobalTemplateWithDoubleProperty) {
|
||||
|
Loading…
Reference in New Issue
Block a user