From 13c929b6dee9fb882ae9e92b680779d428a05607 Mon Sep 17 00:00:00 2001 From: Luis Michaelis Date: Sat, 5 Aug 2023 15:41:30 +0200 Subject: [PATCH 1/3] [#80] feat(vm): add dedicated `func` type and symbol resolver --- include/phoenix/vm.hh | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/include/phoenix/vm.hh b/include/phoenix/vm.hh index a214b62b..eef2db9d 100644 --- a/include/phoenix/vm.hh +++ b/include/phoenix/vm.hh @@ -17,6 +17,10 @@ namespace phoenix { struct naked_call {}; + struct func { + symbol* value; + }; + template static constexpr bool is_instance_ptr_v = false; @@ -625,7 +629,7 @@ namespace phoenix { PHOENIX_API void register_default_external_custom(const std::function& callback); - PHOENIX_API void register_access_trap(const std::function &callback); + PHOENIX_API void register_access_trap(const std::function& callback); /// \brief Registers a function to be called when script execution fails. /// @@ -726,9 +730,9 @@ namespace phoenix { } else if constexpr (std::is_same_v) { if (defined[i]->type() != datatype::float_) throw illegal_external_param(defined[i], "float", i + 1); - } else if constexpr (std::is_same_v || std::is_same_v) { + } else if constexpr (std::is_same_v || std::is_same_v || std::is_same_v) { if (defined[i]->type() != datatype::integer && defined[i]->type() != datatype::function) - throw illegal_external_param(defined[i], "int", i + 1); + throw illegal_external_param(defined[i], "int/func", i + 1); } else if constexpr (std::is_same_v) { if (defined[i]->type() != datatype::string) throw illegal_external_param(defined[i], "string", i + 1); @@ -750,7 +754,7 @@ namespace phoenix { template typename std::enable_if || std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v || - std::is_same_v || is_raw_instance_ptr_v, + std::is_same_v || is_raw_instance_ptr_v || std::is_same_v, T>::type pop_value_for_external() { if constexpr (is_instance_ptr_v) { @@ -799,6 +803,22 @@ namespace phoenix { return pop_string(); } else if constexpr (std::is_same_v) { return std::get<0>(pop_reference()); + } else if constexpr (std::is_same_v) { + auto symbol_id = static_cast(pop_int()); + + auto* sym = find_symbol_by_index(symbol_id); + while (sym != nullptr && sym->type() == datatype::function && !sym->is_const()) { + symbol_id = static_cast(sym->get_int()); + sym = find_symbol_by_index(symbol_id); + } + + if (sym != nullptr && sym->type() != datatype::function) { + PX_LOGW("Failed to resolve external function parameter (func): Reference chain leads to a " + "non-function symbol!"); + return func {nullptr}; + } + + return func {sym}; } else { throw vm_exception {"pop: unsupported stack frame type"}; } @@ -814,7 +834,7 @@ namespace phoenix { template typename std::enable_if || std::is_convertible_v || std::is_convertible_v || std::is_same_v || - std::is_same_v, + std::is_same_v || std::is_same_v, void>::type push_value_from_external(T v) { // clang-format on if constexpr (is_instance_ptr_v) { @@ -823,6 +843,8 @@ namespace phoenix { push_float(static_cast(v)); } else if constexpr (std::is_convertible_v) { push_int(static_cast(v)); + } else if constexpr (std::is_same_v) { + push_int(static_cast(v.value->index())); } else if constexpr (std::is_same_v || std::is_same_v) { push_string(v); } else { @@ -854,7 +876,8 @@ namespace phoenix { template typename std::enable_if || std::is_same_v || std::is_same_v || - std::is_same_v || std::is_same_v, + std::is_same_v || std::is_same_v || + std::is_same_v, void>::type check_call_return_type(const symbol* sym) { if constexpr (is_instance_ptr_v) { @@ -863,7 +886,7 @@ namespace phoenix { } else if constexpr (std::is_same_v) { if (sym->rtype() != datatype::float_) throw vm_exception {"invalid return type for function " + sym->name()}; - } else if constexpr (std::is_same_v) { + } else if constexpr (std::is_same_v || std::is_same_v) { if (sym->rtype() != datatype::integer && sym->rtype() != datatype::function) throw vm_exception {"invalid return type for function " + sym->name()}; } else if constexpr (std::is_same_v) { From 45359674f6fd224279eb47e622755f53a7d428cc Mon Sep 17 00:00:00 2001 From: Luis Michaelis Date: Sat, 5 Aug 2023 15:42:16 +0200 Subject: [PATCH 2/3] lint(*): reformat code --- include/phoenix/script.hh | 2 +- source/vm.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/phoenix/script.hh b/include/phoenix/script.hh index e3e0409b..06b53932 100644 --- a/include/phoenix/script.hh +++ b/include/phoenix/script.hh @@ -46,7 +46,7 @@ namespace phoenix { static constexpr auto external = 1U << 3U; ///< The symbol refers to an external function. static constexpr auto merged = 1U << 4U; ///< Unused. static constexpr auto access_trap = 1U << 6U; ///< VM should call trap callback, when symbol accessed. - } // namespace symbol_flag + } // namespace symbol_flag /// \brief All opcodes supported by the daedalus interpreter. /// diff --git a/source/vm.cc b/source/vm.cc index dc55e3a8..dec717ee 100644 --- a/source/vm.cc +++ b/source/vm.cc @@ -665,7 +665,7 @@ namespace phoenix { _m_default_external = callback; } - void vm::register_access_trap(const std::function &callback) { + void vm::register_access_trap(const std::function& callback) { _m_access_trap = callback; } From c57d1392b16520643d51702c58dd5209ebcf40d9 Mon Sep 17 00:00:00 2001 From: Luis Michaelis Date: Sat, 5 Aug 2023 15:43:57 +0200 Subject: [PATCH 3/3] ci(lint): also run on `pull_request` --- .github/workflows/lint.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index b38ba3f3..03f32ab9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,5 +1,7 @@ name: 'Lint' -on: 'push' +on: + - 'push' + - 'pull_request' jobs: format: name: 'Formatting'