Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-21 10:05:26

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