/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef ECMASCRIPT_TOOLING_AGENT_RUNTIME_IMPL_H #define ECMASCRIPT_TOOLING_AGENT_RUNTIME_IMPL_H #include "base/pt_params.h" #include "dispatcher.h" #include "libpandabase/macros.h" namespace panda::ecmascript::tooling { class RuntimeImpl final { public: RuntimeImpl(const EcmaVM *vm, ProtocolChannel *channel) : vm_(vm), frontend_(channel) {} ~RuntimeImpl() = default; DispatchResponse Enable(); DispatchResponse Disable(); DispatchResponse RunIfWaitingForDebugger(); DispatchResponse CallFunctionOn( const CallFunctionOnParams ¶ms, std::unique_ptr *outRemoteObject, std::optional> *outExceptionDetails); DispatchResponse GetHeapUsage(double *usedSize, double *totalSize); DispatchResponse GetProperties( const GetPropertiesParams ¶ms, std::vector> *outPropertyDesc, std::optional>> *outInternalDescs, std::optional>> *outPrivateProps, std::optional> *outExceptionDetails); class DispatcherImpl final : public DispatcherBase { public: DispatcherImpl(ProtocolChannel *channel, std::unique_ptr runtime) : DispatcherBase(channel), runtime_(std::move(runtime)) {} ~DispatcherImpl() override = default; void Dispatch(const DispatchRequest &request) override; void Disable(const DispatchRequest &request); void Enable(const DispatchRequest &request); void RunIfWaitingForDebugger(const DispatchRequest &request); void GetProperties(const DispatchRequest &request); void CallFunctionOn(const DispatchRequest &request); void GetHeapUsage(const DispatchRequest &request); private: using AgentHandler = void (RuntimeImpl::DispatcherImpl::*)(const DispatchRequest &request); std::unique_ptr runtime_ {}; NO_COPY_SEMANTIC(DispatcherImpl); NO_MOVE_SEMANTIC(DispatcherImpl); }; private: NO_COPY_SEMANTIC(RuntimeImpl); NO_MOVE_SEMANTIC(RuntimeImpl); enum NumberSize : uint8_t { BYTES_OF_16BITS = 2, BYTES_OF_32BITS = 4, BYTES_OF_64BITS = 8 }; void CacheObjectIfNeeded(Local valRef, RemoteObject *remoteObj); template void AddTypedArrayRef(Local arrayBufferRef, int32_t length, const char* name, std::vector> *outPropertyDesc); void AddTypedArrayRefs(Local arrayBufferRef, std::vector> *outPropertyDesc); void AddSharedArrayBufferRefs(Local arrayBufferRef, std::vector> *outPropertyDesc); void GetProtoOrProtoType(Local value, bool isOwn, bool isAccessorOnly, std::vector> *outPropertyDesc); void GetAdditionalProperties(Local value, std::vector> *outPropertyDesc); void SetKeyValue(Local &jsValueRef, std::vector> *outPropertyDesc, const std::string &cstrProName); void GetPrimitiveNumberValue(Local value, std::vector> *outPropertyDesc); void GetPrimitiveStringValue(Local value, std::vector> *outPropertyDesc); void GetPrimitiveBooleanValue(Local value, std::vector> *outPropertyDesc); void GetMapIteratorValue(Local value, std::vector> *outPropertyDesc); void GetSetIteratorValue(Local value, std::vector> *outPropertyDesc); void GetGeneratorFunctionValue(Local value, std::vector> *outPropertyDesc); void GetGeneratorObjectValue(Local value, std::vector> *outPropertyDesc); void GetNumberFormatValue(Local value, std::vector> *outPropertyDesc); void GetCollatorValue(Local value, std::vector> *outPropertyDesc); void GetDateTimeFormatValue(Local value, std::vector> *outPropertyDesc); void GetMapValue(Local value, std::vector> *outPropertyDesc); void GetWeakMapValue(Local value, std::vector> *outPropertyDesc); void GetSetValue(Local value, std::vector> *outPropertyDesc); void GetWeakSetValue(Local value, std::vector> *outPropertyDesc); void GetDataViewValue(Local value, std::vector> *outPropertyDesc); void GetRegExpValue(Local value, std::vector> *outPropertyDesc); void GetArrayListValue(Local value, std::vector> *outPropertyDesc); void GetDequeValue(Local value, std::vector> *outPropertyDesc); void GetHashMapValue(Local value, std::vector> *outPropertyDesc); void GetHashSetValue(Local value, std::vector> *outPropertyDesc); void GetLightWeightMapValue(Local value, std::vector> *outPropertyDesc); void GetLightWeightSetValue(Local value, std::vector> *outPropertyDesc); void GetLinkedListValue(Local value, std::vector> *outPropertyDesc); void GetListValue(Local value, std::vector> *outPropertyDesc); void GetStackValue(Local value, std::vector> *outPropertyDesc); void GetPlainArrayValue(Local value, std::vector> *outPropertyDesc); void GetQueueValue(Local value, std::vector> *outPropertyDesc); void GetTreeMapValue(Local value, std::vector> *outPropertyDesc); void GetTreeSetValue(Local value, std::vector> *outPropertyDesc); void GetVectorValue(Local value, std::vector> *outPropertyDesc); void GetProxyValue(Local value, std::vector> *outPropertyDesc); class Frontend { public: explicit Frontend(ProtocolChannel *channel) : channel_(channel) {} ~Frontend() = default; void RunIfWaitingForDebugger(); private: bool AllowNotify() const; ProtocolChannel *channel_ {nullptr}; }; const EcmaVM *vm_ {nullptr}; Frontend frontend_; RemoteObjectId curObjectId_ {0}; std::unordered_map> properties_ {}; Global internalObjects_; friend class DebuggerImpl; }; } // namespace panda::ecmascript::tooling #endif