1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #ifndef mozilla_dom_LoadedScript_h
8 #define mozilla_dom_LoadedScript_h
9 
10 #include "nsCOMPtr.h"
11 #include "nsCycleCollectionParticipant.h"
12 #include "jsapi.h"
13 #include "ScriptLoadRequest.h"
14 
15 class nsIURI;
16 
17 namespace mozilla {
18 namespace dom {
19 
20 class ScriptLoader;
21 
22 void HostAddRefTopLevelScript(const JS::Value& aPrivate);
23 void HostReleaseTopLevelScript(const JS::Value& aPrivate);
24 
25 class ClassicScript;
26 class ModuleScript;
27 class EventScript;
28 
29 class LoadedScript : public nsISupports {
30   ScriptKind mKind;
31   RefPtr<ScriptFetchOptions> mFetchOptions;
32   nsCOMPtr<nsIURI> mBaseURL;
33 
34  protected:
35   LoadedScript(ScriptKind aKind, ScriptFetchOptions* aFetchOptions,
36                nsIURI* aBaseURL);
37 
38   virtual ~LoadedScript();
39 
40  public:
41   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(LoadedScript)42   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(LoadedScript)
43 
44   bool IsModuleScript() const { return mKind == ScriptKind::eModule; }
IsEventScript()45   bool IsEventScript() const { return mKind == ScriptKind::eEvent; }
46 
47   inline ClassicScript* AsClassicScript();
48   inline ModuleScript* AsModuleScript();
49   inline EventScript* AsEventScript();
50 
GetFetchOptions()51   ScriptFetchOptions* GetFetchOptions() const { return mFetchOptions; }
BaseURL()52   nsIURI* BaseURL() const { return mBaseURL; }
53 
54   void AssociateWithScript(JSScript* aScript);
55 };
56 
57 class ClassicScript final : public LoadedScript {
58   ~ClassicScript() = default;
59 
60  public:
61   ClassicScript(ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL);
62 };
63 
64 class EventScript final : public LoadedScript {
65   ~EventScript() = default;
66 
67  public:
68   EventScript(ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL);
69 };
70 
71 // A single module script. May be used to satisfy multiple load requests.
72 
73 class ModuleScript final : public LoadedScript {
74   JS::Heap<JSObject*> mModuleRecord;
75   JS::Heap<JS::Value> mParseError;
76   JS::Heap<JS::Value> mErrorToRethrow;
77   bool mDebuggerDataInitialized;
78 
79   ~ModuleScript();
80 
81  public:
82   NS_DECL_ISUPPORTS_INHERITED
83   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ModuleScript,
84                                                          LoadedScript)
85 
86   ModuleScript(ScriptFetchOptions* aFetchOptions, nsIURI* aBaseURL);
87 
88   void SetModuleRecord(JS::Handle<JSObject*> aModuleRecord);
89   void SetParseError(const JS::Value& aError);
90   void SetErrorToRethrow(const JS::Value& aError);
91   void SetDebuggerDataInitialized();
92 
ModuleRecord()93   JSObject* ModuleRecord() const { return mModuleRecord; }
94 
ParseError()95   JS::Value ParseError() const { return mParseError; }
ErrorToRethrow()96   JS::Value ErrorToRethrow() const { return mErrorToRethrow; }
HasParseError()97   bool HasParseError() const { return !mParseError.isUndefined(); }
HasErrorToRethrow()98   bool HasErrorToRethrow() const { return !mErrorToRethrow.isUndefined(); }
DebuggerDataInitialized()99   bool DebuggerDataInitialized() const { return mDebuggerDataInitialized; }
100 
101   void UnlinkModuleRecord();
102 
103   friend void CheckModuleScriptPrivate(LoadedScript*, const JS::Value&);
104 };
105 
AsClassicScript()106 ClassicScript* LoadedScript::AsClassicScript() {
107   MOZ_ASSERT(!IsModuleScript());
108   return static_cast<ClassicScript*>(this);
109 }
110 
AsModuleScript()111 ModuleScript* LoadedScript::AsModuleScript() {
112   MOZ_ASSERT(IsModuleScript());
113   return static_cast<ModuleScript*>(this);
114 }
115 
116 }  // namespace dom
117 }  // namespace mozilla
118 
119 #endif  // mozilla_dom_LoadedScript_h
120