diff --git a/.gitignore b/.gitignore index d06d069a5..f20eb9430 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ _deps Brewfile.lock.json .DS_Store .cache +/bindings/*/build diff --git a/CMakeLists.txt b/CMakeLists.txt index 37f1c9480..2ad329d18 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ endif() if(PROJECT_IS_TOP_LEVEL) noa_target_clang_format(SOURCES + bindings/*.cc src/*.h src/*.cc benchmark/*.h benchmark/*.cc test/*.h test/*.cc) diff --git a/bindings/webassembly/Makefile b/bindings/webassembly/Makefile new file mode 100644 index 000000000..1bd85dc1d --- /dev/null +++ b/bindings/webassembly/Makefile @@ -0,0 +1,26 @@ +EMCC = emcc +MKDIR = mkdir +NODE = node + +CXX_FLAGS = -O3 -std=c++20 -flto + +all: compile test +compile: build/jsontoolkit.js .always +test: test.js .always + $(NODE) $< + +build: + $(MKDIR) $@ +build/json: | build + $(MKDIR) $@ + +build/json/%.o: ../../src/json/%.cc | build/json + $(EMCC) $(CXX_FLAGS) -o $@ $< -I../../src/json/include -c + +build/jsontoolkit.js: module.cc build/json/json.o build/json/json_value.o | build + $(EMCC) $(CXX_FLAGS) -o $@ $^ -I../../src/json/include -lembind \ + -s EVAL_CTORS=2 -s EXPORT_NAME=jsontoolkit \ + -s WASM=1 -s NO_EXIT_RUNTIME=1 -s MODULARIZE=1 \ + -s EXPORT_ES6=1 -s ENVIRONMENT=node + +.always: diff --git a/bindings/webassembly/module.cc b/bindings/webassembly/module.cc new file mode 100644 index 000000000..a18ba0fd0 --- /dev/null +++ b/bindings/webassembly/module.cc @@ -0,0 +1,17 @@ +#include + +// See https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html +#include + +#include // EXIT_SUCCESS +#include // std::cout + +static auto hello() -> void { + const sourcemeta::jsontoolkit::JSON document{"Hello World"}; + sourcemeta::jsontoolkit::stringify(document, std::cout); + std::cout << std::endl; +} + +EMSCRIPTEN_BINDINGS(jsontoolkit) { + emscripten::function("hello", &hello); +} diff --git a/bindings/webassembly/test.js b/bindings/webassembly/test.js new file mode 100644 index 000000000..edae5cf8d --- /dev/null +++ b/bindings/webassembly/test.js @@ -0,0 +1,4 @@ +import wrapper from './build/jsontoolkit.js'; +wrapper().then((jsontoolkit) => { + jsontoolkit.hello(); +}); diff --git a/src/json/include/sourcemeta/jsontoolkit/json.h b/src/json/include/sourcemeta/jsontoolkit/json.h index 19fd1b970..d1b850e3a 100644 --- a/src/json/include/sourcemeta/jsontoolkit/json.h +++ b/src/json/include/sourcemeta/jsontoolkit/json.h @@ -1,7 +1,11 @@ #ifndef SOURCEMETA_JSONTOOLKIT_JSON_H_ #define SOURCEMETA_JSONTOOLKIT_JSON_H_ +#ifdef __EMSCRIPTEN__ +#define SOURCEMETA_JSONTOOLKIT_JSON_EXPORT +#else #include "json_export.h" +#endif #include #include diff --git a/src/json/include/sourcemeta/jsontoolkit/json_error.h b/src/json/include/sourcemeta/jsontoolkit/json_error.h index 08b90cab2..133d79a68 100644 --- a/src/json/include/sourcemeta/jsontoolkit/json_error.h +++ b/src/json/include/sourcemeta/jsontoolkit/json_error.h @@ -1,7 +1,11 @@ #ifndef SOURCEMETA_JSONTOOLKIT_JSON_ERROR_H_ #define SOURCEMETA_JSONTOOLKIT_JSON_ERROR_H_ +#ifdef __EMSCRIPTEN__ +#define SOURCEMETA_JSONTOOLKIT_JSON_EXPORT +#else #include "json_export.h" +#endif #include // std::uint64_t #include // std::exception diff --git a/src/json/include/sourcemeta/jsontoolkit/json_value.h b/src/json/include/sourcemeta/jsontoolkit/json_value.h index e2142b02d..44ed5a23b 100644 --- a/src/json/include/sourcemeta/jsontoolkit/json_value.h +++ b/src/json/include/sourcemeta/jsontoolkit/json_value.h @@ -1,7 +1,11 @@ #ifndef SOURCEMETA_JSONTOOLKIT_JSON_VALUE_H_ #define SOURCEMETA_JSONTOOLKIT_JSON_VALUE_H_ +#ifdef __EMSCRIPTEN__ +#define SOURCEMETA_JSONTOOLKIT_JSON_EXPORT +#else #include "json_export.h" +#endif #include #include