From 7f5a8c2cc2a93e6dbf463e8b47104b88e8c2ee5e Mon Sep 17 00:00:00 2001 From: Alexis Jeandet Date: Thu, 11 Jan 2024 14:07:16 +0100 Subject: [PATCH] Basic WASM POC showing CDF variables count Signed-off-by: Alexis Jeandet --- .../cdfpp/cdf-io/loading/records-loading.hpp | 11 +-- meson.build | 5 +- wacdfpp/meson.build | 22 ++++++ wacdfpp/wacdfpp.cpp | 72 +++++++++++++++++++ wacdfpp/wacdfpp.html | 48 +++++++++++++ wacdfpp/wasm.txt | 23 ++++++ 6 files changed, 175 insertions(+), 6 deletions(-) create mode 100644 wacdfpp/meson.build create mode 100644 wacdfpp/wacdfpp.cpp create mode 100644 wacdfpp/wacdfpp.html create mode 100644 wacdfpp/wasm.txt diff --git a/include/cdfpp/cdf-io/loading/records-loading.hpp b/include/cdfpp/cdf-io/loading/records-loading.hpp index dab0d9c..883e02e 100644 --- a/include/cdfpp/cdf-io/loading/records-loading.hpp +++ b/include/cdfpp/cdf-io/loading/records-loading.hpp @@ -56,7 +56,7 @@ struct parsing_context_t } }; -SPLIT_FIELDS_FW_DECL(std::size_t, load_record,); +SPLIT_FIELDS_FW_DECL(std::size_t, load_record, ); template inline std::size_t load_field( @@ -135,7 +135,7 @@ inline std::size_t load_fields(const record_t& r, parsing_context_t& parsing_con return load_fields(r, parsing_context, offset, std::forward(fields)...); } -SPLIT_FIELDS(std::size_t, load_record, load_fields,); +SPLIT_FIELDS(std::size_t, load_record, load_fields, ); template @@ -289,7 +289,7 @@ auto begin_AgrEDR(const cdf_ADR_t& adr, buffer_t& buffer) { using aedr_t = cdf_AgrEDR_t; - return blk_iterator { adr.AgrEDRhead, buffer, + return blk_iterator { static_cast(adr.AgrEDRhead), buffer, [](const aedr_t& aedr) { return aedr.AEDRnext; } }; } @@ -305,7 +305,7 @@ auto begin_AzEDR(const cdf_ADR_t& adr, buffer_t& buffer) { using aedr_t = cdf_AzEDR_t; - return blk_iterator { adr.AzEDRhead, buffer, + return blk_iterator { static_cast(adr.AzEDRhead), buffer, [](const aedr_t& aedr) { return aedr.AEDRnext; } }; } @@ -351,7 +351,8 @@ auto begin_VDR(parsing_context_t& parsing_context) else if constexpr (type == cdf_r_z::z) { using vdr_t = cdf_zVDR_t; - return blk_iterator { parsing_context.gdr.zVDRhead, + return blk_iterator { static_cast( + parsing_context.gdr.zVDRhead), parsing_context, [](const vdr_t& vdr) { return vdr.VDRnext; } }; } } diff --git a/meson.build b/meson.build index 6f11b55..aaf4f8b 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'pycdfpp', 'cpp','c', - meson_version: '>= 0.63.0', + meson_version: '>= 0.64.0', version : run_command('scripts/version.py', capture:true, env:{'SRC_ROOT':meson.project_source_root()} @@ -226,6 +226,9 @@ install_headers( ], subdir:'cdfpp/cdf-io/saving') +subdir('wacdfpp') + + if get_option('with_tests') configure_file(output : 'tests_config.hpp', diff --git a/wacdfpp/meson.build b/wacdfpp/meson.build new file mode 100644 index 0000000..b09c3f3 --- /dev/null +++ b/wacdfpp/meson.build @@ -0,0 +1,22 @@ +fs = import('fs') + + +flags = ['-sWASM=2', '-sALLOW_MEMORY_GROWTH', '-sFETCH=1', '-sASYNCIFY']+['-sWASM=2', '-sEXPORT_ALL=1', '-sMODULARIZE', '-sEXPORTED_RUNTIME_METHODS=ccall', '-lembind', '-sFETCH=1', '--bind', '-sALLOW_MEMORY_GROWTH'] + +lib_wacdfpp = library('wacdfpp', 'wacdfpp.cpp', + dependencies:[cdfpp_dep], + cpp_args : flags, + install: false, + link_args : flags, + build_by_default: meson.get_compiler('cpp').get_id() == 'emscripten', + extra_files : ['wasm.txt', 'wacdfpp.html'] + ) + +js_wrapper = custom_target('js_wrapper', + input : lib_wacdfpp, + output : 'wacdfpp.js', + command : [ 'emcc', '-lembind', '-sFETCH=1', '-sWASM=2', '--bind', '-sALLOW_MEMORY_GROWTH', '-sASYNCIFY', '-o', '@OUTPUT@', '-Wl,--whole-archive','@INPUT@', '-Wl,--no-whole-archive'], + build_by_default: true +) + +fs.copyfile('wacdfpp.html', 'wacdfpp.html') diff --git a/wacdfpp/wacdfpp.cpp b/wacdfpp/wacdfpp.cpp new file mode 100644 index 0000000..e5bbd26 --- /dev/null +++ b/wacdfpp/wacdfpp.cpp @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include +#if __has_include() +#include +#include +#include +#else +#define EMSCRIPTEN_KEEPALIVE +#define EMSCRIPTEN_EXPORT(x) x +#endif + + +EMSCRIPTEN_KEEPALIVE +emscripten::val count_variables(std::string url) +{ + struct fetch_data + { + bool done = false; + std::vector data; + }; + emscripten_fetch_attr_t attr; + emscripten_fetch_attr_init(&attr); + strcpy(attr.requestMethod, "GET"); + attr.attributes = EMSCRIPTEN_FETCH_LOAD_TO_MEMORY; + attr.userData = new fetch_data; + attr.onsuccess = [](emscripten_fetch_t* fetch) + { + auto data = static_cast(fetch->userData); + data->data = std::vector(fetch->data, fetch->data + fetch->numBytes); + data->done = true; + emscripten_fetch_close(fetch); + }; + attr.onerror = [](emscripten_fetch_t* fetch) + { + auto data = static_cast(fetch->userData); + data->done = true; + emscripten_fetch_close(fetch); + }; + emscripten_fetch(&attr, url.c_str()); + while (!static_cast(attr.userData)->done) + { + emscripten_sleep(10); + } + auto data = static_cast(attr.userData); + if (auto cdf_file = cdf::io::load(data->data); cdf_file) + { + std::cout << "Variables: " << std::size(cdf_file->variables) << "\n"; + auto sz = std::size(cdf_file->variables); + delete data; + return emscripten::val(sz); + } + return emscripten::val(-1); +} + + +EMSCRIPTEN_KEEPALIVE +int my_cdf_test() +{ + return 42; +} + + +#ifdef __EMSCRIPTEN__ +EMSCRIPTEN_BINDINGS(cdfppjs) +{ + emscripten::function("my_cdf_test", &my_cdf_test); + emscripten::function("count_variables", &count_variables); +} +#endif diff --git a/wacdfpp/wacdfpp.html b/wacdfpp/wacdfpp.html new file mode 100644 index 0000000..d0fc824 --- /dev/null +++ b/wacdfpp/wacdfpp.html @@ -0,0 +1,48 @@ + + + + +
+

+ + + +

+
+ + + + + + diff --git a/wacdfpp/wasm.txt b/wacdfpp/wasm.txt new file mode 100644 index 0000000..a12263d --- /dev/null +++ b/wacdfpp/wasm.txt @@ -0,0 +1,23 @@ +[binaries] +c = 'emcc' +cpp = 'em++' +ar = 'emar' +exe_wrapper = 'node' + +[built-in options] +c_args = [] +c_link_args = ['-sEXPORT_ALL=1', '-sWASM=2', '-sMODULARIZE', '-sEXPORTED_RUNTIME_METHODS=ccall'] +cpp_args = [] +cpp_link_args = [] + + +[properties] +# Emscripten always needs an exe wrapper. Again, +# maybe Meson could just know this. +needs_exe_wrapper = true + +[host_machine] +system = 'wasm' +cpu_family = 'wasm' +cpu = 'wasm' +endian = 'little'