Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-28 09:18:21

0001 // Copyright 2021 the V8 project authors. All rights reserved.
0002 // Use of this source code is governed by a BSD-style license that can be
0003 // found in the LICENSE file.
0004 
0005 #ifndef INCLUDE_V8_SCRIPT_H_
0006 #define INCLUDE_V8_SCRIPT_H_
0007 
0008 #include <stddef.h>
0009 #include <stdint.h>
0010 
0011 #include <memory>
0012 #include <tuple>
0013 #include <vector>
0014 
0015 #include "v8-callbacks.h"     // NOLINT(build/include_directory)
0016 #include "v8-data.h"          // NOLINT(build/include_directory)
0017 #include "v8-local-handle.h"  // NOLINT(build/include_directory)
0018 #include "v8-maybe.h"         // NOLINT(build/include_directory)
0019 #include "v8-memory-span.h"   // NOLINT(build/include_directory)
0020 #include "v8-message.h"       // NOLINT(build/include_directory)
0021 #include "v8config.h"         // NOLINT(build/include_directory)
0022 
0023 namespace v8 {
0024 
0025 class Function;
0026 class Message;
0027 class Object;
0028 class PrimitiveArray;
0029 class Script;
0030 
0031 namespace internal {
0032 class BackgroundDeserializeTask;
0033 struct ScriptStreamingData;
0034 }  // namespace internal
0035 
0036 /**
0037  * A container type that holds relevant metadata for module loading.
0038  *
0039  * This is passed back to the embedder as part of
0040  * HostImportModuleDynamicallyCallback for module loading.
0041  */
0042 class V8_EXPORT ScriptOrModule {
0043  public:
0044   /**
0045    * The name that was passed by the embedder as ResourceName to the
0046    * ScriptOrigin. This can be either a v8::String or v8::Undefined.
0047    */
0048   Local<Value> GetResourceName();
0049 
0050   /**
0051    * The options that were passed by the embedder as HostDefinedOptions to
0052    * the ScriptOrigin.
0053    */
0054   Local<Data> HostDefinedOptions();
0055 };
0056 
0057 /**
0058  * A compiled JavaScript script, not yet tied to a Context.
0059  */
0060 class V8_EXPORT UnboundScript : public Data {
0061  public:
0062   /**
0063    * Binds the script to the currently entered context.
0064    */
0065   Local<Script> BindToCurrentContext();
0066 
0067   /*
0068    * A unique id.
0069    */
0070   int ScriptId() const;
0071   V8_DEPRECATE_SOON("Use ScriptId")
0072   int GetId() const;
0073 
0074   Local<Value> GetScriptName();
0075 
0076   /**
0077    * Data read from magic sourceURL comments.
0078    */
0079   Local<Value> GetSourceURL();
0080   /**
0081    * Data read from magic sourceMappingURL comments.
0082    */
0083   Local<Value> GetSourceMappingURL();
0084 
0085   /**
0086    * Returns zero based line number of the code_pos location in the script.
0087    * -1 will be returned if no information available.
0088    */
0089   int GetLineNumber(int code_pos = 0);
0090 
0091   /**
0092    * Returns zero based column number of the code_pos location in the script.
0093    * -1 will be returned if no information available.
0094    */
0095   int GetColumnNumber(int code_pos = 0);
0096 
0097   static const int kNoScriptId = 0;
0098 };
0099 
0100 /**
0101  * A compiled JavaScript module, not yet tied to a Context.
0102  */
0103 class V8_EXPORT UnboundModuleScript : public Data {
0104  public:
0105   /**
0106    * Data read from magic sourceURL comments.
0107    */
0108   Local<Value> GetSourceURL();
0109   /**
0110    * Data read from magic sourceMappingURL comments.
0111    */
0112   Local<Value> GetSourceMappingURL();
0113 
0114   /*
0115    * A unique id.
0116    */
0117   int ScriptId() const;
0118 
0119   static const int kNoScriptId = 0;
0120 };
0121 
0122 static_assert(UnboundModuleScript::kNoScriptId == UnboundScript::kNoScriptId);
0123 
0124 /**
0125  * A location in JavaScript source.
0126  */
0127 class V8_EXPORT Location {
0128  public:
0129   int GetLineNumber() { return line_number_; }
0130   int GetColumnNumber() { return column_number_; }
0131 
0132   Location(int line_number, int column_number)
0133       : line_number_(line_number), column_number_(column_number) {}
0134 
0135  private:
0136   int line_number_;
0137   int column_number_;
0138 };
0139 
0140 class V8_EXPORT ModuleRequest : public Data {
0141  public:
0142   /**
0143    * Returns the module specifier for this ModuleRequest.
0144    */
0145   Local<String> GetSpecifier() const;
0146 
0147   /**
0148    * Returns the module import phase for this ModuleRequest.
0149    */
0150   ModuleImportPhase GetPhase() const;
0151 
0152   /**
0153    * Returns the source code offset of this module request.
0154    * Use Module::SourceOffsetToLocation to convert this to line/column numbers.
0155    */
0156   int GetSourceOffset() const;
0157 
0158   /**
0159    * Contains the import attributes for this request in the form:
0160    * [key1, value1, source_offset1, key2, value2, source_offset2, ...].
0161    * The keys and values are of type v8::String, and the source offsets are of
0162    * type Int32. Use Module::SourceOffsetToLocation to convert the source
0163    * offsets to Locations with line/column numbers.
0164    *
0165    * All attributes present in the module request will be supplied in this
0166    * list, regardless of whether they are supported by the host. Per
0167    * https://tc39.es/proposal-import-attributes/#sec-hostgetsupportedimportattributes,
0168    * hosts are expected to throw for attributes that they do not support (as
0169    * opposed to, for example, ignoring them).
0170    */
0171   Local<FixedArray> GetImportAttributes() const;
0172 
0173   V8_DEPRECATED("Use GetImportAttributes instead")
0174   Local<FixedArray> GetImportAssertions() const {
0175     return GetImportAttributes();
0176   }
0177 
0178   V8_INLINE static ModuleRequest* Cast(Data* data);
0179 
0180  private:
0181   static void CheckCast(Data* obj);
0182 };
0183 
0184 /**
0185  * A compiled JavaScript module.
0186  */
0187 class V8_EXPORT Module : public Data {
0188  public:
0189   /**
0190    * The different states a module can be in.
0191    *
0192    * This corresponds to the states used in ECMAScript except that "evaluated"
0193    * is split into kEvaluated and kErrored, indicating success and failure,
0194    * respectively.
0195    */
0196   enum Status {
0197     kUninstantiated,
0198     kInstantiating,
0199     kInstantiated,
0200     kEvaluating,
0201     kEvaluated,
0202     kErrored
0203   };
0204 
0205   /**
0206    * If the module is a Source Text Module, returns the name that was passed
0207    * by the embedder as resource_name to the ScriptOrigin. If it's a Synthetic
0208    * Module, returns the module_name passed to CreateSyntheticModule().
0209    */
0210   Local<Value> GetResourceName() const;
0211 
0212   /**
0213    * Returns the module's current status.
0214    */
0215   Status GetStatus() const;
0216 
0217   /**
0218    * For a module in kErrored status, this returns the corresponding exception.
0219    */
0220   Local<Value> GetException() const;
0221 
0222   /**
0223    * Returns the ModuleRequests for this module.
0224    */
0225   Local<FixedArray> GetModuleRequests() const;
0226 
0227   /**
0228    * For the given source text offset in this module, returns the corresponding
0229    * Location with line and column numbers.
0230    */
0231   Location SourceOffsetToLocation(int offset) const;
0232 
0233   /**
0234    * Returns the identity hash for this object.
0235    */
0236   int GetIdentityHash() const;
0237 
0238   using ResolveModuleCallback = MaybeLocal<Module> (*)(
0239       Local<Context> context, Local<String> specifier,
0240       Local<FixedArray> import_attributes, Local<Module> referrer);
0241   using ResolveSourceCallback = MaybeLocal<Object> (*)(
0242       Local<Context> context, Local<String> specifier,
0243       Local<FixedArray> import_attributes, Local<Module> referrer);
0244 
0245   using ResolveModuleByIndexCallback = MaybeLocal<Module> (*)(
0246       Local<Context> context, size_t module_request_index,
0247       Local<Module> referrer);
0248   using ResolveSourceByIndexCallback = MaybeLocal<Object> (*)(
0249       Local<Context> context, size_t module_request_index,
0250       Local<Module> referrer);
0251 
0252   /**
0253    * Instantiates the module and its dependencies.
0254    *
0255    * Returns an empty Maybe<bool> if an exception occurred during
0256    * instantiation. (In the case where the callback throws an exception, that
0257    * exception is propagated.)
0258    */
0259   V8_WARN_UNUSED_RESULT Maybe<bool> InstantiateModule(
0260       Local<Context> context, ResolveModuleCallback module_callback,
0261       ResolveSourceCallback source_callback = nullptr);
0262 
0263   /**
0264    * Similar to the variant that takes ResolveModuleCallback and
0265    * ResolveSourceCallback, but uses the index into the array that is returned
0266    * by GetModuleRequests() instead of the specifier and import attributes to
0267    * identify the requests.
0268    */
0269   V8_WARN_UNUSED_RESULT Maybe<bool> InstantiateModule(
0270       Local<Context> context, ResolveModuleByIndexCallback module_callback,
0271       ResolveSourceByIndexCallback source_callback = nullptr);
0272 
0273   /**
0274    * Evaluates the module and its dependencies.
0275    *
0276    * If status is kInstantiated, run the module's code and return a Promise
0277    * object. On success, set status to kEvaluated and resolve the Promise with
0278    * the completion value; on failure, set status to kErrored and reject the
0279    * Promise with the error.
0280    *
0281    * If IsGraphAsync() is false, the returned Promise is settled.
0282    */
0283   V8_WARN_UNUSED_RESULT MaybeLocal<Value> Evaluate(Local<Context> context);
0284 
0285   /**
0286    * Returns the namespace object of this module.
0287    *
0288    * The module's status must be at least kInstantiated.
0289    */
0290   Local<Value> GetModuleNamespace();
0291 
0292   /**
0293    * Returns the corresponding context-unbound module script.
0294    *
0295    * The module must be unevaluated, i.e. its status must not be kEvaluating,
0296    * kEvaluated or kErrored.
0297    */
0298   Local<UnboundModuleScript> GetUnboundModuleScript();
0299 
0300   /**
0301    * Returns the underlying script's id.
0302    *
0303    * The module must be a SourceTextModule and must not have a kErrored status.
0304    */
0305   int ScriptId() const;
0306 
0307   /**
0308    * Returns whether this module or any of its requested modules is async,
0309    * i.e. contains top-level await.
0310    *
0311    * The module's status must be at least kInstantiated.
0312    */
0313   bool IsGraphAsync() const;
0314 
0315   /**
0316    * Returns whether this module is individually asynchronous (for example,
0317    * if it's a Source Text Module Record containing a top-level await).
0318    * See [[HasTLA]] in https://tc39.es/ecma262/#sec-cyclic-module-records
0319    */
0320   bool HasTopLevelAwait() const;
0321 
0322   /**
0323    * Returns whether the module is a SourceTextModule.
0324    */
0325   bool IsSourceTextModule() const;
0326 
0327   /**
0328    * Returns whether the module is a SyntheticModule.
0329    */
0330   bool IsSyntheticModule() const;
0331 
0332   /*
0333    * Callback defined in the embedder.  This is responsible for setting
0334    * the module's exported values with calls to SetSyntheticModuleExport().
0335    * The callback must return a resolved Promise to indicate success (where no
0336    * exception was thrown) and return an empy MaybeLocal to indicate falure
0337    * (where an exception was thrown).
0338    */
0339   using SyntheticModuleEvaluationSteps =
0340       MaybeLocal<Value> (*)(Local<Context> context, Local<Module> module);
0341 
0342   /**
0343    * Creates a new SyntheticModule with the specified export names, where
0344    * evaluation_steps will be executed upon module evaluation.
0345    * export_names must not contain duplicates.
0346    * module_name is used solely for logging/debugging and doesn't affect module
0347    * behavior.
0348    */
0349   static Local<Module> CreateSyntheticModule(
0350       Isolate* isolate, Local<String> module_name,
0351       const MemorySpan<const Local<String>>& export_names,
0352       SyntheticModuleEvaluationSteps evaluation_steps);
0353 
0354   /**
0355    * Set this module's exported value for the name export_name to the specified
0356    * export_value. This method must be called only on Modules created via
0357    * CreateSyntheticModule.  An error will be thrown if export_name is not one
0358    * of the export_names that were passed in that CreateSyntheticModule call.
0359    * Returns Just(true) on success, Nothing<bool>() if an error was thrown.
0360    */
0361   V8_WARN_UNUSED_RESULT Maybe<bool> SetSyntheticModuleExport(
0362       Isolate* isolate, Local<String> export_name, Local<Value> export_value);
0363 
0364   /**
0365    * Search the modules requested directly or indirectly by the module for
0366    * any top-level await that has not yet resolved. If there is any, the
0367    * returned pair of vectors (of equal size) contain the unresolved module
0368    * and corresponding message with the pending top-level await.
0369    * An embedder may call this before exiting to improve error messages.
0370    */
0371   std::pair<LocalVector<Module>, LocalVector<Message>>
0372   GetStalledTopLevelAwaitMessages(Isolate* isolate);
0373 
0374   V8_INLINE static Module* Cast(Data* data);
0375 
0376  private:
0377   static void CheckCast(Data* obj);
0378 };
0379 
0380 class V8_EXPORT CompileHintsCollector : public Data {
0381  public:
0382   /**
0383    * Returns the positions of lazy functions which were compiled and executed.
0384    */
0385   std::vector<int> GetCompileHints(Isolate* isolate) const;
0386 };
0387 
0388 /**
0389  * A compiled JavaScript script, tied to a Context which was active when the
0390  * script was compiled.
0391  */
0392 class V8_EXPORT Script : public Data {
0393  public:
0394   /**
0395    * A shorthand for ScriptCompiler::Compile().
0396    */
0397   static V8_WARN_UNUSED_RESULT MaybeLocal<Script> Compile(
0398       Local<Context> context, Local<String> source,
0399       ScriptOrigin* origin = nullptr);
0400 
0401   /**
0402    * Runs the script returning the resulting value. It will be run in the
0403    * context in which it was created (ScriptCompiler::CompileBound or
0404    * UnboundScript::BindToCurrentContext()).
0405    */
0406   V8_WARN_UNUSED_RESULT MaybeLocal<Value> Run(Local<Context> context);
0407   V8_WARN_UNUSED_RESULT MaybeLocal<Value> Run(Local<Context> context,
0408                                               Local<Data> host_defined_options);
0409 
0410   /**
0411    * Returns the corresponding context-unbound script.
0412    */
0413   Local<UnboundScript> GetUnboundScript();
0414 
0415   /**
0416    * Returns the id of the corresponding context-unbound script.
0417    */
0418   int ScriptId() const;
0419 
0420   /**
0421    * The name that was passed by the embedder as ResourceName to the
0422    * ScriptOrigin. This can be either a v8::String or v8::Undefined.
0423    */
0424   Local<Value> GetResourceName();
0425 
0426   /**
0427    * If the script was compiled, returns the positions of lazy functions which
0428    * were eventually compiled and executed.
0429    */
0430   V8_DEPRECATE_SOON("Use GetCompileHintsCollector instead")
0431   std::vector<int> GetProducedCompileHints() const;
0432 
0433   /**
0434    * Get a compile hints collector object which we can use later for retrieving
0435    * compile hints (= positions of lazy functions which were compiled and
0436    * executed).
0437    */
0438   Local<CompileHintsCollector> GetCompileHintsCollector() const;
0439 };
0440 
0441 enum class ScriptType { kClassic, kModule };
0442 
0443 /**
0444  * For compiling scripts.
0445  */
0446 class V8_EXPORT ScriptCompiler {
0447  public:
0448   class ConsumeCodeCacheTask;
0449 
0450   /**
0451    * Compilation data that the embedder can cache and pass back to speed up
0452    * future compilations. The data is produced if the CompilerOptions passed to
0453    * the compilation functions in ScriptCompiler contains produce_data_to_cache
0454    * = true. The data to cache can then can be retrieved from
0455    * UnboundScript.
0456    */
0457   struct V8_EXPORT CachedData {
0458     enum BufferPolicy { BufferNotOwned, BufferOwned };
0459 
0460     CachedData()
0461         : data(nullptr),
0462           length(0),
0463           rejected(false),
0464           buffer_policy(BufferNotOwned) {}
0465 
0466     // If buffer_policy is BufferNotOwned, the caller keeps the ownership of
0467     // data and guarantees that it stays alive until the CachedData object is
0468     // destroyed. If the policy is BufferOwned, the given data will be deleted
0469     // (with delete[]) when the CachedData object is destroyed.
0470     CachedData(const uint8_t* data, int length,
0471                BufferPolicy buffer_policy = BufferNotOwned);
0472     ~CachedData();
0473 
0474     enum CompatibilityCheckResult {
0475       // Don't change order/existing values of this enum since it keys into the
0476       // `code_cache_reject_reason` histogram. Append-only!
0477       kSuccess = 0,
0478       kMagicNumberMismatch = 1,
0479       kVersionMismatch = 2,
0480       kSourceMismatch = 3,
0481       kFlagsMismatch = 5,
0482       kChecksumMismatch = 6,
0483       kInvalidHeader = 7,
0484       kLengthMismatch = 8,
0485       kReadOnlySnapshotChecksumMismatch = 9,
0486 
0487       // This should always point at the last real enum value.
0488       kLast = kReadOnlySnapshotChecksumMismatch
0489     };
0490 
0491     // Check if the CachedData can be loaded in the given isolate.
0492     CompatibilityCheckResult CompatibilityCheck(Isolate* isolate);
0493 
0494     // TODO(marja): Async compilation; add constructors which take a callback
0495     // which will be called when V8 no longer needs the data.
0496     const uint8_t* data;
0497     int length;
0498     bool rejected;
0499     BufferPolicy buffer_policy;
0500 
0501     // Prevent copying.
0502     CachedData(const CachedData&) = delete;
0503     CachedData& operator=(const CachedData&) = delete;
0504   };
0505 
0506   enum class InMemoryCacheResult {
0507     // V8 did not attempt to find this script in its in-memory cache.
0508     kNotAttempted,
0509 
0510     // V8 found a previously compiled copy of this script in its in-memory
0511     // cache. Any data generated by a streaming compilation or background
0512     // deserialization was abandoned.
0513     kHit,
0514 
0515     // V8 didn't have any previously compiled data for this script.
0516     kMiss,
0517 
0518     // V8 had some previously compiled data for an identical script, but the
0519     // data was incomplete.
0520     kPartial,
0521   };
0522 
0523   // Details about what happened during a compilation.
0524   struct CompilationDetails {
0525     InMemoryCacheResult in_memory_cache_result =
0526         InMemoryCacheResult::kNotAttempted;
0527 
0528     static constexpr int64_t kTimeNotMeasured = -1;
0529     int64_t foreground_time_in_microseconds = kTimeNotMeasured;
0530     int64_t background_time_in_microseconds = kTimeNotMeasured;
0531   };
0532 
0533   /**
0534    * Source code which can be then compiled to a UnboundScript or Script.
0535    */
0536   class Source {
0537    public:
0538     // Source takes ownership of both CachedData and CodeCacheConsumeTask.
0539     // The caller *must* ensure that the cached data is from a trusted source.
0540     V8_INLINE Source(Local<String> source_string, const ScriptOrigin& origin,
0541                      CachedData* cached_data = nullptr,
0542                      ConsumeCodeCacheTask* consume_cache_task = nullptr);
0543     // Source takes ownership of both CachedData and CodeCacheConsumeTask.
0544     V8_INLINE explicit Source(
0545         Local<String> source_string, CachedData* cached_data = nullptr,
0546         ConsumeCodeCacheTask* consume_cache_task = nullptr);
0547     V8_INLINE Source(Local<String> source_string, const ScriptOrigin& origin,
0548                      CompileHintCallback callback, void* callback_data);
0549     V8_INLINE ~Source() = default;
0550 
0551     // Ownership of the CachedData or its buffers is *not* transferred to the
0552     // caller. The CachedData object is alive as long as the Source object is
0553     // alive.
0554     V8_INLINE const CachedData* GetCachedData() const;
0555 
0556     V8_INLINE const ScriptOriginOptions& GetResourceOptions() const;
0557 
0558     V8_INLINE const CompilationDetails& GetCompilationDetails() const;
0559 
0560    private:
0561     friend class ScriptCompiler;
0562 
0563     Local<String> source_string;
0564 
0565     // Origin information
0566     Local<Value> resource_name;
0567     int resource_line_offset = -1;
0568     int resource_column_offset = -1;
0569     ScriptOriginOptions resource_options;
0570     Local<Value> source_map_url;
0571     Local<Data> host_defined_options;
0572 
0573     // Cached data from previous compilation (if a kConsume*Cache flag is
0574     // set), or hold newly generated cache data (kProduce*Cache flags) are
0575     // set when calling a compile method.
0576     std::unique_ptr<CachedData> cached_data;
0577     std::unique_ptr<ConsumeCodeCacheTask> consume_cache_task;
0578 
0579     // For requesting compile hints from the embedder.
0580     CompileHintCallback compile_hint_callback = nullptr;
0581     void* compile_hint_callback_data = nullptr;
0582 
0583     // V8 writes this data and never reads it. It exists only to be informative
0584     // to the embedder.
0585     CompilationDetails compilation_details;
0586   };
0587 
0588   /**
0589    * For streaming incomplete script data to V8. The embedder should implement a
0590    * subclass of this class.
0591    */
0592   class V8_EXPORT ExternalSourceStream {
0593    public:
0594     virtual ~ExternalSourceStream() = default;
0595 
0596     /**
0597      * V8 calls this to request the next chunk of data from the embedder. This
0598      * function will be called on a background thread, so it's OK to block and
0599      * wait for the data, if the embedder doesn't have data yet. Returns the
0600      * length of the data returned. When the data ends, GetMoreData should
0601      * return 0. Caller takes ownership of the data.
0602      *
0603      * When streaming UTF-8 data, V8 handles multi-byte characters split between
0604      * two data chunks, but doesn't handle multi-byte characters split between
0605      * more than two data chunks. The embedder can avoid this problem by always
0606      * returning at least 2 bytes of data.
0607      *
0608      * When streaming UTF-16 data, V8 does not handle characters split between
0609      * two data chunks. The embedder has to make sure that chunks have an even
0610      * length.
0611      *
0612      * If the embedder wants to cancel the streaming, they should make the next
0613      * GetMoreData call return 0. V8 will interpret it as end of data (and most
0614      * probably, parsing will fail). The streaming task will return as soon as
0615      * V8 has parsed the data it received so far.
0616      */
0617     virtual size_t GetMoreData(const uint8_t** src) = 0;
0618   };
0619 
0620   /**
0621    * Source code which can be streamed into V8 in pieces. It will be parsed
0622    * while streaming and compiled after parsing has completed. StreamedSource
0623    * must be kept alive while the streaming task is run (see ScriptStreamingTask
0624    * below).
0625    */
0626   class V8_EXPORT StreamedSource {
0627    public:
0628     enum Encoding { ONE_BYTE, TWO_BYTE, UTF8, WINDOWS_1252 };
0629 
0630     StreamedSource(std::unique_ptr<ExternalSourceStream> source_stream,
0631                    Encoding encoding);
0632     ~StreamedSource();
0633 
0634     internal::ScriptStreamingData* impl() const { return impl_.get(); }
0635 
0636     // Prevent copying.
0637     StreamedSource(const StreamedSource&) = delete;
0638     StreamedSource& operator=(const StreamedSource&) = delete;
0639 
0640     CompilationDetails& compilation_details() { return compilation_details_; }
0641 
0642    private:
0643     std::unique_ptr<internal::ScriptStreamingData> impl_;
0644 
0645     // V8 writes this data and never reads it. It exists only to be informative
0646     // to the embedder.
0647     CompilationDetails compilation_details_;
0648   };
0649 
0650   /**
0651    * A streaming task which the embedder must run on a background thread to
0652    * stream scripts into V8. Returned by ScriptCompiler::StartStreaming.
0653    */
0654   class V8_EXPORT ScriptStreamingTask final {
0655    public:
0656     void Run();
0657 
0658    private:
0659     friend class ScriptCompiler;
0660 
0661     explicit ScriptStreamingTask(internal::ScriptStreamingData* data)
0662         : data_(data) {}
0663 
0664     internal::ScriptStreamingData* data_;
0665   };
0666 
0667   /**
0668    * A task which the embedder must run on a background thread to
0669    * consume a V8 code cache. Returned by
0670    * ScriptCompiler::StartConsumingCodeCache.
0671    */
0672   class V8_EXPORT ConsumeCodeCacheTask final {
0673    public:
0674     ~ConsumeCodeCacheTask();
0675 
0676     void Run();
0677 
0678     /**
0679      * Provides the source text string and origin information to the consumption
0680      * task. May be called before, during, or after Run(). This step checks
0681      * whether the script matches an existing script in the Isolate's
0682      * compilation cache. To check whether such a script was found, call
0683      * ShouldMergeWithExistingScript.
0684      *
0685      * The Isolate provided must be the same one used during
0686      * StartConsumingCodeCache and must be currently entered on the thread that
0687      * calls this function. The source text and origin provided in this step
0688      * must precisely match those used later in the ScriptCompiler::Source that
0689      * will contain this ConsumeCodeCacheTask.
0690      */
0691     void SourceTextAvailable(Isolate* isolate, Local<String> source_text,
0692                              const ScriptOrigin& origin);
0693 
0694     /**
0695      * Returns whether the embedder should call MergeWithExistingScript. This
0696      * function may be called from any thread, any number of times, but its
0697      * return value is only meaningful after SourceTextAvailable has completed.
0698      */
0699     bool ShouldMergeWithExistingScript() const;
0700 
0701     /**
0702      * Merges newly deserialized data into an existing script which was found
0703      * during SourceTextAvailable. May be called only after Run() has completed.
0704      * Can execute on any thread, like Run().
0705      */
0706     void MergeWithExistingScript();
0707 
0708    private:
0709     friend class ScriptCompiler;
0710 
0711     explicit ConsumeCodeCacheTask(
0712         std::unique_ptr<internal::BackgroundDeserializeTask> impl);
0713 
0714     std::unique_ptr<internal::BackgroundDeserializeTask> impl_;
0715   };
0716 
0717   enum CompileOptions {
0718     kNoCompileOptions = 0,
0719     kConsumeCodeCache = 1 << 0,
0720     kEagerCompile = 1 << 1,
0721     kProduceCompileHints = 1 << 2,
0722     kConsumeCompileHints = 1 << 3,
0723     kFollowCompileHintsMagicComment = 1 << 4,
0724     kFollowCompileHintsPerFunctionMagicComment = 1 << 5,
0725   };
0726 
0727   static inline bool CompileOptionsIsValid(CompileOptions compile_options) {
0728     // kConsumeCodeCache is mutually exclusive with all other flag bits.
0729     if ((compile_options & kConsumeCodeCache) &&
0730         compile_options != kConsumeCodeCache) {
0731       return false;
0732     }
0733     // kEagerCompile is mutually exclusive with all other flag bits.
0734     if ((compile_options & kEagerCompile) && compile_options != kEagerCompile) {
0735       return false;
0736     }
0737     // We don't currently support producing and consuming compile hints at the
0738     // same time.
0739     constexpr int produce_and_consume = CompileOptions::kProduceCompileHints |
0740                                         CompileOptions::kConsumeCompileHints;
0741     if ((compile_options & produce_and_consume) == produce_and_consume) {
0742       return false;
0743     }
0744     return true;
0745   }
0746 
0747   /**
0748    * The reason for which we are not requesting or providing a code cache.
0749    */
0750   enum NoCacheReason {
0751     kNoCacheNoReason = 0,
0752     kNoCacheBecauseCachingDisabled,
0753     kNoCacheBecauseNoResource,
0754     kNoCacheBecauseInlineScript,
0755     kNoCacheBecauseModule,
0756     kNoCacheBecauseStreamingSource,
0757     kNoCacheBecauseInspector,
0758     kNoCacheBecauseScriptTooSmall,
0759     kNoCacheBecauseCacheTooCold,
0760     kNoCacheBecauseV8Extension,
0761     kNoCacheBecauseExtensionModule,
0762     kNoCacheBecausePacScript,
0763     kNoCacheBecauseInDocumentWrite,
0764     kNoCacheBecauseResourceWithNoCacheHandler,
0765     kNoCacheBecauseDeferredProduceCodeCache,
0766     kNoCacheBecauseStaticCodeCache,
0767   };
0768 
0769   /**
0770    * Compiles the specified script (context-independent).
0771    * Cached data as part of the source object can be optionally produced to be
0772    * consumed later to speed up compilation of identical source scripts.
0773    *
0774    * Note that when producing cached data, the source must point to NULL for
0775    * cached data. When consuming cached data, the cached data must have been
0776    * produced by the same version of V8, and the embedder needs to ensure the
0777    * cached data is the correct one for the given script.
0778    *
0779    * \param source Script source code.
0780    * \return Compiled script object (context independent; for running it must be
0781    *   bound to a context).
0782    */
0783   static V8_WARN_UNUSED_RESULT MaybeLocal<UnboundScript> CompileUnboundScript(
0784       Isolate* isolate, Source* source,
0785       CompileOptions options = kNoCompileOptions,
0786       NoCacheReason no_cache_reason = kNoCacheNoReason);
0787 
0788   /**
0789    * Compiles the specified script (bound to current context).
0790    *
0791    * \param source Script source code.
0792    * \param pre_data Pre-parsing data, as obtained by ScriptData::PreCompile()
0793    *   using pre_data speeds compilation if it's done multiple times.
0794    *   Owned by caller, no references are kept when this function returns.
0795    * \return Compiled script object, bound to the context that was active
0796    *   when this function was called. When run it will always use this
0797    *   context.
0798    */
0799   static V8_WARN_UNUSED_RESULT MaybeLocal<Script> Compile(
0800       Local<Context> context, Source* source,
0801       CompileOptions options = kNoCompileOptions,
0802       NoCacheReason no_cache_reason = kNoCacheNoReason);
0803 
0804   /**
0805    * Returns a task which streams script data into V8, or NULL if the script
0806    * cannot be streamed. The user is responsible for running the task on a
0807    * background thread and deleting it. When ran, the task starts parsing the
0808    * script, and it will request data from the StreamedSource as needed. When
0809    * ScriptStreamingTask::Run exits, all data has been streamed and the script
0810    * can be compiled (see Compile below).
0811    *
0812    * This API allows to start the streaming with as little data as possible, and
0813    * the remaining data (for example, the ScriptOrigin) is passed to Compile.
0814    */
0815   static ScriptStreamingTask* StartStreaming(
0816       Isolate* isolate, StreamedSource* source,
0817       ScriptType type = ScriptType::kClassic,
0818       CompileOptions options = kNoCompileOptions,
0819       CompileHintCallback compile_hint_callback = nullptr,
0820       void* compile_hint_callback_data = nullptr);
0821 
0822   static ConsumeCodeCacheTask* StartConsumingCodeCache(
0823       Isolate* isolate, std::unique_ptr<CachedData> source);
0824   static ConsumeCodeCacheTask* StartConsumingCodeCacheOnBackground(
0825       Isolate* isolate, std::unique_ptr<CachedData> source);
0826 
0827   /**
0828    * Compiles a streamed script (bound to current context).
0829    *
0830    * This can only be called after the streaming has finished
0831    * (ScriptStreamingTask has been run). V8 doesn't construct the source string
0832    * during streaming, so the embedder needs to pass the full source here.
0833    */
0834   static V8_WARN_UNUSED_RESULT MaybeLocal<Script> Compile(
0835       Local<Context> context, StreamedSource* source,
0836       Local<String> full_source_string, const ScriptOrigin& origin);
0837 
0838   /**
0839    * Return a version tag for CachedData for the current V8 version & flags.
0840    *
0841    * This value is meant only for determining whether a previously generated
0842    * CachedData instance is still valid; the tag has no other meaing.
0843    *
0844    * Background: The data carried by CachedData may depend on the exact
0845    *   V8 version number or current compiler flags. This means that when
0846    *   persisting CachedData, the embedder must take care to not pass in
0847    *   data from another V8 version, or the same version with different
0848    *   features enabled.
0849    *
0850    *   The easiest way to do so is to clear the embedder's cache on any
0851    *   such change.
0852    *
0853    *   Alternatively, this tag can be stored alongside the cached data and
0854    *   compared when it is being used.
0855    */
0856   static uint32_t CachedDataVersionTag();
0857 
0858   /**
0859    * Compile an ES module, returning a Module that encapsulates
0860    * the compiled code.
0861    *
0862    * Corresponds to the ParseModule abstract operation in the
0863    * ECMAScript specification.
0864    */
0865   static V8_WARN_UNUSED_RESULT MaybeLocal<Module> CompileModule(
0866       Isolate* isolate, Source* source,
0867       CompileOptions options = kNoCompileOptions,
0868       NoCacheReason no_cache_reason = kNoCacheNoReason);
0869 
0870   /**
0871    * Compiles a streamed module script.
0872    *
0873    * This can only be called after the streaming has finished
0874    * (ScriptStreamingTask has been run). V8 doesn't construct the source string
0875    * during streaming, so the embedder needs to pass the full source here.
0876    */
0877   static V8_WARN_UNUSED_RESULT MaybeLocal<Module> CompileModule(
0878       Local<Context> context, StreamedSource* v8_source,
0879       Local<String> full_source_string, const ScriptOrigin& origin);
0880 
0881   /**
0882    * Compile a function for a given context. This is equivalent to running
0883    *
0884    * with (obj) {
0885    *   return function(args) { ... }
0886    * }
0887    *
0888    * It is possible to specify multiple context extensions (obj in the above
0889    * example).
0890    */
0891   static V8_WARN_UNUSED_RESULT MaybeLocal<Function> CompileFunction(
0892       Local<Context> context, Source* source, size_t arguments_count = 0,
0893       Local<String> arguments[] = nullptr, size_t context_extension_count = 0,
0894       Local<Object> context_extensions[] = nullptr,
0895       CompileOptions options = kNoCompileOptions,
0896       NoCacheReason no_cache_reason = kNoCacheNoReason);
0897 
0898   /**
0899    * Creates and returns code cache for the specified unbound_script.
0900    * This will return nullptr if the script cannot be serialized. The
0901    * CachedData returned by this function should be owned by the caller.
0902    */
0903   static CachedData* CreateCodeCache(Local<UnboundScript> unbound_script);
0904 
0905   /**
0906    * Creates and returns code cache for the specified unbound_module_script.
0907    * This will return nullptr if the script cannot be serialized. The
0908    * CachedData returned by this function should be owned by the caller.
0909    */
0910   static CachedData* CreateCodeCache(
0911       Local<UnboundModuleScript> unbound_module_script);
0912 
0913   /**
0914    * Creates and returns code cache for the specified function that was
0915    * previously produced by CompileFunction.
0916    * This will return nullptr if the script cannot be serialized. The
0917    * CachedData returned by this function should be owned by the caller.
0918    */
0919   static CachedData* CreateCodeCacheForFunction(Local<Function> function);
0920 
0921  private:
0922   static V8_WARN_UNUSED_RESULT MaybeLocal<UnboundScript> CompileUnboundInternal(
0923       Isolate* isolate, Source* source, CompileOptions options,
0924       NoCacheReason no_cache_reason);
0925 
0926   static V8_WARN_UNUSED_RESULT MaybeLocal<Function> CompileFunctionInternal(
0927       Local<Context> context, Source* source, size_t arguments_count,
0928       Local<String> arguments[], size_t context_extension_count,
0929       Local<Object> context_extensions[], CompileOptions options,
0930       NoCacheReason no_cache_reason,
0931       Local<ScriptOrModule>* script_or_module_out);
0932 };
0933 
0934 ScriptCompiler::Source::Source(Local<String> string, const ScriptOrigin& origin,
0935                                CachedData* data,
0936                                ConsumeCodeCacheTask* consume_cache_task)
0937     : source_string(string),
0938       resource_name(origin.ResourceName()),
0939       resource_line_offset(origin.LineOffset()),
0940       resource_column_offset(origin.ColumnOffset()),
0941       resource_options(origin.Options()),
0942       source_map_url(origin.SourceMapUrl()),
0943       host_defined_options(origin.GetHostDefinedOptions()),
0944       cached_data(data),
0945       consume_cache_task(consume_cache_task) {}
0946 
0947 ScriptCompiler::Source::Source(Local<String> string, CachedData* data,
0948                                ConsumeCodeCacheTask* consume_cache_task)
0949     : source_string(string),
0950       cached_data(data),
0951       consume_cache_task(consume_cache_task) {}
0952 
0953 ScriptCompiler::Source::Source(Local<String> string, const ScriptOrigin& origin,
0954                                CompileHintCallback callback,
0955                                void* callback_data)
0956     : source_string(string),
0957       resource_name(origin.ResourceName()),
0958       resource_line_offset(origin.LineOffset()),
0959       resource_column_offset(origin.ColumnOffset()),
0960       resource_options(origin.Options()),
0961       source_map_url(origin.SourceMapUrl()),
0962       host_defined_options(origin.GetHostDefinedOptions()),
0963       compile_hint_callback(callback),
0964       compile_hint_callback_data(callback_data) {}
0965 
0966 const ScriptCompiler::CachedData* ScriptCompiler::Source::GetCachedData()
0967     const {
0968   return cached_data.get();
0969 }
0970 
0971 const ScriptOriginOptions& ScriptCompiler::Source::GetResourceOptions() const {
0972   return resource_options;
0973 }
0974 
0975 const ScriptCompiler::CompilationDetails&
0976 ScriptCompiler::Source::GetCompilationDetails() const {
0977   return compilation_details;
0978 }
0979 
0980 ModuleRequest* ModuleRequest::Cast(Data* data) {
0981 #ifdef V8_ENABLE_CHECKS
0982   CheckCast(data);
0983 #endif
0984   return reinterpret_cast<ModuleRequest*>(data);
0985 }
0986 
0987 Module* Module::Cast(Data* data) {
0988 #ifdef V8_ENABLE_CHECKS
0989   CheckCast(data);
0990 #endif
0991   return reinterpret_cast<Module*>(data);
0992 }
0993 
0994 }  // namespace v8
0995 
0996 #endif  // INCLUDE_V8_SCRIPT_H_