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 #ifndef FXJS_XFA_CFXJSE_ENGINE_H_ 8*3ac0a46fSAndroid Build Coastguard Worker #define FXJS_XFA_CFXJSE_ENGINE_H_ 9*3ac0a46fSAndroid Build Coastguard Worker 10*3ac0a46fSAndroid Build Coastguard Worker #include <map> 11*3ac0a46fSAndroid Build Coastguard Worker #include <memory> 12*3ac0a46fSAndroid Build Coastguard Worker #include <type_traits> 13*3ac0a46fSAndroid Build Coastguard Worker #include <vector> 14*3ac0a46fSAndroid Build Coastguard Worker 15*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/mask.h" 16*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/unowned_ptr.h" 17*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/cfx_v8.h" 18*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/cppgc/persistent.h" 19*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-forward.h" 20*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-persistent-handle.h" 21*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/cxfa_eventparam.h" 22*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_document.h" 23*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_script.h" 24*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/xfa_basic_data.h" 25*3ac0a46fSAndroid Build Coastguard Worker 26*3ac0a46fSAndroid Build Coastguard Worker class CFXJSE_Class; 27*3ac0a46fSAndroid Build Coastguard Worker class CFXJSE_Context; 28*3ac0a46fSAndroid Build Coastguard Worker class CFXJSE_FormCalcContext; 29*3ac0a46fSAndroid Build Coastguard Worker class CFXJSE_HostObject; 30*3ac0a46fSAndroid Build Coastguard Worker class CFXJSE_NodeHelper; 31*3ac0a46fSAndroid Build Coastguard Worker class CFXJSE_ResolveProcessor; 32*3ac0a46fSAndroid Build Coastguard Worker class CFXJSE_Value; 33*3ac0a46fSAndroid Build Coastguard Worker class CJS_Runtime; 34*3ac0a46fSAndroid Build Coastguard Worker 35*3ac0a46fSAndroid Build Coastguard Worker enum class XFA_ResolveFlag : uint16_t { 36*3ac0a46fSAndroid Build Coastguard Worker kChildren = 1 << 0, 37*3ac0a46fSAndroid Build Coastguard Worker kTagName = 1 << 1, 38*3ac0a46fSAndroid Build Coastguard Worker kAttributes = 1 << 2, 39*3ac0a46fSAndroid Build Coastguard Worker kProperties = 1 << 3, 40*3ac0a46fSAndroid Build Coastguard Worker kSiblings = 1 << 5, 41*3ac0a46fSAndroid Build Coastguard Worker kParent = 1 << 6, 42*3ac0a46fSAndroid Build Coastguard Worker kAnyChild = 1 << 7, 43*3ac0a46fSAndroid Build Coastguard Worker kALL = 1 << 8, 44*3ac0a46fSAndroid Build Coastguard Worker kCreateNode = 1 << 10, 45*3ac0a46fSAndroid Build Coastguard Worker kBind = 1 << 11, 46*3ac0a46fSAndroid Build Coastguard Worker kBindNew = 1 << 12, 47*3ac0a46fSAndroid Build Coastguard Worker }; 48*3ac0a46fSAndroid Build Coastguard Worker 49*3ac0a46fSAndroid Build Coastguard Worker class CFXJSE_Engine final : public CFX_V8 { 50*3ac0a46fSAndroid Build Coastguard Worker public: 51*3ac0a46fSAndroid Build Coastguard Worker class ResolveResult { 52*3ac0a46fSAndroid Build Coastguard Worker CPPGC_STACK_ALLOCATED(); // Allow raw/unowned pointers. 53*3ac0a46fSAndroid Build Coastguard Worker 54*3ac0a46fSAndroid Build Coastguard Worker public: 55*3ac0a46fSAndroid Build Coastguard Worker enum class Type { 56*3ac0a46fSAndroid Build Coastguard Worker kNodes = 0, 57*3ac0a46fSAndroid Build Coastguard Worker kAttribute, 58*3ac0a46fSAndroid Build Coastguard Worker kCreateNodeOne, 59*3ac0a46fSAndroid Build Coastguard Worker kCreateNodeAll, 60*3ac0a46fSAndroid Build Coastguard Worker kCreateNodeMidAll, 61*3ac0a46fSAndroid Build Coastguard Worker kExistNodes, 62*3ac0a46fSAndroid Build Coastguard Worker }; 63*3ac0a46fSAndroid Build Coastguard Worker 64*3ac0a46fSAndroid Build Coastguard Worker ResolveResult(); 65*3ac0a46fSAndroid Build Coastguard Worker ResolveResult(const ResolveResult& that); 66*3ac0a46fSAndroid Build Coastguard Worker ResolveResult& operator=(const ResolveResult& that); 67*3ac0a46fSAndroid Build Coastguard Worker ~ResolveResult(); 68*3ac0a46fSAndroid Build Coastguard Worker 69*3ac0a46fSAndroid Build Coastguard Worker Type type = Type::kNodes; 70*3ac0a46fSAndroid Build Coastguard Worker XFA_SCRIPTATTRIBUTEINFO script_attribute = {}; 71*3ac0a46fSAndroid Build Coastguard Worker 72*3ac0a46fSAndroid Build Coastguard Worker // Vector of Member would be correct for stack-based vectors, if 73*3ac0a46fSAndroid Build Coastguard Worker // STL worked with cppgc. 74*3ac0a46fSAndroid Build Coastguard Worker std::vector<cppgc::Member<CXFA_Object>> objects; 75*3ac0a46fSAndroid Build Coastguard Worker }; 76*3ac0a46fSAndroid Build Coastguard Worker 77*3ac0a46fSAndroid Build Coastguard Worker static CXFA_Object* ToObject(const v8::FunctionCallbackInfo<v8::Value>& info); 78*3ac0a46fSAndroid Build Coastguard Worker static CXFA_Object* ToObject(v8::Isolate* pIsolate, 79*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value> value); 80*3ac0a46fSAndroid Build Coastguard Worker static CXFA_Object* ToObject(v8::Isolate* pIsolate, CFXJSE_Value* pValue); 81*3ac0a46fSAndroid Build Coastguard Worker static CXFA_Object* ToObject(CFXJSE_HostObject* pHostObj); 82*3ac0a46fSAndroid Build Coastguard Worker static v8::Local<v8::Value> GlobalPropertyGetter( 83*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate* pIsolate, 84*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> pObject, 85*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szPropName); 86*3ac0a46fSAndroid Build Coastguard Worker static void GlobalPropertySetter(v8::Isolate* pIsolate, 87*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> pObject, 88*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szPropName, 89*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value> pValue); 90*3ac0a46fSAndroid Build Coastguard Worker static v8::Local<v8::Value> NormalPropertyGetter( 91*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate* pIsolate, 92*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> pObject, 93*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szPropName); 94*3ac0a46fSAndroid Build Coastguard Worker static void NormalPropertySetter(v8::Isolate* pIsolate, 95*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> pObject, 96*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szPropName, 97*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value> pValue); 98*3ac0a46fSAndroid Build Coastguard Worker static CJS_Result NormalMethodCall( 99*3ac0a46fSAndroid Build Coastguard Worker const v8::FunctionCallbackInfo<v8::Value>& info, 100*3ac0a46fSAndroid Build Coastguard Worker const WideString& functionName); 101*3ac0a46fSAndroid Build Coastguard Worker static FXJSE_ClassPropType NormalPropTypeGetter(v8::Isolate* pIsolate, 102*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> pObject, 103*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szPropName, 104*3ac0a46fSAndroid Build Coastguard Worker bool bQueryIn); 105*3ac0a46fSAndroid Build Coastguard Worker static FXJSE_ClassPropType GlobalPropTypeGetter(v8::Isolate* pIsolate, 106*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> pObject, 107*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szPropName, 108*3ac0a46fSAndroid Build Coastguard Worker bool bQueryIn); 109*3ac0a46fSAndroid Build Coastguard Worker 110*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Engine(CXFA_Document* pDocument, CJS_Runtime* fxjs_runtime); 111*3ac0a46fSAndroid Build Coastguard Worker ~CFXJSE_Engine() override; 112*3ac0a46fSAndroid Build Coastguard Worker 113*3ac0a46fSAndroid Build Coastguard Worker class EventParamScope { 114*3ac0a46fSAndroid Build Coastguard Worker CPPGC_STACK_ALLOCATED(); 115*3ac0a46fSAndroid Build Coastguard Worker 116*3ac0a46fSAndroid Build Coastguard Worker public: 117*3ac0a46fSAndroid Build Coastguard Worker EventParamScope(CFXJSE_Engine* pEngine, 118*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pTarget, 119*3ac0a46fSAndroid Build Coastguard Worker CXFA_EventParam* pEventParam); 120*3ac0a46fSAndroid Build Coastguard Worker ~EventParamScope(); 121*3ac0a46fSAndroid Build Coastguard Worker 122*3ac0a46fSAndroid Build Coastguard Worker private: 123*3ac0a46fSAndroid Build Coastguard Worker UnownedPtr<CFXJSE_Engine> m_pEngine; 124*3ac0a46fSAndroid Build Coastguard Worker UnownedPtr<CXFA_Node> m_pPrevTarget; 125*3ac0a46fSAndroid Build Coastguard Worker UnownedPtr<CXFA_EventParam> m_pPrevEventParam; 126*3ac0a46fSAndroid Build Coastguard Worker }; 127*3ac0a46fSAndroid Build Coastguard Worker friend class EventParamScope; 128*3ac0a46fSAndroid Build Coastguard Worker GetEventTarget()129*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* GetEventTarget() const { return m_pTarget; } GetEventParam()130*3ac0a46fSAndroid Build Coastguard Worker CXFA_EventParam* GetEventParam() const { return m_eventParam; } 131*3ac0a46fSAndroid Build Coastguard Worker bool RunScript(CXFA_Script::Type eScriptType, 132*3ac0a46fSAndroid Build Coastguard Worker WideStringView wsScript, 133*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Value* pRetValue, 134*3ac0a46fSAndroid Build Coastguard Worker CXFA_Object* pThisObject); 135*3ac0a46fSAndroid Build Coastguard Worker 136*3ac0a46fSAndroid Build Coastguard Worker absl::optional<ResolveResult> ResolveObjects(CXFA_Object* refObject, 137*3ac0a46fSAndroid Build Coastguard Worker WideStringView wsExpression, 138*3ac0a46fSAndroid Build Coastguard Worker Mask<XFA_ResolveFlag> dwStyles); 139*3ac0a46fSAndroid Build Coastguard Worker 140*3ac0a46fSAndroid Build Coastguard Worker absl::optional<ResolveResult> ResolveObjectsWithBindNode( 141*3ac0a46fSAndroid Build Coastguard Worker CXFA_Object* refObject, 142*3ac0a46fSAndroid Build Coastguard Worker WideStringView wsExpression, 143*3ac0a46fSAndroid Build Coastguard Worker Mask<XFA_ResolveFlag> dwStyles, 144*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* bindNode); 145*3ac0a46fSAndroid Build Coastguard Worker 146*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> GetOrCreateJSBindingFromMap(CXFA_Object* pObject); 147*3ac0a46fSAndroid Build Coastguard Worker GetThisObject()148*3ac0a46fSAndroid Build Coastguard Worker CXFA_Object* GetThisObject() const { return m_pThisObject; } GetJseNormalClass()149*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Class* GetJseNormalClass() const { return m_pJsClass; } GetDocument()150*3ac0a46fSAndroid Build Coastguard Worker CXFA_Document* GetDocument() const { return m_pDocument.Get(); } 151*3ac0a46fSAndroid Build Coastguard Worker 152*3ac0a46fSAndroid Build Coastguard Worker void SetNodesOfRunScript(std::vector<cppgc::Persistent<CXFA_Node>>* pArray); 153*3ac0a46fSAndroid Build Coastguard Worker void AddNodesOfRunScript(CXFA_Node* pNode); 154*3ac0a46fSAndroid Build Coastguard Worker SetRunAtType(XFA_AttributeValue eRunAt)155*3ac0a46fSAndroid Build Coastguard Worker void SetRunAtType(XFA_AttributeValue eRunAt) { m_eRunAtType = eRunAt; } IsRunAtClient()156*3ac0a46fSAndroid Build Coastguard Worker bool IsRunAtClient() { return m_eRunAtType != XFA_AttributeValue::Server; } 157*3ac0a46fSAndroid Build Coastguard Worker 158*3ac0a46fSAndroid Build Coastguard Worker CXFA_Script::Type GetType(); 159*3ac0a46fSAndroid Build Coastguard Worker 160*3ac0a46fSAndroid Build Coastguard Worker void AddObjectToUpArray(CXFA_Node* pNode); 161*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* LastObjectFromUpArray(); 162*3ac0a46fSAndroid Build Coastguard Worker 163*3ac0a46fSAndroid Build Coastguard Worker CXFA_Object* ToXFAObject(v8::Local<v8::Value> obj); 164*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> NewNormalXFAObject(CXFA_Object* obj); 165*3ac0a46fSAndroid Build Coastguard Worker IsResolvingNodes()166*3ac0a46fSAndroid Build Coastguard Worker bool IsResolvingNodes() const { return m_bResolvingNodes; } 167*3ac0a46fSAndroid Build Coastguard Worker GetJseContextForTest()168*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Context* GetJseContextForTest() const { return GetJseContext(); } 169*3ac0a46fSAndroid Build Coastguard Worker 170*3ac0a46fSAndroid Build Coastguard Worker private: GetJseContext()171*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Context* GetJseContext() const { return m_JsContext.get(); } 172*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Context* CreateVariablesContext(CXFA_Script* pScriptNode, 173*3ac0a46fSAndroid Build Coastguard Worker CXFA_Node* pSubform); 174*3ac0a46fSAndroid Build Coastguard Worker void RemoveBuiltInObjs(CFXJSE_Context* pContext); 175*3ac0a46fSAndroid Build Coastguard Worker bool QueryNodeByFlag(CXFA_Node* refNode, 176*3ac0a46fSAndroid Build Coastguard Worker WideStringView propname, 177*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value>* pValue, 178*3ac0a46fSAndroid Build Coastguard Worker Mask<XFA_ResolveFlag> dwFlag); 179*3ac0a46fSAndroid Build Coastguard Worker bool UpdateNodeByFlag(CXFA_Node* refNode, 180*3ac0a46fSAndroid Build Coastguard Worker WideStringView propname, 181*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value> pValue, 182*3ac0a46fSAndroid Build Coastguard Worker Mask<XFA_ResolveFlag> dwFlag); 183*3ac0a46fSAndroid Build Coastguard Worker bool IsStrictScopeInJavaScript(); 184*3ac0a46fSAndroid Build Coastguard Worker CXFA_Object* GetVariablesThis(CXFA_Object* pObject); 185*3ac0a46fSAndroid Build Coastguard Worker CXFA_Object* GetVariablesScript(CXFA_Object* pObject); 186*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Context* VariablesContextForScriptNode(CXFA_Script* pScriptNode); 187*3ac0a46fSAndroid Build Coastguard Worker bool QueryVariableValue(CXFA_Script* pScriptNode, 188*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szPropName, 189*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value>* pValue); 190*3ac0a46fSAndroid Build Coastguard Worker bool UpdateVariableValue(CXFA_Script* pScriptNode, 191*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szPropName, 192*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value> pValue); 193*3ac0a46fSAndroid Build Coastguard Worker void RunVariablesScript(CXFA_Script* pScriptNode); 194*3ac0a46fSAndroid Build Coastguard Worker 195*3ac0a46fSAndroid Build Coastguard Worker UnownedPtr<CJS_Runtime> const m_pSubordinateRuntime; 196*3ac0a46fSAndroid Build Coastguard Worker cppgc::WeakPersistent<CXFA_Document> const m_pDocument; 197*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<CFXJSE_Context> m_JsContext; 198*3ac0a46fSAndroid Build Coastguard Worker UnownedPtr<CFXJSE_Class> m_pJsClass; 199*3ac0a46fSAndroid Build Coastguard Worker CXFA_Script::Type m_eScriptType = CXFA_Script::Type::Unknown; 200*3ac0a46fSAndroid Build Coastguard Worker // |m_mapObjectToValue| is what ensures the v8 object bound to a 201*3ac0a46fSAndroid Build Coastguard Worker // CJX_Object remains valid for the lifetime of the engine. 202*3ac0a46fSAndroid Build Coastguard Worker std::map<cppgc::Persistent<CJX_Object>, v8::Global<v8::Object>> 203*3ac0a46fSAndroid Build Coastguard Worker m_mapObjectToObject; 204*3ac0a46fSAndroid Build Coastguard Worker std::map<cppgc::Persistent<CJX_Object>, std::unique_ptr<CFXJSE_Context>> 205*3ac0a46fSAndroid Build Coastguard Worker m_mapVariableToContext; 206*3ac0a46fSAndroid Build Coastguard Worker cppgc::Persistent<CXFA_Node> m_pTarget; 207*3ac0a46fSAndroid Build Coastguard Worker UnownedPtr<CXFA_EventParam> m_eventParam; 208*3ac0a46fSAndroid Build Coastguard Worker std::vector<cppgc::Persistent<CXFA_Node>> m_upObjectArray; 209*3ac0a46fSAndroid Build Coastguard Worker UnownedPtr<std::vector<cppgc::Persistent<CXFA_Node>>> m_pScriptNodeArray; 210*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<CFXJSE_NodeHelper> const m_NodeHelper; 211*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<CFXJSE_ResolveProcessor> const m_ResolveProcessor; 212*3ac0a46fSAndroid Build Coastguard Worker std::unique_ptr<CFXJSE_FormCalcContext> m_FormCalcContext; 213*3ac0a46fSAndroid Build Coastguard Worker cppgc::Persistent<CXFA_Object> m_pThisObject; 214*3ac0a46fSAndroid Build Coastguard Worker XFA_AttributeValue m_eRunAtType = XFA_AttributeValue::Client; 215*3ac0a46fSAndroid Build Coastguard Worker bool m_bResolvingNodes = false; 216*3ac0a46fSAndroid Build Coastguard Worker }; 217*3ac0a46fSAndroid Build Coastguard Worker 218*3ac0a46fSAndroid Build Coastguard Worker #endif // FXJS_XFA_CFXJSE_ENGINE_H_ 219