mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
binpac: Arrays now suport the &transient attribute.
If set, parsed elements won't actually be added to the array, and read access to the array aren't permitted. This is helpful to save memory in the case of large arrays for which elements don't need (or can't) be buffered.
This commit is contained in:
parent
5db7ba4050
commit
092d049f8e
1 changed files with 79 additions and 66 deletions
|
@ -92,6 +92,9 @@ Type *ArrayType::ElementDataType() const
|
||||||
|
|
||||||
string ArrayType::EvalElement(const string &array, const string &index) const
|
string ArrayType::EvalElement(const string &array, const string &index) const
|
||||||
{
|
{
|
||||||
|
if ( attr_transient_ )
|
||||||
|
throw Exception(this, "cannot access element in &transient array");
|
||||||
|
|
||||||
return strfmt("(*(%s))[%s]", array.c_str(), index.c_str());
|
return strfmt("(*(%s))[%s]", array.c_str(), index.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,18 +133,18 @@ void ArrayType::ProcessAttr(Attr *a)
|
||||||
{
|
{
|
||||||
if ( elemtype_->StaticSize(env()) != 1 )
|
if ( elemtype_->StaticSize(env()) != 1 )
|
||||||
{
|
{
|
||||||
throw Exception(elemtype_,
|
throw Exception(elemtype_,
|
||||||
"&restofdata can be applied"
|
"&restofdata can be applied"
|
||||||
" to only byte arrays");
|
" to only byte arrays");
|
||||||
}
|
}
|
||||||
if ( length_ )
|
if ( length_ )
|
||||||
{
|
{
|
||||||
throw Exception(length_,
|
throw Exception(length_,
|
||||||
"&restofdata cannot be applied"
|
"&restofdata cannot be applied"
|
||||||
" to arrays with specified length");
|
" to arrays with specified length");
|
||||||
}
|
}
|
||||||
attr_restofdata_ = true;
|
attr_restofdata_ = true;
|
||||||
// As the array automatically extends to the end of
|
// As the array automatically extends to the end of
|
||||||
// data, we do not have to check boundary.
|
// data, we do not have to check boundary.
|
||||||
SetBoundaryChecked();
|
SetBoundaryChecked();
|
||||||
}
|
}
|
||||||
|
@ -158,7 +161,7 @@ void ArrayType::ProcessAttr(Attr *a)
|
||||||
bool ref_input = a->expr()->HasReference(input_macro_id);
|
bool ref_input = a->expr()->HasReference(input_macro_id);
|
||||||
if ( ref_element && ref_input )
|
if ( ref_element && ref_input )
|
||||||
{
|
{
|
||||||
throw Exception(a->expr(),
|
throw Exception(a->expr(),
|
||||||
"cannot reference both $element and $input "
|
"cannot reference both $element and $input "
|
||||||
"in the same &until---please separate them.");
|
"in the same &until---please separate them.");
|
||||||
}
|
}
|
||||||
|
@ -167,7 +170,7 @@ void ArrayType::ProcessAttr(Attr *a)
|
||||||
{
|
{
|
||||||
if ( attr_until_element_expr_ )
|
if ( attr_until_element_expr_ )
|
||||||
{
|
{
|
||||||
throw Exception(a->expr(),
|
throw Exception(a->expr(),
|
||||||
"multiple &until on $element");
|
"multiple &until on $element");
|
||||||
}
|
}
|
||||||
attr_until_element_expr_ = a->expr();
|
attr_until_element_expr_ = a->expr();
|
||||||
|
@ -176,7 +179,7 @@ void ArrayType::ProcessAttr(Attr *a)
|
||||||
{
|
{
|
||||||
if ( attr_until_input_expr_ )
|
if ( attr_until_input_expr_ )
|
||||||
{
|
{
|
||||||
throw Exception(a->expr(),
|
throw Exception(a->expr(),
|
||||||
"multiple &until on $input");
|
"multiple &until on $input");
|
||||||
}
|
}
|
||||||
attr_until_input_expr_ = a->expr();
|
attr_until_input_expr_ = a->expr();
|
||||||
|
@ -185,7 +188,7 @@ void ArrayType::ProcessAttr(Attr *a)
|
||||||
{
|
{
|
||||||
if ( attr_generic_until_expr_ )
|
if ( attr_generic_until_expr_ )
|
||||||
{
|
{
|
||||||
throw Exception(a->expr(),
|
throw Exception(a->expr(),
|
||||||
"multiple &until condition");
|
"multiple &until condition");
|
||||||
}
|
}
|
||||||
attr_generic_until_expr_ = a->expr();
|
attr_generic_until_expr_ = a->expr();
|
||||||
|
@ -206,15 +209,15 @@ void ArrayType::Prepare(Env *env, int flags)
|
||||||
ID *elem_var = new ID(fmt("%s__elem", value_var()->Name()));
|
ID *elem_var = new ID(fmt("%s__elem", value_var()->Name()));
|
||||||
ID *elem_it_var = new ID(fmt("%s__it", elem_var->Name()));
|
ID *elem_it_var = new ID(fmt("%s__it", elem_var->Name()));
|
||||||
|
|
||||||
elem_var_field_ =
|
elem_var_field_ =
|
||||||
new ParseVarField(Field::CLASS_MEMBER, elem_var, elemtype_);
|
new ParseVarField(Field::CLASS_MEMBER, elem_var, elemtype_);
|
||||||
AddField(elem_var_field_);
|
AddField(elem_var_field_);
|
||||||
|
|
||||||
if ( incremental_parsing() )
|
if ( incremental_parsing() )
|
||||||
{
|
{
|
||||||
arraylength_var_field_ =
|
arraylength_var_field_ =
|
||||||
new PrivVarField(arraylength_var, extern_type_int->Clone());
|
new PrivVarField(arraylength_var, extern_type_int->Clone());
|
||||||
elem_it_var_field_ =
|
elem_it_var_field_ =
|
||||||
new PrivVarField(elem_it_var, extern_type_int->Clone());
|
new PrivVarField(elem_it_var, extern_type_int->Clone());
|
||||||
|
|
||||||
AddField(arraylength_var_field_);
|
AddField(arraylength_var_field_);
|
||||||
|
@ -222,25 +225,25 @@ void ArrayType::Prepare(Env *env, int flags)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
arraylength_var_field_ =
|
arraylength_var_field_ =
|
||||||
new TempVarField(arraylength_var, extern_type_int->Clone());
|
new TempVarField(arraylength_var, extern_type_int->Clone());
|
||||||
elem_it_var_field_ =
|
elem_it_var_field_ =
|
||||||
new TempVarField(elem_it_var, extern_type_int->Clone());
|
new TempVarField(elem_it_var, extern_type_int->Clone());
|
||||||
|
|
||||||
arraylength_var_field_->Prepare(env);
|
arraylength_var_field_->Prepare(env);
|
||||||
elem_it_var_field_->Prepare(env);
|
elem_it_var_field_->Prepare(env);
|
||||||
|
|
||||||
// Add elem_dataptr_var only when not parsing incrementally
|
// Add elem_dataptr_var only when not parsing incrementally
|
||||||
ID *elem_dataptr_var =
|
ID *elem_dataptr_var =
|
||||||
new ID(fmt("%s__dataptr", elem_var->Name()));
|
new ID(fmt("%s__dataptr", elem_var->Name()));
|
||||||
elem_dataptr_var_field_ = new TempVarField(
|
elem_dataptr_var_field_ = new TempVarField(
|
||||||
elem_dataptr_var,
|
elem_dataptr_var,
|
||||||
extern_type_const_byteptr->Clone());
|
extern_type_const_byteptr->Clone());
|
||||||
elem_dataptr_var_field_->Prepare(env);
|
elem_dataptr_var_field_->Prepare(env);
|
||||||
|
|
||||||
// until(dataptr >= end_of_data)
|
// until(dataptr >= end_of_data)
|
||||||
elem_dataptr_until_expr_ = new Expr(
|
elem_dataptr_until_expr_ = new Expr(
|
||||||
Expr::EXPR_GE,
|
Expr::EXPR_GE,
|
||||||
new Expr(elem_dataptr_var->clone()),
|
new Expr(elem_dataptr_var->clone()),
|
||||||
new Expr(end_of_data->clone()));
|
new Expr(end_of_data->clone()));
|
||||||
}
|
}
|
||||||
|
@ -269,8 +272,8 @@ void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data)
|
||||||
|
|
||||||
if ( length_ )
|
if ( length_ )
|
||||||
{
|
{
|
||||||
out_cc->println("%s = %s;",
|
out_cc->println("%s = %s;",
|
||||||
env->LValue(arraylength_var()),
|
env->LValue(arraylength_var()),
|
||||||
length_->EvalExpr(out_cc, env));
|
length_->EvalExpr(out_cc, env));
|
||||||
|
|
||||||
env->SetEvaluated(arraylength_var());
|
env->SetEvaluated(arraylength_var());
|
||||||
|
@ -285,22 +288,22 @@ void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data)
|
||||||
env->LValue(arraylength_var()));
|
env->LValue(arraylength_var()));
|
||||||
out_cc->println("}");
|
out_cc->println("}");
|
||||||
out_cc->dec_indent();
|
out_cc->dec_indent();
|
||||||
|
|
||||||
// Check negative array length
|
// Check negative array length
|
||||||
out_cc->println("if ( %s < 0 )",
|
out_cc->println("if ( %s < 0 )",
|
||||||
env->LValue(arraylength_var()));
|
env->LValue(arraylength_var()));
|
||||||
out_cc->inc_indent();
|
out_cc->inc_indent();
|
||||||
out_cc->println("{");
|
out_cc->println("{");
|
||||||
out_cc->println("%s = 0;",
|
out_cc->println("%s = 0;",
|
||||||
env->LValue(arraylength_var()));
|
env->LValue(arraylength_var()));
|
||||||
out_cc->println("}");
|
out_cc->println("}");
|
||||||
out_cc->dec_indent();
|
out_cc->dec_indent();
|
||||||
}
|
}
|
||||||
else if ( attr_restofdata_ )
|
else if ( attr_restofdata_ )
|
||||||
{
|
{
|
||||||
ASSERT(elemtype_->StaticSize(env) == 1);
|
ASSERT(elemtype_->StaticSize(env) == 1);
|
||||||
out_cc->println("%s = (%s) - (%s);",
|
out_cc->println("%s = (%s) - (%s);",
|
||||||
env->LValue(arraylength_var()),
|
env->LValue(arraylength_var()),
|
||||||
env->RValue(end_of_data),
|
env->RValue(end_of_data),
|
||||||
data.ptr_expr());
|
data.ptr_expr());
|
||||||
env->SetEvaluated(arraylength_var());
|
env->SetEvaluated(arraylength_var());
|
||||||
|
@ -313,6 +316,9 @@ void ArrayType::GenPubDecls(Output *out_h, Env *env)
|
||||||
|
|
||||||
if ( declared_as_type() )
|
if ( declared_as_type() )
|
||||||
{
|
{
|
||||||
|
if ( attr_transient_ )
|
||||||
|
throw Exception(this, "cannot access element in &transient array");
|
||||||
|
|
||||||
out_h->println("int size() const { return %s ? %s->size() : 0; }",
|
out_h->println("int size() const { return %s ? %s->size() : 0; }",
|
||||||
env->RValue(value_var()),
|
env->RValue(value_var()),
|
||||||
env->RValue(value_var()));
|
env->RValue(value_var()));
|
||||||
|
@ -339,7 +345,7 @@ void ArrayType::GenInitCode(Output *out_cc, Env *env)
|
||||||
Type::GenInitCode(out_cc, env);
|
Type::GenInitCode(out_cc, env);
|
||||||
if ( incremental_parsing() )
|
if ( incremental_parsing() )
|
||||||
{
|
{
|
||||||
out_cc->println("%s = -1;",
|
out_cc->println("%s = -1;",
|
||||||
env->LValue(elem_it_var()));
|
env->LValue(elem_it_var()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -352,10 +358,10 @@ void ArrayType::GenCleanUpCode(Output *out_cc, Env *env)
|
||||||
if ( ! elem_var_field_ )
|
if ( ! elem_var_field_ )
|
||||||
{
|
{
|
||||||
ID *elem_var = new ID(fmt("%s__elem", value_var()->Name()));
|
ID *elem_var = new ID(fmt("%s__elem", value_var()->Name()));
|
||||||
elem_var_field_ =
|
elem_var_field_ =
|
||||||
new ParseVarField(
|
new ParseVarField(
|
||||||
Field::NOT_CLASS_MEMBER,
|
Field::NOT_CLASS_MEMBER,
|
||||||
elem_var,
|
elem_var,
|
||||||
elemtype_);
|
elemtype_);
|
||||||
elem_var_field_->Prepare(env);
|
elem_var_field_->Prepare(env);
|
||||||
}
|
}
|
||||||
|
@ -368,9 +374,9 @@ void ArrayType::GenCleanUpCode(Output *out_cc, Env *env)
|
||||||
env->RValue(value_var()));
|
env->RValue(value_var()));
|
||||||
out_cc->inc_indent();
|
out_cc->inc_indent();
|
||||||
out_cc->println("{");
|
out_cc->println("{");
|
||||||
out_cc->println("%s %s = (*%s)[i];",
|
out_cc->println("%s %s = (*%s)[i];",
|
||||||
elemtype_->DataTypeStr().c_str(),
|
elemtype_->DataTypeStr().c_str(),
|
||||||
env->LValue(elem_var()),
|
env->LValue(elem_var()),
|
||||||
lvalue());
|
lvalue());
|
||||||
elemtype_->GenCleanUpCode(out_cc, env);
|
elemtype_->GenCleanUpCode(out_cc, env);
|
||||||
out_cc->println("}");
|
out_cc->println("}");
|
||||||
|
@ -389,7 +395,7 @@ string ArrayType::GenArrayInit(Output *out_cc, Env *env, bool known_array_length
|
||||||
array_str = lvalue();
|
array_str = lvalue();
|
||||||
if ( incremental_parsing() )
|
if ( incremental_parsing() )
|
||||||
{
|
{
|
||||||
out_cc->println("if ( %s < 0 )",
|
out_cc->println("if ( %s < 0 )",
|
||||||
env->LValue(elem_it_var()));
|
env->LValue(elem_it_var()));
|
||||||
out_cc->inc_indent();
|
out_cc->inc_indent();
|
||||||
out_cc->println("{");
|
out_cc->println("{");
|
||||||
|
@ -397,12 +403,12 @@ string ArrayType::GenArrayInit(Output *out_cc, Env *env, bool known_array_length
|
||||||
out_cc->println("%s = 0;", env->LValue(elem_it_var()));
|
out_cc->println("%s = 0;", env->LValue(elem_it_var()));
|
||||||
}
|
}
|
||||||
|
|
||||||
out_cc->println("%s = new %s;",
|
out_cc->println("%s = new %s;",
|
||||||
lvalue(), vector_str_.c_str());
|
lvalue(), vector_str_.c_str());
|
||||||
|
|
||||||
if ( known_array_length )
|
if ( known_array_length )
|
||||||
{
|
{
|
||||||
out_cc->println("%s->reserve(%s);",
|
out_cc->println("%s->reserve(%s);",
|
||||||
lvalue(), env->RValue(arraylength_var()));
|
lvalue(), env->RValue(arraylength_var()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -418,23 +424,30 @@ string ArrayType::GenArrayInit(Output *out_cc, Env *env, bool known_array_length
|
||||||
void ArrayType::GenElementAssignment(Output *out_cc, Env *env,
|
void ArrayType::GenElementAssignment(Output *out_cc, Env *env,
|
||||||
string const &array_str, bool use_vector)
|
string const &array_str, bool use_vector)
|
||||||
{
|
{
|
||||||
|
if ( attr_transient_ )
|
||||||
|
{
|
||||||
|
// Just discard.
|
||||||
|
out_cc->println("delete %s;", env->LValue(elem_var()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Assign the element
|
// Assign the element
|
||||||
if ( ! use_vector )
|
if ( ! use_vector )
|
||||||
{
|
{
|
||||||
out_cc->println("%s[%s] = %s;",
|
out_cc->println("%s[%s] = %s;",
|
||||||
array_str.c_str(),
|
array_str.c_str(),
|
||||||
env->LValue(elem_it_var()),
|
env->LValue(elem_it_var()),
|
||||||
env->LValue(elem_var()));
|
env->LValue(elem_var()));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out_cc->println("%s->push_back(%s);",
|
out_cc->println("%s->push_back(%s);",
|
||||||
array_str.c_str(),
|
array_str.c_str(),
|
||||||
env->LValue(elem_var()));
|
env->LValue(elem_var()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
|
void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
|
||||||
const DataPtr& data, int flags)
|
const DataPtr& data, int flags)
|
||||||
{
|
{
|
||||||
GenArrayLength(out_cc, env, data);
|
GenArrayLength(out_cc, env, data);
|
||||||
|
@ -466,10 +479,10 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
|
||||||
{
|
{
|
||||||
// Do not compute size_var on incremental input
|
// Do not compute size_var on incremental input
|
||||||
compute_size_var = false;
|
compute_size_var = false;
|
||||||
|
|
||||||
if ( ! incremental_parsing() &&
|
if ( ! incremental_parsing() &&
|
||||||
( StaticSize(env) >= 0 ||
|
( StaticSize(env) >= 0 ||
|
||||||
( env->Evaluated(arraylength_var()) &&
|
( env->Evaluated(arraylength_var()) &&
|
||||||
elemtype_->StaticSize(env) >= 0 ) ) )
|
elemtype_->StaticSize(env) >= 0 ) ) )
|
||||||
{
|
{
|
||||||
GenBoundaryCheck(out_cc, env, data);
|
GenBoundaryCheck(out_cc, env, data);
|
||||||
|
@ -491,7 +504,7 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
|
||||||
|
|
||||||
if ( elem_dataptr_var() )
|
if ( elem_dataptr_var() )
|
||||||
{
|
{
|
||||||
out_cc->println("const_byteptr %s = %s;",
|
out_cc->println("const_byteptr %s = %s;",
|
||||||
env->LValue(elem_dataptr_var()), data.ptr_expr());
|
env->LValue(elem_dataptr_var()), data.ptr_expr());
|
||||||
env->SetEvaluated(elem_dataptr_var());
|
env->SetEvaluated(elem_dataptr_var());
|
||||||
|
|
||||||
|
@ -499,13 +512,13 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
|
||||||
}
|
}
|
||||||
|
|
||||||
string for_condition = known_array_length ?
|
string for_condition = known_array_length ?
|
||||||
strfmt("%s < %s",
|
strfmt("%s < %s",
|
||||||
env->LValue(elem_it_var()),
|
env->LValue(elem_it_var()),
|
||||||
env->RValue(arraylength_var())) :
|
env->RValue(arraylength_var())) :
|
||||||
"/* forever */";
|
"/* forever */";
|
||||||
|
|
||||||
out_cc->println("for (; %s; ++%s)",
|
out_cc->println("for (; %s; ++%s)",
|
||||||
for_condition.c_str(),
|
for_condition.c_str(),
|
||||||
env->LValue(elem_it_var()));
|
env->LValue(elem_it_var()));
|
||||||
out_cc->inc_indent();
|
out_cc->inc_indent();
|
||||||
out_cc->println("{");
|
out_cc->println("{");
|
||||||
|
@ -515,13 +528,13 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
|
||||||
|
|
||||||
if ( elem_dataptr_var() )
|
if ( elem_dataptr_var() )
|
||||||
GenUntilCheck(out_cc, env, elem_dataptr_until_expr_, false);
|
GenUntilCheck(out_cc, env, elem_dataptr_until_expr_, false);
|
||||||
|
|
||||||
elemtype_->GenPreParsing(out_cc, env);
|
elemtype_->GenPreParsing(out_cc, env);
|
||||||
elemtype_->GenParseCode(out_cc, env, elem_data, flags);
|
elemtype_->GenParseCode(out_cc, env, elem_data, flags);
|
||||||
|
|
||||||
if ( incremental_parsing() )
|
if ( incremental_parsing() )
|
||||||
{
|
{
|
||||||
out_cc->println("if ( ! %s )",
|
out_cc->println("if ( ! %s )",
|
||||||
elemtype_->parsing_complete(env).c_str());
|
elemtype_->parsing_complete(env).c_str());
|
||||||
out_cc->inc_indent();
|
out_cc->inc_indent();
|
||||||
out_cc->println("goto %s;", kNeedMoreData);
|
out_cc->println("goto %s;", kNeedMoreData);
|
||||||
|
@ -532,11 +545,11 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
|
||||||
|
|
||||||
if ( elem_dataptr_var() )
|
if ( elem_dataptr_var() )
|
||||||
{
|
{
|
||||||
out_cc->println("%s += %s;",
|
out_cc->println("%s += %s;",
|
||||||
env->LValue(elem_dataptr_var()),
|
env->LValue(elem_dataptr_var()),
|
||||||
elemtype_->DataSize(0, env, elem_data).c_str());
|
elemtype_->DataSize(0, env, elem_data).c_str());
|
||||||
out_cc->println("BINPAC_ASSERT(%s <= %s);",
|
out_cc->println("BINPAC_ASSERT(%s <= %s);",
|
||||||
env->RValue(elem_dataptr_var()),
|
env->RValue(elem_dataptr_var()),
|
||||||
env->RValue(end_of_data));
|
env->RValue(end_of_data));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -556,7 +569,7 @@ void ArrayType::DoGenParseCode(Output *out_cc, Env *env,
|
||||||
if ( compute_size_var && elem_dataptr_var() && ! env->Evaluated(size_var()) )
|
if ( compute_size_var && elem_dataptr_var() && ! env->Evaluated(size_var()) )
|
||||||
{
|
{
|
||||||
// Compute the data size
|
// Compute the data size
|
||||||
out_cc->println("%s = %s - (%s);",
|
out_cc->println("%s = %s - (%s);",
|
||||||
env->LValue(size_var()),
|
env->LValue(size_var()),
|
||||||
env->RValue(elem_dataptr_var()),
|
env->RValue(elem_dataptr_var()),
|
||||||
data.ptr_expr());
|
data.ptr_expr());
|
||||||
|
@ -572,7 +585,7 @@ void ArrayType::GenUntilInputCheck(Output *out_cc, Env *env)
|
||||||
elem_input_var_id, extern_type_const_bytestring->Clone());
|
elem_input_var_id, extern_type_const_bytestring->Clone());
|
||||||
elem_input_var_field_->Prepare(env);
|
elem_input_var_field_->Prepare(env);
|
||||||
|
|
||||||
out_cc->println("%s %s(%s, %s);",
|
out_cc->println("%s %s(%s, %s);",
|
||||||
extern_type_const_bytestring->DataTypeStr().c_str(),
|
extern_type_const_bytestring->DataTypeStr().c_str(),
|
||||||
env->LValue(elem_input_var()),
|
env->LValue(elem_input_var()),
|
||||||
env->RValue(begin_of_data),
|
env->RValue(begin_of_data),
|
||||||
|
@ -582,22 +595,22 @@ void ArrayType::GenUntilInputCheck(Output *out_cc, Env *env)
|
||||||
GenUntilCheck(out_cc, env, attr_until_input_expr_, true);
|
GenUntilCheck(out_cc, env, attr_until_input_expr_, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArrayType::GenUntilCheck(Output *out_cc, Env *env,
|
void ArrayType::GenUntilCheck(Output *out_cc, Env *env,
|
||||||
Expr *until_expr, bool delete_elem)
|
Expr *until_expr, bool delete_elem)
|
||||||
{
|
{
|
||||||
ASSERT(until_expr);
|
ASSERT(until_expr);
|
||||||
|
|
||||||
Env check_env(env, this);
|
Env check_env(env, this);
|
||||||
check_env.AddMacro(element_macro_id,
|
check_env.AddMacro(element_macro_id,
|
||||||
new Expr(elem_var()->clone()));
|
new Expr(elem_var()->clone()));
|
||||||
if ( elem_input_var() )
|
if ( elem_input_var() )
|
||||||
{
|
{
|
||||||
check_env.AddMacro(input_macro_id,
|
check_env.AddMacro(input_macro_id,
|
||||||
new Expr(elem_input_var()->clone()));
|
new Expr(elem_input_var()->clone()));
|
||||||
}
|
}
|
||||||
|
|
||||||
out_cc->println("// Check &until(%s)", until_expr->orig());
|
out_cc->println("// Check &until(%s)", until_expr->orig());
|
||||||
out_cc->println("if ( %s )",
|
out_cc->println("if ( %s )",
|
||||||
until_expr->EvalExpr(out_cc, &check_env));
|
until_expr->EvalExpr(out_cc, &check_env));
|
||||||
out_cc->inc_indent();
|
out_cc->inc_indent();
|
||||||
out_cc->println("{");
|
out_cc->println("{");
|
||||||
|
@ -624,12 +637,12 @@ void ArrayType::GenDynamicSize(Output *out_cc, Env *env,
|
||||||
const DataPtr& data)
|
const DataPtr& data)
|
||||||
{
|
{
|
||||||
ASSERT(! incremental_input());
|
ASSERT(! incremental_input());
|
||||||
DEBUG_MSG("Generating dynamic size for array `%s'\n",
|
DEBUG_MSG("Generating dynamic size for array `%s'\n",
|
||||||
value_var()->Name());
|
value_var()->Name());
|
||||||
|
|
||||||
int elem_w = elemtype_->StaticSize(env);
|
int elem_w = elemtype_->StaticSize(env);
|
||||||
if ( elem_w >= 0 &&
|
if ( elem_w >= 0 &&
|
||||||
! attr_until_element_expr_ &&
|
! attr_until_element_expr_ &&
|
||||||
! attr_until_input_expr_ &&
|
! attr_until_input_expr_ &&
|
||||||
( length_ || attr_restofdata_ ) )
|
( length_ || attr_restofdata_ ) )
|
||||||
{
|
{
|
||||||
|
@ -661,7 +674,7 @@ int ArrayType::StaticSize(Env *env) const
|
||||||
if ( elem_w < 0 )
|
if ( elem_w < 0 )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
DEBUG_MSG("static size of %s:%s = %d * %d\n",
|
DEBUG_MSG("static size of %s:%s = %d * %d\n",
|
||||||
decl_id()->Name(), lvalue(), elem_w, num);
|
decl_id()->Name(), lvalue(), elem_w, num);
|
||||||
|
|
||||||
return num * elem_w;
|
return num * elem_w;
|
||||||
|
@ -675,18 +688,18 @@ void ArrayType::SetBoundaryChecked()
|
||||||
|
|
||||||
void ArrayType::DoMarkIncrementalInput()
|
void ArrayType::DoMarkIncrementalInput()
|
||||||
{
|
{
|
||||||
elemtype_->MarkIncrementalInput();
|
elemtype_->MarkIncrementalInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArrayType::RequiresAnalyzerContext()
|
bool ArrayType::RequiresAnalyzerContext()
|
||||||
{
|
{
|
||||||
return Type::RequiresAnalyzerContext() ||
|
return Type::RequiresAnalyzerContext() ||
|
||||||
( length_ && length_->RequiresAnalyzerContext() ) ||
|
( length_ && length_->RequiresAnalyzerContext() ) ||
|
||||||
elemtype_->RequiresAnalyzerContext();
|
elemtype_->RequiresAnalyzerContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArrayType::DoTraverse(DataDepVisitor *visitor)
|
bool ArrayType::DoTraverse(DataDepVisitor *visitor)
|
||||||
{
|
{
|
||||||
if ( ! Type::DoTraverse(visitor) )
|
if ( ! Type::DoTraverse(visitor) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -694,7 +707,7 @@ bool ArrayType::DoTraverse(DataDepVisitor *visitor)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( ! elemtype_->Traverse(visitor) )
|
if ( ! elemtype_->Traverse(visitor) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue