Skip to content

Commit dbfe4a4

Browse files
gsathyaCommit Bot
authored andcommitted
[Modules] Introduce ScriptOrModule and HostDefinedOptions
This patch introduces a new container type ScriptOrModule which provides the name and the host defined options of the script/module. This patch also introduces a new PrimitivesArray that can hold Primitive values, which the embedder can use to store metadata. The HostDefinedOptions is passed to V8 through the ScriptOrigin, and passed back to the embedder through HostImportModuleDynamically for module loading. Bug: v8:5785, v8:6658, v8:6683 Cq-Include-Trybots: master.tryserver.chromium.linux:linux_chromium_rel_ng Change-Id: I56c26fc9a680b273ac0a6691e5ad75f15b8dc80a Reviewed-on: https://chromium-review.googlesource.com/622158 Reviewed-by: Adam Klein <[email protected]> Reviewed-by: Georg Neis <[email protected]> Commit-Queue: Sathya Gunasekaran <[email protected]> Cr-Commit-Position: refs/heads/master@{#47724}
1 parent 30d8255 commit dbfe4a4

19 files changed

Lines changed: 264 additions & 53 deletions

include/v8.h

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class String;
104104
class StringObject;
105105
class Symbol;
106106
class SymbolObject;
107+
class PrimitiveArray;
107108
class Private;
108109
class Uint32;
109110
class Utils;
@@ -978,6 +979,48 @@ class V8_EXPORT Data {
978979
Data();
979980
};
980981

982+
/**
983+
* This is an unfinished experimental feature, and is only exposed
984+
* here for internal testing purposes. DO NOT USE.
985+
*
986+
* A container type that holds relevant metadata for module loading.
987+
*
988+
* This is passed back to the embedder as part of
989+
* HostImportDynamicallyCallback for module loading.
990+
*/
991+
class V8_EXPORT ScriptOrModule {
992+
public:
993+
/**
994+
* The name that was passed by the embedder as ResourceName to the
995+
* ScriptOrigin. This can be either a v8::String or v8::Undefined.
996+
*/
997+
Local<Value> GetResourceName();
998+
999+
/**
1000+
* The options that were passed by the embedder as HostDefinedOptions to
1001+
* the ScriptOrigin.
1002+
*/
1003+
Local<PrimitiveArray> GetHostDefinedOptions();
1004+
};
1005+
1006+
/**
1007+
* This is an unfinished experimental feature, and is only exposed
1008+
* here for internal testing purposes. DO NOT USE.
1009+
*
1010+
* An array to hold Primitive values. This is used by the embedder to
1011+
* pass host defined options to the ScriptOptions during compilation.
1012+
*
1013+
* This is passed back to the embedder as part of
1014+
* HostImportDynamicallyCallback for module loading.
1015+
*
1016+
*/
1017+
class V8_EXPORT PrimitiveArray {
1018+
public:
1019+
static Local<PrimitiveArray> New(Isolate* isolate, int length);
1020+
int Length() const;
1021+
void Set(int index, Local<Primitive> item);
1022+
Local<Primitive> Get(int index);
1023+
};
9811024

