• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2014 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 // CFXJS_ENGINE is a layer that makes it easier to define native objects in V8,
8 // but has no knowledge of PDF-specific native objects. It could in theory be
9 // used to implement other sets of native objects.
10 
11 // PDFium code should include this file rather than including V8 headers
12 // directly.
13 
14 #ifndef FXJS_CFXJS_ENGINE_H_
15 #define FXJS_CFXJS_ENGINE_H_
16 
17 #include <functional>
18 #include <map>
19 #include <memory>
20 #include <utility>
21 #include <vector>
22 
23 #include "core/fxcrt/widestring.h"
24 #include "fxjs/cfx_v8.h"
25 #include "fxjs/ijs_runtime.h"
26 #include "v8/include/v8-forward.h"
27 #include "v8/include/v8-function-callback.h"
28 #include "v8/include/v8-persistent-handle.h"
29 #include "v8/include/v8-template.h"
30 
31 class CFXJS_ObjDefinition;
32 class CJS_Object;
33 class V8TemplateMap;
34 
35 enum FXJSOBJTYPE {
36   FXJSOBJTYPE_DYNAMIC = 0,  // Created by native method and returned to JS.
37   FXJSOBJTYPE_STATIC,       // Created by init and hung off of global object.
38   FXJSOBJTYPE_GLOBAL,       // The global object itself (may only appear once).
39 };
40 
41 class FXJS_PerIsolateData {
42  public:
43   // Hook for XFA's data, when present.
44   class ExtensionIface {
45    public:
46     virtual ~ExtensionIface() = default;
47   };
48 
49   ~FXJS_PerIsolateData();
50 
51   static void SetUp(v8::Isolate* pIsolate);
52   static FXJS_PerIsolateData* Get(v8::Isolate* pIsolate);
53 
54   uint32_t CurrentMaxObjDefinitionID() const;
55   CFXJS_ObjDefinition* ObjDefinitionForID(uint32_t id) const;
56   uint32_t AssignIDForObjDefinition(std::unique_ptr<CFXJS_ObjDefinition> pDefn);
GetDynamicObjsMap()57   V8TemplateMap* GetDynamicObjsMap() { return m_pDynamicObjsMap.get(); }
GetExtension()58   ExtensionIface* GetExtension() { return m_pExtension.get(); }
SetExtension(std::unique_ptr<ExtensionIface> extension)59   void SetExtension(std::unique_ptr<ExtensionIface> extension) {
60     m_pExtension = std::move(extension);
61   }
62 
63  private:
64   explicit FXJS_PerIsolateData(v8::Isolate* pIsolate);
65 
66   const wchar_t* const m_Tag;  // Raw, always a literal.
67   std::vector<std::unique_ptr<CFXJS_ObjDefinition>> m_ObjectDefnArray;
68   std::unique_ptr<V8TemplateMap> m_pDynamicObjsMap;
69   std::unique_ptr<ExtensionIface> m_pExtension;
70 };
71 
72 void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate);
73 void FXJS_Release();
74 
75 // Gets the global isolate set by FXJS_Initialize(), or makes a new one each
76 // time if there is no such isolate. Returns true if a new isolate had to be
77 // created.
78 bool FXJS_GetIsolate(v8::Isolate** pResultIsolate);
79 
80 // Get the global isolate's ref count.
81 size_t FXJS_GlobalIsolateRefCount();
82 
83 class CFXJS_Engine : public CFX_V8 {
84  public:
85   explicit CFXJS_Engine(v8::Isolate* pIsolate);
86   ~CFXJS_Engine() override;
87 
88   using Constructor = std::function<void(CFXJS_Engine* pEngine,
89                                          v8::Local<v8::Object> obj,
90                                          v8::Local<v8::Object> proxy)>;
91   using Destructor = std::function<void(v8::Local<v8::Object> obj)>;
92 
93   static uint32_t GetObjDefnID(v8::Local<v8::Object> pObj);
94   static CJS_Object* GetObjectPrivate(v8::Isolate* pIsolate,
95                                       v8::Local<v8::Object> pObj);
96   static void SetObjectPrivate(v8::Local<v8::Object> pObj,
97                                std::unique_ptr<CJS_Object> p);
98   static void FreeObjectPrivate(v8::Local<v8::Object> pObj);
99 
100   // Always returns a valid (i.e. non-zero), newly-created objDefnID.
101   uint32_t DefineObj(const char* sObjName,
102                      FXJSOBJTYPE eObjType,
103                      Constructor pConstructor,
104                      Destructor pDestructor);
105 
106   void DefineObjMethod(uint32_t nObjDefnID,
107                        const char* sMethodName,
108                        v8::FunctionCallback pMethodCall);
109   void DefineObjProperty(uint32_t nObjDefnID,
110                          const char* sPropName,
111                          v8::AccessorGetterCallback pPropGet,
112                          v8::AccessorSetterCallback pPropPut);
113   void DefineObjAllProperties(
114       uint32_t nObjDefnID,
115       v8::GenericNamedPropertyQueryCallback pPropQurey,
116       v8::GenericNamedPropertyGetterCallback pPropGet,
117       v8::GenericNamedPropertySetterCallback pPropPut,
118       v8::GenericNamedPropertyDeleterCallback pPropDel,
119       v8::GenericNamedPropertyEnumeratorCallback pPropEnum);
120   void DefineObjConst(uint32_t nObjDefnID,
121                       const char* sConstName,
122                       v8::Local<v8::Value> pDefault);
123   void DefineGlobalMethod(const char* sMethodName,
124                           v8::FunctionCallback pMethodCall);
125   void DefineGlobalConst(const wchar_t* sConstName,
126                          v8::FunctionCallback pConstGetter);
127 
128   // Called after FXJS_Define* calls made.
129   void InitializeEngine();
130   void ReleaseEngine();
131 
132   // Called after FXJS_InitializeEngine call made.
133   absl::optional<IJS_Runtime::JS_Error> Execute(const WideString& script);
134 
135   v8::Local<v8::Object> GetThisObj();
136   v8::Local<v8::Object> NewFXJSBoundObject(uint32_t nObjDefnID,
137                                            FXJSOBJTYPE type);
138   void Error(const WideString& message);
139 
140   v8::Local<v8::Context> GetV8Context();
141 
142   v8::Local<v8::Array> GetConstArray(const WideString& name);
143   void SetConstArray(const WideString& name, v8::Local<v8::Array> array);
144 
145  protected:
146   CFXJS_Engine();
147 
148  private:
149   v8::Global<v8::Context> m_V8Context;
150   std::vector<v8::Global<v8::Object>> m_StaticObjects;
151   std::map<WideString, v8::Global<v8::Array>> m_ConstArrays;
152 };
153 
154 #endif  // FXJS_CFXJS_ENGINE_H_
155