From 3c318d6771ed068409e6965bae54af7cb498f5d6 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Tue, 2 Feb 2021 14:04:27 +0100 Subject: [PATCH] Add a very simple test program Not quite a unit test, it looks more like an example but still something. --- include/wrenpp/vm.hpp | 2 + meson.build | 3 ++ src/dynafunc_maker.cpp | 4 ++ src/dynafunc_maker.hpp | 3 ++ src/vm.cpp | 4 ++ test/meson.build | 1 + test/unit/main.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++ test/unit/meson.build | 7 ++++ 8 files changed, 119 insertions(+) create mode 100644 test/meson.build create mode 100644 test/unit/main.cpp create mode 100644 test/unit/meson.build diff --git a/include/wrenpp/vm.hpp b/include/wrenpp/vm.hpp index c22e8e4..8be8d7b 100644 --- a/include/wrenpp/vm.hpp +++ b/include/wrenpp/vm.hpp @@ -104,6 +104,8 @@ namespace wren { void set_user_data (std::nullptr_t); bool has_user_data() const; + std::size_t dynafunc_byte_size() const; + private: struct LocalData; diff --git a/meson.build b/meson.build index 7e07d26..da0ceed 100644 --- a/meson.build +++ b/meson.build @@ -68,3 +68,6 @@ wrenpp_dep = declare_dependency( if get_option('build_examples') subdir('examples') endif +if get_option('build_testing') + subdir('test') +endif diff --git a/src/dynafunc_maker.cpp b/src/dynafunc_maker.cpp index b7b251b..2440a8f 100644 --- a/src/dynafunc_maker.cpp +++ b/src/dynafunc_maker.cpp @@ -100,6 +100,10 @@ namespace wren { m_used_bytes = m_page_size; } + std::size_t DynafuncMaker::total_memory() const { + return m_pages.size() * m_page_size; + } + unsigned char* DynafuncMaker::allocate_chunk() { if (m_page_size - m_used_bytes < g_dynafunc_len) { unique_ptr_free_t page(std::aligned_alloc(m_page_size, m_page_size)); diff --git a/src/dynafunc_maker.hpp b/src/dynafunc_maker.hpp index b32a0bf..f2ca42b 100644 --- a/src/dynafunc_maker.hpp +++ b/src/dynafunc_maker.hpp @@ -18,6 +18,7 @@ #pragma once #include +#include namespace wren { class VM; @@ -31,6 +32,8 @@ namespace wren { void* make (VM* vm, foreign_method_t cb); void clear() noexcept; + std::size_t total_memory() const; + private: unsigned char* allocate_chunk(); diff --git a/src/vm.cpp b/src/vm.cpp index 3acd89a..00ed56c 100644 --- a/src/vm.cpp +++ b/src/vm.cpp @@ -271,6 +271,10 @@ namespace wren { return nullptr != m_local->user_data; } + std::size_t VM::dynafunc_byte_size() const { + return m_local->dynafunc.total_memory(); + } + void VM::ensure_slots (int num_slots) { wrenEnsureSlots(m_local->wvm, num_slots); } diff --git a/test/meson.build b/test/meson.build new file mode 100644 index 0000000..082b746 --- /dev/null +++ b/test/meson.build @@ -0,0 +1 @@ +subdir('unit') diff --git a/test/unit/main.cpp b/test/unit/main.cpp new file mode 100644 index 0000000..b5c91e8 --- /dev/null +++ b/test/unit/main.cpp @@ -0,0 +1,95 @@ +#include "wrenpp/vm_fun.hpp" +#include "wrenpp/def_configuration.hpp" +#include +#include +#include +#include +#include + +namespace { + const constexpr char g_script[] = "" +R"script(class Maths { + foreign static mul(a,b) + foreign static div(a,b) + foreign static sum(a,b) + foreign static sub(a,b) +} + +var my_mul = Maths.mul(Maths.mul(2, 2), Maths.mul(3, 2)) - 4 +System.print("my_mul = %(my_mul) (expected: 20)") + +var my_sum = Maths.sum(Maths.sum(3, 4), Maths.sum(5, -1)) + 8 +System.print("my_sum = %(my_sum) (expected: 19)") + +var my_sub = Maths.sub(Maths.sub(8, 5), Maths.sub(20, 19)) + 1 +System.print("my_sub = %(my_sub) (expected: 3)") + +)script"; + +class MyConfig : public wren::DefConfiguration { + typedef std::map MethodMap; +public: + wren::foreign_method_t foreign_method_fn( + wren::VM* vm, + const char* module_ptr, + const char* class_name_ptr, + bool is_static, + const char* signature_ptr + ) { + auto key = to_map_key(module_ptr, class_name_ptr, signature_ptr); + auto it_found = m_foreign_methods.find(key); + if (m_foreign_methods.end() != it_found) + return it_found->second; + else + return nullptr; + } + + void register_foreign_method ( + std::string_view module_name, + std::string_view class_name, + std::string_view func_name, + wren::foreign_method_t fn + ) { + m_foreign_methods[to_map_key(module_name, class_name, func_name)] = fn; + } + +private: + static std::string to_map_key( + std::string_view module_name, + std::string_view class_name, + std::string_view func_name + ) { + std::string key; + key.reserve(module_name.size() + class_name.size() + func_name.size() + 4); + key.append(module_name); + key += "::"; + key.append(class_name); + key += "::"; + key.append(func_name); + return key; + } + + MethodMap m_foreign_methods; +}; + +template +void do_op(wren::VM& vm) { + using wren::get; + set(vm, 0, Op()(get(vm, 1), get(vm, 2))); +} +} //unnamed namespace + +int main() { + MyConfig config; + + config.register_foreign_method("main", "Maths", "sum(_,_)", &do_op>); + config.register_foreign_method("main", "Maths", "sub(_,_)", &do_op>); + config.register_foreign_method("main", "Maths", "mul(_,_)", &do_op>); + config.register_foreign_method("main", "Maths", "div(_,_)", &do_op>); + + wren::VM vm(&config, nullptr); + vm.interpret("main", g_script); + + std::cout << "Dynafunc mem usage: " << vm.dynafunc_byte_size() << " bytes\n"; + return 0; +} diff --git a/test/unit/meson.build b/test/unit/meson.build new file mode 100644 index 0000000..d5d21ec --- /dev/null +++ b/test/unit/meson.build @@ -0,0 +1,7 @@ +exec_target = executable(meson.project_name() + '_unit', + 'main.cpp', + install: false, + dependencies: [wrenpp_dep], +) + +test(meson.project_name() + ' unit test', exec_target)