From 8f2637decb3a9a9622b2118c27d17d656142351c Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 18 Mar 2021 10:00:01 -0700 Subject: [PATCH 01/11] new function for getting the location, if any, associated with the current call --- src/Frame.cc | 5 +++++ src/Frame.h | 1 + src/broker/Data.cc | 2 +- src/broker/Data.h | 2 +- src/broker/Manager.cc | 2 +- src/reporter.bif | 10 +++++----- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/Frame.cc b/src/Frame.cc index c58d830d89..dd6e391adb 100644 --- a/src/Frame.cc +++ b/src/Frame.cc @@ -616,6 +616,11 @@ void Frame::CaptureClosure(Frame* c, IDPList arg_outer_ids) // if (c) closure = c->SelectiveClone(outer_ids); } +const detail::Location* Frame::GetCallLocation() const + { + return call ? call->GetLocationInfo() : nullptr; + } + void Frame::SetTrigger(trigger::TriggerPtr arg_trigger) { trigger = std::move(arg_trigger); diff --git a/src/Frame.h b/src/Frame.h index 36d775ef9f..4188dded27 100644 --- a/src/Frame.h +++ b/src/Frame.h @@ -262,6 +262,7 @@ public: void SetCall(const CallExpr* arg_call) { call = arg_call; } void ClearCall() { call = nullptr; } const CallExpr* GetCall() const { return call; } + const detail::Location* GetCallLocation() const; void SetDelayed() { delayed = true; } bool HasDelayed() const { return delayed; } diff --git a/src/broker/Data.cc b/src/broker/Data.cc index a54e30287c..2af93460bd 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -1177,7 +1177,7 @@ broker::data& opaque_field_to_data(RecordVal* v, zeek::detail::Frame* f) const auto& d = v->GetField(0); if ( ! d ) - reporter->RuntimeError(f->GetCall()->GetLocationInfo(), + reporter->RuntimeError(f->GetCallLocation(), "Broker::Data's opaque field is not set"); // RuntimeError throws an exception which causes this line to never exceute. diff --git a/src/broker/Data.h b/src/broker/Data.h index a3db6c1514..feb58e3806 100644 --- a/src/broker/Data.h +++ b/src/broker/Data.h @@ -194,7 +194,7 @@ T& require_data_type(broker::data& d, zeek::TypeTag tag, zeek::detail::Frame* f) { auto ptr = caf::get_if(&d); if ( ! ptr ) - zeek::reporter->RuntimeError(f->GetCall()->GetLocationInfo(), + zeek::reporter->RuntimeError(f->GetCallLocation(), "data is of type '%s' not of type '%s'", caf::visit(type_name_getter{tag}, d), zeek::type_name(tag)); diff --git a/src/broker/Manager.cc b/src/broker/Manager.cc index 3d682ea4ab..0ce23d9508 100644 --- a/src/broker/Manager.cc +++ b/src/broker/Manager.cc @@ -74,7 +74,7 @@ int Manager::script_scope = 0; struct scoped_reporter_location { scoped_reporter_location(zeek::detail::Frame* frame) { - reporter->PushLocation(frame->GetCall()->GetLocationInfo()); + reporter->PushLocation(frame->GetCallLocation()); } ~scoped_reporter_location() diff --git a/src/reporter.bif b/src/reporter.bif index 950b58f846..523195debb 100644 --- a/src/reporter.bif +++ b/src/reporter.bif @@ -22,7 +22,7 @@ module Reporter; ## .. zeek:see:: reporter_info function Reporter::info%(msg: string%): bool %{ - reporter->PushLocation(frame->GetCall()->GetLocationInfo()); + reporter->PushLocation(frame->GetCallLocation()); reporter->Info("%s", msg->CheckString()); reporter->PopLocation(); return zeek::val_mgr->True(); @@ -37,7 +37,7 @@ function Reporter::info%(msg: string%): bool ## .. zeek:see:: reporter_warning function Reporter::warning%(msg: string%): bool %{ - reporter->PushLocation(frame->GetCall()->GetLocationInfo()); + reporter->PushLocation(frame->GetCallLocation()); reporter->Warning("%s", msg->CheckString()); reporter->PopLocation(); return zeek::val_mgr->True(); @@ -53,7 +53,7 @@ function Reporter::warning%(msg: string%): bool ## .. zeek:see:: reporter_error function Reporter::error%(msg: string%): bool %{ - reporter->PushLocation(frame->GetCall()->GetLocationInfo()); + reporter->PushLocation(frame->GetCallLocation()); reporter->Error("%s", msg->CheckString()); reporter->PopLocation(); return zeek::val_mgr->True(); @@ -66,7 +66,7 @@ function Reporter::error%(msg: string%): bool ## Returns: Always true. function Reporter::fatal%(msg: string%): bool %{ - reporter->PushLocation(frame->GetCall()->GetLocationInfo()); + reporter->PushLocation(frame->GetCallLocation()); reporter->FatalError("%s", msg->CheckString()); reporter->PopLocation(); return zeek::val_mgr->True(); @@ -80,7 +80,7 @@ function Reporter::fatal%(msg: string%): bool ## Returns: Always true. function Reporter::fatal_error_with_core%(msg: string%): bool %{ - reporter->PushLocation(frame->GetCall()->GetLocationInfo()); + reporter->PushLocation(frame->GetCallLocation()); reporter->FatalErrorWithCore("%s", msg->CheckString()); reporter->PopLocation(); return zeek::val_mgr->True(); From b792feccab1f8b107d329d83bf638e23cbb886e4 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 18 Mar 2021 10:02:22 -0700 Subject: [PATCH 02/11] functions for indexing slices and strings --- src/Expr.cc | 107 +++++++++++++++++++++++++++++----------------------- src/Expr.h | 4 ++ 2 files changed, 63 insertions(+), 48 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index 1f5afbf8a7..24cfde992e 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -2936,24 +2936,7 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const if ( lv->Length() == 1 ) v = vect->ValAt(lv->Idx(0)->CoerceToUnsigned()); else - { - size_t len = vect->Size(); - auto result = make_intrusive(vect->GetType()); - - bro_int_t first = get_slice_index(lv->Idx(0)->CoerceToInt(), len); - bro_int_t last = get_slice_index(lv->Idx(1)->CoerceToInt(), len); - bro_int_t sub_length = last - first; - - if ( sub_length >= 0 ) - { - result->Resize(sub_length); - - for ( bro_int_t idx = first; idx < last; idx++ ) - result->Assign(idx - first, vect->ValAt(idx)); - } - - return result; - } + return index_slice(vect, lv); } break; @@ -2962,36 +2945,7 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const break; case TYPE_STRING: - { - const ListVal* lv = v2->AsListVal(); - const String* s = v1->AsString(); - int len = s->Len(); - String* substring = nullptr; - - if ( lv->Length() == 1 ) - { - bro_int_t idx = lv->Idx(0)->AsInt(); - - if ( idx < 0 ) - idx += len; - - // Out-of-range index will return null pointer. - substring = s->GetSubstring(idx, 1); - } - else - { - bro_int_t first = get_slice_index(lv->Idx(0)->AsInt(), len); - bro_int_t last = get_slice_index(lv->Idx(1)->AsInt(), len); - bro_int_t substring_len = last - first; - - if ( substring_len < 0 ) - substring = nullptr; - else - substring = s->GetSubstring(first, substring_len); - } - - return make_intrusive(substring ? substring : new String("")); - } + return index_string(v1->AsString(), v2->AsListVal()); default: RuntimeError("type cannot be indexed"); @@ -3005,6 +2959,63 @@ ValPtr IndexExpr::Fold(Val* v1, Val* v2) const return nullptr; } +StringValPtr index_string(const String* s, const ListVal* lv) + { + int len = s->Len(); + String* substring = nullptr; + + if ( lv->Length() == 1 ) + { + bro_int_t idx = lv->Idx(0)->AsInt(); + + if ( idx < 0 ) + idx += len; + + // Out-of-range index will return null pointer. + substring = s->GetSubstring(idx, 1); + } + else + { + bro_int_t first = get_slice_index(lv->Idx(0)->AsInt(), len); + bro_int_t last = get_slice_index(lv->Idx(1)->AsInt(), len); + bro_int_t substring_len = last - first; + + if ( substring_len < 0 ) + substring = nullptr; + else + substring = s->GetSubstring(first, substring_len); + } + + return make_intrusive(substring ? substring : new String("")); + } + +VectorValPtr index_slice(VectorVal* vect, const ListVal* lv) + { + auto first = lv->Idx(0)->CoerceToInt(); + auto last = lv->Idx(1)->CoerceToInt(); + return index_slice(vect, first, last); + } + +VectorValPtr index_slice(VectorVal* vect, int _first, int _last) + { + size_t len = vect->Size(); + auto result = make_intrusive(vect->GetType()); + + bro_int_t first = get_slice_index(_first, len); + bro_int_t last = get_slice_index(_last, len); + bro_int_t sub_length = last - first; + + if ( sub_length >= 0 ) + { + result->Resize(sub_length); + + for ( bro_int_t idx = first; idx < last; idx++ ) + result->Assign(idx - first, vect->ValAt(idx)); + } + + return result; + } + void IndexExpr::Assign(Frame* f, ValPtr v) { if ( IsError() ) diff --git a/src/Expr.h b/src/Expr.h index ae275a7a84..6b99b1572a 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -941,6 +941,10 @@ protected: bool is_slice; }; +extern VectorValPtr index_slice(VectorVal* vect, const ListVal* lv); +extern VectorValPtr index_slice(VectorVal* vect, int first, int last); +extern StringValPtr index_string(const String* s, const ListVal* lv); + class IndexExprWhen final : public IndexExpr { public: static inline std::vector results = {}; From 22776167bb0f40caa64a19787f082ff981321a27 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 18 Mar 2021 10:04:21 -0700 Subject: [PATCH 03/11] factor out "print" statement's execution functionality --- src/File.h | 7 ++++--- src/Stmt.cc | 15 +++++++++------ src/Stmt.h | 2 ++ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/File.h b/src/File.h index 8ed5d0a13e..78524826b2 100644 --- a/src/File.h +++ b/src/File.h @@ -12,8 +12,7 @@ #include #endif // NEED_KRB5_H -#include "zeek/Obj.h" -#include "zeek/IntrusivePtr.h" +#include "zeek/Val.h" #include "zeek/util.h" namespace zeek { @@ -23,6 +22,8 @@ namespace detail { class PrintStmt; class Attributes; +extern void do_print_stmt(const std::vector& vals); + } // namespace detail; class RecordVal; @@ -84,7 +85,7 @@ public: protected: - friend class detail::PrintStmt; + friend void detail::do_print_stmt(const std::vector& vals); File() { Init(); } void Init(); diff --git a/src/Stmt.cc b/src/Stmt.cc index fed57f9496..77beb1c9e9 100644 --- a/src/Stmt.cc +++ b/src/Stmt.cc @@ -306,18 +306,23 @@ ValPtr PrintStmt::DoExec(std::vector vals, StmtFlowType& /* flow */) { RegisterAccess(); + do_print_stmt(vals); + return nullptr; + } +void do_print_stmt(const std::vector& vals) + { if ( ! print_stdout ) print_stdout = new File(stdout); File* f = print_stdout; int offset = 0; - if ( vals.size() > 0 && (vals)[0]->GetType()->Tag() == TYPE_FILE ) + if ( vals.size() > 0 && vals[0] && vals[0]->GetType()->Tag() == TYPE_FILE ) { f = (vals)[0]->AsFile(); if ( ! f->IsOpen() ) - return nullptr; + return; ++offset; } @@ -331,7 +336,7 @@ ValPtr PrintStmt::DoExec(std::vector vals, case BifEnum::Log::REDIRECT_ALL: { print_log(vals); - return nullptr; + return; } case BifEnum::Log::REDIRECT_STDOUT: if ( f->FileHandle() == stdout ) @@ -339,7 +344,7 @@ ValPtr PrintStmt::DoExec(std::vector vals, // Should catch even printing to a "manually opened" stdout file, // like "/dev/stdout" or "-". print_log(vals); - return nullptr; + return; } break; default: @@ -368,8 +373,6 @@ ValPtr PrintStmt::DoExec(std::vector vals, describe_vals(vals, &d, offset); f->Write("\n", 1); } - - return nullptr; } ExprStmt::ExprStmt(ExprPtr arg_e) : Stmt(STMT_EXPR), e(std::move(arg_e)) diff --git a/src/Stmt.h b/src/Stmt.h index bd26492afe..9bf13d9c9a 100644 --- a/src/Stmt.h +++ b/src/Stmt.h @@ -62,6 +62,8 @@ protected: StmtPtr DoSubclassReduce(ListExprPtr singletons, Reducer* c) override; }; +extern void do_print_stmt(const std::vector& vals); + class ExprStmt : public Stmt { public: explicit ExprStmt(ExprPtr e); From 5f5ba3881c9bb65bcb13bf61d71ab6a209700f53 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 18 Mar 2021 10:07:15 -0700 Subject: [PATCH 04/11] lower-level method for adding fields to records --- src/Type.cc | 14 +++++++++++--- src/Type.h | 3 +++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Type.cc b/src/Type.cc index 6b39ef9198..97fb94ea03 100644 --- a/src/Type.cc +++ b/src/Type.cc @@ -1043,6 +1043,17 @@ const char* RecordType::AddFields(const type_decl_list& others, TableVal::SaveParseTimeTableState(this); + AddFieldsDirectly(others, add_log_attr); + + RecordVal::ResizeParseTimeRecords(this); + TableVal::RebuildParseTimeTables(); + + return nullptr; + } + +void RecordType::AddFieldsDirectly(const type_decl_list& others, + bool add_log_attr) + { for ( const auto& td : others ) { if ( add_log_attr ) @@ -1059,9 +1070,6 @@ const char* RecordType::AddFields(const type_decl_list& others, } num_fields = types->length(); - RecordVal::ResizeParseTimeRecords(this); - TableVal::RebuildParseTimeTables(); - return nullptr; } void RecordType::DescribeFields(ODesc* d) const diff --git a/src/Type.h b/src/Type.h index 09689ecf90..5a16463263 100644 --- a/src/Type.h +++ b/src/Type.h @@ -623,6 +623,9 @@ public: const char* AddFields(const type_decl_list& types, bool add_log_attr = false); + void AddFieldsDirectly(const type_decl_list& types, + bool add_log_attr = false); + void Describe(ODesc* d) const override; void DescribeReST(ODesc* d, bool roles_only = false) const override; void DescribeFields(ODesc* d) const; From 91c2e050992937f7967e33b4e38dc1f098135cac Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 18 Mar 2021 10:08:31 -0700 Subject: [PATCH 05/11] factor out record coercion; modernize management of coercion "map" --- src/Expr.cc | 41 ++++++++++--------- src/Expr.h | 9 ++-- .../first_set.out | 1 - 3 files changed, 27 insertions(+), 24 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index 24cfde992e..1b2562c2ee 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -3759,8 +3759,7 @@ ValPtr ArithCoerceExpr::Fold(Val* v) const } RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r) - : UnaryExpr(EXPR_RECORD_COERCE, std::move(arg_op)), - map(nullptr), map_size(0) + : UnaryExpr(EXPR_RECORD_COERCE, std::move(arg_op)) { if ( IsError() ) return; @@ -3778,12 +3777,12 @@ RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r) RecordType* t_r = type->AsRecordType(); RecordType* sub_r = op->GetType()->AsRecordType(); - map_size = t_r->NumFields(); - map = new int[map_size]; + int map_size = t_r->NumFields(); + map.reserve(map_size); int i; for ( i = 0; i < map_size; ++i ) - map[i] = -1; // -1 = field is not mapped + map.emplace_back(-1); // -1 = field is not mapped for ( i = 0; i < sub_r->NumFields(); ++i ) { @@ -3865,11 +3864,6 @@ RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r) } } -RecordCoerceExpr::~RecordCoerceExpr() - { - delete [] map; - } - ValPtr RecordCoerceExpr::InitVal(const zeek::Type* t, ValPtr aggr) const { if ( auto v = Eval(nullptr) ) @@ -3892,7 +3886,15 @@ ValPtr RecordCoerceExpr::Fold(Val* v) const if ( same_type(GetType(), Op()->GetType()) ) return IntrusivePtr{NewRef{}, v}; - auto val = make_intrusive(GetType()); + auto rt = cast_intrusive(GetType()); + return coerce_to_record(rt, v, map); + } + +RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v, + const std::vector& map) + { + auto map_size = map.size(); + auto val = make_intrusive(rt); RecordType* val_type = val->GetType()->AsRecordType(); RecordVal* rv = v->AsRecordVal(); @@ -3905,14 +3907,15 @@ ValPtr RecordCoerceExpr::Fold(Val* v) const if ( ! rhs ) { - const auto& def = rv->GetType()->AsRecordType()->FieldDecl( - map[i])->GetAttr(ATTR_DEFAULT); + auto rv_rt = rv->GetType()->AsRecordType(); + const auto& def = rv_rt->FieldDecl(map[i])-> + GetAttr(ATTR_DEFAULT); if ( def ) rhs = def->GetExpr()->Eval(nullptr); } - assert(rhs || GetType()->AsRecordType()->FieldDecl(i)->GetAttr(ATTR_OPTIONAL)); + assert(rhs || rt->FieldDecl(i)->GetAttr(ATTR_OPTIONAL)); if ( ! rhs ) { @@ -3934,21 +3937,19 @@ ValPtr RecordCoerceExpr::Fold(Val* v) const else if ( BothArithmetic(rhs_type->Tag(), field_type->Tag()) && ! same_type(rhs_type, field_type) ) { - if ( auto new_val = check_and_promote(rhs, field_type.get(), false, op->GetLocationInfo()) ) - rhs = std::move(new_val); - else - RuntimeError("Failed type conversion"); + auto new_val = check_and_promote(rhs, field_type.get(), false); + rhs = std::move(new_val); } val->Assign(i, std::move(rhs)); } else { - if ( const auto& def = GetType()->AsRecordType()->FieldDecl(i)->GetAttr(ATTR_DEFAULT) ) + if ( const auto& def = rt->FieldDecl(i)->GetAttr(ATTR_DEFAULT) ) { auto def_val = def->GetExpr()->Eval(nullptr); const auto& def_type = def_val->GetType(); - const auto& field_type = GetType()->AsRecordType()->GetFieldType(i); + const auto& field_type = rt->GetFieldType(i); if ( def_type->Tag() == TYPE_RECORD && field_type->Tag() == TYPE_RECORD && diff --git a/src/Expr.h b/src/Expr.h index 6b99b1572a..33810656e5 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -1170,21 +1170,24 @@ protected: class RecordCoerceExpr final : public UnaryExpr { public: RecordCoerceExpr(ExprPtr op, RecordTypePtr r); - ~RecordCoerceExpr() override; // Optimization-related: ExprPtr Duplicate() override; + const std::vector& Map() const { return map; } + protected: ValPtr InitVal(const zeek::Type* t, ValPtr aggr) const override; ValPtr Fold(Val* v) const override; // For each super-record slot, gives subrecord slot with which to // fill it. - int* map; - int map_size; // equivalent to Type()->AsRecordType()->NumFields() + std::vector map; }; +extern RecordValPtr coerce_to_record(RecordTypePtr rt, Val* v, + const std::vector& map); + class TableCoerceExpr final : public UnaryExpr { public: TableCoerceExpr(ExprPtr op, TableTypePtr r); diff --git a/testing/btest/Baseline/language.type-coerce-numerics/first_set.out b/testing/btest/Baseline/language.type-coerce-numerics/first_set.out index f053ab7046..7af2ad4a31 100644 --- a/testing/btest/Baseline/language.type-coerce-numerics/first_set.out +++ b/testing/btest/Baseline/language.type-coerce-numerics/first_set.out @@ -1,6 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. error in int and ./first_set.zeek, line 46: overflow promoting from unsigned/double to signed arithmetic value (int and 9223372036854775808) -expression error in ./first_set.zeek, line 46: Failed type conversion ((coerce [$ii=9223372036854775808] to record { ii:int &optional; cc:count &optional; dd:double &optional; })) 3 int 4 From 78f18b4fa6458fd483f2a1ae524d8d6a4b140a18 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 18 Mar 2021 10:10:44 -0700 Subject: [PATCH 06/11] support for subclassing ScriptFunc's, esp. for alternate lambda closures --- src/Func.cc | 5 +++++ src/Func.h | 12 +++++++++--- src/broker/Data.cc | 15 ++++++++++++--- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/Func.cc b/src/Func.cc index 319868395e..f24154d1a5 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -587,6 +587,11 @@ bool ScriptFunc::StrengthenClosureReference(Frame* f) return true; } +bool ScriptFunc::CopySemantics() const + { + return type->GetCaptures().has_value(); + } + void ScriptFunc::SetClosureFrame(Frame* f) { if ( closure ) diff --git a/src/Func.h b/src/Func.h index db15fde849..9729fbca1d 100644 --- a/src/Func.h +++ b/src/Func.h @@ -145,7 +145,7 @@ protected: namespace detail { -class ScriptFunc final : public Func { +class ScriptFunc : public Func { public: ScriptFunc(const IDPtr& id, StmtPtr body, const std::vector& inits, @@ -210,12 +210,17 @@ public: */ bool StrengthenClosureReference(Frame* f); + /** + * Whether the function's closure uses copy semantics. + */ + virtual bool CopySemantics() const; + /** * Serializes this function's closure or capture frame. * * @return a serialized version of the function's closure/capture frame. */ - broker::expected SerializeClosure() const; + virtual broker::expected SerializeClosure() const; /** * Sets the captures frame to one built from *data*. @@ -257,6 +262,7 @@ public: protected: ScriptFunc() : Func(SCRIPT_FUNC) {} + StmtPtr AddInits( StmtPtr body, const std::vector& inits); @@ -280,7 +286,7 @@ protected: * * @param f the frame holding the values of capture variables */ - void SetCaptures(Frame* f); + virtual void SetCaptures(Frame* f); private: size_t frame_size; diff --git a/src/broker/Data.cc b/src/broker/Data.cc index 2af93460bd..db372de6fe 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -392,6 +392,17 @@ struct val_converter { if ( a.size() == 2 ) // we have a closure/capture frame { + // Note, seems if we already have a separate + // instance of the same lambda, then unless + // we use a cloned value, we'll step on that + // one's captures, too. This is because + // the capture mapping lives with the Func + // object rather than the FuncVal. However, + // we can't readily Clone() here because + // rval is const (and, grrr, Clone() is not). + // -VP + // rval = rval->Clone(); + auto frame = broker::get_if(a[1]); if ( ! frame ) return nullptr; @@ -400,9 +411,7 @@ struct val_converter { if ( ! b ) return nullptr; - auto copy_semantics = b->GetType()->GetCaptures().has_value(); - - if ( copy_semantics ) + if ( b->CopySemantics() ) { if ( ! b->DeserializeCaptures(*frame) ) return nullptr; From 8782894d7d516ee29fe74d256fc4d2573509812a Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 18 Mar 2021 16:59:08 -0700 Subject: [PATCH 07/11] comments for factored-out index slice functions --- src/Expr.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Expr.h b/src/Expr.h index 33810656e5..3cdecfbb5e 100644 --- a/src/Expr.h +++ b/src/Expr.h @@ -941,8 +941,20 @@ protected: bool is_slice; }; +// The following execute the heart of IndexExpr functionality for +// vector slices and strings. + +// Extracts a slice of a vector, where the span of the slice is specified +// by a list of (exactly) two values. This is how the interpreter develops +// the components of a slice. extern VectorValPtr index_slice(VectorVal* vect, const ListVal* lv); + +// Lower-level access to the slice, where its span is expressed +// directly as integers. extern VectorValPtr index_slice(VectorVal* vect, int first, int last); + +// Returns a subset of a string, with the span specified by a list of +// (exactly) two values. extern StringValPtr index_string(const String* s, const ListVal* lv); class IndexExprWhen final : public IndexExpr { From a7fcc7a5d8e9e47bc397faabd7df3ec6da69778e Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 18 Mar 2021 17:08:12 -0700 Subject: [PATCH 08/11] Use STL functionality to initialize coercion map --- src/Expr.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Expr.cc b/src/Expr.cc index 1b2562c2ee..5778df4235 100644 --- a/src/Expr.cc +++ b/src/Expr.cc @@ -3778,12 +3778,9 @@ RecordCoerceExpr::RecordCoerceExpr(ExprPtr arg_op, RecordTypePtr r) RecordType* sub_r = op->GetType()->AsRecordType(); int map_size = t_r->NumFields(); - map.reserve(map_size); + map.resize(map_size, -1); // -1 = field is not mapped int i; - for ( i = 0; i < map_size; ++i ) - map.emplace_back(-1); // -1 = field is not mapped - for ( i = 0; i < sub_r->NumFields(); ++i ) { int t_i = t_r->FieldOffset(sub_r->FieldName(i)); From 3e07564fb914b55c96d75072aadbe2925986840b Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Thu, 18 Mar 2021 17:12:23 -0700 Subject: [PATCH 09/11] better method name: HasCopySemantics() --- src/Func.cc | 2 +- src/Func.h | 2 +- src/broker/Data.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Func.cc b/src/Func.cc index f24154d1a5..a01362c05e 100644 --- a/src/Func.cc +++ b/src/Func.cc @@ -587,7 +587,7 @@ bool ScriptFunc::StrengthenClosureReference(Frame* f) return true; } -bool ScriptFunc::CopySemantics() const +bool ScriptFunc::HasCopySemantics() const { return type->GetCaptures().has_value(); } diff --git a/src/Func.h b/src/Func.h index 9729fbca1d..b76603eba0 100644 --- a/src/Func.h +++ b/src/Func.h @@ -213,7 +213,7 @@ public: /** * Whether the function's closure uses copy semantics. */ - virtual bool CopySemantics() const; + virtual bool HasCopySemantics() const; /** * Serializes this function's closure or capture frame. diff --git a/src/broker/Data.cc b/src/broker/Data.cc index db372de6fe..6395796801 100644 --- a/src/broker/Data.cc +++ b/src/broker/Data.cc @@ -411,7 +411,7 @@ struct val_converter { if ( ! b ) return nullptr; - if ( b->CopySemantics() ) + if ( b->HasCopySemantics() ) { if ( ! b->DeserializeCaptures(*frame) ) return nullptr; From a2e7dd82c40ce2743e0e084fc969654c2ef6a79f Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Wed, 24 Mar 2021 15:15:19 -0700 Subject: [PATCH 10/11] removal of vestigial #include's (breaking an include loop in the process) --- src/ZVal.cc | 1 - src/ZVal.h | 5 ----- 2 files changed, 6 deletions(-) diff --git a/src/ZVal.cc b/src/ZVal.cc index a5dfea8a7e..119d8c3f2e 100644 --- a/src/ZVal.cc +++ b/src/ZVal.cc @@ -5,7 +5,6 @@ #include "zeek/Func.h" #include "zeek/OpaqueVal.h" #include "zeek/Reporter.h" -#include "zeek/Desc.h" using namespace zeek; diff --git a/src/ZVal.h b/src/ZVal.h index 7cfb228047..1e1af6e900 100644 --- a/src/ZVal.h +++ b/src/ZVal.h @@ -6,11 +6,6 @@ #include "zeek/zeek-config.h" -#include - -#include "zeek/Dict.h" -#include "zeek/Expr.h" - namespace zeek { class StringVal; From a288800b41e5261acb04d9aedd4e215c96e73cc0 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Wed, 24 Mar 2021 15:16:03 -0700 Subject: [PATCH 11/11] test suite update due to factoring out coerce_to_record() --- doc | 2 +- .../btest/Baseline/language.type-coerce-numerics/first_set.out | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc b/doc index afd337f4b0..412a46b035 160000 --- a/doc +++ b/doc @@ -1 +1 @@ -Subproject commit afd337f4b00477401514ae3dc9c20476229318dc +Subproject commit 412a46b035a646f890933de84ac2e7b71c6473a7 diff --git a/testing/btest/Baseline/language.type-coerce-numerics/first_set.out b/testing/btest/Baseline/language.type-coerce-numerics/first_set.out index 7af2ad4a31..4809986d53 100644 --- a/testing/btest/Baseline/language.type-coerce-numerics/first_set.out +++ b/testing/btest/Baseline/language.type-coerce-numerics/first_set.out @@ -1,5 +1,5 @@ ### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. -error in int and ./first_set.zeek, line 46: overflow promoting from unsigned/double to signed arithmetic value (int and 9223372036854775808) +error in int: overflow promoting from unsigned/double to signed arithmetic value (int and 9223372036854775808) 3 int 4