mirror of
https://github.com/zeek/zeek.git
synced 2025-10-05 16:18:19 +00:00
Merge remote-tracking branch 'origin/topic/vern/CPP-type-switch'
* origin/topic/vern/CPP-type-switch: support for compiling type-based switches to C++ make encountering uncompilable "standalone" functions to be a hard error fix: ZAM could misinterpret a "type" switch that starts with a "default" fix: don't treat pseudo-identifiers in type cases as local variables removed development helper scripts now obsolete with --optimize-files=
This commit is contained in:
commit
2accf6dfbf
18 changed files with 130 additions and 139 deletions
12
CHANGES
12
CHANGES
|
@ -1,3 +1,15 @@
|
||||||
|
5.0.0-dev.39 | 2022-01-11 15:02:37 -0700
|
||||||
|
|
||||||
|
* support for compiling type-based switches to C++ (Vern Paxson, Corelight)
|
||||||
|
|
||||||
|
* make encountering uncompilable "standalone" functions to be a hard error (Vern Paxson, Corelight)
|
||||||
|
|
||||||
|
* fix: ZAM could misinterpret a "type" switch that starts with a "default" (Vern Paxson, Corelight)
|
||||||
|
|
||||||
|
* fix: don't treat pseudo-identifiers in type cases as local variables (Vern Paxson, Corelight)
|
||||||
|
|
||||||
|
* removed development helper scripts now obsolete with --optimize-files= (Vern Paxson, Corelight)
|
||||||
|
|
||||||
5.0.0-dev.33 | 2022-01-11 14:57:58 -0700
|
5.0.0-dev.33 | 2022-01-11 14:57:58 -0700
|
||||||
|
|
||||||
* Bump CI sanitizer task to Ubuntu 20.04 (Tim Wojtulewicz, Corelight)
|
* Bump CI sanitizer task to Ubuntu 20.04 (Tim Wojtulewicz, Corelight)
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
5.0.0-dev.33
|
5.0.0-dev.39
|
||||||
|
|
|
@ -191,6 +191,7 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class ZAMCompiler;
|
friend class ZAMCompiler;
|
||||||
|
friend class CPPCompile;
|
||||||
|
|
||||||
int DefaultCaseIndex() const { return default_case_idx; }
|
int DefaultCaseIndex() const { return default_case_idx; }
|
||||||
const auto& ValueMap() const { return case_label_value_map; }
|
const auto& ValueMap() const { return case_label_value_map; }
|
||||||
|
|
|
@ -718,7 +718,11 @@ private:
|
||||||
void GenAddStmt(const ExprStmt* es);
|
void GenAddStmt(const ExprStmt* es);
|
||||||
void GenDeleteStmt(const ExprStmt* es);
|
void GenDeleteStmt(const ExprStmt* es);
|
||||||
void GenEventStmt(const EventStmt* ev);
|
void GenEventStmt(const EventStmt* ev);
|
||||||
|
|
||||||
void GenSwitchStmt(const SwitchStmt* sw);
|
void GenSwitchStmt(const SwitchStmt* sw);
|
||||||
|
void GenTypeSwitchStmt(const Expr* e, const case_list* cases);
|
||||||
|
void GenTypeSwitchCase(const ID* id, int case_offset, bool is_multi);
|
||||||
|
void GenValueSwitchStmt(const Expr* e, const case_list* cases);
|
||||||
|
|
||||||
void GenForStmt(const ForStmt* f);
|
void GenForStmt(const ForStmt* f);
|
||||||
void GenForOverTable(const ExprPtr& tbl, const IDPtr& value_var, const IDPList* loop_vars);
|
void GenForOverTable(const ExprPtr& tbl, const IDPtr& value_var, const IDPList* loop_vars);
|
||||||
|
|
|
@ -113,8 +113,13 @@ void CPPCompile::Compile(bool report_uncompilable)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ( reason && report_uncompilable )
|
if ( reason && standalone )
|
||||||
|
reporter->Error("%s cannot be compiled to standalone C++ due to %s", f->Name(),
|
||||||
|
reason);
|
||||||
|
|
||||||
|
else if ( reason && report_uncompilable )
|
||||||
fprintf(stderr, "%s cannot be compiled to C++ due to %s\n", f->Name(), reason);
|
fprintf(stderr, "%s cannot be compiled to C++ due to %s\n", f->Name(), reason);
|
||||||
|
|
||||||
not_fully_compilable.insert(f->Name());
|
not_fully_compilable.insert(f->Name());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,9 +176,6 @@ an extensible record (i.e., fields added using `redef`).
|
||||||
* The compiler will not compile bodies that include "when" statements
|
* The compiler will not compile bodies that include "when" statements
|
||||||
This is fairly involved to fix.
|
This is fairly involved to fix.
|
||||||
|
|
||||||
* The compiler will not compile bodies that include "type" switches.
|
|
||||||
This is not hard to fix.
|
|
||||||
|
|
||||||
* If a lambda generates an event that is not otherwise referred to, that
|
* If a lambda generates an event that is not otherwise referred to, that
|
||||||
event will not be registered upon instantiating the lambda. This is not
|
event will not be registered upon instantiating the lambda. This is not
|
||||||
particularly difficult to fix.
|
particularly difficult to fix.
|
||||||
|
|
|
@ -233,6 +233,104 @@ void CPPCompile::GenSwitchStmt(const SwitchStmt* sw)
|
||||||
auto e = sw->StmtExpr();
|
auto e = sw->StmtExpr();
|
||||||
auto cases = sw->Cases();
|
auto cases = sw->Cases();
|
||||||
|
|
||||||
|
if ( sw->TypeMap()->empty() )
|
||||||
|
GenValueSwitchStmt(e, cases);
|
||||||
|
else
|
||||||
|
GenTypeSwitchStmt(e, cases);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPPCompile::GenTypeSwitchStmt(const Expr* e, const case_list* cases)
|
||||||
|
{
|
||||||
|
// Start a scoping block so we avoid naming conflicts if a function
|
||||||
|
// has multiple type switches.
|
||||||
|
Emit("{");
|
||||||
|
Emit("static std::vector<int> CPP__switch_types =");
|
||||||
|
StartBlock();
|
||||||
|
|
||||||
|
for ( const auto& c : *cases )
|
||||||
|
{
|
||||||
|
auto tc = c->TypeCases();
|
||||||
|
if ( tc )
|
||||||
|
for ( auto id : *tc )
|
||||||
|
Emit(Fmt(TypeOffset(id->GetType())) + ",");
|
||||||
|
}
|
||||||
|
EndBlock(true);
|
||||||
|
|
||||||
|
NL();
|
||||||
|
|
||||||
|
Emit("ValPtr CPP__sw_val = %s;", GenExpr(e, GEN_VAL_PTR));
|
||||||
|
Emit("auto& CPP__sw_val_t = CPP__sw_val->GetType();");
|
||||||
|
Emit("int CPP__sw_type_ind = 0;");
|
||||||
|
|
||||||
|
Emit("for ( auto CPP__st : CPP__switch_types )");
|
||||||
|
StartBlock();
|
||||||
|
Emit("if ( can_cast_value_to_type(CPP__sw_val.get(), CPP__Type__[CPP__st].get()) )");
|
||||||
|
Emit("\tbreak;");
|
||||||
|
Emit("++CPP__sw_type_ind;");
|
||||||
|
EndBlock();
|
||||||
|
|
||||||
|
Emit("switch ( CPP__sw_type_ind ) {");
|
||||||
|
|
||||||
|
++break_level;
|
||||||
|
|
||||||
|
int case_offset = 0;
|
||||||
|
|
||||||
|
for ( const auto& c : *cases )
|
||||||
|
{
|
||||||
|
auto tc = c->TypeCases();
|
||||||
|
if ( tc )
|
||||||
|
{
|
||||||
|
bool is_multi = tc->size() > 1;
|
||||||
|
for ( auto id : *tc )
|
||||||
|
GenTypeSwitchCase(id, case_offset++, is_multi);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Emit("default:");
|
||||||
|
|
||||||
|
StartBlock();
|
||||||
|
GenStmt(c->Body());
|
||||||
|
EndBlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
--break_level;
|
||||||
|
|
||||||
|
Emit("}"); // end the switch
|
||||||
|
Emit("}"); // end the scoping block
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPPCompile::GenTypeSwitchCase(const ID* id, int case_offset, bool is_multi)
|
||||||
|
{
|
||||||
|
Emit("case %s:", Fmt(case_offset));
|
||||||
|
|
||||||
|
if ( ! id->Name() )
|
||||||
|
// No assignment, we're done.
|
||||||
|
return;
|
||||||
|
|
||||||
|
// It's an assignment case. If it's a collection of multiple cases,
|
||||||
|
// assign to the variable only for this particular case.
|
||||||
|
IndentUp();
|
||||||
|
|
||||||
|
if ( is_multi )
|
||||||
|
{
|
||||||
|
Emit("if ( CPP__sw_type_ind == %s )", Fmt(case_offset));
|
||||||
|
IndentUp();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto targ_val = "CPP__sw_val.get()";
|
||||||
|
auto targ_type = string("CPP__Type__[CPP__switch_types[") + Fmt(case_offset) + "]].get()";
|
||||||
|
|
||||||
|
auto cast = string("cast_value_to_type(") + targ_val + ", " + targ_type + ")";
|
||||||
|
|
||||||
|
Emit("%s = %s;", LocalName(id), GenericValPtrToGT(cast, id->GetType(), GEN_NATIVE));
|
||||||
|
|
||||||
|
IndentDown();
|
||||||
|
|
||||||
|
if ( is_multi )
|
||||||
|
IndentDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPPCompile::GenValueSwitchStmt(const Expr* e, const case_list* cases)
|
||||||
|
{
|
||||||
auto e_it = e->GetType()->InternalType();
|
auto e_it = e->GetType()->InternalType();
|
||||||
bool is_int = e_it == TYPE_INTERNAL_INT;
|
bool is_int = e_it == TYPE_INTERNAL_INT;
|
||||||
bool is_uint = e_it == TYPE_INTERNAL_UNSIGNED;
|
bool is_uint = e_it == TYPE_INTERNAL_UNSIGNED;
|
||||||
|
|
|
@ -45,13 +45,6 @@ bool is_CPP_compilable(const ProfileFunc* pf, const char** reason)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( pf->TypeSwitches().size() > 0 )
|
|
||||||
{
|
|
||||||
if ( reason )
|
|
||||||
*reason = "use of type-based \"switch\"";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto body = pf->ProfiledBody();
|
auto body = pf->ProfiledBody();
|
||||||
if ( body && ! body->GetOptInfo()->is_free_of_conditionals )
|
if ( body && ! body->GetOptInfo()->is_free_of_conditionals )
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
build=../../../build
|
|
||||||
|
|
||||||
cd $build
|
|
||||||
export -n ZEEK_USE_CPP ZEEK_ADD_CPP
|
|
||||||
export ZEEK_HASH_DIR=.
|
|
||||||
echo | src/zeek -b -O gen-C++
|
|
||||||
ninja || echo Bare embedded build failed
|
|
|
@ -1,12 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
base=../../..
|
|
||||||
test=$base/testing/btest
|
|
||||||
so=$base/src/script_opt/CPP
|
|
||||||
build=$base/build
|
|
||||||
gen=CPP-gen-addl.h
|
|
||||||
|
|
||||||
export -n ZEEK_ADD_CPP
|
|
||||||
cd $test
|
|
||||||
rm -rf .tmp
|
|
||||||
../../auxil/btest/btest -j -a cpp -f cpp-test.diag $1
|
|
|
@ -1,9 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
build=../../../build
|
|
||||||
|
|
||||||
cd $build
|
|
||||||
export -n ZEEK_USE_CPP ZEEK_ADD_CPP
|
|
||||||
export ZEEK_HASH_DIR=.
|
|
||||||
echo | src/zeek -O gen-C++
|
|
||||||
ninja || echo Full embedded build failed
|
|
|
@ -1,5 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
cd ../../../build
|
|
||||||
echo >CPP-gen.cc
|
|
||||||
ninja || echo Non-embedded build failed
|
|
|
@ -1,24 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
echo $1
|
|
||||||
|
|
||||||
base=../../..
|
|
||||||
test=$base/testing/btest
|
|
||||||
build=$base/build
|
|
||||||
gen=CPP-gen.cc
|
|
||||||
|
|
||||||
./non-embedded-build >$build/errs 2>&1 || echo non-embedded build failed
|
|
||||||
|
|
||||||
export -n ZEEK_USE_CPP
|
|
||||||
export ZEEK_HASH_DIR=$test ZEEK_GEN_CPP=
|
|
||||||
cd $test
|
|
||||||
../../auxil/btest/btest $1 >jbuild-$1.out 2>&1
|
|
||||||
grep -c '^namespace' $gen
|
|
||||||
mv $gen $build/
|
|
||||||
cd $build
|
|
||||||
ninja >&errs || echo build for $1 failed
|
|
||||||
|
|
||||||
export -n ZEEK_GEN_CPP
|
|
||||||
cd $test
|
|
||||||
rm -rf .tmp
|
|
||||||
../../auxil/btest/btest -a cpp -f cpp-test.$1.diag $1
|
|
|
@ -1,23 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
echo $1
|
|
||||||
|
|
||||||
base=../../..
|
|
||||||
test=$base/testing/btest
|
|
||||||
build=$base/build
|
|
||||||
gen=CPP-gen.cc
|
|
||||||
|
|
||||||
export -n ZEEK_USE_CPP
|
|
||||||
export ZEEK_HASH_DIR=$test ZEEK_ADD_CPP=
|
|
||||||
cd $test
|
|
||||||
cp $build/CPP-hashes.dat .
|
|
||||||
../../auxil/btest/btest $1 >cpp-build-$1.out 2>&1
|
|
||||||
grep -c '^namespace' $gen
|
|
||||||
mv $gen $build
|
|
||||||
cd $build
|
|
||||||
ninja >&errs || echo build for $1 failed
|
|
||||||
|
|
||||||
export -n ZEEK_ADD_CPP
|
|
||||||
cd $test
|
|
||||||
rm -rf .tmp
|
|
||||||
../../auxil/btest/btest -j -a cpp -f cpp-test.$1.diag $1
|
|
|
@ -1,18 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
base=../../..
|
|
||||||
test=$base/testing/btest
|
|
||||||
so=$base/src/script_opt/CPP
|
|
||||||
build=$base/build
|
|
||||||
gen=CPP-gen-addl.h
|
|
||||||
|
|
||||||
export -n ZEEK_USE_CPP
|
|
||||||
export ZEEK_HASH_DIR=$test ZEEK_ADD_CPP=
|
|
||||||
cd $test
|
|
||||||
cp $build/CPP-hashes.dat .
|
|
||||||
echo >$gen
|
|
||||||
../../auxil/btest/btest $1 >test-suite-build.out 2>&1
|
|
||||||
grep -c '^namespace' $gen
|
|
||||||
mv $gen $so
|
|
||||||
cd $build
|
|
||||||
ninja >&errs || echo test suite build failed
|
|
|
@ -1,21 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
base=../../..
|
|
||||||
test=$base/testing/btest
|
|
||||||
build=$base/build
|
|
||||||
gen=CPP-gen.cc
|
|
||||||
|
|
||||||
export -n ZEEK_USE_CPP
|
|
||||||
export ZEEK_HASH_DIR=$test ZEEK_ADD_CPP=
|
|
||||||
cd $test
|
|
||||||
cp $build/CPP-hashes.dat .
|
|
||||||
../../auxil/btest/btest $1 >jbuild-$1.out 2>&1
|
|
||||||
grep -c '^namespace' $gen
|
|
||||||
mv $gen $build/
|
|
||||||
cd $build
|
|
||||||
ninja >&errs || echo build for $1 failed
|
|
||||||
|
|
||||||
export -n ZEEK_ADD_CPP
|
|
||||||
cd $test
|
|
||||||
rm -rf .tmp
|
|
||||||
../../auxil/btest/btest -U -a cpp -f cpp-test.$1.diag.update $1
|
|
|
@ -174,7 +174,11 @@ TraversalCode ProfileFunc::PreStmt(const Stmt* s)
|
||||||
if ( idl )
|
if ( idl )
|
||||||
{
|
{
|
||||||
for ( auto id : *idl )
|
for ( auto id : *idl )
|
||||||
locals.insert(id);
|
// Make sure it's not a placeholder
|
||||||
|
// identifier, used when there's
|
||||||
|
// no explicit one.
|
||||||
|
if ( id->Name() )
|
||||||
|
locals.insert(id);
|
||||||
|
|
||||||
is_type_switch = true;
|
is_type_switch = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -410,12 +410,10 @@ const ZAMStmt ZAMCompiler::CompileSwitch(const SwitchStmt* sw)
|
||||||
// Need to track a new set of contexts for "break" statements.
|
// Need to track a new set of contexts for "break" statements.
|
||||||
PushBreaks();
|
PushBreaks();
|
||||||
|
|
||||||
auto& cases = *sw->Cases();
|
if ( sw->TypeMap()->empty() )
|
||||||
|
|
||||||
if ( cases.length() > 0 && cases[0]->TypeCases() )
|
|
||||||
return TypeSwitch(sw, n, c);
|
|
||||||
else
|
|
||||||
return ValueSwitch(sw, n, c);
|
return ValueSwitch(sw, n, c);
|
||||||
|
else
|
||||||
|
return TypeSwitch(sw, n, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
const ZAMStmt ZAMCompiler::ValueSwitch(const SwitchStmt* sw, const NameExpr* v, const ConstExpr* c)
|
const ZAMStmt ZAMCompiler::ValueSwitch(const SwitchStmt* sw, const NameExpr* v, const ConstExpr* c)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue