Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-01 08:24:14

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