mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
[Spicy] Clean up representation of EVT record fields.
This commit is contained in:
parent
cdadd934ce
commit
36a6770e98
5 changed files with 41 additions and 18 deletions
|
@ -9,6 +9,7 @@ public type Val = __library_type("::zeek::ValPtr");
|
|||
public type BroType = __library_type("::zeek::TypePtr");
|
||||
public type EventHandlerPtr = __library_type("::zeek::EventHandlerPtr");
|
||||
public type PortRange = __library_type("::zeek::spicy::rt::PortRange");
|
||||
public type RecordField = __library_type("::zeek::spicy::rt::RecordField");
|
||||
|
||||
declare public PortRange make_port_range(port begin_, port end_) &cxxname="zeek::spicy::rt::make_port_range" &have_prototype;
|
||||
|
||||
|
@ -29,10 +30,10 @@ declare public void raise_event(EventHandlerPtr handler, vector<Val> args) &cxxn
|
|||
declare public BroType event_arg_type(EventHandlerPtr handler, uint<64> idx) &cxxname="zeek::spicy::rt::event_arg_type" &have_prototype;
|
||||
declare public Val to_val(any x, BroType target) &cxxname="zeek::spicy::rt::to_val" &have_prototype;
|
||||
|
||||
type RecordField = tuple<string, BroType, bool, bool>; # (ID, type, optional, log)
|
||||
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_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;
|
||||
declare public BroType create_vector_type(BroType elem) &cxxname="zeek::spicy::rt::create_vector_type" &have_prototype;
|
||||
|
||||
|
|
|
@ -126,25 +126,30 @@ TypePtr rt::create_record_type(const std::string& ns, const std::string& id,
|
|||
|
||||
auto decls = std::make_unique<type_decl_list>();
|
||||
|
||||
for ( const auto& [id, type, optional, log] : fields ) {
|
||||
for ( const auto& f : fields ) {
|
||||
auto attrs = make_intrusive<detail::Attributes>(nullptr, true, false);
|
||||
|
||||
if ( optional ) {
|
||||
if ( f.is_optional ) {
|
||||
auto optional_ = make_intrusive<detail::Attr>(detail::ATTR_OPTIONAL);
|
||||
attrs->AddAttr(std::move(optional_));
|
||||
}
|
||||
|
||||
if ( log ) {
|
||||
if ( f.is_log ) {
|
||||
auto log_ = make_intrusive<detail::Attr>(detail::ATTR_LOG);
|
||||
attrs->AddAttr(std::move(log_));
|
||||
}
|
||||
|
||||
decls->append(new TypeDecl(util::copy_string(id.c_str()), type, std::move(attrs)));
|
||||
decls->append(new TypeDecl(util::copy_string(f.id.c_str()), f.type, std::move(attrs)));
|
||||
}
|
||||
|
||||
return make_intrusive<RecordType>(decls.release());
|
||||
}
|
||||
|
||||
rt::RecordField rt::create_record_field(const std::string& id, const TypePtr& type, hilti::rt::Bool is_optional,
|
||||
hilti::rt::Bool is_log) {
|
||||
return rt::RecordField{id, type, is_optional, is_log};
|
||||
}
|
||||
|
||||
TypePtr rt::create_table_type(TypePtr key, std::optional<TypePtr> value) {
|
||||
auto _ = hilti::rt::profiler::start("zeek/rt/create_table_type");
|
||||
auto idx = make_intrusive<TypeList>();
|
||||
|
|
|
@ -151,9 +151,17 @@ 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);
|
||||
|
||||
using RecordField = std::tuple<std::string, TypePtr, hilti::rt::Bool, hilti::rt::Bool>; // (ID, type, optional, &log)
|
||||
struct RecordField {
|
||||
std::string id; /**< name of record field */
|
||||
TypePtr type; /**< Spicy-side type object */
|
||||
bool is_optional; /**< true if field is optional */
|
||||
bool is_log; /**< true if field has `&log` */
|
||||
};
|
||||
|
||||
extern TypePtr create_record_type(const std::string& ns, const std::string& id,
|
||||
const hilti::rt::Vector<RecordField>& fields);
|
||||
extern RecordField create_record_field(const std::string& id, const TypePtr& type, hilti::rt::Bool is_optional,
|
||||
hilti::rt::Bool is_log);
|
||||
|
||||
extern TypePtr create_table_type(TypePtr key, std::optional<TypePtr> value);
|
||||
extern TypePtr create_vector_type(const TypePtr& elem);
|
||||
|
|
|
@ -1335,6 +1335,12 @@ struct VisitorZeekType : hilti::visitor::PreOrder<hilti::Result<hilti::Expressio
|
|||
{builder::string(ns), builder::string(local), builder::vector(fields)});
|
||||
}
|
||||
|
||||
hilti::Expression create_record_field(const hilti::ID& id, const hilti::Expression& type, bool optional,
|
||||
bool log) const {
|
||||
return builder::call("zeek_rt::create_record_field",
|
||||
{builder::string(id), type, builder::bool_(optional), builder::bool_(log)});
|
||||
}
|
||||
|
||||
result_t base_type(const char* tag) { return builder::call("zeek_rt::create_base_type", {builder::id(tag)}); }
|
||||
|
||||
result_t createZeekType(const hilti::Type& t, const std::optional<hilti::ID>& id_ = {}) {
|
||||
|
@ -1419,8 +1425,7 @@ struct VisitorZeekType : hilti::visitor::PreOrder<hilti::Result<hilti::Expressio
|
|||
if ( ! ztype )
|
||||
return ztype.error();
|
||||
|
||||
fields.emplace_back(builder::tuple(
|
||||
{builder::string(f.id()), *ztype, builder::bool_(f.isOptional()), builder::bool_(false)}));
|
||||
fields.emplace_back(create_record_field(f.id(), *ztype, f.isOptional(), false));
|
||||
}
|
||||
|
||||
return create_record_type(id()->namespace_(), id()->local(), fields);
|
||||
|
@ -1436,8 +1441,7 @@ struct VisitorZeekType : hilti::visitor::PreOrder<hilti::Result<hilti::Expressio
|
|||
if ( ! ztype )
|
||||
return ztype.error();
|
||||
|
||||
fields.emplace_back(
|
||||
builder::tuple({builder::string(*f.id()), *ztype, builder::bool_(false), builder::bool_(false)}));
|
||||
fields.emplace_back(create_record_field(*f.id(), *ztype, false, false));
|
||||
}
|
||||
|
||||
hilti::ID local;
|
||||
|
@ -1466,18 +1470,16 @@ struct VisitorZeekType : hilti::visitor::PreOrder<hilti::Result<hilti::Expressio
|
|||
|
||||
std::vector<hilti::Expression> fields;
|
||||
for ( const auto& f : gc->recordFields(t) ) {
|
||||
auto field_id = std::get<0>(f);
|
||||
auto export_ = gc->exportForField(*id(), hilti::ID(field_id));
|
||||
auto export_ = gc->exportForField(*id(), hilti::ID(f.id));
|
||||
|
||||
if ( export_.skip )
|
||||
continue;
|
||||
|
||||
auto ztype = createZeekType(std::get<1>(f));
|
||||
auto ztype = createZeekType(f.type);
|
||||
if ( ! ztype )
|
||||
return ztype.error();
|
||||
|
||||
fields.emplace_back(builder::tuple({builder::string(std::get<0>(f)), *ztype, builder::bool_(std::get<2>(f)),
|
||||
builder::bool_(export_.log)}));
|
||||
fields.emplace_back(create_record_field(f.id, *ztype, f.is_optional, export_.log));
|
||||
}
|
||||
|
||||
return create_record_type(id()->namespace_(), id()->local(), fields);
|
||||
|
@ -1507,11 +1509,13 @@ struct VisitorUnitFields : hilti::visitor::PreOrder<void, VisitorUnitFields> {
|
|||
if ( f.isTransient() || f.parseType().isA<hilti::type::Void>() )
|
||||
return;
|
||||
|
||||
fields.emplace_back(f.id(), f.itemType(), true);
|
||||
auto field = GlueCompiler::RecordField{.id = f.id(), .type = f.itemType(), .is_optional = true};
|
||||
fields.emplace_back(std::move(field));
|
||||
}
|
||||
|
||||
void operator()(const ::spicy::type::unit::item::Variable& f, const position_t p) {
|
||||
fields.emplace_back(f.id(), f.itemType(), f.isOptional());
|
||||
auto field = GlueCompiler::RecordField{.id = f.id(), .type = f.itemType(), .is_optional = f.isOptional()};
|
||||
fields.emplace_back(std::move(field));
|
||||
}
|
||||
|
||||
void operator()(const ::spicy::type::unit::item::Switch& f, const position_t p) {
|
||||
|
|
|
@ -201,7 +201,12 @@ public:
|
|||
/** Generates code to convert a HILTI type to a corresponding Zeek type at runtime. */
|
||||
hilti::Result<hilti::Expression> createZeekType(const hilti::Type& t, const hilti::ID& id) const;
|
||||
|
||||
using RecordField = std::tuple<std::string, hilti::Type, bool>; /**< (ID, type, optional) */
|
||||
/** Return type for `recordField()`. */
|
||||
struct RecordField {
|
||||
hilti::ID id; /**< name of record field */
|
||||
hilti::Type type; /**< Spicy-side type object */
|
||||
bool is_optional; /**< true if field is optional */
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to retrieve a list of Zeek-side record fields that converting a
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue