OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
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 // FXJS_V8 is a layer that makes it easier to define native objects in V8, but | |
8 // has no knowledge of PDF-specific native objects. It could in theory be used | |
9 // 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_INCLUDE_FXJS_V8_H_ | |
15 #define FXJS_INCLUDE_FXJS_V8_H_ | |
16 | |
17 #include <v8-util.h> | |
18 #include <v8.h> | |
19 | |
20 #include <map> | |
21 #include <memory> | |
22 #include <vector> | |
23 | |
24 #include "core/fxcrt/fx_string.h" | |
25 #ifdef PDF_ENABLE_XFA | |
26 // Header for CFXJSE_RuntimeData. FXJS_V8 doesn't interpret this class, | |
27 // it is just passed along to XFA. | |
28 #include "fxjs/cfxjse_runtimedata.h" | |
29 #endif // PDF_ENABLE_XFA | |
30 | |
31 class CFXJS_Engine; | |
32 class CFXJS_ObjDefinition; | |
33 | |
34 // FXJS_V8 places no restrictions on this class; it merely passes it | |
35 // on to caller-provided methods. | |
36 class IJS_Context; // A description of the event that caused JS execution. | |
37 | |
38 enum FXJSOBJTYPE { | |
39 FXJSOBJTYPE_DYNAMIC = 0, // Created by native method and returned to JS. | |
40 FXJSOBJTYPE_STATIC, // Created by init and hung off of global object. | |
41 FXJSOBJTYPE_GLOBAL, // The global object itself (may only appear once). | |
42 }; | |
43 | |
44 struct FXJSErr { | |
45 const wchar_t* message; | |
46 const wchar_t* srcline; | |
47 unsigned linnum; | |
48 }; | |
49 | |
50 // Global weak map to save dynamic objects. | |
51 class V8TemplateMapTraits : public v8::StdMapTraits<void*, v8::Object> { | |
52 public: | |
53 typedef v8::GlobalValueMap<void*, v8::Object, V8TemplateMapTraits> MapType; | |
54 typedef void WeakCallbackDataType; | |
55 | |
56 static WeakCallbackDataType* WeakCallbackParameter( | |
57 MapType* map, | |
58 void* key, | |
59 const v8::Local<v8::Object>& value) { | |
60 return key; | |
61 } | |
62 static MapType* MapFromWeakCallbackInfo( | |
63 const v8::WeakCallbackInfo<WeakCallbackDataType>&); | |
64 | |
65 static void* KeyFromWeakCallbackInfo( | |
66 const v8::WeakCallbackInfo<WeakCallbackDataType>& data) { | |
67 return data.GetParameter(); | |
68 } | |
69 static const v8::PersistentContainerCallbackType kCallbackType = | |
70 v8::kWeakWithInternalFields; | |
71 static void DisposeWeak( | |
72 const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {} | |
73 static void OnWeakCallback( | |
74 const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {} | |
75 static void Dispose(v8::Isolate* isolate, | |
76 v8::Global<v8::Object> value, | |
77 void* key); | |
78 static void DisposeCallbackData(WeakCallbackDataType* callbackData) {} | |
79 }; | |
80 | |
81 class V8TemplateMap { | |
82 public: | |
83 typedef v8::GlobalValueMap<void*, v8::Object, V8TemplateMapTraits> MapType; | |
84 | |
85 explicit V8TemplateMap(v8::Isolate* isolate); | |
86 ~V8TemplateMap(); | |
87 | |
88 void set(void* key, v8::Local<v8::Object> handle); | |
89 | |
90 friend class V8TemplateMapTraits; | |
91 | |
92 private: | |
93 MapType m_map; | |
94 }; | |
95 | |
96 class FXJS_PerIsolateData { | |
97 public: | |
98 ~FXJS_PerIsolateData(); | |
99 | |
100 static void SetUp(v8::Isolate* pIsolate); | |
101 static FXJS_PerIsolateData* Get(v8::Isolate* pIsolate); | |
102 | |
103 std::vector<std::unique_ptr<CFXJS_ObjDefinition>> m_ObjectDefnArray; | |
104 #ifdef PDF_ENABLE_XFA | |
105 std::unique_ptr<CFXJSE_RuntimeData> m_pFXJSERuntimeData; | |
106 #endif // PDF_ENABLE_XFA | |
107 std::unique_ptr<V8TemplateMap> m_pDynamicObjsMap; | |
108 | |
109 protected: | |
110 explicit FXJS_PerIsolateData(v8::Isolate* pIsolate); | |
111 }; | |
112 | |
113 class FXJS_ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { | |
114 void* Allocate(size_t length) override; | |
115 void* AllocateUninitialized(size_t length) override; | |
116 void Free(void* data, size_t length) override; | |
117 }; | |
118 | |
119 void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate); | |
120 void FXJS_Release(); | |
121 | |
122 // Gets the global isolate set by FXJS_Initialize(), or makes a new one each | |
123 // time if there is no such isolate. Returns true if a new isolate had to be | |
124 // created. | |
125 bool FXJS_GetIsolate(v8::Isolate** pResultIsolate); | |
126 | |
127 // Get the global isolate's ref count. | |
128 size_t FXJS_GlobalIsolateRefCount(); | |
129 | |
130 class CFXJS_Engine { | |
131 public: | |
132 explicit CFXJS_Engine(v8::Isolate* pIsolate); | |
133 ~CFXJS_Engine(); | |
134 | |
135 using Constructor = void (*)(CFXJS_Engine* pEngine, | |
136 v8::Local<v8::Object> obj); | |
137 using Destructor = void (*)(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj); | |
138 | |
139 static CFXJS_Engine* CurrentEngineFromIsolate(v8::Isolate* pIsolate); | |
140 static int GetObjDefnID(v8::Local<v8::Object> pObj); | |
141 | |
142 #ifdef PDF_ENABLE_XFA | |
143 // Called as part of FXJS_InitializeEngine, exposed so PDF can make its | |
144 // own contexts compatible with XFA or vice versa. | |
145 static void SetForV8Context(v8::Local<v8::Context> v8Context, | |
146 CFXJS_Engine* pEngine); | |
147 #endif // PDF_ENABLE_XFA | |
148 | |
149 v8::Isolate* GetIsolate() const { return m_isolate; } | |
150 | |
151 // Always returns a valid, newly-created objDefnID. | |
152 int DefineObj(const wchar_t* sObjName, | |
153 FXJSOBJTYPE eObjType, | |
154 Constructor pConstructor, | |
155 Destructor pDestructor); | |
156 | |
157 void DefineObjMethod(int nObjDefnID, | |
158 const wchar_t* sMethodName, | |
159 v8::FunctionCallback pMethodCall); | |
160 void DefineObjProperty(int nObjDefnID, | |
161 const wchar_t* sPropName, | |
162 v8::AccessorGetterCallback pPropGet, | |
163 v8::AccessorSetterCallback pPropPut); | |
164 void DefineObjAllProperties(int nObjDefnID, | |
165 v8::NamedPropertyQueryCallback pPropQurey, | |
166 v8::NamedPropertyGetterCallback pPropGet, | |
167 v8::NamedPropertySetterCallback pPropPut, | |
168 v8::NamedPropertyDeleterCallback pPropDel); | |
169 void DefineObjConst(int nObjDefnID, | |
170 const wchar_t* sConstName, | |
171 v8::Local<v8::Value> pDefault); | |
172 void DefineGlobalMethod(const wchar_t* sMethodName, | |
173 v8::FunctionCallback pMethodCall); | |
174 void DefineGlobalConst(const wchar_t* sConstName, | |
175 v8::FunctionCallback pConstGetter); | |
176 | |
177 // Called after FXJS_Define* calls made. | |
178 void InitializeEngine(); | |
179 void ReleaseEngine(); | |
180 | |
181 // Called after FXJS_InitializeEngine call made. | |
182 int Execute(const CFX_WideString& script, FXJSErr* perror); | |
183 | |
184 v8::Local<v8::Context> NewLocalContext(); | |
185 v8::Local<v8::Context> GetPersistentContext(); | |
186 | |
187 v8::Local<v8::Value> NewNull(); | |
188 v8::Local<v8::Array> NewArray(); | |
189 v8::Local<v8::Value> NewNumber(int number); | |
190 v8::Local<v8::Value> NewNumber(double number); | |
191 v8::Local<v8::Value> NewNumber(float number); | |
192 v8::Local<v8::Value> NewBoolean(bool b); | |
193 v8::Local<v8::Value> NewString(const wchar_t* str); | |
194 v8::Local<v8::Date> NewDate(double d); | |
195 v8::Local<v8::Object> NewFxDynamicObj(int nObjDefnID, bool bStatic = false); | |
196 | |
197 v8::Local<v8::Object> GetThisObj(); | |
198 int ToInt32(v8::Local<v8::Value> pValue); | |
199 bool ToBoolean(v8::Local<v8::Value> pValue); | |
200 double ToNumber(v8::Local<v8::Value> pValue); | |
201 CFX_WideString ToString(v8::Local<v8::Value> pValue); | |
202 v8::Local<v8::Object> ToObject(v8::Local<v8::Value> pValue); | |
203 v8::Local<v8::Array> ToArray(v8::Local<v8::Value> pValue); | |
204 | |
205 unsigned GetArrayLength(v8::Local<v8::Array> pArray); | |
206 v8::Local<v8::Value> GetArrayElement(v8::Local<v8::Array> pArray, | |
207 unsigned index); | |
208 unsigned PutArrayElement(v8::Local<v8::Array> pArray, | |
209 unsigned index, | |
210 v8::Local<v8::Value> pValue); | |
211 | |
212 std::vector<CFX_WideString> GetObjectPropertyNames( | |
213 v8::Local<v8::Object> pObj); | |
214 v8::Local<v8::Value> GetObjectProperty(v8::Local<v8::Object> pObj, | |
215 const CFX_WideString& PropertyName); | |
216 | |
217 void PutObjectString(v8::Local<v8::Object> pObj, | |
218 const CFX_WideString& wsPropertyName, | |
219 const CFX_WideString& wsValue); | |
220 void PutObjectNumber(v8::Local<v8::Object> pObj, | |
221 const CFX_WideString& PropertyName, | |
222 int nValue); | |
223 void PutObjectNumber(v8::Local<v8::Object> pObj, | |
224 const CFX_WideString& PropertyName, | |
225 float fValue); | |
226 void PutObjectNumber(v8::Local<v8::Object> pObj, | |
227 const CFX_WideString& PropertyName, | |
228 double dValue); | |
229 void PutObjectBoolean(v8::Local<v8::Object> pObj, | |
230 const CFX_WideString& PropertyName, | |
231 bool bValue); | |
232 void PutObjectObject(v8::Local<v8::Object> pObj, | |
233 const CFX_WideString& PropertyName, | |
234 v8::Local<v8::Object> pPut); | |
235 void PutObjectNull(v8::Local<v8::Object> pObj, | |
236 const CFX_WideString& PropertyName); | |
237 | |
238 // Native object binding. | |
239 void SetObjectPrivate(v8::Local<v8::Object> pObj, void* p); | |
240 void* GetObjectPrivate(v8::Local<v8::Object> pObj); | |
241 static void FreeObjectPrivate(void* p); | |
242 static void FreeObjectPrivate(v8::Local<v8::Object> pObj); | |
243 | |
244 void SetConstArray(const CFX_WideString& name, v8::Local<v8::Array> array); | |
245 v8::Local<v8::Array> GetConstArray(const CFX_WideString& name); | |
246 | |
247 v8::Local<v8::String> WSToJSString(const CFX_WideString& wsPropertyName); | |
248 void Error(const CFX_WideString& message); | |
249 | |
250 protected: | |
251 CFXJS_Engine(); | |
252 | |
253 void SetIsolate(v8::Isolate* pIsolate) { m_isolate = pIsolate; } | |
254 | |
255 private: | |
256 v8::Isolate* m_isolate; | |
257 v8::Global<v8::Context> m_V8PersistentContext; | |
258 std::vector<v8::Global<v8::Object>*> m_StaticObjects; | |
259 std::map<CFX_WideString, v8::Global<v8::Array>> m_ConstArrays; | |
260 }; | |
261 | |
262 #endif // FXJS_INCLUDE_FXJS_V8_H_ | |
OLD | NEW |