1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef INCLUDE_V8_SCRIPT_H_
6 #define INCLUDE_V8_SCRIPT_H_
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <memory>
12 #include <vector>
13 
14 #include "v8-data.h"          // NOLINT(build/include_directory)
15 #include "v8-local-handle.h"  // NOLINT(build/include_directory)
16 #include "v8-maybe.h"         // NOLINT(build/include_directory)
17 #include "v8-message.h"       // NOLINT(build/include_directory)
18 #include "v8config.h"         // NOLINT(build/include_directory)
19 
20 namespace v8 {
21 
22 class Function;
23 class Object;
24 class PrimitiveArray;
25 class Script;
26 
27 namespace internal {
28 class BackgroundDeserializeTask;
29 struct ScriptStreamingData;
30 }  // namespace internal
31 
32 /**
33  * A container type that holds relevant metadata for module loading.
34  *
35  * This is passed back to the embedder as part of
36  * HostImportModuleDynamicallyCallback for module loading.
37  */
38 class V8_EXPORT ScriptOrModule {
39  public:
40   /**
41    * The name that was passed by the embedder as ResourceName to the
42    * ScriptOrigin. This can be either a v8::String or v8::Undefined.
43    */
44   Local<Value> GetResourceName();
45 
46   /**
47    * The options that were passed by the embedder as HostDefinedOptions to
48    * the ScriptOrigin.
49    */
50   Local<PrimitiveArray> GetHostDefinedOptions();
51 };
52 
53 /**
54  * A compiled JavaScript script, not yet tied to a Context.
55  */
56 class V8_EXPORT UnboundScript {
57  public:
58   /**
59    * Binds the script to the currently entered context.
60    */
61   Local<Script> BindToCurrentContext();
62 
63   int GetId() const;
64   Local<Value> GetScriptName();
65 
66   /**
67    * Data read from magic sourceURL comments.
68    */
69   Local<Value> GetSourceURL();
70   /**
71    * Data read from magic sourceMappingURL comments.
72    */
73   Local<Value> GetSourceMappingURL();
74 
75   /**
76    * Returns zero based line number of the code_pos location in the script.
77    * -1 will be returned if no information available.
78    */
79   int GetLineNumber(int code_pos);
80 
81   static const int kNoScriptId = 0;
82 };
83 
84 /**
85  * A compiled JavaScript module, not yet tied to a Context.
86  */
87 class V8_EXPORT UnboundModuleScript : public Data {
88   // Only used as a container for code caching.
89 };
90 
91 /**
92  * A location in JavaScript source.
93  */
94 class V8_EXPORT Location {
95  public:
GetLineNumber()96   int GetLineNumber() { return line_number_; }
GetColumnNumber()97   int GetColumnNumber() { return column_number_; }
98 
Location(int line_number,int column_number)99   Location(int line_number, int column_number)
100       : line_number_(line_number), column_number_(column_number) {}
101 
102  private:
103   int line_number_;
104   int column_number_;
105 };
106 
107 class V8_EXPORT ModuleRequest : public Data {
108  public:
109   /**
110    * Returns the module specifier for this ModuleRequest.
111    */
112   Local<String> GetSpecifier() const;
113 
114   /**
115    * Returns the source code offset of this module request.
116    * Use Module::SourceOffsetToLocation to convert this to line/column numbers.
117    */
118   int GetSourceOffset() const;
119 
120   /**
121    * Contains the import assertions for this request in the form:
122    * [key1, value1, source_offset1, key2, value2, source_offset2, ...].
123    * The keys and values are of type v8::String, and the source offsets are of
124    * type Int32. Use Module::SourceOffsetToLocation to convert the source
125    * offsets to Locations with line/column numbers.
126    *
127    * All assertions present in the module request will be supplied in this
128    * list, regardless of whether they are supported by the host. Per
129    * https://tc39.es/proposal-import-assertions/#sec-hostgetsupportedimportassertions,
130    * hosts are expected to ignore assertions that they do not support (as
131    * opposed to, for example, triggering an error if an unsupported assertion is
132    * present).
133    */
134   Local<FixedArray> GetImportAssertions() const;
135 
136   V8_INLINE static ModuleRequest* Cast(Data* data);
137 
138  private:
139   static void CheckCast(Data* obj);
140 };
141 
142 /**
143  * A compiled JavaScript module.
144  */
145 class V8_EXPORT Module : public Data {
146  public:
147   /**
148    * The different states a module can be in.
149    *
150    * This corresponds to the states used in ECMAScript except that "evaluated"
151    * is split into kEvaluated and kErrored, indicating success and failure,
152    * respectively.
153    */
154   enum Status {
155     kUninstantiated,
156     kInstantiating,
157     kInstantiated,
158     kEvaluating,
159     kEvaluated,
160     kErrored
161   };
162 
163   /**
164    * Returns the module's current status.
165    */
166   Status GetStatus() const;
167 
168   /**
169    * For a module in kErrored status, this returns the corresponding exception.
170    */
171   Local<Value> GetException() const;
172 
173   /**
174    * Returns the number of modules requested by this module.
175    */
176   V8_DEPRECATE_SOON("Use Module::GetModuleRequests() and FixedArray::Length().")
177   int GetModuleRequestsLength() const;
178 
179   /**
180    * Returns the ith module specifier in this module.
181    * i must be < GetModuleRequestsLength() and >= 0.
182    */
183   V8_DEPRECATE_SOON(
184       "Use Module::GetModuleRequests() and ModuleRequest::GetSpecifier().")
185   Local<String> GetModuleRequest(int i) const;
186 
187   /**
188    * Returns the source location (line number and column number) of the ith
189    * module specifier's first occurrence in this module.
190    */
191   V8_DEPRECATE_SOON(
192       "Use Module::GetModuleRequests(), ModuleRequest::GetSourceOffset(), and "
193       "Module::SourceOffsetToLocation().")
194   Location GetModuleRequestLocation(int i) const;
195 
196   /**
197    * Returns the ModuleRequests for this module.
198    */
199   Local<FixedArray> GetModuleRequests() const;
200 
201   /**
202    * For the given source text offset in this module, returns the corresponding
203    * Location with line and column numbers.
204    */
205   Location SourceOffsetToLocation(int offset) const;
206 
207   /**
208    * Returns the identity hash for this object.
209    */
210   int GetIdentityHash() const;
211 
212   using ResolveCallback V8_DEPRECATE_SOON("Use ResolveModuleCallback") =
213       MaybeLocal<Module> (*)(Local<Context> context, Local<String> specifier,
214                              Local<Module> referrer);
215   using ResolveModuleCallback = MaybeLocal<Module> (*)(
216       Local<Context> context, Local<String> specifier,
217       Local<FixedArray> import_assertions, Local<Module> referrer);
218 
219   /**
220    * Instantiates the module and its dependencies.
221    *
222    * Returns an empty Maybe<bool> if an exception occurred during
223    * instantiation. (In the case where the callback throws an exception, that
224    * exception is propagated.)
225    */
226   V8_DEPRECATE_SOON(
227       "Use the version of InstantiateModule that takes a ResolveModuleCallback "
228       "parameter")
229   V8_WARN_UNUSED_RESULT Maybe<bool> InstantiateModule(Local<Context> context,
230                                                       ResolveCallback callback);
231   V8_WARN_UNUSED_RESULT Maybe<bool> InstantiateModule(
232       Local<Context> context, ResolveModuleCallback callback);
233 
234   /**
235    * Evaluates the module and its dependencies.
236    *
237    * If status is kInstantiated, run the module's code and return a Promise
238    * object. On success, set status to kEvaluated and resolve the Promise with
239    * the completion value; on failure, set status to kErrored and reject the
240    * Promise with the error.
241    *
242    * If IsGraphAsync() is false, the returned Promise is settled.
243    */
244   V8_WARN_UNUSED_RESULT MaybeLocal<Value> Evaluate(Local<Context> context);
245 
246   /**
247    * Returns the namespace object of this module.
248    *
249    * The module's status must be at least kInstantiated.
250    */
251   Local<Value> GetModuleNamespace();
252 
253   /**
254    * Returns the corresponding context-unbound module script.
255    *
256    * The module must be unevaluated, i.e. its status must not be kEvaluating,
257    * kEvaluated or kErrored.
258    */
259   Local<UnboundModuleScript> GetUnboundModuleScript();
260 
261   /**
262    * Returns the underlying script's id.
263    *
264    * The module must be a SourceTextModule and must not have a kErrored status.
265    */
266   int ScriptId() const;
267 
268   /**
269    * Returns whether this module or any of its requested modules is async,
270    * i.e. contains top-level await.
271    *
272    * The module's status must be at least kInstantiated.
273    */
274   bool IsGraphAsync() const;
275 
276   /**
277    * Returns whether the module is a SourceTextModule.
278    */
279   bool IsSourceTextModule() const;
280 
281   /**
282    * Returns whether the module is a SyntheticModule.
283    */
284   bool IsSyntheticModule() const;
285 
286   /*
287    * Callback defined in the embedder.  This is responsible for setting
288    * the module's exported values with calls to SetSyntheticModuleExport().
289    * The callback must return a resolved Promise to indicate success (where no
290    * exception was thrown) and return an empy MaybeLocal to indicate falure
291    * (where an exception was thrown).
292    */
293   using SyntheticModuleEvaluationSteps =
294       MaybeLocal<Value> (*)(Local<Context> context, Local<Module> module);
295 
296   /**
297    * Creates a new SyntheticModule with the specified export names, where
298    * evaluation_steps will be executed upon module evaluation.
299    * export_names must not contain duplicates.
300    * module_name is used solely for logging/debugging and doesn't affect module
301    * behavior.
302    */
303   static Local<Module> CreateSyntheticModule(
304       Isolate* isolate, Local<String> module_name,
305       const std::vector<Local<String>>& export_names,
306       SyntheticModuleEvaluationSteps evaluation_steps);
307 
308   /**
309    * Set this module's exported value for the name export_name to the specified
310    * export_value. This method must be called only on Modules created via
311    * CreateSyntheticModule.  An error will be thrown if export_name is not one
312    * of the export_names that were passed in that CreateSyntheticModule call.
313    * Returns Just(true) on success, Nothing<bool>() if an error was thrown.
314    */
315   V8_WARN_UNUSED_RESULT Maybe<bool> SetSyntheticModuleExport(
316       Isolate* isolate, Local<String> export_name, Local<Value> export_value);
317 
318   V8_INLINE static Module* Cast(Data* data);
319 
320  private:
321   static void CheckCast(Data* obj);
322 };
323 
324 /**
325  * A compiled JavaScript script, tied to a Context which was active when the
326  * script was compiled.
327  */
328 class V8_EXPORT Script {
329  public:
330   /**
331    * A shorthand for ScriptCompiler::Compile().
332    */
333   static V8_WARN_UNUSED_RESULT MaybeLocal<Script> Compile(
334       Local<Context> context, Local<String> source,
335       ScriptOrigin* origin = nullptr);
336 
337   /**
338    * Runs the script returning the resulting value. It will be run in the
339    * context in which it was created (ScriptCompiler::CompileBound or
340    * UnboundScript::BindToCurrentContext()).
341    */
342   V8_WARN_UNUSED_RESULT MaybeLocal<Value> Run(Local<Context> context);
343 
344   /**
345    * Returns the corresponding context-unbound script.
346    */
347   Local<UnboundScript> GetUnboundScript();
348 };
349 
350 enum class ScriptType { kClassic, kModule };
351 
352 /**
353  * For compiling scripts.
354  */
355 class V8_EXPORT ScriptCompiler {
356  public:
357   class ConsumeCodeCacheTask;
358 
359   /**
360    * Compilation data that the embedder can cache and pass back to speed up
361    * future compilations. The data is produced if the CompilerOptions passed to
362    * the compilation functions in ScriptCompiler contains produce_data_to_cache
363    * = true. The data to cache can then can be retrieved from
364    * UnboundScript.
365    */
366   struct V8_EXPORT CachedData {
367     enum BufferPolicy { BufferNotOwned, BufferOwned };
368 
CachedDataCachedData369     CachedData()
370         : data(nullptr),
371           length(0),
372           rejected(false),
373           buffer_policy(BufferNotOwned) {}
374 
375     // If buffer_policy is BufferNotOwned, the caller keeps the ownership of
376     // data and guarantees that it stays alive until the CachedData object is
377     // destroyed. If the policy is BufferOwned, the given data will be deleted
378     // (with delete[]) when the CachedData object is destroyed.
379     CachedData(const uint8_t* data, int length,
380                BufferPolicy buffer_policy = BufferNotOwned);
381     ~CachedData();
382     // TODO(marja): Async compilation; add constructors which take a callback
383     // which will be called when V8 no longer needs the data.
384     const uint8_t* data;
385     int length;
386     bool rejected;
387     BufferPolicy buffer_policy;
388 
389     // Prevent copying.
390     CachedData(const CachedData&) = delete;
391     CachedData& operator=(const CachedData&) = delete;
392   };
393 
394   /**
395    * Source code which can be then compiled to a UnboundScript or Script.
396    */
397   class Source {
398    public:
399     // Source takes ownership of both CachedData and CodeCacheConsumeTask.
400     V8_INLINE Source(Local<String> source_string, const ScriptOrigin& origin,
401                      CachedData* cached_data = nullptr,
402                      ConsumeCodeCacheTask* consume_cache_task = nullptr);
403     // Source takes ownership of both CachedData and CodeCacheConsumeTask.
404     V8_INLINE explicit Source(
405         Local<String> source_string, CachedData* cached_data = nullptr,
406         ConsumeCodeCacheTask* consume_cache_task = nullptr);
407     V8_INLINE ~Source() = default;
408 
409     // Ownership of the CachedData or its buffers is *not* transferred to the
410     // caller. The CachedData object is alive as long as the Source object is
411     // alive.
412     V8_INLINE const CachedData* GetCachedData() const;
413 
414     V8_INLINE const ScriptOriginOptions& GetResourceOptions() const;
415 
416    private:
417     friend class ScriptCompiler;
418 
419     Local<String> source_string;
420 
421     // Origin information
422     Local<Value> resource_name;
423     int resource_line_offset;
424     int resource_column_offset;
425     ScriptOriginOptions resource_options;
426     Local<Value> source_map_url;
427     Local<PrimitiveArray> host_defined_options;
428 
429     // Cached data from previous compilation (if a kConsume*Cache flag is
430     // set), or hold newly generated cache data (kProduce*Cache flags) are
431     // set when calling a compile method.
432     std::unique_ptr<CachedData> cached_data;
433     std::unique_ptr<ConsumeCodeCacheTask> consume_cache_task;
434   };
435 
436   /**
437    * For streaming incomplete script data to V8. The embedder should implement a
438    * subclass of this class.
439    */
440   class V8_EXPORT ExternalSourceStream {
441    public:
442     virtual ~ExternalSourceStream() = default;
443 
444     /**
445      * V8 calls this to request the next chunk of data from the embedder. This
446      * function will be called on a background thread, so it's OK to block and
447      * wait for the data, if the embedder doesn't have data yet. Returns the
448      * length of the data returned. When the data ends, GetMoreData should
449      * return 0. Caller takes ownership of the data.
450      *
451      * When streaming UTF-8 data, V8 handles multi-byte characters split between
452      * two data chunks, but doesn't handle multi-byte characters split between
453      * more than two data chunks. The embedder can avoid this problem by always
454      * returning at least 2 bytes of data.
455      *
456      * When streaming UTF-16 data, V8 does not handle characters split between
457      * two data chunks. The embedder has to make sure that chunks have an even
458      * length.
459      *
460      * If the embedder wants to cancel the streaming, they should make the next
461      * GetMoreData call return 0. V8 will interpret it as end of data (and most
462      * probably, parsing will fail). The streaming task will return as soon as
463      * V8 has parsed the data it received so far.
464      */
465     virtual size_t GetMoreData(const uint8_t** src) = 0;
466 
467     /**
468      * V8 calls this method to set a 'bookmark' at the current position in
469      * the source stream, for the purpose of (maybe) later calling
470      * ResetToBookmark. If ResetToBookmark is called later, then subsequent
471      * calls to GetMoreData should return the same data as they did when
472      * SetBookmark was called earlier.
473      *
474      * The embedder may return 'false' to indicate it cannot provide this
475      * functionality.
476      */
477     virtual bool SetBookmark();
478 
479     /**
480      * V8 calls this to return to a previously set bookmark.
481      */
482     virtual void ResetToBookmark();
483   };
484 
485   /**
486    * Source code which can be streamed into V8 in pieces. It will be parsed
487    * while streaming and compiled after parsing has completed. StreamedSource
488    * must be kept alive while the streaming task is run (see ScriptStreamingTask
489    * below).
490    */
491   class V8_EXPORT StreamedSource {
492    public:
493     enum Encoding { ONE_BYTE, TWO_BYTE, UTF8, WINDOWS_1252 };
494 
495     StreamedSource(std::unique_ptr<ExternalSourceStream> source_stream,
496                    Encoding encoding);
497     ~StreamedSource();
498 
impl()499     internal::ScriptStreamingData* impl() const { return impl_.get(); }
500 
501     // Prevent copying.
502     StreamedSource(const StreamedSource&) = delete;
503     StreamedSource& operator=(const StreamedSource&) = delete;
504 
505    private:
506     std::unique_ptr<internal::ScriptStreamingData> impl_;
507   };
508 
509   /**
510    * A streaming task which the embedder must run on a background thread to
511    * stream scripts into V8. Returned by ScriptCompiler::StartStreaming.
512    */
513   class V8_EXPORT ScriptStreamingTask final {
514    public:
515     void Run();
516 
517    private:
518     friend class ScriptCompiler;
519 
ScriptStreamingTask(internal::ScriptStreamingData * data)520     explicit ScriptStreamingTask(internal::ScriptStreamingData* data)
521         : data_(data) {}
522 
523     internal::ScriptStreamingData* data_;
524   };
525 
526   /**
527    * A task which the embedder must run on a background thread to
528    * consume a V8 code cache. Returned by
529    * ScriptCompiler::StarConsumingCodeCache.
530    */
531   class V8_EXPORT ConsumeCodeCacheTask final {
532    public:
533     ~ConsumeCodeCacheTask();
534 
535     void Run();
536 
537    private:
538     friend class ScriptCompiler;
539 
540     explicit ConsumeCodeCacheTask(
541         std::unique_ptr<internal::BackgroundDeserializeTask> impl);
542 
543     std::unique_ptr<internal::BackgroundDeserializeTask> impl_;
544   };
545 
546   enum CompileOptions {
547     kNoCompileOptions = 0,
548     kConsumeCodeCache,
549     kEagerCompile
550   };
551 
552   /**
553    * The reason for which we are not requesting or providing a code cache.
554    */
555   enum NoCacheReason {
556     kNoCacheNoReason = 0,
557     kNoCacheBecauseCachingDisabled,
558     kNoCacheBecauseNoResource,
559     kNoCacheBecauseInlineScript,
560     kNoCacheBecauseModule,
561     kNoCacheBecauseStreamingSource,
562     kNoCacheBecauseInspector,
563     kNoCacheBecauseScriptTooSmall,
564     kNoCacheBecauseCacheTooCold,
565     kNoCacheBecauseV8Extension,
566     kNoCacheBecauseExtensionModule,
567     kNoCacheBecausePacScript,
568     kNoCacheBecauseInDocumentWrite,
569     kNoCacheBecauseResourceWithNoCacheHandler,
570     kNoCacheBecauseDeferredProduceCodeCache
571   };
572 
573   /**
574    * Compiles the specified script (context-independent).
575    * Cached data as part of the source object can be optionally produced to be
576    * consumed later to speed up compilation of identical source scripts.
577    *
578    * Note that when producing cached data, the source must point to NULL for
579    * cached data. When consuming cached data, the cached data must have been
580    * produced by the same version of V8, and the embedder needs to ensure the
581    * cached data is the correct one for the given script.
582    *
583    * \param source Script source code.
584    * \return Compiled script object (context independent; for running it must be
585    *   bound to a context).
586    */
587   static V8_WARN_UNUSED_RESULT MaybeLocal<UnboundScript> CompileUnboundScript(
588       Isolate* isolate, Source* source,
589       CompileOptions options = kNoCompileOptions,
590       NoCacheReason no_cache_reason = kNoCacheNoReason);
591 
592   /**
593    * Compiles the specified script (bound to current context).
594    *
595    * \param source Script source code.
596    * \param pre_data Pre-parsing data, as obtained by ScriptData::PreCompile()
597    *   using pre_data speeds compilation if it's done multiple times.
598    *   Owned by caller, no references are kept when this function returns.
599    * \return Compiled script object, bound to the context that was active
600    *   when this function was called. When run it will always use this
601    *   context.
602    */
603   static V8_WARN_UNUSED_RESULT MaybeLocal<Script> Compile(
604       Local<Context> context, Source* source,
605       CompileOptions options = kNoCompileOptions,
606       NoCacheReason no_cache_reason = kNoCacheNoReason);
607 
608   /**
609    * Returns a task which streams script data into V8, or NULL if the script
610    * cannot be streamed. The user is responsible for running the task on a
611    * background thread and deleting it. When ran, the task starts parsing the
612    * script, and it will request data from the StreamedSource as needed. When
613    * ScriptStreamingTask::Run exits, all data has been streamed and the script
614    * can be compiled (see Compile below).
615    *
616    * This API allows to start the streaming with as little data as possible, and
617    * the remaining data (for example, the ScriptOrigin) is passed to Compile.
618    */
619   static ScriptStreamingTask* StartStreaming(
620       Isolate* isolate, StreamedSource* source,
621       ScriptType type = ScriptType::kClassic);
622 
623   static ConsumeCodeCacheTask* StartConsumingCodeCache(
624       Isolate* isolate, std::unique_ptr<CachedData> source);
625 
626   /**
627    * Compiles a streamed script (bound to current context).
628    *
629    * This can only be called after the streaming has finished
630    * (ScriptStreamingTask has been run). V8 doesn't construct the source string
631    * during streaming, so the embedder needs to pass the full source here.
632    */
633   static V8_WARN_UNUSED_RESULT MaybeLocal<Script> Compile(
634       Local<Context> context, StreamedSource* source,
635       Local<String> full_source_string, const ScriptOrigin& origin);
636 
637   /**
638    * Return a version tag for CachedData for the current V8 version & flags.
639    *
640    * This value is meant only for determining whether a previously generated
641    * CachedData instance is still valid; the tag has no other meaing.
642    *
643    * Background: The data carried by CachedData may depend on the exact
644    *   V8 version number or current compiler flags. This means that when
645    *   persisting CachedData, the embedder must take care to not pass in
646    *   data from another V8 version, or the same version with different
647    *   features enabled.
648    *
649    *   The easiest way to do so is to clear the embedder's cache on any
650    *   such change.
651    *
652    *   Alternatively, this tag can be stored alongside the cached data and
653    *   compared when it is being used.
654    */
655   static uint32_t CachedDataVersionTag();
656 
657   /**
658    * Compile an ES module, returning a Module that encapsulates
659    * the compiled code.
660    *
661    * Corresponds to the ParseModule abstract operation in the
662    * ECMAScript specification.
663    */
664   static V8_WARN_UNUSED_RESULT MaybeLocal<Module> CompileModule(
665       Isolate* isolate, Source* source,
666       CompileOptions options = kNoCompileOptions,
667       NoCacheReason no_cache_reason = kNoCacheNoReason);
668 
669   /**
670    * Compiles a streamed module script.
671    *
672    * This can only be called after the streaming has finished
673    * (ScriptStreamingTask has been run). V8 doesn't construct the source string
674    * during streaming, so the embedder needs to pass the full source here.
675    */
676   static V8_WARN_UNUSED_RESULT MaybeLocal<Module> CompileModule(
677       Local<Context> context, StreamedSource* v8_source,
678       Local<String> full_source_string, const ScriptOrigin& origin);
679 
680   /**
681    * Compile a function for a given context. This is equivalent to running
682    *
683    * with (obj) {
684    *   return function(args) { ... }
685    * }
686    *
687    * It is possible to specify multiple context extensions (obj in the above
688    * example).
689    */
690   static V8_WARN_UNUSED_RESULT MaybeLocal<Function> CompileFunctionInContext(
691       Local<Context> context, Source* source, size_t arguments_count,
692       Local<String> arguments[], size_t context_extension_count,
693       Local<Object> context_extensions[],
694       CompileOptions options = kNoCompileOptions,
695       NoCacheReason no_cache_reason = kNoCacheNoReason,
696       Local<ScriptOrModule>* script_or_module_out = nullptr);
697 
698   /**
699    * Creates and returns code cache for the specified unbound_script.
700    * This will return nullptr if the script cannot be serialized. The
701    * CachedData returned by this function should be owned by the caller.
702    */
703   static CachedData* CreateCodeCache(Local<UnboundScript> unbound_script);
704 
705   /**
706    * Creates and returns code cache for the specified unbound_module_script.
707    * This will return nullptr if the script cannot be serialized. The
708    * CachedData returned by this function should be owned by the caller.
709    */
710   static CachedData* CreateCodeCache(
711       Local<UnboundModuleScript> unbound_module_script);
712 
713   /**
714    * Creates and returns code cache for the specified function that was
715    * previously produced by CompileFunctionInContext.
716    * This will return nullptr if the script cannot be serialized. The
717    * CachedData returned by this function should be owned by the caller.
718    */
719   static CachedData* CreateCodeCacheForFunction(Local<Function> function);
720 
721  private:
722   static V8_WARN_UNUSED_RESULT MaybeLocal<UnboundScript> CompileUnboundInternal(
723       Isolate* isolate, Source* source, CompileOptions options,
724       NoCacheReason no_cache_reason);
725 };
726 
Source(Local<String> string,const ScriptOrigin & origin,CachedData * data,ConsumeCodeCacheTask * consume_cache_task)727 ScriptCompiler::Source::Source(Local<String> string, const ScriptOrigin& origin,
728                                CachedData* data,
729                                ConsumeCodeCacheTask* consume_cache_task)
730     : source_string(string),
731       resource_name(origin.ResourceName()),
732       resource_line_offset(origin.LineOffset()),
733       resource_column_offset(origin.ColumnOffset()),
734       resource_options(origin.Options()),
735       source_map_url(origin.SourceMapUrl()),
736       host_defined_options(origin.HostDefinedOptions()),
737       cached_data(data),
738       consume_cache_task(consume_cache_task) {}
739 
Source(Local<String> string,CachedData * data,ConsumeCodeCacheTask * consume_cache_task)740 ScriptCompiler::Source::Source(Local<String> string, CachedData* data,
741                                ConsumeCodeCacheTask* consume_cache_task)
742     : source_string(string),
743       cached_data(data),
744       consume_cache_task(consume_cache_task) {}
745 
GetCachedData()746 const ScriptCompiler::CachedData* ScriptCompiler::Source::GetCachedData()
747     const {
748   return cached_data.get();
749 }
750 
GetResourceOptions()751 const ScriptOriginOptions& ScriptCompiler::Source::GetResourceOptions() const {
752   return resource_options;
753 }
754 
Cast(Data * data)755 ModuleRequest* ModuleRequest::Cast(Data* data) {
756 #ifdef V8_ENABLE_CHECKS
757   CheckCast(data);
758 #endif
759   return reinterpret_cast<ModuleRequest*>(data);
760 }
761 
Cast(Data * data)762 Module* Module::Cast(Data* data) {
763 #ifdef V8_ENABLE_CHECKS
764   CheckCast(data);
765 #endif
766   return reinterpret_cast<Module*>(data);
767 }
768 
769 }  // namespace v8
770 
771 #endif  // INCLUDE_V8_SCRIPT_H_
772