mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 06:38:20 +00:00
ZAM implementation, pre-debugging
This commit is contained in:
parent
3a0b9325cc
commit
e75c706488
7 changed files with 161 additions and 14 deletions
|
@ -765,7 +765,7 @@ unsigned int StmtList::FindRecAssignmentChain(unsigned int i) const {
|
||||||
std::set<int> fields_seen;
|
std::set<int> fields_seen;
|
||||||
|
|
||||||
for ( ; i < stmts.size(); ++i ) {
|
for ( ; i < stmts.size(); ++i ) {
|
||||||
auto& s = stmts[i];
|
const auto& s = stmts[i];
|
||||||
|
|
||||||
// We're looking for either "x$a = y$b" or "x$a = x$a + y$b".
|
// We're looking for either "x$a = y$b" or "x$a = x$a + y$b".
|
||||||
if ( s->Tag() != STMT_EXPR )
|
if ( s->Tag() != STMT_EXPR )
|
||||||
|
@ -843,6 +843,10 @@ void StmtList::UpdateAssignmentChains(const StmtPtr& s, OpChain& assign_chains,
|
||||||
if ( rhs_op2->Tag() != EXPR_FIELD )
|
if ( rhs_op2->Tag() != EXPR_FIELD )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ( ! IsArithmetic(rhs_op2->GetType()->Tag()) )
|
||||||
|
// Avoid esoteric forms of adding.
|
||||||
|
return;
|
||||||
|
|
||||||
f = rhs_op2->AsFieldExpr();
|
f = rhs_op2->AsFieldExpr();
|
||||||
c = &add_chains;
|
c = &add_chains;
|
||||||
}
|
}
|
||||||
|
@ -922,8 +926,15 @@ bool StmtList::SimplifyChain(unsigned int start, unsigned int end, std::vector<S
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
f_stmts.push_back(TransformChain(assign_chains, EXPR_ASSIGN, chain_stmts));
|
auto as_c = TransformChain(assign_chains, EXPR_ASSIGN, chain_stmts);
|
||||||
f_stmts.push_back(TransformChain(add_chains, EXPR_ADD, chain_stmts));
|
auto ad_c = TransformChain(add_chains, EXPR_ADD, chain_stmts);
|
||||||
|
|
||||||
|
ASSERT(as_c || ad_c);
|
||||||
|
|
||||||
|
if ( as_c )
|
||||||
|
f_stmts.push_back(as_c);
|
||||||
|
if ( ad_c )
|
||||||
|
f_stmts.push_back(ad_c);
|
||||||
|
|
||||||
// At this point, chain_stmts has only the remainders that weren't removed.
|
// At this point, chain_stmts has only the remainders that weren't removed.
|
||||||
for ( auto s : stmts )
|
for ( auto s : stmts )
|
||||||
|
@ -939,8 +950,10 @@ bool StmtList::ReduceStmt(unsigned int& s_i, std::vector<StmtPtr>& f_stmts, Redu
|
||||||
auto old_stmt = stmt_i;
|
auto old_stmt = stmt_i;
|
||||||
|
|
||||||
auto chain_end = FindRecAssignmentChain(s_i);
|
auto chain_end = FindRecAssignmentChain(s_i);
|
||||||
if ( chain_end > s_i && SimplifyChain(s_i, chain_end - 1, f_stmts) )
|
if ( chain_end > s_i && SimplifyChain(s_i, chain_end - 1, f_stmts) ) {
|
||||||
|
s_i = chain_end - 1;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
auto stmt = stmt_i->Reduce(c);
|
auto stmt = stmt_i->Reduce(c);
|
||||||
|
|
||||||
|
|
|
@ -189,6 +189,7 @@ private:
|
||||||
const ZAMStmt CompileAddToExpr(const AddToExpr* e);
|
const ZAMStmt CompileAddToExpr(const AddToExpr* e);
|
||||||
const ZAMStmt CompileRemoveFromExpr(const RemoveFromExpr* e);
|
const ZAMStmt CompileRemoveFromExpr(const RemoveFromExpr* e);
|
||||||
const ZAMStmt CompileAssignExpr(const AssignExpr* e);
|
const ZAMStmt CompileAssignExpr(const AssignExpr* e);
|
||||||
|
const ZAMStmt CompileRecFieldUpdates(const RecordFieldUpdates* e);
|
||||||
const ZAMStmt CompileZAMBuiltin(const NameExpr* lhs, const ScriptOptBuiltinExpr* zbi);
|
const ZAMStmt CompileZAMBuiltin(const NameExpr* lhs, const ScriptOptBuiltinExpr* zbi);
|
||||||
const ZAMStmt CompileAssignToIndex(const NameExpr* lhs, const IndexExpr* rhs);
|
const ZAMStmt CompileAssignToIndex(const NameExpr* lhs, const IndexExpr* rhs);
|
||||||
const ZAMStmt CompileFieldLHSAssignExpr(const FieldLHSAssignExpr* e);
|
const ZAMStmt CompileFieldLHSAssignExpr(const FieldLHSAssignExpr* e);
|
||||||
|
|
|
@ -22,6 +22,9 @@ const ZAMStmt ZAMCompiler::CompileExpr(const Expr* e) {
|
||||||
|
|
||||||
case EXPR_ASSIGN: return CompileAssignExpr(static_cast<const AssignExpr*>(e));
|
case EXPR_ASSIGN: return CompileAssignExpr(static_cast<const AssignExpr*>(e));
|
||||||
|
|
||||||
|
case EXPR_REC_ASSIGN_FIELDS:
|
||||||
|
case EXPR_REC_ADD_FIELDS: return CompileRecFieldUpdates(static_cast<const RecordFieldUpdates*>(e));
|
||||||
|
|
||||||
case EXPR_INDEX_ASSIGN: {
|
case EXPR_INDEX_ASSIGN: {
|
||||||
auto iae = static_cast<const IndexAssignExpr*>(e);
|
auto iae = static_cast<const IndexAssignExpr*>(e);
|
||||||
auto t = iae->GetOp1()->GetType()->Tag();
|
auto t = iae->GetOp1()->GetType()->Tag();
|
||||||
|
@ -227,6 +230,64 @@ const ZAMStmt ZAMCompiler::CompileAssignExpr(const AssignExpr* e) {
|
||||||
#include "ZAM-GenExprsDefsV.h"
|
#include "ZAM-GenExprsDefsV.h"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const ZAMStmt ZAMCompiler::CompileRecFieldUpdates(const RecordFieldUpdates* e) {
|
||||||
|
auto lhs = e->GetOp1()->AsNameExpr();
|
||||||
|
auto rhs = e->GetOp2()->AsNameExpr();
|
||||||
|
|
||||||
|
auto& rhs_map = e->RHSMap();
|
||||||
|
|
||||||
|
auto aux = new ZInstAux(0);
|
||||||
|
aux->map = e->LHSMap();
|
||||||
|
aux->rhs_map = e->RHSMap();
|
||||||
|
|
||||||
|
std::set<TypeTag> field_tags;
|
||||||
|
|
||||||
|
bool is_managed = false;
|
||||||
|
|
||||||
|
for ( auto i : rhs_map ) {
|
||||||
|
auto rt = rhs->GetType()->AsRecordType();
|
||||||
|
auto rt_ft_i = rt->GetFieldType(i);
|
||||||
|
field_tags.insert(rt_ft_i->Tag());
|
||||||
|
|
||||||
|
if ( ZVal::IsManagedType(rt_ft_i) ) {
|
||||||
|
aux->is_managed.push_back(true);
|
||||||
|
is_managed = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
// This will only be needed if is_managed winds up being true,
|
||||||
|
// but it's harmless to build it up in any case.
|
||||||
|
aux->is_managed.push_back(false);
|
||||||
|
|
||||||
|
// The following is only needed for non-homogeneous "add"s, but
|
||||||
|
// likewise it's harmless to build it anyway.
|
||||||
|
aux->types.push_back(rt_ft_i);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool homogeneous = field_tags.size() == 1;
|
||||||
|
if ( ! homogeneous && field_tags.size() == 2 && field_tags.count(TYPE_INT) > 0 && field_tags.count(TYPE_COUNT) > 0 )
|
||||||
|
homogeneous = true;
|
||||||
|
|
||||||
|
ZOp op;
|
||||||
|
|
||||||
|
if ( e->Tag() == EXPR_REC_ASSIGN_FIELDS )
|
||||||
|
op = is_managed ? OP_REC_ASSIGN_FIELDS_MANAGED_VV : OP_REC_ASSIGN_FIELDS_VV;
|
||||||
|
|
||||||
|
else if ( homogeneous ) {
|
||||||
|
if ( field_tags.count(TYPE_DOUBLE) > 0 )
|
||||||
|
op = OP_REC_ADD_DOUBLE_FIELDS_VV;
|
||||||
|
else
|
||||||
|
op = OP_REC_ADD_INT_FIELDS_VV;
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
op = OP_REC_ADD_FIELDS_VV;
|
||||||
|
|
||||||
|
auto z = GenInst(op, lhs, rhs);
|
||||||
|
z.aux = aux;
|
||||||
|
|
||||||
|
return AddInst(z);
|
||||||
|
}
|
||||||
|
|
||||||
const ZAMStmt ZAMCompiler::CompileZAMBuiltin(const NameExpr* lhs, const ScriptOptBuiltinExpr* zbi) {
|
const ZAMStmt ZAMCompiler::CompileZAMBuiltin(const NameExpr* lhs, const ScriptOptBuiltinExpr* zbi) {
|
||||||
auto op1 = zbi->GetOp1();
|
auto op1 = zbi->GetOp1();
|
||||||
auto op2 = zbi->GetOp2();
|
auto op2 = zbi->GetOp2();
|
||||||
|
|
|
@ -51,9 +51,9 @@ public:
|
||||||
if ( lv < 0 )
|
if ( lv < 0 )
|
||||||
continue;
|
continue;
|
||||||
auto& var = frame[lv];
|
auto& var = frame[lv];
|
||||||
if ( aux->lvt_is_managed[i] )
|
if ( aux->is_managed[i] )
|
||||||
ZVal::DeleteManagedType(var);
|
ZVal::DeleteManagedType(var);
|
||||||
auto& t = aux->loop_var_types[i];
|
auto& t = aux->types[i];
|
||||||
var = ZVal(ind_lv_p, t);
|
var = ZVal(ind_lv_p, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1268,6 +1268,71 @@ eval auto init_vals = z.aux->ToZValVecWithMap(frame);
|
||||||
init_vals[z.v2] = ZVal(run_state::network_time);
|
init_vals[z.v2] = ZVal(run_state::network_time);
|
||||||
ConstructRecordPost()
|
ConstructRecordPost()
|
||||||
|
|
||||||
|
macro SetUpRecFieldOps()
|
||||||
|
auto lhs = frame[z.v1].record_val;
|
||||||
|
auto rhs = frame[z.v2].record_val;
|
||||||
|
auto aux = z.aux;
|
||||||
|
auto& lhs_map = aux->map;
|
||||||
|
auto& rhs_map = aux->rhs_map;
|
||||||
|
auto n = rhs_map.size();
|
||||||
|
|
||||||
|
op Rec-Assign-Fields
|
||||||
|
op1-read
|
||||||
|
type VV
|
||||||
|
eval SetUpRecFieldOps()
|
||||||
|
for ( size_t i = 0U; i < n; ++i )
|
||||||
|
lhs->RawOptField(lhs_map[i]) = rhs->RawField(rhs_map[i]);
|
||||||
|
|
||||||
|
op Rec-Assign-Fields-Managed
|
||||||
|
op1-read
|
||||||
|
type VV
|
||||||
|
eval SetUpRecFieldOps()
|
||||||
|
auto is_managed = aux->is_managed;
|
||||||
|
for ( auto i = 0; i < n; ++i )
|
||||||
|
if ( is_managed[i] )
|
||||||
|
{
|
||||||
|
auto& lhs_i = lhs->RawOptField(lhs_map[i]);
|
||||||
|
auto rhs_i = rhs->RawField(rhs_map[i]);
|
||||||
|
zeek::Ref(rhs_i.ManagedVal());
|
||||||
|
if ( lhs_i )
|
||||||
|
ZVal::DeleteManagedType(*lhs_i);
|
||||||
|
lhs_i = rhs_i;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lhs->RawOptField(lhs_map[i]) = rhs->RawField(rhs_map[i]);
|
||||||
|
|
||||||
|
op Rec-Add-Int-Fields
|
||||||
|
op1-read
|
||||||
|
type VV
|
||||||
|
eval SetUpRecFieldOps()
|
||||||
|
for ( size_t i = 0U; i < n; ++i )
|
||||||
|
lhs->RawField(lhs_map[i]).int_val += rhs->RawField(rhs_map[i]).int_val;
|
||||||
|
|
||||||
|
op Rec-Add-Double-Fields
|
||||||
|
op1-read
|
||||||
|
type VV
|
||||||
|
eval SetUpRecFieldOps()
|
||||||
|
for ( size_t i = 0U; i < n; ++i )
|
||||||
|
lhs->RawField(lhs_map[i]).double_val += rhs->RawField(rhs_map[i]).double_val;
|
||||||
|
|
||||||
|
op Rec-Add-Fields
|
||||||
|
op1-read
|
||||||
|
type VV
|
||||||
|
eval SetUpRecFieldOps()
|
||||||
|
auto& types = aux->types;
|
||||||
|
for ( size_t i = 0U; i < n; ++i )
|
||||||
|
{
|
||||||
|
auto& lhs_i = lhs->RawField(lhs_map[i]);
|
||||||
|
auto rhs_i = rhs->RawField(rhs_map[i]);
|
||||||
|
auto tag = types[i]->Tag();
|
||||||
|
if ( tag == TYPE_INT )
|
||||||
|
lhs_i.int_val += rhs_i.int_val;
|
||||||
|
else if ( tag == TYPE_COUNT )
|
||||||
|
lhs_i.uint_val += rhs_i.uint_val;
|
||||||
|
else
|
||||||
|
lhs_i.double_val += rhs_i.double_val;
|
||||||
|
}
|
||||||
|
|
||||||
# Special instruction for concretizing vectors that are fields in a
|
# Special instruction for concretizing vectors that are fields in a
|
||||||
# newly-constructed record. "aux" holds which fields in the record to
|
# newly-constructed record. "aux" holds which fields in the record to
|
||||||
# inspect.
|
# inspect.
|
||||||
|
|
|
@ -765,8 +765,8 @@ const ZAMStmt ZAMCompiler::LoopOverTable(const ForStmt* f, const NameExpr* val)
|
||||||
int slot = id->IsBlank() ? -1 : FrameSlot(id);
|
int slot = id->IsBlank() ? -1 : FrameSlot(id);
|
||||||
aux->loop_vars.push_back(slot);
|
aux->loop_vars.push_back(slot);
|
||||||
auto& t = id->GetType();
|
auto& t = id->GetType();
|
||||||
aux->loop_var_types.push_back(t);
|
aux->types.push_back(t);
|
||||||
aux->lvt_is_managed.push_back(ZVal::IsManagedType(t));
|
aux->is_managed.push_back(ZVal::IsManagedType(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool no_loop_vars = (num_unused == loop_vars->length());
|
bool no_loop_vars = (num_unused == loop_vars->length());
|
||||||
|
|
|
@ -484,20 +484,27 @@ public:
|
||||||
// store here.
|
// store here.
|
||||||
bool can_change_non_locals = false;
|
bool can_change_non_locals = false;
|
||||||
|
|
||||||
// The following is used for constructing records, to map elements in
|
// The following is used for constructing records or in record chain
|
||||||
// slots/constants/types to record field offsets.
|
// operations, to map elements in slots/constants/types to record field
|
||||||
|
// offsets.
|
||||||
std::vector<int> map;
|
std::vector<int> map;
|
||||||
|
|
||||||
|
// The following is used when we need two maps, a LHS one (done with
|
||||||
|
// the above) and a RHS one.
|
||||||
|
std::vector<int> rhs_map;
|
||||||
|
|
||||||
|
// For operations that need to track types corresponding to other vectors.
|
||||||
|
std::vector<TypePtr> types;
|
||||||
|
|
||||||
|
// For operations that mix managed and unmanaged assignments.
|
||||||
|
std::vector<bool> is_managed;
|
||||||
|
|
||||||
///// The following four apply to looping over the elements of tables.
|
///// The following four apply to looping over the elements of tables.
|
||||||
|
|
||||||
// Frame slots of iteration variables, such as "[v1, v2, v3] in aggr".
|
// Frame slots of iteration variables, such as "[v1, v2, v3] in aggr".
|
||||||
// A negative value means "skip assignment".
|
// A negative value means "skip assignment".
|
||||||
std::vector<int> loop_vars;
|
std::vector<int> loop_vars;
|
||||||
|
|
||||||
// Their types and whether they're managed.
|
|
||||||
std::vector<TypePtr> loop_var_types;
|
|
||||||
std::vector<bool> lvt_is_managed;
|
|
||||||
|
|
||||||
// Type associated with the "value" entry, for "k, value in aggr"
|
// Type associated with the "value" entry, for "k, value in aggr"
|
||||||
// iteration.
|
// iteration.
|
||||||
TypePtr value_var_type;
|
TypePtr value_var_type;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue