diff --git a/bridge/CMakeLists.txt b/bridge/CMakeLists.txt index fc075dd225..a25a55c2fe 100644 --- a/bridge/CMakeLists.txt +++ b/bridge/CMakeLists.txt @@ -83,8 +83,8 @@ endif() list(APPEND BRIDGE_SOURCE kraken_bridge.cc ${CMAKE_CURRENT_SOURCE_DIR}/include/kraken_bridge.h - ${CMAKE_CURRENT_SOURCE_DIR}/include/kraken_foundation.h ${CMAKE_CURRENT_SOURCE_DIR}/include/dart_methods.h + foundation/macros.h foundation/logging.cc foundation/logging.h foundation/colors.h @@ -98,10 +98,11 @@ list(APPEND BRIDGE_SOURCE foundation/inspector_task_queue.cc foundation/task_queue.cc foundation/task_queue.h + foundation/native_value.cc + foundation/native_value.h foundation/ui_command_buffer.cc foundation/ui_command_buffer.h foundation/ui_command_callback_queue.cc - foundation/closure.h dart_methods.cc polyfill/dist/polyfill.cc ) @@ -193,8 +194,8 @@ if ($ENV{KRAKEN_JS_ENGINE} MATCHES "quickjs") bindings/qjs/executing_context_data.h bindings/qjs/wrapper_type_info.h bindings/qjs/heap_hashmap.h - bindings/qjs/native_value.cc - bindings/qjs/native_value.h + bindings/qjs/native_string.cc + bindings/qjs/native_string.h bindings/qjs/qjs_patch.cc bindings/qjs/qjs_patch.h bindings/qjs/module_manager.cc @@ -288,7 +289,7 @@ endif () list(APPEND PUBLIC_HEADER include/kraken_bridge.h - ) +) add_library(kraken SHARED ${BRIDGE_SOURCE}) add_library(kraken_static STATIC ${BRIDGE_SOURCE}) diff --git a/bridge/bindings/qjs/bom/blob.cc b/bridge/bindings/qjs/bom/blob.cc index 3fe0fb6e28..dbe8bee144 100644 --- a/bridge/bindings/qjs/bom/blob.cc +++ b/bridge/bindings/qjs/bom/blob.cc @@ -6,7 +6,7 @@ #include "blob.h" #include "dart_methods.h" -namespace kraken::binding::qjs { +namespace kraken { void bindBlob(std::unique_ptr& context) { JSValue constructor = context->contextData()->constructorForType(&blobTypeInfo); @@ -260,4 +260,4 @@ uint8_t* Blob::bytes() { void Blob::trace(JSRuntime* rt, JSValue val, JS_MarkFunc* mark_func) const {} void Blob::dispose() const {} -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/bom/blob.h b/bridge/bindings/qjs/bom/blob.h index db3312c25c..13d14e1308 100644 --- a/bridge/bindings/qjs/bom/blob.h +++ b/bridge/bindings/qjs/bom/blob.h @@ -9,7 +9,7 @@ #include "bindings/qjs/context_macros.h" #include "bindings/qjs/garbage_collected.h" -namespace kraken::binding::qjs { +namespace kraken { class BlobBuilder; class BlobInstance; @@ -113,6 +113,6 @@ auto blobCreator = [](JSContext* ctx, JSValueConst func_obj, JSValueConst this_v const WrapperTypeInfo blobTypeInfo = {"Blob", nullptr, blobCreator}; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_BLOB_H diff --git a/bridge/bindings/qjs/bom/console.cc b/bridge/bindings/qjs/bom/console.cc index 2fefe57b99..17243e85e1 100644 --- a/bridge/bindings/qjs/bom/console.cc +++ b/bridge/bindings/qjs/bom/console.cc @@ -5,7 +5,7 @@ #include "console.h" -namespace kraken::binding::qjs { +namespace kraken { JSValue print(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv) { std::stringstream stream; @@ -34,4 +34,4 @@ void bindConsole(ExecutionContext* context) { QJS_GLOBAL_BINDING_FUNCTION(context, print, "__kraken_print__", 2); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/bom/console.h b/bridge/bindings/qjs/bom/console.h index b8db2594b2..e239662f09 100644 --- a/bridge/bindings/qjs/bom/console.h +++ b/bridge/bindings/qjs/bom/console.h @@ -8,7 +8,7 @@ #include "bindings/qjs/executing_context.h" -namespace kraken::binding::qjs { +namespace kraken { void bindConsole(ExecutionContext* context); diff --git a/bridge/bindings/qjs/bom/dom_timer_coordinator.cc b/bridge/bindings/qjs/bom/dom_timer_coordinator.cc index d95e0338c7..7ff63c46fe 100644 --- a/bridge/bindings/qjs/bom/dom_timer_coordinator.cc +++ b/bridge/bindings/qjs/bom/dom_timer_coordinator.cc @@ -11,7 +11,7 @@ #include "kraken_test_env.h" #endif -namespace kraken::binding::qjs { +namespace kraken { static void handleTimerCallback(DOMTimer* timer, const char* errmsg) { auto* context = static_cast(JS_GetContextOpaque(timer->ctx())); @@ -80,4 +80,4 @@ void DOMTimerCoordinator::trace(JSRuntime* rt, JSValue val, JS_MarkFunc* mark_fu } } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/bom/dom_timer_coordinator.h b/bridge/bindings/qjs/bom/dom_timer_coordinator.h index cd3fcbb54b..f165562bfd 100644 --- a/bridge/bindings/qjs/bom/dom_timer_coordinator.h +++ b/bridge/bindings/qjs/bom/dom_timer_coordinator.h @@ -10,7 +10,7 @@ #include #include -namespace kraken::binding::qjs { +namespace kraken { class DOMTimer; class ExecutionContext; @@ -37,6 +37,6 @@ class DOMTimerCoordinator { std::vector m_abandonedTimers; }; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_BINDINGS_QJS_BOM_DOM_TIMER_COORDINATOR_H_ diff --git a/bridge/bindings/qjs/bom/location.cc b/bridge/bindings/qjs/bom/location.cc index 85f8b77aa0..b43cee23a8 100644 --- a/bridge/bindings/qjs/bom/location.cc +++ b/bridge/bindings/qjs/bom/location.cc @@ -7,7 +7,7 @@ #include #include "dart_methods.h" -namespace kraken::binding::qjs { +namespace kraken { void bindLocation(std::unique_ptr& context) { auto* contextData = context->contextData(); @@ -42,4 +42,4 @@ void Location::trace(JSRuntime* rt, JSValue val, JS_MarkFunc* mark_func) const { void Location::dispose() const {} -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/bom/location.h b/bridge/bindings/qjs/bom/location.h index 8813793201..c198f525c7 100644 --- a/bridge/bindings/qjs/bom/location.h +++ b/bridge/bindings/qjs/bom/location.h @@ -10,7 +10,7 @@ #include "bindings/qjs/garbage_collected.h" #include "bindings/qjs/wrapper_type_info.h" -namespace kraken::binding::qjs { +namespace kraken { void bindLocation(std::unique_ptr& context); @@ -38,6 +38,6 @@ auto locationCreator = [](JSContext* ctx, JSValueConst func_obj, JSValueConst th const WrapperTypeInfo locationTypeInfo = {"Location", nullptr, locationCreator}; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_LOCATION_H diff --git a/bridge/bindings/qjs/bom/performance.cc b/bridge/bindings/qjs/bom/performance.cc index 5c8d678395..7a8cfabc9b 100644 --- a/bridge/bindings/qjs/bom/performance.cc +++ b/bridge/bindings/qjs/bom/performance.cc @@ -9,7 +9,7 @@ #define PERFORMANCE_ENTRY_NONE_UNIQUE_ID -1024 -namespace kraken::binding::qjs { +namespace kraken { void bindPerformance(ExecutionContext* context) { auto* performance = Performance::instance(context); @@ -580,4 +580,4 @@ Rendering: %.*fms #endif -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/bom/performance.h b/bridge/bindings/qjs/bom/performance.h index 1348d82937..7a9d63479e 100644 --- a/bridge/bindings/qjs/bom/performance.h +++ b/bridge/bindings/qjs/bom/performance.h @@ -123,7 +123,7 @@ #include "bindings/qjs/host_object.h" -namespace kraken::binding::qjs { +namespace kraken { void bindPerformance(ExecutionContext* context); @@ -222,6 +222,6 @@ class Performance : public HostObject { #endif }; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_PERFORMANCE_H diff --git a/bridge/bindings/qjs/bom/screen.cc b/bridge/bindings/qjs/bom/screen.cc index 56f3f3cc04..bd31b5b6ca 100644 --- a/bridge/bindings/qjs/bom/screen.cc +++ b/bridge/bindings/qjs/bom/screen.cc @@ -5,7 +5,7 @@ #include "screen.h" -namespace kraken::binding::qjs { +namespace kraken { void bindScreen(ExecutionContext* context) { auto* screen = new Screen(context); @@ -32,4 +32,4 @@ IMPL_PROPERTY_GETTER(Screen, height)(JSContext* ctx, JSValue this_val, int argc, return JS_NewFloat64(ctx, screen->height); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/bom/screen.h b/bridge/bindings/qjs/bom/screen.h index bc4fa774cb..2ac23ec116 100644 --- a/bridge/bindings/qjs/bom/screen.h +++ b/bridge/bindings/qjs/bom/screen.h @@ -10,7 +10,7 @@ #include "bindings/qjs/host_object.h" #include "dart_methods.h" -namespace kraken::binding::qjs { +namespace kraken { struct NativeScreen { double width; @@ -28,7 +28,7 @@ class Screen : public HostObject { void bindScreen(ExecutionContext* context); -} // namespace kraken::binding::qjs +} // namespace kraken class screen {}; diff --git a/bridge/bindings/qjs/bom/timer.cc b/bridge/bindings/qjs/bom/timer.cc index 4f4af60816..4692f694de 100644 --- a/bridge/bindings/qjs/bom/timer.cc +++ b/bridge/bindings/qjs/bom/timer.cc @@ -12,7 +12,7 @@ #include "kraken_test_env.h" #endif -namespace kraken::binding::qjs { +namespace kraken { DOMTimer::DOMTimer(JSValue callback) : m_callback(callback) {} @@ -225,4 +225,4 @@ void bindTimer(ExecutionContext* context) { QJS_GLOBAL_BINDING_FUNCTION(context, clearTimeout, "clearTimeout", 1); QJS_GLOBAL_BINDING_FUNCTION(context, clearTimeout, "clearInterval", 1); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/bom/timer.h b/bridge/bindings/qjs/bom/timer.h index 58cc951cfa..42862bc36b 100644 --- a/bridge/bindings/qjs/bom/timer.h +++ b/bridge/bindings/qjs/bom/timer.h @@ -10,7 +10,7 @@ #include "bindings/qjs/garbage_collected.h" #include "dom_timer_coordinator.h" -namespace kraken::binding::qjs { +namespace kraken { class DOMTimer : public GarbageCollected { public: @@ -36,6 +36,6 @@ class DOMTimer : public GarbageCollected { void bindTimer(ExecutionContext* context); -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_TIMER_H diff --git a/bridge/bindings/qjs/bom/timer_test.cc b/bridge/bindings/qjs/bom/timer_test.cc index d98a59733c..4e7f8062ed 100644 --- a/bridge/bindings/qjs/bom/timer_test.cc +++ b/bridge/bindings/qjs/bom/timer_test.cc @@ -4,7 +4,6 @@ */ #include "gtest/gtest.h" -#include "kraken_bridge.h" #include "kraken_test_env.h" #include "page.h" diff --git a/bridge/bindings/qjs/bom/window.cc b/bridge/bindings/qjs/bom/window.cc index 40f0310c36..fd04391060 100644 --- a/bridge/bindings/qjs/bom/window.cc +++ b/bridge/bindings/qjs/bom/window.cc @@ -10,7 +10,7 @@ #include "bindings/qjs/qjs_patch.h" #include "dart_methods.h" -namespace kraken::binding::qjs { +namespace kraken { void bindWindow(std::unique_ptr& context) { auto* contextData = context->contextData(); @@ -271,4 +271,4 @@ IMPL_PROPERTY_GETTER(Window, self)(JSContext* ctx, JSValue this_val, int argc, J return JS_GetGlobalObject(ctx); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/bom/window.h b/bridge/bindings/qjs/bom/window.h index 4d78939e26..ca33d315e1 100644 --- a/bridge/bindings/qjs/bom/window.h +++ b/bridge/bindings/qjs/bom/window.h @@ -11,7 +11,7 @@ #include "bindings/qjs/executing_context.h" #include "bindings/qjs/wrapper_type_info.h" -namespace kraken::binding::qjs { +namespace kraken { void bindWindow(ExecutionContext* context); @@ -58,6 +58,6 @@ auto windowCreator = [](JSContext* ctx, JSValueConst func_obj, JSValueConst this const WrapperTypeInfo windowTypeInfo = {"Window", &eventTargetTypeInfo, windowCreator}; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_WINDOW_H diff --git a/bridge/bindings/qjs/dart_methods.cc b/bridge/bindings/qjs/dart_methods.cc new file mode 100644 index 0000000000..2f955890ae --- /dev/null +++ b/bridge/bindings/qjs/dart_methods.cc @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019 Alibaba Inc. All rights reserved. + * Author: Kraken Team. + */ + +#include "dart_methods.h" +#include "foundation/macros.h" +#include + +namespace kraken { + +//std::shared_ptr methodPointer = std::make_shared() + + +std::shared_ptr getDartMethod() { + std::thread::id currentThread = std::this_thread::get_id(); + +#ifndef NDEBUG + // Dart methods can only invoked from Flutter UI threads. Javascript Debugger like Safari Debugger can invoke + // Javascript methods from debugger thread and will crash the app. + // @TODO: implement task loops for async method call. + if (currentThread != getUIThreadId()) { + // return empty struct to stop further behavior. + return std::make_shared(); + } +#endif +// return methodPointer; +} + +void registerDartMethods(std::shared_ptr methodPointer, uint64_t* methodBytes, int32_t length) { + +} + +void registerTestEnvDartMethods(std::shared_ptr methodPointer, uint64_t* methodBytes, int32_t length) { + +} + +#if ENABLE_PROFILE +void registerGetPerformanceEntries(GetPerformanceEntries getPerformanceEntries) { + methodPointer->getPerformanceEntries = getPerformanceEntries; +} +#endif + +} // namespace kraken diff --git a/bridge/include/dart_methods.h b/bridge/bindings/qjs/dart_methods.h similarity index 92% rename from bridge/include/dart_methods.h rename to bridge/bindings/qjs/dart_methods.h index 47bd2f24df..4ad2a663ec 100644 --- a/bridge/include/dart_methods.h +++ b/bridge/bindings/qjs/dart_methods.h @@ -11,10 +11,6 @@ #include #include -#define KRAKEN_EXPORT __attribute__((__visibility__("default"))) - -struct NativeScreen; - using AsyncCallback = void (*)(void* callbackContext, int32_t contextId, const char* errmsg); using AsyncRAFCallback = void (*)(void* callbackContext, int32_t contextId, double result, const char* errmsg); using AsyncModuleCallback = void (*)(void* callbackContext, int32_t contextId, NativeString* errmsg, NativeString* json); @@ -85,16 +81,13 @@ struct DartMethodPointer { InitDocument initDocument{nullptr}; }; -void registerDartMethods(uint64_t* methodBytes, int32_t length); +void registerDartMethods(std::shared_ptr methodPointer, uint64_t* methodBytes, int32_t length); #ifdef IS_TEST KRAKEN_EXPORT -void registerTestEnvDartMethods(uint64_t* methodBytes, int32_t length); +void registerTestEnvDartMethods(std::shared_ptr methodPointer, uint64_t* methodBytes, int32_t length); #endif -KRAKEN_EXPORT -std::shared_ptr getDartMethod(); - } // namespace kraken #endif diff --git a/bridge/bindings/qjs/dom/all_collection.cc b/bridge/bindings/qjs/dom/all_collection.cc index 9a5692b416..5717b4e759 100644 --- a/bridge/bindings/qjs/dom/all_collection.cc +++ b/bridge/bindings/qjs/dom/all_collection.cc @@ -5,7 +5,7 @@ #include "all_collection.h" -namespace kraken::binding::qjs { +namespace kraken { JSValue AllCollection::item(JSContext* ctx, JSValue this_val, int argc, JSValue* argv) { if (argc < 1) { @@ -76,4 +76,4 @@ IMPL_PROPERTY_GETTER(AllCollection, length)(JSContext* ctx, JSValue this_val, in return JS_NewUint32(ctx, collection->m_nodes.size()); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/all_collection.h b/bridge/bindings/qjs/dom/all_collection.h index 0c1a43213f..c2fef3acd1 100644 --- a/bridge/bindings/qjs/dom/all_collection.h +++ b/bridge/bindings/qjs/dom/all_collection.h @@ -9,7 +9,7 @@ #include "bindings/qjs/host_object.h" #include "node.h" -namespace kraken::binding::qjs { +namespace kraken { class AllCollection : public HostObject { public: @@ -27,6 +27,6 @@ class AllCollection : public HostObject { std::vector m_nodes; }; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_ALL_COLLECTION_H diff --git a/bridge/bindings/qjs/dom/comment_node.cc b/bridge/bindings/qjs/dom/comment_node.cc index 6af1bef852..d2b6a705f7 100644 --- a/bridge/bindings/qjs/dom/comment_node.cc +++ b/bridge/bindings/qjs/dom/comment_node.cc @@ -5,9 +5,8 @@ #include "comment_node.h" #include "document.h" -#include "kraken_bridge.h" -namespace kraken::binding::qjs { +namespace kraken { void bindCommentNode(std::unique_ptr& context) { // auto* constructor = Comment::instance(context.get()); @@ -53,4 +52,4 @@ CommentInstance::CommentInstance(Comment* comment) : NodeInstance(comment, NodeT m_context->uiCommandBuffer()->addCommand(m_eventTargetId, UICommand::createComment, nativeEventTarget); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/comment_node.h b/bridge/bindings/qjs/dom/comment_node.h index 3e776e9f98..cffd59accb 100644 --- a/bridge/bindings/qjs/dom/comment_node.h +++ b/bridge/bindings/qjs/dom/comment_node.h @@ -8,7 +8,7 @@ #include "node.h" -namespace kraken::binding::qjs { +namespace kraken { void bindCommentNode(ExecutionContext* context); @@ -50,6 +50,6 @@ const WrapperTypeInfo commentTypeInfo = {"Comment", &nodeTypeInfo, commentCreato // friend Comment; //}; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_COMMENT_NODE_H diff --git a/bridge/bindings/qjs/dom/custom_event.cc b/bridge/bindings/qjs/dom/custom_event.cc index f92a6a5f18..e8fb237a79 100644 --- a/bridge/bindings/qjs/dom/custom_event.cc +++ b/bridge/bindings/qjs/dom/custom_event.cc @@ -6,11 +6,10 @@ #include "custom_event.h" #include "bindings/qjs/native_value.h" #include "bindings/qjs/qjs_patch.h" -#include "kraken_bridge.h" #include -namespace kraken::binding::qjs { +namespace kraken { void bindCustomEvent(std::unique_ptr& context) { JSValue constructor = context->contextData()->constructorForType(&customEventTypeInfo); @@ -130,4 +129,4 @@ IMPL_PROPERTY_GETTER(CustomEvent, detail)(JSContext* ctx, JSValue this_val, int return JS_DupValue(ctx, customEventInstance->m_detail); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/custom_event.h b/bridge/bindings/qjs/dom/custom_event.h index d4f286ab67..e8de13d6f7 100644 --- a/bridge/bindings/qjs/dom/custom_event.h +++ b/bridge/bindings/qjs/dom/custom_event.h @@ -8,7 +8,7 @@ #include "event.h" -namespace kraken::binding::qjs { +namespace kraken { void bindCustomEvent(ExecutionContext* context); @@ -71,6 +71,6 @@ auto customEventCreator = [](JSContext* ctx, JSValueConst func_obj, JSValueConst const WrapperTypeInfo customEventTypeInfo = {"CustomEvent", &eventTypeInfo, customEventCreator}; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_CUSTOM_EVENT_H diff --git a/bridge/bindings/qjs/dom/document.cc b/bridge/bindings/qjs/dom/document.cc index 4c12abaac3..650d616047 100644 --- a/bridge/bindings/qjs/dom/document.cc +++ b/bridge/bindings/qjs/dom/document.cc @@ -32,7 +32,9 @@ #include "events/.gen/popstate_event.h" #include "events/touch_event.h" -namespace kraken::binding::qjs { +#define DOCUMENT_TARGET_ID -2 + +namespace kraken { void traverseNode(Node* node, TraverseHandler handler) { bool shouldExit = handler(node); @@ -632,4 +634,4 @@ void Document::dispose() const { } } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/document.h b/bridge/bindings/qjs/dom/document.h index 346287ede2..bde60659c7 100644 --- a/bridge/bindings/qjs/dom/document.h +++ b/bridge/bindings/qjs/dom/document.h @@ -11,7 +11,7 @@ #include "node.h" #include "script_animation_controller.h" -namespace kraken::binding::qjs { +namespace kraken { void bindDocument(ExecutionContext* context); @@ -85,6 +85,6 @@ auto documentCreator = [](JSContext* ctx, JSValueConst func_obj, JSValueConst th const WrapperTypeInfo documentTypeInfo = {"Document", &nodeTypeInfo, documentCreator}; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_DOCUMENT_H diff --git a/bridge/bindings/qjs/dom/document_fragment.cc b/bridge/bindings/qjs/dom/document_fragment.cc index 2b2c096ad1..bc90a2c44c 100644 --- a/bridge/bindings/qjs/dom/document_fragment.cc +++ b/bridge/bindings/qjs/dom/document_fragment.cc @@ -5,9 +5,8 @@ #include "document_fragment.h" #include "document.h" -#include "kraken_bridge.h" -namespace kraken::binding::qjs { +namespace kraken { void bindDocumentFragment(std::unique_ptr& context) { JSValue classObject = context->contextData()->constructorForType(&documentFragmentInfo); @@ -34,4 +33,4 @@ DocumentFragment::DocumentFragment() { context()->uiCommandBuffer()->addCommand(eventTargetId(), UICommand::createDocumentFragment, nativeEventTarget); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/document_fragment.h b/bridge/bindings/qjs/dom/document_fragment.h index ba6dd85efa..dadfb93624 100644 --- a/bridge/bindings/qjs/dom/document_fragment.h +++ b/bridge/bindings/qjs/dom/document_fragment.h @@ -8,7 +8,7 @@ #include "node.h" -namespace kraken::binding::qjs { +namespace kraken { void bindDocumentFragment(ExecutionContext* context); @@ -31,6 +31,6 @@ auto documentFragmentCreator = [](JSContext* ctx, JSValueConst func_obj, JSValue const WrapperTypeInfo documentFragmentInfo = {"DocumentFragment", &nodeTypeInfo, documentFragmentCreator}; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_DOCUMENT_FRAGMENT_H diff --git a/bridge/bindings/qjs/dom/element.cc b/bridge/bindings/qjs/dom/element.cc index d10626f52e..23197896af 100644 --- a/bridge/bindings/qjs/dom/element.cc +++ b/bridge/bindings/qjs/dom/element.cc @@ -15,7 +15,7 @@ #include "kraken_test_env.h" #endif -namespace kraken::binding::qjs { +namespace kraken { const std::string ATTR_ID = "id"; const std::string ATTR_CLASS = "class"; @@ -981,4 +981,4 @@ IMPL_PROPERTY_GETTER(BoundingClientRect, left)(JSContext* ctx, JSValue this_val, return JS_NewFloat64(ctx, boundingClientRect->m_nativeBoundingClientRect->left); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/element.h b/bridge/bindings/qjs/dom/element.h index b4b8aefbf0..58cc3d1d8d 100644 --- a/bridge/bindings/qjs/dom/element.h +++ b/bridge/bindings/qjs/dom/element.h @@ -12,7 +12,7 @@ #include "node.h" #include "style_declaration.h" -namespace kraken::binding::qjs { +namespace kraken { void bindElement(ExecutionContext* context); @@ -190,6 +190,6 @@ class BoundingClientRect : public GarbageCollected { NativeBoundingClientRect* m_nativeBoundingClientRect{nullptr}; }; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_ELEMENT_H diff --git a/bridge/bindings/qjs/dom/element_test.cc b/bridge/bindings/qjs/dom/element_test.cc index dc76a6b938..b92d2c77ad 100644 --- a/bridge/bindings/qjs/dom/element_test.cc +++ b/bridge/bindings/qjs/dom/element_test.cc @@ -117,7 +117,7 @@ TEST(Element, instanceofEventTarget) { } TEST(Element, stringifyBoundingClientRect) { - using namespace kraken::binding::qjs; + using namespace kraken; bool static errorCalled = false; bool static logCalled = false; diff --git a/bridge/bindings/qjs/dom/elements/image_element.cc b/bridge/bindings/qjs/dom/elements/image_element.cc index 258705e2fc..d1859431f9 100644 --- a/bridge/bindings/qjs/dom/elements/image_element.cc +++ b/bridge/bindings/qjs/dom/elements/image_element.cc @@ -7,7 +7,7 @@ #include "bindings/qjs/qjs_patch.h" #include "page.h" -namespace kraken::binding::qjs { +namespace kraken { ImageElement::ImageElement(ExecutionContext* context) : Element(context) { JS_SetPrototype(m_ctx, m_prototypeObject, Element::instance(m_context)->prototype()); @@ -105,4 +105,4 @@ bool ImageElementInstance::dispatchEvent(EventInstance* event) { return result; } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/elements/image_element.h b/bridge/bindings/qjs/dom/elements/image_element.h index 70b9fd4f48..2af8eed083 100644 --- a/bridge/bindings/qjs/dom/elements/image_element.h +++ b/bridge/bindings/qjs/dom/elements/image_element.h @@ -8,7 +8,7 @@ #include "bindings/qjs/dom/element.h" -namespace kraken::binding::qjs { +namespace kraken { void bindImageElement(ExecutionContext* context); @@ -43,6 +43,6 @@ class ImageElementInstance : public ElementInstance { friend ImageElement; }; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_IMAGE_ELEMENTT_H diff --git a/bridge/bindings/qjs/dom/elements/template_element.cc b/bridge/bindings/qjs/dom/elements/template_element.cc index ef87ddcfb1..00a9efdfc0 100644 --- a/bridge/bindings/qjs/dom/elements/template_element.cc +++ b/bridge/bindings/qjs/dom/elements/template_element.cc @@ -8,7 +8,7 @@ #include "bindings/qjs/qjs_patch.h" #include "page.h" -namespace kraken::binding::qjs { +namespace kraken { TemplateElement::TemplateElement(ExecutionContext* context) : Element(context) { JS_SetPrototype(m_ctx, m_prototypeObject, Element::instance(m_context)->prototype()); @@ -38,4 +38,4 @@ void TemplateElementInstance::trace(JSRuntime* rt, JSValue val, JS_MarkFunc* mar ElementInstance::trace(rt, val, mark_func); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/elements/template_element.h b/bridge/bindings/qjs/dom/elements/template_element.h index 0e8b0ca6a2..5df8e80ae1 100644 --- a/bridge/bindings/qjs/dom/elements/template_element.h +++ b/bridge/bindings/qjs/dom/elements/template_element.h @@ -9,7 +9,7 @@ #include "bindings/qjs/dom/document_fragment.h" #include "bindings/qjs/dom/element.h" -namespace kraken::binding::qjs { +namespace kraken { void bindTemplateElement(ExecutionContext* context); class TemplateElementInstance; @@ -42,6 +42,6 @@ class TemplateElementInstance : public ElementInstance { friend TemplateElement; }; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_TEMPLATE_ELEMENTT_H diff --git a/bridge/bindings/qjs/dom/event.cc b/bridge/bindings/qjs/dom/event.cc index b783b3db5c..a8917d3669 100644 --- a/bridge/bindings/qjs/dom/event.cc +++ b/bridge/bindings/qjs/dom/event.cc @@ -7,9 +7,8 @@ #include "bindings/qjs/qjs_patch.h" #include "custom_event.h" #include "event_target.h" -#include "kraken_bridge.h" -namespace kraken::binding::qjs { +namespace kraken { void bindEvent(std::unique_ptr& context) { JSValue constructor = Event::constructor(context.get()); @@ -207,4 +206,4 @@ void Event::dispose() const { delete nativeEvent; } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/event.h b/bridge/bindings/qjs/dom/event.h index 366d13dbe9..2dbe1033c8 100644 --- a/bridge/bindings/qjs/dom/event.h +++ b/bridge/bindings/qjs/dom/event.h @@ -9,7 +9,7 @@ #include "bindings/qjs/context_macros.h" #include "bindings/qjs/executing_context.h" -namespace kraken::binding::qjs { +namespace kraken { #define EVENT_CLICK "click" #define EVENT_INPUT "input" @@ -135,6 +135,6 @@ auto eventCreator = [](JSContext* ctx, JSValueConst func_obj, JSValueConst this_ const WrapperTypeInfo eventTypeInfo = {"Event", nullptr, eventCreator}; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_EVENT_H diff --git a/bridge/bindings/qjs/dom/event_listener_map.cc b/bridge/bindings/qjs/dom/event_listener_map.cc index bfb1bc89d0..0264b257ee 100644 --- a/bridge/bindings/qjs/dom/event_listener_map.cc +++ b/bridge/bindings/qjs/dom/event_listener_map.cc @@ -5,7 +5,7 @@ #include "event_listener_map.h" -namespace kraken::binding::qjs { +namespace kraken { static bool addListenerToVector(EventListenerVector* vector, JSValue callback) { if (std::find_if(vector->begin(), vector->end(), [&callback](JSValue fn) { return JS_VALUE_GET_PTR(fn) == JS_VALUE_GET_PTR(callback); }) != vector->end()) { @@ -95,4 +95,4 @@ EventListenerMap::~EventListenerMap() { } } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/event_listener_map.h b/bridge/bindings/qjs/dom/event_listener_map.h index e9eddfb5cb..659b398b41 100644 --- a/bridge/bindings/qjs/dom/event_listener_map.h +++ b/bridge/bindings/qjs/dom/event_listener_map.h @@ -10,7 +10,7 @@ #include #include "include/kraken_foundation.h" -namespace kraken::binding::qjs { +namespace kraken { using EventListenerVector = std::vector; @@ -39,6 +39,6 @@ class EventListenerMap final { JSRuntime* m_runtime; }; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_BINDINGS_QJS_DOM_EVENT_LISTENER_MAP_H_ diff --git a/bridge/bindings/qjs/dom/event_target.cc b/bridge/bindings/qjs/dom/event_target.cc index 4b7d934282..ff8d1d8af8 100644 --- a/bridge/bindings/qjs/dom/event_target.cc +++ b/bridge/bindings/qjs/dom/event_target.cc @@ -13,13 +13,12 @@ #include "document.h" #include "element.h" #include "event.h" -#include "kraken_bridge.h" #if UNIT_TEST #include "kraken_test_env.h" #endif -namespace kraken::binding::qjs { +namespace kraken { static std::atomic globalEventTargetId{0}; #define GetPropertyCallPreFix "_getProperty_" @@ -481,4 +480,4 @@ void NativeEventTarget::dispatchEventImpl(int32_t contextId, NativeEventTarget* JS_FreeValue(context->ctx(), event->toQuickJS()); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/event_target.h b/bridge/bindings/qjs/dom/event_target.h index d54f603290..e127f0497d 100644 --- a/bridge/bindings/qjs/dom/event_target.h +++ b/bridge/bindings/qjs/dom/event_target.h @@ -16,7 +16,7 @@ void TEST_callNativeMethod(void* nativePtr, void* returnValue, void* method, int32_t argc, void* argv); #endif -namespace kraken::binding::qjs { +namespace kraken { class EventTarget; class NativeEventTarget; @@ -25,7 +25,7 @@ class Event; void bindEventTarget(ExecutionContext* context); -using NativeDispatchEvent = void (*)(NativeEventTarget* nativeEventTarget, NativeString* eventType, void* nativeEvent, int32_t isCustomEvent); +using NativeDispatchEvent = void (*)(int32_t contextId, NativeEventTarget* nativeEventTarget, NativeString* eventType, void* nativeEvent, int32_t isCustomEvent); using CallNativeMethods = void (*)(void* nativePtr, NativeValue* returnValue, NativeString* method, int32_t argc, NativeValue* argv); struct NativeEventTarget { @@ -112,6 +112,6 @@ auto eventTargetCreator = [](JSContext* ctx, JSValueConst func_obj, JSValueConst const WrapperTypeInfo eventTargetTypeInfo = {"EventTarget", nullptr, eventTargetCreator}; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_EVENT_TARGET_H diff --git a/bridge/bindings/qjs/dom/event_target_test.cc b/bridge/bindings/qjs/dom/event_target_test.cc index c5bc6c5b84..c3a3804998 100644 --- a/bridge/bindings/qjs/dom/event_target_test.cc +++ b/bridge/bindings/qjs/dom/event_target_test.cc @@ -202,7 +202,7 @@ TEST(EventTarget, wontLeakWithStringProperty) { } TEST(EventTarget, dispatchEventOnGC) { - using namespace kraken::binding::qjs; + using namespace kraken; bool static errorCalled = false; bool static logCalled = false; diff --git a/bridge/bindings/qjs/dom/events/touch_event.cc b/bridge/bindings/qjs/dom/events/touch_event.cc index a807514644..bd4c69fc07 100644 --- a/bridge/bindings/qjs/dom/events/touch_event.cc +++ b/bridge/bindings/qjs/dom/events/touch_event.cc @@ -7,7 +7,7 @@ #include "bindings/qjs/qjs_patch.h" #include "page.h" -namespace kraken::binding::qjs { +namespace kraken { void bindTouchEvent(ExecutionContext* context) { auto* constructor = TouchEvent::instance(context); @@ -252,4 +252,4 @@ IMPL_PROPERTY_GETTER(TouchEvent, shiftKey)(JSContext* ctx, JSValue this_val, int TouchEventInstance::TouchEventInstance(TouchEvent* event, NativeEvent* nativeEvent) : EventInstance(event, nativeEvent) {} -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/events/touch_event.h b/bridge/bindings/qjs/dom/events/touch_event.h index b1de883b71..019666ebfb 100644 --- a/bridge/bindings/qjs/dom/events/touch_event.h +++ b/bridge/bindings/qjs/dom/events/touch_event.h @@ -8,7 +8,7 @@ #include "bindings/qjs/dom/element.h" -namespace kraken::binding::qjs { +namespace kraken { void bindTouchEvent(ExecutionContext* context); @@ -113,6 +113,6 @@ class TouchEventInstance : public EventInstance { friend TouchEvent; }; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_TOUCH_EVENTT_H diff --git a/bridge/bindings/qjs/dom/frame_request_callback_collection.cc b/bridge/bindings/qjs/dom/frame_request_callback_collection.cc index dc3907c7c6..378bc6923f 100644 --- a/bridge/bindings/qjs/dom/frame_request_callback_collection.cc +++ b/bridge/bindings/qjs/dom/frame_request_callback_collection.cc @@ -5,7 +5,7 @@ #include "frame_request_callback_collection.h" -namespace kraken::binding::qjs { +namespace kraken { JSClassID FrameCallback::classId{0}; FrameCallback::FrameCallback(JSValue callback) : m_callback(callback) {} @@ -71,4 +71,4 @@ void FrameRequestCallbackCollection::trace(JSRuntime* rt, JSValue val, JS_MarkFu } } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/frame_request_callback_collection.h b/bridge/bindings/qjs/dom/frame_request_callback_collection.h index 8327555b7a..a101d5b032 100644 --- a/bridge/bindings/qjs/dom/frame_request_callback_collection.h +++ b/bridge/bindings/qjs/dom/frame_request_callback_collection.h @@ -8,7 +8,7 @@ #include "bindings/qjs/executing_context.h" -namespace kraken::binding::qjs { +namespace kraken { // |FrameCallback| is an interface type which generalizes callbacks which are // invoked when a script-based animation needs to be resampled. @@ -41,7 +41,7 @@ class FrameRequestCallbackCollection final { std::vector m_abandonedCallbacks; }; -} // namespace kraken::binding::qjs +} // namespace kraken class frame_request_callback_collection {}; diff --git a/bridge/bindings/qjs/dom/node.cc b/bridge/bindings/qjs/dom/node.cc index 2f3c5fc468..8aa0ac6a6e 100644 --- a/bridge/bindings/qjs/dom/node.cc +++ b/bridge/bindings/qjs/dom/node.cc @@ -9,10 +9,9 @@ #include "document.h" #include "document_fragment.h" #include "element.h" -#include "kraken_bridge.h" #include "text_node.h" -namespace kraken::binding::qjs { +namespace kraken { void bindNode(std::unique_ptr& context) { auto* contextData = context->contextData(); @@ -580,4 +579,4 @@ void Node::trace(JSRuntime* rt, JSValue val, JS_MarkFunc* mark_func) const { void Node::dispose() const {} -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/node.h b/bridge/bindings/qjs/dom/node.h index b47fd31090..0e98ce0516 100644 --- a/bridge/bindings/qjs/dom/node.h +++ b/bridge/bindings/qjs/dom/node.h @@ -11,7 +11,7 @@ #include "event_target.h" -namespace kraken::binding::qjs { +namespace kraken { class Element; class Document; @@ -106,6 +106,6 @@ auto nodeCreator = [](JSContext* ctx, JSValueConst func_obj, JSValueConst this_v const WrapperTypeInfo nodeTypeInfo = {"Node", &eventTargetTypeInfo, nodeCreator}; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_NODE_H diff --git a/bridge/bindings/qjs/dom/script_animation_controller.cc b/bridge/bindings/qjs/dom/script_animation_controller.cc index f28b4f552b..fd21563e52 100644 --- a/bridge/bindings/qjs/dom/script_animation_controller.cc +++ b/bridge/bindings/qjs/dom/script_animation_controller.cc @@ -11,7 +11,7 @@ #include "kraken_test_env.h" #endif -namespace kraken::binding::qjs { +namespace kraken { JSClassID ScriptAnimationController::classId{0}; @@ -62,4 +62,4 @@ void ScriptAnimationController::cancelFrameCallback(uint32_t callbackId) { m_frameRequestCallbackCollection.cancelFrameCallback(callbackId); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/script_animation_controller.h b/bridge/bindings/qjs/dom/script_animation_controller.h index cd07d97c56..4e3d4d92f4 100644 --- a/bridge/bindings/qjs/dom/script_animation_controller.h +++ b/bridge/bindings/qjs/dom/script_animation_controller.h @@ -9,7 +9,7 @@ #include "bindings/qjs/garbage_collected.h" #include "frame_request_callback_collection.h" -namespace kraken::binding::qjs { +namespace kraken { class ScriptAnimationController : public GarbageCollected { public: @@ -30,6 +30,6 @@ class ScriptAnimationController : public GarbageCollectedjsObject, mark_func); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/style_declaration.h b/bridge/bindings/qjs/dom/style_declaration.h index 099aceb32d..318d301e69 100644 --- a/bridge/bindings/qjs/dom/style_declaration.h +++ b/bridge/bindings/qjs/dom/style_declaration.h @@ -10,7 +10,7 @@ #include "bindings/qjs/dom/event_target.h" #include "bindings/qjs/garbage_collected.h" -namespace kraken::binding::qjs { +namespace kraken { void bindCSSStyleDeclaration(std::unique_ptr& context); @@ -51,6 +51,6 @@ class CSSStyleDeclaration : public GarbageCollected { std::unordered_map m_properties; }; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_STYLE_DECLARATION_H diff --git a/bridge/bindings/qjs/dom/text_node.cc b/bridge/bindings/qjs/dom/text_node.cc index 0ee6065437..b05c90388f 100644 --- a/bridge/bindings/qjs/dom/text_node.cc +++ b/bridge/bindings/qjs/dom/text_node.cc @@ -5,9 +5,8 @@ #include "text_node.h" #include "document.h" -#include "kraken_bridge.h" -namespace kraken::binding::qjs { +namespace kraken { std::once_flag kTextNodeInitFlag; @@ -84,4 +83,4 @@ void TextNode::internalSetTextContent(JSValue content) { std::unique_ptr args_02 = jsValueToNativeString(m_ctx, content); context()->uiCommandBuffer()->addCommand(eventTargetId(), UICommand::setProperty, *args_01, *args_02, nullptr); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/dom/text_node.h b/bridge/bindings/qjs/dom/text_node.h index dfc78c197b..a3a65afdc9 100644 --- a/bridge/bindings/qjs/dom/text_node.h +++ b/bridge/bindings/qjs/dom/text_node.h @@ -8,7 +8,7 @@ #include "node.h" -namespace kraken::binding::qjs { +namespace kraken { class TextNodeInstance; @@ -49,6 +49,6 @@ auto textNodeCreator = [](JSContext* ctx, JSValueConst func_obj, JSValueConst th const WrapperTypeInfo textNodeType = {"TextNode", &nodeTypeInfo, textNodeCreator}; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_TEXT_NODE_H diff --git a/bridge/bindings/qjs/executing_context.cc b/bridge/bindings/qjs/executing_context.cc index 295e3ecbf6..8459229641 100644 --- a/bridge/bindings/qjs/executing_context.cc +++ b/bridge/bindings/qjs/executing_context.cc @@ -10,17 +10,12 @@ #include "bindings/qjs/module_manager.h" #include "bom/dom_timer_coordinator.h" #include "garbage_collected.h" -#include "kraken_bridge.h" #include "qjs_patch.h" -namespace kraken::binding::qjs { +namespace kraken { static std::atomic context_unique_id{0}; -JSClassID ExecutionContext::kHostClassClassId{0}; -JSClassID ExecutionContext::kHostObjectClassId{0}; -JSClassID ExecutionContext::kHostExoticObjectClassId{0}; - std::atomic runningContexts{0}; #define MAX_JS_CONTEXT 1024 @@ -48,12 +43,6 @@ ExecutionContext::ExecutionContext(int32_t contextId, const JSExceptionHandler& if (contextId > running_context_list) running_context_list = contextId; - std::call_once(kinitJSClassIDFlag, []() { - JS_NewClassID(&kHostClassClassId); - JS_NewClassID(&kHostObjectClassId); - JS_NewClassID(&kHostExoticObjectClassId); - }); - init_list_head(&node_job_list); init_list_head(&module_job_list); init_list_head(&module_callback_job_list); @@ -382,28 +371,6 @@ DOMTimerCoordinator* ExecutionContext::timers() { return &m_timers; } -std::unique_ptr jsValueToNativeString(JSContext* ctx, JSValue value) { - bool isValueString = true; - if (JS_IsNull(value)) { - value = JS_NewString(ctx, ""); - isValueString = false; - } else if (!JS_IsString(value)) { - value = JS_ToString(ctx, value); - isValueString = false; - } - - uint32_t length; - uint16_t* buffer = JS_ToUnicode(ctx, value, &length); - std::unique_ptr ptr = std::make_unique(); - ptr->string = buffer; - ptr->length = length; - - if (!isValueString) { - JS_FreeValue(ctx, value); - } - return ptr; -} - void buildUICommandArgs(JSContext* ctx, JSValue key, NativeString& args_01) { if (!JS_IsString(key)) return; @@ -414,35 +381,6 @@ void buildUICommandArgs(JSContext* ctx, JSValue key, NativeString& args_01) { args_01.length = length; } -std::unique_ptr stringToNativeString(const std::string& string) { - std::u16string utf16; - fromUTF8(string, utf16); - NativeString tmp{}; - tmp.string = reinterpret_cast(utf16.c_str()); - tmp.length = utf16.size(); - return std::unique_ptr(tmp.clone()); -} - -std::unique_ptr atomToNativeString(JSContext* ctx, JSAtom atom) { - JSValue stringValue = JS_AtomToString(ctx, atom); - std::unique_ptr string = jsValueToNativeString(ctx, stringValue); - JS_FreeValue(ctx, stringValue); - return string; -} - -std::string jsValueToStdString(JSContext* ctx, JSValue& value) { - const char* cString = JS_ToCString(ctx, value); - std::string str = std::string(cString); - JS_FreeCString(ctx, cString); - return str; -} - -std::string jsAtomToStdString(JSContext* ctx, JSAtom atom) { - const char* cstr = JS_AtomToCString(ctx, atom); - std::string str = std::string(cstr); - JS_FreeCString(ctx, cstr); - return str; -} // An lock free context validator. bool isContextValid(int32_t contextId) { @@ -522,4 +460,4 @@ void ExecutionContext::trace(JSRuntime* rt, JSValue val, JS_MarkFunc* mark_func) m_timers.trace(rt, JS_NULL, mark_func); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/executing_context.h b/bridge/bindings/qjs/executing_context.h index 78b4b41dbd..86bb222198 100644 --- a/bridge/bindings/qjs/executing_context.h +++ b/bridge/bindings/qjs/executing_context.h @@ -16,17 +16,19 @@ #include #include #include +#include "foundation/macros.h" #include "bindings/qjs/bom/dom_timer_coordinator.h" #include "executing_context_data.h" #include "foundation/ui_command_buffer.h" #include "garbage_collected.h" #include "kraken_foundation.h" #include "qjs_patch.h" +#include "dart_methods.h" #include "wrapper_type_info.h" using JSExceptionHandler = std::function; -namespace kraken::binding::qjs { +namespace kraken { static std::once_flag kinitJSClassIDFlag; @@ -95,7 +97,8 @@ class ExecutionContext { DOMTimerCoordinator* timers(); FORCE_INLINE Document* document() { return m_document; }; - FORCE_INLINE foundation::UICommandBuffer* uiCommandBuffer() { return &m_commandBuffer; }; + FORCE_INLINE UICommandBuffer* uiCommandBuffer() { return &m_commandBuffer; }; + FORCE_INLINE std::unique_ptr& dartMethodPtr() { return m_dartMethodPtr; } void trace(JSRuntime* rt, JSValue val, JS_MarkFunc* mark_func); @@ -109,10 +112,6 @@ class ExecutionContext { struct list_head promise_job_list; struct list_head native_function_job_list; - static JSClassID kHostClassClassId; - static JSClassID kHostObjectClassId; - static JSClassID kHostExoticObjectClassId; - private: static void promiseRejectTracker(JSContext* ctx, JSValueConst promise, JSValueConst reason, JS_BOOL is_handled, void* opaque); void dispatchGlobalErrorEvent(JSValueConst error); @@ -129,7 +128,8 @@ class ExecutionContext { DOMTimerCoordinator m_timers; ExecutionContextGCTracker* m_gcTracker{nullptr}; ExecutionContextData m_data{this}; - foundation::UICommandBuffer m_commandBuffer{contextId}; + UICommandBuffer m_commandBuffer{contextId}; + std::unique_ptr m_dartMethodPtr = std::make_unique(); }; // The read object's method or properties via Proxy, we should redirect this_val from Proxy into target property of @@ -194,23 +194,8 @@ class JSValueHolder { std::unique_ptr createJSContext(int32_t contextId, const JSExceptionHandler& handler, void* owner); -// Convert to string and return a full copy of NativeString from JSValue. -std::unique_ptr jsValueToNativeString(JSContext* ctx, JSValue value); - void buildUICommandArgs(JSContext* ctx, JSValue key, NativeString& args_01); -// Encode utf-8 to utf-16, and return a full copy of NativeString. -std::unique_ptr stringToNativeString(const std::string& string); - -// Return a full copy of NativeString form JSAtom. -std::unique_ptr atomToNativeString(JSContext* ctx, JSAtom atom); - -// Convert to string and return a full copy of std::string from JSValue. -std::string jsValueToStdString(JSContext* ctx, JSValue& value); - -// Return a full copy of std::string form JSAtom. -std::string jsAtomToStdString(JSContext* ctx, JSAtom atom); - // JS array operation utilities. void arrayPushValue(JSContext* ctx, JSValue array, JSValue val); void arrayInsert(JSContext* ctx, JSValue array, uint32_t start, JSValue targetValue); @@ -222,6 +207,6 @@ void arraySpliceValue(JSContext* ctx, JSValue array, uint32_t start, uint32_t de // JS object operation utilities. JSValue objectGetKeys(JSContext* ctx, JSValue obj); -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_JS_CONTEXT_H diff --git a/bridge/bindings/qjs/executing_context_data.cc b/bridge/bindings/qjs/executing_context_data.cc index d8e0eda910..949e5c5e18 100644 --- a/bridge/bindings/qjs/executing_context_data.cc +++ b/bridge/bindings/qjs/executing_context_data.cc @@ -6,7 +6,7 @@ #include "executing_context_data.h" #include "executing_context.h" -namespace kraken::binding::qjs { +namespace kraken { JSValue ExecutionContextData::constructorForType(const WrapperTypeInfo* type) { auto it = m_constructorMap.find(type); @@ -71,4 +71,4 @@ JSValue ExecutionContextData::constructorForIdSlowCase(const WrapperTypeInfo* ty return classObject; } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/executing_context_data.h b/bridge/bindings/qjs/executing_context_data.h index abdc8d54a7..c18b7120c4 100644 --- a/bridge/bindings/qjs/executing_context_data.h +++ b/bridge/bindings/qjs/executing_context_data.h @@ -9,7 +9,7 @@ #include #include "wrapper_type_info.h" -namespace kraken::binding::qjs { +namespace kraken { class ExecutionContext; @@ -34,6 +34,6 @@ class ExecutionContextData final { ExecutionContext* m_context; }; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_CONTEXT_DATA_H diff --git a/bridge/bindings/qjs/garbage_collected.h b/bridge/bindings/qjs/garbage_collected.h index 1da6426a93..e6d1a0057a 100644 --- a/bridge/bindings/qjs/garbage_collected.h +++ b/bridge/bindings/qjs/garbage_collected.h @@ -10,7 +10,7 @@ #include "include/kraken_foundation.h" #include "qjs_patch.h" -namespace kraken::binding::qjs { +namespace kraken { template class MakeGarbageCollectedTrait; @@ -159,6 +159,6 @@ T* makeGarbageCollected(Args&&... args) { return MakeGarbageCollectedTrait::allocate(std::forward(args)...); } -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_GARBAGE_COLLECTED_H diff --git a/bridge/bindings/qjs/garbage_collected_test.cc b/bridge/bindings/qjs/garbage_collected_test.cc index c1e740884b..060bb701f2 100644 --- a/bridge/bindings/qjs/garbage_collected_test.cc +++ b/bridge/bindings/qjs/garbage_collected_test.cc @@ -9,7 +9,7 @@ //#include "kraken_test_env.h" //#include "page.h" // -// namespace kraken::binding::qjs { +// namespace kraken { // // class ParentClass : public HostClass { // public: @@ -411,7 +411,7 @@ // EXPECT_EQ(logCalled, true); //} // -//} // namespace kraken::binding::qjs +//} // namespace kraken ///* // * Copyright (C) 2021 Alibaba Inc. All rights reserved. @@ -424,7 +424,7 @@ //#include "kraken_test_env.h" //#include "page.h" // -// namespace kraken::binding::qjs { +// namespace kraken { // // static bool isSampleFree = false; // @@ -573,4 +573,4 @@ // EXPECT_EQ(isSampleFree, true); //} // -//} // namespace kraken::binding::qjs +//} // namespace kraken diff --git a/bridge/bindings/qjs/heap_hashmap.h b/bridge/bindings/qjs/heap_hashmap.h index 8a5e98d8ad..8449fbe152 100644 --- a/bridge/bindings/qjs/heap_hashmap.h +++ b/bridge/bindings/qjs/heap_hashmap.h @@ -9,7 +9,7 @@ #include #include -namespace kraken::binding::qjs { +namespace kraken { template class HeapHashMap { @@ -98,6 +98,6 @@ void HeapHashMap::trace(JSRuntime* rt, JSValue val, JS_MarkFunc* mark_func) c } } -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_BINDINGS_QJS_HEAP_HASHMAP_H_ diff --git a/bridge/bindings/qjs/html_parser.cc b/bridge/bindings/qjs/html_parser.cc index 2a9e7fae89..0fcdaeecb8 100644 --- a/bridge/bindings/qjs/html_parser.cc +++ b/bridge/bindings/qjs/html_parser.cc @@ -10,7 +10,7 @@ #include -namespace kraken::binding::qjs { +namespace kraken { inline std::string trim(std::string& str) { str.erase(0, str.find_first_not_of(' ')); // prefixing spaces @@ -71,7 +71,7 @@ void HTMLParser::traverseHTML(Node* root, GumboNode* node) { } } -bool HTMLParser::parseHTML(std::string html, NodeInstance* rootNode) { +bool HTMLParser::parseHTML(std::string html, Node* rootNode) { if (rootNode != nullptr) { rootNode->internalClearChild(); @@ -90,7 +90,7 @@ bool HTMLParser::parseHTML(std::string html, NodeInstance* rootNode) { return true; } -bool HTMLParser::parseHTML(const char* code, size_t codeLength, NodeInstance* rootNode) { +bool HTMLParser::parseHTML(const char* code, size_t codeLength, Node* rootNode) { std::string html = std::string(code, codeLength); return parseHTML(html, rootNode); } @@ -122,4 +122,4 @@ void HTMLParser::parseProperty(ElementInstance* element, GumboElement* gumboElem } } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/html_parser.h b/bridge/bindings/qjs/html_parser.h index 7e01625e8f..9d4703d12e 100644 --- a/bridge/bindings/qjs/html_parser.h +++ b/bridge/bindings/qjs/html_parser.h @@ -8,10 +8,10 @@ #include "bindings/qjs/dom/element.h" #include "executing_context.h" -#include "include/kraken_bridge.h" +#include "foundation/native_string.h" #include "third_party/gumbo-parser/src/gumbo.h" -namespace kraken::binding::qjs { +namespace kraken { class HTMLParser { public: @@ -23,6 +23,6 @@ class HTMLParser { static void traverseHTML(Node* root, GumboNode* node); static void parseProperty(Element* element, GumboElement* gumboElement); }; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_HTML_PARSER_H diff --git a/bridge/bindings/qjs/module_manager.cc b/bridge/bindings/qjs/module_manager.cc index b08252c293..a7914697af 100644 --- a/bridge/bindings/qjs/module_manager.cc +++ b/bridge/bindings/qjs/module_manager.cc @@ -7,7 +7,7 @@ #include "page.h" #include "qjs_patch.h" -namespace kraken::binding::qjs { +namespace kraken { JSValue krakenModuleListener(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv) { if (argc < 1) { @@ -168,4 +168,4 @@ void bindModuleManager(ExecutionContext* context) { QJS_GLOBAL_BINDING_FUNCTION(context, flushUICommand, "__kraken_flush_ui_command__", 0); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/module_manager.h b/bridge/bindings/qjs/module_manager.h index 0ee8edf589..2dfef7a6a5 100644 --- a/bridge/bindings/qjs/module_manager.h +++ b/bridge/bindings/qjs/module_manager.h @@ -8,7 +8,7 @@ #include "executing_context.h" -namespace kraken::binding::qjs { +namespace kraken { struct ModuleContext { JSValue callback; @@ -18,6 +18,6 @@ struct ModuleContext { void bindModuleManager(ExecutionContext* context); void handleInvokeModuleUnexpectedCallback(void* callbackContext, int32_t contextId, NativeString* errmsg, NativeString* json); -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_MODULE_MANAGER_H diff --git a/bridge/bindings/qjs/module_manager_test.cc b/bridge/bindings/qjs/module_manager_test.cc index 31899da571..055acbbc12 100644 --- a/bridge/bindings/qjs/module_manager_test.cc +++ b/bridge/bindings/qjs/module_manager_test.cc @@ -9,7 +9,7 @@ #include "kraken_test_env.h" #include "page.h" -namespace kraken::binding::qjs { +namespace kraken { TEST(ModuleManager, shouldThrowErrorWhenBadJSON) { bool static errorCalled = false; @@ -40,4 +40,4 @@ kraken.methodChannel.invokeMethod('abc', 'fn', object); EXPECT_EQ(errorCalled, true); } -} // namespace kraken::binding::qjs +} // namespace kraken diff --git a/bridge/bindings/qjs/native_string.cc b/bridge/bindings/qjs/native_string.cc new file mode 100644 index 0000000000..278f97b805 --- /dev/null +++ b/bridge/bindings/qjs/native_string.cc @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2020-present Alibaba Inc. All rights reserved. + * Author: Kraken Team. + */ + +#include "native_string.h" +#include "bindings/qjs/qjs_patch.h" + +namespace kraken { + + +NativeString* NativeString::clone() { + auto* newNativeString = new NativeString(); + auto* newString = new uint16_t[length]; + + memcpy(newString, string, length * sizeof(uint16_t)); + newNativeString->string = newString; + newNativeString->length = length; + return newNativeString; +} + +void NativeString::free() { + delete[] string; +} + +std::unique_ptr jsValueToNativeString(JSContext* ctx, JSValue value) { + bool isValueString = true; + if (JS_IsNull(value)) { + value = JS_NewString(ctx, ""); + isValueString = false; + } else if (!JS_IsString(value)) { + value = JS_ToString(ctx, value); + isValueString = false; + } + + uint32_t length; + uint16_t* buffer = JS_ToUnicode(ctx, value, &length); + std::unique_ptr ptr = std::make_unique(); + ptr->string = buffer; + ptr->length = length; + + if (!isValueString) { + JS_FreeValue(ctx, value); + } + return ptr; +} + + +std::unique_ptr stringToNativeString(const std::string& string) { + std::u16string utf16; + fromUTF8(string, utf16); + NativeString tmp{}; + tmp.string = reinterpret_cast(utf16.c_str()); + tmp.length = utf16.size(); + return std::unique_ptr(tmp.clone()); +} + +std::unique_ptr atomToNativeString(JSContext* ctx, JSAtom atom) { + JSValue stringValue = JS_AtomToString(ctx, atom); + std::unique_ptr string = jsValueToNativeString(ctx, stringValue); + JS_FreeValue(ctx, stringValue); + return string; +} + +std::string jsValueToStdString(JSContext* ctx, JSValue& value) { + const char* cString = JS_ToCString(ctx, value); + std::string str = std::string(cString); + JS_FreeCString(ctx, cString); + return str; +} + +std::string jsAtomToStdString(JSContext* ctx, JSAtom atom) { + const char* cstr = JS_AtomToCString(ctx, atom); + std::string str = std::string(cstr); + JS_FreeCString(ctx, cstr); + return str; +} + + + +} diff --git a/bridge/bindings/qjs/native_string.h b/bridge/bindings/qjs/native_string.h new file mode 100644 index 0000000000..92783e2aae --- /dev/null +++ b/bridge/bindings/qjs/native_string.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2020-present Alibaba Inc. All rights reserved. + * Author: Kraken Team. + */ + +#ifndef KRAKENBRIDGE_NATIVE_STRING_H +#define KRAKENBRIDGE_NATIVE_STRING_H + +#include +#include +#include +#include +#include +#include + +namespace kraken { + +struct NativeString { + const uint16_t* string; + uint32_t length; + + NativeString* clone(); + void free(); +}; + +// Convert to string and return a full copy of NativeString from JSValue. +std::unique_ptr jsValueToNativeString(JSContext* ctx, JSValue value); + +// Encode utf-8 to utf-16, and return a full copy of NativeString. +std::unique_ptr stringToNativeString(const std::string& string); + +// Return a full copy of NativeString form JSAtom. +std::unique_ptr atomToNativeString(JSContext* ctx, JSAtom atom); + +// Convert to string and return a full copy of std::string from JSValue. +std::string jsValueToStdString(JSContext* ctx, JSValue& value); + +// Return a full copy of std::string form JSAtom. +std::string jsAtomToStdString(JSContext* ctx, JSAtom atom); + +template +std::string toUTF8(const std::basic_string, std::allocator>& source) { + std::string result; + + std::wstring_convert, T> convertor; + result = convertor.to_bytes(source); + + return result; +} + +template +void fromUTF8(const std::string& source, std::basic_string, std::allocator>& result) { + std::wstring_convert, T> convertor; + result = convertor.from_bytes(source); +} + +} + +class native_string {}; + +#endif // KRAKENBRIDGE_NATIVE_STRING_H diff --git a/bridge/bindings/qjs/wrapper_type_info.h b/bridge/bindings/qjs/wrapper_type_info.h index 02496a855c..d849b3af89 100644 --- a/bridge/bindings/qjs/wrapper_type_info.h +++ b/bridge/bindings/qjs/wrapper_type_info.h @@ -11,7 +11,7 @@ #include "bindings/qjs/qjs_patch.h" #include "include/kraken_foundation.h" -namespace kraken::binding::qjs { +namespace kraken { // This struct provides a way to store a bunch of information that is helpful // when creating quickjs objects. Each quickjs bindings class has exactly one static @@ -36,6 +36,6 @@ class WrapperTypeInfo final { JSClassID classId{0}; }; -} // namespace kraken::binding::qjs +} // namespace kraken #endif // KRAKENBRIDGE_WRAPPER_TYPE_INFO_H diff --git a/bridge/dart_methods.cc b/bridge/dart_methods.cc deleted file mode 100644 index b815895f64..0000000000 --- a/bridge/dart_methods.cc +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2019 Alibaba Inc. All rights reserved. - * Author: Kraken Team. - */ - -#include "dart_methods.h" -#include -#include "kraken_bridge.h" - -namespace kraken { - -std::shared_ptr methodPointer = std::make_shared(); - -std::shared_ptr getDartMethod() { - std::thread::id currentThread = std::this_thread::get_id(); - -#ifndef NDEBUG - // Dart methods can only invoked from Flutter UI threads. Javascript Debugger like Safari Debugger can invoke - // Javascript methods from debugger thread and will crash the app. - // @TODO: implement task loops for async method call. - if (currentThread != getUIThreadId()) { - // return empty struct to stop further behavior. - return std::make_shared(); - } -#endif - - return methodPointer; -} - -void registerDartMethods(uint64_t* methodBytes, int32_t length) { - size_t i = 0; - - methodPointer->invokeModule = reinterpret_cast(methodBytes[i++]); - methodPointer->requestBatchUpdate = reinterpret_cast(methodBytes[i++]); - methodPointer->reloadApp = reinterpret_cast(methodBytes[i++]); - methodPointer->setTimeout = reinterpret_cast(methodBytes[i++]); - methodPointer->setInterval = reinterpret_cast(methodBytes[i++]); - methodPointer->clearTimeout = reinterpret_cast(methodBytes[i++]); - methodPointer->requestAnimationFrame = reinterpret_cast(methodBytes[i++]); - methodPointer->cancelAnimationFrame = reinterpret_cast(methodBytes[i++]); - methodPointer->getScreen = reinterpret_cast(methodBytes[i++]); - methodPointer->devicePixelRatio = reinterpret_cast(methodBytes[i++]); - methodPointer->platformBrightness = reinterpret_cast(methodBytes[i++]); - methodPointer->toBlob = reinterpret_cast(methodBytes[i++]); - methodPointer->flushUICommand = reinterpret_cast(methodBytes[i++]); - methodPointer->initWindow = reinterpret_cast(methodBytes[i++]); - methodPointer->initDocument = reinterpret_cast(methodBytes[i++]); - -#if ENABLE_PROFILE - methodPointer->getPerformanceEntries = reinterpret_cast(methodBytes[i++]); -#else - i++; -#endif - - methodPointer->onJsError = reinterpret_cast(methodBytes[i++]); - - assert_m(i == length, "Dart native methods count is not equal with C++ side method registrations."); -} - -void registerTestEnvDartMethods(uint64_t* methodBytes, int32_t length) { - size_t i = 0; - - methodPointer->onJsError = reinterpret_cast(methodBytes[i++]); - methodPointer->matchImageSnapshot = reinterpret_cast(methodBytes[i++]); - methodPointer->environment = reinterpret_cast(methodBytes[i++]); - methodPointer->simulatePointer = reinterpret_cast(methodBytes[i++]); - methodPointer->simulateInputText = reinterpret_cast(methodBytes[i++]); - - assert_m(i == length, "Dart native methods count is not equal with C++ side method registrations."); -} - -#if ENABLE_PROFILE -void registerGetPerformanceEntries(GetPerformanceEntries getPerformanceEntries) { - methodPointer->getPerformanceEntries = getPerformanceEntries; -} -#endif - -} // namespace kraken diff --git a/bridge/foundation/closure.h b/bridge/foundation/closure.h deleted file mode 100644 index bcb042af34..0000000000 --- a/bridge/foundation/closure.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2020-present Alibaba Inc. All rights reserved. - * Author: Kraken Team. - */ - -#ifndef KRAKENBRIDGE_CLOSURE_H -#define KRAKENBRIDGE_CLOSURE_H - -#include - -namespace fml { -using closure = std::function; -} - -#endif // KRAKENBRIDGE_CLOSURE_H diff --git a/bridge/foundation/inspector_task_queue.cc b/bridge/foundation/inspector_task_queue.cc index 42c8852398..486a726826 100644 --- a/bridge/foundation/inspector_task_queue.cc +++ b/bridge/foundation/inspector_task_queue.cc @@ -5,9 +5,9 @@ #include "inspector_task_queue.h" -namespace foundation { +namespace kraken { std::mutex InspectorTaskQueue::inspector_task_creation_mutex_{}; fml::RefPtr InspectorTaskQueue::instance_{}; -} // namespace foundation +} // namespace kraken diff --git a/bridge/foundation/inspector_task_queue.h b/bridge/foundation/inspector_task_queue.h index 12c0a02105..17625d0855 100644 --- a/bridge/foundation/inspector_task_queue.h +++ b/bridge/foundation/inspector_task_queue.h @@ -9,7 +9,7 @@ #include "kraken_foundation.h" #include "task_queue.h" -namespace foundation { +namespace kraken { class InspectorTaskQueue; using Task = void (*)(void*); @@ -26,7 +26,6 @@ class InspectorTaskQueue : public TaskQueue { }; int32_t registerTask(const Task& task, void* data) override { int32_t taskId = TaskQueue::registerTask(task, data); - assert(std::this_thread::get_id() == getUIThreadId()); return taskId; } @@ -36,6 +35,6 @@ class InspectorTaskQueue : public TaskQueue { static fml::RefPtr instance_; }; -} // namespace foundation +} // namespace kraken #endif // KRAKENBRIDGE_INSPECTOR_TASK_QUEUE_H diff --git a/bridge/foundation/logging.cc b/bridge/foundation/logging.cc index e8e312ac78..40a6f13d88 100644 --- a/bridge/foundation/logging.cc +++ b/bridge/foundation/logging.cc @@ -24,7 +24,7 @@ #include "inspector/impl/jsc_console_client_impl.h" #endif -namespace foundation { +namespace kraken { namespace { const char* const kLogSeverityNames[LOG_NUM_SEVERITIES] = {"VERBOSE", BOLD("INFO"), FYEL("WARN"), BOLD("DEBUG"), FRED("ERROR")}; @@ -141,4 +141,4 @@ void printLog(int32_t contextId, std::stringstream& stream, std::string level, v } } -} // namespace foundation +} // namespace kraken diff --git a/bridge/foundation/logging.h b/bridge/foundation/logging.h index 9ca8e6a49a..5e2f47805a 100644 --- a/bridge/foundation/logging.h +++ b/bridge/foundation/logging.h @@ -7,10 +7,52 @@ #define KRAKEN_FOUNDATION_LOGGING_H_ #include - #include -#include "include/kraken_bridge.h" -namespace foundation {} // namespace foundation +#define KRAKEN_LOG_STREAM(severity) ::kraken::LogMessage(::kraken::LOG_##severity, __FILE__, __LINE__, nullptr).stream() + +#define KRAKEN_LAZY_STREAM(stream, condition) !(condition) ? (void)0 : ::kraken::LogMessageVoidify() & (stream) + +#define KRAKEN_EAT_STREAM_PARAMETERS(ignored) true || (ignored) ? (void)0 : ::LogMessageVoidify() & ::LogMessage(::LOG_FATAL, 0, 0, nullptr).stream() + +#define KRAKEN_LOG(severity) KRAKEN_LAZY_STREAM(KRAKEN_LOG_STREAM(severity), true) + +#define KRAKEN_CHECK(condition) KRAKEN_LAZY_STREAM(::kraken::LogMessage(::kraken::LOG_FATAL, __FILE__, __LINE__, #condition).stream(), !(condition)) + +namespace kraken { + +typedef int LogSeverity; + +// Default log levels. Negative values can be used for verbose log levels. +constexpr LogSeverity LOG_VERBOSE = 0; +constexpr LogSeverity LOG_INFO = 1; +constexpr LogSeverity LOG_WARN = 2; +constexpr LogSeverity LOG_DEBUG_ = 3; +constexpr LogSeverity LOG_ERROR = 4; +constexpr LogSeverity LOG_NUM_SEVERITIES = 5; +constexpr LogSeverity LOG_FATAL = 6; + +class LogMessageVoidify { +public: + void operator&(std::ostream&) {} +}; + +class LogMessage { + public: + LogMessage(LogSeverity severity, const char* file, int line, const char* condition); + ~LogMessage(); + + std::ostream& stream() { return stream_; } + + private: + std::ostringstream stream_; + const LogSeverity severity_; + const char* file_; + const int line_; +}; + +void printLog(int32_t contextId, std::stringstream& stream, std::string level, void* ctx); + +} // namespace kraken #endif // KRAKEN_FOUNDATION_LOGGING_H_ diff --git a/bridge/foundation/macros.h b/bridge/foundation/macros.h new file mode 100644 index 0000000000..a65cf1ec79 --- /dev/null +++ b/bridge/foundation/macros.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2019 Alibaba Inc. All rights reserved. + * Author: Kraken Team. + */ + +#ifndef KRAKENBRIDGE_MACROS_H +#define KRAKENBRIDGE_MACROS_H + +#if defined(__GNUC__) || defined(__clang__) +#define LIKELY(x) __builtin_expect(!!(x), 1) +#define UNLIKELY(x) __builtin_expect(!!(x), 0) +#define FORCE_INLINE inline __attribute__((always_inline)) +#else +#define LIKELY(x) (x) +#define UNLIKELY(x) (x) +#define FORCE_INLINE inline +#endif + +#define assert_m(exp, msg) assert(((void)msg, exp)) + +#define KRAKEN_DISALLOW_COPY(TypeName) TypeName(const TypeName&) = delete + +#define KRAKEN_DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete + +#define KRAKEN_DISALLOW_MOVE(TypeName) \ + TypeName(TypeName&&) = delete; \ + TypeName& operator=(TypeName&&) = delete + +#define KRAKEN_DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&) = delete; \ + TypeName& operator=(const TypeName&) = delete + +#define KRAKEN_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName) \ + TypeName(const TypeName&) = delete; \ + TypeName(TypeName&&) = delete; \ + TypeName& operator=(const TypeName&) = delete; \ + TypeName& operator=(TypeName&&) = delete + +#define KRAKEN_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ + TypeName() = delete; \ + KRAKEN_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName) + + +#endif // KRAKENBRIDGE_MACROS_H diff --git a/bridge/bindings/qjs/native_value.cc b/bridge/foundation/native_value.cc similarity index 94% rename from bridge/bindings/qjs/native_value.cc rename to bridge/foundation/native_value.cc index 92f372da8d..8bc6bdaf3d 100644 --- a/bridge/bindings/qjs/native_value.cc +++ b/bridge/foundation/native_value.cc @@ -4,31 +4,17 @@ */ #include "native_value.h" -#include "bindings/qjs/dom/elements/image_element.h" +#include "bindings/qjs/executing_context.h" #include "bindings/qjs/qjs_patch.h" -#include "dom/element.h" -#include "dom/elements/.gen/canvas_element.h" -#include "kraken_bridge.h" +#include "bindings/qjs/dom/event_target.h" -namespace kraken::binding::qjs { +namespace kraken { + +using namespace kraken::binding::qjs; #define AnonymousFunctionCallPreFix "_anonymous_fn_" #define AsyncAnonymousFunctionCallPreFix "_anonymous_async_fn_" -NativeString* NativeString::clone() { - auto* newNativeString = new NativeString(); - auto* newString = new uint16_t[length]; - - memcpy(newString, string, length * sizeof(uint16_t)); - newNativeString->string = newString; - newNativeString->length = length; - return newNativeString; -} - -void NativeString::free() { - delete[] string; -} - NativeValue Native_NewNull() { return (NativeValue){0, .u = {.int64 = 0}, NativeTag::TAG_NULL}; } @@ -161,7 +147,7 @@ NativeFunctionContext::~NativeFunctionContext() { static JSValue anonymousFunction(JSContext* ctx, JSValueConst this_val, int argc, JSValueConst* argv, int magic, JSValue* func_data) { auto id = magic; - auto* eventTarget = static_cast(JS_GetOpaque(this_val, JSValueGetClassId(this_val))); + auto* eventTarget = static_cast(JS_GetOpaque(this_val, JSValueGetClassId(this_val))); std::string call_params = AnonymousFunctionCallPreFix + std::to_string(id); diff --git a/bridge/bindings/qjs/native_value.h b/bridge/foundation/native_value.h similarity index 93% rename from bridge/bindings/qjs/native_value.h rename to bridge/foundation/native_value.h index 8edaaf0d46..d031856943 100644 --- a/bridge/bindings/qjs/native_value.h +++ b/bridge/foundation/native_value.h @@ -11,6 +11,8 @@ #include #include +namespace kraken { + enum NativeTag { TAG_STRING = 0, TAG_INT = 1, @@ -25,16 +27,6 @@ enum NativeTag { enum class JSPointerType { AsyncContextContext = 0, NativeFunctionContext = 1, NativeBoundingClientRect = 2, NativeCanvasRenderingContext2D = 3, NativeEventTarget = 4 }; -namespace kraken::binding::qjs { - -struct NativeString { - const uint16_t* string; - uint32_t length; - - NativeString* clone(); - void free(); -}; - class ExecutionContext; // Exchange data struct between dart and C++ diff --git a/bridge/foundation/ref_counted_internal.h b/bridge/foundation/ref_counted_internal.h index a196cf9cdd..5c01b96b9d 100644 --- a/bridge/foundation/ref_counted_internal.h +++ b/bridge/foundation/ref_counted_internal.h @@ -8,7 +8,6 @@ #define FLUTTER_FML_MEMORY_REF_COUNTED_INTERNAL_H_ #include -#include "include/kraken_bridge.h" #include "logging.h" namespace fml { @@ -76,8 +75,6 @@ class RefCountedThreadSafeBase { mutable bool adoption_required_; mutable bool destruction_started_; #endif - - KRAKEN_DISALLOW_COPY_AND_ASSIGN(RefCountedThreadSafeBase); }; inline RefCountedThreadSafeBase::RefCountedThreadSafeBase() diff --git a/bridge/foundation/ref_ptr.h b/bridge/foundation/ref_ptr.h index ccf61a5a5c..ddadd0e382 100644 --- a/bridge/foundation/ref_ptr.h +++ b/bridge/foundation/ref_ptr.h @@ -14,6 +14,7 @@ #include "logging.h" #include "ref_ptr_internal.h" +#include "macros.h" namespace fml { diff --git a/bridge/foundation/ref_ptr_internal.h b/bridge/foundation/ref_ptr_internal.h index b81ffb2468..a3579864fe 100644 --- a/bridge/foundation/ref_ptr_internal.h +++ b/bridge/foundation/ref_ptr_internal.h @@ -6,7 +6,6 @@ #define FLUTTER_FML_MEMORY_REF_PTR_INTERNAL_H_ #include -#include "include/kraken_bridge.h" namespace fml { diff --git a/bridge/foundation/task_queue.cc b/bridge/foundation/task_queue.cc index 5322b6aab6..dc98c34459 100644 --- a/bridge/foundation/task_queue.cc +++ b/bridge/foundation/task_queue.cc @@ -5,7 +5,7 @@ #include "task_queue.h" -namespace foundation { +namespace kraken { int32_t TaskQueue::registerTask(const Task& task, void* data) { std::lock_guard guard(queue_mutex_); @@ -32,4 +32,4 @@ void TaskQueue::flushTask() { m_map.clear(); } -} // namespace foundation +} // namespace kraken diff --git a/bridge/foundation/task_queue.h b/bridge/foundation/task_queue.h index 30be05d854..2339f5474c 100644 --- a/bridge/foundation/task_queue.h +++ b/bridge/foundation/task_queue.h @@ -8,11 +8,12 @@ #include #include -#include "closure.h" #include "ref_counter.h" #include "ref_ptr.h" -namespace foundation { +namespace kraken { + +using Task = void (*)(void*); class TaskQueue : public fml::RefCountedThreadSafe { public: @@ -35,6 +36,6 @@ class TaskQueue : public fml::RefCountedThreadSafe { FML_FRIEND_REF_COUNTED_THREAD_SAFE(TaskQueue); }; -} // namespace foundation +} // namespace kraken #endif // KRAKENBRIDGE_TASK_QUEUE_H diff --git a/bridge/foundation/ui_command_buffer.cc b/bridge/foundation/ui_command_buffer.cc index 0d14560f24..36bb49aa79 100644 --- a/bridge/foundation/ui_command_buffer.cc +++ b/bridge/foundation/ui_command_buffer.cc @@ -5,9 +5,8 @@ #include "ui_command_buffer.h" #include "dart_methods.h" -#include "include/kraken_bridge.h" -namespace foundation { +namespace kraken { UICommandBuffer::UICommandBuffer(int32_t contextId) : contextId(contextId) {} @@ -73,4 +72,4 @@ void UICommandBuffer::clear() { update_batched = false; } -} // namespace foundation +} // namespace kraken diff --git a/bridge/foundation/ui_command_buffer.h b/bridge/foundation/ui_command_buffer.h index 15b10b5bea..0a249dde16 100644 --- a/bridge/foundation/ui_command_buffer.h +++ b/bridge/foundation/ui_command_buffer.h @@ -6,7 +6,49 @@ #ifndef KRAKENBRIDGE_FOUNDATION_UI_COMMAND_BUFFER_H_ #define KRAKENBRIDGE_FOUNDATION_UI_COMMAND_BUFFER_H_ -namespace foundation { +#include +#include +#include "native_value.h" +#include "bindings/qjs/native_string.h" + +namespace kraken { + +enum UICommand { + createElement, + createTextNode, + createComment, + disposeEventTarget, + addEvent, + removeNode, + insertAdjacentNode, + setStyle, + setProperty, + removeProperty, + cloneNode, + removeEvent, + createDocumentFragment, +}; + +struct UICommandItem { + UICommandItem(int32_t id, int32_t type, NativeString args_01, NativeString args_02, void* nativePtr) + : type(type), + string_01(reinterpret_cast(args_01.string)), + args_01_length(args_01.length), + string_02(reinterpret_cast(args_02.string)), + args_02_length(args_02.length), + id(id), + nativePtr(reinterpret_cast(nativePtr)){}; + UICommandItem(int32_t id, int32_t type, NativeString args_01, void* nativePtr) + : type(type), string_01(reinterpret_cast(args_01.string)), args_01_length(args_01.length), id(id), nativePtr(reinterpret_cast(nativePtr)){}; + UICommandItem(int32_t id, int32_t type, void* nativePtr) : type(type), id(id), nativePtr(reinterpret_cast(nativePtr)){}; + int32_t type; + int32_t id; + int32_t args_01_length{0}; + int32_t args_02_length{0}; + int64_t string_01{0}; + int64_t string_02{0}; + int64_t nativePtr{0}; +}; class UICommandBuffer { public: @@ -26,6 +68,6 @@ class UICommandBuffer { std::vector queue; }; -} // namespace foundation +} // namespace kraken #endif // KRAKENBRIDGE_FOUNDATION_UI_COMMAND_BUFFER_H_ diff --git a/bridge/foundation/ui_command_callback_queue.cc b/bridge/foundation/ui_command_callback_queue.cc index 5d0dceebc3..1182984337 100644 --- a/bridge/foundation/ui_command_callback_queue.cc +++ b/bridge/foundation/ui_command_callback_queue.cc @@ -3,9 +3,7 @@ * Author: Kraken Team. */ -#include "kraken_bridge.h" - -namespace foundation { +namespace kraken { UICommandCallbackQueue* UICommandCallbackQueue::instance() { static UICommandCallbackQueue* queue = nullptr; @@ -29,4 +27,4 @@ void UICommandCallbackQueue::registerCallback(const Callback& callback, void* da queue.emplace_back(item); } -} // namespace foundation +} // namespace kraken diff --git a/bridge/foundation/ui_task_queue.cc b/bridge/foundation/ui_task_queue.cc index aa55c1b051..64f9d0492d 100644 --- a/bridge/foundation/ui_task_queue.cc +++ b/bridge/foundation/ui_task_queue.cc @@ -5,7 +5,7 @@ #include "ui_task_queue.h" -namespace foundation { +namespace kraken { std::mutex UITaskQueue::ui_task_creation_mutex_{}; fml::RefPtr UITaskQueue::instance_{}; @@ -15,4 +15,4 @@ int32_t UITaskQueue::registerTask(const Task& task, void* data) { return taskId; } -} // namespace foundation +} // namespace kraken diff --git a/bridge/foundation/ui_task_queue.h b/bridge/foundation/ui_task_queue.h index 62b73ae8be..b87d452c23 100644 --- a/bridge/foundation/ui_task_queue.h +++ b/bridge/foundation/ui_task_queue.h @@ -8,9 +8,7 @@ #include "task_queue.h" -namespace foundation { - -using Task = void (*)(void*); +namespace kraken { class UITaskQueue : public TaskQueue { public: @@ -30,6 +28,6 @@ class UITaskQueue : public TaskQueue { int m_contextId; }; -} // namespace foundation +} // namespace kraken #endif // KRAKENBRIDGE_UI_TASK_QUEUE_H diff --git a/bridge/include/kraken_bridge.h b/bridge/include/kraken_bridge.h index 6f29301a64..0cce47d4f5 100644 --- a/bridge/include/kraken_bridge.h +++ b/bridge/include/kraken_bridge.h @@ -8,26 +8,15 @@ #include -#include "dart_methods.h" -#include "kraken_foundation.h" - -#if KRAKEN_JSC_ENGINE -#include "kraken_bridge_jsc.h" -#elif KRAKEN_QUICK_JS_ENGINE -#endif - #define KRAKEN_EXPORT_C extern "C" __attribute__((visibility("default"))) __attribute__((used)) #define KRAKEN_EXPORT __attribute__((__visibility__("default"))) KRAKEN_EXPORT std::thread::id getUIThreadId(); -typedef struct void* NativeString*; - -struct NativeByteCode { - uint8_t* bytes; - int32_t length; -}; +typedef struct NativeString NativeString; +typedef struct NativeScreen NativeScreen; +typedef struct NativeByteCode NativeByteCode; struct KrakenInfo; @@ -38,43 +27,6 @@ struct KrakenInfo { const char* system_name{nullptr}; }; -enum UICommand { - createElement, - createTextNode, - createComment, - disposeEventTarget, - addEvent, - removeNode, - insertAdjacentNode, - setStyle, - setProperty, - removeProperty, - cloneNode, - removeEvent, - createDocumentFragment, -}; - -struct KRAKEN_EXPORT UICommandItem { - UICommandItem(int32_t id, int32_t type, NativeString args_01, NativeString args_02, void* nativePtr) - : type(type), - string_01(reinterpret_cast(args_01.string)), - args_01_length(args_01.length), - string_02(reinterpret_cast(args_02.string)), - args_02_length(args_02.length), - id(id), - nativePtr(reinterpret_cast(nativePtr)){}; - UICommandItem(int32_t id, int32_t type, NativeString args_01, void* nativePtr) - : type(type), string_01(reinterpret_cast(args_01.string)), args_01_length(args_01.length), id(id), nativePtr(reinterpret_cast(nativePtr)){}; - UICommandItem(int32_t id, int32_t type, void* nativePtr) : type(type), id(id), nativePtr(reinterpret_cast(nativePtr)){}; - int32_t type; - int32_t id; - int32_t args_01_length{0}; - int32_t args_02_length{0}; - int64_t string_01{0}; - int64_t string_02{0}; - int64_t nativePtr{0}; -}; - typedef void (*Task)(void*); typedef void (*ConsoleMessageHandler)(void* ctx, const std::string& message, int logLevel); @@ -99,7 +51,7 @@ void reloadJsContext(int32_t contextId); KRAKEN_EXPORT_C void invokeModuleEvent(int32_t contextId, NativeString* module, const char* eventType, void* event, NativeString* extra); KRAKEN_EXPORT_C -void registerDartMethods(uint64_t* methodBytes, int32_t length); +void registerDartMethods(int32_t contextId, uint64_t* methodBytes, int32_t length); KRAKEN_EXPORT_C NativeScreen* createScreen(double width, double height); KRAKEN_EXPORT_C @@ -111,9 +63,7 @@ void flushUITask(int32_t contextId); KRAKEN_EXPORT_C void registerUITask(int32_t contextId, Task task, void* data); KRAKEN_EXPORT_C -void flushUICommandCallback(); -KRAKEN_EXPORT_C -UICommandItem* getUICommandItems(int32_t contextId); +void* getUICommandItems(int32_t contextId); KRAKEN_EXPORT_C int64_t getUICommandItemSize(int32_t contextId); KRAKEN_EXPORT_C diff --git a/bridge/include/kraken_foundation.h b/bridge/include/kraken_foundation.h deleted file mode 100644 index eb85806234..0000000000 --- a/bridge/include/kraken_foundation.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2020 Alibaba Inc. All rights reserved. - * Author: Kraken Team. - */ - -#ifndef KRAKENBRIDGE_FOUNDATION_H -#define KRAKENBRIDGE_FOUNDATION_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define WINDOW_TARGET_ID -1 -#define DOCUMENT_TARGET_ID -2 - -#define assert_m(exp, msg) assert(((void)msg, exp)) - -#define KRAKEN_EXPORT __attribute__((__visibility__("default"))) - -#if defined(__GNUC__) || defined(__clang__) -#define LIKELY(x) __builtin_expect(!!(x), 1) -#define UNLIKELY(x) __builtin_expect(!!(x), 0) -#define FORCE_INLINE inline __attribute__((always_inline)) -#else -#define LIKELY(x) (x) -#define UNLIKELY(x) (x) -#define FORCE_INLINE inline -#endif - -#define KRAKEN_DISALLOW_COPY(TypeName) TypeName(const TypeName&) = delete - -#define KRAKEN_DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete - -#define KRAKEN_DISALLOW_MOVE(TypeName) \ - TypeName(TypeName&&) = delete; \ - TypeName& operator=(TypeName&&) = delete - -#define KRAKEN_DISALLOW_COPY_AND_ASSIGN(TypeName) \ - TypeName(const TypeName&) = delete; \ - TypeName& operator=(const TypeName&) = delete - -#define KRAKEN_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName) \ - TypeName(const TypeName&) = delete; \ - TypeName(TypeName&&) = delete; \ - TypeName& operator=(const TypeName&) = delete; \ - TypeName& operator=(TypeName&&) = delete - -#define KRAKEN_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ - TypeName() = delete; \ - KRAKEN_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName) - -struct NativeString; -struct UICommandItem; - -namespace foundation { - -// An un thread safe queue used for dart side to read ui command items. -class UICommandCallbackQueue { - public: - using Callback = void (*)(void*); - UICommandCallbackQueue() = default; - static KRAKEN_EXPORT UICommandCallbackQueue* instance(); - KRAKEN_EXPORT void registerCallback(const Callback& callback, void* data); - KRAKEN_EXPORT void flushCallbacks(); - - private: - struct CallbackItem { - CallbackItem(const Callback& callback, void* data) : callback(callback), data(data){}; - Callback callback; - void* data; - }; - - std::vector queue; -}; - -typedef int LogSeverity; - -// Default log levels. Negative values can be used for verbose log levels. -constexpr LogSeverity LOG_VERBOSE = 0; -constexpr LogSeverity LOG_INFO = 1; -constexpr LogSeverity LOG_WARN = 2; -constexpr LogSeverity LOG_DEBUG_ = 3; -constexpr LogSeverity LOG_ERROR = 4; -constexpr LogSeverity LOG_NUM_SEVERITIES = 5; -constexpr LogSeverity LOG_FATAL = 6; - -class LogMessageVoidify { - public: - void operator&(std::ostream&) {} -}; - -class KRAKEN_EXPORT LogMessage { - public: - LogMessage(LogSeverity severity, const char* file, int line, const char* condition); - ~LogMessage(); - - std::ostream& stream() { return stream_; } - - private: - std::ostringstream stream_; - const LogSeverity severity_; - const char* file_; - const int line_; - - KRAKEN_DISALLOW_COPY_AND_ASSIGN(LogMessage); -}; - -void printLog(int32_t contextId, std::stringstream& stream, std::string level, void* ctx); - -} // namespace foundation - -#define KRAKEN_LOG_STREAM(severity) ::foundation::LogMessage(::foundation::LOG_##severity, __FILE__, __LINE__, nullptr).stream() - -#define KRAKEN_LAZY_STREAM(stream, condition) !(condition) ? (void)0 : ::foundation::LogMessageVoidify() & (stream) - -#define KRAKEN_EAT_STREAM_PARAMETERS(ignored) true || (ignored) ? (void)0 : ::foundation::LogMessageVoidify() & ::foundation::LogMessage(::foundation::LOG_FATAL, 0, 0, nullptr).stream() - -#define KRAKEN_LOG(severity) KRAKEN_LAZY_STREAM(KRAKEN_LOG_STREAM(severity), true) - -#define KRAKEN_CHECK(condition) KRAKEN_LAZY_STREAM(::foundation::LogMessage(::foundation::LOG_FATAL, __FILE__, __LINE__, #condition).stream(), !(condition)) - -template -std::string toUTF8(const std::basic_string, std::allocator>& source) { - std::string result; - - std::wstring_convert, T> convertor; - result = convertor.to_bytes(source); - - return result; -} - -template -void fromUTF8(const std::string& source, std::basic_string, std::allocator>& result) { - std::wstring_convert, T> convertor; - result = convertor.from_bytes(source); -} - -#endif diff --git a/bridge/kraken_bridge.cc b/bridge/kraken_bridge.cc index 9f44000469..26237b63b1 100644 --- a/bridge/kraken_bridge.cc +++ b/bridge/kraken_bridge.cc @@ -3,24 +3,17 @@ * Author: Kraken Team. */ -#include "kraken_bridge.h" +#include +#include #include -#include "dart_methods.h" + +#include "include/kraken_bridge.h" #include "foundation/inspector_task_queue.h" #include "foundation/logging.h" #include "foundation/ui_task_queue.h" -#if KRAKEN_JSC_ENGINE -#include "bindings/jsc/KOM/performance.h" -#elif KRAKEN_QUICK_JS_ENGINE +#include "foundation/ui_command_buffer.h" +#include "bindings/qjs/native_string.h" #include "page.h" -#endif - -#if KRAKEN_JSC_ENGINE -#include "bridge_jsc.h" -#endif - -#include -#include #if defined(_WIN32) #define SYSTEM_NAME "windows" // Windows @@ -49,20 +42,6 @@ std::atomic inited{false}; std::atomic poolIndex{0}; int maxPoolSize = 0; -NativeScreen screen; - -std::thread::id uiThreadId; - -std::thread::id getUIThreadId() { - return uiThreadId; -} - -void printError(int32_t contextId, const char* errmsg) { - if (kraken::getDartMethod()->onJsError != nullptr) { - kraken::getDartMethod()->onJsError(contextId, errmsg); - } - KRAKEN_LOG(ERROR) << errmsg << std::endl; -} namespace { @@ -86,7 +65,6 @@ int32_t searchForAvailableContextId() { } // namespace void initJSPagePool(int poolSize) { - uiThreadId = std::this_thread::get_id(); // When dart hot restarted, should dispose previous bridge and clear task message queue. if (inited) { disposeAllPages(); @@ -96,7 +74,7 @@ void initJSPagePool(int poolSize) { kraken::KrakenPage::pageContextPool[i] = nullptr; } - kraken::KrakenPage::pageContextPool[0] = new kraken::KrakenPage(0, printError); + kraken::KrakenPage::pageContextPool[0] = new kraken::KrakenPage(0, nullptr); inited = true; maxPoolSize = poolSize; } @@ -122,7 +100,7 @@ int32_t allocateNewPage(int32_t targetContextId) { assert(kraken::KrakenPage::pageContextPool[targetContextId] == nullptr && (std::string("can not allocate page at index") + std::to_string(targetContextId) + std::string(": page have already exist.")).c_str()); - auto* page = new kraken::KrakenPage(targetContextId, printError); + auto* page = new kraken::KrakenPage(targetContextId, nullptr); kraken::KrakenPage::pageContextPool[targetContextId] = page; return targetContextId; } @@ -144,7 +122,7 @@ bool checkPage(int32_t contextId, void* context) { return page->getContext() == context; } -void evaluateScripts(int32_t contextId, NativeString* code, const char* bundleFilename, int startLine) { +void evaluateScripts(int32_t contextId, kraken::NativeString* code, const char* bundleFilename, int startLine) { assert(checkPage(contextId) && "evaluateScripts: contextId is not valid"); auto context = static_cast(getPage(contextId)); context->evaluateScript(code, bundleFilename, startLine); @@ -166,25 +144,27 @@ void reloadJsContext(int32_t contextId) { assert(checkPage(contextId) && "reloadJSContext: contextId is not valid"); auto bridgePtr = getPage(contextId); auto context = static_cast(bridgePtr); - auto newContext = new kraken::KrakenPage(contextId, printError); + auto newContext = new kraken::KrakenPage(contextId, nullptr); delete context; kraken::KrakenPage::pageContextPool[contextId] = newContext; } -void invokeModuleEvent(int32_t contextId, NativeString* moduleName, const char* eventType, void* event, NativeString* extra) { +void invokeModuleEvent(int32_t contextId, kraken::NativeString* moduleName, const char* eventType, void* event, kraken::NativeString* extra) { assert(checkPage(contextId) && "invokeEventListener: contextId is not valid"); auto context = static_cast(getPage(contextId)); context->invokeModuleEvent(moduleName, eventType, event, extra); } -void registerDartMethods(uint64_t* methodBytes, int32_t length) { - kraken::registerDartMethods(methodBytes, length); +void registerDartMethods(int32_t contextId, uint64_t* methodBytes, int32_t length) { + assert(checkPage(contextId) && "registerDartMethods: contextId is not valid"); + auto context = static_cast(getPage(contextId)); + context->registerDartMethods(methodBytes, length); } NativeScreen* createScreen(double width, double height) { - screen.width = width; - screen.height = height; - return &screen; +// screen.width = width; +// screen.height = height; +// return &screen; } static KrakenInfo* krakenInfo{nullptr}; @@ -211,18 +191,14 @@ void dispatchUITask(int32_t contextId, void* context, void* callback) { } void flushUITask(int32_t contextId) { - foundation::UITaskQueue::instance(contextId)->flushTask(); + kraken::UITaskQueue::instance(contextId)->flushTask(); } void registerUITask(int32_t contextId, Task task, void* data) { - foundation::UITaskQueue::instance(contextId)->registerTask(task, data); + kraken::UITaskQueue::instance(contextId)->registerTask(task, data); }; -void flushUICommandCallback() { - foundation::UICommandCallbackQueue::instance()->flushCallbacks(); -} - -UICommandItem* getUICommandItems(int32_t contextId) { +void* getUICommandItems(int32_t contextId) { auto* page = static_cast(getPage(contextId)); if (page == nullptr) return nullptr; @@ -249,7 +225,7 @@ void registerContextDisposedCallbacks(int32_t contextId, Task task, void* data) } void registerPluginByteCode(uint8_t* bytes, int32_t length, const char* pluginName) { - kraken::KrakenPage::pluginByteCode[pluginName] = NativeByteCode{bytes, length}; + kraken::KrakenPage::pluginByteCode[pluginName] = kraken::NativeByteCode{bytes, length}; } int32_t profileModeEnabled() { diff --git a/bridge/page.cc b/bridge/page.cc index 445e16b20d..0274e4bf37 100644 --- a/bridge/page.cc +++ b/bridge/page.cc @@ -3,11 +3,11 @@ * Author: Kraken Team. */ -#include "polyfill.h" - #include + +#include "foundation/logging.h" +#include "polyfill.h" #include "bindings/qjs/qjs_patch.h" -#include "dart_methods.h" #include "page.h" #include "bindings/qjs/bom/blob.h" @@ -53,11 +53,16 @@ ConsoleMessageHandler KrakenPage::consoleMessageHandler{nullptr}; kraken::KrakenPage** KrakenPage::pageContextPool{nullptr}; -KrakenPage::KrakenPage(int32_t contextId, const JSExceptionHandler& handler) : contextId(contextId) { +KrakenPage::KrakenPage(int32_t contextId, const JSExceptionHandler& handler) : contextId(contextId), ownerThreadId(std::this_thread::get_id()) { #if ENABLE_PROFILE auto jsContextStartTime = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); #endif - m_context = new ExecutionContext(contextId, handler, this); + m_context = new ExecutionContext(contextId, [this](int32_t contextId, const char* message) { + if (m_context->dartMethodPtr()->onJsError != nullptr) { + m_context->dartMethodPtr()->onJsError(contextId, message); + } + KRAKEN_LOG(ERROR) << message << std::endl; + }, this); #if ENABLE_PROFILE auto nativePerformance = Performance::instance(m_context)->m_nativePerformance; @@ -127,7 +132,7 @@ bool KrakenPage::parseHTML(const char* code, size_t length) { return true; } -void KrakenPage::invokeModuleEvent(NativeString* moduleName, const char* eventType, void* ptr, NativeString* extra) { +void KrakenPage::invokeModuleEvent(const NativeString* moduleName, const char* eventType, void* ptr, NativeString* extra) { if (!m_context->isValid()) return; @@ -208,6 +213,38 @@ void KrakenPage::evaluateByteCode(uint8_t* bytes, size_t byteLength) { m_context->evaluateByteCode(bytes, byteLength); } +void KrakenPage::registerDartMethods(uint64_t* methodBytes, int32_t length) { + size_t i = 0; + + auto& dartMethodPointer = m_context->dartMethodPtr(); + + dartMethodPointer->invokeModule = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->requestBatchUpdate = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->reloadApp = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->setTimeout = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->setInterval = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->clearTimeout = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->requestAnimationFrame = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->cancelAnimationFrame = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->getScreen = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->devicePixelRatio = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->platformBrightness = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->toBlob = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->flushUICommand = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->initWindow = reinterpret_cast(methodBytes[i++]); + dartMethodPointer->initDocument = reinterpret_cast(methodBytes[i++]); + +#if ENABLE_PROFILE + methodPointer->getPerformanceEntries = reinterpret_cast(methodBytes[i++]); +#else + i++; +#endif + + dartMethodPointer->onJsError = reinterpret_cast(methodBytes[i++]); + + assert_m(i == length, "Dart native methods count is not equal with C++ side method registrations."); +} + KrakenPage::~KrakenPage() { #if IS_TEST if (disposeCallback != nullptr) { diff --git a/bridge/page.h b/bridge/page.h index f41a53e5f7..d979b5b322 100644 --- a/bridge/page.h +++ b/bridge/page.h @@ -7,18 +7,25 @@ #define KRAKEN_JS_QJS_BRIDGE_H_ #include -#include "bindings/qjs/executing_context.h" -#include "bindings/qjs/html_parser.h" -#include "include/kraken_bridge.h" - #include #include #include +#include + +#include "bindings/qjs/executing_context.h" +#include "bindings/qjs/html_parser.h" +#include "bindings/qjs/native_string.h" namespace kraken { +struct NativeByteCode { + uint8_t* bytes; + int32_t length; +}; + class KrakenPage; using JSBridgeDisposeCallback = void (*)(KrakenPage* bridge); +using ConsoleMessageHandler = std::function; /// KrakenPage is class which manage all js objects create by flutter widget. /// Every flutter widgets have a corresponding KrakenPage, and all objects created by JavaScript are stored here, @@ -43,9 +50,11 @@ class KrakenPage final { uint8_t* dumpByteCode(const char* script, size_t length, const char* url, size_t* byteLength); void evaluateByteCode(uint8_t* bytes, size_t byteLength); - [[nodiscard]] kraken::binding::qjs::ExecutionContext* getContext() const { return m_context; } + void registerDartMethods(uint64_t* methodBytes, int32_t length); + + [[nodiscard]] ExecutionContext* getContext() const { return m_context; } - void invokeModuleEvent(NativeString* moduleName, const char* eventType, void* event, NativeString* extra); + void invokeModuleEvent(const NativeString* moduleName, const char* eventType, void* event, NativeString* extra); void reportError(const char* errmsg); int32_t contextId; @@ -55,9 +64,10 @@ class KrakenPage final { JSBridgeDisposeCallback disposeCallback{nullptr}; #endif private: + const std::thread::id ownerThreadId; // FIXME: we must to use raw pointer instead of unique_ptr because we needs to access m_context when dispose page. // TODO: Raw pointer is dangerous and just works but it's fragile. We needs refactor this for more stable and maintainable. - binding::qjs::ExecutionContext* m_context; + ExecutionContext* m_context; JSExceptionHandler m_handler; }; diff --git a/bridge/page_test.cc b/bridge/page_test.cc index 4ced535a7e..b5c1fb7164 100644 --- a/bridge/page_test.cc +++ b/bridge/page_test.cc @@ -281,4 +281,18 @@ void KrakenPageTest::invokeExecuteTest(ExecuteCallback executeCallback) { executeTestCallback = JS_NULL; } +void KrakenPageTest::registerTestEnvDartMethods(uint64_t* methodBytes, int32_t length) { + size_t i = 0; + + auto& dartMethodPtr = m_page_context->dartMethodPtr(); + + dartMethodPtr->onJsError = reinterpret_cast(methodBytes[i++]); + dartMethodPtr->matchImageSnapshot = reinterpret_cast(methodBytes[i++]); + dartMethodPtr->environment = reinterpret_cast(methodBytes[i++]); + dartMethodPtr->simulatePointer = reinterpret_cast(methodBytes[i++]); + dartMethodPtr->simulateInputText = reinterpret_cast(methodBytes[i++]); + + assert_m(i == length, "Dart native methods count is not equal with C++ side method registrations."); +} + } // namespace kraken diff --git a/bridge/page_test.h b/bridge/page_test.h index 6e359083bf..b19761bd4b 100644 --- a/bridge/page_test.h +++ b/bridge/page_test.h @@ -15,7 +15,7 @@ namespace kraken { struct ImageSnapShotContext { JSValue callback; - binding::qjs::ExecutionContext* context; + ExecutionContext* context; list_head link; }; @@ -45,6 +45,7 @@ class KrakenPageTest final { bool evaluateTestScripts(const uint16_t* code, size_t codeLength, const char* sourceURL, int startLine); bool parseTestHTML(const uint16_t* code, size_t codeLength); void invokeExecuteTest(ExecuteCallback executeCallback); + void registerTestEnvDartMethods(uint64_t* methodBytes, int32_t length); JSValue executeTestCallback{JS_NULL}; JSValue executeTestProxyObject{JS_NULL}; @@ -54,7 +55,7 @@ class KrakenPageTest final { /// the pointer of bridge, ownership belongs to JSBridge KrakenPage* m_page; /// the pointer of JSContext, overship belongs to JSContext - binding::qjs::ExecutionContext* m_page_context; + ExecutionContext* m_page_context; }; } // namespace kraken diff --git a/bridge/test/kraken_test_env.cc b/bridge/test/kraken_test_env.cc index a20332eb50..49869d0768 100644 --- a/bridge/test/kraken_test_env.cc +++ b/bridge/test/kraken_test_env.cc @@ -8,7 +8,6 @@ #include #include "bindings/qjs/dom/event_target.h" #include "dart_methods.h" -#include "include/kraken_bridge.h" #include "kraken_bridge_test.h" #include "page.h"