diff --git a/src/script_opt/ZAM/Support.cc b/src/script_opt/ZAM/Support.cc index 7e0d9172be..61efb9265d 100644 --- a/src/script_opt/ZAM/Support.cc +++ b/src/script_opt/ZAM/Support.cc @@ -16,7 +16,7 @@ namespace ZAM { std::string curr_func; std::shared_ptr curr_loc; TypePtr log_ID_enum_type; -TypePtr any_base_type; +TypePtr any_base_type = base_type(TYPE_ANY); } // namespace ZAM 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 CheckAnyType(const TypePtr& any_type, const TypePtr& expected_type, const std::shared_ptr& 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) { auto bs = sv->AsString(); 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 loc, const char* msg) { - reporter->RuntimeError(loc->Loc(), "%s", msg); + if ( loc ) + reporter->RuntimeError(loc->Loc(), "%s", msg); + else + fprintf(stderr, ": %s\n", msg); 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 loc, const char* msg, const Obj* o) { - reporter->RuntimeError(loc->Loc(), "%s (%s)", msg, obj_desc(o).c_str()); + if ( loc ) + reporter->RuntimeError(loc->Loc(), "%s (%s)", msg, obj_desc(o).c_str()); + else + ZAM_run_time_error(msg, o); ZAM_error = true; } diff --git a/src/script_opt/ZAM/Support.h b/src/script_opt/ZAM/Support.h index 6e01b7c611..96777b26f6 100644 --- a/src/script_opt/ZAM/Support.h +++ b/src/script_opt/ZAM/Support.h @@ -42,6 +42,10 @@ extern bool IsAny(const Type* t); inline bool IsAny(const TypePtr& t) { return IsAny(t.get()); } 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& loc); + extern void ZAM_run_time_error(const char* msg); extern void ZAM_run_time_error(std::shared_ptr loc, const char* msg); extern void ZAM_run_time_error(std::shared_ptr loc, const char* msg, const Obj* o); diff --git a/src/script_opt/ZAM/ZBody.cc b/src/script_opt/ZAM/ZBody.cc index 80a1039c5d..126c01d55f 100644 --- a/src/script_opt/ZAM/ZBody.cc +++ b/src/script_opt/ZAM/ZBody.cc @@ -14,27 +14,6 @@ #include "zeek/script_opt/ZAM/Compile.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 { 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), // 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 ) vv->Resize(ind + 1); @@ -200,7 +179,7 @@ static void vec_exec(ZOp op, TypePtr t, VectorVal*& v1, const VectorVal* v2, con // Vector coercion. #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 z_loc) { \ auto& v = vec->RawVec(); \ auto yt = make_intrusive(base_type(lhs_type)); \ 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 "; \ err += ov_err; \ 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; \ } \ 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"); ASSERT(log_ID_type); ZAM::log_ID_enum_type = log_ID_type->GetType(); - ZAM::any_base_type = base_type(TYPE_ANY); ZVal::SetZValNilStatusAddr(&ZAM_error); 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. TypePtr ret_type; + // ListVal corresponding to INDEX_LIST. + static auto zam_index_val_list = make_intrusive(TYPE_ANY); + #ifdef ENABLE_ZAM_PROFILE static bool profiling_active = analysis_options.profile_ZAM; 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& 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 { printf("Frame:\n"); diff --git a/src/script_opt/ZAM/ZBody.h b/src/script_opt/ZAM/ZBody.h index db4c5beb7b..794ee36467 100644 --- a/src/script_opt/ZAM/ZBody.h +++ b/src/script_opt/ZAM/ZBody.h @@ -8,6 +8,31 @@ #include "zeek/script_opt/ZAM/Profile.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 { // Static information about globals used in a function. @@ -63,6 +88,11 @@ public: const std::string& FuncName() const { return func_name; } private: + friend class CPPCompile; + + auto Instructions() const { return insts; } + auto NumInsts() const { return end_pc; } + // Initializes profiling information, if needed. void InitProfile(); std::shared_ptr BuildProfVec() const; @@ -70,11 +100,6 @@ private: void ReportProfile(ProfMap& pm, const ProfVec& pv, const std::string& prefix, std::set 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& loc) const; - StmtPtr Duplicate() override { return {NewRef{}, this}; } void StmtDescribe(ODesc* d) const override; @@ -128,4 +153,13 @@ private: 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 z_loc); +extern VectorVal* vec_coerce_DU(VectorVal* vec, std::shared_ptr z_loc); +extern VectorVal* vec_coerce_ID(VectorVal* vec, std::shared_ptr z_loc); +extern VectorVal* vec_coerce_IU(VectorVal* vec, std::shared_ptr z_loc); +extern VectorVal* vec_coerce_UD(VectorVal* vec, std::shared_ptr z_loc); +extern VectorVal* vec_coerce_UI(VectorVal* vec, std::shared_ptr z_loc); + } // namespace zeek::detail