|  | // Copyright 2014 The PDFium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com | 
|  |  | 
|  | #ifndef FXJS_XFA_CFXJSE_ENGINE_H_ | 
|  | #define FXJS_XFA_CFXJSE_ENGINE_H_ | 
|  |  | 
|  | #include <map> | 
|  | #include <memory> | 
|  | #include <type_traits> | 
|  | #include <vector> | 
|  |  | 
|  | #include "core/fxcrt/mask.h" | 
|  | #include "core/fxcrt/unowned_ptr.h" | 
|  | #include "fxjs/cfx_v8.h" | 
|  | #include "v8/include/cppgc/persistent.h" | 
|  | #include "v8/include/v8-forward.h" | 
|  | #include "v8/include/v8-persistent-handle.h" | 
|  | #include "xfa/fxfa/cxfa_eventparam.h" | 
|  | #include "xfa/fxfa/parser/cxfa_document.h" | 
|  | #include "xfa/fxfa/parser/cxfa_script.h" | 
|  | #include "xfa/fxfa/parser/xfa_basic_data.h" | 
|  |  | 
|  | class CFXJSE_Class; | 
|  | class CFXJSE_Context; | 
|  | class CFXJSE_FormCalcContext; | 
|  | class CFXJSE_HostObject; | 
|  | class CFXJSE_NodeHelper; | 
|  | class CFXJSE_ResolveProcessor; | 
|  | class CFXJSE_Value; | 
|  | class CJS_Runtime; | 
|  |  | 
|  | enum class XFA_ResolveFlag : uint16_t { | 
|  | kChildren = 1 << 0, | 
|  | kTagName = 1 << 1, | 
|  | kAttributes = 1 << 2, | 
|  | kProperties = 1 << 3, | 
|  | kSiblings = 1 << 5, | 
|  | kParent = 1 << 6, | 
|  | kAnyChild = 1 << 7, | 
|  | kALL = 1 << 8, | 
|  | kCreateNode = 1 << 10, | 
|  | kBind = 1 << 11, | 
|  | kBindNew = 1 << 12, | 
|  | }; | 
|  |  | 
|  | class CFXJSE_Engine final : public CFX_V8 { | 
|  | public: | 
|  | class ResolveResult { | 
|  | CPPGC_STACK_ALLOCATED();  // Allow raw/unowned pointers. | 
|  |  | 
|  | public: | 
|  | enum class Type { | 
|  | kNodes = 0, | 
|  | kAttribute, | 
|  | kCreateNodeOne, | 
|  | kCreateNodeAll, | 
|  | kCreateNodeMidAll, | 
|  | kExistNodes, | 
|  | }; | 
|  |  | 
|  | ResolveResult(); | 
|  | ResolveResult(const ResolveResult& that); | 
|  | ResolveResult& operator=(const ResolveResult& that); | 
|  | ~ResolveResult(); | 
|  |  | 
|  | Type type = Type::kNodes; | 
|  | XFA_SCRIPTATTRIBUTEINFO script_attribute = {}; | 
|  |  | 
|  | // Vector of Member would be correct for stack-based vectors, if | 
|  | // STL worked with cppgc. | 
|  | std::vector<cppgc::Member<CXFA_Object>> objects; | 
|  | }; | 
|  |  | 
|  | static CXFA_Object* ToObject(const v8::FunctionCallbackInfo<v8::Value>& info); | 
|  | static CXFA_Object* ToObject(v8::Isolate* pIsolate, | 
|  | v8::Local<v8::Value> value); | 
|  | static CXFA_Object* ToObject(v8::Isolate* pIsolate, CFXJSE_Value* pValue); | 
|  | static CXFA_Object* ToObject(CFXJSE_HostObject* pHostObj); | 
|  | static v8::Local<v8::Value> GlobalPropertyGetter( | 
|  | v8::Isolate* pIsolate, | 
|  | v8::Local<v8::Object> pObject, | 
|  | ByteStringView szPropName); | 
|  | static void GlobalPropertySetter(v8::Isolate* pIsolate, | 
|  | v8::Local<v8::Object> pObject, | 
|  | ByteStringView szPropName, | 
|  | v8::Local<v8::Value> pValue); | 
|  | static v8::Local<v8::Value> NormalPropertyGetter( | 
|  | v8::Isolate* pIsolate, | 
|  | v8::Local<v8::Object> pObject, | 
|  | ByteStringView szPropName); | 
|  | static void NormalPropertySetter(v8::Isolate* pIsolate, | 
|  | v8::Local<v8::Object> pObject, | 
|  | ByteStringView szPropName, | 
|  | v8::Local<v8::Value> pValue); | 
|  | static CJS_Result NormalMethodCall( | 
|  | const v8::FunctionCallbackInfo<v8::Value>& info, | 
|  | const WideString& functionName); | 
|  | static FXJSE_ClassPropType NormalPropTypeGetter(v8::Isolate* pIsolate, | 
|  | v8::Local<v8::Object> pObject, | 
|  | ByteStringView szPropName, | 
|  | bool bQueryIn); | 
|  | static FXJSE_ClassPropType GlobalPropTypeGetter(v8::Isolate* pIsolate, | 
|  | v8::Local<v8::Object> pObject, | 
|  | ByteStringView szPropName, | 
|  | bool bQueryIn); | 
|  |  | 
|  | CFXJSE_Engine(CXFA_Document* pDocument, CJS_Runtime* fxjs_runtime); | 
|  | ~CFXJSE_Engine() override; | 
|  |  | 
|  | void SetEventParam(CXFA_EventParam* param) { m_eventParam = param; } | 
|  | CXFA_EventParam* GetEventParam() const { return m_eventParam; } | 
|  | bool RunScript(CXFA_Script::Type eScriptType, | 
|  | WideStringView wsScript, | 
|  | CFXJSE_Value* pRetValue, | 
|  | CXFA_Object* pThisObject); | 
|  |  | 
|  | absl::optional<ResolveResult> ResolveObjects(CXFA_Object* refObject, | 
|  | WideStringView wsExpression, | 
|  | Mask<XFA_ResolveFlag> dwStyles); | 
|  |  | 
|  | absl::optional<ResolveResult> ResolveObjectsWithBindNode( | 
|  | CXFA_Object* refObject, | 
|  | WideStringView wsExpression, | 
|  | Mask<XFA_ResolveFlag> dwStyles, | 
|  | CXFA_Node* bindNode); | 
|  |  | 
|  | v8::Local<v8::Object> GetOrCreateJSBindingFromMap(CXFA_Object* pObject); | 
|  |  | 
|  | CXFA_Object* GetThisObject() const { return m_pThisObject; } | 
|  | CFXJSE_Class* GetJseNormalClass() const { return m_pJsClass; } | 
|  | CXFA_Document* GetDocument() const { return m_pDocument.Get(); } | 
|  |  | 
|  | void SetNodesOfRunScript(std::vector<cppgc::Persistent<CXFA_Node>>* pArray); | 
|  | void AddNodesOfRunScript(CXFA_Node* pNode); | 
|  |  | 
|  | void SetRunAtType(XFA_AttributeValue eRunAt) { m_eRunAtType = eRunAt; } | 
|  | bool IsRunAtClient() { return m_eRunAtType != XFA_AttributeValue::Server; } | 
|  |  | 
|  | CXFA_Script::Type GetType(); | 
|  |  | 
|  | void AddObjectToUpArray(CXFA_Node* pNode); | 
|  | CXFA_Node* LastObjectFromUpArray(); | 
|  |  | 
|  | CXFA_Object* ToXFAObject(v8::Local<v8::Value> obj); | 
|  | v8::Local<v8::Object> NewNormalXFAObject(CXFA_Object* obj); | 
|  |  | 
|  | bool IsResolvingNodes() const { return m_bResolvingNodes; } | 
|  |  | 
|  | CFXJSE_Context* GetJseContextForTest() const { return GetJseContext(); } | 
|  |  | 
|  | private: | 
|  | CFXJSE_Context* GetJseContext() const { return m_JsContext.get(); } | 
|  | CFXJSE_Context* CreateVariablesContext(CXFA_Script* pScriptNode, | 
|  | CXFA_Node* pSubform); | 
|  | void RemoveBuiltInObjs(CFXJSE_Context* pContext); | 
|  | bool QueryNodeByFlag(CXFA_Node* refNode, | 
|  | WideStringView propname, | 
|  | v8::Local<v8::Value>* pValue, | 
|  | Mask<XFA_ResolveFlag> dwFlag); | 
|  | bool UpdateNodeByFlag(CXFA_Node* refNode, | 
|  | WideStringView propname, | 
|  | v8::Local<v8::Value> pValue, | 
|  | Mask<XFA_ResolveFlag> dwFlag); | 
|  | bool IsStrictScopeInJavaScript(); | 
|  | CXFA_Object* GetVariablesThis(CXFA_Object* pObject); | 
|  | CXFA_Object* GetVariablesScript(CXFA_Object* pObject); | 
|  | CFXJSE_Context* VariablesContextForScriptNode(CXFA_Script* pScriptNode); | 
|  | bool QueryVariableValue(CXFA_Script* pScriptNode, | 
|  | ByteStringView szPropName, | 
|  | v8::Local<v8::Value>* pValue); | 
|  | bool UpdateVariableValue(CXFA_Script* pScriptNode, | 
|  | ByteStringView szPropName, | 
|  | v8::Local<v8::Value> pValue); | 
|  | void RunVariablesScript(CXFA_Script* pScriptNode); | 
|  |  | 
|  | UnownedPtr<CJS_Runtime> const m_pSubordinateRuntime; | 
|  | cppgc::WeakPersistent<CXFA_Document> const m_pDocument; | 
|  | std::unique_ptr<CFXJSE_Context> m_JsContext; | 
|  | UnownedPtr<CFXJSE_Class> m_pJsClass; | 
|  | CXFA_Script::Type m_eScriptType = CXFA_Script::Type::Unknown; | 
|  | // |m_mapObjectToValue| is what ensures the v8 object bound to a | 
|  | // CJX_Object remains valid for the lifetime of the engine. | 
|  | std::map<CJX_Object*, v8::Global<v8::Object>> m_mapObjectToObject; | 
|  | std::map<CJX_Object*, std::unique_ptr<CFXJSE_Context>> m_mapVariableToContext; | 
|  | UnownedPtr<CXFA_EventParam> m_eventParam; | 
|  | std::vector<cppgc::Persistent<CXFA_Node>> m_upObjectArray; | 
|  | UnownedPtr<std::vector<cppgc::Persistent<CXFA_Node>>> m_pScriptNodeArray; | 
|  | std::unique_ptr<CFXJSE_NodeHelper> const m_NodeHelper; | 
|  | std::unique_ptr<CFXJSE_ResolveProcessor> const m_ResolveProcessor; | 
|  | std::unique_ptr<CFXJSE_FormCalcContext> m_FormCalcContext; | 
|  | cppgc::Persistent<CXFA_Object> m_pThisObject; | 
|  | XFA_AttributeValue m_eRunAtType = XFA_AttributeValue::Client; | 
|  | bool m_bResolvingNodes = false; | 
|  | }; | 
|  |  | 
|  | #endif  //  FXJS_XFA_CFXJSE_ENGINE_H_ |