exposing some functionality for greater flexibility in structuring run-time execution

This commit is contained in:
Vern Paxson 2024-08-05 21:11:34 +01:00 committed by Arne Welzel
parent 65e713e6ea
commit 63f76c7f84
4 changed files with 84 additions and 60 deletions

View file

@ -16,7 +16,7 @@ namespace ZAM {
std::string curr_func; std::string curr_func;
std::shared_ptr<ZAMLocInfo> curr_loc; std::shared_ptr<ZAMLocInfo> curr_loc;
TypePtr log_ID_enum_type; TypePtr log_ID_enum_type;
TypePtr any_base_type; TypePtr any_base_type = base_type(TYPE_ANY);
} // namespace ZAM } // namespace ZAM
bool ZAM_error = false; bool ZAM_error = false;
@ -35,6 +35,32 @@ bool is_ZAM_compilable(const ProfileFunc* pf, const char** reason) {
bool IsAny(const Type* t) { return t->Tag() == TYPE_ANY; } bool IsAny(const Type* t) { return t->Tag() == TYPE_ANY; }
bool CheckAnyType(const TypePtr& any_type, const TypePtr& expected_type, const std::shared_ptr<ZAMLocInfo>& loc) {
if ( IsAny(expected_type) )
return true;
if ( ! same_type(any_type, expected_type, false, false) ) {
auto at = any_type->Tag();
auto et = expected_type->Tag();
if ( at == TYPE_RECORD && et == TYPE_RECORD ) {
auto at_r = any_type->AsRecordType();
auto et_r = expected_type->AsRecordType();
if ( record_promotion_compatible(et_r, at_r) )
return true;
}
char buf[8192];
snprintf(buf, sizeof buf, "run-time type clash (%s/%s)", type_name(at), type_name(et));
reporter->RuntimeError(loc->Loc(), "%s", buf);
return false;
}
return true;
}
StringVal* ZAM_to_lower(const StringVal* sv) { StringVal* ZAM_to_lower(const StringVal* sv) {
auto bs = sv->AsString(); auto bs = sv->AsString();
const u_char* s = bs->Bytes(); const u_char* s = bs->Bytes();
@ -82,7 +108,10 @@ void ZAM_run_time_error(const char* msg) {
} }
void ZAM_run_time_error(std::shared_ptr<ZAMLocInfo> loc, const char* msg) { void ZAM_run_time_error(std::shared_ptr<ZAMLocInfo> loc, const char* msg) {
if ( loc )
reporter->RuntimeError(loc->Loc(), "%s", msg); reporter->RuntimeError(loc->Loc(), "%s", msg);
else
fprintf(stderr, "<no location in optimized code>: %s\n", msg);
ZAM_error = true; ZAM_error = true;
} }
@ -92,7 +121,10 @@ void ZAM_run_time_error(const char* msg, const Obj* o) {
} }
void ZAM_run_time_error(std::shared_ptr<ZAMLocInfo> loc, const char* msg, const Obj* o) { void ZAM_run_time_error(std::shared_ptr<ZAMLocInfo> loc, const char* msg, const Obj* o) {
if ( loc )
reporter->RuntimeError(loc->Loc(), "%s (%s)", msg, obj_desc(o).c_str()); reporter->RuntimeError(loc->Loc(), "%s (%s)", msg, obj_desc(o).c_str());
else
ZAM_run_time_error(msg, o);
ZAM_error = true; ZAM_error = true;
} }

View file

@ -42,6 +42,10 @@ extern bool IsAny(const Type* t);
inline bool IsAny(const TypePtr& t) { return IsAny(t.get()); } inline bool IsAny(const TypePtr& t) { return IsAny(t.get()); }
inline bool IsAny(const Expr* e) { return IsAny(e->GetType()); } inline bool IsAny(const Expr* e) { return IsAny(e->GetType()); }
// Run-time checking for "any" type being consistent with
// expected typed. Returns true if the type match is okay.
extern bool CheckAnyType(const TypePtr& any_type, const TypePtr& expected_type, const std::shared_ptr<ZAMLocInfo>& loc);
extern void ZAM_run_time_error(const char* msg); extern void ZAM_run_time_error(const char* msg);
extern void ZAM_run_time_error(std::shared_ptr<ZAMLocInfo> loc, const char* msg); extern void ZAM_run_time_error(std::shared_ptr<ZAMLocInfo> loc, const char* msg);
extern void ZAM_run_time_error(std::shared_ptr<ZAMLocInfo> loc, const char* msg, const Obj* o); extern void ZAM_run_time_error(std::shared_ptr<ZAMLocInfo> loc, const char* msg, const Obj* o);

View file

@ -14,27 +14,6 @@
#include "zeek/script_opt/ZAM/Compile.h" #include "zeek/script_opt/ZAM/Compile.h"
#include "zeek/session/Manager.h" #include "zeek/session/Manager.h"
// Needed for managing the corresponding values.
#include "zeek/File.h"
#include "zeek/Func.h"
#include "zeek/OpaqueVal.h"
// Just needed for BiFs.
#include "zeek/analyzer/Manager.h"
#include "zeek/analyzer/protocol/conn-size/ConnSize.h"
#include "zeek/broker/Manager.h"
#include "zeek/file_analysis/Manager.h"
#include "zeek/file_analysis/file_analysis.bif.h"
#include "zeek/logging/Manager.h"
#include "zeek/packet_analysis/Manager.h"
#include "zeek/packet_analysis/protocol/gtpv1/GTPv1.h"
#include "zeek/packet_analysis/protocol/teredo/Teredo.h"
#include "zeek.bif.func_h"
// For reading_live and reading_traces
#include "zeek/RunState.h"
namespace zeek::detail { namespace zeek::detail {
static double CPU_prof_overhead = 0.0; static double CPU_prof_overhead = 0.0;
@ -165,7 +144,7 @@ void report_ZOP_profile() {
// assigned value was missing (which we can only tell for managed types), // assigned value was missing (which we can only tell for managed types),
// true otherwise. // true otherwise.
static bool copy_vec_elem(VectorVal* vv, zeek_uint_t ind, ZVal zv, const TypePtr& t) { bool copy_vec_elem(VectorVal* vv, zeek_uint_t ind, ZVal zv, const TypePtr& t) {
if ( vv->Size() <= ind ) if ( vv->Size() <= ind )
vv->Resize(ind + 1); vv->Resize(ind + 1);
@ -200,7 +179,7 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con
// Vector coercion. // Vector coercion.
#define VEC_COERCE(tag, lhs_type, cast, rhs_accessor, ov_check, ov_err) \ #define VEC_COERCE(tag, lhs_type, cast, rhs_accessor, ov_check, ov_err) \
static VectorVal* vec_coerce_##tag(VectorVal* vec, const ZInst& z) { \ VectorVal* vec_coerce_##tag(VectorVal* vec, std::shared_ptr<ZAMLocInfo> z_loc) { \
auto& v = vec->RawVec(); \ auto& v = vec->RawVec(); \
auto yt = make_intrusive<VectorType>(base_type(lhs_type)); \ auto yt = make_intrusive<VectorType>(base_type(lhs_type)); \
auto res_zv = new VectorVal(yt); \ auto res_zv = new VectorVal(yt); \
@ -214,7 +193,7 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con
std::string err = "overflow promoting from "; \ std::string err = "overflow promoting from "; \
err += ov_err; \ err += ov_err; \
err += " arithmetic value"; \ err += " arithmetic value"; \
ZAM_run_time_error(z.loc, err.c_str()); \ ZAM_run_time_error(z_loc, err.c_str()); \
res[i] = std::nullopt; \ res[i] = std::nullopt; \
} \ } \
else \ else \
@ -272,7 +251,6 @@ ZBody::ZBody(std::string _func_name, const ZAMCompiler* zc) : Stmt(STMT_ZAM) {
auto log_ID_type = lookup_ID("ID", "Log"); auto log_ID_type = lookup_ID("ID", "Log");
ASSERT(log_ID_type); ASSERT(log_ID_type);
ZAM::log_ID_enum_type = log_ID_type->GetType<EnumType>(); ZAM::log_ID_enum_type = log_ID_type->GetType<EnumType>();
ZAM::any_base_type = base_type(TYPE_ANY);
ZVal::SetZValNilStatusAddr(&ZAM_error); ZVal::SetZValNilStatusAddr(&ZAM_error);
did_init = false; did_init = false;
} }
@ -335,6 +313,9 @@ ValPtr ZBody::Exec(Frame* f, StmtFlowType& flow) {
// Type of the return value. If nil, then we don't have a value. // Type of the return value. If nil, then we don't have a value.
TypePtr ret_type; TypePtr ret_type;
// ListVal corresponding to INDEX_LIST.
static auto zam_index_val_list = make_intrusive<ListVal>(TYPE_ANY);
#ifdef ENABLE_ZAM_PROFILE #ifdef ENABLE_ZAM_PROFILE
static bool profiling_active = analysis_options.profile_ZAM; static bool profiling_active = analysis_options.profile_ZAM;
static int sampling_rate = analysis_options.profile_sampling_rate; static int sampling_rate = analysis_options.profile_sampling_rate;
@ -529,33 +510,6 @@ void ZBody::ReportProfile(ProfMap& pm, const ProfVec& pv, const std::string& pre
} }
} }
bool ZBody::CheckAnyType(const TypePtr& any_type, const TypePtr& expected_type,
const std::shared_ptr<ZAMLocInfo>& loc) const {
if ( IsAny(expected_type) )
return true;
if ( ! same_type(any_type, expected_type, false, false) ) {
auto at = any_type->Tag();
auto et = expected_type->Tag();
if ( at == TYPE_RECORD && et == TYPE_RECORD ) {
auto at_r = any_type->AsRecordType();
auto et_r = expected_type->AsRecordType();
if ( record_promotion_compatible(et_r, at_r) )
return true;
}
char buf[8192];
snprintf(buf, sizeof buf, "run-time type clash (%s/%s)", type_name(at), type_name(et));
reporter->RuntimeError(loc->Loc(), "%s", buf);
return false;
}
return true;
}
void ZBody::Dump() const { void ZBody::Dump() const {
printf("Frame:\n"); printf("Frame:\n");

View file

@ -8,6 +8,31 @@
#include "zeek/script_opt/ZAM/Profile.h" #include "zeek/script_opt/ZAM/Profile.h"
#include "zeek/script_opt/ZAM/Support.h" #include "zeek/script_opt/ZAM/Support.h"
////////////////////////////////////////////////////////////////////////
// Headers needed for run-time execution:
// Needed for managing the corresponding values.
#include "zeek/File.h"
#include "zeek/Func.h"
#include "zeek/OpaqueVal.h"
// Just needed for BiFs.
#include "zeek/analyzer/Manager.h"
#include "zeek/analyzer/protocol/conn-size/ConnSize.h"
#include "zeek/broker/Manager.h"
#include "zeek/file_analysis/Manager.h"
#include "zeek/file_analysis/file_analysis.bif.h"
#include "zeek/logging/Manager.h"
#include "zeek/packet_analysis/Manager.h"
#include "zeek/packet_analysis/protocol/gtpv1/GTPv1.h"
#include "zeek/packet_analysis/protocol/teredo/Teredo.h"
#include "zeek.bif.func_h"
// For reading_live and reading_traces
#include "zeek/RunState.h"
////////////////////////////////////////////////////////////////////////
namespace zeek::detail { namespace zeek::detail {
// Static information about globals used in a function. // Static information about globals used in a function.
@ -63,6 +88,11 @@ public:
const std::string& FuncName() const { return func_name; } const std::string& FuncName() const { return func_name; }
private: private:
friend class CPPCompile;
auto Instructions() const { return insts; }
auto NumInsts() const { return end_pc; }
// Initializes profiling information, if needed. // Initializes profiling information, if needed.
void InitProfile(); void InitProfile();
std::shared_ptr<ProfVec> BuildProfVec() const; std::shared_ptr<ProfVec> BuildProfVec() const;
@ -70,11 +100,6 @@ private:
void ReportProfile(ProfMap& pm, const ProfVec& pv, const std::string& prefix, void ReportProfile(ProfMap& pm, const ProfVec& pv, const std::string& prefix,
std::set<std::string> caller_modules) const; std::set<std::string> caller_modules) const;
// Run-time checking for "any" type being consistent with
// expected typed. Returns true if the type match is okay.
bool CheckAnyType(const TypePtr& any_type, const TypePtr& expected_type,
const std::shared_ptr<ZAMLocInfo>& loc) const;
StmtPtr Duplicate() override { return {NewRef{}, this}; } StmtPtr Duplicate() override { return {NewRef{}, this}; }
void StmtDescribe(ODesc* d) const override; void StmtDescribe(ODesc* d) const override;
@ -128,4 +153,13 @@ private:
ProfVec* curr_prof_vec; ProfVec* curr_prof_vec;
}; };
extern bool copy_vec_elem(VectorVal* vv, zeek_uint_t ind, ZVal zv, const TypePtr& t);
extern VectorVal* vec_coerce_DI(VectorVal* vec, std::shared_ptr<ZAMLocInfo> z_loc);
extern VectorVal* vec_coerce_DU(VectorVal* vec, std::shared_ptr<ZAMLocInfo> z_loc);
extern VectorVal* vec_coerce_ID(VectorVal* vec, std::shared_ptr<ZAMLocInfo> z_loc);
extern VectorVal* vec_coerce_IU(VectorVal* vec, std::shared_ptr<ZAMLocInfo> z_loc);
extern VectorVal* vec_coerce_UD(VectorVal* vec, std::shared_ptr<ZAMLocInfo> z_loc);
extern VectorVal* vec_coerce_UI(VectorVal* vec, std::shared_ptr<ZAMLocInfo> z_loc);
} // namespace zeek::detail } // namespace zeek::detail