LCOV - code coverage report
Current view: top level - js/src/builtin - ModuleObject.h (source / functions) Hit Total Coverage
Test: output.info Lines: 2 16 12.5 %
Date: 2017-07-14 16:53:18 Functions: 1 12 8.3 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
       2             :  * vim: set ts=8 sts=4 et sw=4 tw=99:
       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 builtin_ModuleObject_h
       8             : #define builtin_ModuleObject_h
       9             : 
      10             : #include "jsapi.h"
      11             : #include "jsatom.h"
      12             : 
      13             : #include "builtin/SelfHostingDefines.h"
      14             : #include "gc/Zone.h"
      15             : #include "js/GCVector.h"
      16             : #include "js/Id.h"
      17             : #include "vm/NativeObject.h"
      18             : #include "vm/ProxyObject.h"
      19             : 
      20             : namespace js {
      21             : 
      22             : class ModuleEnvironmentObject;
      23             : class ModuleObject;
      24             : 
      25             : namespace frontend {
      26             : class ParseNode;
      27             : } /* namespace frontend */
      28             : 
      29             : typedef Rooted<ModuleObject*> RootedModuleObject;
      30             : typedef Handle<ModuleObject*> HandleModuleObject;
      31             : typedef Rooted<ModuleEnvironmentObject*> RootedModuleEnvironmentObject;
      32             : typedef Handle<ModuleEnvironmentObject*> HandleModuleEnvironmentObject;
      33             : 
      34             : class ImportEntryObject : public NativeObject
      35             : {
      36             :   public:
      37             :     enum
      38             :     {
      39             :         ModuleRequestSlot = 0,
      40             :         ImportNameSlot,
      41             :         LocalNameSlot,
      42             :         SlotCount
      43             :     };
      44             : 
      45             :     static const Class class_;
      46             :     static JSObject* initClass(JSContext* cx, HandleObject obj);
      47             :     static bool isInstance(HandleValue value);
      48             :     static ImportEntryObject* create(JSContext* cx,
      49             :                                      HandleAtom moduleRequest,
      50             :                                      HandleAtom importName,
      51             :                                      HandleAtom localName);
      52             :     JSAtom* moduleRequest() const;
      53             :     JSAtom* importName() const;
      54             :     JSAtom* localName() const;
      55             : };
      56             : 
      57             : typedef Rooted<ImportEntryObject*> RootedImportEntryObject;
      58             : typedef Handle<ImportEntryObject*> HandleImportEntryObject;
      59             : 
      60             : class ExportEntryObject : public NativeObject
      61             : {
      62             :   public:
      63             :     enum
      64             :     {
      65             :         ExportNameSlot = 0,
      66             :         ModuleRequestSlot,
      67             :         ImportNameSlot,
      68             :         LocalNameSlot,
      69             :         SlotCount
      70             :     };
      71             : 
      72             :     static const Class class_;
      73             :     static JSObject* initClass(JSContext* cx, HandleObject obj);
      74             :     static bool isInstance(HandleValue value);
      75             :     static ExportEntryObject* create(JSContext* cx,
      76             :                                      HandleAtom maybeExportName,
      77             :                                      HandleAtom maybeModuleRequest,
      78             :                                      HandleAtom maybeImportName,
      79             :                                      HandleAtom maybeLocalName);
      80             :     JSAtom* exportName() const;
      81             :     JSAtom* moduleRequest() const;
      82             :     JSAtom* importName() const;
      83             :     JSAtom* localName() const;
      84             : };
      85             : 
      86             : typedef Rooted<ExportEntryObject*> RootedExportEntryObject;
      87             : typedef Handle<ExportEntryObject*> HandleExportEntryObject;
      88             : 
      89           0 : class IndirectBindingMap
      90             : {
      91             :   public:
      92             :     explicit IndirectBindingMap(Zone* zone);
      93             :     bool init();
      94             : 
      95             :     void trace(JSTracer* trc);
      96             : 
      97             :     bool putNew(JSContext* cx, HandleId name,
      98             :                 HandleModuleEnvironmentObject environment, HandleId localName);
      99             : 
     100           0 :     size_t count() const {
     101           0 :         return map_.count();
     102             :     }
     103             : 
     104           0 :     bool has(jsid name) const {
     105           0 :         return map_.has(name);
     106             :     }
     107             : 
     108             :     bool lookup(jsid name, ModuleEnvironmentObject** envOut, Shape** shapeOut) const;
     109             : 
     110             :     template <typename Func>
     111           0 :     void forEachExportedName(Func func) const {
     112           0 :         for (auto r = map_.all(); !r.empty(); r.popFront())
     113           0 :             func(r.front().key());
     114           0 :     }
     115             : 
     116             :   private:
     117           0 :     struct Binding
     118             :     {
     119             :         Binding(ModuleEnvironmentObject* environment, Shape* shape);
     120             :         HeapPtr<ModuleEnvironmentObject*> environment;
     121             :         HeapPtr<Shape*> shape;
     122             :     };
     123             : 
     124             :     typedef HashMap<jsid, Binding, DefaultHasher<jsid>, ZoneAllocPolicy> Map;
     125             : 
     126             :     Map map_;
     127             : };
     128             : 
     129             : class ModuleNamespaceObject : public ProxyObject
     130             : {
     131             :   public:
     132             :     static bool isInstance(HandleValue value);
     133             :     static ModuleNamespaceObject* create(JSContext* cx, HandleModuleObject module);
     134             : 
     135             :     ModuleObject& module();
     136             :     JSObject& exports();
     137             :     IndirectBindingMap& bindings();
     138             : 
     139             :     bool addBinding(JSContext* cx, HandleAtom exportedName, HandleModuleObject targetModule,
     140             :                     HandleAtom localName);
     141             : 
     142             :   private:
     143             :     struct ProxyHandler : public BaseProxyHandler
     144             :     {
     145             :         ProxyHandler();
     146             : 
     147             :         bool getOwnPropertyDescriptor(JSContext* cx, HandleObject proxy, HandleId id,
     148             :                                       MutableHandle<PropertyDescriptor> desc) const override;
     149             :         bool defineProperty(JSContext* cx, HandleObject proxy, HandleId id,
     150             :                             Handle<PropertyDescriptor> desc,
     151             :                             ObjectOpResult& result) const override;
     152             :         bool ownPropertyKeys(JSContext* cx, HandleObject proxy,
     153             :                              AutoIdVector& props) const override;
     154             :         bool delete_(JSContext* cx, HandleObject proxy, HandleId id,
     155             :                      ObjectOpResult& result) const override;
     156             :         bool getPrototype(JSContext* cx, HandleObject proxy,
     157             :                           MutableHandleObject protop) const override;
     158             :         bool setPrototype(JSContext* cx, HandleObject proxy, HandleObject proto,
     159             :                           ObjectOpResult& result) const override;
     160             :         bool getPrototypeIfOrdinary(JSContext* cx, HandleObject proxy, bool* isOrdinary,
     161             :                                     MutableHandleObject protop) const override;
     162             :         bool setImmutablePrototype(JSContext* cx, HandleObject proxy,
     163             :                                    bool* succeeded) const override;
     164             : 
     165             :         bool preventExtensions(JSContext* cx, HandleObject proxy,
     166             :                                ObjectOpResult& result) const override;
     167             :         bool isExtensible(JSContext* cx, HandleObject proxy, bool* extensible) const override;
     168             :         bool has(JSContext* cx, HandleObject proxy, HandleId id, bool* bp) const override;
     169             :         bool get(JSContext* cx, HandleObject proxy, HandleValue receiver,
     170             :                  HandleId id, MutableHandleValue vp) const override;
     171             :         bool set(JSContext* cx, HandleObject proxy, HandleId id, HandleValue v,
     172             :                  HandleValue receiver, ObjectOpResult& result) const override;
     173             : 
     174             :         static const char family;
     175             :     };
     176             : 
     177             :   public:
     178             :     static const ProxyHandler proxyHandler;
     179             : };
     180             : 
     181             : typedef Rooted<ModuleNamespaceObject*> RootedModuleNamespaceObject;
     182             : typedef Handle<ModuleNamespaceObject*> HandleModuleNamespaceObject;
     183             : 
     184           0 : struct FunctionDeclaration
     185             : {
     186             :     FunctionDeclaration(HandleAtom name, HandleFunction fun);
     187             :     void trace(JSTracer* trc);
     188             : 
     189             :     HeapPtr<JSAtom*> name;
     190             :     HeapPtr<JSFunction*> fun;
     191             : };
     192             : 
     193             : using FunctionDeclarationVector = GCVector<FunctionDeclaration, 0, ZoneAllocPolicy>;
     194             : 
     195             : // Possible values for ModuleState are defined in SelfHostingDefines.h.
     196             : using ModuleState = int32_t;
     197             : 
     198             : class ModuleObject : public NativeObject
     199             : {
     200             :   public:
     201             :     enum
     202             :     {
     203             :         ScriptSlot = 0,
     204             :         InitialEnvironmentSlot,
     205             :         EnvironmentSlot,
     206             :         NamespaceSlot,
     207             :         StateSlot,
     208             :         HostDefinedSlot,
     209             :         RequestedModulesSlot,
     210             :         ImportEntriesSlot,
     211             :         LocalExportEntriesSlot,
     212             :         IndirectExportEntriesSlot,
     213             :         StarExportEntriesSlot,
     214             :         ImportBindingsSlot,
     215             :         NamespaceExportsSlot,
     216             :         NamespaceBindingsSlot,
     217             :         FunctionDeclarationsSlot,
     218             :         SlotCount
     219             :     };
     220             : 
     221             :     static_assert(EnvironmentSlot == MODULE_OBJECT_ENVIRONMENT_SLOT,
     222             :                   "EnvironmentSlot must match self-hosting define");
     223             : 
     224             :     static const Class class_;
     225             : 
     226             :     static bool isInstance(HandleValue value);
     227             : 
     228             :     static ModuleObject* create(JSContext* cx);
     229             :     void init(HandleScript script);
     230             :     void setInitialEnvironment(Handle<ModuleEnvironmentObject*> initialEnvironment);
     231             :     void initImportExportData(HandleArrayObject requestedModules,
     232             :                               HandleArrayObject importEntries,
     233             :                               HandleArrayObject localExportEntries,
     234             :                               HandleArrayObject indiretExportEntries,
     235             :                               HandleArrayObject starExportEntries);
     236             :     static bool Freeze(JSContext* cx, HandleModuleObject self);
     237             : #ifdef DEBUG
     238             :     static bool IsFrozen(JSContext* cx, HandleModuleObject self);
     239             : #endif
     240             :     void fixEnvironmentsAfterCompartmentMerge();
     241             : 
     242             :     JSScript* script() const;
     243             :     Scope* enclosingScope() const;
     244             :     ModuleEnvironmentObject& initialEnvironment() const;
     245             :     ModuleEnvironmentObject* environment() const;
     246             :     ModuleNamespaceObject* namespace_();
     247             :     ModuleState state() const;
     248             :     Value hostDefinedField() const;
     249             :     ArrayObject& requestedModules() const;
     250             :     ArrayObject& importEntries() const;
     251             :     ArrayObject& localExportEntries() const;
     252             :     ArrayObject& indirectExportEntries() const;
     253             :     ArrayObject& starExportEntries() const;
     254             :     IndirectBindingMap& importBindings();
     255             :     JSObject* namespaceExports();
     256             :     IndirectBindingMap* namespaceBindings();
     257             : 
     258             :     static bool DeclarationInstantiation(JSContext* cx, HandleModuleObject self);
     259             :     static bool Evaluation(JSContext* cx, HandleModuleObject self);
     260             : 
     261             :     void setHostDefinedField(const JS::Value& value);
     262             : 
     263             :     // For intrinsic_CreateModuleEnvironment.
     264             :     void createEnvironment();
     265             : 
     266             :     // For BytecodeEmitter.
     267             :     bool noteFunctionDeclaration(JSContext* cx, HandleAtom name, HandleFunction fun);
     268             : 
     269             :     // For intrinsic_InstantiateModuleFunctionDeclarations.
     270             :     static bool instantiateFunctionDeclarations(JSContext* cx, HandleModuleObject self);
     271             : 
     272             :     void setState(ModuleState newState);
     273             : 
     274             :     // For intrinsic_EvaluateModule.
     275             :     static bool evaluate(JSContext* cx, HandleModuleObject self, MutableHandleValue rval);
     276             : 
     277             :     // For intrinsic_NewModuleNamespace.
     278             :     static ModuleNamespaceObject* createNamespace(JSContext* cx, HandleModuleObject self,
     279             :                                                   HandleObject exports);
     280             : 
     281             :   private:
     282             :     static const ClassOps classOps_;
     283             : 
     284             :     static void trace(JSTracer* trc, JSObject* obj);
     285             :     static void finalize(js::FreeOp* fop, JSObject* obj);
     286             : 
     287             :     bool hasScript() const;
     288             :     bool hasImportBindings() const;
     289             :     FunctionDeclarationVector* functionDeclarations();
     290             : };
     291             : 
     292             : // Process a module's parse tree to collate the import and export data used when
     293             : // creating a ModuleObject.
     294           0 : class MOZ_STACK_CLASS ModuleBuilder
     295             : {
     296             :   public:
     297             :     explicit ModuleBuilder(JSContext* cx, HandleModuleObject module);
     298             : 
     299             :     bool processImport(frontend::ParseNode* pn);
     300             :     bool processExport(frontend::ParseNode* pn);
     301             :     bool processExportFrom(frontend::ParseNode* pn);
     302             : 
     303             :     bool hasExportedName(JSAtom* name) const;
     304             : 
     305             :     using ExportEntryVector = GCVector<ExportEntryObject*>;
     306           0 :     const ExportEntryVector& localExportEntries() const {
     307           0 :         return localExportEntries_;
     308             :     }
     309             : 
     310             :     bool buildTables();
     311             :     bool initModule();
     312             : 
     313             :   private:
     314             :     using AtomVector = GCVector<JSAtom*>;
     315             :     using RootedAtomVector = JS::Rooted<AtomVector>;
     316             :     using ImportEntryVector = GCVector<ImportEntryObject*>;
     317             :     using RootedImportEntryVector = JS::Rooted<ImportEntryVector>;
     318             :     using RootedExportEntryVector = JS::Rooted<ExportEntryVector>;
     319             : 
     320             :     JSContext* cx_;
     321             :     RootedModuleObject module_;
     322             :     RootedAtomVector requestedModules_;
     323             :     RootedAtomVector importedBoundNames_;
     324             :     RootedImportEntryVector importEntries_;
     325             :     RootedExportEntryVector exportEntries_;
     326             :     RootedExportEntryVector localExportEntries_;
     327             :     RootedExportEntryVector indirectExportEntries_;
     328             :     RootedExportEntryVector starExportEntries_;
     329             : 
     330             :     ImportEntryObject* importEntryFor(JSAtom* localName) const;
     331             : 
     332             :     bool appendExportEntry(HandleAtom exportName, HandleAtom localName);
     333             :     bool appendExportFromEntry(HandleAtom exportName, HandleAtom moduleRequest,
     334             :                                HandleAtom importName);
     335             : 
     336             :     bool maybeAppendRequestedModule(HandleAtom module);
     337             : 
     338             :     template <typename T>
     339             :     ArrayObject* createArray(const GCVector<T>& vector);
     340             : };
     341             : 
     342             : } // namespace js
     343             : 
     344             : template<>
     345             : inline bool
     346         992 : JSObject::is<js::ModuleNamespaceObject>() const
     347             : {
     348         992 :     return js::IsDerivedProxyObject(this, &js::ModuleNamespaceObject::proxyHandler);
     349             : }
     350             : 
     351             : #endif /* builtin_ModuleObject_h */

Generated by: LCOV version 1.13