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