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 FPDFSDK_INCLUDE_JSAPI_FXJS_V8_H_
15 #define FPDFSDK_INCLUDE_JSAPI_FXJS_V8_H_
16 
17 #include <v8.h>
18 
19 #include <vector>
20 
21 #include "core/include/fxcrt/fx_string.h"
22 
23 class CFXJS_ObjDefinition;
24 
25 // FXJS_V8 places no restrictions on these two classes; it merely passes them
26 // on to caller-provided methods.
27 class IJS_Context;  // A description of the event that caused JS execution.
28 class IJS_Runtime;  // A native runtime, typically owns the v8::Context.
29 
30 #ifdef PDF_ENABLE_XFA
31 // FXJS_V8 places no interpreation on this calass; it merely passes it
32 // along to XFA.
33 class CFXJSE_RuntimeData;
34 #endif  // PDF_ENABLE_XFA
35 
36 enum FXJSOBJTYPE {
37   FXJSOBJTYPE_DYNAMIC = 0,  // Created by native method and returned to JS.
38   FXJSOBJTYPE_STATIC,       // Created by init and hung off of global object.
39   FXJSOBJTYPE_GLOBAL,       // The global object itself (may only appear once).
40 };
41 
42 struct FXJSErr {
43   const wchar_t* message;
44   const wchar_t* srcline;
45   unsigned linnum;
46 };
47 
48 class FXJS_PerIsolateData {
49  public:
50   static void SetUp(v8::Isolate* pIsolate);
51   static FXJS_PerIsolateData* Get(v8::Isolate* pIsolate);
52 
53   std::vector<CFXJS_ObjDefinition*> m_ObjectDefnArray;
54 #ifdef PDF_ENABLE_XFA
55   CFXJSE_RuntimeData* m_pFXJSERuntimeData;
56 #endif  // PDF_ENABLE_XFA
57 
58  protected:
59 #ifndef PDF_ENABLE_XFA
FXJS_PerIsolateData()60   FXJS_PerIsolateData() {}
61 #else  // PDF_ENABLE_XFA
62   FXJS_PerIsolateData() : m_pFXJSERuntimeData(nullptr) {}
63 #endif  // PDF_ENABLE_XFA
64 };
65 
66 extern const wchar_t kFXJSValueNameString[];
67 extern const wchar_t kFXJSValueNameNumber[];
68 extern const wchar_t kFXJSValueNameBoolean[];
69 extern const wchar_t kFXJSValueNameDate[];
70 extern const wchar_t kFXJSValueNameObject[];
71 extern const wchar_t kFXJSValueNameFxobj[];
72 extern const wchar_t kFXJSValueNameNull[];
73 extern const wchar_t kFXJSValueNameUndefined[];
74 
75 class FXJS_ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
76   void* Allocate(size_t length) override;
77   void* AllocateUninitialized(size_t length) override;
78   void Free(void* data, size_t length) override;
79 };
80 
81 using FXJS_CONSTRUCTOR = void (*)(IJS_Runtime* cc, v8::Local<v8::Object> obj);
82 using FXJS_DESTRUCTOR = void (*)(v8::Local<v8::Object> obj);
83 
84 // Call before making FXJS_PrepareIsolate call.
85 void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate);
86 void FXJS_Release();
87 
88 // Gets the global isolate set by FXJS_Initialize(), or makes a new one each
89 // time if there is no such isolate. Returns true if a new isolate had to be
90 // created.
91 bool FXJS_GetIsolate(v8::Isolate** pResultIsolate);
92 
93 // Get the global isolate's ref count.
94 size_t FXJS_GlobalIsolateRefCount();
95 
96 // Call before making FXJS_Define* calls. Resources allocated here are cleared
97 // as part of FXJS_ReleaseRuntime().
98 void FXJS_PrepareIsolate(v8::Isolate* pIsolate);
99 
100 // Call before making JS_Define* calls. Resources allocated here are cleared
101 // as part of JS_ReleaseRuntime().
102 void JS_PrepareIsolate(v8::Isolate* pIsolate);
103 
104 // Always returns a valid, newly-created objDefnID.
105 int FXJS_DefineObj(v8::Isolate* pIsolate,
106                    const wchar_t* sObjName,
107                    FXJSOBJTYPE eObjType,
108                    FXJS_CONSTRUCTOR pConstructor,
109                    FXJS_DESTRUCTOR pDestructor);
110 
111 void FXJS_DefineObjMethod(v8::Isolate* pIsolate,
112                           int nObjDefnID,
113                           const wchar_t* sMethodName,
114                           v8::FunctionCallback pMethodCall);
115 void FXJS_DefineObjProperty(v8::Isolate* pIsolate,
116                             int nObjDefnID,
117                             const wchar_t* sPropName,
118                             v8::AccessorGetterCallback pPropGet,
119                             v8::AccessorSetterCallback pPropPut);
120 void FXJS_DefineObjAllProperties(v8::Isolate* pIsolate,
121                                  int nObjDefnID,
122                                  v8::NamedPropertyQueryCallback pPropQurey,
123                                  v8::NamedPropertyGetterCallback pPropGet,
124                                  v8::NamedPropertySetterCallback pPropPut,
125                                  v8::NamedPropertyDeleterCallback pPropDel);
126 void FXJS_DefineObjConst(v8::Isolate* pIsolate,
127                          int nObjDefnID,
128                          const wchar_t* sConstName,
129                          v8::Local<v8::Value> pDefault);
130 void FXJS_DefineGlobalMethod(v8::Isolate* pIsolate,
131                              const wchar_t* sMethodName,
132                              v8::FunctionCallback pMethodCall);
133 void FXJS_DefineGlobalConst(v8::Isolate* pIsolate,
134                             const wchar_t* sConstName,
135                             v8::Local<v8::Value> pDefault);
136 
137 // Called after FXJS_Define* calls made.
138 void FXJS_InitializeRuntime(
139     v8::Isolate* pIsolate,
140     IJS_Runtime* pIRuntime,
141     v8::Global<v8::Context>* pV8PersistentContext,
142     std::vector<v8::Global<v8::Object>*>* pStaticObjects);
143 void FXJS_ReleaseRuntime(v8::Isolate* pIsolate,
144                          v8::Global<v8::Context>* pV8PersistentContext,
145                          std::vector<v8::Global<v8::Object>*>* pStaticObjects);
146 IJS_Runtime* FXJS_GetRuntimeFromIsolate(v8::Isolate* pIsolate);
147 
148 #ifdef PDF_ENABLE_XFA
149 // Called as part of FXJS_InitializeRuntime, exposed so PDF can make its
150 // own contexts compatible with XFA or vice versa.
151 void FXJS_SetRuntimeForV8Context(v8::Local<v8::Context> v8Context,
152                                  IJS_Runtime* pIRuntime);
153 #endif  // PDF_ENABLE_XFA
154 
155 // Called after FXJS_InitializeRuntime call made.
156 int FXJS_Execute(v8::Isolate* pIsolate,
157                  IJS_Context* pJSContext,
158                  const wchar_t* script,
159                  FXJSErr* perror);
160 
161 v8::Local<v8::Object> FXJS_NewFxDynamicObj(v8::Isolate* pIsolate,
162                                            IJS_Runtime* pJSContext,
163                                            int nObjDefnID);
164 v8::Local<v8::Object> FXJS_GetThisObj(v8::Isolate* pIsolate);
165 int FXJS_GetObjDefnID(v8::Local<v8::Object> pObj);
166 const wchar_t* FXJS_GetTypeof(v8::Local<v8::Value> pObj);
167 
168 void FXJS_SetPrivate(v8::Isolate* pIsolate,
169                      v8::Local<v8::Object> pObj,
170                      void* p);
171 void* FXJS_GetPrivate(v8::Isolate* pIsolate, v8::Local<v8::Object> pObj);
172 void FXJS_FreePrivate(void* p);
173 void FXJS_FreePrivate(v8::Local<v8::Object> pObj);
174 
175 void FXJS_Error(v8::Isolate* isolate, const CFX_WideString& message);
176 v8::Local<v8::String> FXJS_WSToJSString(v8::Isolate* pIsolate,
177                                         const wchar_t* PropertyName,
178                                         int Len = -1);
179 
180 v8::Local<v8::Value> FXJS_GetObjectElement(v8::Isolate* pIsolate,
181                                            v8::Local<v8::Object> pObj,
182                                            const wchar_t* PropertyName);
183 v8::Local<v8::Array> FXJS_GetObjectElementNames(v8::Isolate* pIsolate,
184                                                 v8::Local<v8::Object> pObj);
185 
186 v8::Local<v8::Value> FXJS_GetArrayElement(v8::Isolate* pIsolate,
187                                           v8::Local<v8::Array> pArray,
188                                           unsigned index);
189 unsigned FXJS_GetArrayLength(v8::Local<v8::Array> pArray);
190 
191 void FXJS_PutObjectString(v8::Isolate* pIsolate,
192                           v8::Local<v8::Object> pObj,
193                           const wchar_t* PropertyName,
194                           const wchar_t* sValue);
195 void FXJS_PutObjectNumber(v8::Isolate* pIsolate,
196                           v8::Local<v8::Object> pObj,
197                           const wchar_t* PropertyName,
198                           int nValue);
199 void FXJS_PutObjectNumber(v8::Isolate* pIsolate,
200                           v8::Local<v8::Object> pObj,
201                           const wchar_t* PropertyName,
202                           float fValue);
203 void FXJS_PutObjectNumber(v8::Isolate* pIsolate,
204                           v8::Local<v8::Object> pObj,
205                           const wchar_t* PropertyName,
206                           double dValue);
207 void FXJS_PutObjectBoolean(v8::Isolate* pIsolate,
208                            v8::Local<v8::Object> pObj,
209                            const wchar_t* PropertyName,
210                            bool bValue);
211 void FXJS_PutObjectObject(v8::Isolate* pIsolate,
212                           v8::Local<v8::Object> pObj,
213                           const wchar_t* PropertyName,
214                           v8::Local<v8::Object> pPut);
215 void FXJS_PutObjectNull(v8::Isolate* pIsolate,
216                         v8::Local<v8::Object> pObj,
217                         const wchar_t* PropertyName);
218 unsigned FXJS_PutArrayElement(v8::Isolate* pIsolate,
219                               v8::Local<v8::Array> pArray,
220                               unsigned index,
221                               v8::Local<v8::Value> pValue);
222 
223 v8::Local<v8::Array> FXJS_NewArray(v8::Isolate* pIsolate);
224 v8::Local<v8::Value> FXJS_NewNumber(v8::Isolate* pIsolate, int number);
225 v8::Local<v8::Value> FXJS_NewNumber(v8::Isolate* pIsolate, double number);
226 v8::Local<v8::Value> FXJS_NewNumber(v8::Isolate* pIsolate, float number);
227 v8::Local<v8::Value> FXJS_NewBoolean(v8::Isolate* pIsolate, bool b);
228 v8::Local<v8::Value> FXJS_NewObject(v8::Isolate* pIsolate,
229                                     v8::Local<v8::Object> pObj);
230 v8::Local<v8::Value> FXJS_NewObject2(v8::Isolate* pIsolate,
231                                      v8::Local<v8::Array> pObj);
232 v8::Local<v8::Value> FXJS_NewString(v8::Isolate* pIsolate,
233                                     const wchar_t* string);
234 v8::Local<v8::Value> FXJS_NewNull();
235 v8::Local<v8::Value> FXJS_NewDate(v8::Isolate* pIsolate, double d);
236 
237 int FXJS_ToInt32(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue);
238 bool FXJS_ToBoolean(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue);
239 double FXJS_ToNumber(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue);
240 v8::Local<v8::Object> FXJS_ToObject(v8::Isolate* pIsolate,
241                                     v8::Local<v8::Value> pValue);
242 CFX_WideString FXJS_ToString(v8::Isolate* pIsolate,
243                              v8::Local<v8::Value> pValue);
244 v8::Local<v8::Array> FXJS_ToArray(v8::Isolate* pIsolate,
245                                   v8::Local<v8::Value> pValue);
246 void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom);
247 
248 #endif  // FPDFSDK_INCLUDE_JSAPI_FXJS_V8_H_
249