9821025
/**
9831026
* The optional attributes of ScriptOrigin.
@@ -1027,13 +1070,15 @@ class ScriptOrigin {
10271070
Local<Value> source_map_url = Local<Value>(),
10281071
Local<Boolean> resource_is_opaque = Local<Boolean>(),
10291072
Local<Boolean> is_wasm = Local<Boolean>(),
1030-
Local<Boolean> is_module = Local<Boolean>());
1073+
Local<Boolean> is_module = Local<Boolean>(),
1074+
Local<PrimitiveArray> host_defined_options = Local<PrimitiveArray>());
10311075

10321076
V8_INLINE Local<Value> ResourceName() const;
10331077
V8_INLINE Local<Integer> ResourceLineOffset() const;
10341078
V8_INLINE Local<Integer> ResourceColumnOffset() const;
10351079
V8_INLINE Local<Integer> ScriptID() const;
10361080
V8_INLINE Local<Value> SourceMapUrl() const;
1081+
V8_INLINE Local<PrimitiveArray> HostDefinedOptions() const;
10371082
V8_INLINE ScriptOriginOptions Options() const { return options_; }
10381083

10391084
private:
@@ -1043,6 +1088,7 @@ class ScriptOrigin {
10431088
ScriptOriginOptions options_;
10441089
Local<Integer> script_id_;
10451090
Local<Value> source_map_url_;
1091+
Local<PrimitiveArray> host_defined_options_;
10461092
};
10471093

10481094
/**
@@ -1289,6 +1335,7 @@ class V8_EXPORT ScriptCompiler {
12891335
Local<Integer> resource_column_offset;
12901336
ScriptOriginOptions resource_options;
12911337
Local<Value> source_map_url;
1338+
Local<PrimitiveArray> host_defined_options;
12921339

12931340
// Cached data from previous compilation (if a kConsume*Cache flag is
12941341
// set), or hold newly generated cache data (kProduce*Cache flags) are
@@ -6204,8 +6251,8 @@ typedef void (*DeprecatedCallCompletedCallback)();
62046251
* embedder to load a module. This is used as part of the dynamic
62056252
* import syntax.
62066253
*
6207-
* The referrer is the name of the file which calls the dynamic
6208-
* import. The referrer can be used to resolve the module location.
6254+
* The referrer contains metadata about the script/module that calls
6255+
* import.
62096256
*
62106257
* The specifier is the name of the module that should be imported.
62116258
*
@@ -6220,7 +6267,8 @@ typedef void (*DeprecatedCallCompletedCallback)();
62206267
* that exception by returning an empty MaybeLocal.
62216268
*/
62226269
typedef MaybeLocal<Promise> (*HostImportModuleDynamicallyCallback)(
6223-
Local<Context> context, Local<String> referrer, Local<String> specifier);
6270+
Local<Context> context, Local<ScriptOrModule> referrer,
6271+
Local<String> specifier);
62246272

