From e67c094f77be5e641934985e8cbe7ae77cc17dfe Mon Sep 17 00:00:00 2001 From: checkroom Date: Wed, 18 Dec 2024 08:40:46 +0000 Subject: [PATCH] Refreshing support for dynamic linking --- include/globals.hpp | 2 +- include/pipelines/commons.hpp | 12 ++++++++++++ include/pipelines/quickjs-js.hpp | 7 ++++--- include/pipelines/tcc-c.hpp | 8 ++++---- src/pipelines/quickjs-js.cpp | 2 +- src/pipelines/tcc-c.cpp | 5 ++++- src/ui-tree.xml.cpp | 27 +++++++++++++++++++-------- 7 files changed, 45 insertions(+), 18 deletions(-) create mode 100644 include/pipelines/commons.hpp diff --git a/include/globals.hpp b/include/globals.hpp index bd8611f6..c10f4094 100644 --- a/include/globals.hpp +++ b/include/globals.hpp @@ -1,6 +1,6 @@ #pragma once -#include "utils/app-env.hpp" +#include #include #include #include diff --git a/include/pipelines/commons.hpp b/include/pipelines/commons.hpp new file mode 100644 index 00000000..8b69aa79 --- /dev/null +++ b/include/pipelines/commons.hpp @@ -0,0 +1,12 @@ +#pragma once + +namespace vs{ +namespace pipelines{ + +struct link_with_t{ + const char* lib; + const char* header; +}; + +} +} diff --git a/include/pipelines/quickjs-js.hpp b/include/pipelines/quickjs-js.hpp index 268189b6..5739dd5e 100644 --- a/include/pipelines/quickjs-js.hpp +++ b/include/pipelines/quickjs-js.hpp @@ -1,6 +1,5 @@ #pragma once -#include "globals.hpp" #if VS_USE_QJS #include @@ -8,6 +7,8 @@ #include #include +#include "globals.hpp" +#include "commons.hpp" //TODO: restructure following changes in the tcc interface @@ -42,10 +43,10 @@ struct quickjs_t{ } }; -extern std::shared_ptr qjs_js_pipeline(global_ctx_t& globals, bool is_runtime, vs::ui_base* obj, const char* src, void* ctx, void(*error_fn)(void*,const char*), const char *link_with); +extern std::shared_ptr qjs_js_pipeline(global_ctx_t& globals, bool is_runtime, vs::ui_base* obj, const char* src, void* ctx, void(*error_fn)(void*,const char*), link_with_t link_with); extern std::shared_ptr> qjs_js_pipeline_apply(const std::shared_ptr& script,vs::ui_base* obj,void* ctx,void(*register_fn)(void*,const char*, const char*)); -inline std::shared_ptr qjs_js_pipeline_xml(global_ctx_t& globals, bool is_runtime, vs::ui_base* obj, pugi::xml_node& ctx, const char *link_with){ +inline std::shared_ptr qjs_js_pipeline_xml(global_ctx_t& globals, bool is_runtime, vs::ui_base* obj, pugi::xml_node& ctx, link_with_t link_with){ return qjs_js_pipeline(globals,is_runtime,obj,ctx.text().as_string(),&ctx,(void(*)(void*,const char*))qjs_error_func_xml,link_with); } diff --git a/include/pipelines/tcc-c.hpp b/include/pipelines/tcc-c.hpp index b0ee35e8..718ac001 100644 --- a/include/pipelines/tcc-c.hpp +++ b/include/pipelines/tcc-c.hpp @@ -1,13 +1,13 @@ #pragma once -#include "globals.hpp" #if VS_USE_TCC - #include #include #include #include +#include "globals.hpp" +#include "commons.hpp" namespace vs{ namespace pipelines{ @@ -31,10 +31,10 @@ extern void tcc_log_symbol_func_xml(const pugi::xml_node& env, const char * msg, * @param link_with path of a library to be linked against (exposing the standard vs interface) * @return std::shared_ptr */ -extern std::shared_ptr tcc_c_pipeline(global_ctx_t& globals, bool is_runtime, ui_base* obj, const char* src, void* ctx, void(*error_fn)(void*,const char*), bool compact, const char *link_with); +extern std::shared_ptr tcc_c_pipeline(global_ctx_t& globals, bool is_runtime, ui_base* obj, const char* src, void* ctx, void(*error_fn)(void*,const char*), bool compact, link_with_t link_with); extern std::shared_ptr> tcc_c_pipeline_apply(const std::shared_ptr& script,vs::ui_base* obj,void* ctx,void(*register_fn)(void*,const char*, const char*)); -inline std::shared_ptr tcc_c_pipeline_xml(global_ctx_t& globals, bool is_runtime, vs::ui_base* obj, pugi::xml_node& ctx, bool compact, const char *link_with){ +inline std::shared_ptr tcc_c_pipeline_xml(global_ctx_t& globals, bool is_runtime, vs::ui_base* obj, pugi::xml_node& ctx, bool compact, link_with_t link_with){ return tcc_c_pipeline(globals,is_runtime,obj,ctx.text().as_string(),&ctx,(void(*)(void*,const char*))tcc_error_func_xml, compact, link_with); } diff --git a/src/pipelines/quickjs-js.cpp b/src/pipelines/quickjs-js.cpp index 81f894ab..14d8cfd5 100644 --- a/src/pipelines/quickjs-js.cpp +++ b/src/pipelines/quickjs-js.cpp @@ -219,7 +219,7 @@ std::shared_ptr> qjs_js_pipeline_apply(const std::shared_ptr qjs_js_pipeline(global_ctx_t& globals, bool is_runtime, vs::ui_base* obj, const char* src, void* nctx, void(*error_fn)(void*,const char*), const char *link_with){ +std::shared_ptr qjs_js_pipeline(global_ctx_t& globals, bool is_runtime, vs::ui_base* obj, const char* src, void* nctx, void(*error_fn)(void*,const char*), link_with_t link_with){ //std::shared_ptr _ctx = std::make_shared((JSRuntime*)(globals::js_rt())); std::shared_ptr _ctx = std::shared_ptr( new quickjs_t((JSRuntime*)(globals.js_rt())), +[](void* o){delete (quickjs_t*)o;}); diff --git a/src/pipelines/tcc-c.cpp b/src/pipelines/tcc-c.cpp index 6efac771..8c4c2984 100644 --- a/src/pipelines/tcc-c.cpp +++ b/src/pipelines/tcc-c.cpp @@ -57,7 +57,10 @@ static void vs_debug(const char* k, const char* v){singleton::debug(k,v);} #define LIB(x) script->add_sym(#x, (void*) x) #define LIBT(x,t) script->add_sym(#x, (void*) t x) -std::shared_ptr tcc_c_pipeline(global_ctx_t& globals, bool is_runtime, vs::ui_base* obj, const char* src, void* ctx, void(*error_fn)(void*,const char*), bool compact, const char *link_with){ + + + +std::shared_ptr tcc_c_pipeline(global_ctx_t& globals, bool is_runtime, vs::ui_base* obj, const char* src, void* ctx, void(*error_fn)(void*,const char*), bool compact, link_with_t link_with){ auto script = std::make_shared(); //This part is a bit of a mess. diff --git a/src/ui-tree.xml.cpp b/src/ui-tree.xml.cpp index 513e13f7..8652d899 100755 --- a/src/ui-tree.xml.cpp +++ b/src/ui-tree.xml.cpp @@ -421,14 +421,25 @@ void ui_tree_xml::_build_base_widget_extended_attr(const pugi::xml_node &root, u } //Information for linking - auto link_with = doc.first_child().attribute("link-with").as_string(nullptr); - std::string tmp_link; - if(link_with!=nullptr){ + pipelines::link_with_t link_with = { + doc.first_child().attribute("link-with.lib").as_string(nullptr), + doc.first_child().attribute("link-with.header").as_string(nullptr) + }; + + std::string tmp_link_lib, tmp_link_header; + if(link_with.lib!=nullptr && link_with.header!=nullptr){ resolve_path resolver(policies,globals.path_env,local); - auto computed_path = resolver(resolve_path::from_t::NATIVE_CODE,link_with); - if(computed_path.first==resolve_path::reason_t::OK){ + auto computed_path_lib = resolver(resolve_path::from_t::NATIVE_CODE,link_with.lib); + auto computed_path_header = resolver(resolve_path::from_t::NATIVE_CODE,link_with.header); + if(computed_path_lib.first==resolve_path::reason_t::OK && computed_path_header.first==resolve_path::reason_t::OK){ //TODO: For now I am assuming it is on the fs. I should resolve it to tmp if remote for example - tmp_link=computed_path.second.location; + //The issue is tcc capabilities in handling dynamic linking from a buffer sourced from memory. + //This is why for now it will only be assumed to be on the fs. + //Hopefully this restriction will never apply to native components for example. + tmp_link_lib=computed_path_lib.second.location; + tmp_link_header=computed_path_header.second.location; + link_with.lib = tmp_link_lib.c_str(); + link_with.header = tmp_link_header.c_str(); log(severety_t::INFO, root, "Requested linking with `%s`", link_with); } } @@ -439,7 +450,7 @@ void ui_tree_xml::_build_base_widget_extended_attr(const pugi::xml_node &root, u const auto &lang = root.attribute("lang").as_string(mode==frame_mode_t::NATIVE?"c":""); if (strcmp(lang, "c") == 0) { #ifdef VS_USE_TCC - auto compiler = pipelines::tcc_c_pipeline_xml(globals,true, is_module?nullptr:current, root, compact, (link_with==nullptr)?nullptr:tmp_link.c_str()); + auto compiler = pipelines::tcc_c_pipeline_xml(globals,true, is_module?nullptr:current, root, compact, link_with); if(compiler!=nullptr){ current->set_mode(frame_mode_t::NATIVE); current->attach_script(compiler,is_module); @@ -461,7 +472,7 @@ void ui_tree_xml::_build_base_widget_extended_attr(const pugi::xml_node &root, u const auto &lang = root.attribute("lang").as_string(mode==frame_mode_t::QUICKJS?"js":""); if (strcmp(lang, "js") == 0) { #ifdef VS_USE_QJS - auto compiler = pipelines::qjs_js_pipeline_xml(globals,true, is_module?nullptr:current, root, (link_with==nullptr)?nullptr:tmp_link.c_str()); + auto compiler = pipelines::qjs_js_pipeline_xml(globals,true, is_module?nullptr:current, root, link_with); if(compiler!=nullptr){ current->set_mode(frame_mode_t::QUICKJS); current->attach_script(compiler,is_module);