From a96d7500bb19a8244baf0a5c49029e1c84bb6c45 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 27 Apr 2023 17:37:08 -0700 Subject: [PATCH 01/23] chore: Use jint for Java object ID everywhere The Java object ID is an integer returned from Java, so it should be typed as jint. jint is int32_t, so using uint32_t is incorrect here. Using int is probably OK, but change it anyway for consistency. --- .../runtime/src/main/cpp/CallbackHandlers.cpp | 2 +- .../runtime/src/main/cpp/CallbackHandlers.h | 2 +- .../runtime/src/main/cpp/FieldAccessor.cpp | 2 +- .../runtime/src/main/cpp/JsArgConverter.cpp | 2 +- .../src/main/cpp/JsArgToArrayConverter.cpp | 2 +- .../runtime/src/main/cpp/ObjectManager.cpp | 20 ++++++------ test-app/runtime/src/main/cpp/ObjectManager.h | 32 +++++++++---------- test-app/runtime/src/main/cpp/Runtime.cpp | 4 +-- .../objects/JSToJavaObjectsConverter.cpp | 2 +- 9 files changed, 33 insertions(+), 35 deletions(-) diff --git a/test-app/runtime/src/main/cpp/CallbackHandlers.cpp b/test-app/runtime/src/main/cpp/CallbackHandlers.cpp index d86348e94..660c4c953 100644 --- a/test-app/runtime/src/main/cpp/CallbackHandlers.cpp +++ b/test-app/runtime/src/main/cpp/CallbackHandlers.cpp @@ -84,7 +84,7 @@ bool CallbackHandlers::RegisterInstance(Isolate *isolate, const Local &j implementationObject, isInterface); - int javaObjectID = objectManager->GenerateNewObjectID(); + jint javaObjectID = objectManager->GenerateNewObjectID(); objectManager->Link(jsObject, javaObjectID, nullptr); diff --git a/test-app/runtime/src/main/cpp/CallbackHandlers.h b/test-app/runtime/src/main/cpp/CallbackHandlers.h index 0ca90e7ac..22b0b31b6 100644 --- a/test-app/runtime/src/main/cpp/CallbackHandlers.h +++ b/test-app/runtime/src/main/cpp/CallbackHandlers.h @@ -269,7 +269,7 @@ namespace tns { static FieldAccessor fieldAccessor; struct JavaObjectIdScope { - JavaObjectIdScope(JEnv &env, jfieldID fieldId, jobject runtime, int javaObjectId) + JavaObjectIdScope(JEnv &env, jfieldID fieldId, jobject runtime, jint javaObjectId) : _env(env), _fieldID(fieldId), _runtime(runtime) { _env.SetIntField(_runtime, _fieldID, javaObjectId); } diff --git a/test-app/runtime/src/main/cpp/FieldAccessor.cpp b/test-app/runtime/src/main/cpp/FieldAccessor.cpp index f8f7148c1..1f03bffe5 100644 --- a/test-app/runtime/src/main/cpp/FieldAccessor.cpp +++ b/test-app/runtime/src/main/cpp/FieldAccessor.cpp @@ -166,7 +166,7 @@ Local FieldAccessor::GetJavaField(Isolate* isolate, const Local& auto resultV8Value = ArgConverter::jstringToV8String(isolate, (jstring) result); fieldResult = handleScope.Escape(resultV8Value); } else { - int javaObjectID = objectManager->GetOrCreateObjectId(result); + jint javaObjectID = objectManager->GetOrCreateObjectId(result); auto objectResult = objectManager->GetJsObjectByJavaObject(javaObjectID); if (objectResult.IsEmpty()) { diff --git a/test-app/runtime/src/main/cpp/JsArgConverter.cpp b/test-app/runtime/src/main/cpp/JsArgConverter.cpp index 5dfa72fbb..7de43e9b5 100644 --- a/test-app/runtime/src/main/cpp/JsArgConverter.cpp +++ b/test-app/runtime/src/main/cpp/JsArgConverter.cpp @@ -327,7 +327,7 @@ bool JsArgConverter::ConvertArg(const Local &arg, int index) { buffer = env.NewGlobalRef(buffer); - int id = objectManager->GetOrCreateObjectId(buffer); + jint id = objectManager->GetOrCreateObjectId(buffer); auto clazz = env.GetObjectClass(buffer); objectManager->Link(jsObject, id, clazz); diff --git a/test-app/runtime/src/main/cpp/JsArgToArrayConverter.cpp b/test-app/runtime/src/main/cpp/JsArgToArrayConverter.cpp index 485e5efac..0e2360a01 100644 --- a/test-app/runtime/src/main/cpp/JsArgToArrayConverter.cpp +++ b/test-app/runtime/src/main/cpp/JsArgToArrayConverter.cpp @@ -331,7 +331,7 @@ bool JsArgToArrayConverter::ConvertArg(Local context, const LocalGetOrCreateObjectId(buffer); + jint id = objectManager->GetOrCreateObjectId(buffer); auto clazz = env.GetObjectClass(buffer); objectManager->Link(jsObj, id, clazz); diff --git a/test-app/runtime/src/main/cpp/ObjectManager.cpp b/test-app/runtime/src/main/cpp/ObjectManager.cpp index f8995a78f..189064f06 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.cpp +++ b/test-app/runtime/src/main/cpp/ObjectManager.cpp @@ -144,13 +144,13 @@ bool ObjectManager::IsJsRuntimeObject(const v8::Local &object) { return internalFieldCount == count; } -jweak ObjectManager::GetJavaObjectByID(uint32_t javaObjectID) { +jweak ObjectManager::GetJavaObjectByID(jint javaObjectID) { jweak obj = m_cache(javaObjectID); return obj; } -jobject ObjectManager::GetJavaObjectByIDImpl(uint32_t javaObjectID) { +jobject ObjectManager::GetJavaObjectByIDImpl(jint javaObjectID) { JEnv env; jobject object = env.CallObjectMethod(m_javaRuntimeObject, GET_JAVAOBJECT_BY_ID_METHOD_ID, javaObjectID); @@ -175,7 +175,7 @@ void ObjectManager::SetJavaClass(const Local &instance, jclass clazz) { jsInfo->ObjectClazz = clazz; } -int ObjectManager::GetOrCreateObjectId(jobject object) { +jint ObjectManager::GetOrCreateObjectId(jobject object) { JEnv env; jint javaObjectID = env.CallIntMethod(m_javaRuntimeObject, GET_OR_CREATE_JAVA_OBJECT_ID_METHOD_ID, object); @@ -183,7 +183,7 @@ int ObjectManager::GetOrCreateObjectId(jobject object) { return javaObjectID; } -Local ObjectManager::GetJsObjectByJavaObject(int javaObjectID) { +Local ObjectManager::GetJsObjectByJavaObject(jint javaObjectID) { auto isolate = m_isolate; EscapableHandleScope handleScope(isolate); @@ -233,7 +233,7 @@ ObjectManager::CreateJSWrapperHelper(jint javaObjectID, const string &typeName, /* * * Link the JavaScript object and it's java counterpart with an ID */ -void ObjectManager::Link(const Local &object, uint32_t javaObjectID, jclass clazz) { +void ObjectManager::Link(const Local &object, jint javaObjectID, jclass clazz) { if (!IsJsRuntimeObject(object)) { string errMsg("Trying to link invalid 'this' to a Java object"); throw NativeScriptException(errMsg); @@ -407,15 +407,15 @@ void ObjectManager::JSObjectWeakCallback(Isolate *isolate, ObjectWeakCallbackSta po->SetWeak(callbackState, JSObjectWeakCallbackStatic, WeakCallbackType::kFinalizer); } -int ObjectManager::GenerateNewObjectID() { - const int one = 1; - int oldValue = __sync_fetch_and_add(&m_currentObjectId, one); +jint ObjectManager::GenerateNewObjectID() { + const jint one = 1; + jint oldValue = __sync_fetch_and_add(&m_currentObjectId, one); return oldValue; } void ObjectManager::ReleaseJSInstance(Persistent *po, JSInstanceInfo *jsInstanceInfo) { - int javaObjectID = jsInstanceInfo->JavaObjectID; + jint javaObjectID = jsInstanceInfo->JavaObjectID; auto it = m_idToObject.find(javaObjectID); @@ -495,7 +495,7 @@ bool ObjectManager::HasImplObject(Isolate *isolate, const Local &obj) { return hasImplObj; } -jweak ObjectManager::NewWeakGlobalRefCallback(const int &javaObjectID, void *state) { +jweak ObjectManager::NewWeakGlobalRefCallback(const jint &javaObjectID, void *state) { auto objManager = reinterpret_cast(state); JniLocalRef obj(objManager->GetJavaObjectByIDImpl(javaObjectID)); diff --git a/test-app/runtime/src/main/cpp/ObjectManager.h b/test-app/runtime/src/main/cpp/ObjectManager.h index 28cfd4372..2ed51b525 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.h +++ b/test-app/runtime/src/main/cpp/ObjectManager.h @@ -27,15 +27,15 @@ class ObjectManager { jclass GetJavaClass(const v8::Local& instance); void SetJavaClass(const v8::Local& instance, jclass clazz); - int GetOrCreateObjectId(jobject object); + jint GetOrCreateObjectId(jobject object); - v8::Local GetJsObjectByJavaObject(int javaObjectID); + v8::Local GetJsObjectByJavaObject(jint javaObjectID); v8::Local CreateJSWrapper(jint javaObjectID, const std::string& typeName); v8::Local CreateJSWrapper(jint javaObjectID, const std::string& typeName, jobject instance); - void Link(const v8::Local& object, uint32_t javaObjectID, jclass clazz); + void Link(const v8::Local& object, jint javaObjectID, jclass clazz); void ReleaseNativeCounterpart(v8::Local& object); @@ -47,7 +47,7 @@ class ObjectManager { std::string GetClassName(jclass clazz); - int GenerateNewObjectID(); + jint GenerateNewObjectID(); void SetInstanceIsolate(v8::Isolate* isolate); @@ -81,12 +81,12 @@ class ObjectManager { struct JSInstanceInfo { public: - JSInstanceInfo(bool isJavaObjectWeak, uint32_t javaObjectID, jclass claz) + JSInstanceInfo(bool isJavaObjectWeak, jint javaObjectID, jclass claz) :IsJavaObjectWeak(isJavaObjectWeak), JavaObjectID(javaObjectID), ObjectClazz(claz) { } bool IsJavaObjectWeak; - uint32_t JavaObjectID; + jint JavaObjectID; jclass ObjectClazz; }; @@ -121,7 +121,7 @@ class ObjectManager { m_IDs.clear(); } - void insert(v8::Persistent* po, int javaObjectId) { + void insert(v8::Persistent* po, jint javaObjectId) { m_POs.insert(po); m_IDs.insert(javaObjectId); } @@ -131,16 +131,16 @@ class ObjectManager { } std::set*> m_POs; - std::set m_IDs; + std::set m_IDs; }; struct PersistentObjectIdPair { - PersistentObjectIdPair(v8::Persistent* _po, int _javaObjectId) + PersistentObjectIdPair(v8::Persistent* _po, jint _javaObjectId) : po(_po), javaObjectId(_javaObjectId) { } v8::Persistent* po; - int javaObjectId; + jint javaObjectId; }; @@ -171,9 +171,9 @@ class ObjectManager { bool HasImplObject(v8::Isolate* isolate, const v8::Local& obj); - jweak GetJavaObjectByID(uint32_t javaObjectID); + jweak GetJavaObjectByID(jint javaObjectID); - jobject GetJavaObjectByIDImpl(uint32_t javaObjectID); + jobject GetJavaObjectByIDImpl(jint javaObjectID); static jweak NewWeakGlobalRefCallback(const int& javaObjectID, void* state); @@ -189,19 +189,19 @@ class ObjectManager { std::stack m_markedForGC; - std::unordered_map*> m_idToObject; + std::unordered_map*> m_idToObject; PersistentObjectIdSet m_released; std::set m_visited; - LRUCache m_cache; + LRUCache m_cache; std::set*> m_visitedPOs; std::vector m_implObjWeak; - std::unordered_map*> m_implObjStrong; + std::unordered_map*> m_implObjStrong; - volatile int m_currentObjectId; + volatile jint m_currentObjectId; DirectBuffer m_buff; diff --git a/test-app/runtime/src/main/cpp/Runtime.cpp b/test-app/runtime/src/main/cpp/Runtime.cpp index 43238b0bc..bc849d453 100644 --- a/test-app/runtime/src/main/cpp/Runtime.cpp +++ b/test-app/runtime/src/main/cpp/Runtime.cpp @@ -364,9 +364,7 @@ void Runtime::CreateJSInstanceNative(JNIEnv* _env, jobject obj, jobject javaObje } jint Runtime::GenerateNewObjectId(JNIEnv* env, jobject obj) { - int objectId = m_objectManager->GenerateNewObjectID(); - - return objectId; + return m_objectManager->GenerateNewObjectID(); } void Runtime::AdjustAmountOfExternalAllocatedMemory() { diff --git a/test-app/runtime/src/main/cpp/conversions/objects/JSToJavaObjectsConverter.cpp b/test-app/runtime/src/main/cpp/conversions/objects/JSToJavaObjectsConverter.cpp index e92bb9e26..2a8781512 100644 --- a/test-app/runtime/src/main/cpp/conversions/objects/JSToJavaObjectsConverter.cpp +++ b/test-app/runtime/src/main/cpp/conversions/objects/JSToJavaObjectsConverter.cpp @@ -210,7 +210,7 @@ bool tns::ConvertJavaScriptObject( buffer = env.NewGlobalRef(buffer); - int id = objectManager->GetOrCreateObjectId(buffer); + jint id = objectManager->GetOrCreateObjectId(buffer); auto clazz = env.GetObjectClass(buffer); objectManager->Link(jsObject, id, clazz); From 9c5358742e0cb30261c27802f0b4f8f3bfdadc4a Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Mon, 8 May 2023 13:07:46 -0700 Subject: [PATCH 02/23] chore: Avoid shadowing variable Shadowing the outer jsInfo variable looks like a bug and causes a compiler warning. But it actually is not a bug, because the earlier GetJSInstanceInfo() call returns the JSInstanceInfo* pointer, whereas we need the v8::External to put into the internal field. It's easier to reuse the same External than to create a new one. --- test-app/runtime/src/main/cpp/ObjectManager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test-app/runtime/src/main/cpp/ObjectManager.cpp b/test-app/runtime/src/main/cpp/ObjectManager.cpp index 189064f06..2aaa78c7e 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.cpp +++ b/test-app/runtime/src/main/cpp/ObjectManager.cpp @@ -273,8 +273,9 @@ bool ObjectManager::CloneLink(const Local &src, const Local &des if (success) { auto jsInfoIdx = static_cast(MetadataNodeKeys::JsInfo); - auto jsInfo = src->GetInternalField(jsInfoIdx); - dest->SetInternalField(jsInfoIdx, jsInfo); + // fetches the JSInstanceInfo again, but allows reusing the same v8::External + Local jsInfoExternal = src->GetInternalField(jsInfoIdx); + dest->SetInternalField(jsInfoIdx, jsInfoExternal); } return success; From f2d6cac00ec15f181cb16f44a20600e23a70d6e3 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Mon, 8 May 2023 12:35:56 -0700 Subject: [PATCH 03/23] chore: Remove dead code from ObjectManager These may be left over from previous refactorings. There are some methods of ObjectManager that are never used, some pieces of data that are stored but never read, and some fields that are never stored in the first place. --- test-app/runtime/CMakeLists.txt | 1 - .../runtime/src/main/cpp/CallbackHandlers.cpp | 7 +- .../runtime/src/main/cpp/DirectBuffer.cpp | 56 -------- test-app/runtime/src/main/cpp/DirectBuffer.h | 30 ---- .../runtime/src/main/cpp/JsArgConverter.cpp | 4 +- .../src/main/cpp/JsArgToArrayConverter.cpp | 3 +- .../runtime/src/main/cpp/ObjectManager.cpp | 128 ++---------------- test-app/runtime/src/main/cpp/ObjectManager.h | 86 +----------- test-app/runtime/src/main/cpp/Runtime.cpp | 15 +- test-app/runtime/src/main/cpp/Runtime.h | 4 +- .../runtime/src/main/cpp/com_tns_Runtime.cpp | 6 +- .../objects/JSToJavaObjectsConverter.cpp | 3 +- .../src/main/java/com/tns/Runtime.java | 60 +------- 13 files changed, 31 insertions(+), 372 deletions(-) delete mode 100644 test-app/runtime/src/main/cpp/DirectBuffer.cpp delete mode 100644 test-app/runtime/src/main/cpp/DirectBuffer.h diff --git a/test-app/runtime/CMakeLists.txt b/test-app/runtime/CMakeLists.txt index 60b0a1714..ed955bb6d 100644 --- a/test-app/runtime/CMakeLists.txt +++ b/test-app/runtime/CMakeLists.txt @@ -96,7 +96,6 @@ add_library( src/main/cpp/AssetExtractor.cpp src/main/cpp/CallbackHandlers.cpp src/main/cpp/Constants.cpp - src/main/cpp/DirectBuffer.cpp src/main/cpp/FieldAccessor.cpp src/main/cpp/File.cpp src/main/cpp/IsolateDisposer.cpp diff --git a/test-app/runtime/src/main/cpp/CallbackHandlers.cpp b/test-app/runtime/src/main/cpp/CallbackHandlers.cpp index 660c4c953..78aa52d73 100644 --- a/test-app/runtime/src/main/cpp/CallbackHandlers.cpp +++ b/test-app/runtime/src/main/cpp/CallbackHandlers.cpp @@ -86,7 +86,7 @@ bool CallbackHandlers::RegisterInstance(Isolate *isolate, const Local &j jint javaObjectID = objectManager->GenerateNewObjectID(); - objectManager->Link(jsObject, javaObjectID, nullptr); + objectManager->Link(jsObject, javaObjectID); // resolve constructor auto mi = MethodCache::ResolveConstructorSignature(argWrapper, fullClassName, @@ -118,10 +118,7 @@ bool CallbackHandlers::RegisterInstance(Isolate *isolate, const Local &j JniLocalRef localInstance(instance); success = !localInstance.IsNull(); - if (success) { - jclass instanceClass = env.FindClass(fullClassName); - objectManager->SetJavaClass(jsObject, instanceClass); - } else { + if (!success) { DEBUG_WRITE_FORCE("RegisterInstance failed with null new instance class: %s", fullClassName.c_str()); } diff --git a/test-app/runtime/src/main/cpp/DirectBuffer.cpp b/test-app/runtime/src/main/cpp/DirectBuffer.cpp deleted file mode 100644 index 1b3e6f8a3..000000000 --- a/test-app/runtime/src/main/cpp/DirectBuffer.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "DirectBuffer.h" -#include "JniLocalRef.h" - -using namespace tns; - -DirectBuffer::DirectBuffer(uint32_t length) { - m_length = length; - - m_data = new int[m_length]; - - m_end = m_data + m_length; - - Reset(); - - int capacity = m_length * sizeof(int); - - JEnv env; - JniLocalRef buff(env.NewDirectByteBuffer(m_data, capacity)); - - m_buff = env.NewGlobalRef(buff); -} - -DirectBuffer::operator jobject() const { - return m_buff; -} - -int* DirectBuffer::GetData() const { - return m_data; -} - -int DirectBuffer::Length() const { - return m_length; -} - -int DirectBuffer::Size() const { - return m_pos - m_data; -} - -void DirectBuffer::Reset() { - m_pos = m_data; -} - -bool DirectBuffer::Write(int value) { - bool canWrite = m_pos < m_end; - if (canWrite) { - int bigEndianInt = __builtin_bswap32(value); - *(m_pos++) = bigEndianInt; - } - return canWrite; -} - -DirectBuffer::~DirectBuffer() { - JEnv env; - env.DeleteGlobalRef(m_buff); - delete[] m_data; -} diff --git a/test-app/runtime/src/main/cpp/DirectBuffer.h b/test-app/runtime/src/main/cpp/DirectBuffer.h deleted file mode 100644 index 4de8a8a63..000000000 --- a/test-app/runtime/src/main/cpp/DirectBuffer.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef DIRECTBUFFER_H_ -#define DIRECTBUFFER_H_ - -#include "JEnv.h" - -namespace tns { -class DirectBuffer { - public: - DirectBuffer(uint32_t capacity = 65536); - ~DirectBuffer(); - - operator jobject() const; - - int* GetData() const; - int Length() const; - int Size() const; - - void Reset(); - bool Write(int value); - - private: - jobject m_buff; - int* m_data; - jlong m_length; - int* m_pos; - int* m_end; -}; -} - -#endif /* DIRECTBUFFER_H_ */ diff --git a/test-app/runtime/src/main/cpp/JsArgConverter.cpp b/test-app/runtime/src/main/cpp/JsArgConverter.cpp index 7de43e9b5..6f284f031 100644 --- a/test-app/runtime/src/main/cpp/JsArgConverter.cpp +++ b/test-app/runtime/src/main/cpp/JsArgConverter.cpp @@ -328,9 +328,7 @@ bool JsArgConverter::ConvertArg(const Local &arg, int index) { buffer = env.NewGlobalRef(buffer); jint id = objectManager->GetOrCreateObjectId(buffer); - auto clazz = env.GetObjectClass(buffer); - - objectManager->Link(jsObject, id, clazz); + objectManager->Link(jsObject, id); obj = objectManager->GetJavaObjectByJsObject(jsObject); } diff --git a/test-app/runtime/src/main/cpp/JsArgToArrayConverter.cpp b/test-app/runtime/src/main/cpp/JsArgToArrayConverter.cpp index 0e2360a01..5177e326d 100644 --- a/test-app/runtime/src/main/cpp/JsArgToArrayConverter.cpp +++ b/test-app/runtime/src/main/cpp/JsArgToArrayConverter.cpp @@ -332,8 +332,7 @@ bool JsArgToArrayConverter::ConvertArg(Local context, const LocalGetOrCreateObjectId(buffer); - auto clazz = env.GetObjectClass(buffer); - objectManager->Link(jsObj, id, clazz); + objectManager->Link(jsObj, id); obj = objectManager->GetJavaObjectByJsObject(jsObj); } diff --git a/test-app/runtime/src/main/cpp/ObjectManager.cpp b/test-app/runtime/src/main/cpp/ObjectManager.cpp index 2aaa78c7e..0933dcf77 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.cpp +++ b/test-app/runtime/src/main/cpp/ObjectManager.cpp @@ -18,7 +18,6 @@ using namespace tns; ObjectManager::ObjectManager(jobject javaRuntimeObject) : m_javaRuntimeObject(javaRuntimeObject), - m_numberOfGC(0), m_currentObjectId(0), m_cache(NewWeakGlobalRefCallback, DeleteWeakGlobalRefCallback, 1000, this) { @@ -35,10 +34,6 @@ ObjectManager::ObjectManager(jobject javaRuntimeObject) : "(Ljava/lang/Object;)I"); assert(GET_OR_CREATE_JAVA_OBJECT_ID_METHOD_ID != nullptr); - MAKE_INSTANCE_WEAK_BATCH_METHOD_ID = env.GetMethodID(runtimeClass, "makeInstanceWeak", - "(Ljava/nio/ByteBuffer;IZ)V"); - assert(MAKE_INSTANCE_WEAK_BATCH_METHOD_ID != nullptr); - MAKE_INSTANCE_WEAK_AND_CHECK_IF_ALIVE_METHOD_ID = env.GetMethodID(runtimeClass, "makeInstanceWeakAndCheckIfAlive", "(I)Z"); @@ -48,15 +43,10 @@ ObjectManager::ObjectManager(jobject javaRuntimeObject) : "(I)V"); assert(RELEASE_NATIVE_INSTANCE_METHOD_ID != nullptr); - CHECK_WEAK_OBJECTS_ARE_ALIVE_METHOD_ID = env.GetMethodID(runtimeClass, - "checkWeakObjectAreAlive", - "(Ljava/nio/ByteBuffer;Ljava/nio/ByteBuffer;I)V"); - assert(CHECK_WEAK_OBJECTS_ARE_ALIVE_METHOD_ID != nullptr); - - JAVA_LANG_CLASS = env.FindClass("java/lang/Class"); - assert(JAVA_LANG_CLASS != nullptr); + jclass javaLangClass = env.FindClass("java/lang/Class"); + assert(javaLangClass != nullptr); - GET_NAME_METHOD_ID = env.GetMethodID(JAVA_LANG_CLASS, "getName", "()Ljava/lang/String;"); + GET_NAME_METHOD_ID = env.GetMethodID(javaLangClass, "getName", "()Ljava/lang/String;"); assert(GET_NAME_METHOD_ID != nullptr); auto useGlobalRefsMethodID = env.GetStaticMethodID(runtimeClass, "useGlobalRefs", "()Z"); @@ -104,7 +94,6 @@ JniLocalRef ObjectManager::GetJavaObjectByJsObject(const Local &object) } ObjectManager::JSInstanceInfo *ObjectManager::GetJSInstanceInfo(const Local &object) { - JSInstanceInfo *jsInstanceInfo = nullptr; if (IsJsRuntimeObject(object)) { return GetJSInstanceInfoFromRuntimeObject(object); } @@ -157,24 +146,6 @@ jobject ObjectManager::GetJavaObjectByIDImpl(jint javaObjectID) { return object; } -void ObjectManager::UpdateCache(int objectID, jobject obj) { - m_cache.update(objectID, obj); -} - -jclass ObjectManager::GetJavaClass(const Local &instance) { - DEBUG_WRITE("GetClass called"); - - JSInstanceInfo *jsInfo = GetJSInstanceInfo(instance); - jclass clazz = jsInfo->ObjectClazz; - - return clazz; -} - -void ObjectManager::SetJavaClass(const Local &instance, jclass clazz) { - JSInstanceInfo *jsInfo = GetJSInstanceInfo(instance); - jsInfo->ObjectClazz = clazz; -} - jint ObjectManager::GetOrCreateObjectId(jobject object) { JEnv env; jint javaObjectID = env.CallIntMethod(m_javaRuntimeObject, @@ -222,9 +193,7 @@ ObjectManager::CreateJSWrapperHelper(jint javaObjectID, const string &typeName, auto jsWrapper = node->CreateJSWrapper(isolate, this); if (!jsWrapper.IsEmpty()) { - JEnv env; - auto claz = env.FindClass(className); - Link(jsWrapper, javaObjectID, claz); + Link(jsWrapper, javaObjectID); } return jsWrapper; } @@ -233,7 +202,7 @@ ObjectManager::CreateJSWrapperHelper(jint javaObjectID, const string &typeName, /* * * Link the JavaScript object and it's java counterpart with an ID */ -void ObjectManager::Link(const Local &object, jint javaObjectID, jclass clazz) { +void ObjectManager::Link(const Local &object, jint javaObjectID) { if (!IsJsRuntimeObject(object)) { string errMsg("Trying to link invalid 'this' to a Java object"); throw NativeScriptException(errMsg); @@ -244,10 +213,10 @@ void ObjectManager::Link(const Local &object, jint javaObjectID, jclass DEBUG_WRITE("Linking js object: %d and java instance id: %d", object->GetIdentityHash(), javaObjectID); - auto jsInstanceInfo = new JSInstanceInfo(false/*isJavaObjWeak*/, javaObjectID, clazz); + auto jsInstanceInfo = new JSInstanceInfo(false/*isJavaObjWeak*/, javaObjectID); auto objectHandle = new Persistent(isolate, object); - auto state = new ObjectWeakCallbackState(this, jsInstanceInfo, objectHandle); + auto state = new ObjectWeakCallbackState(this, objectHandle); // subscribe for JS GC event if (m_markingMode == JavaScriptMarkingMode::None) { @@ -382,9 +351,7 @@ void ObjectManager::JSObjectWeakCallback(Isolate *isolate, ObjectWeakCallbackSta DEBUG_WRITE("JSObjectWeakCallback objectId: %d, hasImplObj=%d", javaObjectID, hasImplObj); if (hasImplObj) { - if (jsInstanceInfo->IsJavaObjectWeak) { - m_implObjWeak.emplace_back(po, javaObjectID); - } else { + if (!jsInstanceInfo->IsJavaObjectWeak) { m_implObjStrong.insert(make_pair(javaObjectID, po)); jsInstanceInfo->IsJavaObjectWeak = true; } @@ -394,7 +361,7 @@ void ObjectManager::JSObjectWeakCallback(Isolate *isolate, ObjectWeakCallbackSta // to the V8 GC is done only on the markSweepCompact phase. The JSObjectWeakCallback // however is still triggered in other V8 GC phases (scavenger for example). This // creates a problem that there is no 'top' on the m_markedForGC stack. - GarbageCollectionInfo gcInfo(++m_numberOfGC); + GarbageCollectionInfo gcInfo; gcInfo.markedForGC.push_back(po); m_markedForGC.push(gcInfo); } else { @@ -415,79 +382,6 @@ jint ObjectManager::GenerateNewObjectID() { return oldValue; } -void ObjectManager::ReleaseJSInstance(Persistent *po, JSInstanceInfo *jsInstanceInfo) { - jint javaObjectID = jsInstanceInfo->JavaObjectID; - - auto it = m_idToObject.find(javaObjectID); - - if (it == m_idToObject.end()) { - stringstream ss; - ss << "(InternalError): Js object with id: " << javaObjectID << " not found"; - throw NativeScriptException(ss.str()); - } - - assert(po == it->second); - - m_idToObject.erase(it); - m_released.insert(po, javaObjectID); - po->Reset(); - - delete po; - delete jsInstanceInfo; - - DEBUG_WRITE("ReleaseJSObject instance disposed. id:%d", javaObjectID); -} - -/* - * The "regular" JS objects added on ObjectManager::JSObjectWeakCallback are dealt with(released) here. - * */ -void ObjectManager::ReleaseRegularObjects() { - TNSPERF(); - - HandleScope handleScope(m_isolate); - - auto propName = String::NewFromUtf8(m_isolate, "t::gcNum", - NewStringType::kNormal).ToLocalChecked(); - - auto &topGCInfo = m_markedForGC.top(); - auto &marked = topGCInfo.markedForGC; - int numberOfGC = topGCInfo.numberOfGC; - - for (auto po : marked) { - if (m_released.contains(po)) { - continue; - } - - auto obj = Local::New(m_isolate, *po); - - assert(!obj.IsEmpty()); - - Local gcNum; - V8GetPrivateValue(m_isolate, obj, propName, gcNum); - - bool isReachableFromImplementationObject = false; - - if (!gcNum.IsEmpty() && gcNum->IsNumber()) { - double objGcNum = gcNum.As()->Value(); - - // done so we can release only java objects from this GC stack and pass all objects that will be released in parent GC stacks - isReachableFromImplementationObject = objGcNum >= numberOfGC; - } - - JSInstanceInfo *jsInstanceInfo = GetJSInstanceInfo(obj); - - if (!isReachableFromImplementationObject) { - if (!jsInstanceInfo->IsJavaObjectWeak) { - jsInstanceInfo->IsJavaObjectWeak = true; - - ReleaseJSInstance(po, jsInstanceInfo); - } - } - } - - marked.clear(); -} - bool ObjectManager::HasImplObject(Isolate *isolate, const Local &obj) { auto implObject = MetadataNode::GetImplementationObject(isolate, obj); @@ -507,9 +401,7 @@ jweak ObjectManager::NewWeakGlobalRefCallback(const jint &javaObjectID, void *st return weakRef; } -void ObjectManager::DeleteWeakGlobalRefCallback(const jweak &object, void *state) { - auto objManager = reinterpret_cast(state); - +void ObjectManager::DeleteWeakGlobalRefCallback(const jweak &object, [[maybe_unused]] void *state) { JEnv env; env.DeleteWeakGlobalRef(object); } diff --git a/test-app/runtime/src/main/cpp/ObjectManager.h b/test-app/runtime/src/main/cpp/ObjectManager.h index 2ed51b525..82cfc9f3a 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.h +++ b/test-app/runtime/src/main/cpp/ObjectManager.h @@ -5,7 +5,6 @@ #include "JEnv.h" #include "JniLocalRef.h" #include "ArgsWrapper.h" -#include "DirectBuffer.h" #include "LRUCache.h" #include #include @@ -22,11 +21,6 @@ class ObjectManager { JniLocalRef GetJavaObjectByJsObject(const v8::Local& object); - void UpdateCache(int objectID, jobject obj); - - jclass GetJavaClass(const v8::Local& instance); - - void SetJavaClass(const v8::Local& instance, jclass clazz); jint GetOrCreateObjectId(jobject object); v8::Local GetJsObjectByJavaObject(jint javaObjectID); @@ -35,7 +29,7 @@ class ObjectManager { v8::Local CreateJSWrapper(jint javaObjectID, const std::string& typeName, jobject instance); - void Link(const v8::Local& object, jint javaObjectID, jclass clazz); + void Link(const v8::Local& object, jint javaObjectID); void ReleaseNativeCounterpart(v8::Local& object); @@ -81,84 +75,31 @@ class ObjectManager { struct JSInstanceInfo { public: - JSInstanceInfo(bool isJavaObjectWeak, jint javaObjectID, jclass claz) - :IsJavaObjectWeak(isJavaObjectWeak), JavaObjectID(javaObjectID), ObjectClazz(claz) { + JSInstanceInfo(bool isJavaObjectWeak, jint javaObjectID) + : IsJavaObjectWeak(isJavaObjectWeak), JavaObjectID(javaObjectID) { } bool IsJavaObjectWeak; jint JavaObjectID; - jclass ObjectClazz; }; struct ObjectWeakCallbackState { - ObjectWeakCallbackState(ObjectManager* _thisPtr, JSInstanceInfo* _jsInfo, v8::Persistent* _target) - : - thisPtr(_thisPtr), jsInfo(_jsInfo), target(_target) { + ObjectWeakCallbackState(ObjectManager* _thisPtr, v8::Persistent* _target) + : thisPtr(_thisPtr), target(_target) { } ObjectManager* thisPtr; - JSInstanceInfo* jsInfo; v8::Persistent* target; }; struct GarbageCollectionInfo { - GarbageCollectionInfo(int _numberOfGC) - : - numberOfGC(_numberOfGC) { - } std::vector*> markedForGC; - int numberOfGC; - }; - - class PersistentObjectIdSet { - public: - PersistentObjectIdSet() { - /* TODO: use functors */ - } - - void clear() { - m_POs.clear(); - m_IDs.clear(); - } - - void insert(v8::Persistent* po, jint javaObjectId) { - m_POs.insert(po); - m_IDs.insert(javaObjectId); - } - - bool contains(v8::Persistent* po) { - return m_POs.find(po) != m_POs.end(); - } - - std::set*> m_POs; - std::set m_IDs; - }; - - struct PersistentObjectIdPair { - PersistentObjectIdPair(v8::Persistent* _po, jint _javaObjectId) - : - po(_po), javaObjectId(_javaObjectId) { - } - v8::Persistent* po; - jint javaObjectId; }; - - JSInstanceInfo* GetJSInstanceInfo(const v8::Local& object); JSInstanceInfo* GetJSInstanceInfoFromRuntimeObject(const v8::Local& object); - void ReleaseJSInstance(v8::Persistent* po, JSInstanceInfo* jsInstanceInfo); - - void ReleaseRegularObjects(); - - void MakeRegularObjectsWeak(const std::set& instances, DirectBuffer& inputBuff); - - void MakeImplObjectsWeak(const std::unordered_map*>& instances, DirectBuffer& inputBuff); - - void CheckWeakObjectsAreAlive(const std::vector& instances, DirectBuffer& inputBuff, DirectBuffer& outputBuff); - v8::Local CreateJSWrapperHelper(jint javaObjectID, const std::string& typeName, jclass clazz); static void JSObjectWeakCallbackStatic(const v8::WeakCallbackInfo& data); @@ -183,50 +124,33 @@ class ObjectManager { jobject m_javaRuntimeObject; - int m_numberOfGC; - v8::Isolate* m_isolate; std::stack m_markedForGC; std::unordered_map*> m_idToObject; - PersistentObjectIdSet m_released; - - std::set m_visited; - LRUCache m_cache; std::set*> m_visitedPOs; - std::vector m_implObjWeak; std::unordered_map*> m_implObjStrong; volatile jint m_currentObjectId; - DirectBuffer m_buff; - - DirectBuffer m_outBuff; - bool m_useGlobalRefs; JavaScriptMarkingMode m_markingMode; - jclass JAVA_LANG_CLASS; - jmethodID GET_NAME_METHOD_ID; jmethodID GET_JAVAOBJECT_BY_ID_METHOD_ID; jmethodID GET_OR_CREATE_JAVA_OBJECT_ID_METHOD_ID; - jmethodID MAKE_INSTANCE_WEAK_BATCH_METHOD_ID; - jmethodID MAKE_INSTANCE_WEAK_AND_CHECK_IF_ALIVE_METHOD_ID; jmethodID RELEASE_NATIVE_INSTANCE_METHOD_ID; - jmethodID CHECK_WEAK_OBJECTS_ARE_ALIVE_METHOD_ID; - v8::Persistent* m_poJsWrapperFunc; }; } diff --git a/test-app/runtime/src/main/cpp/Runtime.cpp b/test-app/runtime/src/main/cpp/Runtime.cpp index bc849d453..af41fc94a 100644 --- a/test-app/runtime/src/main/cpp/Runtime.cpp +++ b/test-app/runtime/src/main/cpp/Runtime.cpp @@ -296,7 +296,7 @@ jobject Runtime::RunScript(JNIEnv* _env, jobject obj, jstring scriptFile) { return res; } -jobject Runtime::CallJSMethodNative(JNIEnv* _env, jobject obj, jint javaObjectID, jstring methodName, jint retType, jboolean isConstructor, jobjectArray packagedArgs) { +jobject Runtime::CallJSMethodNative(JNIEnv* _env, jobject obj, jint javaObjectID, jstring methodName, jint retType, jobjectArray packagedArgs) { SET_PROFILER_FRAME(); auto isolate = m_isolate; @@ -314,12 +314,6 @@ jobject Runtime::CallJSMethodNative(JNIEnv* _env, jobject obj, jint javaObjectID throw NativeScriptException(ss.str()); } - if (isConstructor) { - DEBUG_WRITE("CallJSMethodNative: Updating linked instance with its real class"); - jclass instanceClass = env.GetObjectClass(obj); - m_objectManager->SetJavaClass(jsObject, instanceClass); - } - DEBUG_WRITE("CallJSMethodNative called jsObject=%d", jsObject->GetIdentityHash()); string method_name = ArgConverter::jstringToString(methodName); @@ -330,15 +324,13 @@ jobject Runtime::CallJSMethodNative(JNIEnv* _env, jobject obj, jint javaObjectID return javaObject; } -void Runtime::CreateJSInstanceNative(JNIEnv* _env, jobject obj, jobject javaObject, jint javaObjectID, jstring className) { +void Runtime::CreateJSInstanceNative(jobject obj, jobject javaObject, jint javaObjectID, jstring className) { SET_PROFILER_FRAME(); DEBUG_WRITE("createJSInstanceNative called"); auto isolate = m_isolate; - JEnv env(_env); - string existingClassName = ArgConverter::jstringToString(className); string jniName = Util::ConvertFromCanonicalToJniName(existingClassName); Local jsInstance; @@ -359,8 +351,7 @@ void Runtime::CreateJSInstanceNative(JNIEnv* _env, jobject obj, jobject javaObje } DEBUG_WRITE("createJSInstanceNative: implementationObject :%d", implementationObject->GetIdentityHash()); - jclass clazz = env.FindClass(jniName); - m_objectManager->Link(jsInstance, javaObjectID, clazz); + m_objectManager->Link(jsInstance, javaObjectID); } jint Runtime::GenerateNewObjectId(JNIEnv* env, jobject obj) { diff --git a/test-app/runtime/src/main/cpp/Runtime.h b/test-app/runtime/src/main/cpp/Runtime.h index 7ffd17eb9..2d042d0fd 100644 --- a/test-app/runtime/src/main/cpp/Runtime.h +++ b/test-app/runtime/src/main/cpp/Runtime.h @@ -52,8 +52,8 @@ class Runtime { void RunModule(JNIEnv* _env, jobject obj, jstring scriptFile); void RunWorker(jstring scriptFile); jobject RunScript(JNIEnv* _env, jobject obj, jstring scriptFile); - jobject CallJSMethodNative(JNIEnv* _env, jobject obj, jint javaObjectID, jstring methodName, jint retType, jboolean isConstructor, jobjectArray packagedArgs); - void CreateJSInstanceNative(JNIEnv* _env, jobject obj, jobject javaObject, jint javaObjectID, jstring className); + jobject CallJSMethodNative(JNIEnv* _env, jobject obj, jint javaObjectID, jstring methodName, jint retType, jobjectArray packagedArgs); + void CreateJSInstanceNative(jobject obj, jobject javaObject, jint javaObjectID, jstring className); jint GenerateNewObjectId(JNIEnv* env, jobject obj); void AdjustAmountOfExternalAllocatedMemory(); bool NotifyGC(JNIEnv* env, jobject obj); diff --git a/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp b/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp index 01777f9ab..836c1fe76 100644 --- a/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp +++ b/test-app/runtime/src/main/cpp/com_tns_Runtime.cpp @@ -155,7 +155,7 @@ extern "C" JNIEXPORT jobject Java_com_tns_Runtime_runScript(JNIEnv* _env, jobjec return result; } -extern "C" JNIEXPORT jobject Java_com_tns_Runtime_callJSMethodNative(JNIEnv* _env, jobject obj, jint runtimeId, jint javaObjectID, jstring methodName, jint retType, jboolean isConstructor, jobjectArray packagedArgs) { +extern "C" JNIEXPORT jobject Java_com_tns_Runtime_callJSMethodNative(JNIEnv* _env, jobject obj, jint runtimeId, jint javaObjectID, jstring methodName, jint retType, jobjectArray packagedArgs) { jobject result = nullptr; auto runtime = TryGetRuntime(runtimeId); @@ -171,7 +171,7 @@ extern "C" JNIEXPORT jobject Java_com_tns_Runtime_callJSMethodNative(JNIEnv* _en v8::Context::Scope context_scope(context); try { - result = runtime->CallJSMethodNative(_env, obj, javaObjectID, methodName, retType, isConstructor, packagedArgs); + result = runtime->CallJSMethodNative(_env, obj, javaObjectID, methodName, retType, packagedArgs); } catch (NativeScriptException& e) { e.ReThrowToJava(); } catch (std::exception e) { @@ -200,7 +200,7 @@ extern "C" JNIEXPORT void Java_com_tns_Runtime_createJSInstanceNative(JNIEnv* _e v8::Context::Scope context_scope(context); try { - runtime->CreateJSInstanceNative(_env, obj, javaObject, javaObjectID, className); + runtime->CreateJSInstanceNative(obj, javaObject, javaObjectID, className); } catch (NativeScriptException& e) { e.ReThrowToJava(); } catch (std::exception e) { diff --git a/test-app/runtime/src/main/cpp/conversions/objects/JSToJavaObjectsConverter.cpp b/test-app/runtime/src/main/cpp/conversions/objects/JSToJavaObjectsConverter.cpp index 2a8781512..72f907174 100644 --- a/test-app/runtime/src/main/cpp/conversions/objects/JSToJavaObjectsConverter.cpp +++ b/test-app/runtime/src/main/cpp/conversions/objects/JSToJavaObjectsConverter.cpp @@ -211,8 +211,7 @@ bool tns::ConvertJavaScriptObject( buffer = env.NewGlobalRef(buffer); jint id = objectManager->GetOrCreateObjectId(buffer); - auto clazz = env.GetObjectClass(buffer); - objectManager->Link(jsObject, id, clazz); + objectManager->Link(jsObject, id); obj = objectManager->GetJavaObjectByJsObject(jsObject); } diff --git a/test-app/runtime/src/main/java/com/tns/Runtime.java b/test-app/runtime/src/main/java/com/tns/Runtime.java index ad8caed91..c5651a997 100644 --- a/test-app/runtime/src/main/java/com/tns/Runtime.java +++ b/test-app/runtime/src/main/java/com/tns/Runtime.java @@ -46,7 +46,7 @@ private native void initNativeScript(int runtimeId, String filesPath, String nat private native Object runScript(int runtimeId, String filePath) throws NativeScriptException; - private native Object callJSMethodNative(int runtimeId, int javaObjectID, String methodName, int retType, boolean isConstructor, Object... packagedArgs) throws NativeScriptException; + private native Object callJSMethodNative(int runtimeId, int javaObjectID, String methodName, int retType, Object... packagedArgs) throws NativeScriptException; private native void createJSInstanceNative(int runtimeId, Object javaObject, int javaObjectID, String canonicalName); @@ -969,30 +969,6 @@ private void makeInstanceStrong(Object instance, int objectId) { } } - private void makeInstanceWeak(int javaObjectID, boolean keepAsWeak) { - if (logger.isEnabled()) { - logger.write("makeInstanceWeak instance " + javaObjectID + " keepAsWeak=" + keepAsWeak); - } - Object instance = strongInstances.get(javaObjectID); - - if (keepAsWeak) { - weakJavaObjectToID.put(instance, Integer.valueOf(javaObjectID)); - weakInstances.put(javaObjectID, new WeakReference(instance)); - } - - strongInstances.remove(javaObjectID); - strongJavaObjectToID.remove(instance); - } - - @RuntimeCallable - private void makeInstanceWeak(ByteBuffer buff, int length, boolean keepAsWeak) { - buff.position(0); - for (int i = 0; i < length; i++) { - int javaObjectId = buff.getInt(); - makeInstanceWeak(javaObjectId, keepAsWeak); - } - } - @RuntimeCallable private boolean makeInstanceWeakAndCheckIfAlive(int javaObjectID) { if (logger.isEnabled()) { @@ -1025,34 +1001,6 @@ private boolean makeInstanceWeakAndCheckIfAlive(int javaObjectID) { } } - @RuntimeCallable - private void checkWeakObjectAreAlive(ByteBuffer input, ByteBuffer output, int length) { - input.position(0); - output.position(0); - for (int i = 0; i < length; i++) { - int javaObjectId = input.getInt(); - - WeakReference weakRef = weakInstances.get(javaObjectId); - - int isReleased; - - if (weakRef != null) { - Object instance = weakRef.get(); - - if (instance == null) { - isReleased = 1; - weakInstances.remove(javaObjectId); - } else { - isReleased = 0; - } - } else { - isReleased = (strongInstances.get(javaObjectId) == null) ? 1 : 0; - } - - output.putInt(isReleased); - } - } - @RuntimeCallable private Object getJavaObjectByID(int javaObjectID) throws Exception { if (logger.isEnabled()) { @@ -1298,7 +1246,7 @@ private Object dispatchCallJSMethodNative(final int javaObjectID, final String m if (enableMultithreadedJavascript || isWorkThread) { Object[] packagedArgs = packageArgs(tmpArgs); try { - ret = callJSMethodNative(getRuntimeId(), javaObjectID, methodName, returnType, isConstructor, packagedArgs); + ret = callJSMethodNative(getRuntimeId(), javaObjectID, methodName, returnType, packagedArgs); } catch (NativeScriptException e) { if (discardUncaughtJsExceptions) { String errorMessage = "Error on \"" + Thread.currentThread().getName() + "\" thread for callJSMethodNative\n"; @@ -1311,15 +1259,13 @@ private Object dispatchCallJSMethodNative(final int javaObjectID, final String m } else { final Object[] arr = new Object[2]; - final boolean isCtor = isConstructor; - Runnable r = new Runnable() { @Override public void run() { synchronized (this) { try { final Object[] packagedArgs = packageArgs(tmpArgs); - arr[0] = callJSMethodNative(getRuntimeId(), javaObjectID, methodName, returnType, isCtor, packagedArgs); + arr[0] = callJSMethodNative(getRuntimeId(), javaObjectID, methodName, returnType, packagedArgs); } catch (NativeScriptException e) { if (discardUncaughtJsExceptions) { String errorMessage = "Error on \"" + Thread.currentThread().getName() + "\" thread for callJSMethodNative\n"; From 29311b232facc774e4203f9fcee4fe7e61672090 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Mon, 8 May 2023 12:02:15 -0700 Subject: [PATCH 04/23] feat: Remove markingMode BREAKING CHANGE: The "markingMode" configuration option in package.json no longer has any effect. It is always set to "none", which was already the default. "markingMode": "full" will be ignored. BREAKING CHANGE: The `__markingMode` global variable no longer exists. Removing support for full marking mode allows removing a big chunk of GC finalizer code, which would otherwise need to be ported to CPPGC. --- test-app/app/src/main/assets/app/mainpage.js | 1 - test-app/app/src/main/assets/app/package.json | 1 - .../app/src/main/assets/app/tests/testGC.js | 320 ------------------ .../runtime/src/main/cpp/ObjectManager.cpp | 90 +---- test-app/runtime/src/main/cpp/ObjectManager.h | 41 +-- test-app/runtime/src/main/cpp/Runtime.cpp | 1 - .../src/main/java/com/tns/AppConfig.java | 17 - .../src/main/java/com/tns/MarkingMode.java | 9 - .../src/main/java/com/tns/Runtime.java | 9 - 9 files changed, 4 insertions(+), 485 deletions(-) delete mode 100644 test-app/app/src/main/assets/app/tests/testGC.js delete mode 100644 test-app/runtime/src/main/java/com/tns/MarkingMode.java diff --git a/test-app/app/src/main/assets/app/mainpage.js b/test-app/app/src/main/assets/app/mainpage.js index 287bf2cb8..7c9355b21 100644 --- a/test-app/app/src/main/assets/app/mainpage.js +++ b/test-app/app/src/main/assets/app/mainpage.js @@ -40,7 +40,6 @@ require("./tests/discardedExceptionsTest"); require("./tests/dispatchCallbacksOnUiThreadTests"); require("./tests/stringConversionTests"); require("./tests/testsForTypescript"); -require("./tests/testGC"); require("./tests/testsMemoryManagement"); require("./tests/testFieldGetSet"); require("./tests/extendedClassesTests"); diff --git a/test-app/app/src/main/assets/app/package.json b/test-app/app/src/main/assets/app/package.json index cc5e7badd..52cee3369 100644 --- a/test-app/app/src/main/assets/app/package.json +++ b/test-app/app/src/main/assets/app/package.json @@ -6,7 +6,6 @@ "gcThrottleTime": 500, "memoryCheckInterval": 10, "freeMemoryRatio": 0.50, - "markingMode": "none", "maxLogcatObjectSize": 1024, "forceLog": false, "suppressCallJSMethodExceptions": false, diff --git a/test-app/app/src/main/assets/app/tests/testGC.js b/test-app/app/src/main/assets/app/tests/testGC.js deleted file mode 100644 index 89e337625..000000000 --- a/test-app/app/src/main/assets/app/tests/testGC.js +++ /dev/null @@ -1,320 +0,0 @@ -// Run GC tests only in Full marking mode -let describeFunc = __markingMode == 0 ? describe : xdescribe; - -describeFunc("Tests garbage collection", function () { - var myCustomEquality = function(first, second) { - return first == second; - }; - - beforeEach(function() { - jasmine.addCustomEqualityTester(myCustomEquality); - }); - - xit("TestGarbageCollection", function (done) { - var normalTest = function () { - - __log("TEST: TestGarbageCollection"); - - var obj = new com.tns.tests.ClassX(); - - obj.dummy(); - - obj = null; - - gc(); - java.lang.System.gc(); - gc(); - java.lang.System.gc(); - gc(); - java.lang.System.gc(); - - new java.lang.Thread(new java.lang.Runnable("ThreadFunc", { - run: function() { - var isCollected = com.tns.tests.ClassX.IsCollected; - __log('----------> isCollected: ' + isCollected); - expect(isCollected).toBe(true); - done(); - } - })).start(); - }; - normalTest(); - }); - - // this test has implicit assert in com.tns.Runtime.getJavaObjectByID method - it("test1", function () { - - function createObjects(name) { - var c1 = new com.tns.tests.Class1(); - - var cb1 = new com.tns.tests.Class1.Callback1(name, { - getMessage: function() { - var msg = c1.getMessage(); - return msg; - } - }); - - return com.tns.tests.Class1.Class2.printMessageWithDelay(cb1, 5 * 1000); - } - - expect(createObjects("Callback5")).toBe(true); - expect(createObjects("Callback26")).toBe(true); - - gc(); - java.lang.System.gc(); - }); - - // this test has implicit assert in com.tns.Runtime.getJavaObjectByID method - it("test2", function () { - - function indref1() { - this.class1 = new com.tns.tests.Class1(); - } - indref1.prototype.getMessage = function() { - return "~~~" + this.class1.getMessage(); - } - - function createObjects(name) { - var c1 = new indref1(); - - var cb1 = new com.tns.tests.Class1.Callback1(name, { - getMessage: function() { - var msg = c1.getMessage(); - return msg; - } - }); - - return com.tns.tests.Class1.Class2.printMessageWithDelay(cb1, 5 * 1000); - } - - expect(createObjects("Callback55")).toBe(true); - expect(createObjects("Callback56")).toBe(true); - gc(); - java.lang.System.gc(); - }); - - // this test has implicit assert in com.tns.Runtime.getJavaObjectByID method - it("test3", function () { - - function indref2() { - this.helper = new indref2helper(); - } - indref2.prototype.getMessage = function() { - return "---" + this.helper.getMessage(); - } - function indref2helper() { - this.class1 = new com.tns.tests.Class1(); - } - indref2helper.prototype.getMessage = function() { - return "***" + this.class1.getMessage(); - } - - function createObjects(name) { - var c1 = new indref2(); - - var cb1 = new com.tns.tests.Class1.Callback1(name, { - getMessage: function() { - var msg = c1.getMessage(); - return msg; - } - }); - - return com.tns.tests.Class1.Class2.printMessageWithDelay(cb1, 5 * 1000); - } - - expect(createObjects("Callback91")).toBe(true); - expect(createObjects("Callback92")).toBe(true); - gc(); - java.lang.System.gc(); - }); - - // this test has implicit assert in com.tns.Runtime.getJavaObjectByID method - it("test4", function () { - - function indref3() { - this.helper = new indref3helper(); - } - indref3.prototype.getMessage = function() { - return "+++" + this.helper.getMessage(); - } - function indref3helper() { - this._class1 = new com.tns.tests.Class1(); - - Object.defineProperty(this, "class1", { - get: function() { - return this._class1 - } - }); - } - indref3helper.prototype.getMessage = function() { - return "^^^" + this.class1.getMessage(); - } - - function createObjects(name) { - var c1 = new indref3(); - - var cb1 = new com.tns.tests.Class1.Callback1(name, { - getMessage: function() { - var msg = c1.getMessage(); - return msg; - } - }); - - return com.tns.tests.Class1.Class2.printMessageWithDelay(cb1, 5 * 1000); - } - - expect(createObjects("Callback1133")).toBe(true); - expect(createObjects("Callback1134")).toBe(true); - gc(); - java.lang.System.gc(); - }); - - // this test has implicit assert in com.tns.Runtime.getJavaObjectByID method - //originally test was commented out - xit("test5", function () { - - function indref4() { - this.helper = new indref4helper(); - } - indref4.prototype.getMessage = function() { - return "&&&" + this.helper.getMessageZZZ(); - } - function indref4helper() { - var _class1 = new com.tns.tests.Class1(); - - __log("indref4helper _class1=" + _class1); - - Object.defineProperty(this, "class1", { - get: function() { - return _class1 - } - ,enumerable: false - }); - } - indref4helper.prototype.getMessageZZZ = function() { - return "```" + this.class1.getMessage(); - } - - function createObjects(name) { - var c1 = new indref4(); - - var cb1 = new com.tns.tests.Class1.Callback1(name, { - getMessage: function() { - var msg = c1.getMessage(); - return msg; - } - }); - - return com.tns.tests.Class1.Class2.printMessageWithDelay(cb1, 5 * 1000); - } - - expect(createObjects("Callback1178")).toBe(true); - expect(createObjects("Callback1179")).toBe(true); - gc(); - java.lang.System.gc(); - }); - - it("testAccessingStringFieldWontLeak", function () { - - __log("TEST: testAccessingStringFieldWontLeak"); - - var dummy = new com.tns.tests.DummyClass(); - - for (var i=0; i<10000; i++) - { - var name = dummy.nameField; - - expect(name).toBe("dummy"); - } - }); - - xit("should persist JavaScript object when it reappears after GC", function () { - - function getObject() { - var o = new java.lang.Object(); - o.x = 123; - var arr = java.lang.reflect.Array.newInstance(java.lang.Object.class, 1); - arr[0] = o; - return arr; - } - - var arr = getObject(); - gc(); - var o = arr[0]; - - expect(o.x).toBe(123); - }); - - it("should keep extended instances alive after GC", function () { - var C1 = com.tns.tests.Class1.extend({}); - - function createObjects(name) { - var c1 = new C1(); - - var cb1 = new com.tns.tests.Class1.Callback1(name, { - getMessage: function() { - var msg = c1.getMessage(); - return msg; - } - }); - - return com.tns.tests.Class1.Class2.printMessageWithDelay(cb1, 5 * 1000); - } - - expect(createObjects("Callback452356")).toBe(true); - expect(createObjects("Callback417892")).toBe(true); - - gc(); - java.lang.System.gc(); - }); - - it("should keep array-enclosed objects alive after GC", function () { - function createObjects(name) { - var arr = new Array(); - arr.push(new com.tns.tests.Class1()); - - var cb1 = new com.tns.tests.Class1.Callback1(name, { - getMessage: function() { - var msg = arr[0].getMessage(); - return msg; - } - }); - - return com.tns.tests.Class1.Class2.printMessageWithDelay(cb1, 2 * 1000); - } - - expect(createObjects("Callback1")).toBe(true); - expect(createObjects("Callback2")).toBe(true); - expect(createObjects("Callback3")).toBe(true); - - gc(); - java.lang.System.gc(); - }) - - it("should properly reintroduce Java object back in a callback", function () { - function getTestObject() { - return new com.tns.tests.BadEqualsTest( - new com.tns.tests.BadEqualsTest.BadEqualsObject(), - new com.tns.tests.BadEqualsTest.Callback({ - onFinish: function(o) { - __log(">>o=" + o.toString()); - } - })); - } - - var test = getTestObject(); - - // flush LRU cache - for (var i=0; i<65536; i++) { - new java.lang.Object().hashCode(); - } - - gc(); - java.lang.Runtime.getRuntime().gc(); - gc(); - java.lang.Runtime.getRuntime().gc(); - gc(); - java.lang.Runtime.getRuntime().gc(); - - test.postCallback(); - }); -}); \ No newline at end of file diff --git a/test-app/runtime/src/main/cpp/ObjectManager.cpp b/test-app/runtime/src/main/cpp/ObjectManager.cpp index 0933dcf77..a69d62d6c 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.cpp +++ b/test-app/runtime/src/main/cpp/ObjectManager.cpp @@ -54,11 +54,6 @@ ObjectManager::ObjectManager(jobject javaRuntimeObject) : auto useGlobalRefs = env.CallStaticBooleanMethod(runtimeClass, useGlobalRefsMethodID); m_useGlobalRefs = useGlobalRefs == JNI_TRUE; - - auto getMarkingModeOrdinalMethodID = env.GetMethodID(runtimeClass, "getMarkingModeOrdinal", - "()I"); - jint markingMode = env.CallIntMethod(m_javaRuntimeObject, getMarkingModeOrdinalMethodID); - m_markingMode = static_cast(markingMode); } void ObjectManager::SetInstanceIsolate(Isolate *isolate) { @@ -213,17 +208,13 @@ void ObjectManager::Link(const Local &object, jint javaObjectID) { DEBUG_WRITE("Linking js object: %d and java instance id: %d", object->GetIdentityHash(), javaObjectID); - auto jsInstanceInfo = new JSInstanceInfo(false/*isJavaObjWeak*/, javaObjectID); + auto jsInstanceInfo = new JSInstanceInfo(javaObjectID); auto objectHandle = new Persistent(isolate, object); auto state = new ObjectWeakCallbackState(this, objectHandle); // subscribe for JS GC event - if (m_markingMode == JavaScriptMarkingMode::None) { - objectHandle->SetWeak(state, JSObjectFinalizerStatic, WeakCallbackType::kFinalizer); - } else { - objectHandle->SetWeak(state, JSObjectWeakCallbackStatic, WeakCallbackType::kFinalizer); - } + objectHandle->SetWeak(state, JSObjectFinalizerStatic, WeakCallbackType::kFinalizer); auto jsInfoIdx = static_cast(MetadataNodeKeys::JsInfo); @@ -268,17 +259,6 @@ string ObjectManager::GetClassName(jclass clazz) { return className; } -void -ObjectManager::JSObjectWeakCallbackStatic(const WeakCallbackInfo &data) { - ObjectWeakCallbackState *callbackState = data.GetParameter(); - - ObjectManager *thisPtr = callbackState->thisPtr; - - auto isolate = data.GetIsolate(); - - thisPtr->JSObjectWeakCallback(isolate, callbackState); -} - void ObjectManager::JSObjectFinalizerStatic(const WeakCallbackInfo &data) { ObjectWeakCallbackState *callbackState = data.GetParameter(); @@ -321,60 +301,6 @@ void ObjectManager::JSObjectFinalizer(Isolate *isolate, ObjectWeakCallbackState } } - -/* - * When JS GC happens change state of the java counterpart to mirror state of JS object and REVIVE the JS object unconditionally - * "Regular" js objects are pushed into the "regular objects" array - * "Callback" js objects (ones that have implementation object) are pushed into two "special objects" array: - * -ones called for the first time which are originally strong in java - * -ones called for the second or next time which are already weak in java too - * These objects are categorized by "regular" and "callback" and saved in different arrays for performance optimizations during GC - * */ -void ObjectManager::JSObjectWeakCallback(Isolate *isolate, ObjectWeakCallbackState *callbackState) { - HandleScope handleScope(isolate); - - Persistent *po = callbackState->target; - - auto itFound = m_visitedPOs.find(po); - - if (itFound == m_visitedPOs.end()) { - m_visitedPOs.insert(po); - - auto obj = Local::New(isolate, *po); - JSInstanceInfo *jsInstanceInfo = GetJSInstanceInfo(obj); - - if(jsInstanceInfo != nullptr){ - int javaObjectID = jsInstanceInfo->JavaObjectID; - - bool hasImplObj = HasImplObject(isolate, obj); - - DEBUG_WRITE("JSObjectWeakCallback objectId: %d, hasImplObj=%d", javaObjectID, hasImplObj); - - if (hasImplObj) { - if (!jsInstanceInfo->IsJavaObjectWeak) { - m_implObjStrong.insert(make_pair(javaObjectID, po)); - jsInstanceInfo->IsJavaObjectWeak = true; - } - } else { - if(m_markedForGC.empty()){ - // Emulates the behavior in the OnGcStarted callback. Đ¢his is necessary as the hooking - // to the V8 GC is done only on the markSweepCompact phase. The JSObjectWeakCallback - // however is still triggered in other V8 GC phases (scavenger for example). This - // creates a problem that there is no 'top' on the m_markedForGC stack. - GarbageCollectionInfo gcInfo; - gcInfo.markedForGC.push_back(po); - m_markedForGC.push(gcInfo); - } else { - auto &topGCInfo = m_markedForGC.top(); - topGCInfo.markedForGC.push_back(po); - } - } - } - } - - po->SetWeak(callbackState, JSObjectWeakCallbackStatic, WeakCallbackType::kFinalizer); -} - jint ObjectManager::GenerateNewObjectID() { const jint one = 1; jint oldValue = __sync_fetch_and_add(&m_currentObjectId, one); @@ -382,14 +308,6 @@ jint ObjectManager::GenerateNewObjectID() { return oldValue; } -bool ObjectManager::HasImplObject(Isolate *isolate, const Local &obj) { - auto implObject = MetadataNode::GetImplementationObject(isolate, obj); - - bool hasImplObj = !implObject.IsEmpty(); - - return hasImplObj; -} - jweak ObjectManager::NewWeakGlobalRefCallback(const jint &javaObjectID, void *state) { auto objManager = reinterpret_cast(state); @@ -443,7 +361,3 @@ void ObjectManager::ReleaseNativeCounterpart(v8::Local &object) { auto jsInfoIdx = static_cast(MetadataNodeKeys::JsInfo); object->SetInternalField(jsInfoIdx, Undefined(m_isolate)); } - -ObjectManager::JavaScriptMarkingMode ObjectManager::GetMarkingMode() { - return this->m_markingMode; -} \ No newline at end of file diff --git a/test-app/runtime/src/main/cpp/ObjectManager.h b/test-app/runtime/src/main/cpp/ObjectManager.h index 82cfc9f3a..48adac75a 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.h +++ b/test-app/runtime/src/main/cpp/ObjectManager.h @@ -53,33 +53,14 @@ class ObjectManager { END }; - /** - * Memory management modes. Keep the members in sync with the java/com/tns/MarkingMode. - */ - enum JavaScriptMarkingMode { - /** - * For JavaScript instances with implementation objects that were marked for collection, - * MarkReachableObjects will scan the whole graph of reachable objects and keep strong reference to - * the Java instances of implementation objects. - */ - Full, - /** - * Fully suppress the MarkReachableObjects. - */ - None - }; - - JavaScriptMarkingMode GetMarkingMode(); - private: struct JSInstanceInfo { public: - JSInstanceInfo(bool isJavaObjectWeak, jint javaObjectID) - : IsJavaObjectWeak(isJavaObjectWeak), JavaObjectID(javaObjectID) { + JSInstanceInfo(jint javaObjectID) + : JavaObjectID(javaObjectID) { } - bool IsJavaObjectWeak; jint JavaObjectID; }; @@ -92,26 +73,15 @@ class ObjectManager { v8::Persistent* target; }; - struct GarbageCollectionInfo { - std::vector*> markedForGC; - }; - JSInstanceInfo* GetJSInstanceInfo(const v8::Local& object); JSInstanceInfo* GetJSInstanceInfoFromRuntimeObject(const v8::Local& object); v8::Local CreateJSWrapperHelper(jint javaObjectID, const std::string& typeName, jclass clazz); - static void JSObjectWeakCallbackStatic(const v8::WeakCallbackInfo& data); - static void JSObjectFinalizerStatic(const v8::WeakCallbackInfo& data); - - void JSObjectWeakCallback(v8::Isolate* isolate, ObjectWeakCallbackState* callbackState); - void JSObjectFinalizer(v8::Isolate* isolate, ObjectWeakCallbackState* callbackState); - bool HasImplObject(v8::Isolate* isolate, const v8::Local& obj); - jweak GetJavaObjectByID(jint javaObjectID); jobject GetJavaObjectByIDImpl(jint javaObjectID); @@ -126,21 +96,14 @@ class ObjectManager { v8::Isolate* m_isolate; - std::stack m_markedForGC; - std::unordered_map*> m_idToObject; LRUCache m_cache; - std::set*> m_visitedPOs; - std::unordered_map*> m_implObjStrong; - volatile jint m_currentObjectId; bool m_useGlobalRefs; - JavaScriptMarkingMode m_markingMode; - jmethodID GET_NAME_METHOD_ID; jmethodID GET_JAVAOBJECT_BY_ID_METHOD_ID; diff --git a/test-app/runtime/src/main/cpp/Runtime.cpp b/test-app/runtime/src/main/cpp/Runtime.cpp index af41fc94a..87640d0d2 100644 --- a/test-app/runtime/src/main/cpp/Runtime.cpp +++ b/test-app/runtime/src/main/cpp/Runtime.cpp @@ -502,7 +502,6 @@ Isolate* Runtime::PrepareV8Runtime(const string& filesPath, const string& native globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__runtimeVersion"), ArgConverter::ConvertToV8String(isolate, NATIVE_SCRIPT_RUNTIME_VERSION), readOnlyFlags); globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__time"), FunctionTemplate::New(isolate, CallbackHandlers::TimeCallback)); globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__releaseNativeCounterpart"), FunctionTemplate::New(isolate, CallbackHandlers::ReleaseNativeCounterpartCallback)); - globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__markingMode"), Number::New(isolate, m_objectManager->GetMarkingMode()), readOnlyFlags); globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__runOnMainThread"), FunctionTemplate::New(isolate, CallbackHandlers::RunOnMainThreadCallback)); globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__postFrameCallback"), FunctionTemplate::New(isolate, CallbackHandlers::PostFrameCallback)); globalTemplate->Set(ArgConverter::ConvertToV8String(isolate, "__removeFrameCallback"), FunctionTemplate::New(isolate, CallbackHandlers::RemoveFrameCallback)); diff --git a/test-app/runtime/src/main/java/com/tns/AppConfig.java b/test-app/runtime/src/main/java/com/tns/AppConfig.java index d989f93ca..855c20b7d 100644 --- a/test-app/runtime/src/main/java/com/tns/AppConfig.java +++ b/test-app/runtime/src/main/java/com/tns/AppConfig.java @@ -14,7 +14,6 @@ protected enum KnownKeys { MemoryCheckInterval("memoryCheckInterval", 0), FreeMemoryRatio("freeMemoryRatio", 0.0), Profiling("profiling", ""), - MarkingMode("markingMode", com.tns.MarkingMode.none), HandleTimeZoneChanges("handleTimeZoneChanges", false), MaxLogcatObjectSize("maxLogcatObjectSize", 1024), ForceLog("forceLog", false), @@ -80,18 +79,6 @@ public AppConfig(File appDir) { if (androidObject.has(KnownKeys.FreeMemoryRatio.getName())) { values[KnownKeys.FreeMemoryRatio.ordinal()] = androidObject.getDouble(KnownKeys.FreeMemoryRatio.getName()); } - if (androidObject.has(KnownKeys.MarkingMode.getName())) { - try { - String markingModeString = androidObject.getString(KnownKeys.MarkingMode.getName()); - MarkingMode markingMode = MarkingMode.valueOf(markingModeString); - values[KnownKeys.MarkingMode.ordinal()] = markingMode; - } catch (Exception e) { - Log.e("JS", String.format("Failed to parse marking mode: %s. The default %s will be used!", e.getMessage(), ((MarkingMode)KnownKeys.MarkingMode.getDefaultValue()).name())); - if (com.tns.Runtime.isDebuggable()) { - e.printStackTrace(); - } - } - } if (androidObject.has(KnownKeys.HandleTimeZoneChanges.getName())) { values[KnownKeys.HandleTimeZoneChanges.ordinal()] = androidObject.getBoolean(KnownKeys.HandleTimeZoneChanges.getName()); } @@ -144,10 +131,6 @@ public String getProfilingMode() { return (String)values[KnownKeys.Profiling.ordinal()]; } - public MarkingMode getMarkingMode() { - return (MarkingMode)values[KnownKeys.MarkingMode.ordinal()]; - } - public boolean handleTimeZoneChanges() { return (boolean)values[KnownKeys.HandleTimeZoneChanges.ordinal()]; } diff --git a/test-app/runtime/src/main/java/com/tns/MarkingMode.java b/test-app/runtime/src/main/java/com/tns/MarkingMode.java deleted file mode 100644 index 224a87a91..000000000 --- a/test-app/runtime/src/main/java/com/tns/MarkingMode.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.tns; - -/** - * Created by cankov on 24/08/2017. - */ -enum MarkingMode { - full, - none -} diff --git a/test-app/runtime/src/main/java/com/tns/Runtime.java b/test-app/runtime/src/main/java/com/tns/Runtime.java index c5651a997..e7f1957c1 100644 --- a/test-app/runtime/src/main/java/com/tns/Runtime.java +++ b/test-app/runtime/src/main/java/com/tns/Runtime.java @@ -334,15 +334,6 @@ public static boolean getLineBreakpointsEnabled() { } } - @RuntimeCallable - public int getMarkingModeOrdinal() { - if (staticConfiguration != null && staticConfiguration.appConfig != null) { - return staticConfiguration.appConfig.getMarkingMode().ordinal(); - } else { - return ((MarkingMode) AppConfig.KnownKeys.MarkingMode.getDefaultValue()).ordinal(); - } - } - public static boolean isInitialized() { Runtime runtime = Runtime.getCurrentRuntime(); return (runtime != null) ? runtime.isInitializedImpl() : false; From 8d5f8f54df954b5508394cd65159b3a6a6df26dd Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Wed, 10 May 2023 11:59:22 -0700 Subject: [PATCH 05/23] chore: Remove useGlobalRefs This is always set to true for SDK level 16 and later; and we require level 17 to build. So it doesn't need to be configurable. --- test-app/runtime/src/main/cpp/ObjectManager.cpp | 17 ++--------------- test-app/runtime/src/main/cpp/ObjectManager.h | 2 -- .../runtime/src/main/java/com/tns/Runtime.java | 7 ------- 3 files changed, 2 insertions(+), 24 deletions(-) diff --git a/test-app/runtime/src/main/cpp/ObjectManager.cpp b/test-app/runtime/src/main/cpp/ObjectManager.cpp index a69d62d6c..7151cdc46 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.cpp +++ b/test-app/runtime/src/main/cpp/ObjectManager.cpp @@ -48,12 +48,6 @@ ObjectManager::ObjectManager(jobject javaRuntimeObject) : GET_NAME_METHOD_ID = env.GetMethodID(javaLangClass, "getName", "()Ljava/lang/String;"); assert(GET_NAME_METHOD_ID != nullptr); - - auto useGlobalRefsMethodID = env.GetStaticMethodID(runtimeClass, "useGlobalRefs", "()Z"); - assert(useGlobalRefsMethodID != nullptr); - - auto useGlobalRefs = env.CallStaticBooleanMethod(runtimeClass, useGlobalRefsMethodID); - m_useGlobalRefs = useGlobalRefs == JNI_TRUE; } void ObjectManager::SetInstanceIsolate(Isolate *isolate) { @@ -74,15 +68,8 @@ JniLocalRef ObjectManager::GetJavaObjectByJsObject(const Local &object) JSInstanceInfo *jsInstanceInfo = GetJSInstanceInfo(object); if (jsInstanceInfo != nullptr) { - if (m_useGlobalRefs) { - JniLocalRef javaObject(GetJavaObjectByID(jsInstanceInfo->JavaObjectID), true); - return javaObject; - } else { - JEnv env; - JniLocalRef javaObject( - env.NewLocalRef(GetJavaObjectByID(jsInstanceInfo->JavaObjectID))); - return javaObject; - } + JniLocalRef javaObject(GetJavaObjectByID(jsInstanceInfo->JavaObjectID), true); + return javaObject; } return JniLocalRef(); diff --git a/test-app/runtime/src/main/cpp/ObjectManager.h b/test-app/runtime/src/main/cpp/ObjectManager.h index 48adac75a..012f9a283 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.h +++ b/test-app/runtime/src/main/cpp/ObjectManager.h @@ -102,8 +102,6 @@ class ObjectManager { volatile jint m_currentObjectId; - bool m_useGlobalRefs; - jmethodID GET_NAME_METHOD_ID; jmethodID GET_JAVAOBJECT_BY_ID_METHOD_ID; diff --git a/test-app/runtime/src/main/java/com/tns/Runtime.java b/test-app/runtime/src/main/java/com/tns/Runtime.java index e7f1957c1..64fb43a7d 100644 --- a/test-app/runtime/src/main/java/com/tns/Runtime.java +++ b/test-app/runtime/src/main/java/com/tns/Runtime.java @@ -1335,13 +1335,6 @@ private static Object createArrayHelper(String arrayClassName, int size) throws return arr; } - @RuntimeCallable - private static boolean useGlobalRefs() { - int JELLY_BEAN = 16; - boolean useGlobalRefs = android.os.Build.VERSION.SDK_INT >= JELLY_BEAN; - return useGlobalRefs; - } - /* ====================================================================== ====================================================================== From 4ec850279d17c5045931abb73b42f8751b7f2ba4 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 16 May 2023 10:47:36 -0700 Subject: [PATCH 06/23] chore: Init ObjectManager::m_isolate in Init() Remove the ObjectManager::SetInstanceIsolate method. It can be considered part of initializing the ObjectManager after the Isolate is created. Previously, both SetInstanceIsolate and Init were called with the newly created Isolate in Runtime::PrepareV8Runtime, but we don't need to have a 2-stage init process for the ObjectManager. --- test-app/runtime/src/main/cpp/ObjectManager.cpp | 5 +---- test-app/runtime/src/main/cpp/ObjectManager.h | 2 -- test-app/runtime/src/main/cpp/Runtime.cpp | 2 -- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/test-app/runtime/src/main/cpp/ObjectManager.cpp b/test-app/runtime/src/main/cpp/ObjectManager.cpp index 7151cdc46..137178c04 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.cpp +++ b/test-app/runtime/src/main/cpp/ObjectManager.cpp @@ -50,11 +50,8 @@ ObjectManager::ObjectManager(jobject javaRuntimeObject) : assert(GET_NAME_METHOD_ID != nullptr); } -void ObjectManager::SetInstanceIsolate(Isolate *isolate) { - m_isolate = isolate; -} - void ObjectManager::Init(Isolate *isolate) { + m_isolate = isolate; auto jsWrapperFuncTemplate = FunctionTemplate::New(isolate, JSWrapperConstructorCallback); jsWrapperFuncTemplate->InstanceTemplate()->SetInternalFieldCount( static_cast(MetadataNodeKeys::END)); diff --git a/test-app/runtime/src/main/cpp/ObjectManager.h b/test-app/runtime/src/main/cpp/ObjectManager.h index 012f9a283..c906fa010 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.h +++ b/test-app/runtime/src/main/cpp/ObjectManager.h @@ -43,8 +43,6 @@ class ObjectManager { jint GenerateNewObjectID(); - void SetInstanceIsolate(v8::Isolate* isolate); - v8::Local GetEmptyObject(v8::Isolate* isolate); enum class MetadataNodeKeys { diff --git a/test-app/runtime/src/main/cpp/Runtime.cpp b/test-app/runtime/src/main/cpp/Runtime.cpp index 87640d0d2..e20a7bd48 100644 --- a/test-app/runtime/src/main/cpp/Runtime.cpp +++ b/test-app/runtime/src/main/cpp/Runtime.cpp @@ -473,8 +473,6 @@ Isolate* Runtime::PrepareV8Runtime(const string& filesPath, const string& native Isolate::Scope isolate_scope(isolate); HandleScope handleScope(isolate); - m_objectManager->SetInstanceIsolate(isolate); - // Sets a structure with v8 String constants on the isolate object at slot 1 auto consts = new V8StringConstants::PerIsolateV8Constants(isolate); isolate->SetData((uint32_t)Runtime::IsolateData::RUNTIME, this); From d7a590d5438b5c2f54d055db1a9f8dc0a4aabf88 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 16 May 2023 16:51:45 -0700 Subject: [PATCH 07/23] chore: Initialize ObjectManager in one phase Combine the ObjectManager::Init() method into the ObjectManager constructor. This way, we don't have to worry about the isolate and things that depend on it being null. Give Runtime a unique_ptr member. I'm planning to use this in the upcoming CPPGC port, where I'll be defining more function templates in the constructor. --- test-app/runtime/src/main/cpp/ObjectManager.cpp | 6 ++---- test-app/runtime/src/main/cpp/ObjectManager.h | 4 +--- test-app/runtime/src/main/cpp/Runtime.cpp | 13 ++++++------- test-app/runtime/src/main/cpp/Runtime.h | 2 +- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/test-app/runtime/src/main/cpp/ObjectManager.cpp b/test-app/runtime/src/main/cpp/ObjectManager.cpp index 137178c04..0d16a98cd 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.cpp +++ b/test-app/runtime/src/main/cpp/ObjectManager.cpp @@ -16,7 +16,8 @@ using namespace v8; using namespace std; using namespace tns; -ObjectManager::ObjectManager(jobject javaRuntimeObject) : +ObjectManager::ObjectManager(v8::Isolate* isolate, jobject javaRuntimeObject) : + m_isolate(isolate), m_javaRuntimeObject(javaRuntimeObject), m_currentObjectId(0), m_cache(NewWeakGlobalRefCallback, DeleteWeakGlobalRefCallback, 1000, this) { @@ -48,10 +49,7 @@ ObjectManager::ObjectManager(jobject javaRuntimeObject) : GET_NAME_METHOD_ID = env.GetMethodID(javaLangClass, "getName", "()Ljava/lang/String;"); assert(GET_NAME_METHOD_ID != nullptr); -} -void ObjectManager::Init(Isolate *isolate) { - m_isolate = isolate; auto jsWrapperFuncTemplate = FunctionTemplate::New(isolate, JSWrapperConstructorCallback); jsWrapperFuncTemplate->InstanceTemplate()->SetInternalFieldCount( static_cast(MetadataNodeKeys::END)); diff --git a/test-app/runtime/src/main/cpp/ObjectManager.h b/test-app/runtime/src/main/cpp/ObjectManager.h index c906fa010..f33bae184 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.h +++ b/test-app/runtime/src/main/cpp/ObjectManager.h @@ -15,9 +15,7 @@ namespace tns { class ObjectManager { public: - ObjectManager(jobject javaRuntimeObject); - - void Init(v8::Isolate* isolate); + ObjectManager(v8::Isolate* isolate, jobject javaRuntimeObject); JniLocalRef GetJavaObjectByJsObject(const v8::Local& object); diff --git a/test-app/runtime/src/main/cpp/Runtime.cpp b/test-app/runtime/src/main/cpp/Runtime.cpp index e20a7bd48..c0e458559 100644 --- a/test-app/runtime/src/main/cpp/Runtime.cpp +++ b/test-app/runtime/src/main/cpp/Runtime.cpp @@ -94,9 +94,8 @@ int Runtime::GetAndroidVersion() { } Runtime::Runtime(JNIEnv* env, jobject runtime, int id) - : m_id(id), m_isolate(nullptr), m_lastUsedMemory(0), m_gcFunc(nullptr), m_runGC(false) { + : m_id(id), m_isolate(nullptr), m_objectManager(nullptr), m_lastUsedMemory(0), m_gcFunc(nullptr), m_runGC(false) { m_runtime = env->NewGlobalRef(runtime); - m_objectManager = new ObjectManager(m_runtime); m_loopTimer = new MessageLoopTimer(); s_id2RuntimeCache.insert(make_pair(id, this)); @@ -162,7 +161,8 @@ jobject Runtime::GetJavaRuntime() const { } ObjectManager* Runtime::GetObjectManager() const { - return m_objectManager; + assert(m_objectManager && "ObjectManager is only available after Runtime is initialized"); + return m_objectManager.get(); } void Runtime::Init(JNIEnv* _env, jobject obj, int runtimeId, jstring filesPath, jstring nativeLibDir, jboolean verboseLoggingEnabled, jboolean isDebuggable, jstring packageName, jobjectArray args, jstring callingDir, int maxLogcatObjectSize, bool forceLog) { @@ -201,7 +201,6 @@ void Runtime::Init(JNIEnv* env, jstring filesPath, jstring nativeLibDir, bool ve } Runtime::~Runtime() { - delete this->m_objectManager; delete this->m_loopTimer; CallbackHandlers::RemoveIsolateEntries(m_isolate); if (m_isMainThread) { @@ -338,7 +337,7 @@ void Runtime::CreateJSInstanceNative(jobject obj, jobject javaObject, jint javaO auto proxyClassName = m_objectManager->GetClassName(javaObject); DEBUG_WRITE("createJSInstanceNative class %s", proxyClassName.c_str()); - jsInstance = MetadataNode::CreateExtendedJSWrapper(isolate, m_objectManager, proxyClassName); + jsInstance = MetadataNode::CreateExtendedJSWrapper(isolate, m_objectManager.get(), proxyClassName); if (jsInstance.IsEmpty()) { throw NativeScriptException(string("Failed to create JavaScript extend wrapper for class '" + proxyClassName + "'")); @@ -576,7 +575,7 @@ Isolate* Runtime::PrepareV8Runtime(const string& filesPath, const string& native v8::Context::Scope contextScope{context}; - m_objectManager->Init(isolate); + m_objectManager = std::make_unique(isolate, m_runtime); m_module.Init(isolate, callingDir); @@ -624,7 +623,7 @@ Isolate* Runtime::PrepareV8Runtime(const string& filesPath, const string& native ArrayHelper::Init(context); - m_arrayBufferHelper.CreateConvertFunctions(context, global, m_objectManager); + m_arrayBufferHelper.CreateConvertFunctions(context, global, m_objectManager.get()); m_loopTimer->Init(context); diff --git a/test-app/runtime/src/main/cpp/Runtime.h b/test-app/runtime/src/main/cpp/Runtime.h index 2d042d0fd..2c5dda84d 100644 --- a/test-app/runtime/src/main/cpp/Runtime.h +++ b/test-app/runtime/src/main/cpp/Runtime.h @@ -86,7 +86,7 @@ class Runtime { jobject m_runtime; v8::Isolate* m_isolate; - ObjectManager* m_objectManager; + std::unique_ptr m_objectManager; ModuleInternal m_module; From 489100c9c88236c69f128976dc93c4c90017492a Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 16 May 2023 17:45:20 -0700 Subject: [PATCH 08/23] chore: Make some methods static These methods don't use the instance pointer, so they can be static - at least according to Android Studio's static analysis. --- test-app/runtime/src/main/cpp/MetadataNode.h | 8 ++++---- test-app/runtime/src/main/cpp/ObjectManager.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test-app/runtime/src/main/cpp/MetadataNode.h b/test-app/runtime/src/main/cpp/MetadataNode.h index d66ef0484..7be68409f 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.h +++ b/test-app/runtime/src/main/cpp/MetadataNode.h @@ -81,7 +81,7 @@ class MetadataNode { v8::Local GetConstructorFunctionTemplate(v8::Isolate* isolate, MetadataTreeNode* treeNode); v8::Local GetConstructorFunctionTemplate(v8::Isolate* isolate, MetadataTreeNode* treeNode, std::vector& instanceMethodsCallbackData); v8::Persistent* GetPersistentConstructorFunction(v8::Isolate* isolate); - v8::Local GetOrCreateArrayObjectTemplate(v8::Isolate* isolate); + static v8::Local GetOrCreateArrayObjectTemplate(v8::Isolate* isolate); std::vector SetInstanceMembers( v8::Isolate* isolate, v8::Local& ctorFuncTemplate, @@ -95,7 +95,7 @@ class MetadataNode { std::vector& instanceMethodsCallbackData, const std::vector& baseInstanceMethodsCallbackData, MetadataTreeNode* treeNode); - MethodCallbackData* tryGetExtensionMethodCallbackData( + static MethodCallbackData* tryGetExtensionMethodCallbackData( std::unordered_map collectedMethodCallbackDatas, std::string lookupName); void SetInstanceFieldsFromStaticMetadata( @@ -107,7 +107,7 @@ class MetadataNode { const std::vector& baseInstanceMethodsCallbackData, MetadataTreeNode* treeNode); void SetStaticMembers(v8::Isolate* isolate, v8::Local& ctorFunction, MetadataTreeNode* treeNode); - void SetInnerTypes(v8::Isolate* isolate, v8::Local& ctorFunction, MetadataTreeNode* treeNode); + static void SetInnerTypes(v8::Isolate* isolate, v8::Local& ctorFunction, MetadataTreeNode* treeNode); static void BuildMetadata(uint32_t nodesLength, uint8_t* nodeData, uint32_t nameLength, uint8_t* nameData, uint32_t valueLength, uint8_t* valueData); @@ -161,7 +161,7 @@ class MetadataNode { static void SymbolHasInstanceCallback(const v8::FunctionCallbackInfo& info); static std::string GetJniClassName(MetadataEntry entry); - v8::Local Wrap(v8::Isolate* isolate, const v8::Local& function, const std::string& name, const std::string& origin, bool isCtorFunc); + static v8::Local Wrap(v8::Isolate* isolate, const v8::Local& function, const std::string& name, const std::string& origin, bool isCtorFunc); bool CheckClassHierarchy(JEnv& env, jclass currentClass, MetadataTreeNode* curentTreeNode, MetadataTreeNode* baseTreeNode, std::vector& skippedBaseTypes); void SetMissingBaseMethods(v8::Isolate* isolate, diff --git a/test-app/runtime/src/main/cpp/ObjectManager.h b/test-app/runtime/src/main/cpp/ObjectManager.h index f33bae184..ef9c5ae8c 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.h +++ b/test-app/runtime/src/main/cpp/ObjectManager.h @@ -33,8 +33,6 @@ class ObjectManager { bool CloneLink(const v8::Local& src, const v8::Local& dest); - bool IsJsRuntimeObject(const v8::Local& object); - std::string GetClassName(jobject javaObject); std::string GetClassName(jclass clazz); @@ -88,6 +86,8 @@ class ObjectManager { static void JSWrapperConstructorCallback(const v8::FunctionCallbackInfo& info); + static bool IsJsRuntimeObject(const v8::Local& object); + jobject m_javaRuntimeObject; v8::Isolate* m_isolate; From cc6fd5d0690ff9a27490cf695784fcecd300645b Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 18 May 2023 15:39:12 -0700 Subject: [PATCH 09/23] chore: Store wrapper object template instead of ctor function template Previously we stored a function template in ObjectManager, with which a constructor function could be created, which would return an empty wrapper object. Using an object template should achieve the same effect, but without a call back into JS, so slightly more efficient. --- .../runtime/src/main/cpp/ObjectManager.cpp | 19 ++++--------------- test-app/runtime/src/main/cpp/ObjectManager.h | 2 +- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/test-app/runtime/src/main/cpp/ObjectManager.cpp b/test-app/runtime/src/main/cpp/ObjectManager.cpp index 0d16a98cd..faa32f18a 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.cpp +++ b/test-app/runtime/src/main/cpp/ObjectManager.cpp @@ -50,12 +50,9 @@ ObjectManager::ObjectManager(v8::Isolate* isolate, jobject javaRuntimeObject) : GET_NAME_METHOD_ID = env.GetMethodID(javaLangClass, "getName", "()Ljava/lang/String;"); assert(GET_NAME_METHOD_ID != nullptr); - auto jsWrapperFuncTemplate = FunctionTemplate::New(isolate, JSWrapperConstructorCallback); - jsWrapperFuncTemplate->InstanceTemplate()->SetInternalFieldCount( - static_cast(MetadataNodeKeys::END)); - auto context = isolate->GetCurrentContext(); - auto jsWrapperFunc = jsWrapperFuncTemplate->GetFunction(context).ToLocalChecked(); - m_poJsWrapperFunc = new Persistent(isolate, jsWrapperFunc); + Local tmpl = ObjectTemplate::New(m_isolate); + tmpl->SetInternalFieldCount(static_cast(MetadataNodeKeys::END)); + m_wrapperObjectTemplate.Reset(m_isolate, tmpl); } @@ -307,16 +304,8 @@ void ObjectManager::DeleteWeakGlobalRefCallback(const jweak &object, [[maybe_unu } Local ObjectManager::GetEmptyObject(Isolate *isolate) { - auto emptyObjCtorFunc = Local::New(isolate, *m_poJsWrapperFunc); auto context = Runtime::GetRuntime(isolate)->GetContext(); - auto val = emptyObjCtorFunc->CallAsConstructor(context, 0, nullptr); - if (val.IsEmpty()) { - return Local(); - } - auto localVal = val.ToLocalChecked(); - assert(localVal->IsObject()); - auto obj = localVal.As(); - return obj; + return m_wrapperObjectTemplate.Get(isolate)->NewInstance(context).ToLocalChecked(); } void ObjectManager::JSWrapperConstructorCallback(const v8::FunctionCallbackInfo &info) { diff --git a/test-app/runtime/src/main/cpp/ObjectManager.h b/test-app/runtime/src/main/cpp/ObjectManager.h index ef9c5ae8c..f299826ca 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.h +++ b/test-app/runtime/src/main/cpp/ObjectManager.h @@ -108,7 +108,7 @@ class ObjectManager { jmethodID RELEASE_NATIVE_INSTANCE_METHOD_ID; - v8::Persistent* m_poJsWrapperFunc; + v8::Persistent m_wrapperObjectTemplate; }; } From 917422f11763952987370e85e52378fca171936b Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Wed, 30 Aug 2023 14:37:44 -0700 Subject: [PATCH 10/23] fix: NativeScript include directories in cmake file The previous cmake code accidentally set the INTERFACE_INCLUDE_DIRECTORIES property to the string "NATIVES_BLOB_INCLUDE_DIRECTORIES". We actually want the value of the variable. (I don't think this affects anything in the current build, but it complains that INTERFACE_INCLUDE_DIRECTORIES contains a relative path if you try to link anything else against libNativeScript.so.) --- test-app/runtime/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test-app/runtime/CMakeLists.txt b/test-app/runtime/CMakeLists.txt index ed955bb6d..d7e061d9c 100644 --- a/test-app/runtime/CMakeLists.txt +++ b/test-app/runtime/CMakeLists.txt @@ -146,13 +146,13 @@ if (OPTIMIZED_BUILD OR OPTIMIZED_WITH_INSPECTOR_BUILD) set_target_properties( NativeScript PROPERTIES LINK_FLAGS -Wl,--allow-multiple-definition -Wl,--exclude-libs=ALL -Wl,--gc-sections - INTERFACE_INCLUDE_DIRECTORIES NATIVES_BLOB_INCLUDE_DIRECTORIES + INTERFACE_INCLUDE_DIRECTORIES ${NATIVES_BLOB_INCLUDE_DIRECTORIES} ) else () set_target_properties( NativeScript PROPERTIES LINK_FLAGS -Wl,--allow-multiple-definition - INTERFACE_INCLUDE_DIRECTORIES NATIVES_BLOB_INCLUDE_DIRECTORIES + INTERFACE_INCLUDE_DIRECTORIES ${NATIVES_BLOB_INCLUDE_DIRECTORIES} ) endif () From e8e9dec60b505478953b01ceb88ceb4482a16710 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 29 Aug 2023 15:00:17 -0700 Subject: [PATCH 11/23] fix: passing wrong arguments to NativeScriptException ctor In the case where a Java exception is thrown from a JNI call, wrapped into a C++ NativeScriptException, and caught by C++ code that re-throws it to Java, we'd get a crash. (Admittedly, this does not happen very much. Initializing the ObjectManager is one of the few places where it can happen.) --- test-app/runtime/src/main/cpp/NativeScriptException.cpp | 8 ++++++-- test-app/runtime/src/main/cpp/NativeScriptException.h | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/test-app/runtime/src/main/cpp/NativeScriptException.cpp b/test-app/runtime/src/main/cpp/NativeScriptException.cpp index add4c553f..9e4ae599d 100644 --- a/test-app/runtime/src/main/cpp/NativeScriptException.cpp +++ b/test-app/runtime/src/main/cpp/NativeScriptException.cpp @@ -106,7 +106,7 @@ void NativeScriptException::ReThrowToJava() { auto objectManager = Runtime::GetObjectManager(isolate); auto excClassName = objectManager->GetClassName(ex); if (excClassName != "com/tns/NativeScriptException") { - ex = static_cast(env.NewObject(NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_THROWABLE_CTOR_ID, (jstring) msg, (jstring)stackTrace, ex)); + ex = static_cast(env.NewObject(NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_THROWABLE_WITH_STACK_CTOR_ID, (jstring) msg, (jstring)stackTrace, ex)); } } } else if (!m_message.empty()) { @@ -135,9 +135,12 @@ void NativeScriptException::Init() { NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID = env.GetMethodID(NATIVESCRIPTEXCEPTION_CLASS, "", "(Ljava/lang/String;Ljava/lang/String;J)V"); assert(NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID != nullptr); - NATIVESCRIPTEXCEPTION_THROWABLE_CTOR_ID = env.GetMethodID(NATIVESCRIPTEXCEPTION_CLASS, "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V"); + NATIVESCRIPTEXCEPTION_THROWABLE_CTOR_ID = env.GetMethodID(NATIVESCRIPTEXCEPTION_CLASS, "", "(Ljava/lang/String;Ljava/lang/Throwable;)V"); assert(NATIVESCRIPTEXCEPTION_THROWABLE_CTOR_ID != nullptr); + NATIVESCRIPTEXCEPTION_THROWABLE_WITH_STACK_CTOR_ID = env.GetMethodID(NATIVESCRIPTEXCEPTION_CLASS, "", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)V"); + assert(NATIVESCRIPTEXCEPTION_THROWABLE_WITH_STACK_CTOR_ID != nullptr); + NATIVESCRIPTEXCEPTION_GET_STACK_TRACE_AS_STRING_METHOD_ID = env.GetStaticMethodID(NATIVESCRIPTEXCEPTION_CLASS, "getStackTraceAsString", "(Ljava/lang/Throwable;)Ljava/lang/String;"); assert(NATIVESCRIPTEXCEPTION_GET_STACK_TRACE_AS_STRING_METHOD_ID != nullptr); @@ -409,5 +412,6 @@ jclass NativeScriptException::THROWABLE_CLASS = nullptr; jclass NativeScriptException::NATIVESCRIPTEXCEPTION_CLASS = nullptr; jmethodID NativeScriptException::NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID = nullptr; jmethodID NativeScriptException::NATIVESCRIPTEXCEPTION_THROWABLE_CTOR_ID = nullptr; +jmethodID NativeScriptException::NATIVESCRIPTEXCEPTION_THROWABLE_WITH_STACK_CTOR_ID = nullptr; jmethodID NativeScriptException::NATIVESCRIPTEXCEPTION_GET_MESSAGE_METHOD_ID = nullptr; jmethodID NativeScriptException::NATIVESCRIPTEXCEPTION_GET_STACK_TRACE_AS_STRING_METHOD_ID = nullptr; \ No newline at end of file diff --git a/test-app/runtime/src/main/cpp/NativeScriptException.h b/test-app/runtime/src/main/cpp/NativeScriptException.h index ee8afad0d..b9522a21c 100644 --- a/test-app/runtime/src/main/cpp/NativeScriptException.h +++ b/test-app/runtime/src/main/cpp/NativeScriptException.h @@ -97,6 +97,7 @@ class NativeScriptException { static jclass NATIVESCRIPTEXCEPTION_CLASS; static jmethodID NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID; static jmethodID NATIVESCRIPTEXCEPTION_THROWABLE_CTOR_ID; + static jmethodID NATIVESCRIPTEXCEPTION_THROWABLE_WITH_STACK_CTOR_ID; static jmethodID NATIVESCRIPTEXCEPTION_GET_MESSAGE_METHOD_ID; static jmethodID NATIVESCRIPTEXCEPTION_GET_STACK_TRACE_AS_STRING_METHOD_ID; From 016c077a550278b69dda57a649ca434014df654e Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Wed, 30 Aug 2023 15:15:14 -0700 Subject: [PATCH 12/23] fix: Populate keywords set during static initialization Running the worker tests would occasionally hit a crash where the keywords set contained corrupt data. I believe this is because the keywords.empty() check was being hit in two different threads. We can supply the keywords in an initializer list so that the set is fully populated during static initialization. --- test-app/runtime/src/main/cpp/MetadataNode.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/test-app/runtime/src/main/cpp/MetadataNode.cpp b/test-app/runtime/src/main/cpp/MetadataNode.cpp index 9959bf0ea..0f680d778 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.cpp +++ b/test-app/runtime/src/main/cpp/MetadataNode.cpp @@ -2039,17 +2039,12 @@ void MetadataNode::EnableProfiler(bool enableProfiler) { } bool MetadataNode::IsJavascriptKeyword(std::string word) { - static set keywords; - - if (keywords.empty()) { - string kw[] { "abstract", "arguments", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", - "double", "else", "enum", "eval", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", - "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", "null", "package", "private", "protected", "public", "return", - "short", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with", "yield" - }; - - keywords = set(kw, kw + sizeof(kw)/sizeof(kw[0])); - } + static set keywords{ + "abstract", "arguments", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", + "double", "else", "enum", "eval", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", + "import", "in", "instanceof", "int", "interface", "let", "long", "native", "new", "null", "package", "private", "protected", "public", "return", + "short", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "typeof", "var", "void", "volatile", "while", "with", "yield" + }; return keywords.find(word) != keywords.end(); } From e87074a955abed5abf0a51e5e177bb7fba81f2ca Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 29 Aug 2023 15:00:49 -0700 Subject: [PATCH 13/23] fix: init NativeScriptException earlier Unlikely, but the ArgConverter calls at the beginning of Runtime::Init() could theoretically throw a Java exception, in which case they'd be wrapped into a C++ NativeScriptException and then re-thrown to Java. For that to work, NativeScriptException has to be initialized. --- test-app/runtime/src/main/cpp/Runtime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test-app/runtime/src/main/cpp/Runtime.cpp b/test-app/runtime/src/main/cpp/Runtime.cpp index c0e458559..077b1d573 100644 --- a/test-app/runtime/src/main/cpp/Runtime.cpp +++ b/test-app/runtime/src/main/cpp/Runtime.cpp @@ -177,6 +177,7 @@ void Runtime::Init(JNIEnv* _env, jobject obj, int runtimeId, jstring filesPath, void Runtime::Init(JNIEnv* env, jstring filesPath, jstring nativeLibDir, bool verboseLoggingEnabled, bool isDebuggable, jstring packageName, jobjectArray args, jstring callingDir, int maxLogcatObjectSize, bool forceLog) { LogEnabled = verboseLoggingEnabled; + NativeScriptException::Init(); auto filesRoot = ArgConverter::jstringToString(filesPath); auto nativeLibDirStr = ArgConverter::jstringToString(nativeLibDir); @@ -196,7 +197,6 @@ void Runtime::Init(JNIEnv* env, jstring filesPath, jstring nativeLibDir, bool ve auto profilerOutputDirStr = ArgConverter::jstringToString(profilerOutputDir); - NativeScriptException::Init(); m_isolate = PrepareV8Runtime(filesRoot, nativeLibDirStr, packageNameStr, isDebuggable, callingDirStr, profilerOutputDirStr, maxLogcatObjectSize, forceLog); } From e284c07ee9f5789b676c6ea9f7e66222160ea28a Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 29 Aug 2023 15:01:38 -0700 Subject: [PATCH 14/23] fix: move GetClassName out of ObjectManager Particularly in NativeScriptException::ReThrowToJava(), we may need to call GetClassName before the ObjectManager is initialized. This would cause a crash when handling exceptions early in the NativeScript runtime's initialization process. Luckily, GetClassName doesn't actually need to be part of ObjectManager, it can be moved to JEnv instead. --- .../src/main/cpp/ArrayElementAccessor.cpp | 2 +- .../runtime/src/main/cpp/CallbackHandlers.cpp | 8 ------- .../runtime/src/main/cpp/CallbackHandlers.h | 2 -- test-app/runtime/src/main/cpp/JEnv.cpp | 18 +++++++++++++++ test-app/runtime/src/main/cpp/JEnv.h | 3 +++ .../runtime/src/main/cpp/MetadataNode.cpp | 3 ++- .../src/main/cpp/NativeScriptException.cpp | 11 ++++----- .../runtime/src/main/cpp/ObjectManager.cpp | 23 +------------------ test-app/runtime/src/main/cpp/ObjectManager.h | 6 ----- test-app/runtime/src/main/cpp/Runtime.cpp | 6 +++-- 10 files changed, 33 insertions(+), 49 deletions(-) diff --git a/test-app/runtime/src/main/cpp/ArrayElementAccessor.cpp b/test-app/runtime/src/main/cpp/ArrayElementAccessor.cpp index 587e67320..58ac5ef8a 100644 --- a/test-app/runtime/src/main/cpp/ArrayElementAccessor.cpp +++ b/test-app/runtime/src/main/cpp/ArrayElementAccessor.cpp @@ -190,7 +190,7 @@ Local ArrayElementAccessor::ConvertToJsValue(Isolate* isolate, ObjectMana if (elementSignature[0] == '[') { className = Util::JniClassPathToCanonicalName(elementSignature); } else { - className = objectManager->GetClassName(*(jobject*) value); + className = env.GetClassName(*(jobject*) value); } jsValue = objectManager->CreateJSWrapper(javaObjectID, className); diff --git a/test-app/runtime/src/main/cpp/CallbackHandlers.cpp b/test-app/runtime/src/main/cpp/CallbackHandlers.cpp index 78aa52d73..13641cbff 100644 --- a/test-app/runtime/src/main/cpp/CallbackHandlers.cpp +++ b/test-app/runtime/src/main/cpp/CallbackHandlers.cpp @@ -162,14 +162,6 @@ jclass CallbackHandlers::ResolveClass(Isolate *isolate, const string &baseClassN return globalRefToGeneratedClass; } -// Called by ExtendMethodCallback when extending a class -string CallbackHandlers::ResolveClassName(Isolate *isolate, jclass &clazz) { - auto runtime = Runtime::GetRuntime(isolate); - auto objectManager = runtime->GetObjectManager(); - auto className = objectManager->GetClassName(clazz); - return className; -} - Local CallbackHandlers::GetArrayElement(Local context, const Local &array, uint32_t index, const string &arraySignature) { return arrayElementAccessor.GetArrayElement(context, array, index, arraySignature); diff --git a/test-app/runtime/src/main/cpp/CallbackHandlers.h b/test-app/runtime/src/main/cpp/CallbackHandlers.h index 22b0b31b6..c05ea76aa 100644 --- a/test-app/runtime/src/main/cpp/CallbackHandlers.h +++ b/test-app/runtime/src/main/cpp/CallbackHandlers.h @@ -48,8 +48,6 @@ namespace tns { const v8::Local &implementationObject, bool isInterface); - static std::string ResolveClassName(v8::Isolate *isolate, jclass &clazz); - static v8::Local GetArrayElement(v8::Local context, const v8::Local &array, uint32_t index, const std::string &arraySignature); diff --git a/test-app/runtime/src/main/cpp/JEnv.cpp b/test-app/runtime/src/main/cpp/JEnv.cpp index cc6629749..4542f2390 100644 --- a/test-app/runtime/src/main/cpp/JEnv.cpp +++ b/test-app/runtime/src/main/cpp/JEnv.cpp @@ -828,6 +828,10 @@ void JEnv::Init(JavaVM *jvm) { GET_CACHED_CLASS_METHOD_ID = env.GetStaticMethodID(RUNTIME_CLASS, "getCachedClass", "(Ljava/lang/String;)Ljava/lang/Class;"); assert(GET_CACHED_CLASS_METHOD_ID != nullptr); + jclass javaLangClass = env.FindClass("java/lang/Class"); + assert(javaLangClass != nullptr); + GET_NAME_METHOD_ID = env.GetMethodID(javaLangClass, "getName", "()Ljava/lang/String;"); + assert(GET_NAME_METHOD_ID != nullptr); } jclass JEnv::GetObjectClass(jobject obj) { @@ -836,6 +840,19 @@ jclass JEnv::GetObjectClass(jobject obj) { return jcl; } +std::string JEnv::GetClassName(jclass cls) { + JniLocalRef javaCanonicalName{CallObjectMethod(cls, GET_NAME_METHOD_ID)}; + + jboolean unused = JNI_FALSE; + const char* chars = GetStringUTFChars(jstring{javaCanonicalName}, &unused); + std::string className{chars}; + ReleaseStringUTFChars(jstring{javaCanonicalName}, chars); + + std::replace(className.begin(), className.end(), '.', '/'); + + return className; +} + jsize JEnv::GetArrayLength(jarray array) { jsize jsz = m_env->GetArrayLength(array); CheckForJavaException(); @@ -859,6 +876,7 @@ map JEnv::s_classCache; map JEnv::s_missingClasses; jclass JEnv::RUNTIME_CLASS = nullptr; jmethodID JEnv::GET_CACHED_CLASS_METHOD_ID = nullptr; +jmethodID JEnv::GET_NAME_METHOD_ID = nullptr; std::pair JEnv::GetInterfaceStaticMethodIDAndJClass(const std::string &interfaceName, diff --git a/test-app/runtime/src/main/cpp/JEnv.h b/test-app/runtime/src/main/cpp/JEnv.h index a85fcc637..9f1f7d402 100644 --- a/test-app/runtime/src/main/cpp/JEnv.h +++ b/test-app/runtime/src/main/cpp/JEnv.h @@ -17,6 +17,8 @@ class JEnv { operator JNIEnv* () const; jclass GetObjectClass(jobject obj); + std::string GetClassName(jclass cls); + std::string GetClassName(jobject obj) { return GetClassName(GetObjectClass(obj)); } jsize GetArrayLength(jarray array); @@ -341,6 +343,7 @@ class JEnv { static jclass RUNTIME_CLASS; static jmethodID GET_CACHED_CLASS_METHOD_ID; + static jmethodID GET_NAME_METHOD_ID; static std::map s_classCache; static std::map s_missingClasses; diff --git a/test-app/runtime/src/main/cpp/MetadataNode.cpp b/test-app/runtime/src/main/cpp/MetadataNode.cpp index 0f680d778..19f762a5c 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.cpp +++ b/test-app/runtime/src/main/cpp/MetadataNode.cpp @@ -1690,7 +1690,8 @@ void MetadataNode::ExtendMethodCallback(const v8::FunctionCallbackInfom_treeNode); bool isInterface = s_metadataReader.IsNodeTypeInterface(nodeType); auto clazz = CallbackHandlers::ResolveClass(isolate, baseClassName, fullClassName, implementationObject, isInterface); - auto fullExtendedName = CallbackHandlers::ResolveClassName(isolate, clazz); + JEnv env; + std::string fullExtendedName{env.GetClassName(clazz)}; DEBUG_WRITE("ExtendsCallMethodHandler: extend full name %s", fullClassName.c_str()); auto cachedData = GetCachedExtendedClassData(isolate, fullExtendedName); diff --git a/test-app/runtime/src/main/cpp/NativeScriptException.cpp b/test-app/runtime/src/main/cpp/NativeScriptException.cpp index 9e4ae599d..6ec695278 100644 --- a/test-app/runtime/src/main/cpp/NativeScriptException.cpp +++ b/test-app/runtime/src/main/cpp/NativeScriptException.cpp @@ -75,8 +75,7 @@ void NativeScriptException::ReThrowToJava() { if (!m_javaException.IsNull()) { - auto objectManager = Runtime::GetObjectManager(isolate); - auto excClassName = objectManager->GetClassName((jobject) m_javaException); + std::string excClassName{env.GetClassName((jobject) m_javaException)}; if (excClassName == "com/tns/NativeScriptException") { ex = m_javaException; } else { @@ -103,8 +102,7 @@ void NativeScriptException::ReThrowToJava() { if (ex == nullptr) { ex = static_cast(env.NewObject(NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_JSVALUE_CTOR_ID, (jstring) msg, (jstring)stackTrace, reinterpret_cast(m_javascriptException))); } else { - auto objectManager = Runtime::GetObjectManager(isolate); - auto excClassName = objectManager->GetClassName(ex); + std::string excClassName{env.GetClassName(ex)}; if (excClassName != "com/tns/NativeScriptException") { ex = static_cast(env.NewObject(NATIVESCRIPTEXCEPTION_CLASS, NATIVESCRIPTEXCEPTION_THROWABLE_WITH_STACK_CTOR_ID, (jstring) msg, (jstring)stackTrace, ex)); } @@ -187,9 +185,8 @@ Local NativeScriptException::WrapJavaToJsException() { JEnv env; auto isolate = Isolate::GetCurrent(); - auto objectManager = Runtime::GetObjectManager(isolate); - string excClassName = objectManager->GetClassName((jobject) m_javaException); + string excClassName{env.GetClassName((jobject) m_javaException)}; if (excClassName == "com/tns/NativeScriptException") { jfieldID fieldID = env.GetFieldID(env.GetObjectClass(m_javaException), "jsValueAddress", "J"); jlong addr = env.GetLongField(m_javaException, fieldID); @@ -223,7 +220,7 @@ Local NativeScriptException::GetJavaExceptionFromEnv(const JniLocalRef& e auto nativeExceptionObject = objectManager->GetJsObjectByJavaObject(javaObjectID); if (nativeExceptionObject.IsEmpty()) { - string className = objectManager->GetClassName((jobject) exc); + string className{env.GetClassName((jobject) exc)}; nativeExceptionObject = objectManager->CreateJSWrapper(javaObjectID, className); } diff --git a/test-app/runtime/src/main/cpp/ObjectManager.cpp b/test-app/runtime/src/main/cpp/ObjectManager.cpp index faa32f18a..fe134660c 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.cpp +++ b/test-app/runtime/src/main/cpp/ObjectManager.cpp @@ -47,9 +47,6 @@ ObjectManager::ObjectManager(v8::Isolate* isolate, jobject javaRuntimeObject) : jclass javaLangClass = env.FindClass("java/lang/Class"); assert(javaLangClass != nullptr); - GET_NAME_METHOD_ID = env.GetMethodID(javaLangClass, "getName", "()Ljava/lang/String;"); - assert(GET_NAME_METHOD_ID != nullptr); - Local tmpl = ObjectTemplate::New(m_isolate); tmpl->SetInternalFieldCount(static_cast(MetadataNodeKeys::END)); m_wrapperObjectTemplate.Reset(m_isolate, tmpl); @@ -160,7 +157,7 @@ Local ObjectManager::CreateJSWrapperHelper(jint javaObjectID, const string &typeName, jclass clazz) { auto isolate = m_isolate; - auto className = (clazz != nullptr) ? GetClassName(clazz) : typeName; + std::string className{clazz != nullptr ? JEnv{}.GetClassName(clazz) : typeName}; auto node = MetadataNode::GetOrCreate(className); @@ -220,24 +217,6 @@ bool ObjectManager::CloneLink(const Local &src, const Local &des return success; } -string ObjectManager::GetClassName(jobject javaObject) { - JEnv env; - JniLocalRef objectClass(env.GetObjectClass(javaObject)); - - return GetClassName((jclass) objectClass); -} - -string ObjectManager::GetClassName(jclass clazz) { - JEnv env; - JniLocalRef javaCanonicalName(env.CallObjectMethod(clazz, GET_NAME_METHOD_ID)); - - string className = ArgConverter::jstringToString(javaCanonicalName); - - std::replace(className.begin(), className.end(), '.', '/'); - - return className; -} - void ObjectManager::JSObjectFinalizerStatic(const WeakCallbackInfo &data) { ObjectWeakCallbackState *callbackState = data.GetParameter(); diff --git a/test-app/runtime/src/main/cpp/ObjectManager.h b/test-app/runtime/src/main/cpp/ObjectManager.h index f299826ca..1b5244b10 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.h +++ b/test-app/runtime/src/main/cpp/ObjectManager.h @@ -33,10 +33,6 @@ class ObjectManager { bool CloneLink(const v8::Local& src, const v8::Local& dest); - std::string GetClassName(jobject javaObject); - - std::string GetClassName(jclass clazz); - jint GenerateNewObjectID(); v8::Local GetEmptyObject(v8::Isolate* isolate); @@ -98,8 +94,6 @@ class ObjectManager { volatile jint m_currentObjectId; - jmethodID GET_NAME_METHOD_ID; - jmethodID GET_JAVAOBJECT_BY_ID_METHOD_ID; jmethodID GET_OR_CREATE_JAVA_OBJECT_ID_METHOD_ID; diff --git a/test-app/runtime/src/main/cpp/Runtime.cpp b/test-app/runtime/src/main/cpp/Runtime.cpp index 077b1d573..959f59cf4 100644 --- a/test-app/runtime/src/main/cpp/Runtime.cpp +++ b/test-app/runtime/src/main/cpp/Runtime.cpp @@ -335,7 +335,8 @@ void Runtime::CreateJSInstanceNative(jobject obj, jobject javaObject, jint javaO Local jsInstance; Local implementationObject; - auto proxyClassName = m_objectManager->GetClassName(javaObject); + JEnv env; + std::string proxyClassName{env.GetClassName(javaObject)}; DEBUG_WRITE("createJSInstanceNative class %s", proxyClassName.c_str()); jsInstance = MetadataNode::CreateExtendedJSWrapper(isolate, m_objectManager.get(), proxyClassName); @@ -404,7 +405,8 @@ void Runtime::PassExceptionToJsNative(JNIEnv* env, jobject obj, jthrowable excep auto nativeExceptionObject = m_objectManager->GetJsObjectByJavaObject(javaObjectID); if (nativeExceptionObject.IsEmpty()) { - string className = m_objectManager->GetClassName((jobject) exception); + JEnv java{env}; + string className{java.GetClassName((jobject) exception)}; //create proxy object that wraps the java err nativeExceptionObject = m_objectManager->CreateJSWrapper(javaObjectID, className); if (nativeExceptionObject.IsEmpty()) { From 91ca870eaadced09a748386d0332665b1a6dc072 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 29 Aug 2023 17:28:27 -0700 Subject: [PATCH 15/23] fix: Safety check on clearing dex cache Giving a wrong path to DexFactory can result in folders unexpectedly being wiped. Add a safety check to DexFactory.purgeDexesByThumb() to make sure we are only deleting files with the expected extensions. --- test-app/runtime/src/main/java/com/tns/DexFactory.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test-app/runtime/src/main/java/com/tns/DexFactory.java b/test-app/runtime/src/main/java/com/tns/DexFactory.java index 8fe8246d2..cd0e04c62 100644 --- a/test-app/runtime/src/main/java/com/tns/DexFactory.java +++ b/test-app/runtime/src/main/java/com/tns/DexFactory.java @@ -338,6 +338,11 @@ private void purgeDexesByThumb(String cachedDexThumb, File pathToPurge) { continue; } + if (!filename.endsWith(".dex") && !filename.endsWith(".jar") && !filename.endsWith(".jar.cur.prof") && !filename.endsWith(".odex")) { + logger.write("Not purging unexpected file type " + purgeCandidate.getAbsolutePath()); + continue; + } + if (!purgeCandidate.delete()) { logger.write("Error purging cached proxy file: " + purgeCandidate.getAbsolutePath()); } From c58d3ff68e87958846432579bff7c34d9f1420f7 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 9 Feb 2023 16:16:57 -0800 Subject: [PATCH 16/23] chore: Switch from CreationContext() to GetCreationContextChecked() See https://github.com/v8/v8/commit/b38bf5b0. The creation context may be null for WASM objects, so the old API is deprecated in favour of GetCreationContext() which returns a MaybeLocal. However, we are not handling any WASM objects here, so we can use the version of the API that asserts that we do have a creation context. --- test-app/runtime/src/main/cpp/CallbackHandlers.cpp | 4 ++-- test-app/runtime/src/main/cpp/MetadataNode.cpp | 2 +- test-app/runtime/src/main/cpp/NumericCasts.cpp | 4 ++-- test-app/runtime/src/main/cpp/V8GlobalHelpers.cpp | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test-app/runtime/src/main/cpp/CallbackHandlers.cpp b/test-app/runtime/src/main/cpp/CallbackHandlers.cpp index 13641cbff..9860ba209 100644 --- a/test-app/runtime/src/main/cpp/CallbackHandlers.cpp +++ b/test-app/runtime/src/main/cpp/CallbackHandlers.cpp @@ -558,7 +558,7 @@ CallbackHandlers::GetImplementedInterfaces(JEnv &env, const Local &imple vector interfacesToImplement; auto isolate = implementationObject->GetIsolate(); - auto context = implementationObject->CreationContext(); + Local context = implementationObject->GetCreationContextChecked(); Local interfacesName = String::NewFromUtf8Literal(isolate, "interfaces"); Local prop; if (implementationObject->Get(context, interfacesName).ToLocal(&prop) && !prop.IsEmpty() && prop->IsArray()) { @@ -604,7 +604,7 @@ CallbackHandlers::GetMethodOverrides(JEnv &env, const Local &implementat vector methodNames; auto isolate = implementationObject->GetIsolate(); - auto context = implementationObject->CreationContext(); + Local context = implementationObject->GetCreationContextChecked(); auto propNames = implementationObject->GetOwnPropertyNames(context).ToLocalChecked(); for (int i = 0; i < propNames->Length(); i++) { auto name = propNames->Get(context, i).ToLocalChecked().As(); diff --git a/test-app/runtime/src/main/cpp/MetadataNode.cpp b/test-app/runtime/src/main/cpp/MetadataNode.cpp index 19f762a5c..e858d6d34 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.cpp +++ b/test-app/runtime/src/main/cpp/MetadataNode.cpp @@ -1398,7 +1398,7 @@ Local MetadataNode::GetImplementationObject(Isolate* isolate, const Loca return implementationObject; } - auto context = object->CreationContext(); + Local context = object->GetCreationContextChecked(); if (object->HasOwnProperty(context, V8StringConstants::GetIsPrototypeImplementationObject(isolate)).ToChecked()) { auto v8Prototype = V8StringConstants::GetPrototype(isolate); auto maybeHasOwnProperty = object->HasOwnProperty(context, v8Prototype); diff --git a/test-app/runtime/src/main/cpp/NumericCasts.cpp b/test-app/runtime/src/main/cpp/NumericCasts.cpp index 9ae4026db..147df5497 100644 --- a/test-app/runtime/src/main/cpp/NumericCasts.cpp +++ b/test-app/runtime/src/main/cpp/NumericCasts.cpp @@ -37,7 +37,7 @@ CastType NumericCasts::GetCastType(Isolate* isolate, const Local& object Local NumericCasts::GetCastValue(const Local& object) { auto isolate = object->GetIsolate(); - auto context = object->CreationContext(); + Local context = object->GetCreationContextChecked(); Local value; object->Get(context, V8StringConstants::GetValue(isolate)).ToLocal(&value); return value; @@ -364,7 +364,7 @@ void NumericCasts::MarkJsObject(Isolate* isolate, const Local& object, C auto key = ArgConverter::ConvertToV8String(isolate, s_castMarker); auto type = Integer::New(isolate, static_cast(castType)); V8SetPrivateValue(isolate, object, key, type); - auto context = object->CreationContext(); + Local context = object->GetCreationContextChecked(); object->Set(context, V8StringConstants::GetValue(isolate), value); DEBUG_WRITE("MarkJsObject: Marking js object: %d with cast type: %d", object->GetIdentityHash(), castType); diff --git a/test-app/runtime/src/main/cpp/V8GlobalHelpers.cpp b/test-app/runtime/src/main/cpp/V8GlobalHelpers.cpp index 2fc637848..427a2b426 100644 --- a/test-app/runtime/src/main/cpp/V8GlobalHelpers.cpp +++ b/test-app/runtime/src/main/cpp/V8GlobalHelpers.cpp @@ -107,7 +107,7 @@ std::string tns::JsonStringifyObject(Isolate* isolate, v8::Local val bool tns::V8GetPrivateValue(Isolate* isolate, const Local& obj, const Local& propName, Local& out) { auto privateKey = Private::ForApi(isolate, propName); - auto context = obj->CreationContext(); + Local context = obj->GetCreationContextChecked(); auto hasPrivate = obj->HasPrivate(context, privateKey); if (hasPrivate.IsNothing()) { @@ -133,7 +133,7 @@ bool tns::V8GetPrivateValue(Isolate* isolate, const Local& obj, const Lo bool tns::V8SetPrivateValue(Isolate* isolate, const Local& obj, const Local& propName, const Local& value) { auto privateKey = Private::ForApi(isolate, propName); - auto context = obj->CreationContext(); + Local context = obj->GetCreationContextChecked(); auto res = obj->SetPrivate(context, privateKey, value); if (res.IsNothing()) { From 492dadc76dd5012288cb44050c674a18139b23e9 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Fri, 28 Apr 2023 16:22:39 -0700 Subject: [PATCH 17/23] chore: Set V8 flags before initializing V8 In 11.x, it's no longer allowed to change the flags after V8 has been initialized. We can also avoid storing the string in Constants::V8_STARTUP_FLAGS, as it's no longer used anywhere else in the code base. --- test-app/runtime/src/main/cpp/Constants.cpp | 1 - test-app/runtime/src/main/cpp/Constants.h | 1 - test-app/runtime/src/main/cpp/Runtime.cpp | 4 ++-- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/test-app/runtime/src/main/cpp/Constants.cpp b/test-app/runtime/src/main/cpp/Constants.cpp index b79ad93b5..942e20c50 100644 --- a/test-app/runtime/src/main/cpp/Constants.cpp +++ b/test-app/runtime/src/main/cpp/Constants.cpp @@ -9,4 +9,3 @@ std::string Constants::APP_ROOT_FOLDER_PATH = ""; bool Constants::V8_CACHE_COMPILED_CODE = false; -std::string Constants::V8_STARTUP_FLAGS = ""; diff --git a/test-app/runtime/src/main/cpp/Constants.h b/test-app/runtime/src/main/cpp/Constants.h index a5a089a65..d02335c34 100644 --- a/test-app/runtime/src/main/cpp/Constants.h +++ b/test-app/runtime/src/main/cpp/Constants.h @@ -8,7 +8,6 @@ class Constants { const static char CLASS_NAME_LOCATION_SEPARATOR = '_'; static std::string APP_ROOT_FOLDER_PATH; - static std::string V8_STARTUP_FLAGS; static bool V8_CACHE_COMPILED_CODE; private: diff --git a/test-app/runtime/src/main/cpp/Runtime.cpp b/test-app/runtime/src/main/cpp/Runtime.cpp index 959f59cf4..3fa434f26 100644 --- a/test-app/runtime/src/main/cpp/Runtime.cpp +++ b/test-app/runtime/src/main/cpp/Runtime.cpp @@ -188,7 +188,8 @@ void Runtime::Init(JNIEnv* env, jstring filesPath, jstring nativeLibDir, bool ve // read config options passed from Java // Indices correspond to positions in the com.tns.AppConfig.KnownKeys enum JniLocalRef v8Flags(env->GetObjectArrayElement(args, 0)); - Constants::V8_STARTUP_FLAGS = ArgConverter::jstringToString(v8Flags); + std::string v8FlagsString = ArgConverter::jstringToString(v8Flags); + V8::SetFlagsFromString(v8FlagsString.c_str(), v8FlagsString.size()); JniLocalRef cacheCode(env->GetObjectArrayElement(args, 1)); Constants::V8_CACHE_COMPILED_CODE = (bool) cacheCode; JniLocalRef profilerOutputDir(env->GetObjectArrayElement(args, 2)); @@ -479,7 +480,6 @@ Isolate* Runtime::PrepareV8Runtime(const string& filesPath, const string& native isolate->SetData((uint32_t)Runtime::IsolateData::RUNTIME, this); isolate->SetData((uint32_t)Runtime::IsolateData::CONSTANTS, consts); - V8::SetFlagsFromString(Constants::V8_STARTUP_FLAGS.c_str(), Constants::V8_STARTUP_FLAGS.size()); isolate->SetCaptureStackTraceForUncaughtExceptions(true, 100, StackTrace::kOverview); isolate->AddMessageListener(NativeScriptException::OnUncaughtError); From 9a960299517e664ddd950da42be1b59d6f65b87f Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 16 May 2023 17:52:03 -0700 Subject: [PATCH 18/23] chore: Use CPPGC-compatible platform For the CPPGC port we'll need to use a cppgc::DefaultPlatform instead of the v8::platform::NewDefaultPlatform(). It's also harmless to use it already even if we don't use CPPGC yet. --- test-app/runtime/src/main/cpp/JsV8InspectorClient.cpp | 5 +++-- test-app/runtime/src/main/cpp/MessageLoopTimer.cpp | 6 ++++-- test-app/runtime/src/main/cpp/Runtime.cpp | 11 ++++++++--- test-app/runtime/src/main/cpp/Runtime.h | 8 +++++++- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/test-app/runtime/src/main/cpp/JsV8InspectorClient.cpp b/test-app/runtime/src/main/cpp/JsV8InspectorClient.cpp index 4c356324c..476712248 100644 --- a/test-app/runtime/src/main/cpp/JsV8InspectorClient.cpp +++ b/test-app/runtime/src/main/cpp/JsV8InspectorClient.cpp @@ -1,6 +1,7 @@ #include "JsV8InspectorClient.h" #include -#include + +#include #include #include #include @@ -134,7 +135,7 @@ void JsV8InspectorClient::runMessageLoopOnPause(int context_group_id) { doDispatchMessage(inspectorMessage); } - while (v8::platform::PumpMessageLoop(Runtime::platform, isolate_)) { + while (v8::platform::PumpMessageLoop(Runtime::platform->GetV8Platform(), isolate_)) { } } terminated_ = false; diff --git a/test-app/runtime/src/main/cpp/MessageLoopTimer.cpp b/test-app/runtime/src/main/cpp/MessageLoopTimer.cpp index 6693c9823..12278e0b9 100644 --- a/test-app/runtime/src/main/cpp/MessageLoopTimer.cpp +++ b/test-app/runtime/src/main/cpp/MessageLoopTimer.cpp @@ -3,7 +3,9 @@ #include #include #include -#include "include/libplatform/libplatform.h" + +#include + #include "NativeScriptAssert.h" #include "ArgConverter.h" #include "Runtime.h" @@ -128,7 +130,7 @@ int MessageLoopTimer::PumpMessageLoopCallback(int fd, int events, void* data) { v8::Isolate::Scope isolate_scope(isolate); v8::HandleScope handleScope(isolate); - while (v8::platform::PumpMessageLoop(Runtime::platform, isolate)) { + while (v8::platform::PumpMessageLoop(Runtime::platform->GetV8Platform(), isolate)) { isolate->PerformMicrotaskCheckpoint(); } diff --git a/test-app/runtime/src/main/cpp/Runtime.cpp b/test-app/runtime/src/main/cpp/Runtime.cpp index 3fa434f26..fb9e1dd0b 100644 --- a/test-app/runtime/src/main/cpp/Runtime.cpp +++ b/test-app/runtime/src/main/cpp/Runtime.cpp @@ -28,7 +28,12 @@ #include "ManualInstrumentation.h" #include "IsolateDisposer.h" #include + +#include #include + +#include + #include "File.h" #ifdef APPLICATION_IN_DEBUG @@ -446,8 +451,8 @@ void Runtime::PassUncaughtExceptionFromWorkerToMainHandler(Local mes } static void InitializeV8() { - Runtime::platform = v8::platform::NewDefaultPlatform().release(); - V8::InitializePlatform(Runtime::platform); + Runtime::platform = std::make_shared(); + V8::InitializePlatform(Runtime::platform->GetV8Platform()); V8::Initialize(); } @@ -682,7 +687,7 @@ jmethodID Runtime::GET_USED_MEMORY_METHOD_ID = nullptr; map Runtime::s_id2RuntimeCache; unordered_map Runtime::s_isolate2RuntimesCache; bool Runtime::s_mainThreadInitialized = false; -v8::Platform* Runtime::platform = nullptr; +std::shared_ptr Runtime::platform; int Runtime::m_androidVersion = Runtime::GetAndroidVersion(); ALooper* Runtime::m_mainLooper = nullptr; int Runtime::m_mainLooper_fd[2]; diff --git a/test-app/runtime/src/main/cpp/Runtime.h b/test-app/runtime/src/main/cpp/Runtime.h index 2c5dda84d..fab26b0b7 100644 --- a/test-app/runtime/src/main/cpp/Runtime.h +++ b/test-app/runtime/src/main/cpp/Runtime.h @@ -1,6 +1,8 @@ #ifndef RUNTIME_H_ #define RUNTIME_H_ +#include + #include "v8.h" #include "JniLocalRef.h" #include "ObjectManager.h" @@ -16,6 +18,10 @@ #include #include +namespace cppgc { +class DefaultPlatform; +} + namespace tns { class Runtime { public: @@ -69,7 +75,7 @@ class Runtime { v8::Local GetContext(); - static v8::Platform* platform; + static std::shared_ptr platform; std::string ReadFileText(const std::string& filePath); From a11a490180548a1466c9edc2d344d9732347224d Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 9 May 2023 11:22:46 -0700 Subject: [PATCH 19/23] chore: Remove unused V8 inspector sources These sources are already compiled into the V8 artifacts, and are not compiled as part of the runtime. --- .../src/inspector/protocol/Console.cpp | 231 --- .../src/inspector/protocol/Debugger.cpp | 1748 ----------------- .../src/inspector/protocol/HeapProfiler.cpp | 666 ------- .../src/inspector/protocol/Profiler.cpp | 659 ------- .../src/inspector/protocol/Protocol.cpp | 727 ------- .../src/inspector/protocol/Runtime.cpp | 1629 --------------- .../src/inspector/protocol/Schema.cpp | 160 -- .../inspector/protocol/base_string_adapter.cc | 121 -- 8 files changed, 5941 deletions(-) delete mode 100644 test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Console.cpp delete mode 100644 test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Debugger.cpp delete mode 100644 test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/HeapProfiler.cpp delete mode 100644 test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Profiler.cpp delete mode 100644 test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Protocol.cpp delete mode 100644 test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Runtime.cpp delete mode 100644 test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Schema.cpp delete mode 100644 test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/base_string_adapter.cc diff --git a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Console.cpp b/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Console.cpp deleted file mode 100644 index 1417dc0b4..000000000 --- a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Console.cpp +++ /dev/null @@ -1,231 +0,0 @@ -// This file is generated by TypeBuilder_cpp.template. - -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/inspector/protocol/Console.h" - -#include "src/inspector/protocol/Protocol.h" - -#include "third_party/inspector_protocol/crdtp/cbor.h" -#include "third_party/inspector_protocol/crdtp/find_by_first.h" -#include "third_party/inspector_protocol/crdtp/span.h" - -namespace v8_inspector { -namespace protocol { -namespace Console { - -using v8_crdtp::DeserializerState; -using v8_crdtp::ProtocolTypeTraits; - -// ------------- Enum values from types. - -const char Metainfo::domainName[] = "Console"; -const char Metainfo::commandPrefix[] = "Console."; -const char Metainfo::version[] = "1.3"; - - -const char* ConsoleMessage::SourceEnum::Xml = "xml"; -const char* ConsoleMessage::SourceEnum::Javascript = "javascript"; -const char* ConsoleMessage::SourceEnum::Network = "network"; -const char* ConsoleMessage::SourceEnum::ConsoleApi = "console-api"; -const char* ConsoleMessage::SourceEnum::Storage = "storage"; -const char* ConsoleMessage::SourceEnum::Appcache = "appcache"; -const char* ConsoleMessage::SourceEnum::Rendering = "rendering"; -const char* ConsoleMessage::SourceEnum::Security = "security"; -const char* ConsoleMessage::SourceEnum::Other = "other"; -const char* ConsoleMessage::SourceEnum::Deprecation = "deprecation"; -const char* ConsoleMessage::SourceEnum::Worker = "worker"; - -const char* ConsoleMessage::LevelEnum::Log = "log"; -const char* ConsoleMessage::LevelEnum::Warning = "warning"; -const char* ConsoleMessage::LevelEnum::Error = "error"; -const char* ConsoleMessage::LevelEnum::Debug = "debug"; -const char* ConsoleMessage::LevelEnum::Info = "info"; -V8_CRDTP_BEGIN_DESERIALIZER(ConsoleMessage) - V8_CRDTP_DESERIALIZE_FIELD_OPT("column", m_column), - V8_CRDTP_DESERIALIZE_FIELD("level", m_level), - V8_CRDTP_DESERIALIZE_FIELD_OPT("line", m_line), - V8_CRDTP_DESERIALIZE_FIELD("source", m_source), - V8_CRDTP_DESERIALIZE_FIELD("text", m_text), - V8_CRDTP_DESERIALIZE_FIELD_OPT("url", m_url), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(ConsoleMessage) - V8_CRDTP_SERIALIZE_FIELD("source", m_source); - V8_CRDTP_SERIALIZE_FIELD("level", m_level); - V8_CRDTP_SERIALIZE_FIELD("text", m_text); - V8_CRDTP_SERIALIZE_FIELD("url", m_url); - V8_CRDTP_SERIALIZE_FIELD("line", m_line); - V8_CRDTP_SERIALIZE_FIELD("column", m_column); -V8_CRDTP_END_SERIALIZER(); - - -// ------------- Enum values from params. - - -// ------------- Frontend notifications. - -void Frontend::messageAdded(std::unique_ptr message) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("message"), message); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Console.messageAdded", serializer.Finish())); -} - -void Frontend::flush() -{ - frontend_channel_->FlushProtocolNotifications(); -} - -void Frontend::sendRawNotification(std::unique_ptr notification) -{ - frontend_channel_->SendProtocolNotification(std::move(notification)); -} - -// --------------------- Dispatcher. - -class DomainDispatcherImpl : public protocol::DomainDispatcher { -public: - DomainDispatcherImpl(FrontendChannel* frontendChannel, Backend* backend) - : DomainDispatcher(frontendChannel) - , m_backend(backend) {} - ~DomainDispatcherImpl() override { } - - using CallHandler = void (DomainDispatcherImpl::*)(const v8_crdtp::Dispatchable& dispatchable); - - std::function Dispatch(v8_crdtp::span command_name) override; - - void clearMessages(const v8_crdtp::Dispatchable& dispatchable); - void disable(const v8_crdtp::Dispatchable& dispatchable); - void enable(const v8_crdtp::Dispatchable& dispatchable); - protected: - Backend* m_backend; -}; - -namespace { -// This helper method with a static map of command methods (instance methods -// of DomainDispatcherImpl declared just above) by their name is used immediately below, -// in the DomainDispatcherImpl::Dispatch method. -DomainDispatcherImpl::CallHandler CommandByName(v8_crdtp::span command_name) { - static auto* commands = [](){ - auto* commands = new std::vector, - DomainDispatcherImpl::CallHandler>>{ - { - v8_crdtp::SpanFrom("clearMessages"), - &DomainDispatcherImpl::clearMessages - }, - { - v8_crdtp::SpanFrom("disable"), - &DomainDispatcherImpl::disable - }, - { - v8_crdtp::SpanFrom("enable"), - &DomainDispatcherImpl::enable - }, - }; - return commands; - }(); - return v8_crdtp::FindByFirst(*commands, command_name, nullptr); -} -} // namespace - -std::function DomainDispatcherImpl::Dispatch(v8_crdtp::span command_name) { - CallHandler handler = CommandByName(command_name); - if (!handler) return nullptr; - - return [this, handler](const v8_crdtp::Dispatchable& dispatchable) { - (this->*handler)(dispatchable); - }; -} - - -namespace { - - -} // namespace - -void DomainDispatcherImpl::clearMessages(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->clearMessages(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Console.clearMessages"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::disable(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->disable(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Console.disable"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::enable(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->enable(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Console.enable"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { -// This helper method (with a static map of redirects) is used from Dispatcher::wire -// immediately below. -const std::vector, v8_crdtp::span>>& SortedRedirects() { - static auto* redirects = [](){ - auto* redirects = new std::vector, v8_crdtp::span>>{ - }; - return redirects; - }(); - return *redirects; -} -} // namespace - -// static -void Dispatcher::wire(UberDispatcher* uber, Backend* backend) -{ - auto dispatcher = std::make_unique(uber->channel(), backend); - uber->WireBackend(v8_crdtp::SpanFrom("Console"), SortedRedirects(), std::move(dispatcher)); -} - -} // Console -} // namespace v8_inspector -} // namespace protocol diff --git a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Debugger.cpp b/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Debugger.cpp deleted file mode 100644 index 8e28bbd8d..000000000 --- a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Debugger.cpp +++ /dev/null @@ -1,1748 +0,0 @@ -// This file is generated by TypeBuilder_cpp.template. - -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/inspector/protocol/Debugger.h" - -#include "src/inspector/protocol/Protocol.h" - -#include "third_party/inspector_protocol/crdtp/cbor.h" -#include "third_party/inspector_protocol/crdtp/find_by_first.h" -#include "third_party/inspector_protocol/crdtp/span.h" - -namespace v8_inspector { -namespace protocol { -namespace Debugger { - -using v8_crdtp::DeserializerState; -using v8_crdtp::ProtocolTypeTraits; - -// ------------- Enum values from types. - -const char Metainfo::domainName[] = "Debugger"; -const char Metainfo::commandPrefix[] = "Debugger."; -const char Metainfo::version[] = "1.3"; - - - -V8_CRDTP_BEGIN_DESERIALIZER(Location) - V8_CRDTP_DESERIALIZE_FIELD_OPT("columnNumber", m_columnNumber), - V8_CRDTP_DESERIALIZE_FIELD("lineNumber", m_lineNumber), - V8_CRDTP_DESERIALIZE_FIELD("scriptId", m_scriptId), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(Location) - V8_CRDTP_SERIALIZE_FIELD("scriptId", m_scriptId); - V8_CRDTP_SERIALIZE_FIELD("lineNumber", m_lineNumber); - V8_CRDTP_SERIALIZE_FIELD("columnNumber", m_columnNumber); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(ScriptPosition) - V8_CRDTP_DESERIALIZE_FIELD("columnNumber", m_columnNumber), - V8_CRDTP_DESERIALIZE_FIELD("lineNumber", m_lineNumber), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(ScriptPosition) - V8_CRDTP_SERIALIZE_FIELD("lineNumber", m_lineNumber); - V8_CRDTP_SERIALIZE_FIELD("columnNumber", m_columnNumber); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(LocationRange) - V8_CRDTP_DESERIALIZE_FIELD("end", m_end), - V8_CRDTP_DESERIALIZE_FIELD("scriptId", m_scriptId), - V8_CRDTP_DESERIALIZE_FIELD("start", m_start), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(LocationRange) - V8_CRDTP_SERIALIZE_FIELD("scriptId", m_scriptId); - V8_CRDTP_SERIALIZE_FIELD("start", m_start); - V8_CRDTP_SERIALIZE_FIELD("end", m_end); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(CallFrame) - V8_CRDTP_DESERIALIZE_FIELD("callFrameId", m_callFrameId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("canBeRestarted", m_canBeRestarted), - V8_CRDTP_DESERIALIZE_FIELD_OPT("functionLocation", m_functionLocation), - V8_CRDTP_DESERIALIZE_FIELD("functionName", m_functionName), - V8_CRDTP_DESERIALIZE_FIELD("location", m_location), - V8_CRDTP_DESERIALIZE_FIELD_OPT("returnValue", m_returnValue), - V8_CRDTP_DESERIALIZE_FIELD("scopeChain", m_scopeChain), - V8_CRDTP_DESERIALIZE_FIELD("this", m_this), - V8_CRDTP_DESERIALIZE_FIELD("url", m_url), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(CallFrame) - V8_CRDTP_SERIALIZE_FIELD("callFrameId", m_callFrameId); - V8_CRDTP_SERIALIZE_FIELD("functionName", m_functionName); - V8_CRDTP_SERIALIZE_FIELD("functionLocation", m_functionLocation); - V8_CRDTP_SERIALIZE_FIELD("location", m_location); - V8_CRDTP_SERIALIZE_FIELD("url", m_url); - V8_CRDTP_SERIALIZE_FIELD("scopeChain", m_scopeChain); - V8_CRDTP_SERIALIZE_FIELD("this", m_this); - V8_CRDTP_SERIALIZE_FIELD("returnValue", m_returnValue); - V8_CRDTP_SERIALIZE_FIELD("canBeRestarted", m_canBeRestarted); -V8_CRDTP_END_SERIALIZER(); - - - -const char* Scope::TypeEnum::Global = "global"; -const char* Scope::TypeEnum::Local = "local"; -const char* Scope::TypeEnum::With = "with"; -const char* Scope::TypeEnum::Closure = "closure"; -const char* Scope::TypeEnum::Catch = "catch"; -const char* Scope::TypeEnum::Block = "block"; -const char* Scope::TypeEnum::Script = "script"; -const char* Scope::TypeEnum::Eval = "eval"; -const char* Scope::TypeEnum::Module = "module"; -const char* Scope::TypeEnum::WasmExpressionStack = "wasm-expression-stack"; -V8_CRDTP_BEGIN_DESERIALIZER(Scope) - V8_CRDTP_DESERIALIZE_FIELD_OPT("endLocation", m_endLocation), - V8_CRDTP_DESERIALIZE_FIELD_OPT("name", m_name), - V8_CRDTP_DESERIALIZE_FIELD("object", m_object), - V8_CRDTP_DESERIALIZE_FIELD_OPT("startLocation", m_startLocation), - V8_CRDTP_DESERIALIZE_FIELD("type", m_type), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(Scope) - V8_CRDTP_SERIALIZE_FIELD("type", m_type); - V8_CRDTP_SERIALIZE_FIELD("object", m_object); - V8_CRDTP_SERIALIZE_FIELD("name", m_name); - V8_CRDTP_SERIALIZE_FIELD("startLocation", m_startLocation); - V8_CRDTP_SERIALIZE_FIELD("endLocation", m_endLocation); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(SearchMatch) - V8_CRDTP_DESERIALIZE_FIELD("lineContent", m_lineContent), - V8_CRDTP_DESERIALIZE_FIELD("lineNumber", m_lineNumber), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(SearchMatch) - V8_CRDTP_SERIALIZE_FIELD("lineNumber", m_lineNumber); - V8_CRDTP_SERIALIZE_FIELD("lineContent", m_lineContent); -V8_CRDTP_END_SERIALIZER(); - -// static -std::unique_ptr API::SearchMatch::fromBinary(const uint8_t* data, size_t length) -{ - return protocol::Debugger::SearchMatch::FromBinary(data, length); -} - - -const char* BreakLocation::TypeEnum::DebuggerStatement = "debuggerStatement"; -const char* BreakLocation::TypeEnum::Call = "call"; -const char* BreakLocation::TypeEnum::Return = "return"; -V8_CRDTP_BEGIN_DESERIALIZER(BreakLocation) - V8_CRDTP_DESERIALIZE_FIELD_OPT("columnNumber", m_columnNumber), - V8_CRDTP_DESERIALIZE_FIELD("lineNumber", m_lineNumber), - V8_CRDTP_DESERIALIZE_FIELD("scriptId", m_scriptId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("type", m_type), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(BreakLocation) - V8_CRDTP_SERIALIZE_FIELD("scriptId", m_scriptId); - V8_CRDTP_SERIALIZE_FIELD("lineNumber", m_lineNumber); - V8_CRDTP_SERIALIZE_FIELD("columnNumber", m_columnNumber); - V8_CRDTP_SERIALIZE_FIELD("type", m_type); -V8_CRDTP_END_SERIALIZER(); - - -namespace ScriptLanguageEnum { -const char JavaScript[] = "JavaScript"; -const char WebAssembly[] = "WebAssembly"; -} // namespace ScriptLanguageEnum - - - -const char* DebugSymbols::TypeEnum::None = "None"; -const char* DebugSymbols::TypeEnum::SourceMap = "SourceMap"; -const char* DebugSymbols::TypeEnum::EmbeddedDWARF = "EmbeddedDWARF"; -const char* DebugSymbols::TypeEnum::ExternalDWARF = "ExternalDWARF"; -V8_CRDTP_BEGIN_DESERIALIZER(DebugSymbols) - V8_CRDTP_DESERIALIZE_FIELD_OPT("externalURL", m_externalURL), - V8_CRDTP_DESERIALIZE_FIELD("type", m_type), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(DebugSymbols) - V8_CRDTP_SERIALIZE_FIELD("type", m_type); - V8_CRDTP_SERIALIZE_FIELD("externalURL", m_externalURL); -V8_CRDTP_END_SERIALIZER(); - - -// ------------- Enum values from params. - - -namespace ContinueToLocation { -namespace TargetCallFramesEnum { -const char* Any = "any"; -const char* Current = "current"; -} // namespace TargetCallFramesEnum -} // namespace ContinueToLocation - -namespace SetInstrumentationBreakpoint { -namespace InstrumentationEnum { -const char* BeforeScriptExecution = "beforeScriptExecution"; -const char* BeforeScriptWithSourceMapExecution = "beforeScriptWithSourceMapExecution"; -} // namespace InstrumentationEnum -} // namespace SetInstrumentationBreakpoint - -namespace SetPauseOnExceptions { -namespace StateEnum { -const char* None = "none"; -const char* Uncaught = "uncaught"; -const char* All = "all"; -} // namespace StateEnum -} // namespace SetPauseOnExceptions - -namespace Paused { -namespace ReasonEnum { -const char* Ambiguous = "ambiguous"; -const char* Assert = "assert"; -const char* CSPViolation = "CSPViolation"; -const char* DebugCommand = "debugCommand"; -const char* DOM = "DOM"; -const char* EventListener = "EventListener"; -const char* Exception = "exception"; -const char* Instrumentation = "instrumentation"; -const char* OOM = "OOM"; -const char* Other = "other"; -const char* PromiseRejection = "promiseRejection"; -const char* XHR = "XHR"; -} // namespace ReasonEnum -} // namespace Paused - -namespace API { -namespace Paused { -namespace ReasonEnum { -const char* Ambiguous = "ambiguous"; -const char* Assert = "assert"; -const char* CSPViolation = "CSPViolation"; -const char* DebugCommand = "debugCommand"; -const char* DOM = "DOM"; -const char* EventListener = "EventListener"; -const char* Exception = "exception"; -const char* Instrumentation = "instrumentation"; -const char* OOM = "OOM"; -const char* Other = "other"; -const char* PromiseRejection = "promiseRejection"; -const char* XHR = "XHR"; -} // namespace ReasonEnum -} // namespace Paused -} // namespace API - -// ------------- Frontend notifications. - -void Frontend::breakpointResolved(const String& breakpointId, std::unique_ptr location) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("breakpointId"), breakpointId); - serializer.AddField(v8_crdtp::MakeSpan("location"), location); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Debugger.breakpointResolved", serializer.Finish())); -} - -void Frontend::paused(std::unique_ptr> callFrames, const String& reason, Maybe data, Maybe> hitBreakpoints, Maybe asyncStackTrace, Maybe asyncStackTraceId, Maybe asyncCallStackTraceId) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("callFrames"), callFrames); - serializer.AddField(v8_crdtp::MakeSpan("reason"), reason); - serializer.AddField(v8_crdtp::MakeSpan("data"), data); - serializer.AddField(v8_crdtp::MakeSpan("hitBreakpoints"), hitBreakpoints); - serializer.AddField(v8_crdtp::MakeSpan("asyncStackTrace"), asyncStackTrace); - serializer.AddField(v8_crdtp::MakeSpan("asyncStackTraceId"), asyncStackTraceId); - serializer.AddField(v8_crdtp::MakeSpan("asyncCallStackTraceId"), asyncCallStackTraceId); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Debugger.paused", serializer.Finish())); -} - -void Frontend::resumed() -{ - if (!frontend_channel_) - return; - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Debugger.resumed")); -} - -void Frontend::scriptFailedToParse(const String& scriptId, const String& url, int startLine, int startColumn, int endLine, int endColumn, int executionContextId, const String& hash, Maybe executionContextAuxData, Maybe sourceMapURL, Maybe hasSourceURL, Maybe isModule, Maybe length, Maybe stackTrace, Maybe codeOffset, Maybe scriptLanguage, Maybe embedderName) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("scriptId"), scriptId); - serializer.AddField(v8_crdtp::MakeSpan("url"), url); - serializer.AddField(v8_crdtp::MakeSpan("startLine"), startLine); - serializer.AddField(v8_crdtp::MakeSpan("startColumn"), startColumn); - serializer.AddField(v8_crdtp::MakeSpan("endLine"), endLine); - serializer.AddField(v8_crdtp::MakeSpan("endColumn"), endColumn); - serializer.AddField(v8_crdtp::MakeSpan("executionContextId"), executionContextId); - serializer.AddField(v8_crdtp::MakeSpan("hash"), hash); - serializer.AddField(v8_crdtp::MakeSpan("executionContextAuxData"), executionContextAuxData); - serializer.AddField(v8_crdtp::MakeSpan("sourceMapURL"), sourceMapURL); - serializer.AddField(v8_crdtp::MakeSpan("hasSourceURL"), hasSourceURL); - serializer.AddField(v8_crdtp::MakeSpan("isModule"), isModule); - serializer.AddField(v8_crdtp::MakeSpan("length"), length); - serializer.AddField(v8_crdtp::MakeSpan("stackTrace"), stackTrace); - serializer.AddField(v8_crdtp::MakeSpan("codeOffset"), codeOffset); - serializer.AddField(v8_crdtp::MakeSpan("scriptLanguage"), scriptLanguage); - serializer.AddField(v8_crdtp::MakeSpan("embedderName"), embedderName); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Debugger.scriptFailedToParse", serializer.Finish())); -} - -void Frontend::scriptParsed(const String& scriptId, const String& url, int startLine, int startColumn, int endLine, int endColumn, int executionContextId, const String& hash, Maybe executionContextAuxData, Maybe isLiveEdit, Maybe sourceMapURL, Maybe hasSourceURL, Maybe isModule, Maybe length, Maybe stackTrace, Maybe codeOffset, Maybe scriptLanguage, Maybe debugSymbols, Maybe embedderName) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("scriptId"), scriptId); - serializer.AddField(v8_crdtp::MakeSpan("url"), url); - serializer.AddField(v8_crdtp::MakeSpan("startLine"), startLine); - serializer.AddField(v8_crdtp::MakeSpan("startColumn"), startColumn); - serializer.AddField(v8_crdtp::MakeSpan("endLine"), endLine); - serializer.AddField(v8_crdtp::MakeSpan("endColumn"), endColumn); - serializer.AddField(v8_crdtp::MakeSpan("executionContextId"), executionContextId); - serializer.AddField(v8_crdtp::MakeSpan("hash"), hash); - serializer.AddField(v8_crdtp::MakeSpan("executionContextAuxData"), executionContextAuxData); - serializer.AddField(v8_crdtp::MakeSpan("isLiveEdit"), isLiveEdit); - serializer.AddField(v8_crdtp::MakeSpan("sourceMapURL"), sourceMapURL); - serializer.AddField(v8_crdtp::MakeSpan("hasSourceURL"), hasSourceURL); - serializer.AddField(v8_crdtp::MakeSpan("isModule"), isModule); - serializer.AddField(v8_crdtp::MakeSpan("length"), length); - serializer.AddField(v8_crdtp::MakeSpan("stackTrace"), stackTrace); - serializer.AddField(v8_crdtp::MakeSpan("codeOffset"), codeOffset); - serializer.AddField(v8_crdtp::MakeSpan("scriptLanguage"), scriptLanguage); - serializer.AddField(v8_crdtp::MakeSpan("debugSymbols"), debugSymbols); - serializer.AddField(v8_crdtp::MakeSpan("embedderName"), embedderName); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Debugger.scriptParsed", serializer.Finish())); -} - -void Frontend::flush() -{ - frontend_channel_->FlushProtocolNotifications(); -} - -void Frontend::sendRawNotification(std::unique_ptr notification) -{ - frontend_channel_->SendProtocolNotification(std::move(notification)); -} - -// --------------------- Dispatcher. - -class DomainDispatcherImpl : public protocol::DomainDispatcher { -public: - DomainDispatcherImpl(FrontendChannel* frontendChannel, Backend* backend) - : DomainDispatcher(frontendChannel) - , m_backend(backend) {} - ~DomainDispatcherImpl() override { } - - using CallHandler = void (DomainDispatcherImpl::*)(const v8_crdtp::Dispatchable& dispatchable); - - std::function Dispatch(v8_crdtp::span command_name) override; - - void continueToLocation(const v8_crdtp::Dispatchable& dispatchable); - void disable(const v8_crdtp::Dispatchable& dispatchable); - void enable(const v8_crdtp::Dispatchable& dispatchable); - void evaluateOnCallFrame(const v8_crdtp::Dispatchable& dispatchable); - void getPossibleBreakpoints(const v8_crdtp::Dispatchable& dispatchable); - void getScriptSource(const v8_crdtp::Dispatchable& dispatchable); - void getWasmBytecode(const v8_crdtp::Dispatchable& dispatchable); - void getStackTrace(const v8_crdtp::Dispatchable& dispatchable); - void pause(const v8_crdtp::Dispatchable& dispatchable); - void pauseOnAsyncCall(const v8_crdtp::Dispatchable& dispatchable); - void removeBreakpoint(const v8_crdtp::Dispatchable& dispatchable); - void restartFrame(const v8_crdtp::Dispatchable& dispatchable); - void resume(const v8_crdtp::Dispatchable& dispatchable); - void searchInContent(const v8_crdtp::Dispatchable& dispatchable); - void setAsyncCallStackDepth(const v8_crdtp::Dispatchable& dispatchable); - void setBlackboxPatterns(const v8_crdtp::Dispatchable& dispatchable); - void setBlackboxedRanges(const v8_crdtp::Dispatchable& dispatchable); - void setBreakpoint(const v8_crdtp::Dispatchable& dispatchable); - void setInstrumentationBreakpoint(const v8_crdtp::Dispatchable& dispatchable); - void setBreakpointByUrl(const v8_crdtp::Dispatchable& dispatchable); - void setBreakpointOnFunctionCall(const v8_crdtp::Dispatchable& dispatchable); - void setBreakpointsActive(const v8_crdtp::Dispatchable& dispatchable); - void setPauseOnExceptions(const v8_crdtp::Dispatchable& dispatchable); - void setReturnValue(const v8_crdtp::Dispatchable& dispatchable); - void setScriptSource(const v8_crdtp::Dispatchable& dispatchable); - void setSkipAllPauses(const v8_crdtp::Dispatchable& dispatchable); - void setVariableValue(const v8_crdtp::Dispatchable& dispatchable); - void stepInto(const v8_crdtp::Dispatchable& dispatchable); - void stepOut(const v8_crdtp::Dispatchable& dispatchable); - void stepOver(const v8_crdtp::Dispatchable& dispatchable); - protected: - Backend* m_backend; -}; - -namespace { -// This helper method with a static map of command methods (instance methods -// of DomainDispatcherImpl declared just above) by their name is used immediately below, -// in the DomainDispatcherImpl::Dispatch method. -DomainDispatcherImpl::CallHandler CommandByName(v8_crdtp::span command_name) { - static auto* commands = [](){ - auto* commands = new std::vector, - DomainDispatcherImpl::CallHandler>>{ - { - v8_crdtp::SpanFrom("continueToLocation"), - &DomainDispatcherImpl::continueToLocation - }, - { - v8_crdtp::SpanFrom("disable"), - &DomainDispatcherImpl::disable - }, - { - v8_crdtp::SpanFrom("enable"), - &DomainDispatcherImpl::enable - }, - { - v8_crdtp::SpanFrom("evaluateOnCallFrame"), - &DomainDispatcherImpl::evaluateOnCallFrame - }, - { - v8_crdtp::SpanFrom("getPossibleBreakpoints"), - &DomainDispatcherImpl::getPossibleBreakpoints - }, - { - v8_crdtp::SpanFrom("getScriptSource"), - &DomainDispatcherImpl::getScriptSource - }, - { - v8_crdtp::SpanFrom("getStackTrace"), - &DomainDispatcherImpl::getStackTrace - }, - { - v8_crdtp::SpanFrom("getWasmBytecode"), - &DomainDispatcherImpl::getWasmBytecode - }, - { - v8_crdtp::SpanFrom("pause"), - &DomainDispatcherImpl::pause - }, - { - v8_crdtp::SpanFrom("pauseOnAsyncCall"), - &DomainDispatcherImpl::pauseOnAsyncCall - }, - { - v8_crdtp::SpanFrom("removeBreakpoint"), - &DomainDispatcherImpl::removeBreakpoint - }, - { - v8_crdtp::SpanFrom("restartFrame"), - &DomainDispatcherImpl::restartFrame - }, - { - v8_crdtp::SpanFrom("resume"), - &DomainDispatcherImpl::resume - }, - { - v8_crdtp::SpanFrom("searchInContent"), - &DomainDispatcherImpl::searchInContent - }, - { - v8_crdtp::SpanFrom("setAsyncCallStackDepth"), - &DomainDispatcherImpl::setAsyncCallStackDepth - }, - { - v8_crdtp::SpanFrom("setBlackboxPatterns"), - &DomainDispatcherImpl::setBlackboxPatterns - }, - { - v8_crdtp::SpanFrom("setBlackboxedRanges"), - &DomainDispatcherImpl::setBlackboxedRanges - }, - { - v8_crdtp::SpanFrom("setBreakpoint"), - &DomainDispatcherImpl::setBreakpoint - }, - { - v8_crdtp::SpanFrom("setBreakpointByUrl"), - &DomainDispatcherImpl::setBreakpointByUrl - }, - { - v8_crdtp::SpanFrom("setBreakpointOnFunctionCall"), - &DomainDispatcherImpl::setBreakpointOnFunctionCall - }, - { - v8_crdtp::SpanFrom("setBreakpointsActive"), - &DomainDispatcherImpl::setBreakpointsActive - }, - { - v8_crdtp::SpanFrom("setInstrumentationBreakpoint"), - &DomainDispatcherImpl::setInstrumentationBreakpoint - }, - { - v8_crdtp::SpanFrom("setPauseOnExceptions"), - &DomainDispatcherImpl::setPauseOnExceptions - }, - { - v8_crdtp::SpanFrom("setReturnValue"), - &DomainDispatcherImpl::setReturnValue - }, - { - v8_crdtp::SpanFrom("setScriptSource"), - &DomainDispatcherImpl::setScriptSource - }, - { - v8_crdtp::SpanFrom("setSkipAllPauses"), - &DomainDispatcherImpl::setSkipAllPauses - }, - { - v8_crdtp::SpanFrom("setVariableValue"), - &DomainDispatcherImpl::setVariableValue - }, - { - v8_crdtp::SpanFrom("stepInto"), - &DomainDispatcherImpl::stepInto - }, - { - v8_crdtp::SpanFrom("stepOut"), - &DomainDispatcherImpl::stepOut - }, - { - v8_crdtp::SpanFrom("stepOver"), - &DomainDispatcherImpl::stepOver - }, - }; - return commands; - }(); - return v8_crdtp::FindByFirst(*commands, command_name, nullptr); -} -} // namespace - -std::function DomainDispatcherImpl::Dispatch(v8_crdtp::span command_name) { - CallHandler handler = CommandByName(command_name); - if (!handler) return nullptr; - - return [this, handler](const v8_crdtp::Dispatchable& dispatchable) { - (this->*handler)(dispatchable); - }; -} - - -namespace { - -struct continueToLocationParams : public v8_crdtp::DeserializableProtocolObject { - std::unique_ptr location; - Maybe targetCallFrames; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(continueToLocationParams) - V8_CRDTP_DESERIALIZE_FIELD("location", location), - V8_CRDTP_DESERIALIZE_FIELD_OPT("targetCallFrames", targetCallFrames), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::continueToLocation(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - continueToLocationParams params; - continueToLocationParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->continueToLocation(std::move(params.location), std::move(params.targetCallFrames)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.continueToLocation"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::disable(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->disable(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.disable"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct enableParams : public v8_crdtp::DeserializableProtocolObject { - Maybe maxScriptsCacheSize; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(enableParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("maxScriptsCacheSize", maxScriptsCacheSize), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::enable(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - enableParams params; - enableParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - String out_debuggerId; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->enable(std::move(params.maxScriptsCacheSize), &out_debuggerId); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.enable"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("debuggerId"), out_debuggerId); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct evaluateOnCallFrameParams : public v8_crdtp::DeserializableProtocolObject { - String callFrameId; - String expression; - Maybe objectGroup; - Maybe includeCommandLineAPI; - Maybe silent; - Maybe returnByValue; - Maybe generatePreview; - Maybe throwOnSideEffect; - Maybe timeout; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(evaluateOnCallFrameParams) - V8_CRDTP_DESERIALIZE_FIELD("callFrameId", callFrameId), - V8_CRDTP_DESERIALIZE_FIELD("expression", expression), - V8_CRDTP_DESERIALIZE_FIELD_OPT("generatePreview", generatePreview), - V8_CRDTP_DESERIALIZE_FIELD_OPT("includeCommandLineAPI", includeCommandLineAPI), - V8_CRDTP_DESERIALIZE_FIELD_OPT("objectGroup", objectGroup), - V8_CRDTP_DESERIALIZE_FIELD_OPT("returnByValue", returnByValue), - V8_CRDTP_DESERIALIZE_FIELD_OPT("silent", silent), - V8_CRDTP_DESERIALIZE_FIELD_OPT("throwOnSideEffect", throwOnSideEffect), - V8_CRDTP_DESERIALIZE_FIELD_OPT("timeout", timeout), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::evaluateOnCallFrame(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - evaluateOnCallFrameParams params; - evaluateOnCallFrameParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - std::unique_ptr out_result; - Maybe out_exceptionDetails; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->evaluateOnCallFrame(params.callFrameId, params.expression, std::move(params.objectGroup), std::move(params.includeCommandLineAPI), std::move(params.silent), std::move(params.returnByValue), std::move(params.generatePreview), std::move(params.throwOnSideEffect), std::move(params.timeout), &out_result, &out_exceptionDetails); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.evaluateOnCallFrame"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("result"), out_result); - serializer.AddField(v8_crdtp::MakeSpan("exceptionDetails"), out_exceptionDetails); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct getPossibleBreakpointsParams : public v8_crdtp::DeserializableProtocolObject { - std::unique_ptr start; - Maybe end; - Maybe restrictToFunction; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(getPossibleBreakpointsParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("end", end), - V8_CRDTP_DESERIALIZE_FIELD_OPT("restrictToFunction", restrictToFunction), - V8_CRDTP_DESERIALIZE_FIELD("start", start), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::getPossibleBreakpoints(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - getPossibleBreakpointsParams params; - getPossibleBreakpointsParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - std::unique_ptr> out_locations; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getPossibleBreakpoints(std::move(params.start), std::move(params.end), std::move(params.restrictToFunction), &out_locations); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.getPossibleBreakpoints"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("locations"), out_locations); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct getScriptSourceParams : public v8_crdtp::DeserializableProtocolObject { - String scriptId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(getScriptSourceParams) - V8_CRDTP_DESERIALIZE_FIELD("scriptId", scriptId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::getScriptSource(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - getScriptSourceParams params; - getScriptSourceParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - String out_scriptSource; - Maybe out_bytecode; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getScriptSource(params.scriptId, &out_scriptSource, &out_bytecode); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.getScriptSource"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("scriptSource"), out_scriptSource); - serializer.AddField(v8_crdtp::MakeSpan("bytecode"), out_bytecode); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct getWasmBytecodeParams : public v8_crdtp::DeserializableProtocolObject { - String scriptId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(getWasmBytecodeParams) - V8_CRDTP_DESERIALIZE_FIELD("scriptId", scriptId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::getWasmBytecode(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - getWasmBytecodeParams params; - getWasmBytecodeParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - Binary out_bytecode; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getWasmBytecode(params.scriptId, &out_bytecode); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.getWasmBytecode"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("bytecode"), out_bytecode); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct getStackTraceParams : public v8_crdtp::DeserializableProtocolObject { - std::unique_ptr stackTraceId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(getStackTraceParams) - V8_CRDTP_DESERIALIZE_FIELD("stackTraceId", stackTraceId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::getStackTrace(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - getStackTraceParams params; - getStackTraceParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - std::unique_ptr out_stackTrace; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getStackTrace(std::move(params.stackTraceId), &out_stackTrace); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.getStackTrace"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("stackTrace"), out_stackTrace); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::pause(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->pause(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.pause"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct pauseOnAsyncCallParams : public v8_crdtp::DeserializableProtocolObject { - std::unique_ptr parentStackTraceId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(pauseOnAsyncCallParams) - V8_CRDTP_DESERIALIZE_FIELD("parentStackTraceId", parentStackTraceId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::pauseOnAsyncCall(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - pauseOnAsyncCallParams params; - pauseOnAsyncCallParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->pauseOnAsyncCall(std::move(params.parentStackTraceId)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.pauseOnAsyncCall"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct removeBreakpointParams : public v8_crdtp::DeserializableProtocolObject { - String breakpointId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(removeBreakpointParams) - V8_CRDTP_DESERIALIZE_FIELD("breakpointId", breakpointId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::removeBreakpoint(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - removeBreakpointParams params; - removeBreakpointParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->removeBreakpoint(params.breakpointId); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.removeBreakpoint"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct restartFrameParams : public v8_crdtp::DeserializableProtocolObject { - String callFrameId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(restartFrameParams) - V8_CRDTP_DESERIALIZE_FIELD("callFrameId", callFrameId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::restartFrame(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - restartFrameParams params; - restartFrameParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - std::unique_ptr> out_callFrames; - Maybe out_asyncStackTrace; - Maybe out_asyncStackTraceId; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->restartFrame(params.callFrameId, &out_callFrames, &out_asyncStackTrace, &out_asyncStackTraceId); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.restartFrame"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("callFrames"), out_callFrames); - serializer.AddField(v8_crdtp::MakeSpan("asyncStackTrace"), out_asyncStackTrace); - serializer.AddField(v8_crdtp::MakeSpan("asyncStackTraceId"), out_asyncStackTraceId); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct resumeParams : public v8_crdtp::DeserializableProtocolObject { - Maybe terminateOnResume; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(resumeParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("terminateOnResume", terminateOnResume), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::resume(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - resumeParams params; - resumeParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->resume(std::move(params.terminateOnResume)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.resume"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct searchInContentParams : public v8_crdtp::DeserializableProtocolObject { - String scriptId; - String query; - Maybe caseSensitive; - Maybe isRegex; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(searchInContentParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("caseSensitive", caseSensitive), - V8_CRDTP_DESERIALIZE_FIELD_OPT("isRegex", isRegex), - V8_CRDTP_DESERIALIZE_FIELD("query", query), - V8_CRDTP_DESERIALIZE_FIELD("scriptId", scriptId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::searchInContent(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - searchInContentParams params; - searchInContentParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - std::unique_ptr> out_result; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->searchInContent(params.scriptId, params.query, std::move(params.caseSensitive), std::move(params.isRegex), &out_result); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.searchInContent"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("result"), out_result); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct setAsyncCallStackDepthParams : public v8_crdtp::DeserializableProtocolObject { - int maxDepth; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setAsyncCallStackDepthParams) - V8_CRDTP_DESERIALIZE_FIELD("maxDepth", maxDepth), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setAsyncCallStackDepth(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setAsyncCallStackDepthParams params; - setAsyncCallStackDepthParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setAsyncCallStackDepth(params.maxDepth); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setAsyncCallStackDepth"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct setBlackboxPatternsParams : public v8_crdtp::DeserializableProtocolObject { - std::unique_ptr> patterns; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setBlackboxPatternsParams) - V8_CRDTP_DESERIALIZE_FIELD("patterns", patterns), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setBlackboxPatterns(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setBlackboxPatternsParams params; - setBlackboxPatternsParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setBlackboxPatterns(std::move(params.patterns)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setBlackboxPatterns"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct setBlackboxedRangesParams : public v8_crdtp::DeserializableProtocolObject { - String scriptId; - std::unique_ptr> positions; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setBlackboxedRangesParams) - V8_CRDTP_DESERIALIZE_FIELD("positions", positions), - V8_CRDTP_DESERIALIZE_FIELD("scriptId", scriptId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setBlackboxedRanges(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setBlackboxedRangesParams params; - setBlackboxedRangesParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setBlackboxedRanges(params.scriptId, std::move(params.positions)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setBlackboxedRanges"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct setBreakpointParams : public v8_crdtp::DeserializableProtocolObject { - std::unique_ptr location; - Maybe condition; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setBreakpointParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("condition", condition), - V8_CRDTP_DESERIALIZE_FIELD("location", location), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setBreakpoint(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setBreakpointParams params; - setBreakpointParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - String out_breakpointId; - std::unique_ptr out_actualLocation; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setBreakpoint(std::move(params.location), std::move(params.condition), &out_breakpointId, &out_actualLocation); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setBreakpoint"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("breakpointId"), out_breakpointId); - serializer.AddField(v8_crdtp::MakeSpan("actualLocation"), out_actualLocation); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct setInstrumentationBreakpointParams : public v8_crdtp::DeserializableProtocolObject { - String instrumentation; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setInstrumentationBreakpointParams) - V8_CRDTP_DESERIALIZE_FIELD("instrumentation", instrumentation), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setInstrumentationBreakpoint(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setInstrumentationBreakpointParams params; - setInstrumentationBreakpointParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - String out_breakpointId; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setInstrumentationBreakpoint(params.instrumentation, &out_breakpointId); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setInstrumentationBreakpoint"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("breakpointId"), out_breakpointId); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct setBreakpointByUrlParams : public v8_crdtp::DeserializableProtocolObject { - int lineNumber; - Maybe url; - Maybe urlRegex; - Maybe scriptHash; - Maybe columnNumber; - Maybe condition; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setBreakpointByUrlParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("columnNumber", columnNumber), - V8_CRDTP_DESERIALIZE_FIELD_OPT("condition", condition), - V8_CRDTP_DESERIALIZE_FIELD("lineNumber", lineNumber), - V8_CRDTP_DESERIALIZE_FIELD_OPT("scriptHash", scriptHash), - V8_CRDTP_DESERIALIZE_FIELD_OPT("url", url), - V8_CRDTP_DESERIALIZE_FIELD_OPT("urlRegex", urlRegex), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setBreakpointByUrl(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setBreakpointByUrlParams params; - setBreakpointByUrlParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - String out_breakpointId; - std::unique_ptr> out_locations; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setBreakpointByUrl(params.lineNumber, std::move(params.url), std::move(params.urlRegex), std::move(params.scriptHash), std::move(params.columnNumber), std::move(params.condition), &out_breakpointId, &out_locations); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setBreakpointByUrl"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("breakpointId"), out_breakpointId); - serializer.AddField(v8_crdtp::MakeSpan("locations"), out_locations); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct setBreakpointOnFunctionCallParams : public v8_crdtp::DeserializableProtocolObject { - String objectId; - Maybe condition; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setBreakpointOnFunctionCallParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("condition", condition), - V8_CRDTP_DESERIALIZE_FIELD("objectId", objectId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setBreakpointOnFunctionCall(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setBreakpointOnFunctionCallParams params; - setBreakpointOnFunctionCallParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - String out_breakpointId; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setBreakpointOnFunctionCall(params.objectId, std::move(params.condition), &out_breakpointId); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setBreakpointOnFunctionCall"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("breakpointId"), out_breakpointId); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct setBreakpointsActiveParams : public v8_crdtp::DeserializableProtocolObject { - bool active; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setBreakpointsActiveParams) - V8_CRDTP_DESERIALIZE_FIELD("active", active), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setBreakpointsActive(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setBreakpointsActiveParams params; - setBreakpointsActiveParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setBreakpointsActive(params.active); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setBreakpointsActive"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct setPauseOnExceptionsParams : public v8_crdtp::DeserializableProtocolObject { - String state; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setPauseOnExceptionsParams) - V8_CRDTP_DESERIALIZE_FIELD("state", state), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setPauseOnExceptions(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setPauseOnExceptionsParams params; - setPauseOnExceptionsParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setPauseOnExceptions(params.state); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setPauseOnExceptions"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct setReturnValueParams : public v8_crdtp::DeserializableProtocolObject { - std::unique_ptr newValue; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setReturnValueParams) - V8_CRDTP_DESERIALIZE_FIELD("newValue", newValue), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setReturnValue(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setReturnValueParams params; - setReturnValueParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setReturnValue(std::move(params.newValue)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setReturnValue"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct setScriptSourceParams : public v8_crdtp::DeserializableProtocolObject { - String scriptId; - String scriptSource; - Maybe dryRun; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setScriptSourceParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("dryRun", dryRun), - V8_CRDTP_DESERIALIZE_FIELD("scriptId", scriptId), - V8_CRDTP_DESERIALIZE_FIELD("scriptSource", scriptSource), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setScriptSource(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setScriptSourceParams params; - setScriptSourceParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - Maybe> out_callFrames; - Maybe out_stackChanged; - Maybe out_asyncStackTrace; - Maybe out_asyncStackTraceId; - Maybe out_exceptionDetails; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setScriptSource(params.scriptId, params.scriptSource, std::move(params.dryRun), &out_callFrames, &out_stackChanged, &out_asyncStackTrace, &out_asyncStackTraceId, &out_exceptionDetails); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setScriptSource"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("callFrames"), out_callFrames); - serializer.AddField(v8_crdtp::MakeSpan("stackChanged"), out_stackChanged); - serializer.AddField(v8_crdtp::MakeSpan("asyncStackTrace"), out_asyncStackTrace); - serializer.AddField(v8_crdtp::MakeSpan("asyncStackTraceId"), out_asyncStackTraceId); - serializer.AddField(v8_crdtp::MakeSpan("exceptionDetails"), out_exceptionDetails); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct setSkipAllPausesParams : public v8_crdtp::DeserializableProtocolObject { - bool skip; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setSkipAllPausesParams) - V8_CRDTP_DESERIALIZE_FIELD("skip", skip), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setSkipAllPauses(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setSkipAllPausesParams params; - setSkipAllPausesParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setSkipAllPauses(params.skip); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setSkipAllPauses"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct setVariableValueParams : public v8_crdtp::DeserializableProtocolObject { - int scopeNumber; - String variableName; - std::unique_ptr newValue; - String callFrameId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setVariableValueParams) - V8_CRDTP_DESERIALIZE_FIELD("callFrameId", callFrameId), - V8_CRDTP_DESERIALIZE_FIELD("newValue", newValue), - V8_CRDTP_DESERIALIZE_FIELD("scopeNumber", scopeNumber), - V8_CRDTP_DESERIALIZE_FIELD("variableName", variableName), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setVariableValue(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setVariableValueParams params; - setVariableValueParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setVariableValue(params.scopeNumber, params.variableName, std::move(params.newValue), params.callFrameId); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.setVariableValue"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct stepIntoParams : public v8_crdtp::DeserializableProtocolObject { - Maybe breakOnAsyncCall; - Maybe> skipList; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(stepIntoParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("breakOnAsyncCall", breakOnAsyncCall), - V8_CRDTP_DESERIALIZE_FIELD_OPT("skipList", skipList), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::stepInto(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - stepIntoParams params; - stepIntoParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->stepInto(std::move(params.breakOnAsyncCall), std::move(params.skipList)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.stepInto"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::stepOut(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->stepOut(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.stepOut"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct stepOverParams : public v8_crdtp::DeserializableProtocolObject { - Maybe> skipList; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(stepOverParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("skipList", skipList), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::stepOver(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - stepOverParams params; - stepOverParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->stepOver(std::move(params.skipList)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Debugger.stepOver"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { -// This helper method (with a static map of redirects) is used from Dispatcher::wire -// immediately below. -const std::vector, v8_crdtp::span>>& SortedRedirects() { - static auto* redirects = [](){ - auto* redirects = new std::vector, v8_crdtp::span>>{ - }; - return redirects; - }(); - return *redirects; -} -} // namespace - -// static -void Dispatcher::wire(UberDispatcher* uber, Backend* backend) -{ - auto dispatcher = std::make_unique(uber->channel(), backend); - uber->WireBackend(v8_crdtp::SpanFrom("Debugger"), SortedRedirects(), std::move(dispatcher)); -} - -} // Debugger -} // namespace v8_inspector -} // namespace protocol diff --git a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/HeapProfiler.cpp b/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/HeapProfiler.cpp deleted file mode 100644 index a6a725b6d..000000000 --- a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/HeapProfiler.cpp +++ /dev/null @@ -1,666 +0,0 @@ -// This file is generated by TypeBuilder_cpp.template. - -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/inspector/protocol/HeapProfiler.h" - -#include "src/inspector/protocol/Protocol.h" - -#include "third_party/inspector_protocol/crdtp/cbor.h" -#include "third_party/inspector_protocol/crdtp/find_by_first.h" -#include "third_party/inspector_protocol/crdtp/span.h" - -namespace v8_inspector { -namespace protocol { -namespace HeapProfiler { - -using v8_crdtp::DeserializerState; -using v8_crdtp::ProtocolTypeTraits; - -// ------------- Enum values from types. - -const char Metainfo::domainName[] = "HeapProfiler"; -const char Metainfo::commandPrefix[] = "HeapProfiler."; -const char Metainfo::version[] = "1.3"; - - -V8_CRDTP_BEGIN_DESERIALIZER(SamplingHeapProfileNode) - V8_CRDTP_DESERIALIZE_FIELD("callFrame", m_callFrame), - V8_CRDTP_DESERIALIZE_FIELD("children", m_children), - V8_CRDTP_DESERIALIZE_FIELD("id", m_id), - V8_CRDTP_DESERIALIZE_FIELD("selfSize", m_selfSize), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(SamplingHeapProfileNode) - V8_CRDTP_SERIALIZE_FIELD("callFrame", m_callFrame); - V8_CRDTP_SERIALIZE_FIELD("selfSize", m_selfSize); - V8_CRDTP_SERIALIZE_FIELD("id", m_id); - V8_CRDTP_SERIALIZE_FIELD("children", m_children); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(SamplingHeapProfileSample) - V8_CRDTP_DESERIALIZE_FIELD("nodeId", m_nodeId), - V8_CRDTP_DESERIALIZE_FIELD("ordinal", m_ordinal), - V8_CRDTP_DESERIALIZE_FIELD("size", m_size), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(SamplingHeapProfileSample) - V8_CRDTP_SERIALIZE_FIELD("size", m_size); - V8_CRDTP_SERIALIZE_FIELD("nodeId", m_nodeId); - V8_CRDTP_SERIALIZE_FIELD("ordinal", m_ordinal); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(SamplingHeapProfile) - V8_CRDTP_DESERIALIZE_FIELD("head", m_head), - V8_CRDTP_DESERIALIZE_FIELD("samples", m_samples), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(SamplingHeapProfile) - V8_CRDTP_SERIALIZE_FIELD("head", m_head); - V8_CRDTP_SERIALIZE_FIELD("samples", m_samples); -V8_CRDTP_END_SERIALIZER(); - - -// ------------- Enum values from params. - - -// ------------- Frontend notifications. - -void Frontend::addHeapSnapshotChunk(const String& chunk) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("chunk"), chunk); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("HeapProfiler.addHeapSnapshotChunk", serializer.Finish())); -} - -void Frontend::heapStatsUpdate(std::unique_ptr> statsUpdate) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("statsUpdate"), statsUpdate); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("HeapProfiler.heapStatsUpdate", serializer.Finish())); -} - -void Frontend::lastSeenObjectId(int lastSeenObjectId, double timestamp) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("lastSeenObjectId"), lastSeenObjectId); - serializer.AddField(v8_crdtp::MakeSpan("timestamp"), timestamp); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("HeapProfiler.lastSeenObjectId", serializer.Finish())); -} - -void Frontend::reportHeapSnapshotProgress(int done, int total, Maybe finished) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("done"), done); - serializer.AddField(v8_crdtp::MakeSpan("total"), total); - serializer.AddField(v8_crdtp::MakeSpan("finished"), finished); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("HeapProfiler.reportHeapSnapshotProgress", serializer.Finish())); -} - -void Frontend::resetProfiles() -{ - if (!frontend_channel_) - return; - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("HeapProfiler.resetProfiles")); -} - -void Frontend::flush() -{ - frontend_channel_->FlushProtocolNotifications(); -} - -void Frontend::sendRawNotification(std::unique_ptr notification) -{ - frontend_channel_->SendProtocolNotification(std::move(notification)); -} - -// --------------------- Dispatcher. - -class DomainDispatcherImpl : public protocol::DomainDispatcher { -public: - DomainDispatcherImpl(FrontendChannel* frontendChannel, Backend* backend) - : DomainDispatcher(frontendChannel) - , m_backend(backend) {} - ~DomainDispatcherImpl() override { } - - using CallHandler = void (DomainDispatcherImpl::*)(const v8_crdtp::Dispatchable& dispatchable); - - std::function Dispatch(v8_crdtp::span command_name) override; - - void addInspectedHeapObject(const v8_crdtp::Dispatchable& dispatchable); - void collectGarbage(const v8_crdtp::Dispatchable& dispatchable); - void disable(const v8_crdtp::Dispatchable& dispatchable); - void enable(const v8_crdtp::Dispatchable& dispatchable); - void getHeapObjectId(const v8_crdtp::Dispatchable& dispatchable); - void getObjectByHeapObjectId(const v8_crdtp::Dispatchable& dispatchable); - void getSamplingProfile(const v8_crdtp::Dispatchable& dispatchable); - void startSampling(const v8_crdtp::Dispatchable& dispatchable); - void startTrackingHeapObjects(const v8_crdtp::Dispatchable& dispatchable); - void stopSampling(const v8_crdtp::Dispatchable& dispatchable); - void stopTrackingHeapObjects(const v8_crdtp::Dispatchable& dispatchable); - void takeHeapSnapshot(const v8_crdtp::Dispatchable& dispatchable); - protected: - Backend* m_backend; -}; - -namespace { -// This helper method with a static map of command methods (instance methods -// of DomainDispatcherImpl declared just above) by their name is used immediately below, -// in the DomainDispatcherImpl::Dispatch method. -DomainDispatcherImpl::CallHandler CommandByName(v8_crdtp::span command_name) { - static auto* commands = [](){ - auto* commands = new std::vector, - DomainDispatcherImpl::CallHandler>>{ - { - v8_crdtp::SpanFrom("addInspectedHeapObject"), - &DomainDispatcherImpl::addInspectedHeapObject - }, - { - v8_crdtp::SpanFrom("collectGarbage"), - &DomainDispatcherImpl::collectGarbage - }, - { - v8_crdtp::SpanFrom("disable"), - &DomainDispatcherImpl::disable - }, - { - v8_crdtp::SpanFrom("enable"), - &DomainDispatcherImpl::enable - }, - { - v8_crdtp::SpanFrom("getHeapObjectId"), - &DomainDispatcherImpl::getHeapObjectId - }, - { - v8_crdtp::SpanFrom("getObjectByHeapObjectId"), - &DomainDispatcherImpl::getObjectByHeapObjectId - }, - { - v8_crdtp::SpanFrom("getSamplingProfile"), - &DomainDispatcherImpl::getSamplingProfile - }, - { - v8_crdtp::SpanFrom("startSampling"), - &DomainDispatcherImpl::startSampling - }, - { - v8_crdtp::SpanFrom("startTrackingHeapObjects"), - &DomainDispatcherImpl::startTrackingHeapObjects - }, - { - v8_crdtp::SpanFrom("stopSampling"), - &DomainDispatcherImpl::stopSampling - }, - { - v8_crdtp::SpanFrom("stopTrackingHeapObjects"), - &DomainDispatcherImpl::stopTrackingHeapObjects - }, - { - v8_crdtp::SpanFrom("takeHeapSnapshot"), - &DomainDispatcherImpl::takeHeapSnapshot - }, - }; - return commands; - }(); - return v8_crdtp::FindByFirst(*commands, command_name, nullptr); -} -} // namespace - -std::function DomainDispatcherImpl::Dispatch(v8_crdtp::span command_name) { - CallHandler handler = CommandByName(command_name); - if (!handler) return nullptr; - - return [this, handler](const v8_crdtp::Dispatchable& dispatchable) { - (this->*handler)(dispatchable); - }; -} - - -namespace { - -struct addInspectedHeapObjectParams : public v8_crdtp::DeserializableProtocolObject { - String heapObjectId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(addInspectedHeapObjectParams) - V8_CRDTP_DESERIALIZE_FIELD("heapObjectId", heapObjectId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::addInspectedHeapObject(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - addInspectedHeapObjectParams params; - addInspectedHeapObjectParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->addInspectedHeapObject(params.heapObjectId); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("HeapProfiler.addInspectedHeapObject"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -class CollectGarbageCallbackImpl : public Backend::CollectGarbageCallback, public DomainDispatcher::Callback { -public: - CollectGarbageCallbackImpl(std::unique_ptr backendImpl, int callId, v8_crdtp::span message) - : DomainDispatcher::Callback(std::move(backendImpl), callId, -v8_crdtp::SpanFrom("HeapProfiler.collectGarbage"), message) { } - - void sendSuccess() override - { - v8_crdtp::ObjectSerializer serializer; - sendIfActive(serializer.Finish(), DispatchResponse::Success()); - } - - void fallThrough() override - { - fallThroughIfActive(); - } - - void sendFailure(const DispatchResponse& response) override - { - DCHECK(response.IsError()); - sendIfActive(nullptr, response); - } -}; - -namespace { - - -} // namespace - -void DomainDispatcherImpl::collectGarbage(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - m_backend->collectGarbage(std::make_unique(weakPtr(), dispatchable.CallId(), dispatchable.Serialized())); -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::disable(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->disable(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("HeapProfiler.disable"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::enable(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->enable(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("HeapProfiler.enable"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct getHeapObjectIdParams : public v8_crdtp::DeserializableProtocolObject { - String objectId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(getHeapObjectIdParams) - V8_CRDTP_DESERIALIZE_FIELD("objectId", objectId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::getHeapObjectId(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - getHeapObjectIdParams params; - getHeapObjectIdParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - String out_heapSnapshotObjectId; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getHeapObjectId(params.objectId, &out_heapSnapshotObjectId); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("HeapProfiler.getHeapObjectId"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("heapSnapshotObjectId"), out_heapSnapshotObjectId); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct getObjectByHeapObjectIdParams : public v8_crdtp::DeserializableProtocolObject { - String objectId; - Maybe objectGroup; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(getObjectByHeapObjectIdParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("objectGroup", objectGroup), - V8_CRDTP_DESERIALIZE_FIELD("objectId", objectId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::getObjectByHeapObjectId(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - getObjectByHeapObjectIdParams params; - getObjectByHeapObjectIdParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - std::unique_ptr out_result; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getObjectByHeapObjectId(params.objectId, std::move(params.objectGroup), &out_result); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("HeapProfiler.getObjectByHeapObjectId"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("result"), out_result); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::getSamplingProfile(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - // Declare output parameters. - std::unique_ptr out_profile; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getSamplingProfile(&out_profile); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("HeapProfiler.getSamplingProfile"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("profile"), out_profile); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct startSamplingParams : public v8_crdtp::DeserializableProtocolObject { - Maybe samplingInterval; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(startSamplingParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("samplingInterval", samplingInterval), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::startSampling(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - startSamplingParams params; - startSamplingParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->startSampling(std::move(params.samplingInterval)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("HeapProfiler.startSampling"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct startTrackingHeapObjectsParams : public v8_crdtp::DeserializableProtocolObject { - Maybe trackAllocations; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(startTrackingHeapObjectsParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("trackAllocations", trackAllocations), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::startTrackingHeapObjects(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - startTrackingHeapObjectsParams params; - startTrackingHeapObjectsParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->startTrackingHeapObjects(std::move(params.trackAllocations)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("HeapProfiler.startTrackingHeapObjects"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::stopSampling(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - // Declare output parameters. - std::unique_ptr out_profile; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->stopSampling(&out_profile); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("HeapProfiler.stopSampling"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("profile"), out_profile); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct stopTrackingHeapObjectsParams : public v8_crdtp::DeserializableProtocolObject { - Maybe reportProgress; - Maybe treatGlobalObjectsAsRoots; - Maybe captureNumericValue; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(stopTrackingHeapObjectsParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("captureNumericValue", captureNumericValue), - V8_CRDTP_DESERIALIZE_FIELD_OPT("reportProgress", reportProgress), - V8_CRDTP_DESERIALIZE_FIELD_OPT("treatGlobalObjectsAsRoots", treatGlobalObjectsAsRoots), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::stopTrackingHeapObjects(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - stopTrackingHeapObjectsParams params; - stopTrackingHeapObjectsParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->stopTrackingHeapObjects(std::move(params.reportProgress), std::move(params.treatGlobalObjectsAsRoots), std::move(params.captureNumericValue)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("HeapProfiler.stopTrackingHeapObjects"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct takeHeapSnapshotParams : public v8_crdtp::DeserializableProtocolObject { - Maybe reportProgress; - Maybe treatGlobalObjectsAsRoots; - Maybe captureNumericValue; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(takeHeapSnapshotParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("captureNumericValue", captureNumericValue), - V8_CRDTP_DESERIALIZE_FIELD_OPT("reportProgress", reportProgress), - V8_CRDTP_DESERIALIZE_FIELD_OPT("treatGlobalObjectsAsRoots", treatGlobalObjectsAsRoots), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::takeHeapSnapshot(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - takeHeapSnapshotParams params; - takeHeapSnapshotParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->takeHeapSnapshot(std::move(params.reportProgress), std::move(params.treatGlobalObjectsAsRoots), std::move(params.captureNumericValue)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("HeapProfiler.takeHeapSnapshot"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { -// This helper method (with a static map of redirects) is used from Dispatcher::wire -// immediately below. -const std::vector, v8_crdtp::span>>& SortedRedirects() { - static auto* redirects = [](){ - auto* redirects = new std::vector, v8_crdtp::span>>{ - }; - return redirects; - }(); - return *redirects; -} -} // namespace - -// static -void Dispatcher::wire(UberDispatcher* uber, Backend* backend) -{ - auto dispatcher = std::make_unique(uber->channel(), backend); - uber->WireBackend(v8_crdtp::SpanFrom("HeapProfiler"), SortedRedirects(), std::move(dispatcher)); -} - -} // HeapProfiler -} // namespace v8_inspector -} // namespace protocol diff --git a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Profiler.cpp b/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Profiler.cpp deleted file mode 100644 index 1be0233c2..000000000 --- a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Profiler.cpp +++ /dev/null @@ -1,659 +0,0 @@ -// This file is generated by TypeBuilder_cpp.template. - -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/inspector/protocol/Profiler.h" - -#include "src/inspector/protocol/Protocol.h" - -#include "third_party/inspector_protocol/crdtp/cbor.h" -#include "third_party/inspector_protocol/crdtp/find_by_first.h" -#include "third_party/inspector_protocol/crdtp/span.h" - -namespace v8_inspector { -namespace protocol { -namespace Profiler { - -using v8_crdtp::DeserializerState; -using v8_crdtp::ProtocolTypeTraits; - -// ------------- Enum values from types. - -const char Metainfo::domainName[] = "Profiler"; -const char Metainfo::commandPrefix[] = "Profiler."; -const char Metainfo::version[] = "1.3"; - -V8_CRDTP_BEGIN_DESERIALIZER(ProfileNode) - V8_CRDTP_DESERIALIZE_FIELD("callFrame", m_callFrame), - V8_CRDTP_DESERIALIZE_FIELD_OPT("children", m_children), - V8_CRDTP_DESERIALIZE_FIELD_OPT("deoptReason", m_deoptReason), - V8_CRDTP_DESERIALIZE_FIELD_OPT("hitCount", m_hitCount), - V8_CRDTP_DESERIALIZE_FIELD("id", m_id), - V8_CRDTP_DESERIALIZE_FIELD_OPT("positionTicks", m_positionTicks), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(ProfileNode) - V8_CRDTP_SERIALIZE_FIELD("id", m_id); - V8_CRDTP_SERIALIZE_FIELD("callFrame", m_callFrame); - V8_CRDTP_SERIALIZE_FIELD("hitCount", m_hitCount); - V8_CRDTP_SERIALIZE_FIELD("children", m_children); - V8_CRDTP_SERIALIZE_FIELD("deoptReason", m_deoptReason); - V8_CRDTP_SERIALIZE_FIELD("positionTicks", m_positionTicks); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(Profile) - V8_CRDTP_DESERIALIZE_FIELD("endTime", m_endTime), - V8_CRDTP_DESERIALIZE_FIELD("nodes", m_nodes), - V8_CRDTP_DESERIALIZE_FIELD_OPT("samples", m_samples), - V8_CRDTP_DESERIALIZE_FIELD("startTime", m_startTime), - V8_CRDTP_DESERIALIZE_FIELD_OPT("timeDeltas", m_timeDeltas), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(Profile) - V8_CRDTP_SERIALIZE_FIELD("nodes", m_nodes); - V8_CRDTP_SERIALIZE_FIELD("startTime", m_startTime); - V8_CRDTP_SERIALIZE_FIELD("endTime", m_endTime); - V8_CRDTP_SERIALIZE_FIELD("samples", m_samples); - V8_CRDTP_SERIALIZE_FIELD("timeDeltas", m_timeDeltas); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(PositionTickInfo) - V8_CRDTP_DESERIALIZE_FIELD("line", m_line), - V8_CRDTP_DESERIALIZE_FIELD("ticks", m_ticks), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(PositionTickInfo) - V8_CRDTP_SERIALIZE_FIELD("line", m_line); - V8_CRDTP_SERIALIZE_FIELD("ticks", m_ticks); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(CoverageRange) - V8_CRDTP_DESERIALIZE_FIELD("count", m_count), - V8_CRDTP_DESERIALIZE_FIELD("endOffset", m_endOffset), - V8_CRDTP_DESERIALIZE_FIELD("startOffset", m_startOffset), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(CoverageRange) - V8_CRDTP_SERIALIZE_FIELD("startOffset", m_startOffset); - V8_CRDTP_SERIALIZE_FIELD("endOffset", m_endOffset); - V8_CRDTP_SERIALIZE_FIELD("count", m_count); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(FunctionCoverage) - V8_CRDTP_DESERIALIZE_FIELD("functionName", m_functionName), - V8_CRDTP_DESERIALIZE_FIELD("isBlockCoverage", m_isBlockCoverage), - V8_CRDTP_DESERIALIZE_FIELD("ranges", m_ranges), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(FunctionCoverage) - V8_CRDTP_SERIALIZE_FIELD("functionName", m_functionName); - V8_CRDTP_SERIALIZE_FIELD("ranges", m_ranges); - V8_CRDTP_SERIALIZE_FIELD("isBlockCoverage", m_isBlockCoverage); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(ScriptCoverage) - V8_CRDTP_DESERIALIZE_FIELD("functions", m_functions), - V8_CRDTP_DESERIALIZE_FIELD("scriptId", m_scriptId), - V8_CRDTP_DESERIALIZE_FIELD("url", m_url), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(ScriptCoverage) - V8_CRDTP_SERIALIZE_FIELD("scriptId", m_scriptId); - V8_CRDTP_SERIALIZE_FIELD("url", m_url); - V8_CRDTP_SERIALIZE_FIELD("functions", m_functions); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(TypeObject) - V8_CRDTP_DESERIALIZE_FIELD("name", m_name), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(TypeObject) - V8_CRDTP_SERIALIZE_FIELD("name", m_name); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(TypeProfileEntry) - V8_CRDTP_DESERIALIZE_FIELD("offset", m_offset), - V8_CRDTP_DESERIALIZE_FIELD("types", m_types), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(TypeProfileEntry) - V8_CRDTP_SERIALIZE_FIELD("offset", m_offset); - V8_CRDTP_SERIALIZE_FIELD("types", m_types); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(ScriptTypeProfile) - V8_CRDTP_DESERIALIZE_FIELD("entries", m_entries), - V8_CRDTP_DESERIALIZE_FIELD("scriptId", m_scriptId), - V8_CRDTP_DESERIALIZE_FIELD("url", m_url), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(ScriptTypeProfile) - V8_CRDTP_SERIALIZE_FIELD("scriptId", m_scriptId); - V8_CRDTP_SERIALIZE_FIELD("url", m_url); - V8_CRDTP_SERIALIZE_FIELD("entries", m_entries); -V8_CRDTP_END_SERIALIZER(); - - -// ------------- Enum values from params. - - -// ------------- Frontend notifications. - -void Frontend::consoleProfileFinished(const String& id, std::unique_ptr location, std::unique_ptr profile, Maybe title) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("id"), id); - serializer.AddField(v8_crdtp::MakeSpan("location"), location); - serializer.AddField(v8_crdtp::MakeSpan("profile"), profile); - serializer.AddField(v8_crdtp::MakeSpan("title"), title); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Profiler.consoleProfileFinished", serializer.Finish())); -} - -void Frontend::consoleProfileStarted(const String& id, std::unique_ptr location, Maybe title) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("id"), id); - serializer.AddField(v8_crdtp::MakeSpan("location"), location); - serializer.AddField(v8_crdtp::MakeSpan("title"), title); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Profiler.consoleProfileStarted", serializer.Finish())); -} - -void Frontend::preciseCoverageDeltaUpdate(double timestamp, const String& occasion, std::unique_ptr> result) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("timestamp"), timestamp); - serializer.AddField(v8_crdtp::MakeSpan("occasion"), occasion); - serializer.AddField(v8_crdtp::MakeSpan("result"), result); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Profiler.preciseCoverageDeltaUpdate", serializer.Finish())); -} - -void Frontend::flush() -{ - frontend_channel_->FlushProtocolNotifications(); -} - -void Frontend::sendRawNotification(std::unique_ptr notification) -{ - frontend_channel_->SendProtocolNotification(std::move(notification)); -} - -// --------------------- Dispatcher. - -class DomainDispatcherImpl : public protocol::DomainDispatcher { -public: - DomainDispatcherImpl(FrontendChannel* frontendChannel, Backend* backend) - : DomainDispatcher(frontendChannel) - , m_backend(backend) {} - ~DomainDispatcherImpl() override { } - - using CallHandler = void (DomainDispatcherImpl::*)(const v8_crdtp::Dispatchable& dispatchable); - - std::function Dispatch(v8_crdtp::span command_name) override; - - void disable(const v8_crdtp::Dispatchable& dispatchable); - void enable(const v8_crdtp::Dispatchable& dispatchable); - void getBestEffortCoverage(const v8_crdtp::Dispatchable& dispatchable); - void setSamplingInterval(const v8_crdtp::Dispatchable& dispatchable); - void start(const v8_crdtp::Dispatchable& dispatchable); - void startPreciseCoverage(const v8_crdtp::Dispatchable& dispatchable); - void startTypeProfile(const v8_crdtp::Dispatchable& dispatchable); - void stop(const v8_crdtp::Dispatchable& dispatchable); - void stopPreciseCoverage(const v8_crdtp::Dispatchable& dispatchable); - void stopTypeProfile(const v8_crdtp::Dispatchable& dispatchable); - void takePreciseCoverage(const v8_crdtp::Dispatchable& dispatchable); - void takeTypeProfile(const v8_crdtp::Dispatchable& dispatchable); - protected: - Backend* m_backend; -}; - -namespace { -// This helper method with a static map of command methods (instance methods -// of DomainDispatcherImpl declared just above) by their name is used immediately below, -// in the DomainDispatcherImpl::Dispatch method. -DomainDispatcherImpl::CallHandler CommandByName(v8_crdtp::span command_name) { - static auto* commands = [](){ - auto* commands = new std::vector, - DomainDispatcherImpl::CallHandler>>{ - { - v8_crdtp::SpanFrom("disable"), - &DomainDispatcherImpl::disable - }, - { - v8_crdtp::SpanFrom("enable"), - &DomainDispatcherImpl::enable - }, - { - v8_crdtp::SpanFrom("getBestEffortCoverage"), - &DomainDispatcherImpl::getBestEffortCoverage - }, - { - v8_crdtp::SpanFrom("setSamplingInterval"), - &DomainDispatcherImpl::setSamplingInterval - }, - { - v8_crdtp::SpanFrom("start"), - &DomainDispatcherImpl::start - }, - { - v8_crdtp::SpanFrom("startPreciseCoverage"), - &DomainDispatcherImpl::startPreciseCoverage - }, - { - v8_crdtp::SpanFrom("startTypeProfile"), - &DomainDispatcherImpl::startTypeProfile - }, - { - v8_crdtp::SpanFrom("stop"), - &DomainDispatcherImpl::stop - }, - { - v8_crdtp::SpanFrom("stopPreciseCoverage"), - &DomainDispatcherImpl::stopPreciseCoverage - }, - { - v8_crdtp::SpanFrom("stopTypeProfile"), - &DomainDispatcherImpl::stopTypeProfile - }, - { - v8_crdtp::SpanFrom("takePreciseCoverage"), - &DomainDispatcherImpl::takePreciseCoverage - }, - { - v8_crdtp::SpanFrom("takeTypeProfile"), - &DomainDispatcherImpl::takeTypeProfile - }, - }; - return commands; - }(); - return v8_crdtp::FindByFirst(*commands, command_name, nullptr); -} -} // namespace - -std::function DomainDispatcherImpl::Dispatch(v8_crdtp::span command_name) { - CallHandler handler = CommandByName(command_name); - if (!handler) return nullptr; - - return [this, handler](const v8_crdtp::Dispatchable& dispatchable) { - (this->*handler)(dispatchable); - }; -} - - -namespace { - - -} // namespace - -void DomainDispatcherImpl::disable(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->disable(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Profiler.disable"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::enable(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->enable(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Profiler.enable"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::getBestEffortCoverage(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - // Declare output parameters. - std::unique_ptr> out_result; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getBestEffortCoverage(&out_result); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Profiler.getBestEffortCoverage"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("result"), out_result); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct setSamplingIntervalParams : public v8_crdtp::DeserializableProtocolObject { - int interval; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setSamplingIntervalParams) - V8_CRDTP_DESERIALIZE_FIELD("interval", interval), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setSamplingInterval(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setSamplingIntervalParams params; - setSamplingIntervalParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setSamplingInterval(params.interval); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Profiler.setSamplingInterval"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::start(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->start(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Profiler.start"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct startPreciseCoverageParams : public v8_crdtp::DeserializableProtocolObject { - Maybe callCount; - Maybe detailed; - Maybe allowTriggeredUpdates; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(startPreciseCoverageParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("allowTriggeredUpdates", allowTriggeredUpdates), - V8_CRDTP_DESERIALIZE_FIELD_OPT("callCount", callCount), - V8_CRDTP_DESERIALIZE_FIELD_OPT("detailed", detailed), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::startPreciseCoverage(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - startPreciseCoverageParams params; - startPreciseCoverageParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - double out_timestamp; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->startPreciseCoverage(std::move(params.callCount), std::move(params.detailed), std::move(params.allowTriggeredUpdates), &out_timestamp); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Profiler.startPreciseCoverage"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("timestamp"), out_timestamp); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::startTypeProfile(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->startTypeProfile(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Profiler.startTypeProfile"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::stop(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - // Declare output parameters. - std::unique_ptr out_profile; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->stop(&out_profile); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Profiler.stop"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("profile"), out_profile); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::stopPreciseCoverage(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->stopPreciseCoverage(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Profiler.stopPreciseCoverage"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::stopTypeProfile(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->stopTypeProfile(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Profiler.stopTypeProfile"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::takePreciseCoverage(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - // Declare output parameters. - std::unique_ptr> out_result; - double out_timestamp; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->takePreciseCoverage(&out_result, &out_timestamp); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Profiler.takePreciseCoverage"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("result"), out_result); - serializer.AddField(v8_crdtp::MakeSpan("timestamp"), out_timestamp); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::takeTypeProfile(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - // Declare output parameters. - std::unique_ptr> out_result; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->takeTypeProfile(&out_result); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Profiler.takeTypeProfile"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("result"), out_result); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { -// This helper method (with a static map of redirects) is used from Dispatcher::wire -// immediately below. -const std::vector, v8_crdtp::span>>& SortedRedirects() { - static auto* redirects = [](){ - auto* redirects = new std::vector, v8_crdtp::span>>{ - }; - return redirects; - }(); - return *redirects; -} -} // namespace - -// static -void Dispatcher::wire(UberDispatcher* uber, Backend* backend) -{ - auto dispatcher = std::make_unique(uber->channel(), backend); - uber->WireBackend(v8_crdtp::SpanFrom("Profiler"), SortedRedirects(), std::move(dispatcher)); -} - -} // Profiler -} // namespace v8_inspector -} // namespace protocol diff --git a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Protocol.cpp b/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Protocol.cpp deleted file mode 100644 index c8d18b096..000000000 --- a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Protocol.cpp +++ /dev/null @@ -1,727 +0,0 @@ -// This file is generated by Protocol_cpp.template. - -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/inspector/protocol/Protocol.h" - -#include -#include -#include -#include - - -// This file is generated by Values_cpp.template. - -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -//#include "Values.h" - -#include "third_party/inspector_protocol/crdtp/cbor.h" - -namespace v8_inspector { -namespace protocol { - -namespace { -using v8_crdtp::Status; -using v8_crdtp::ParserHandler; -using v8_crdtp::span; -namespace cbor { -using v8_crdtp::cbor::ParseCBOR; -using v8_crdtp::cbor::EncodeBinary; -using v8_crdtp::cbor::EncodeDouble; -using v8_crdtp::cbor::EncodeFalse; -using v8_crdtp::cbor::EncodeFromLatin1; -using v8_crdtp::cbor::EncodeFromUTF16; -using v8_crdtp::cbor::EncodeIndefiniteLengthArrayStart; -using v8_crdtp::cbor::EncodeIndefiniteLengthMapStart; -using v8_crdtp::cbor::EncodeInt32; -using v8_crdtp::cbor::EncodeNull; -using v8_crdtp::cbor::EncodeStop; -using v8_crdtp::cbor::EncodeString8; -using v8_crdtp::cbor::EncodeTrue; -using v8_crdtp::cbor::EnvelopeEncoder; -using v8_crdtp::cbor::InitialByteForEnvelope; -} // namespace cbor - -// Uses the parsing events received from driver of |ParserHandler| -// (e.g. cbor::ParseCBOR) into a protocol::Value instance. -class ValueParserHandler : public ParserHandler { - public: - // Provides the parsed protocol::Value. - std::unique_ptr ReleaseRoot() { return std::move(root_); } - - // The first parsing error encountered; |status().ok()| is the default. - Status status() const { return status_; } - - private: - // - // Implementation of ParserHandler. - // - void HandleMapBegin() override { - if (!status_.ok()) return; - std::unique_ptr dict = DictionaryValue::create(); - DictionaryValue* dict_ptr = dict.get(); - AddValueToParent(std::move(dict)); - stack_.emplace_back(dict_ptr); - } - - void HandleMapEnd() override { - if (!status_.ok()) return; - DCHECK(!stack_.empty()); - DCHECK(stack_.back().is_dict); - stack_.pop_back(); - } - - void HandleArrayBegin() override { - if (!status_.ok()) return; - std::unique_ptr list = ListValue::create(); - ListValue* list_ptr = list.get(); - AddValueToParent(std::move(list)); - stack_.emplace_back(list_ptr); - } - - void HandleArrayEnd() override { - if (!status_.ok()) return; - DCHECK(!stack_.empty()); - DCHECK(!stack_.back().is_dict); - stack_.pop_back(); - } - - void HandleString8(span chars) override { - AddStringToParent(StringUtil::fromUTF8(chars.data(), chars.size())); - } - - void HandleString16(span chars) override { - AddStringToParent( - StringUtil::fromUTF16LE(chars.data(), chars.size())); - } - - void HandleBinary(span bytes) override { - AddValueToParent( - BinaryValue::create(Binary::fromSpan(bytes.data(), bytes.size()))); - } - - void HandleDouble(double value) override { - AddValueToParent(FundamentalValue::create(value)); - } - - void HandleInt32(int32_t value) override { - AddValueToParent(FundamentalValue::create(value)); - } - - void HandleBool(bool value) override { - AddValueToParent(FundamentalValue::create(value)); - } - - void HandleNull() override { - AddValueToParent(Value::null()); - } - - void HandleError(Status error) override { - status_ = error; - } - - // - // Adding strings and values to the parent value. - // Strings are handled separately because they can be keys for - // dictionary values. - // - void AddStringToParent(String str) { - if (!status_.ok()) return; - if (!root_) { - DCHECK(!key_is_pending_); - root_ = StringValue::create(str); - } else if (stack_.back().is_dict) { - // If we already have a pending key, then this is the value of the - // key/value pair. Otherwise, it's the new pending key. - if (key_is_pending_) { - stack_.back().dict->setString(pending_key_, str); - key_is_pending_ = false; - } else { - pending_key_ = std::move(str); - key_is_pending_ = true; - } - } else { // Top of the stack is a list. - DCHECK(!key_is_pending_); - stack_.back().list->pushValue(StringValue::create(str)); - } - } - - void AddValueToParent(std::unique_ptr value) { - if (!status_.ok()) return; - if (!root_) { - DCHECK(!key_is_pending_); - root_ = std::move(value); - } else if (stack_.back().is_dict) { - DCHECK(key_is_pending_); - stack_.back().dict->setValue(pending_key_, std::move(value)); - key_is_pending_ = false; - } else { // Top of the stack is a list. - DCHECK(!key_is_pending_); - stack_.back().list->pushValue(std::move(value)); - } - } - - // |status_.ok()| is the default; if we receive an error event - // we keep the first one and stop modifying any other state. - Status status_; - - // The root of the parsed protocol::Value tree. - std::unique_ptr root_; - - // If root_ is a list or a dictionary, this stack keeps track of - // the container we're currently parsing as well as its ancestors. - struct ContainerState { - ContainerState(DictionaryValue* dict) : is_dict(true), dict(dict) {} - ContainerState(ListValue* list) : is_dict(false), list(list) {} - - bool is_dict; - union { - DictionaryValue* dict; - ListValue* list; - }; - }; - std::vector stack_; - - // For maps, keys and values are alternating events, so we keep the - // key around and process it when the value arrives. - bool key_is_pending_ = false; - String pending_key_; -}; -} // anonymous namespace - -// static -std::unique_ptr Value::parseBinary(const uint8_t* data, size_t size) { - ValueParserHandler handler; - cbor::ParseCBOR(span(data, size), &handler); - // TODO(johannes): We have decent error info in handler.status(); provide - // a richer interface that makes this available to client code. - if (handler.status().ok()) - return handler.ReleaseRoot(); - return nullptr; -} - -bool Value::asBoolean(bool*) const -{ - return false; -} - -bool Value::asDouble(double*) const -{ - return false; -} - -bool Value::asInteger(int*) const -{ - return false; -} - -bool Value::asString(String*) const -{ - return false; -} - -bool Value::asBinary(Binary*) const -{ - return false; -} - -void Value::AppendSerialized(std::vector* bytes) const { - DCHECK(m_type == TypeNull); - bytes->push_back(cbor::EncodeNull()); -} - -std::unique_ptr Value::clone() const -{ - return Value::null(); -} - -bool FundamentalValue::asBoolean(bool* output) const -{ - if (type() != TypeBoolean) - return false; - *output = m_boolValue; - return true; -} - -bool FundamentalValue::asDouble(double* output) const -{ - if (type() == TypeDouble) { - *output = m_doubleValue; - return true; - } - if (type() == TypeInteger) { - *output = m_integerValue; - return true; - } - return false; -} - -bool FundamentalValue::asInteger(int* output) const -{ - if (type() != TypeInteger) - return false; - *output = m_integerValue; - return true; -} - -void FundamentalValue::AppendSerialized(std::vector* bytes) const { - switch (type()) { - case TypeDouble: - cbor::EncodeDouble(m_doubleValue, bytes); - return; - case TypeInteger: - cbor::EncodeInt32(m_integerValue, bytes); - return; - case TypeBoolean: - bytes->push_back(m_boolValue ? cbor::EncodeTrue() : cbor::EncodeFalse()); - return; - default: - DCHECK(false); - } -} - -std::unique_ptr FundamentalValue::clone() const -{ - switch (type()) { - case TypeDouble: return FundamentalValue::create(m_doubleValue); - case TypeInteger: return FundamentalValue::create(m_integerValue); - case TypeBoolean: return FundamentalValue::create(m_boolValue); - default: - DCHECK(false); - } - return nullptr; -} - -bool StringValue::asString(String* output) const -{ - *output = m_stringValue; - return true; -} - -namespace { -// This routine distinguishes between the current encoding for a given -// string |s|, and calls encoding routines that will -// - Ensure that all ASCII strings end up being encoded as UTF8 in -// the wire format - e.g., EncodeFromUTF16 will detect ASCII and -// do the (trivial) transcode to STRING8 on the wire, but if it's -// not ASCII it'll do STRING16. -// - Select a format that's cheap to convert to. E.g., we don't -// have LATIN1 on the wire, so we call EncodeFromLatin1 which -// transcodes to UTF8 if needed. -void EncodeString(const String& s, std::vector* out) { - if (StringUtil::CharacterCount(s) == 0) { - cbor::EncodeString8(span(nullptr, 0), out); // Empty string. - } else if (StringUtil::CharactersLatin1(s)) { - cbor::EncodeFromLatin1(span(StringUtil::CharactersLatin1(s), - StringUtil::CharacterCount(s)), - out); - } else if (StringUtil::CharactersUTF16(s)) { - cbor::EncodeFromUTF16(span(StringUtil::CharactersUTF16(s), - StringUtil::CharacterCount(s)), - out); - } else if (StringUtil::CharactersUTF8(s)) { - cbor::EncodeString8(span(StringUtil::CharactersUTF8(s), - StringUtil::CharacterCount(s)), - out); - } -} -} // namespace -void StringValue::AppendSerialized(std::vector* bytes) const { - EncodeString(m_stringValue, bytes); -} - -std::unique_ptr StringValue::clone() const -{ - return StringValue::create(m_stringValue); -} - -bool BinaryValue::asBinary(Binary* output) const -{ - *output = m_binaryValue; - return true; -} - -void BinaryValue::AppendSerialized(std::vector* bytes) const { - cbor::EncodeBinary(span(m_binaryValue.data(), - m_binaryValue.size()), bytes); -} - -std::unique_ptr BinaryValue::clone() const -{ - return BinaryValue::create(m_binaryValue); -} - - -DictionaryValue::~DictionaryValue() -{ -} - -void DictionaryValue::setBoolean(const String& name, bool value) -{ - setValue(name, FundamentalValue::create(value)); -} - -void DictionaryValue::setInteger(const String& name, int value) -{ - setValue(name, FundamentalValue::create(value)); -} - -void DictionaryValue::setDouble(const String& name, double value) -{ - setValue(name, FundamentalValue::create(value)); -} - -void DictionaryValue::setString(const String& name, const String& value) -{ - setValue(name, StringValue::create(value)); -} - -void DictionaryValue::setValue(const String& name, std::unique_ptr value) -{ - set(name, value); -} - -void DictionaryValue::setObject(const String& name, std::unique_ptr value) -{ - set(name, value); -} - -void DictionaryValue::setArray(const String& name, std::unique_ptr value) -{ - set(name, value); -} - -bool DictionaryValue::getBoolean(const String& name, bool* output) const -{ - protocol::Value* value = get(name); - if (!value) - return false; - return value->asBoolean(output); -} - -bool DictionaryValue::getInteger(const String& name, int* output) const -{ - Value* value = get(name); - if (!value) - return false; - return value->asInteger(output); -} - -bool DictionaryValue::getDouble(const String& name, double* output) const -{ - Value* value = get(name); - if (!value) - return false; - return value->asDouble(output); -} - -bool DictionaryValue::getString(const String& name, String* output) const -{ - protocol::Value* value = get(name); - if (!value) - return false; - return value->asString(output); -} - -DictionaryValue* DictionaryValue::getObject(const String& name) const -{ - return DictionaryValue::cast(get(name)); -} - -protocol::ListValue* DictionaryValue::getArray(const String& name) const -{ - return ListValue::cast(get(name)); -} - -protocol::Value* DictionaryValue::get(const String& name) const -{ - Dictionary::const_iterator it = m_data.find(name); - if (it == m_data.end()) - return nullptr; - return it->second.get(); -} - -DictionaryValue::Entry DictionaryValue::at(size_t index) const -{ - const String key = m_order[index]; - return std::make_pair(key, m_data.find(key)->second.get()); -} - -bool DictionaryValue::booleanProperty(const String& name, bool defaultValue) const -{ - bool result = defaultValue; - getBoolean(name, &result); - return result; -} - -int DictionaryValue::integerProperty(const String& name, int defaultValue) const -{ - int result = defaultValue; - getInteger(name, &result); - return result; -} - -double DictionaryValue::doubleProperty(const String& name, double defaultValue) const -{ - double result = defaultValue; - getDouble(name, &result); - return result; -} - -void DictionaryValue::remove(const String& name) -{ - m_data.erase(name); - m_order.erase(std::remove(m_order.begin(), m_order.end(), name), m_order.end()); -} - -void DictionaryValue::AppendSerialized(std::vector* bytes) const { - cbor::EnvelopeEncoder encoder; - encoder.EncodeStart(bytes); - bytes->push_back(cbor::EncodeIndefiniteLengthMapStart()); - for (size_t i = 0; i < m_order.size(); ++i) { - const String& key = m_order[i]; - Dictionary::const_iterator value = m_data.find(key); - DCHECK(value != m_data.cend() && value->second); - EncodeString(key, bytes); - value->second->AppendSerialized(bytes); - } - bytes->push_back(cbor::EncodeStop()); - encoder.EncodeStop(bytes); -} - -std::unique_ptr DictionaryValue::clone() const -{ - std::unique_ptr result = DictionaryValue::create(); - for (size_t i = 0; i < m_order.size(); ++i) { - String key = m_order[i]; - Dictionary::const_iterator value = m_data.find(key); - DCHECK(value != m_data.cend() && value->second); - result->setValue(key, value->second->clone()); - } - return result; -} - -DictionaryValue::DictionaryValue() - : Value(TypeObject) -{ -} - -ListValue::~ListValue() -{ -} - -void ListValue::AppendSerialized(std::vector* bytes) const { - cbor::EnvelopeEncoder encoder; - encoder.EncodeStart(bytes); - bytes->push_back(cbor::EncodeIndefiniteLengthArrayStart()); - for (size_t i = 0; i < m_data.size(); ++i) { - m_data[i]->AppendSerialized(bytes); - } - bytes->push_back(cbor::EncodeStop()); - encoder.EncodeStop(bytes); -} - -std::unique_ptr ListValue::clone() const -{ - std::unique_ptr result = ListValue::create(); - for (const std::unique_ptr& value : m_data) - result->pushValue(value->clone()); - return result; -} - -ListValue::ListValue() - : Value(TypeArray) -{ -} - -void ListValue::pushValue(std::unique_ptr value) -{ - DCHECK(value); - m_data.push_back(std::move(value)); -} - -protocol::Value* ListValue::at(size_t index) -{ - DCHECK_LT(index, m_data.size()); - return m_data[index].get(); -} - -} // namespace v8_inspector -} // namespace protocol - - -// This file is generated by Object_cpp.template. - -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -//#include "Object.h" - -namespace v8_inspector { -namespace protocol { - -std::unique_ptr Object::fromValue(protocol::Value* value, ErrorSupport* errors) -{ - protocol::DictionaryValue* dictionary = DictionaryValue::cast(value); - if (!dictionary) { - errors->AddError("object expected"); - return nullptr; - } - dictionary = static_cast(dictionary->clone().release()); - return std::unique_ptr(new Object(std::unique_ptr(dictionary))); -} - -// Implements Serializable. -void Object::AppendSerialized(std::vector* out) const { - m_object->AppendSerialized(out); -} - -std::unique_ptr Object::toValue() const -{ - return DictionaryValue::cast(m_object->clone()); -} - -std::unique_ptr Object::clone() const -{ - return std::unique_ptr(new Object(DictionaryValue::cast(m_object->clone()))); -} - -Object::Object(std::unique_ptr object) : m_object(std::move(object)) { } - -Object::~Object() { } - -} // namespace v8_inspector -} // namespace protocol - - -// This file is generated by ValueConversions_cpp.template. - -// Copyright 2020 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/inspector/protocol/Protocol.h" - -#include -#include -#include - -//#include "ValueConversions.h" -//#include "Values.h" - -namespace v8_inspector { -namespace protocol { - -} // namespace -} // namespace - - -namespace v8_crdtp { - -namespace { - -using v8_inspector::protocol::Binary; -using v8_inspector::protocol::Object; -using v8_inspector::protocol::Value; -using v8_inspector::protocol::String; -using v8_inspector::protocol::DictionaryValue; -using v8_inspector::protocol::FundamentalValue; -using v8_inspector::protocol::StringValue; -using v8_inspector::protocol::StringUtil; -//using v8_inspector::protocol::EncodeString; - -std::unique_ptr ReadValue(DeserializerState* state) { - cbor::CBORTokenizer* tokenizer = state->tokenizer(); - switch (tokenizer->TokenTag()) { - case cbor::CBORTokenTag::TRUE_VALUE: - return FundamentalValue::create(true); - case cbor::CBORTokenTag::FALSE_VALUE: - return FundamentalValue::create(false); - case cbor::CBORTokenTag::NULL_VALUE: - return Value::null(); - case cbor::CBORTokenTag::INT32: - return FundamentalValue::create(tokenizer->GetInt32()); - case cbor::CBORTokenTag::DOUBLE: - return FundamentalValue::create(tokenizer->GetDouble()); - case cbor::CBORTokenTag::STRING8: { - const auto str = tokenizer->GetString8(); - return StringValue::create(StringUtil::fromUTF8(str.data(), str.size())); - } - case cbor::CBORTokenTag::STRING16: { - const auto str = tokenizer->GetString16WireRep(); - return StringValue::create(StringUtil::fromUTF16LE(reinterpret_cast(str.data()), str.size() / 2)); - } - case cbor::CBORTokenTag::ENVELOPE: { - const auto env = tokenizer->GetEnvelope(); - return Value::parseBinary(env.data(), env.size()); - } - // Intentionally not supported. - case cbor::CBORTokenTag::BINARY: - // Should not be encountered outside of envelope. - case cbor::CBORTokenTag::MAP_START: - case cbor::CBORTokenTag::ARRAY_START: - default: - state->RegisterError(Error::CBOR_UNSUPPORTED_VALUE); - return nullptr; - } -} - -} // namespace - -// static -bool ProtocolTypeTraits>::Deserialize( - DeserializerState* state, std::unique_ptr* value) { - auto result = ReadValue(state); - if (!result) - return false; - *value = std::move(result); - return true; -} - -// static -void ProtocolTypeTraits>::Serialize( - const std::unique_ptr& value, std::vector* bytes) { - value->AppendSerialized(bytes); -} - -// static -bool ProtocolTypeTraits>::Deserialize( - DeserializerState* state, std::unique_ptr* value) { - std::unique_ptr res; - if (!ProtocolTypeTraits>::Deserialize(state, &res)) - return false; - if (res->type() != Value::TypeObject) { - state->RegisterError(Error::BINDINGS_DICTIONARY_VALUE_EXPECTED); - return false; - } - *value = DictionaryValue::cast(std::move(res)); - return true; -} - -// static -void ProtocolTypeTraits>::Serialize( - const std::unique_ptr& value, std::vector* bytes) { - value->AppendSerialized(bytes); -} - -// static -bool ProtocolTypeTraits>::Deserialize(DeserializerState* state, std::unique_ptr* value) { - auto res = DictionaryValue::create(); - if (ProtocolTypeTraits>::Deserialize(state, &res)) { - *value = std::make_unique(std::move(res)); - return true; - } - return false; -} - -void ProtocolTypeTraits>::Serialize(const std::unique_ptr& value, std::vector* bytes) { - value->AppendSerialized(bytes); -} - -} // namespace v8_crdtp diff --git a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Runtime.cpp b/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Runtime.cpp deleted file mode 100644 index 474b32c11..000000000 --- a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Runtime.cpp +++ /dev/null @@ -1,1629 +0,0 @@ -// This file is generated by TypeBuilder_cpp.template. - -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/inspector/protocol/Runtime.h" - -#include "src/inspector/protocol/Protocol.h" - -#include "third_party/inspector_protocol/crdtp/cbor.h" -#include "third_party/inspector_protocol/crdtp/find_by_first.h" -#include "third_party/inspector_protocol/crdtp/span.h" - -namespace v8_inspector { -namespace protocol { -namespace Runtime { - -using v8_crdtp::DeserializerState; -using v8_crdtp::ProtocolTypeTraits; - -// ------------- Enum values from types. - -const char Metainfo::domainName[] = "Runtime"; -const char Metainfo::commandPrefix[] = "Runtime."; -const char Metainfo::version[] = "1.3"; - - - -const char* WebDriverValue::TypeEnum::Undefined = "undefined"; -const char* WebDriverValue::TypeEnum::Null = "null"; -const char* WebDriverValue::TypeEnum::String = "string"; -const char* WebDriverValue::TypeEnum::Number = "number"; -const char* WebDriverValue::TypeEnum::Boolean = "boolean"; -const char* WebDriverValue::TypeEnum::Bigint = "bigint"; -const char* WebDriverValue::TypeEnum::Regexp = "regexp"; -const char* WebDriverValue::TypeEnum::Date = "date"; -const char* WebDriverValue::TypeEnum::Symbol = "symbol"; -const char* WebDriverValue::TypeEnum::Array = "array"; -const char* WebDriverValue::TypeEnum::Object = "object"; -const char* WebDriverValue::TypeEnum::Function = "function"; -const char* WebDriverValue::TypeEnum::Map = "map"; -const char* WebDriverValue::TypeEnum::Set = "set"; -const char* WebDriverValue::TypeEnum::Weakmap = "weakmap"; -const char* WebDriverValue::TypeEnum::Weakset = "weakset"; -const char* WebDriverValue::TypeEnum::Error = "error"; -const char* WebDriverValue::TypeEnum::Proxy = "proxy"; -const char* WebDriverValue::TypeEnum::Promise = "promise"; -const char* WebDriverValue::TypeEnum::Typedarray = "typedarray"; -const char* WebDriverValue::TypeEnum::Arraybuffer = "arraybuffer"; -const char* WebDriverValue::TypeEnum::Node = "node"; -const char* WebDriverValue::TypeEnum::Window = "window"; -V8_CRDTP_BEGIN_DESERIALIZER(WebDriverValue) - V8_CRDTP_DESERIALIZE_FIELD_OPT("objectId", m_objectId), - V8_CRDTP_DESERIALIZE_FIELD("type", m_type), - V8_CRDTP_DESERIALIZE_FIELD_OPT("value", m_value), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(WebDriverValue) - V8_CRDTP_SERIALIZE_FIELD("type", m_type); - V8_CRDTP_SERIALIZE_FIELD("value", m_value); - V8_CRDTP_SERIALIZE_FIELD("objectId", m_objectId); -V8_CRDTP_END_SERIALIZER(); - - - - - -const char* RemoteObject::TypeEnum::Object = "object"; -const char* RemoteObject::TypeEnum::Function = "function"; -const char* RemoteObject::TypeEnum::Undefined = "undefined"; -const char* RemoteObject::TypeEnum::String = "string"; -const char* RemoteObject::TypeEnum::Number = "number"; -const char* RemoteObject::TypeEnum::Boolean = "boolean"; -const char* RemoteObject::TypeEnum::Symbol = "symbol"; -const char* RemoteObject::TypeEnum::Bigint = "bigint"; - -const char* RemoteObject::SubtypeEnum::Array = "array"; -const char* RemoteObject::SubtypeEnum::Null = "null"; -const char* RemoteObject::SubtypeEnum::Node = "node"; -const char* RemoteObject::SubtypeEnum::Regexp = "regexp"; -const char* RemoteObject::SubtypeEnum::Date = "date"; -const char* RemoteObject::SubtypeEnum::Map = "map"; -const char* RemoteObject::SubtypeEnum::Set = "set"; -const char* RemoteObject::SubtypeEnum::Weakmap = "weakmap"; -const char* RemoteObject::SubtypeEnum::Weakset = "weakset"; -const char* RemoteObject::SubtypeEnum::Iterator = "iterator"; -const char* RemoteObject::SubtypeEnum::Generator = "generator"; -const char* RemoteObject::SubtypeEnum::Error = "error"; -const char* RemoteObject::SubtypeEnum::Proxy = "proxy"; -const char* RemoteObject::SubtypeEnum::Promise = "promise"; -const char* RemoteObject::SubtypeEnum::Typedarray = "typedarray"; -const char* RemoteObject::SubtypeEnum::Arraybuffer = "arraybuffer"; -const char* RemoteObject::SubtypeEnum::Dataview = "dataview"; -const char* RemoteObject::SubtypeEnum::Webassemblymemory = "webassemblymemory"; -const char* RemoteObject::SubtypeEnum::Wasmvalue = "wasmvalue"; -V8_CRDTP_BEGIN_DESERIALIZER(RemoteObject) - V8_CRDTP_DESERIALIZE_FIELD_OPT("className", m_className), - V8_CRDTP_DESERIALIZE_FIELD_OPT("customPreview", m_customPreview), - V8_CRDTP_DESERIALIZE_FIELD_OPT("description", m_description), - V8_CRDTP_DESERIALIZE_FIELD_OPT("objectId", m_objectId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("preview", m_preview), - V8_CRDTP_DESERIALIZE_FIELD_OPT("subtype", m_subtype), - V8_CRDTP_DESERIALIZE_FIELD("type", m_type), - V8_CRDTP_DESERIALIZE_FIELD_OPT("unserializableValue", m_unserializableValue), - V8_CRDTP_DESERIALIZE_FIELD_OPT("value", m_value), - V8_CRDTP_DESERIALIZE_FIELD_OPT("webDriverValue", m_webDriverValue), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(RemoteObject) - V8_CRDTP_SERIALIZE_FIELD("type", m_type); - V8_CRDTP_SERIALIZE_FIELD("subtype", m_subtype); - V8_CRDTP_SERIALIZE_FIELD("className", m_className); - V8_CRDTP_SERIALIZE_FIELD("value", m_value); - V8_CRDTP_SERIALIZE_FIELD("unserializableValue", m_unserializableValue); - V8_CRDTP_SERIALIZE_FIELD("description", m_description); - V8_CRDTP_SERIALIZE_FIELD("webDriverValue", m_webDriverValue); - V8_CRDTP_SERIALIZE_FIELD("objectId", m_objectId); - V8_CRDTP_SERIALIZE_FIELD("preview", m_preview); - V8_CRDTP_SERIALIZE_FIELD("customPreview", m_customPreview); -V8_CRDTP_END_SERIALIZER(); - -// static -std::unique_ptr API::RemoteObject::fromBinary(const uint8_t* data, size_t length) -{ - return protocol::Runtime::RemoteObject::FromBinary(data, length); -} - -V8_CRDTP_BEGIN_DESERIALIZER(CustomPreview) - V8_CRDTP_DESERIALIZE_FIELD_OPT("bodyGetterId", m_bodyGetterId), - V8_CRDTP_DESERIALIZE_FIELD("header", m_header), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(CustomPreview) - V8_CRDTP_SERIALIZE_FIELD("header", m_header); - V8_CRDTP_SERIALIZE_FIELD("bodyGetterId", m_bodyGetterId); -V8_CRDTP_END_SERIALIZER(); - - - -const char* ObjectPreview::TypeEnum::Object = "object"; -const char* ObjectPreview::TypeEnum::Function = "function"; -const char* ObjectPreview::TypeEnum::Undefined = "undefined"; -const char* ObjectPreview::TypeEnum::String = "string"; -const char* ObjectPreview::TypeEnum::Number = "number"; -const char* ObjectPreview::TypeEnum::Boolean = "boolean"; -const char* ObjectPreview::TypeEnum::Symbol = "symbol"; -const char* ObjectPreview::TypeEnum::Bigint = "bigint"; - -const char* ObjectPreview::SubtypeEnum::Array = "array"; -const char* ObjectPreview::SubtypeEnum::Null = "null"; -const char* ObjectPreview::SubtypeEnum::Node = "node"; -const char* ObjectPreview::SubtypeEnum::Regexp = "regexp"; -const char* ObjectPreview::SubtypeEnum::Date = "date"; -const char* ObjectPreview::SubtypeEnum::Map = "map"; -const char* ObjectPreview::SubtypeEnum::Set = "set"; -const char* ObjectPreview::SubtypeEnum::Weakmap = "weakmap"; -const char* ObjectPreview::SubtypeEnum::Weakset = "weakset"; -const char* ObjectPreview::SubtypeEnum::Iterator = "iterator"; -const char* ObjectPreview::SubtypeEnum::Generator = "generator"; -const char* ObjectPreview::SubtypeEnum::Error = "error"; -const char* ObjectPreview::SubtypeEnum::Proxy = "proxy"; -const char* ObjectPreview::SubtypeEnum::Promise = "promise"; -const char* ObjectPreview::SubtypeEnum::Typedarray = "typedarray"; -const char* ObjectPreview::SubtypeEnum::Arraybuffer = "arraybuffer"; -const char* ObjectPreview::SubtypeEnum::Dataview = "dataview"; -const char* ObjectPreview::SubtypeEnum::Webassemblymemory = "webassemblymemory"; -const char* ObjectPreview::SubtypeEnum::Wasmvalue = "wasmvalue"; -V8_CRDTP_BEGIN_DESERIALIZER(ObjectPreview) - V8_CRDTP_DESERIALIZE_FIELD_OPT("description", m_description), - V8_CRDTP_DESERIALIZE_FIELD_OPT("entries", m_entries), - V8_CRDTP_DESERIALIZE_FIELD("overflow", m_overflow), - V8_CRDTP_DESERIALIZE_FIELD("properties", m_properties), - V8_CRDTP_DESERIALIZE_FIELD_OPT("subtype", m_subtype), - V8_CRDTP_DESERIALIZE_FIELD("type", m_type), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(ObjectPreview) - V8_CRDTP_SERIALIZE_FIELD("type", m_type); - V8_CRDTP_SERIALIZE_FIELD("subtype", m_subtype); - V8_CRDTP_SERIALIZE_FIELD("description", m_description); - V8_CRDTP_SERIALIZE_FIELD("overflow", m_overflow); - V8_CRDTP_SERIALIZE_FIELD("properties", m_properties); - V8_CRDTP_SERIALIZE_FIELD("entries", m_entries); -V8_CRDTP_END_SERIALIZER(); - - - -const char* PropertyPreview::TypeEnum::Object = "object"; -const char* PropertyPreview::TypeEnum::Function = "function"; -const char* PropertyPreview::TypeEnum::Undefined = "undefined"; -const char* PropertyPreview::TypeEnum::String = "string"; -const char* PropertyPreview::TypeEnum::Number = "number"; -const char* PropertyPreview::TypeEnum::Boolean = "boolean"; -const char* PropertyPreview::TypeEnum::Symbol = "symbol"; -const char* PropertyPreview::TypeEnum::Accessor = "accessor"; -const char* PropertyPreview::TypeEnum::Bigint = "bigint"; - -const char* PropertyPreview::SubtypeEnum::Array = "array"; -const char* PropertyPreview::SubtypeEnum::Null = "null"; -const char* PropertyPreview::SubtypeEnum::Node = "node"; -const char* PropertyPreview::SubtypeEnum::Regexp = "regexp"; -const char* PropertyPreview::SubtypeEnum::Date = "date"; -const char* PropertyPreview::SubtypeEnum::Map = "map"; -const char* PropertyPreview::SubtypeEnum::Set = "set"; -const char* PropertyPreview::SubtypeEnum::Weakmap = "weakmap"; -const char* PropertyPreview::SubtypeEnum::Weakset = "weakset"; -const char* PropertyPreview::SubtypeEnum::Iterator = "iterator"; -const char* PropertyPreview::SubtypeEnum::Generator = "generator"; -const char* PropertyPreview::SubtypeEnum::Error = "error"; -const char* PropertyPreview::SubtypeEnum::Proxy = "proxy"; -const char* PropertyPreview::SubtypeEnum::Promise = "promise"; -const char* PropertyPreview::SubtypeEnum::Typedarray = "typedarray"; -const char* PropertyPreview::SubtypeEnum::Arraybuffer = "arraybuffer"; -const char* PropertyPreview::SubtypeEnum::Dataview = "dataview"; -const char* PropertyPreview::SubtypeEnum::Webassemblymemory = "webassemblymemory"; -const char* PropertyPreview::SubtypeEnum::Wasmvalue = "wasmvalue"; -V8_CRDTP_BEGIN_DESERIALIZER(PropertyPreview) - V8_CRDTP_DESERIALIZE_FIELD("name", m_name), - V8_CRDTP_DESERIALIZE_FIELD_OPT("subtype", m_subtype), - V8_CRDTP_DESERIALIZE_FIELD("type", m_type), - V8_CRDTP_DESERIALIZE_FIELD_OPT("value", m_value), - V8_CRDTP_DESERIALIZE_FIELD_OPT("valuePreview", m_valuePreview), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(PropertyPreview) - V8_CRDTP_SERIALIZE_FIELD("name", m_name); - V8_CRDTP_SERIALIZE_FIELD("type", m_type); - V8_CRDTP_SERIALIZE_FIELD("value", m_value); - V8_CRDTP_SERIALIZE_FIELD("valuePreview", m_valuePreview); - V8_CRDTP_SERIALIZE_FIELD("subtype", m_subtype); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(EntryPreview) - V8_CRDTP_DESERIALIZE_FIELD_OPT("key", m_key), - V8_CRDTP_DESERIALIZE_FIELD("value", m_value), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(EntryPreview) - V8_CRDTP_SERIALIZE_FIELD("key", m_key); - V8_CRDTP_SERIALIZE_FIELD("value", m_value); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(PropertyDescriptor) - V8_CRDTP_DESERIALIZE_FIELD("configurable", m_configurable), - V8_CRDTP_DESERIALIZE_FIELD("enumerable", m_enumerable), - V8_CRDTP_DESERIALIZE_FIELD_OPT("get", m_get), - V8_CRDTP_DESERIALIZE_FIELD_OPT("isOwn", m_isOwn), - V8_CRDTP_DESERIALIZE_FIELD("name", m_name), - V8_CRDTP_DESERIALIZE_FIELD_OPT("set", m_set), - V8_CRDTP_DESERIALIZE_FIELD_OPT("symbol", m_symbol), - V8_CRDTP_DESERIALIZE_FIELD_OPT("value", m_value), - V8_CRDTP_DESERIALIZE_FIELD_OPT("wasThrown", m_wasThrown), - V8_CRDTP_DESERIALIZE_FIELD_OPT("writable", m_writable), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(PropertyDescriptor) - V8_CRDTP_SERIALIZE_FIELD("name", m_name); - V8_CRDTP_SERIALIZE_FIELD("value", m_value); - V8_CRDTP_SERIALIZE_FIELD("writable", m_writable); - V8_CRDTP_SERIALIZE_FIELD("get", m_get); - V8_CRDTP_SERIALIZE_FIELD("set", m_set); - V8_CRDTP_SERIALIZE_FIELD("configurable", m_configurable); - V8_CRDTP_SERIALIZE_FIELD("enumerable", m_enumerable); - V8_CRDTP_SERIALIZE_FIELD("wasThrown", m_wasThrown); - V8_CRDTP_SERIALIZE_FIELD("isOwn", m_isOwn); - V8_CRDTP_SERIALIZE_FIELD("symbol", m_symbol); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(InternalPropertyDescriptor) - V8_CRDTP_DESERIALIZE_FIELD("name", m_name), - V8_CRDTP_DESERIALIZE_FIELD_OPT("value", m_value), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(InternalPropertyDescriptor) - V8_CRDTP_SERIALIZE_FIELD("name", m_name); - V8_CRDTP_SERIALIZE_FIELD("value", m_value); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(PrivatePropertyDescriptor) - V8_CRDTP_DESERIALIZE_FIELD_OPT("get", m_get), - V8_CRDTP_DESERIALIZE_FIELD("name", m_name), - V8_CRDTP_DESERIALIZE_FIELD_OPT("set", m_set), - V8_CRDTP_DESERIALIZE_FIELD_OPT("value", m_value), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(PrivatePropertyDescriptor) - V8_CRDTP_SERIALIZE_FIELD("name", m_name); - V8_CRDTP_SERIALIZE_FIELD("value", m_value); - V8_CRDTP_SERIALIZE_FIELD("get", m_get); - V8_CRDTP_SERIALIZE_FIELD("set", m_set); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(CallArgument) - V8_CRDTP_DESERIALIZE_FIELD_OPT("objectId", m_objectId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("unserializableValue", m_unserializableValue), - V8_CRDTP_DESERIALIZE_FIELD_OPT("value", m_value), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(CallArgument) - V8_CRDTP_SERIALIZE_FIELD("value", m_value); - V8_CRDTP_SERIALIZE_FIELD("unserializableValue", m_unserializableValue); - V8_CRDTP_SERIALIZE_FIELD("objectId", m_objectId); -V8_CRDTP_END_SERIALIZER(); - - - -V8_CRDTP_BEGIN_DESERIALIZER(ExecutionContextDescription) - V8_CRDTP_DESERIALIZE_FIELD_OPT("auxData", m_auxData), - V8_CRDTP_DESERIALIZE_FIELD("id", m_id), - V8_CRDTP_DESERIALIZE_FIELD("name", m_name), - V8_CRDTP_DESERIALIZE_FIELD("origin", m_origin), - V8_CRDTP_DESERIALIZE_FIELD("uniqueId", m_uniqueId), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(ExecutionContextDescription) - V8_CRDTP_SERIALIZE_FIELD("id", m_id); - V8_CRDTP_SERIALIZE_FIELD("origin", m_origin); - V8_CRDTP_SERIALIZE_FIELD("name", m_name); - V8_CRDTP_SERIALIZE_FIELD("uniqueId", m_uniqueId); - V8_CRDTP_SERIALIZE_FIELD("auxData", m_auxData); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(ExceptionDetails) - V8_CRDTP_DESERIALIZE_FIELD("columnNumber", m_columnNumber), - V8_CRDTP_DESERIALIZE_FIELD_OPT("exception", m_exception), - V8_CRDTP_DESERIALIZE_FIELD("exceptionId", m_exceptionId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("exceptionMetaData", m_exceptionMetaData), - V8_CRDTP_DESERIALIZE_FIELD_OPT("executionContextId", m_executionContextId), - V8_CRDTP_DESERIALIZE_FIELD("lineNumber", m_lineNumber), - V8_CRDTP_DESERIALIZE_FIELD_OPT("scriptId", m_scriptId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("stackTrace", m_stackTrace), - V8_CRDTP_DESERIALIZE_FIELD("text", m_text), - V8_CRDTP_DESERIALIZE_FIELD_OPT("url", m_url), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(ExceptionDetails) - V8_CRDTP_SERIALIZE_FIELD("exceptionId", m_exceptionId); - V8_CRDTP_SERIALIZE_FIELD("text", m_text); - V8_CRDTP_SERIALIZE_FIELD("lineNumber", m_lineNumber); - V8_CRDTP_SERIALIZE_FIELD("columnNumber", m_columnNumber); - V8_CRDTP_SERIALIZE_FIELD("scriptId", m_scriptId); - V8_CRDTP_SERIALIZE_FIELD("url", m_url); - V8_CRDTP_SERIALIZE_FIELD("stackTrace", m_stackTrace); - V8_CRDTP_SERIALIZE_FIELD("exception", m_exception); - V8_CRDTP_SERIALIZE_FIELD("executionContextId", m_executionContextId); - V8_CRDTP_SERIALIZE_FIELD("exceptionMetaData", m_exceptionMetaData); -V8_CRDTP_END_SERIALIZER(); - - - - -V8_CRDTP_BEGIN_DESERIALIZER(CallFrame) - V8_CRDTP_DESERIALIZE_FIELD("columnNumber", m_columnNumber), - V8_CRDTP_DESERIALIZE_FIELD("functionName", m_functionName), - V8_CRDTP_DESERIALIZE_FIELD("lineNumber", m_lineNumber), - V8_CRDTP_DESERIALIZE_FIELD("scriptId", m_scriptId), - V8_CRDTP_DESERIALIZE_FIELD("url", m_url), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(CallFrame) - V8_CRDTP_SERIALIZE_FIELD("functionName", m_functionName); - V8_CRDTP_SERIALIZE_FIELD("scriptId", m_scriptId); - V8_CRDTP_SERIALIZE_FIELD("url", m_url); - V8_CRDTP_SERIALIZE_FIELD("lineNumber", m_lineNumber); - V8_CRDTP_SERIALIZE_FIELD("columnNumber", m_columnNumber); -V8_CRDTP_END_SERIALIZER(); - - -V8_CRDTP_BEGIN_DESERIALIZER(StackTrace) - V8_CRDTP_DESERIALIZE_FIELD("callFrames", m_callFrames), - V8_CRDTP_DESERIALIZE_FIELD_OPT("description", m_description), - V8_CRDTP_DESERIALIZE_FIELD_OPT("parent", m_parent), - V8_CRDTP_DESERIALIZE_FIELD_OPT("parentId", m_parentId), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(StackTrace) - V8_CRDTP_SERIALIZE_FIELD("description", m_description); - V8_CRDTP_SERIALIZE_FIELD("callFrames", m_callFrames); - V8_CRDTP_SERIALIZE_FIELD("parent", m_parent); - V8_CRDTP_SERIALIZE_FIELD("parentId", m_parentId); -V8_CRDTP_END_SERIALIZER(); - -// static -std::unique_ptr API::StackTrace::fromBinary(const uint8_t* data, size_t length) -{ - return protocol::Runtime::StackTrace::FromBinary(data, length); -} - - -V8_CRDTP_BEGIN_DESERIALIZER(StackTraceId) - V8_CRDTP_DESERIALIZE_FIELD_OPT("debuggerId", m_debuggerId), - V8_CRDTP_DESERIALIZE_FIELD("id", m_id), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(StackTraceId) - V8_CRDTP_SERIALIZE_FIELD("id", m_id); - V8_CRDTP_SERIALIZE_FIELD("debuggerId", m_debuggerId); -V8_CRDTP_END_SERIALIZER(); - -// static -std::unique_ptr API::StackTraceId::fromBinary(const uint8_t* data, size_t length) -{ - return protocol::Runtime::StackTraceId::FromBinary(data, length); -} - -// ------------- Enum values from params. - - -namespace ConsoleAPICalled { -namespace TypeEnum { -const char* Log = "log"; -const char* Debug = "debug"; -const char* Info = "info"; -const char* Error = "error"; -const char* Warning = "warning"; -const char* Dir = "dir"; -const char* Dirxml = "dirxml"; -const char* Table = "table"; -const char* Trace = "trace"; -const char* Clear = "clear"; -const char* StartGroup = "startGroup"; -const char* StartGroupCollapsed = "startGroupCollapsed"; -const char* EndGroup = "endGroup"; -const char* Assert = "assert"; -const char* Profile = "profile"; -const char* ProfileEnd = "profileEnd"; -const char* Count = "count"; -const char* TimeEnd = "timeEnd"; -} // namespace TypeEnum -} // namespace ConsoleAPICalled - -// ------------- Frontend notifications. - -void Frontend::bindingCalled(const String& name, const String& payload, int executionContextId) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("name"), name); - serializer.AddField(v8_crdtp::MakeSpan("payload"), payload); - serializer.AddField(v8_crdtp::MakeSpan("executionContextId"), executionContextId); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Runtime.bindingCalled", serializer.Finish())); -} - -void Frontend::consoleAPICalled(const String& type, std::unique_ptr> args, int executionContextId, double timestamp, Maybe stackTrace, Maybe context) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("type"), type); - serializer.AddField(v8_crdtp::MakeSpan("args"), args); - serializer.AddField(v8_crdtp::MakeSpan("executionContextId"), executionContextId); - serializer.AddField(v8_crdtp::MakeSpan("timestamp"), timestamp); - serializer.AddField(v8_crdtp::MakeSpan("stackTrace"), stackTrace); - serializer.AddField(v8_crdtp::MakeSpan("context"), context); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Runtime.consoleAPICalled", serializer.Finish())); -} - -void Frontend::exceptionRevoked(const String& reason, int exceptionId) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("reason"), reason); - serializer.AddField(v8_crdtp::MakeSpan("exceptionId"), exceptionId); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Runtime.exceptionRevoked", serializer.Finish())); -} - -void Frontend::exceptionThrown(double timestamp, std::unique_ptr exceptionDetails) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("timestamp"), timestamp); - serializer.AddField(v8_crdtp::MakeSpan("exceptionDetails"), exceptionDetails); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Runtime.exceptionThrown", serializer.Finish())); -} - -void Frontend::executionContextCreated(std::unique_ptr context) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("context"), context); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Runtime.executionContextCreated", serializer.Finish())); -} - -void Frontend::executionContextDestroyed(int executionContextId) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("executionContextId"), executionContextId); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Runtime.executionContextDestroyed", serializer.Finish())); -} - -void Frontend::executionContextsCleared() -{ - if (!frontend_channel_) - return; - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Runtime.executionContextsCleared")); -} - -void Frontend::inspectRequested(std::unique_ptr object, std::unique_ptr hints, Maybe executionContextId) -{ - if (!frontend_channel_) - return; - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("object"), object); - serializer.AddField(v8_crdtp::MakeSpan("hints"), hints); - serializer.AddField(v8_crdtp::MakeSpan("executionContextId"), executionContextId); - frontend_channel_->SendProtocolNotification(v8_crdtp::CreateNotification("Runtime.inspectRequested", serializer.Finish())); -} - -void Frontend::flush() -{ - frontend_channel_->FlushProtocolNotifications(); -} - -void Frontend::sendRawNotification(std::unique_ptr notification) -{ - frontend_channel_->SendProtocolNotification(std::move(notification)); -} - -// --------------------- Dispatcher. - -class DomainDispatcherImpl : public protocol::DomainDispatcher { -public: - DomainDispatcherImpl(FrontendChannel* frontendChannel, Backend* backend) - : DomainDispatcher(frontendChannel) - , m_backend(backend) {} - ~DomainDispatcherImpl() override { } - - using CallHandler = void (DomainDispatcherImpl::*)(const v8_crdtp::Dispatchable& dispatchable); - - std::function Dispatch(v8_crdtp::span command_name) override; - - void awaitPromise(const v8_crdtp::Dispatchable& dispatchable); - void callFunctionOn(const v8_crdtp::Dispatchable& dispatchable); - void compileScript(const v8_crdtp::Dispatchable& dispatchable); - void disable(const v8_crdtp::Dispatchable& dispatchable); - void discardConsoleEntries(const v8_crdtp::Dispatchable& dispatchable); - void enable(const v8_crdtp::Dispatchable& dispatchable); - void evaluate(const v8_crdtp::Dispatchable& dispatchable); - void getIsolateId(const v8_crdtp::Dispatchable& dispatchable); - void getHeapUsage(const v8_crdtp::Dispatchable& dispatchable); - void getProperties(const v8_crdtp::Dispatchable& dispatchable); - void globalLexicalScopeNames(const v8_crdtp::Dispatchable& dispatchable); - void queryObjects(const v8_crdtp::Dispatchable& dispatchable); - void releaseObject(const v8_crdtp::Dispatchable& dispatchable); - void releaseObjectGroup(const v8_crdtp::Dispatchable& dispatchable); - void runIfWaitingForDebugger(const v8_crdtp::Dispatchable& dispatchable); - void runScript(const v8_crdtp::Dispatchable& dispatchable); - void setCustomObjectFormatterEnabled(const v8_crdtp::Dispatchable& dispatchable); - void setMaxCallStackSizeToCapture(const v8_crdtp::Dispatchable& dispatchable); - void terminateExecution(const v8_crdtp::Dispatchable& dispatchable); - void addBinding(const v8_crdtp::Dispatchable& dispatchable); - void removeBinding(const v8_crdtp::Dispatchable& dispatchable); - void getExceptionDetails(const v8_crdtp::Dispatchable& dispatchable); - protected: - Backend* m_backend; -}; - -namespace { -// This helper method with a static map of command methods (instance methods -// of DomainDispatcherImpl declared just above) by their name is used immediately below, -// in the DomainDispatcherImpl::Dispatch method. -DomainDispatcherImpl::CallHandler CommandByName(v8_crdtp::span command_name) { - static auto* commands = [](){ - auto* commands = new std::vector, - DomainDispatcherImpl::CallHandler>>{ - { - v8_crdtp::SpanFrom("addBinding"), - &DomainDispatcherImpl::addBinding - }, - { - v8_crdtp::SpanFrom("awaitPromise"), - &DomainDispatcherImpl::awaitPromise - }, - { - v8_crdtp::SpanFrom("callFunctionOn"), - &DomainDispatcherImpl::callFunctionOn - }, - { - v8_crdtp::SpanFrom("compileScript"), - &DomainDispatcherImpl::compileScript - }, - { - v8_crdtp::SpanFrom("disable"), - &DomainDispatcherImpl::disable - }, - { - v8_crdtp::SpanFrom("discardConsoleEntries"), - &DomainDispatcherImpl::discardConsoleEntries - }, - { - v8_crdtp::SpanFrom("enable"), - &DomainDispatcherImpl::enable - }, - { - v8_crdtp::SpanFrom("evaluate"), - &DomainDispatcherImpl::evaluate - }, - { - v8_crdtp::SpanFrom("getExceptionDetails"), - &DomainDispatcherImpl::getExceptionDetails - }, - { - v8_crdtp::SpanFrom("getHeapUsage"), - &DomainDispatcherImpl::getHeapUsage - }, - { - v8_crdtp::SpanFrom("getIsolateId"), - &DomainDispatcherImpl::getIsolateId - }, - { - v8_crdtp::SpanFrom("getProperties"), - &DomainDispatcherImpl::getProperties - }, - { - v8_crdtp::SpanFrom("globalLexicalScopeNames"), - &DomainDispatcherImpl::globalLexicalScopeNames - }, - { - v8_crdtp::SpanFrom("queryObjects"), - &DomainDispatcherImpl::queryObjects - }, - { - v8_crdtp::SpanFrom("releaseObject"), - &DomainDispatcherImpl::releaseObject - }, - { - v8_crdtp::SpanFrom("releaseObjectGroup"), - &DomainDispatcherImpl::releaseObjectGroup - }, - { - v8_crdtp::SpanFrom("removeBinding"), - &DomainDispatcherImpl::removeBinding - }, - { - v8_crdtp::SpanFrom("runIfWaitingForDebugger"), - &DomainDispatcherImpl::runIfWaitingForDebugger - }, - { - v8_crdtp::SpanFrom("runScript"), - &DomainDispatcherImpl::runScript - }, - { - v8_crdtp::SpanFrom("setCustomObjectFormatterEnabled"), - &DomainDispatcherImpl::setCustomObjectFormatterEnabled - }, - { - v8_crdtp::SpanFrom("setMaxCallStackSizeToCapture"), - &DomainDispatcherImpl::setMaxCallStackSizeToCapture - }, - { - v8_crdtp::SpanFrom("terminateExecution"), - &DomainDispatcherImpl::terminateExecution - }, - }; - return commands; - }(); - return v8_crdtp::FindByFirst(*commands, command_name, nullptr); -} -} // namespace - -std::function DomainDispatcherImpl::Dispatch(v8_crdtp::span command_name) { - CallHandler handler = CommandByName(command_name); - if (!handler) return nullptr; - - return [this, handler](const v8_crdtp::Dispatchable& dispatchable) { - (this->*handler)(dispatchable); - }; -} - - -class AwaitPromiseCallbackImpl : public Backend::AwaitPromiseCallback, public DomainDispatcher::Callback { -public: - AwaitPromiseCallbackImpl(std::unique_ptr backendImpl, int callId, v8_crdtp::span message) - : DomainDispatcher::Callback(std::move(backendImpl), callId, -v8_crdtp::SpanFrom("Runtime.awaitPromise"), message) { } - - void sendSuccess(std::unique_ptr result, Maybe exceptionDetails) override - { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("result"), result); - serializer.AddField(v8_crdtp::MakeSpan("exceptionDetails"), exceptionDetails); - sendIfActive(serializer.Finish(), DispatchResponse::Success()); - } - - void fallThrough() override - { - fallThroughIfActive(); - } - - void sendFailure(const DispatchResponse& response) override - { - DCHECK(response.IsError()); - sendIfActive(nullptr, response); - } -}; - -namespace { - -struct awaitPromiseParams : public v8_crdtp::DeserializableProtocolObject { - String promiseObjectId; - Maybe returnByValue; - Maybe generatePreview; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(awaitPromiseParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("generatePreview", generatePreview), - V8_CRDTP_DESERIALIZE_FIELD("promiseObjectId", promiseObjectId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("returnByValue", returnByValue), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::awaitPromise(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - awaitPromiseParams params; - awaitPromiseParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - m_backend->awaitPromise(params.promiseObjectId, std::move(params.returnByValue), std::move(params.generatePreview), std::make_unique(weakPtr(), dispatchable.CallId(), dispatchable.Serialized())); -} - -class CallFunctionOnCallbackImpl : public Backend::CallFunctionOnCallback, public DomainDispatcher::Callback { -public: - CallFunctionOnCallbackImpl(std::unique_ptr backendImpl, int callId, v8_crdtp::span message) - : DomainDispatcher::Callback(std::move(backendImpl), callId, -v8_crdtp::SpanFrom("Runtime.callFunctionOn"), message) { } - - void sendSuccess(std::unique_ptr result, Maybe exceptionDetails) override - { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("result"), result); - serializer.AddField(v8_crdtp::MakeSpan("exceptionDetails"), exceptionDetails); - sendIfActive(serializer.Finish(), DispatchResponse::Success()); - } - - void fallThrough() override - { - fallThroughIfActive(); - } - - void sendFailure(const DispatchResponse& response) override - { - DCHECK(response.IsError()); - sendIfActive(nullptr, response); - } -}; - -namespace { - -struct callFunctionOnParams : public v8_crdtp::DeserializableProtocolObject { - String functionDeclaration; - Maybe objectId; - Maybe> arguments; - Maybe silent; - Maybe returnByValue; - Maybe generatePreview; - Maybe userGesture; - Maybe awaitPromise; - Maybe executionContextId; - Maybe objectGroup; - Maybe throwOnSideEffect; - Maybe generateWebDriverValue; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(callFunctionOnParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("arguments", arguments), - V8_CRDTP_DESERIALIZE_FIELD_OPT("awaitPromise", awaitPromise), - V8_CRDTP_DESERIALIZE_FIELD_OPT("executionContextId", executionContextId), - V8_CRDTP_DESERIALIZE_FIELD("functionDeclaration", functionDeclaration), - V8_CRDTP_DESERIALIZE_FIELD_OPT("generatePreview", generatePreview), - V8_CRDTP_DESERIALIZE_FIELD_OPT("generateWebDriverValue", generateWebDriverValue), - V8_CRDTP_DESERIALIZE_FIELD_OPT("objectGroup", objectGroup), - V8_CRDTP_DESERIALIZE_FIELD_OPT("objectId", objectId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("returnByValue", returnByValue), - V8_CRDTP_DESERIALIZE_FIELD_OPT("silent", silent), - V8_CRDTP_DESERIALIZE_FIELD_OPT("throwOnSideEffect", throwOnSideEffect), - V8_CRDTP_DESERIALIZE_FIELD_OPT("userGesture", userGesture), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::callFunctionOn(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - callFunctionOnParams params; - callFunctionOnParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - m_backend->callFunctionOn(params.functionDeclaration, std::move(params.objectId), std::move(params.arguments), std::move(params.silent), std::move(params.returnByValue), std::move(params.generatePreview), std::move(params.userGesture), std::move(params.awaitPromise), std::move(params.executionContextId), std::move(params.objectGroup), std::move(params.throwOnSideEffect), std::move(params.generateWebDriverValue), std::make_unique(weakPtr(), dispatchable.CallId(), dispatchable.Serialized())); -} - -namespace { - -struct compileScriptParams : public v8_crdtp::DeserializableProtocolObject { - String expression; - String sourceURL; - bool persistScript; - Maybe executionContextId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(compileScriptParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("executionContextId", executionContextId), - V8_CRDTP_DESERIALIZE_FIELD("expression", expression), - V8_CRDTP_DESERIALIZE_FIELD("persistScript", persistScript), - V8_CRDTP_DESERIALIZE_FIELD("sourceURL", sourceURL), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::compileScript(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - compileScriptParams params; - compileScriptParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - Maybe out_scriptId; - Maybe out_exceptionDetails; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->compileScript(params.expression, params.sourceURL, params.persistScript, std::move(params.executionContextId), &out_scriptId, &out_exceptionDetails); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.compileScript"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("scriptId"), out_scriptId); - serializer.AddField(v8_crdtp::MakeSpan("exceptionDetails"), out_exceptionDetails); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::disable(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->disable(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.disable"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::discardConsoleEntries(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->discardConsoleEntries(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.discardConsoleEntries"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::enable(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->enable(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.enable"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -class EvaluateCallbackImpl : public Backend::EvaluateCallback, public DomainDispatcher::Callback { -public: - EvaluateCallbackImpl(std::unique_ptr backendImpl, int callId, v8_crdtp::span message) - : DomainDispatcher::Callback(std::move(backendImpl), callId, -v8_crdtp::SpanFrom("Runtime.evaluate"), message) { } - - void sendSuccess(std::unique_ptr result, Maybe exceptionDetails) override - { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("result"), result); - serializer.AddField(v8_crdtp::MakeSpan("exceptionDetails"), exceptionDetails); - sendIfActive(serializer.Finish(), DispatchResponse::Success()); - } - - void fallThrough() override - { - fallThroughIfActive(); - } - - void sendFailure(const DispatchResponse& response) override - { - DCHECK(response.IsError()); - sendIfActive(nullptr, response); - } -}; - -namespace { - -struct evaluateParams : public v8_crdtp::DeserializableProtocolObject { - String expression; - Maybe objectGroup; - Maybe includeCommandLineAPI; - Maybe silent; - Maybe contextId; - Maybe returnByValue; - Maybe generatePreview; - Maybe userGesture; - Maybe awaitPromise; - Maybe throwOnSideEffect; - Maybe timeout; - Maybe disableBreaks; - Maybe replMode; - Maybe allowUnsafeEvalBlockedByCSP; - Maybe uniqueContextId; - Maybe generateWebDriverValue; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(evaluateParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("allowUnsafeEvalBlockedByCSP", allowUnsafeEvalBlockedByCSP), - V8_CRDTP_DESERIALIZE_FIELD_OPT("awaitPromise", awaitPromise), - V8_CRDTP_DESERIALIZE_FIELD_OPT("contextId", contextId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("disableBreaks", disableBreaks), - V8_CRDTP_DESERIALIZE_FIELD("expression", expression), - V8_CRDTP_DESERIALIZE_FIELD_OPT("generatePreview", generatePreview), - V8_CRDTP_DESERIALIZE_FIELD_OPT("generateWebDriverValue", generateWebDriverValue), - V8_CRDTP_DESERIALIZE_FIELD_OPT("includeCommandLineAPI", includeCommandLineAPI), - V8_CRDTP_DESERIALIZE_FIELD_OPT("objectGroup", objectGroup), - V8_CRDTP_DESERIALIZE_FIELD_OPT("replMode", replMode), - V8_CRDTP_DESERIALIZE_FIELD_OPT("returnByValue", returnByValue), - V8_CRDTP_DESERIALIZE_FIELD_OPT("silent", silent), - V8_CRDTP_DESERIALIZE_FIELD_OPT("throwOnSideEffect", throwOnSideEffect), - V8_CRDTP_DESERIALIZE_FIELD_OPT("timeout", timeout), - V8_CRDTP_DESERIALIZE_FIELD_OPT("uniqueContextId", uniqueContextId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("userGesture", userGesture), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::evaluate(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - evaluateParams params; - evaluateParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - m_backend->evaluate(params.expression, std::move(params.objectGroup), std::move(params.includeCommandLineAPI), std::move(params.silent), std::move(params.contextId), std::move(params.returnByValue), std::move(params.generatePreview), std::move(params.userGesture), std::move(params.awaitPromise), std::move(params.throwOnSideEffect), std::move(params.timeout), std::move(params.disableBreaks), std::move(params.replMode), std::move(params.allowUnsafeEvalBlockedByCSP), std::move(params.uniqueContextId), std::move(params.generateWebDriverValue), std::make_unique(weakPtr(), dispatchable.CallId(), dispatchable.Serialized())); -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::getIsolateId(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - // Declare output parameters. - String out_id; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getIsolateId(&out_id); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.getIsolateId"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("id"), out_id); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::getHeapUsage(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - // Declare output parameters. - double out_usedSize; - double out_totalSize; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getHeapUsage(&out_usedSize, &out_totalSize); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.getHeapUsage"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("usedSize"), out_usedSize); - serializer.AddField(v8_crdtp::MakeSpan("totalSize"), out_totalSize); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct getPropertiesParams : public v8_crdtp::DeserializableProtocolObject { - String objectId; - Maybe ownProperties; - Maybe accessorPropertiesOnly; - Maybe generatePreview; - Maybe nonIndexedPropertiesOnly; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(getPropertiesParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("accessorPropertiesOnly", accessorPropertiesOnly), - V8_CRDTP_DESERIALIZE_FIELD_OPT("generatePreview", generatePreview), - V8_CRDTP_DESERIALIZE_FIELD_OPT("nonIndexedPropertiesOnly", nonIndexedPropertiesOnly), - V8_CRDTP_DESERIALIZE_FIELD("objectId", objectId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("ownProperties", ownProperties), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::getProperties(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - getPropertiesParams params; - getPropertiesParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - std::unique_ptr> out_result; - Maybe> out_internalProperties; - Maybe> out_privateProperties; - Maybe out_exceptionDetails; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getProperties(params.objectId, std::move(params.ownProperties), std::move(params.accessorPropertiesOnly), std::move(params.generatePreview), std::move(params.nonIndexedPropertiesOnly), &out_result, &out_internalProperties, &out_privateProperties, &out_exceptionDetails); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.getProperties"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("result"), out_result); - serializer.AddField(v8_crdtp::MakeSpan("internalProperties"), out_internalProperties); - serializer.AddField(v8_crdtp::MakeSpan("privateProperties"), out_privateProperties); - serializer.AddField(v8_crdtp::MakeSpan("exceptionDetails"), out_exceptionDetails); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct globalLexicalScopeNamesParams : public v8_crdtp::DeserializableProtocolObject { - Maybe executionContextId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(globalLexicalScopeNamesParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("executionContextId", executionContextId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::globalLexicalScopeNames(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - globalLexicalScopeNamesParams params; - globalLexicalScopeNamesParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - std::unique_ptr> out_names; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->globalLexicalScopeNames(std::move(params.executionContextId), &out_names); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.globalLexicalScopeNames"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("names"), out_names); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct queryObjectsParams : public v8_crdtp::DeserializableProtocolObject { - String prototypeObjectId; - Maybe objectGroup; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(queryObjectsParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("objectGroup", objectGroup), - V8_CRDTP_DESERIALIZE_FIELD("prototypeObjectId", prototypeObjectId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::queryObjects(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - queryObjectsParams params; - queryObjectsParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - std::unique_ptr out_objects; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->queryObjects(params.prototypeObjectId, std::move(params.objectGroup), &out_objects); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.queryObjects"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("objects"), out_objects); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { - -struct releaseObjectParams : public v8_crdtp::DeserializableProtocolObject { - String objectId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(releaseObjectParams) - V8_CRDTP_DESERIALIZE_FIELD("objectId", objectId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::releaseObject(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - releaseObjectParams params; - releaseObjectParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->releaseObject(params.objectId); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.releaseObject"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct releaseObjectGroupParams : public v8_crdtp::DeserializableProtocolObject { - String objectGroup; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(releaseObjectGroupParams) - V8_CRDTP_DESERIALIZE_FIELD("objectGroup", objectGroup), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::releaseObjectGroup(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - releaseObjectGroupParams params; - releaseObjectGroupParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->releaseObjectGroup(params.objectGroup); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.releaseObjectGroup"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - - -} // namespace - -void DomainDispatcherImpl::runIfWaitingForDebugger(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->runIfWaitingForDebugger(); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.runIfWaitingForDebugger"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -class RunScriptCallbackImpl : public Backend::RunScriptCallback, public DomainDispatcher::Callback { -public: - RunScriptCallbackImpl(std::unique_ptr backendImpl, int callId, v8_crdtp::span message) - : DomainDispatcher::Callback(std::move(backendImpl), callId, -v8_crdtp::SpanFrom("Runtime.runScript"), message) { } - - void sendSuccess(std::unique_ptr result, Maybe exceptionDetails) override - { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("result"), result); - serializer.AddField(v8_crdtp::MakeSpan("exceptionDetails"), exceptionDetails); - sendIfActive(serializer.Finish(), DispatchResponse::Success()); - } - - void fallThrough() override - { - fallThroughIfActive(); - } - - void sendFailure(const DispatchResponse& response) override - { - DCHECK(response.IsError()); - sendIfActive(nullptr, response); - } -}; - -namespace { - -struct runScriptParams : public v8_crdtp::DeserializableProtocolObject { - String scriptId; - Maybe executionContextId; - Maybe objectGroup; - Maybe silent; - Maybe includeCommandLineAPI; - Maybe returnByValue; - Maybe generatePreview; - Maybe awaitPromise; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(runScriptParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("awaitPromise", awaitPromise), - V8_CRDTP_DESERIALIZE_FIELD_OPT("executionContextId", executionContextId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("generatePreview", generatePreview), - V8_CRDTP_DESERIALIZE_FIELD_OPT("includeCommandLineAPI", includeCommandLineAPI), - V8_CRDTP_DESERIALIZE_FIELD_OPT("objectGroup", objectGroup), - V8_CRDTP_DESERIALIZE_FIELD_OPT("returnByValue", returnByValue), - V8_CRDTP_DESERIALIZE_FIELD("scriptId", scriptId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("silent", silent), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::runScript(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - runScriptParams params; - runScriptParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - m_backend->runScript(params.scriptId, std::move(params.executionContextId), std::move(params.objectGroup), std::move(params.silent), std::move(params.includeCommandLineAPI), std::move(params.returnByValue), std::move(params.generatePreview), std::move(params.awaitPromise), std::make_unique(weakPtr(), dispatchable.CallId(), dispatchable.Serialized())); -} - -namespace { - -struct setCustomObjectFormatterEnabledParams : public v8_crdtp::DeserializableProtocolObject { - bool enabled; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setCustomObjectFormatterEnabledParams) - V8_CRDTP_DESERIALIZE_FIELD("enabled", enabled), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setCustomObjectFormatterEnabled(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setCustomObjectFormatterEnabledParams params; - setCustomObjectFormatterEnabledParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setCustomObjectFormatterEnabled(params.enabled); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.setCustomObjectFormatterEnabled"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct setMaxCallStackSizeToCaptureParams : public v8_crdtp::DeserializableProtocolObject { - int size; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(setMaxCallStackSizeToCaptureParams) - V8_CRDTP_DESERIALIZE_FIELD("size", size), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::setMaxCallStackSizeToCapture(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - setMaxCallStackSizeToCaptureParams params; - setMaxCallStackSizeToCaptureParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->setMaxCallStackSizeToCapture(params.size); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.setMaxCallStackSizeToCapture"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -class TerminateExecutionCallbackImpl : public Backend::TerminateExecutionCallback, public DomainDispatcher::Callback { -public: - TerminateExecutionCallbackImpl(std::unique_ptr backendImpl, int callId, v8_crdtp::span message) - : DomainDispatcher::Callback(std::move(backendImpl), callId, -v8_crdtp::SpanFrom("Runtime.terminateExecution"), message) { } - - void sendSuccess() override - { - v8_crdtp::ObjectSerializer serializer; - sendIfActive(serializer.Finish(), DispatchResponse::Success()); - } - - void fallThrough() override - { - fallThroughIfActive(); - } - - void sendFailure(const DispatchResponse& response) override - { - DCHECK(response.IsError()); - sendIfActive(nullptr, response); - } -}; - -namespace { - - -} // namespace - -void DomainDispatcherImpl::terminateExecution(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - - m_backend->terminateExecution(std::make_unique(weakPtr(), dispatchable.CallId(), dispatchable.Serialized())); -} - -namespace { - -struct addBindingParams : public v8_crdtp::DeserializableProtocolObject { - String name; - Maybe executionContextId; - Maybe executionContextName; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(addBindingParams) - V8_CRDTP_DESERIALIZE_FIELD_OPT("executionContextId", executionContextId), - V8_CRDTP_DESERIALIZE_FIELD_OPT("executionContextName", executionContextName), - V8_CRDTP_DESERIALIZE_FIELD("name", name), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::addBinding(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - addBindingParams params; - addBindingParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->addBinding(params.name, std::move(params.executionContextId), std::move(params.executionContextName)); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.addBinding"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct removeBindingParams : public v8_crdtp::DeserializableProtocolObject { - String name; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(removeBindingParams) - V8_CRDTP_DESERIALIZE_FIELD("name", name), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::removeBinding(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - removeBindingParams params; - removeBindingParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->removeBinding(params.name); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.removeBinding"), dispatchable.Serialized()); - return; - } - if (weak->get()) - weak->get()->sendResponse(dispatchable.CallId(), response); - return; -} - -namespace { - -struct getExceptionDetailsParams : public v8_crdtp::DeserializableProtocolObject { - String errorObjectId; - DECLARE_DESERIALIZATION_SUPPORT(); -}; - -V8_CRDTP_BEGIN_DESERIALIZER(getExceptionDetailsParams) - V8_CRDTP_DESERIALIZE_FIELD("errorObjectId", errorObjectId), -V8_CRDTP_END_DESERIALIZER() - -} // namespace - -void DomainDispatcherImpl::getExceptionDetails(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - auto deserializer = v8_crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer(); - getExceptionDetailsParams params; - getExceptionDetailsParams::Deserialize(&deserializer, ¶ms); - if (MaybeReportInvalidParams(dispatchable, deserializer)) - return; - - // Declare output parameters. - Maybe out_exceptionDetails; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getExceptionDetails(params.errorObjectId, &out_exceptionDetails); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Runtime.getExceptionDetails"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("exceptionDetails"), out_exceptionDetails); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { -// This helper method (with a static map of redirects) is used from Dispatcher::wire -// immediately below. -const std::vector, v8_crdtp::span>>& SortedRedirects() { - static auto* redirects = [](){ - auto* redirects = new std::vector, v8_crdtp::span>>{ - { v8_crdtp::SpanFrom("Runtime.setAsyncCallStackDepth"), v8_crdtp::SpanFrom("Debugger.setAsyncCallStackDepth") }, - }; - return redirects; - }(); - return *redirects; -} -} // namespace - -// static -void Dispatcher::wire(UberDispatcher* uber, Backend* backend) -{ - auto dispatcher = std::make_unique(uber->channel(), backend); - uber->WireBackend(v8_crdtp::SpanFrom("Runtime"), SortedRedirects(), std::move(dispatcher)); -} - -} // Runtime -} // namespace v8_inspector -} // namespace protocol diff --git a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Schema.cpp b/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Schema.cpp deleted file mode 100644 index 5a0310e06..000000000 --- a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/Schema.cpp +++ /dev/null @@ -1,160 +0,0 @@ -// This file is generated by TypeBuilder_cpp.template. - -// Copyright (c) 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/inspector/protocol/Schema.h" - -#include "src/inspector/protocol/Protocol.h" - -#include "third_party/inspector_protocol/crdtp/cbor.h" -#include "third_party/inspector_protocol/crdtp/find_by_first.h" -#include "third_party/inspector_protocol/crdtp/span.h" - -namespace v8_inspector { -namespace protocol { -namespace Schema { - -using v8_crdtp::DeserializerState; -using v8_crdtp::ProtocolTypeTraits; - -// ------------- Enum values from types. - -const char Metainfo::domainName[] = "Schema"; -const char Metainfo::commandPrefix[] = "Schema."; -const char Metainfo::version[] = "1.3"; - -V8_CRDTP_BEGIN_DESERIALIZER(Domain) - V8_CRDTP_DESERIALIZE_FIELD("name", m_name), - V8_CRDTP_DESERIALIZE_FIELD("version", m_version), -V8_CRDTP_END_DESERIALIZER() - -V8_CRDTP_BEGIN_SERIALIZER(Domain) - V8_CRDTP_SERIALIZE_FIELD("name", m_name); - V8_CRDTP_SERIALIZE_FIELD("version", m_version); -V8_CRDTP_END_SERIALIZER(); - -// static -std::unique_ptr API::Domain::fromBinary(const uint8_t* data, size_t length) -{ - return protocol::Schema::Domain::FromBinary(data, length); -} - -// ------------- Enum values from params. - - -// ------------- Frontend notifications. - -void Frontend::flush() -{ - frontend_channel_->FlushProtocolNotifications(); -} - -void Frontend::sendRawNotification(std::unique_ptr notification) -{ - frontend_channel_->SendProtocolNotification(std::move(notification)); -} - -// --------------------- Dispatcher. - -class DomainDispatcherImpl : public protocol::DomainDispatcher { -public: - DomainDispatcherImpl(FrontendChannel* frontendChannel, Backend* backend) - : DomainDispatcher(frontendChannel) - , m_backend(backend) {} - ~DomainDispatcherImpl() override { } - - using CallHandler = void (DomainDispatcherImpl::*)(const v8_crdtp::Dispatchable& dispatchable); - - std::function Dispatch(v8_crdtp::span command_name) override; - - void getDomains(const v8_crdtp::Dispatchable& dispatchable); - protected: - Backend* m_backend; -}; - -namespace { -// This helper method with a static map of command methods (instance methods -// of DomainDispatcherImpl declared just above) by their name is used immediately below, -// in the DomainDispatcherImpl::Dispatch method. -DomainDispatcherImpl::CallHandler CommandByName(v8_crdtp::span command_name) { - static auto* commands = [](){ - auto* commands = new std::vector, - DomainDispatcherImpl::CallHandler>>{ - { - v8_crdtp::SpanFrom("getDomains"), - &DomainDispatcherImpl::getDomains - }, - }; - return commands; - }(); - return v8_crdtp::FindByFirst(*commands, command_name, nullptr); -} -} // namespace - -std::function DomainDispatcherImpl::Dispatch(v8_crdtp::span command_name) { - CallHandler handler = CommandByName(command_name); - if (!handler) return nullptr; - - return [this, handler](const v8_crdtp::Dispatchable& dispatchable) { - (this->*handler)(dispatchable); - }; -} - - -namespace { - - -} // namespace - -void DomainDispatcherImpl::getDomains(const v8_crdtp::Dispatchable& dispatchable) -{ - // Prepare input parameters. - - // Declare output parameters. - std::unique_ptr> out_domains; - - std::unique_ptr weak = weakPtr(); - DispatchResponse response = m_backend->getDomains(&out_domains); - if (response.IsFallThrough()) { - channel()->FallThrough(dispatchable.CallId(), v8_crdtp::SpanFrom("Schema.getDomains"), dispatchable.Serialized()); - return; - } - if (weak->get()) { - std::unique_ptr result; - if (response.IsSuccess()) { - v8_crdtp::ObjectSerializer serializer; - serializer.AddField(v8_crdtp::MakeSpan("domains"), out_domains); - result = serializer.Finish(); - } else { - result = Serializable::From({}); - } - weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result)); - } - return; -} - -namespace { -// This helper method (with a static map of redirects) is used from Dispatcher::wire -// immediately below. -const std::vector, v8_crdtp::span>>& SortedRedirects() { - static auto* redirects = [](){ - auto* redirects = new std::vector, v8_crdtp::span>>{ - }; - return redirects; - }(); - return *redirects; -} -} // namespace - -// static -void Dispatcher::wire(UberDispatcher* uber, Backend* backend) -{ - auto dispatcher = std::make_unique(uber->channel(), backend); - uber->WireBackend(v8_crdtp::SpanFrom("Schema"), SortedRedirects(), std::move(dispatcher)); -} - -} // Schema -} // namespace v8_inspector -} // namespace protocol diff --git a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/base_string_adapter.cc b/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/base_string_adapter.cc deleted file mode 100644 index c9ae3626f..000000000 --- a/test-app/runtime/src/main/cpp/v8_inspector/src/inspector/protocol/base_string_adapter.cc +++ /dev/null @@ -1,121 +0,0 @@ -// This file is generated by base_string_adapter_cc.template. - -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/inspector/protocol/base_string_adapter.h" -#include "src/inspector/protocol/Protocol.h" - -#include -#include "base/base64.h" -#include "base/json/json_reader.h" -#include "base/memory/ptr_util.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "base/values.h" -#include "third_party/inspector_protocol/crdtp/cbor.h" -#include "third_party/inspector_protocol/crdtp/protocol_core.h" - -using namespace v8_crdtp; - -using v8_inspector::protocol::Binary; -using v8_inspector::protocol::String; -using v8_inspector::protocol::StringUtil; - -namespace v8_inspector { -namespace protocol { - -// In Chromium, we do not support big endian architectures, so no conversion is needed -// to interpret UTF16LE. -// static -String StringUtil::fromUTF16LE(const uint16_t* data, size_t length) { - std::string utf8; - base::UTF16ToUTF8(reinterpret_cast(data), length, &utf8); - return utf8; -} - -std::unique_ptr toProtocolValue( - const base::Value& value, int depth) { - if (!depth) - return nullptr; - if (value.is_none()) - return protocol::Value::null(); - if (value.is_bool()) - return protocol::FundamentalValue::create(value.GetBool()); - if (value.is_int()) - return protocol::FundamentalValue::create(value.GetInt()); - if (value.is_double()) - return protocol::FundamentalValue::create(value.GetDouble()); - if (value.is_string()) - return protocol::StringValue::create(value.GetString()); - if (value.is_list()) { - auto result = protocol::ListValue::create(); - for (const base::Value& item : value.GetList()) { - if (auto converted = toProtocolValue(item, depth - 1)) { - result->pushValue(std::move(converted)); - } - } - return result; - } - if (value.is_dict()) { - auto result = protocol::DictionaryValue::create(); - for (auto kv : value.DictItems()) { - if (auto converted = toProtocolValue(kv.second, depth - 1)) { - result->setValue(kv.first, std::move(converted)); - } - } - return result; - } - return nullptr; -} - -base::Value toBaseValue(Value* value, int depth) { - if (!value || !depth) - return base::Value(); - if (value->type() == Value::TypeBoolean) { - bool inner; - value->asBoolean(&inner); - return base::Value(inner); - } - if (value->type() == Value::TypeInteger) { - int inner; - value->asInteger(&inner); - return base::Value(inner); - } - if (value->type() == Value::TypeDouble) { - double inner; - value->asDouble(&inner); - return base::Value(inner); - } - if (value->type() == Value::TypeString) { - std::string inner; - value->asString(&inner); - return base::Value(inner); - } - if (value->type() == Value::TypeArray) { - ListValue* list = ListValue::cast(value); - base::Value result(base::Value::Type::LIST); - for (size_t i = 0; i < list->size(); i++) { - base::Value converted = toBaseValue(list->at(i), depth - 1); - if (!converted.is_none()) - result.Append(std::move(converted)); - } - return result; - } - if (value->type() == Value::TypeObject) { - DictionaryValue* dict = DictionaryValue::cast(value); - base::Value result(base::Value::Type::DICTIONARY); - for (size_t i = 0; i < dict->size(); i++) { - DictionaryValue::Entry entry = dict->at(i); - base::Value converted = toBaseValue(entry.second, depth - 1); - if (!converted.is_none()) - result.SetKey(entry.first, std::move(converted)); - } - return result; - } - return base::Value(); -} - -} // namespace v8_inspector { -} // namespace protocol { From 34d27867eb2f1b86d601bfd4b93a150a12269348 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 25 May 2023 16:08:31 -0700 Subject: [PATCH 20/23] chore: Remove duplicate code This line shadows a v8::Context already present in the outer scope, so it's not necessary. --- test-app/runtime/src/main/cpp/MetadataNode.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test-app/runtime/src/main/cpp/MetadataNode.cpp b/test-app/runtime/src/main/cpp/MetadataNode.cpp index e858d6d34..f1b74a05e 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.cpp +++ b/test-app/runtime/src/main/cpp/MetadataNode.cpp @@ -1053,7 +1053,6 @@ Local MetadataNode::GetConstructorFunctionTemplate(Isolate* is // insert isolate-specific persistent function handle node->m_poCtorCachePerIsolate.insert({isolate, new Persistent(isolate, wrappedCtorFunc)}); if (!baseCtorFunc.IsEmpty()) { - auto context = isolate->GetCurrentContext(); wrappedCtorFunc->SetPrototype(context, baseCtorFunc); } From 18f90c4c313bcfb5c39e673ca36c6613756cfc81 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Tue, 30 May 2023 14:33:57 -0700 Subject: [PATCH 21/23] chore: Make MetadataNode::tryGetExtensionMethodCallbackData more efficient Two changes suggested by Android Studio. We avoid copying the string argument, and we check quicker whether the map is empty without having to count all the entries. --- test-app/runtime/src/main/cpp/MetadataNode.cpp | 4 ++-- test-app/runtime/src/main/cpp/MetadataNode.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test-app/runtime/src/main/cpp/MetadataNode.cpp b/test-app/runtime/src/main/cpp/MetadataNode.cpp index f1b74a05e..f5dc703ab 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.cpp +++ b/test-app/runtime/src/main/cpp/MetadataNode.cpp @@ -671,9 +671,9 @@ vector MetadataNode::SetInstanceMethodsFromS MetadataNode::MethodCallbackData *MetadataNode::tryGetExtensionMethodCallbackData( std::unordered_map collectedMethodCallbackDatas, - std::string lookupName) { + const std::string& lookupName) { - if (collectedMethodCallbackDatas.size() < 1) { + if (collectedMethodCallbackDatas.empty()) { return nullptr; } diff --git a/test-app/runtime/src/main/cpp/MetadataNode.h b/test-app/runtime/src/main/cpp/MetadataNode.h index 7be68409f..c0de8da0a 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.h +++ b/test-app/runtime/src/main/cpp/MetadataNode.h @@ -97,7 +97,7 @@ class MetadataNode { MetadataTreeNode* treeNode); static MethodCallbackData* tryGetExtensionMethodCallbackData( std::unordered_map collectedMethodCallbackDatas, - std::string lookupName); + const std::string& lookupName); void SetInstanceFieldsFromStaticMetadata( v8::Isolate* isolate, PrototypeTemplateFiller& protoFiller, MetadataTreeNode* treeNode); From 1843dd2c3150c5f0580cf42a6d972ce812d5a5c5 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Thu, 24 Aug 2023 17:59:00 -0700 Subject: [PATCH 22/23] chore: Remove ObjectManager dead code JSWrapperConstructorCallback isn't used anywhere. --- test-app/runtime/src/main/cpp/ObjectManager.cpp | 4 ---- test-app/runtime/src/main/cpp/ObjectManager.h | 2 -- 2 files changed, 6 deletions(-) diff --git a/test-app/runtime/src/main/cpp/ObjectManager.cpp b/test-app/runtime/src/main/cpp/ObjectManager.cpp index fe134660c..e9575805b 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.cpp +++ b/test-app/runtime/src/main/cpp/ObjectManager.cpp @@ -287,10 +287,6 @@ Local ObjectManager::GetEmptyObject(Isolate *isolate) { return m_wrapperObjectTemplate.Get(isolate)->NewInstance(context).ToLocalChecked(); } -void ObjectManager::JSWrapperConstructorCallback(const v8::FunctionCallbackInfo &info) { - assert(info.IsConstructCall()); -} - void ObjectManager::ReleaseNativeCounterpart(v8::Local &object) { if(!object->IsObject()){ diff --git a/test-app/runtime/src/main/cpp/ObjectManager.h b/test-app/runtime/src/main/cpp/ObjectManager.h index 1b5244b10..912183fdb 100644 --- a/test-app/runtime/src/main/cpp/ObjectManager.h +++ b/test-app/runtime/src/main/cpp/ObjectManager.h @@ -80,8 +80,6 @@ class ObjectManager { static void DeleteWeakGlobalRefCallback(const jweak& object, void* state); - static void JSWrapperConstructorCallback(const v8::FunctionCallbackInfo& info); - static bool IsJsRuntimeObject(const v8::Local& object); jobject m_javaRuntimeObject; From 25338bf927b15c96027694a801d7bf82d910bb14 Mon Sep 17 00:00:00 2001 From: Philip Chimento Date: Wed, 30 Aug 2023 15:10:38 -0700 Subject: [PATCH 23/23] chore: Avoid copy in MetadataNode::IsJavascriptKeyword Noticed while fixing static initialization of keywords set, see next commit. --- test-app/runtime/src/main/cpp/MetadataNode.cpp | 2 +- test-app/runtime/src/main/cpp/MetadataNode.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test-app/runtime/src/main/cpp/MetadataNode.cpp b/test-app/runtime/src/main/cpp/MetadataNode.cpp index f5dc703ab..73a82f02a 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.cpp +++ b/test-app/runtime/src/main/cpp/MetadataNode.cpp @@ -2038,7 +2038,7 @@ void MetadataNode::EnableProfiler(bool enableProfiler) { s_profilerEnabled = enableProfiler; } -bool MetadataNode::IsJavascriptKeyword(std::string word) { +bool MetadataNode::IsJavascriptKeyword(const std::string& word) { static set keywords{ "abstract", "arguments", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "debugger", "default", "delete", "do", "double", "else", "enum", "eval", "export", "extends", "false", "final", "finally", "float", "for", "function", "goto", "if", "implements", diff --git a/test-app/runtime/src/main/cpp/MetadataNode.h b/test-app/runtime/src/main/cpp/MetadataNode.h index c0de8da0a..f954f0557 100644 --- a/test-app/runtime/src/main/cpp/MetadataNode.h +++ b/test-app/runtime/src/main/cpp/MetadataNode.h @@ -74,7 +74,7 @@ class MetadataNode { MetadataNode(MetadataTreeNode* treeNode); - static bool IsJavascriptKeyword(std::string word); + static bool IsJavascriptKeyword(const std::string& word); v8::Local CreatePackageObject(v8::Isolate* isolate); v8::Local GetConstructorFunction(v8::Isolate* isolate);