62256273
/**
62266274
* PromiseHook with type kInit is called when a new promise is
@@ -9531,7 +9579,8 @@ ScriptOrigin::ScriptOrigin(Local<Value> resource_name,
95319579
Local<Integer> script_id,
95329580
Local<Value> source_map_url,
95339581
Local<Boolean> resource_is_opaque,
9534-
Local<Boolean> is_wasm, Local<Boolean> is_module)
9582+
Local<Boolean> is_wasm, Local<Boolean> is_module,
9583+
Local<PrimitiveArray> host_defined_options)
95359584
: resource_name_(resource_name),
95369585
resource_line_offset_(resource_line_offset),
95379586
resource_column_offset_(resource_column_offset),
@@ -9541,10 +9590,14 @@ ScriptOrigin::ScriptOrigin(Local<Value> resource_name,
95419590
!is_wasm.IsEmpty() && is_wasm->IsTrue(),
95429591
!is_module.IsEmpty() && is_module->IsTrue()),
95439592
script_id_(script_id),
9544-
source_map_url_(source_map_url) {}
9593+
source_map_url_(source_map_url),
9594+
host_defined_options_(host_defined_options) {}
95459595

95469596
Local<Value> ScriptOrigin::ResourceName() const { return resource_name_; }
95479597

9598+
Local<PrimitiveArray> ScriptOrigin::HostDefinedOptions() const {
9599+
return host_defined_options_;
9600+
}
95489601

95499602
Local<Integer> ScriptOrigin::ResourceLineOffset() const {
95509603
return resource_line_offset_;
@@ -9561,7 +9614,6 @@ Local<Integer> ScriptOrigin::ScriptID() const { return script_id_; }
95619614

95629615
Local<Value> ScriptOrigin::SourceMapUrl() const { return source_map_url_; }
95639616

9564-
95659617
ScriptCompiler::Source::Source(Local<String> string, const ScriptOrigin& origin,
95669618
CachedData* data)
95679619
: source_string(string),
@@ -9570,9 +9622,9 @@ ScriptCompiler::Source::Source(Local<String> string, const ScriptOrigin& origin,
95709622
resource_column_offset(origin.ResourceColumnOffset()),
95719623
resource_options(origin.Options()),
95729624
source_map_url(origin.SourceMapUrl()),
9625+
host_defined_options(origin.HostDefinedOptions()),
95739626
cached_data(data) {}
95749627

9575-
95769628
ScriptCompiler::Source::Source(Local<String> string,
95779629
CachedData* data)
95789630
: source_string(string), cached_data(data) {}

src/api.cc

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,8 @@ static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
279279
i::Handle<i::Script> script) {
280280
i::Handle<i::Object> scriptName(script->GetNameOrSourceURL(), isolate);
281281
i::Handle<i::Object> source_map_url(script->source_mapping_url(), isolate);
282+
i::Handle<i::FixedArray> host_defined_options(script->host_defined_options(),
283+
isolate);
282284
v8::Isolate* v8_isolate =
283285
reinterpret_cast<v8::Isolate*>(script->GetIsolate());
284286
ScriptOriginOptions options(script->origin_options());
@@ -291,7 +293,8 @@ static ScriptOrigin GetScriptOriginForScript(i::Isolate* isolate,
291293
Utils::ToLocal(source_map_url),
292294
v8::Boolean::New(v8_isolate, options.IsOpaque()),
293295
v8::Boolean::New(v8_isolate, script->type() == i::Script::TYPE_WASM),
294-
v8::Boolean::New(v8_isolate, options.IsModule()));
296+
v8::Boolean::New(v8_isolate, options.IsModule()),
297+
Utils::ToLocal(host_defined_options));
295298
return origin;
296299
}
297300

@@ -2090,13 +2093,68 @@ Local<Value> Script::Run() {
20902093
RETURN_TO_LOCAL_UNCHECKED(Run(context), Value);
20912094
}
20922095

2096+
Local<Value> ScriptOrModule::GetResourceName() {
2097+
i::Handle<i::Script> obj = Utils::OpenHandle(this);
2098+
i::Isolate* isolate = obj->GetIsolate();
2099+
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2100+
i::Handle<i::Object> val(obj->name(), isolate);
2101+
return ToApiHandle<Value>(val);
2102+
}
2103+
2104+
Local<PrimitiveArray> ScriptOrModule::GetHostDefinedOptions() {
2105+
i::Handle<i::Script> obj = Utils::OpenHandle(this);
2106+
i::Isolate* isolate = obj->GetIsolate();
2107+
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2108+
i::Handle<i::FixedArray> val(obj->host_defined_options(), isolate);
2109+
return ToApiHandle<PrimitiveArray>(val);
2110+
}
20932111

20942112
Local<UnboundScript> Script::GetUnboundScript() {
20952113
i::Handle<i::Object> obj = Utils::OpenHandle(this);
20962114
return ToApiHandle<UnboundScript>(
20972115
i::Handle<i::SharedFunctionInfo>(i::JSFunction::cast(*obj)->shared()));
20982116
}
20992117

2118+
// static
2119+
Local<PrimitiveArray> PrimitiveArray::New(Isolate* v8_isolate, int length) {
2120+
i::Isolate* isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
2121+
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2122+
Utils::ApiCheck(length >= 0, "v8::PrimitiveArray::New",
2123+
"length must be equal or greater than zero");
2124+
i::Handle<i::FixedArray> array = isolate->factory()->NewFixedArray(length);
2125+
return ToApiHandle<PrimitiveArray>(array);
2126+
}
2127+
2128+
int PrimitiveArray::Length() const {
2129+
i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2130+
i::Isolate* isolate = array->GetIsolate();
2131+
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2132+
return array->length();
2133+
}
2134+
2135+
void PrimitiveArray::Set(int index, Local<Primitive> item) {
2136+
i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2137+
i::Isolate* isolate = array->GetIsolate();
2138+
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2139+
Utils::ApiCheck(index >= 0 && index < array->length(),
2140+
"v8::PrimitiveArray::Set",
2141+
"index must be greater than or equal to 0 and less than the "
2142+
"array length");
2143+
i::Handle<i::Object> i_item = Utils::OpenHandle(*item);
2144+
array->set(index, *i_item);
2145+
}
2146+
2147+
Local<Primitive> PrimitiveArray::Get(int index) {
2148+
i::Handle<i::FixedArray> array = Utils::OpenHandle(this);
2149+
i::Isolate* isolate = array->GetIsolate();
2150+
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
2151+
Utils::ApiCheck(index >= 0 && index < array->length(),
2152+
"v8::PrimitiveArray::Get",
2153+
"index must be greater than or equal to 0 and less than the "
2154+
"array length");
2155+
i::Handle<i::Object> i_item(array->get(index), isolate);
2156+
return ToApiHandle<Primitive>(i_item);
2157+
}
21002158

21012159
Module::Status Module::GetStatus() const {
21022160
i::Handle<i::Module> self = Utils::OpenHandle(this);
@@ -2233,11 +2291,16 @@ MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
22332291
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileScript");
22342292
i::Handle<i::Object> name_obj;
22352293
i::Handle<i::Object> source_map_url;
2294+
i::Handle<i::FixedArray> host_defined_options =
2295+
isolate->factory()->empty_fixed_array();
22362296
int line_offset = 0;
22372297
int column_offset = 0;
22382298
if (!source->resource_name.IsEmpty()) {
22392299
name_obj = Utils::OpenHandle(*(source->resource_name));
22402300
}
2301+
if (!source->host_defined_options.IsEmpty()) {
2302+
host_defined_options = Utils::OpenHandle(*(source->host_defined_options));
2303+
}
22412304
if (!source->resource_line_offset.IsEmpty()) {
22422305
line_offset = static_cast<int>(source->resource_line_offset->Value());
22432306
}
@@ -2251,7 +2314,7 @@ MaybeLocal<UnboundScript> ScriptCompiler::CompileUnboundInternal(
22512314
result = i::Compiler::GetSharedFunctionInfoForScript(
22522315
str, name_obj, line_offset, column_offset, source->resource_options,
22532316
source_map_url, isolate->native_context(), NULL, &script_data, options,
2254-
i::NOT_NATIVES_CODE);
2317+
i::NOT_NATIVES_CODE, host_defined_options);
22552318
has_pending_exception = result.is_null();
22562319
if (has_pending_exception && script_data != NULL) {
22572320
// This case won't happen during normal operation; we have compiled
@@ -2516,6 +2579,10 @@ MaybeLocal<Script> ScriptCompiler::Compile(Local<Context> context,
25162579
if (!origin.ResourceName().IsEmpty()) {
25172580
script->set_name(*Utils::OpenHandle(*(origin.ResourceName())));
25182581
}
2582+
if (!origin.HostDefinedOptions().IsEmpty()) {
2583+
script->set_host_defined_options(
2584+
*Utils::OpenHandle(*(origin.HostDefinedOptions())));
2585+
}
25192586
if (!origin.ResourceLineOffset().IsEmpty()) {
25202587
script->set_line_offset(
25212588
static_cast<int>(origin.ResourceLineOffset()->Value()));
@@ -9807,7 +9874,8 @@ MaybeLocal<UnboundScript> debug::CompileInspectorScript(Isolate* v8_isolate,
98079874
i::Handle<i::Object>(), isolate->native_context(), NULL, &script_data,
98089875
ScriptCompiler::kNoCompileOptions,
98099876
i::FLAG_expose_inspector_scripts ? i::NOT_NATIVES_CODE
9810-
: i::INSPECTOR_CODE);
9877+
: i::INSPECTOR_CODE,
9878+
i::Handle<i::FixedArray>());
98119879
has_pending_exception = result.is_null();
98129880
RETURN_ON_FAILED_EXECUTION(UnboundScript);
98139881
}

src/api.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,10 @@ class RegisteredExtension {
111111
V(NativeWeakMap, JSWeakMap) \
112112
V(debug::GeneratorObject, JSGeneratorObject) \
113113
V(debug::Script, Script) \
114-
V(Promise, JSPromise)
114+
V(Promise, JSPromise) \
115+
V(Primitive, Object) \
116+
V(PrimitiveArray, FixedArray) \
117+
V(ScriptOrModule, Script)
115118

116119
class Utils {
117120
public:
@@ -209,6 +212,12 @@ class Utils {
209212
v8::internal::Handle<v8::internal::JSWeakMap> obj);
210213
static inline Local<Function> CallableToLocal(
211214
v8::internal::Handle<v8::internal::JSReceiver> obj);
215+
static inline Local<Primitive> ToLocalPrimitive(
216+
v8::internal::Handle<v8::internal::Object> obj);
217+
static inline Local<PrimitiveArray> ToLocal(
218+
v8::internal::Handle<v8::internal::FixedArray> obj);
219+
static inline Local<ScriptOrModule> ScriptOrModuleToLocal(
220+
v8::internal::Handle<v8::internal::Script> obj);
212221

213222
#define DECLARE_OPEN_HANDLE(From, To) \
214223
static inline v8::internal::Handle<v8::internal::To> \
@@ -325,6 +334,9 @@ MAKE_TO_LOCAL(Uint32ToLocal, Object, Uint32)
325334
MAKE_TO_LOCAL(ExternalToLocal, JSObject, External)
326335
MAKE_TO_LOCAL(NativeWeakMapToLocal, JSWeakMap, NativeWeakMap)
327336
MAKE_TO_LOCAL(CallableToLocal, JSReceiver, Function)
337+
MAKE_TO_LOCAL(ToLocalPrimitive, Object, Primitive)
338+
MAKE_TO_LOCAL(ToLocal, FixedArray, PrimitiveArray)
339+
MAKE_TO_LOCAL(ScriptOrModuleToLocal, Script, ScriptOrModule)
328340

329341
#undef MAKE_TO_LOCAL_TYPED_ARRAY
330342
#undef MAKE_TO_LOCAL

src/bootstrapper.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3539,7 +3539,8 @@ bool Bootstrapper::CompileNative(Isolate* isolate, Vector<const char> name,
35393539
Handle<SharedFunctionInfo> function_info =
35403540
Compiler::GetSharedFunctionInfoForScript(
35413541
source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
3542-
context, NULL, NULL, ScriptCompiler::kNoCompileOptions, natives_flag);
3542+
context, NULL, NULL, ScriptCompiler::kNoCompileOptions, natives_flag,
3543+
Handle<FixedArray>());
35433544
if (function_info.is_null()) return false;
35443545

35453546
DCHECK(context->IsNativeContext());
@@ -3602,7 +3603,7 @@ bool Genesis::CompileExtension(Isolate* isolate, v8::Extension* extension) {
36023603
function_info = Compiler::GetSharedFunctionInfoForScript(
36033604
source, script_name, 0, 0, ScriptOriginOptions(), Handle<Object>(),
36043605
context, extension, NULL, ScriptCompiler::kNoCompileOptions,
3605-
EXTENSION_CODE);
3606+
EXTENSION_CODE, Handle<FixedArray>());
36063607
if (function_info.is_null()) return false;
36073608
cache->Add(name, function_info);
36083609
}

src/compiler.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1208,7 +1208,8 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
12081208
int column_offset, ScriptOriginOptions resource_options,
12091209
Handle<Object> source_map_url, Handle<Context> context,
12101210
v8::Extension* extension, ScriptData** cached_data,
1211-
ScriptCompiler::CompileOptions compile_options, NativesFlag natives) {
1211+
ScriptCompiler::CompileOptions compile_options, NativesFlag natives,
1212+
Handle<FixedArray> host_defined_options) {
12121213
Isolate* isolate = source->GetIsolate();
12131214
if (compile_options == ScriptCompiler::kNoCompileOptions) {
12141215
cached_data = NULL;
@@ -1304,6 +1305,9 @@ Handle<SharedFunctionInfo> Compiler::GetSharedFunctionInfoForScript(
13041305
if (!source_map_url.is_null()) {
13051306
script->set_source_mapping_url(*source_map_url);
13061307
}
1308+
if (!host_defined_options.is_null()) {
1309+
script->set_host_defined_options(*host_defined_options);
1310+
}
13071311

13081312
// Compile the function and add it to the cache.
13091313
ParseInfo parse_info(script);

src/compiler.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
113113
Handle<Object> source_map_url, Handle<Context> context,
114114
v8::Extension* extension, ScriptData** cached_data,
115115
ScriptCompiler::CompileOptions compile_options,
116-
NativesFlag is_natives_code);
116+
NativesFlag is_natives_code, Handle<FixedArray> host_defined_options);
117117

118118
// Create a shared function info object for a Script that has already been
119119
// parsed while the script was being loaded from a streamed source.

src/d8.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -797,15 +797,17 @@ struct DynamicImportData {
797797
} // namespace
798798

799799
MaybeLocal<Promise> Shell::HostImportModuleDynamically(
800-
Local<Context> context, Local<String> referrer, Local<String> specifier) {
800+
Local<Context> context, Local<ScriptOrModule> referrer,
801+
Local<String> specifier) {
801802
Isolate* isolate = context->GetIsolate();
802803

803804
MaybeLocal<Promise::Resolver> maybe_resolver =
804805
Promise::Resolver::New(context);
805806
Local<Promise::Resolver> resolver;
806807
if (maybe_resolver.ToLocal(&resolver)) {
807-
DynamicImportData* data =
808-
new DynamicImportData(isolate, referrer, specifier, resolver);
808+
DynamicImportData* data = new DynamicImportData(
809+
isolate, Local<String>::Cast(referrer->GetResourceName()), specifier,
810+
resolver);
809811
isolate->EnqueueMicrotask(Shell::DoHostImportModuleDynamically, data);
810812
return resolver->GetPromise();
811813
}

0 commit comments

Comments
 (0)