mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
Spicy: Port over to Spicy's new tuple representation.
Includes a fix for supporting CMake 4.0.
This commit is contained in:
parent
71305b0009
commit
94ddd7f411
9 changed files with 111 additions and 141 deletions
|
@ -18,6 +18,22 @@ if (WIN32)
|
|||
set(CMAKE_TOOLCHAIN_FILE ${_toolchain} CACHE STRING "Vcpkg toolchain file")
|
||||
endif ()
|
||||
|
||||
if (APPLE AND CMAKE_VERSION VERSION_GREATER_EQUAL 4.0.0 AND NOT CMAKE_OSX_SYSROOT)
|
||||
# Spicy needs having CMAKE_OSX_SYSROOT point to the macOS SDK
|
||||
# path, but starting with CMake 4.0 CMAKE_OSX_SYSROOT is not set
|
||||
# automatically anymore. So we follow the guidance from the CMake 4.0
|
||||
# release notes here:
|
||||
#
|
||||
# Builds targeting macOS no longer choose any SDK or pass an "-isysroot"
|
||||
# flag to the compiler by default. [...] users must now specify
|
||||
# "-DCMAKE_OSX_SYSROOT=macosx" when configuring their build.
|
||||
#
|
||||
# Note that this needs to happen before the project() call below, meaning
|
||||
# we cannot rely on the corresponding code inside the Spicy CMake
|
||||
# configuration.
|
||||
set(CMAKE_OSX_SYSROOT "macosx")
|
||||
endif ()
|
||||
|
||||
project(Zeek C CXX)
|
||||
|
||||
# We want to set ENABLE_DEBUG to ON by default if the build type is Debug.
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 1650d875a87accce61bb9d8cde7f51f033280acf
|
||||
Subproject commit 26421d12f15d8b16ba6f385bbd47394cc9f9a0df
|
|
@ -33,7 +33,7 @@ declare public BroType event_arg_type(EventHandlerPtr handler, uint<64> idx) &cx
|
|||
declare public Val to_val(any x, BroType target) &cxxname="zeek::spicy::rt::to_val" &have_prototype;
|
||||
|
||||
declare public BroType create_base_type(ZeekTypeTag tag) &cxxname="zeek::spicy::rt::create_base_type" &have_prototype;
|
||||
declare public BroType create_enum_type(string ns, string id, vector<tuple<string, int<64>>> labels) &cxxname="zeek::spicy::rt::create_enum_type" &have_prototype;
|
||||
declare public BroType create_enum_type(string ns, string id, set<tuple<string, int<64>>> labels) &cxxname="zeek::spicy::rt::create_enum_type" &have_prototype;
|
||||
declare public BroType create_record_type(string ns, string id, vector<RecordField> fields) &cxxname="zeek::spicy::rt::create_record_type" &have_prototype;
|
||||
declare public RecordField create_record_field(string id, BroType type_, bool is_optional, bool is_log) &cxxname="zeek::spicy::rt::create_record_field" &have_prototype;
|
||||
declare public BroType create_table_type(BroType key, optional<BroType> value = Null) &cxxname="zeek::spicy::rt::create_table_type" &have_prototype;
|
||||
|
|
|
@ -691,7 +691,7 @@ void Manager::InitPostScript() {
|
|||
// event that will do it for us through a predefined handler.
|
||||
zeek::Args vals = Args();
|
||||
vals.emplace_back(tag.AsVal());
|
||||
vals.emplace_back(zeek::spicy::rt::to_val(port_, base_type(TYPE_PORT)));
|
||||
vals.emplace_back(zeek::spicy::rt::to_val(port_, &hilti::rt::type_info::port, base_type(TYPE_PORT)));
|
||||
EventHandlerPtr handler = event_registry->Register("spicy_analyzer_for_port");
|
||||
event_mgr.Enqueue(handler, std::move(vals));
|
||||
};
|
||||
|
|
|
@ -108,7 +108,8 @@ std::string hilti::rt::detail::adl::to_string(const zeek::spicy::rt::ZeekTypeTag
|
|||
|
||||
TypePtr rt::create_enum_type(
|
||||
const std::string& ns, const std::string& id,
|
||||
const hilti::rt::Vector<std::tuple<std::string, hilti::rt::integer::safe<int64_t>>>& labels) {
|
||||
const hilti::rt::Set<std::tuple<std::optional<std::string>, std::optional<hilti::rt::integer::safe<int64_t>>>>&
|
||||
labels) {
|
||||
auto _ = hilti::rt::profiler::start("zeek/rt/create_enum_type");
|
||||
|
||||
if ( auto t = findType(TYPE_ENUM, ns, id) )
|
||||
|
@ -117,13 +118,14 @@ TypePtr rt::create_enum_type(
|
|||
auto etype = make_intrusive<EnumType>(ns + "::" + id);
|
||||
|
||||
for ( auto [lid, lval] : labels ) {
|
||||
auto name = ::hilti::rt::fmt("%s_%s", id, lid);
|
||||
assert(lid && lval);
|
||||
auto name = ::hilti::rt::fmt("%s_%s", id, *lid);
|
||||
|
||||
if ( lval == -1 )
|
||||
if ( *lval == -1 )
|
||||
// Zeek's enum can't be negative, so swap in max_int for our Undef.
|
||||
lval = std::numeric_limits<::zeek_int_t>::max();
|
||||
|
||||
etype->AddName(ns, name.c_str(), lval, true);
|
||||
etype->AddName(ns, name.c_str(), *lval, true);
|
||||
}
|
||||
|
||||
return std::move(etype);
|
||||
|
@ -393,7 +395,7 @@ std::string rt::uid() {
|
|||
throw ValueUnavailable("uid() not available in current context");
|
||||
}
|
||||
|
||||
std::tuple<hilti::rt::Address, hilti::rt::Port, hilti::rt::Address, hilti::rt::Port> rt::conn_id() {
|
||||
hilti::rt::Tuple<hilti::rt::Address, hilti::rt::Port, hilti::rt::Address, hilti::rt::Port> rt::conn_id() {
|
||||
auto _ = hilti::rt::profiler::start("zeek/rt/conn_id");
|
||||
|
||||
static auto convert_address = [](const IPAddr& zaddr) -> hilti::rt::Address {
|
||||
|
@ -424,10 +426,10 @@ std::tuple<hilti::rt::Address, hilti::rt::Port, hilti::rt::Address, hilti::rt::P
|
|||
if ( auto cookie = static_cast<Cookie*>(hilti::rt::context::cookie()) ) {
|
||||
if ( auto c = cookie->protocol ) {
|
||||
const auto* conn = c->analyzer->Conn();
|
||||
return std::make_tuple(convert_address(conn->OrigAddr()),
|
||||
convert_port(conn->OrigPort(), conn->ConnTransport()),
|
||||
convert_address(conn->RespAddr()),
|
||||
convert_port(conn->RespPort(), conn->ConnTransport()));
|
||||
return hilti::rt::tuple::make(convert_address(conn->OrigAddr()),
|
||||
convert_port(conn->OrigPort(), conn->ConnTransport()),
|
||||
convert_address(conn->RespAddr()),
|
||||
convert_port(conn->RespPort(), conn->ConnTransport()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,11 @@
|
|||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include <hilti/rt/deferred-expression.h>
|
||||
#include <hilti/rt/exception.h>
|
||||
#include <hilti/rt/extension-points.h>
|
||||
#include <hilti/rt/fmt.h>
|
||||
#include <hilti/rt/profiler.h>
|
||||
#include <hilti/rt/type-info.h>
|
||||
#include <hilti/rt/types/all.h>
|
||||
#include <hilti/rt/util.h>
|
||||
|
||||
|
@ -78,6 +79,8 @@ public:
|
|||
: TypeMismatch(hilti::rt::fmt("Event parameter mismatch, %s", msg)) {}
|
||||
ParameterMismatch(std::string_view have, const TypePtr& want, std::string_view location = "")
|
||||
: ParameterMismatch(_fmt(have, want)) {}
|
||||
ParameterMismatch(const hilti::rt::TypeInfo& have, const TypePtr& want, std::string_view location = "")
|
||||
: ParameterMismatch(_fmt(have.display, want)) {}
|
||||
|
||||
private:
|
||||
static std::string _fmt(const std::string_view& have, const TypePtr& want) {
|
||||
|
@ -169,7 +172,8 @@ extern TypePtr create_base_type(ZeekTypeTag tag);
|
|||
|
||||
extern TypePtr create_enum_type(
|
||||
const std::string& ns, const std::string& id,
|
||||
const hilti::rt::Vector<std::tuple<std::string, hilti::rt::integer::safe<int64_t>>>& labels);
|
||||
const hilti::rt::Set<std::tuple<std::optional<std::string>, std::optional<hilti::rt::integer::safe<int64_t>>>>&
|
||||
labels);
|
||||
|
||||
struct RecordField {
|
||||
std::string id; /**< name of record field */
|
||||
|
@ -279,7 +283,7 @@ std::string uid();
|
|||
/**
|
||||
* Returns the current connection's ID tuple.
|
||||
*/
|
||||
std::tuple<hilti::rt::Address, hilti::rt::Port, hilti::rt::Address, hilti::rt::Port> conn_id();
|
||||
hilti::rt::Tuple<hilti::rt::Address, hilti::rt::Port, hilti::rt::Address, hilti::rt::Port> conn_id();
|
||||
|
||||
/** Instructs to Zeek to flip the directionality of the current connecction. */
|
||||
void flip_roles();
|
||||
|
@ -488,39 +492,37 @@ void forward_packet(const hilti::rt::integer::safe<uint32_t>& identifier);
|
|||
hilti::rt::Time network_time();
|
||||
|
||||
// Forward-declare to_val() functions.
|
||||
template<typename T, typename std::enable_if_t<hilti::rt::is_tuple<T>::value>* = nullptr>
|
||||
ValPtr to_val(const T& t, const TypePtr& target);
|
||||
template<typename... Ts>
|
||||
inline ValPtr to_val(const hilti::rt::Bitfield<Ts...>& v, const TypePtr& target);
|
||||
ValPtr to_val(const hilti::rt::Tuple<Ts...>& t, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
template<typename... Ts>
|
||||
inline ValPtr to_val(const hilti::rt::Bitfield<Ts...>& v, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
template<typename T, typename std::enable_if_t<std::is_base_of<::hilti::rt::trait::isStruct, T>::value>* = nullptr>
|
||||
ValPtr to_val(const T& t, const TypePtr& target);
|
||||
ValPtr to_val(const T& t, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<typename T::Value>::value>* = nullptr>
|
||||
ValPtr to_val(const T& t, const TypePtr& target);
|
||||
ValPtr to_val(const T& t, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<T>::value>* = nullptr>
|
||||
ValPtr to_val(const T& t, const TypePtr& target);
|
||||
ValPtr to_val(const T& t, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
template<typename K, typename V>
|
||||
ValPtr to_val(const hilti::rt::Map<K, V>& s, const TypePtr& target);
|
||||
ValPtr to_val(const hilti::rt::Map<K, V>& s, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
template<typename T>
|
||||
ValPtr to_val(const hilti::rt::Set<T>& s, const TypePtr& target);
|
||||
ValPtr to_val(const hilti::rt::Set<T>& s, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
template<typename T, typename Allocator>
|
||||
ValPtr to_val(const hilti::rt::Vector<T, Allocator>& v, const TypePtr& target);
|
||||
ValPtr to_val(const hilti::rt::Vector<T, Allocator>& v, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
template<typename T>
|
||||
ValPtr to_val(const std::optional<T>& t, const TypePtr& target);
|
||||
template<typename T, typename E>
|
||||
ValPtr to_val(const hilti::rt::DeferredExpression<T, E>& t, const TypePtr& target);
|
||||
ValPtr to_val(const std::optional<T>& t, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
template<typename T>
|
||||
ValPtr to_val(hilti::rt::integer::safe<T> i, const TypePtr& target);
|
||||
ValPtr to_val(hilti::rt::integer::safe<T> i, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
template<typename T>
|
||||
ValPtr to_val(const hilti::rt::ValueReference<T>& t, const TypePtr& target);
|
||||
ValPtr to_val(const hilti::rt::ValueReference<T>& t, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
|
||||
inline ValPtr to_val(const hilti::rt::Bool& b, const TypePtr& target);
|
||||
inline ValPtr to_val(const hilti::rt::Address& d, const TypePtr& target);
|
||||
inline ValPtr to_val(const hilti::rt::Bytes& b, const TypePtr& target);
|
||||
inline ValPtr to_val(const hilti::rt::Interval& t, const TypePtr& target);
|
||||
inline ValPtr to_val(const hilti::rt::Port& d, const TypePtr& target);
|
||||
inline ValPtr to_val(const hilti::rt::Time& t, const TypePtr& target);
|
||||
inline ValPtr to_val(const std::string& s, const TypePtr& target);
|
||||
inline ValPtr to_val(double r, const TypePtr& target);
|
||||
inline ValPtr to_val(const hilti::rt::Bool& b, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
inline ValPtr to_val(const hilti::rt::Address& d, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
inline ValPtr to_val(const hilti::rt::Bytes& b, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
inline ValPtr to_val(const hilti::rt::Interval& t, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
inline ValPtr to_val(const hilti::rt::Port& d, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
inline ValPtr to_val(const hilti::rt::Time& t, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
inline ValPtr to_val(const std::string& s, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
inline ValPtr to_val(double r, const hilti::rt::TypeInfo* ti, const TypePtr& target);
|
||||
|
||||
/**
|
||||
* Converts a Spicy-side optional value to a Zeek value. This assumes the
|
||||
|
@ -528,33 +530,18 @@ inline ValPtr to_val(double r, const TypePtr& target);
|
|||
* returned with ref count +1.
|
||||
*/
|
||||
template<typename T>
|
||||
inline ValPtr to_val(const std::optional<T>& t, const TypePtr& target) {
|
||||
inline ValPtr to_val(const std::optional<T>& t, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( t.has_value() )
|
||||
return to_val(hilti::rt::optional::value(t), target);
|
||||
return to_val(hilti::rt::optional::value(t), nullptr, target);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Spicy-side DeferredExpression<T,E> value to a Zeek value. Such
|
||||
* result values are returned by the ``.?`` operator. If the result is not
|
||||
* set, this will convert into nullptr (which the tuple-to-record to_val()
|
||||
* picks up on).
|
||||
*/
|
||||
template<typename T, typename E>
|
||||
inline ValPtr to_val(const hilti::rt::DeferredExpression<T, E>& t, const TypePtr& target) {
|
||||
try {
|
||||
return to_val(t(), target);
|
||||
} catch ( const hilti::rt::AttributeNotSet& ) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a Spicy-side string to a Zeek value. The result is returned with
|
||||
* ref count +1.
|
||||
*/
|
||||
inline ValPtr to_val(const std::string& s, const TypePtr& target) {
|
||||
inline ValPtr to_val(const std::string& s, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_STRING )
|
||||
throw ParameterMismatch("string", target);
|
||||
|
||||
|
@ -565,7 +552,7 @@ inline ValPtr to_val(const std::string& s, const TypePtr& target) {
|
|||
* Converts a Spicy-side bytes instance to a Zeek value. The result is returned with
|
||||
* ref count +1.
|
||||
*/
|
||||
inline ValPtr to_val(const hilti::rt::Bytes& b, const TypePtr& target) {
|
||||
inline ValPtr to_val(const hilti::rt::Bytes& b, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_STRING )
|
||||
throw ParameterMismatch("string", target);
|
||||
|
||||
|
@ -577,7 +564,7 @@ inline ValPtr to_val(const hilti::rt::Bytes& b, const TypePtr& target) {
|
|||
* returned with ref count +1.
|
||||
*/
|
||||
template<typename T>
|
||||
inline ValPtr to_val(hilti::rt::integer::safe<T> i, const TypePtr& target) {
|
||||
inline ValPtr to_val(hilti::rt::integer::safe<T> i, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
ValPtr v = nullptr;
|
||||
if constexpr ( std::is_unsigned<T>::value ) {
|
||||
if ( target->Tag() == TYPE_COUNT )
|
||||
|
@ -604,9 +591,9 @@ inline ValPtr to_val(hilti::rt::integer::safe<T> i, const TypePtr& target) {
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
ValPtr to_val(const hilti::rt::ValueReference<T>& t, const TypePtr& target) {
|
||||
ValPtr to_val(const hilti::rt::ValueReference<T>& t, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( auto* x = t.get() )
|
||||
return to_val(*x, target);
|
||||
return to_val(*x, nullptr, target);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -615,7 +602,7 @@ ValPtr to_val(const hilti::rt::ValueReference<T>& t, const TypePtr& target) {
|
|||
* Converts a Spicy-side signed bool to a Zeek value. The result is
|
||||
* returned with ref count +1.
|
||||
*/
|
||||
inline ValPtr to_val(const hilti::rt::Bool& b, const TypePtr& target) {
|
||||
inline ValPtr to_val(const hilti::rt::Bool& b, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_BOOL )
|
||||
throw ParameterMismatch("bool", target);
|
||||
|
||||
|
@ -626,7 +613,7 @@ inline ValPtr to_val(const hilti::rt::Bool& b, const TypePtr& target) {
|
|||
* Converts a Spicy-side real to a Zeek value. The result is returned with
|
||||
* ref count +1.
|
||||
*/
|
||||
inline ValPtr to_val(double r, const TypePtr& target) {
|
||||
inline ValPtr to_val(double r, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_DOUBLE )
|
||||
throw ParameterMismatch("double", target);
|
||||
|
||||
|
@ -637,7 +624,7 @@ inline ValPtr to_val(double r, const TypePtr& target) {
|
|||
* Converts a Spicy-side address to a Zeek value. The result is returned with
|
||||
* ref count +1.
|
||||
*/
|
||||
inline ValPtr to_val(const hilti::rt::Address& d, const TypePtr& target) {
|
||||
inline ValPtr to_val(const hilti::rt::Address& d, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_ADDR )
|
||||
throw ParameterMismatch("addr", target);
|
||||
|
||||
|
@ -654,7 +641,7 @@ inline ValPtr to_val(const hilti::rt::Address& d, const TypePtr& target) {
|
|||
* Converts a Spicy-side address to a Zeek value. The result is returned with
|
||||
* ref count +1.
|
||||
*/
|
||||
inline ValPtr to_val(const hilti::rt::Port& p, const TypePtr& target) {
|
||||
inline ValPtr to_val(const hilti::rt::Port& p, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_PORT )
|
||||
throw ParameterMismatch("port", target);
|
||||
|
||||
|
@ -673,7 +660,7 @@ inline ValPtr to_val(const hilti::rt::Port& p, const TypePtr& target) {
|
|||
* Converts a Spicy-side time to a Zeek value. The result is returned with
|
||||
* ref count +1.
|
||||
*/
|
||||
inline ValPtr to_val(const hilti::rt::Interval& i, const TypePtr& target) {
|
||||
inline ValPtr to_val(const hilti::rt::Interval& i, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_INTERVAL )
|
||||
throw ParameterMismatch("interval", target);
|
||||
|
||||
|
@ -684,7 +671,7 @@ inline ValPtr to_val(const hilti::rt::Interval& i, const TypePtr& target) {
|
|||
* Converts a Spicy-side time to a Zeek value. The result is returned with
|
||||
* ref count +1.
|
||||
*/
|
||||
inline ValPtr to_val(const hilti::rt::Time& t, const TypePtr& target) {
|
||||
inline ValPtr to_val(const hilti::rt::Time& t, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_TIME )
|
||||
throw ParameterMismatch("time", target);
|
||||
|
||||
|
@ -696,14 +683,14 @@ inline ValPtr to_val(const hilti::rt::Time& t, const TypePtr& target) {
|
|||
* ref count +1.
|
||||
*/
|
||||
template<typename T, typename Allocator>
|
||||
inline ValPtr to_val(const hilti::rt::Vector<T, Allocator>& v, const TypePtr& target) {
|
||||
inline ValPtr to_val(const hilti::rt::Vector<T, Allocator>& v, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_VECTOR && target->Tag() != TYPE_LIST )
|
||||
throw ParameterMismatch("expected vector or list", target);
|
||||
|
||||
auto vt = cast_intrusive<VectorType>(target);
|
||||
auto zv = make_intrusive<VectorVal>(vt);
|
||||
for ( const auto& i : v )
|
||||
zv->Assign(zv->Size(), to_val(i, vt->Yield()));
|
||||
zv->Assign(zv->Size(), to_val(i, nullptr, vt->Yield()));
|
||||
|
||||
return std::move(zv);
|
||||
}
|
||||
|
@ -713,10 +700,7 @@ inline ValPtr to_val(const hilti::rt::Vector<T, Allocator>& v, const TypePtr& ta
|
|||
* ref count +1.
|
||||
*/
|
||||
template<typename K, typename V>
|
||||
inline ValPtr to_val(const hilti::rt::Map<K, V>& m, const TypePtr& target) {
|
||||
if constexpr ( hilti::rt::is_tuple<K>::value )
|
||||
throw ParameterMismatch("internal error: sets with tuples not yet supported in to_val()");
|
||||
|
||||
inline ValPtr to_val(const hilti::rt::Map<K, V>& m, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_TABLE )
|
||||
throw ParameterMismatch("map", target);
|
||||
|
||||
|
@ -730,8 +714,8 @@ inline ValPtr to_val(const hilti::rt::Map<K, V>& m, const TypePtr& target) {
|
|||
auto zv = make_intrusive<TableVal>(tt);
|
||||
|
||||
for ( const auto& i : m ) {
|
||||
auto k = to_val(i.first, tt->GetIndexTypes()[0]);
|
||||
auto v = to_val(i.second, tt->Yield());
|
||||
auto k = to_val(i.first, nullptr, tt->GetIndexTypes()[0]);
|
||||
auto v = to_val(i.second, nullptr, tt->Yield());
|
||||
zv->Assign(std::move(k), std::move(v));
|
||||
}
|
||||
|
||||
|
@ -743,7 +727,7 @@ inline ValPtr to_val(const hilti::rt::Map<K, V>& m, const TypePtr& target) {
|
|||
* ref count +1.
|
||||
*/
|
||||
template<typename T>
|
||||
inline ValPtr to_val(const hilti::rt::Set<T>& s, const TypePtr& target) {
|
||||
inline ValPtr to_val(const hilti::rt::Set<T>& s, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_TABLE )
|
||||
throw ParameterMismatch("set", target);
|
||||
|
||||
|
@ -754,15 +738,11 @@ inline ValPtr to_val(const hilti::rt::Set<T>& s, const TypePtr& target) {
|
|||
auto zv = make_intrusive<TableVal>(tt);
|
||||
|
||||
for ( const auto& i : s ) {
|
||||
if constexpr ( hilti::rt::is_tuple<T>::value )
|
||||
throw ParameterMismatch("internal error: sets with tuples not yet supported in to_val()");
|
||||
else {
|
||||
if ( tt->GetIndexTypes().size() != 1 )
|
||||
throw ParameterMismatch("set with non-tuple elements", target);
|
||||
if ( tt->GetIndexTypes().size() != 1 )
|
||||
throw ParameterMismatch("set with non-tuple elements", target);
|
||||
|
||||
auto idx = to_val(i, tt->GetIndexTypes()[0]);
|
||||
zv->Assign(std::move(idx), nullptr);
|
||||
}
|
||||
auto idx = to_val(i, nullptr, tt->GetIndexTypes()[0]);
|
||||
zv->Assign(std::move(idx), nullptr);
|
||||
}
|
||||
|
||||
return zv;
|
||||
|
@ -820,18 +800,11 @@ inline void set_record_field(RecordVal* rval, const IntrusivePtr<RecordType>& rt
|
|||
if ( x.has_value() )
|
||||
set_record_field(rval, rtype, idx, *x);
|
||||
}
|
||||
else if constexpr ( is_instance<T, hilti::rt::DeferredExpression>::value ) {
|
||||
try {
|
||||
set_record_field(rval, rtype, idx, x());
|
||||
} catch ( const hilti::rt::AttributeNotSet& ) {
|
||||
// leave unset
|
||||
}
|
||||
}
|
||||
else {
|
||||
ValPtr v = nullptr;
|
||||
|
||||
// This may return a nullptr in cases where the field is to be left unset.
|
||||
v = to_val(x, rtype->GetFieldType(idx));
|
||||
v = to_val(x, nullptr, rtype->GetFieldType(idx));
|
||||
|
||||
if ( v )
|
||||
rval->Assign(idx, v);
|
||||
|
@ -848,14 +821,14 @@ inline void set_record_field(RecordVal* rval, const IntrusivePtr<RecordType>& rt
|
|||
* Converts a Spicy-side tuple to a Zeek record value. The result is returned
|
||||
* with ref count +1.
|
||||
*/
|
||||
template<typename T, typename std::enable_if_t<hilti::rt::is_tuple<T>::value>*>
|
||||
inline ValPtr to_val(const T& t, const TypePtr& target) {
|
||||
template<typename... Ts>
|
||||
ValPtr to_val(const hilti::rt::Tuple<Ts...>& t, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_RECORD )
|
||||
throw ParameterMismatch("tuple", target);
|
||||
|
||||
auto rtype = cast_intrusive<RecordType>(target);
|
||||
|
||||
if ( std::tuple_size<T>::value != rtype->NumFields() )
|
||||
if ( sizeof...(Ts) != rtype->NumFields() )
|
||||
throw ParameterMismatch("tuple", target);
|
||||
|
||||
auto rval = make_intrusive<RecordVal>(rtype);
|
||||
|
@ -870,7 +843,7 @@ inline ValPtr to_val(const T& t, const TypePtr& target) {
|
|||
* with ref count +1.
|
||||
*/
|
||||
template<typename... Ts>
|
||||
inline ValPtr to_val(const hilti::rt::Bitfield<Ts...>& v, const TypePtr& target) {
|
||||
inline ValPtr to_val(const hilti::rt::Bitfield<Ts...>& v, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
using Bitfield = hilti::rt::Bitfield<Ts...>;
|
||||
|
||||
if ( target->Tag() != TYPE_RECORD )
|
||||
|
@ -903,7 +876,7 @@ constexpr bool is_optional = is_optional_impl<std::remove_cv_t<std::remove_refer
|
|||
* with a ref count +1.
|
||||
*/
|
||||
template<typename T, typename std::enable_if_t<std::is_base_of<::hilti::rt::trait::isStruct, T>::value>*>
|
||||
inline ValPtr to_val(const T& t, const TypePtr& target) {
|
||||
inline ValPtr to_val(const T& t, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_RECORD )
|
||||
throw ParameterMismatch("struct", target);
|
||||
|
||||
|
@ -958,7 +931,7 @@ inline ValPtr to_val(const T& t, const TypePtr& target) {
|
|||
}
|
||||
|
||||
/** Maps HILTI's `Protocol` enum to Zeek's `transport_proto` enum. */
|
||||
inline ValPtr to_val_for_transport_proto(int64_t val, const TypePtr& target) {
|
||||
inline ValPtr to_val_for_transport_proto(int64_t val, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
switch ( val ) {
|
||||
case hilti::rt::Protocol::TCP: return id::transport_proto->GetEnumVal(::TransportProto::TRANSPORT_TCP);
|
||||
case hilti::rt::Protocol::UDP: return id::transport_proto->GetEnumVal(::TransportProto::TRANSPORT_UDP);
|
||||
|
@ -975,7 +948,7 @@ inline ValPtr to_val_for_transport_proto(int64_t val, const TypePtr& target) {
|
|||
* with ref count +1.
|
||||
*/
|
||||
template<typename T, typename std::enable_if_t<std::is_enum<typename T::Value>::value>*>
|
||||
inline ValPtr to_val(const T& t, const TypePtr& target) {
|
||||
inline ValPtr to_val(const T& t, const hilti::rt::TypeInfo* ti, const TypePtr& target) {
|
||||
if ( target->Tag() != TYPE_ENUM )
|
||||
throw ParameterMismatch("enum", target);
|
||||
|
||||
|
@ -989,7 +962,7 @@ inline ValPtr to_val(const T& t, const TypePtr& target) {
|
|||
if ( ! std::is_same_v<T, hilti::rt::Protocol> )
|
||||
throw ParameterMismatch(hilti::rt::demangle(typeid(t).name()), target);
|
||||
|
||||
return to_val_for_transport_proto(it, target);
|
||||
return to_val_for_transport_proto(it, nullptr, target);
|
||||
}
|
||||
|
||||
// Zeek's enum can't be negative, so we swap in max_int for our Undef (-1).
|
||||
|
@ -1243,28 +1216,28 @@ inline hilti::rt::Bool record_has_field(const std::string& name, const std::stri
|
|||
|
||||
/** Checks if a Zeek set contains a given element. Throws on errors. */
|
||||
template<typename T>
|
||||
::hilti::rt::Bool set_contains(const ValSetPtr& v, const T& key) {
|
||||
::hilti::rt::Bool set_contains(const ValSetPtr& v, const T& key, const hilti::rt::TypeInfo* ktype) {
|
||||
auto index = v->GetType()->AsTableType()->GetIndexTypes()[0];
|
||||
return (v->Find(to_val(key, index)) != nullptr);
|
||||
return (v->Find(to_val(key, ktype, index)) != nullptr);
|
||||
}
|
||||
|
||||
/** Checks if a Zeek set contains a given element. Throws on errors. */
|
||||
template<typename T>
|
||||
::hilti::rt::Bool set_contains(const std::string& name, const T& key) {
|
||||
return set_contains(get_set(name), key);
|
||||
::hilti::rt::Bool set_contains(const std::string& name, const T& key, const hilti::rt::TypeInfo* ktype) {
|
||||
return set_contains(get_set(name), key, ktype);
|
||||
}
|
||||
|
||||
/** Checks if a Zeek table contains a given element. Throws on errors. */
|
||||
template<typename T>
|
||||
::hilti::rt::Bool table_contains(const ValTablePtr& v, const T& key) {
|
||||
::hilti::rt::Bool table_contains(const ValTablePtr& v, const T& key, const hilti::rt::TypeInfo* ktype) {
|
||||
auto index = v->GetType()->AsTableType()->GetIndexTypes()[0];
|
||||
return (v->Find(to_val(key, index)) != nullptr);
|
||||
return (v->Find(to_val(key, ktype, index)) != nullptr);
|
||||
}
|
||||
|
||||
/** Check if a Zeek table contains a given element. Throws on errors. */
|
||||
template<typename T>
|
||||
::hilti::rt::Bool table_contains(const std::string& name, const T& key) {
|
||||
return table_contains(get_table(name), key);
|
||||
::hilti::rt::Bool table_contains(const std::string& name, const T& key, const hilti::rt::TypeInfo* ktype) {
|
||||
return table_contains(get_table(name), key, ktype);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1272,9 +1245,10 @@ template<typename T>
|
|||
* not exist. Throws on other errors.
|
||||
*/
|
||||
template<typename T>
|
||||
std::optional<::zeek::ValPtr> table_lookup(const zeek::spicy::rt::ValTablePtr& v, const T& key) {
|
||||
std::optional<::zeek::ValPtr> table_lookup(const zeek::spicy::rt::ValTablePtr& v, const T& key,
|
||||
const hilti::rt::TypeInfo* ktype) {
|
||||
auto index = v->GetType()->AsTableType()->GetIndexTypes()[0];
|
||||
if ( auto x = v->FindOrDefault(to_val(key, index)) )
|
||||
if ( auto x = v->FindOrDefault(to_val(key, ktype, index)) )
|
||||
return x;
|
||||
else
|
||||
return {};
|
||||
|
@ -1285,8 +1259,8 @@ std::optional<::zeek::ValPtr> table_lookup(const zeek::spicy::rt::ValTablePtr& v
|
|||
* not exist. Throws on other errors.
|
||||
*/
|
||||
template<typename T>
|
||||
std::optional<::zeek::ValPtr> table_lookup(const std::string& name, const T& key) {
|
||||
return table_lookup(get_table(name), key);
|
||||
std::optional<::zeek::ValPtr> table_lookup(const std::string& name, const T& key, const hilti::rt::TypeInfo* ktype) {
|
||||
return table_lookup(get_table(name), key, ktype);
|
||||
}
|
||||
|
||||
/** Returns a Zeek vector element. Throws on errors. */
|
||||
|
|
|
@ -1204,33 +1204,12 @@ bool GlueCompiler::PopulateEvents() {
|
|||
|
||||
#include <spicy/ast/visitor.h>
|
||||
|
||||
// Helper visitor to wrap expressions using the TryMember operator into a
|
||||
// "deferred" expression.
|
||||
class WrapTryMemberVisitor : public spicy::visitor::MutatingPostOrder {
|
||||
public:
|
||||
WrapTryMemberVisitor(Builder* builder, bool catch_exception)
|
||||
: spicy::visitor::MutatingPostOrder(builder, logging::debug::GlueCompiler), _catch_exception(catch_exception) {}
|
||||
|
||||
void operator()(hilti::expression::UnresolvedOperator* n) final {
|
||||
if ( n->kind() == hilti::operator_::Kind::TryMember )
|
||||
replaceNode(n, builder()->expressionDeferred(n->as<hilti::Expression>(), _catch_exception), "wrap .?");
|
||||
}
|
||||
|
||||
private:
|
||||
bool _catch_exception;
|
||||
};
|
||||
|
||||
static hilti::Result<hilti::Expression*> parseArgument(Builder* builder, const std::string& expression,
|
||||
bool catch_exception, const hilti::Meta& meta) {
|
||||
auto expr = ::spicy::builder::parseExpression(builder, expression, meta);
|
||||
if ( ! expr )
|
||||
return hilti::result::Error(hilti::util::fmt("error parsing event argument expression '%s'", expression));
|
||||
|
||||
// If the expression uses the ".?" operator, we need to defer evaluation
|
||||
// so that we can handle potential exceptions at runtime.
|
||||
auto v = WrapTryMemberVisitor(builder, catch_exception);
|
||||
spicy::visitor::visit(v, *expr);
|
||||
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
@ -1538,7 +1517,7 @@ struct VisitorZeekType : spicy::visitor::PreOrder {
|
|||
});
|
||||
|
||||
auto tmp = builder->addTmp(tmpName("labels", id()),
|
||||
builder->typeVector(
|
||||
builder->typeSet(
|
||||
builder->qualifiedType(builder->typeTuple(hilti::QualifiedTypes{
|
||||
builder->qualifiedType(builder->typeString(),
|
||||
hilti::Constness::Const),
|
||||
|
@ -1547,9 +1526,8 @@ struct VisitorZeekType : spicy::visitor::PreOrder {
|
|||
hilti::Constness::Const)));
|
||||
|
||||
for ( const auto& l : t->labels() )
|
||||
builder->addMemberCall(tmp, "push_back",
|
||||
{builder->tuple(
|
||||
{builder->stringLiteral(l->id().str()), builder->integer(l->value())})});
|
||||
builder->addExpression(builder->add(tmp, builder->tuple({builder->stringMutable(l->id().str()),
|
||||
builder->integer(l->value())})));
|
||||
|
||||
result(builder->call("zeek_rt::create_enum_type", {builder->stringMutable(id().namespace_().str()),
|
||||
builder->stringMutable(id().local().str()), tmp}));
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
|
||||
== spicyz
|
||||
::hilti::rt::print("have zeek"s, ::hilti::rt::Bool(true));
|
||||
::hilti::rt::print("have spicy version"s, ::hilti::rt::Bool(true));
|
||||
::hilti::rt::print("have spicy version >= 0.4"s, ::hilti::rt::Bool(true));
|
||||
::hilti::rt::print("not have spicy version >= 4"s, ::hilti::rt::Bool(true));
|
||||
::hilti::rt::print("have zeek and zeek version > 1.0"s, ::hilti::rt::Bool(true));
|
||||
::hilti::rt::print("have zeek"s, &::hilti::rt::type_info::string, ::hilti::rt::Bool(true));
|
||||
::hilti::rt::print("have spicy version"s, &::hilti::rt::type_info::string, ::hilti::rt::Bool(true));
|
||||
::hilti::rt::print("have spicy version >= 0.4"s, &::hilti::rt::type_info::string, ::hilti::rt::Bool(true));
|
||||
::hilti::rt::print("not have spicy version >= 4"s, &::hilti::rt::type_info::string, ::hilti::rt::Bool(true));
|
||||
::hilti::rt::print("have zeek and zeek version > 1.0"s, &::hilti::rt::type_info::string, ::hilti::rt::Bool(true));
|
||||
|
|
|
@ -5,5 +5,5 @@
|
|||
[i=4, s=<uninitialized>]
|
||||
[zeek] [SPICY_SSH/3/orig] -> event ssh::banner((1, b"OpenSSH_3.8.1p1"))
|
||||
[zeek] [SPICY_SSH/3/orig] -> event ssh::banner((2, b"OpenSSH_3.8.1p1"))
|
||||
[zeek] [SPICY_SSH/3/orig] -> event ssh::banner((3, b""))
|
||||
[zeek] [SPICY_SSH/3/orig] -> event ssh::banner((3, (not set)))
|
||||
[zeek] [SPICY_SSH/3/orig] -> event ssh::banner((4, Null))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue