[modules] Add an IsModule flag to ScriptOriginOptions.
Since the script origin is part of the key used in the compilation cache, this ensures that the cache never confuses a module with a non-module script. BUG=v8:1569,v8:5685 Review-Url: https://codereview.chromium.org/2611643002 Cr-Commit-Position: refs/heads/master@{#42490}
This commit is contained in:
parent
975430161e
commit
b0f5abbea3
34
include/v8.h
34
include/v8.h
@ -962,20 +962,31 @@ class V8_EXPORT Data {
|
||||
class ScriptOriginOptions {
|
||||
public:
|
||||
V8_INLINE ScriptOriginOptions(bool is_shared_cross_origin = false,
|
||||
bool is_opaque = false, bool is_wasm = false)
|
||||
bool is_opaque = false, bool is_wasm = false,
|
||||
bool is_module = false)
|
||||
: flags_((is_shared_cross_origin ? kIsSharedCrossOrigin : 0) |
|
||||
(is_wasm ? kIsWasm : 0) | (is_opaque ? kIsOpaque : 0)) {}
|
||||
(is_wasm ? kIsWasm : 0) | (is_opaque ? kIsOpaque : 0) |
|
||||
(is_module ? kIsModule : 0)) {}
|
||||
V8_INLINE ScriptOriginOptions(int flags)
|
||||
: flags_(flags & (kIsSharedCrossOrigin | kIsOpaque | kIsWasm)) {}
|
||||
: flags_(flags &
|
||||
(kIsSharedCrossOrigin | kIsOpaque | kIsWasm | kIsModule)) {}
|
||||
|
||||
bool IsSharedCrossOrigin() const {
|
||||
return (flags_ & kIsSharedCrossOrigin) != 0;
|
||||
}
|
||||
bool IsOpaque() const { return (flags_ & kIsOpaque) != 0; }
|
||||
bool IsWasm() const { return (flags_ & kIsWasm) != 0; }
|
||||
bool IsModule() const { return (flags_ & kIsModule) != 0; }
|
||||
|
||||
int Flags() const { return flags_; }
|
||||
|
||||
private:
|
||||
enum { kIsSharedCrossOrigin = 1, kIsOpaque = 1 << 1, kIsWasm = 1 << 2 };
|
||||
enum {
|
||||
kIsSharedCrossOrigin = 1,
|
||||
kIsOpaque = 1 << 1,
|
||||
kIsWasm = 1 << 2,
|
||||
kIsModule = 1 << 3
|
||||
};
|
||||
const int flags_;
|
||||
};
|
||||
|
||||
@ -992,7 +1003,8 @@ class ScriptOrigin {
|
||||
Local<Integer> script_id = Local<Integer>(),
|
||||
Local<Value> source_map_url = Local<Value>(),
|
||||
Local<Boolean> resource_is_opaque = Local<Boolean>(),
|
||||
Local<Boolean> is_wasm = Local<Boolean>());
|
||||
Local<Boolean> is_wasm = Local<Boolean>(),
|
||||
Local<Boolean> is_module = Local<Boolean>());
|
||||
|
||||
V8_INLINE Local<Value> ResourceName() const;
|
||||
V8_INLINE Local<Integer> ResourceLineOffset() const;
|
||||
@ -1183,6 +1195,8 @@ class V8_EXPORT ScriptCompiler {
|
||||
// alive.
|
||||
V8_INLINE const CachedData* GetCachedData() const;
|
||||
|
||||
V8_INLINE const ScriptOriginOptions& GetResourceOptions() const;
|
||||
|
||||
// Prevent copying.
|
||||
Source(const Source&) = delete;
|
||||
Source& operator=(const Source&) = delete;
|
||||
@ -1425,7 +1439,7 @@ class V8_EXPORT ScriptCompiler {
|
||||
|
||||
private:
|
||||
static V8_WARN_UNUSED_RESULT MaybeLocal<UnboundScript> CompileUnboundInternal(
|
||||
Isolate* isolate, Source* source, CompileOptions options, bool is_module);
|
||||
Isolate* isolate, Source* source, CompileOptions options);
|
||||
};
|
||||
|
||||
|
||||
@ -8987,14 +9001,15 @@ ScriptOrigin::ScriptOrigin(Local<Value> resource_name,
|
||||
Local<Integer> script_id,
|
||||
Local<Value> source_map_url,
|
||||
Local<Boolean> resource_is_opaque,
|
||||
Local<Boolean> is_wasm)
|
||||
Local<Boolean> is_wasm, Local<Boolean> is_module)
|
||||
: resource_name_(resource_name),
|
||||
resource_line_offset_(resource_line_offset),
|
||||
resource_column_offset_(resource_column_offset),
|
||||
options_(!resource_is_shared_cross_origin.IsEmpty() &&
|
||||
resource_is_shared_cross_origin->IsTrue(),
|
||||
!resource_is_opaque.IsEmpty() && resource_is_opaque->IsTrue(),
|
||||
!is_wasm.IsEmpty() && is_wasm->IsTrue()),
|
||||
!is_wasm.IsEmpty() && is_wasm->IsTrue(),
|
||||
!is_module.IsEmpty() && is_module->IsTrue()),
|
||||
script_id_(script_id),
|
||||
source_map_url_(source_map_url) {}
|
||||
|
||||
@ -9043,6 +9058,9 @@ const ScriptCompiler::CachedData* ScriptCompiler::Source::GetCachedData()
|
||||
return cached_data;
|
||||
}
|
||||
|
||||
const ScriptOriginOptions& ScriptCompiler::Source::GetResourceOptions() const {
|
||||
return resource_options;
|
||||
}
|
||||
|
||||
Local<Boolean> Boolean::New(Isolate* isolate, bool value) {
|
||||
return value ? True(isolate) : False(isolate);
|
||||
|
25
src/api.cc
25
src/api.cc
@ -283,7 +283,8 @@ static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
|
||||
v8::Integer::New(v8_isolate, script->id()),
|
||||
Utils::ToLocal(source_map_url),
|
||||
v8::Boolean::New(v8_isolate, options.IsOpaque()),
|
||||
v8::Boolean::New(v8_isolate, script->type() == i::Script::TYPE_WASM));
|
||||
v8::Boolean::New(v8_isolate, script->type() == i::Script::TYPE_WASM),
|
||||
v8::Boolean::New(v8_isolate, options.IsModule()));
|
||||
return origin;
|
||||
}
|
||||
|
||||
@ -2103,8 +2104,7 @@ MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
|
||||
}
|
||||
|
||||
MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
|
||||
Isolate* v8_isolate, Source* source, CompileOptions options,
|
||||
bool is_module) {
|
||||
Isolate* v8_isolate, Source* source, CompileOptions options) {
|
||||
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
|
||||
PREPARE_FOR_EXECUTION_WITH_ISOLATE(isolate, ScriptCompiler, CompileUnbound,
|
||||
UnboundScript);
|
||||
@ -2149,7 +2149,7 @@ MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
|
||||
result = i::Compiler::GetSharedFunctionInfoForScript(
|
||||
str, name_obj, line_offset, column_offset, source->resource_options,
|
||||
source_map_url, isolate->native_context(), NULL, &script_data, options,
|
||||
i::NOT_NATIVES_CODE, is_module);
|
||||
i::NOT_NATIVES_CODE);
|
||||
has_pending_exception = result.is_null();
|
||||
if (has_pending_exception && script_data != NULL) {
|
||||
// This case won't happen during normal operation; we have compiled
|
||||
@ -2178,24 +2178,26 @@ MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
|
||||
|
||||
MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundScript(
|
||||
Isolate* v8_isolate, Source* source, CompileOptions options) {
|
||||
return CompileUnboundInternal(v8_isolate, source, options, false);
|
||||
DCHECK(!source->GetResourceOptions().IsModule());
|
||||
return CompileUnboundInternal(v8_isolate, source, options);
|
||||
}
|
||||
|
||||
|
||||
Local<UnboundScript> ScriptCompiler::CompileUnbound(Isolate* v8_isolate,
|
||||
Source* source,
|
||||
CompileOptions options) {
|
||||
RETURN_TO_LOCAL_UNCHECKED(
|
||||
CompileUnboundInternal(v8_isolate, source, options, false),
|
||||
UnboundScript);
|
||||
DCHECK(!source->GetResourceOptions().IsModule());
|
||||
RETURN_TO_LOCAL_UNCHECKED(CompileUnboundInternal(v8_isolate, source, options),
|
||||
UnboundScript);
|
||||
}
|
||||
|
||||
|
||||
MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
|
||||
Source* source,
|
||||
CompileOptions options) {
|
||||
DCHECK(!source->GetResourceOptions().IsModule());
|
||||
auto isolate = context->GetIsolate();
|
||||
auto maybe = CompileUnboundInternal(isolate, source, options, false);
|
||||
auto maybe = CompileUnboundInternal(isolate, source, options);
|
||||
Local<UnboundScript> result;
|
||||
if (!maybe.ToLocal(&result)) return MaybeLocal<Script>();
|
||||
v8::Context::Scope scope(context);
|
||||
@ -2215,7 +2217,8 @@ MaybeLocal<Module> ScriptCompiler::CompileModule(Isolate* isolate,
|
||||
Source* source) {
|
||||
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
|
||||
|
||||
auto maybe = CompileUnboundInternal(isolate, source, kNoCompileOptions, true);
|
||||
DCHECK(source->GetResourceOptions().IsModule());
|
||||
auto maybe = CompileUnboundInternal(isolate, source, kNoCompileOptions);
|
||||
Local<UnboundScript> unbound;
|
||||
if (!maybe.ToLocal(&unbound)) return MaybeLocal<Module>();
|
||||
|
||||
@ -9311,7 +9314,7 @@ MaybeLocal<UnboundScript> debug::CompileInspectorScript(Isolate* v8_isolate,
|
||||
result = i::Compiler::GetSharedFunctionInfoForScript(
|
||||
str, i::Handle<i::Object>(), 0, 0, origin_options,
|
||||
i::Handle<i::Object>(), isolate->native_context(), NULL, &script_data,
|
||||
ScriptCompiler::kNoCompileOptions, i::INSPECTOR_CODE, false);
|
||||
ScriptCompiler::kNoCompileOptions, i::INSPECTOR_CODE);
|
||||
has_pending_exception = result.is_null();
|
||||
RETURN_ON_FAILED_EXECUTION(UnboundScript);
|
||||
}
|
||||
|
@ -2992,8 +2992,7 @@ bool Bootstrapper::CompileNative(Isolate* isolate, Vector<const char> name,
|
||||
Handle<SharedFunctionInfo> function_info =
|
||||
Compiler::GetSharedFunctionInfoForScript(
|
||||
source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
|
||||
context, NULL, NULL, ScriptCompiler::kNoCompileOptions, natives_flag,
|
||||
false);
|
||||
context, NULL, NULL, ScriptCompiler::kNoCompileOptions, natives_flag);
|
||||
if (function_info.is_null()) return false;
|
||||
|
||||
DCHECK(context->IsNativeContext());
|
||||
@ -3056,7 +3055,7 @@ bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
|
||||
function_info = Compiler::GetSharedFunctionInfoForScript(
|
||||
source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
|
||||
context, extension, NULL, ScriptCompiler::kNoCompileOptions,
|
||||
EXTENSION_CODE, false);
|
||||
EXTENSION_CODE);
|
||||
if (function_info.is_null()) return false;
|
||||
cache->Add(name, function_info);
|
||||
}
|
||||
|
@ -1490,8 +1490,7 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
|
||||
int column_offset, ScriptOriginOptions resource_options,
|
||||
Handle<Object> source_map_url, Handle<Context> context,
|
||||
v8::Extension* extension, ScriptData** cached_data,
|
||||
ScriptCompiler::CompileOptions compile_options, NativesFlag natives,
|
||||
bool is_module) {
|
||||
ScriptCompiler::CompileOptions compile_options, NativesFlag natives) {
|
||||
Isolate* isolate = source->GetIsolate();
|
||||
if (compile_options == ScriptCompiler::kNoCompileOptions) {
|
||||
cached_data = NULL;
|
||||
@ -1578,7 +1577,7 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
|
||||
Zone zone(isolate->allocator(), ZONE_NAME);
|
||||
ParseInfo parse_info(&zone, script);
|
||||
CompilationInfo info(&parse_info, Handle<JSFunction>::null());
|
||||
if (is_module) parse_info.set_module();
|
||||
if (resource_options.IsModule()) parse_info.set_module();
|
||||
if (compile_options != ScriptCompiler::kNoCompileOptions) {
|
||||
parse_info.set_cached_data(cached_data);
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ class Compiler : public AllStatic {
|
||||
Handle<Object> source_map_url, Handle<Context> context,
|
||||
v8::Extension* extension, ScriptData** cached_data,
|
||||
ScriptCompiler::CompileOptions compile_options,
|
||||
NativesFlag is_natives_code, bool is_module);
|
||||
NativesFlag is_natives_code);
|
||||
|
||||
// Create a shared function info object for a Script that has already been
|
||||
// parsed while the script was being loaded from a streamed source.
|
||||
|
@ -694,7 +694,9 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Context> context,
|
||||
}
|
||||
ScriptOrigin origin(
|
||||
String::NewFromUtf8(isolate, file_name.c_str(), NewStringType::kNormal)
|
||||
.ToLocalChecked());
|
||||
.ToLocalChecked(),
|
||||
Local<Integer>(), Local<Integer>(), Local<Boolean>(), Local<Integer>(),
|
||||
Local<Value>(), Local<Boolean>(), Local<Boolean>(), True(isolate));
|
||||
ScriptCompiler::Source source(source_text, origin);
|
||||
Local<Module> module;
|
||||
if (!ScriptCompiler::CompileModule(isolate, &source).ToLocal(&module)) {
|
||||
|
@ -6967,7 +6967,7 @@ class Script: public Struct {
|
||||
static const int kCompilationTypeBit = 0;
|
||||
static const int kCompilationStateBit = 1;
|
||||
static const int kOriginOptionsShift = 2;
|
||||
static const int kOriginOptionsSize = 3;
|
||||
static const int kOriginOptionsSize = 4;
|
||||
static const int kOriginOptionsMask = ((1 << kOriginOptionsSize) - 1)
|
||||
<< kOriginOptionsShift;
|
||||
|
||||
|
@ -34,7 +34,7 @@ static Handle<JSFunction> Compile(const char* source) {
|
||||
Handle<SharedFunctionInfo> shared = Compiler::GetSharedFunctionInfoForScript(
|
||||
source_code, Handle<String>(), 0, 0, v8::ScriptOriginOptions(),
|
||||
Handle<Object>(), Handle<Context>(isolate->native_context()), NULL, NULL,
|
||||
v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE, false);
|
||||
v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE);
|
||||
return isolate->factory()->NewFunctionFromSharedFunctionInfo(
|
||||
shared, isolate->native_context());
|
||||
}
|
||||
|
@ -70,7 +70,11 @@ v8::Local<v8::Script> BytecodeExpectationsPrinter::CompileScript(
|
||||
|
||||
v8::Local<v8::Module> BytecodeExpectationsPrinter::CompileModule(
|
||||
const char* program) const {
|
||||
v8::ScriptCompiler::Source source(V8StringFromUTF8(program));
|
||||
ScriptOrigin origin(
|
||||
Local<v8::Value>(), Local<v8::Integer>(), Local<v8::Integer>(),
|
||||
Local<v8::Boolean>(), Local<v8::Integer>(), Local<v8::Value>(),
|
||||
Local<v8::Boolean>(), Local<v8::Boolean>(), True(isolate_));
|
||||
v8::ScriptCompiler::Source source(V8StringFromUTF8(program), origin);
|
||||
return v8::ScriptCompiler::CompileModule(isolate_, &source).ToLocalChecked();
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ static Handle<JSFunction> Compile(const char* source) {
|
||||
Handle<SharedFunctionInfo> shared = Compiler::GetSharedFunctionInfoForScript(
|
||||
source_code, Handle<String>(), 0, 0, v8::ScriptOriginOptions(),
|
||||
Handle<Object>(), Handle<Context>(isolate->native_context()), NULL, NULL,
|
||||
v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE, false);
|
||||
v8::ScriptCompiler::kNoCompileOptions, NOT_NATIVES_CODE);
|
||||
return isolate->factory()->NewFunctionFromSharedFunctionInfo(
|
||||
shared, isolate->native_context());
|
||||
}
|
||||
|
@ -19,6 +19,14 @@ using v8::ScriptOrigin;
|
||||
using v8::String;
|
||||
using v8::Value;
|
||||
|
||||
ScriptOrigin ModuleOrigin(Local<v8::Value> resource_name, Isolate* isolate) {
|
||||
ScriptOrigin origin(resource_name, Local<v8::Integer>(), Local<v8::Integer>(),
|
||||
Local<v8::Boolean>(), Local<v8::Integer>(),
|
||||
Local<v8::Value>(), Local<v8::Boolean>(),
|
||||
Local<v8::Boolean>(), True(isolate));
|
||||
return origin;
|
||||
}
|
||||
|
||||
MaybeLocal<Module> AlwaysEmptyResolveCallback(Local<Context> context,
|
||||
Local<String> specifier,
|
||||
Local<Module> referrer) {
|
||||
@ -31,7 +39,7 @@ MaybeLocal<Module> FailOnSecondCallResolveCallback(Local<Context> context,
|
||||
Local<Module> referrer) {
|
||||
if (g_count++ > 0) return MaybeLocal<Module>();
|
||||
Local<String> source_text = v8_str("");
|
||||
ScriptOrigin origin(v8_str("module.js"));
|
||||
ScriptOrigin origin = ModuleOrigin(v8_str("module.js"), CcTest::isolate());
|
||||
ScriptCompiler::Source source(source_text, origin);
|
||||
return ScriptCompiler::CompileModule(CcTest::isolate(), &source)
|
||||
.ToLocalChecked();
|
||||
@ -45,7 +53,7 @@ TEST(ModuleInstantiationFailures) {
|
||||
Local<String> source_text = v8_str(
|
||||
"import './foo.js';"
|
||||
"export {} from './bar.js';");
|
||||
ScriptOrigin origin(v8_str("file.js"));
|
||||
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
|
||||
ScriptCompiler::Source source(source_text, origin);
|
||||
Local<Module> module =
|
||||
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
|
||||
@ -66,7 +74,7 @@ TEST(ModuleInstantiationFailures) {
|
||||
|
||||
static MaybeLocal<Module> CompileSpecifierAsModuleResolveCallback(
|
||||
Local<Context> context, Local<String> specifier, Local<Module> referrer) {
|
||||
ScriptOrigin origin(v8_str("module.js"));
|
||||
ScriptOrigin origin = ModuleOrigin(v8_str("module.js"), CcTest::isolate());
|
||||
ScriptCompiler::Source source(specifier, origin);
|
||||
return ScriptCompiler::CompileModule(CcTest::isolate(), &source)
|
||||
.ToLocalChecked();
|
||||
@ -80,7 +88,7 @@ TEST(ModuleEvaluation) {
|
||||
Local<String> source_text = v8_str(
|
||||
"import 'Object.expando = 5';"
|
||||
"import 'Object.expando *= 2';");
|
||||
ScriptOrigin origin(v8_str("file.js"));
|
||||
ScriptOrigin origin = ModuleOrigin(v8_str("file.js"), CcTest::isolate());
|
||||
ScriptCompiler::Source source(source_text, origin);
|
||||
Local<Module> module =
|
||||
ScriptCompiler::CompileModule(isolate, &source).ToLocalChecked();
|
||||
|
@ -931,7 +931,7 @@ static Handle<SharedFunctionInfo> CompileScript(
|
||||
return Compiler::GetSharedFunctionInfoForScript(
|
||||
source, name, 0, 0, v8::ScriptOriginOptions(), Handle<Object>(),
|
||||
Handle<Context>(isolate->native_context()), NULL, cached_data, options,
|
||||
NOT_NATIVES_CODE, false);
|
||||
NOT_NATIVES_CODE);
|
||||
}
|
||||
|
||||
TEST(CodeSerializerOnePlusOne) {
|
||||
@ -1846,8 +1846,7 @@ TEST(Regress503552) {
|
||||
Handle<SharedFunctionInfo> shared = Compiler::GetSharedFunctionInfoForScript(
|
||||
source, Handle<String>(), 0, 0, v8::ScriptOriginOptions(),
|
||||
Handle<Object>(), Handle<Context>(isolate->native_context()), NULL,
|
||||
&script_data, v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE,
|
||||
false);
|
||||
&script_data, v8::ScriptCompiler::kProduceCodeCache, NOT_NATIVES_CODE);
|
||||
delete script_data;
|
||||
|
||||
heap::SimulateIncrementalMarking(isolate->heap());
|
||||
|
Loading…
Reference in New Issue
Block a user