for cat() replacements, confine frame knowledge to aux

This commit is contained in:
Vern Paxson 2024-06-03 16:02:35 -07:00
parent b62b31846e
commit 8088f91145
5 changed files with 104 additions and 90 deletions

View file

@ -9,6 +9,7 @@ extend-ignore-re = [
"Remove in v6.1.*SupressWeird",
"max_repititions:.*Remove in v6.1",
"mis-aliasing of",
"mis-indexing",
# On purpose
"\"THE NETBIOS NAM\"",
# NFS stuff.

View file

@ -48,8 +48,7 @@ FixedCatArg::FixedCatArg(TypePtr _t) : t(std::move(_t)) {
}
}
void FixedCatArg::RenderInto(ZVal* zframe, int slot, char*& res) {
auto& z = zframe[slot];
void FixedCatArg::RenderInto(const ZVal& z, char*& res) {
int n;
const char* text;
std::string str;
@ -140,8 +139,8 @@ void FixedCatArg::RenderInto(ZVal* zframe, int slot, char*& res) {
}
}
size_t PatternCatArg::ComputeMaxSize(ZVal* zframe, int slot) {
text = zframe[slot].AsPattern()->AsPattern()->PatternText();
size_t PatternCatArg::ComputeMaxSize(const ZVal& zv) {
text = zv.AsPattern()->AsPattern()->PatternText();
n = strlen(text);
return n;
}

View file

@ -13,9 +13,9 @@ public:
virtual ~CatArg() {}
size_t MaxSize(ZVal* zframe, int slot) { return max_size ? *max_size : ComputeMaxSize(zframe, slot); }
size_t MaxSize(const ZVal& zv) { return max_size ? *max_size : ComputeMaxSize(zv); }
virtual void RenderInto(ZVal* zframe, int slot, char*& res) {
virtual void RenderInto(const ZVal& zv, char*& res) {
auto n = *max_size;
memcpy(res, s->data(), n);
res += n;
@ -25,7 +25,7 @@ protected:
CatArg() {}
CatArg(size_t _max_size) : max_size(_max_size) {}
virtual size_t ComputeMaxSize(ZVal* zframe, int slot) { return 0; }
virtual size_t ComputeMaxSize(const ZVal& zv) { return 0; }
// Present if max size is known a priori.
std::optional<size_t> max_size;
@ -38,7 +38,7 @@ class FixedCatArg : public CatArg {
public:
FixedCatArg(TypePtr t);
void RenderInto(ZVal* zframe, int slot, char*& res) override;
void RenderInto(const ZVal& zv, char*& res) override;
protected:
TypePtr t;
@ -49,22 +49,22 @@ class StringCatArg : public CatArg {
public:
StringCatArg() : CatArg() {}
void RenderInto(ZVal* zframe, int slot, char*& res) override {
auto s = zframe[slot].AsString();
void RenderInto(const ZVal& zv, char*& res) override {
auto s = zv.AsString();
auto n = s->Len();
memcpy(res, s->Bytes(), n);
res += n;
}
protected:
size_t ComputeMaxSize(ZVal* zframe, int slot) override { return zframe[slot].AsString()->Len(); }
size_t ComputeMaxSize(const ZVal& zv) override { return zv.AsString()->Len(); }
};
class PatternCatArg : public CatArg {
public:
PatternCatArg() : CatArg() {}
void RenderInto(ZVal* zframe, int slot, char*& res) override {
void RenderInto(const ZVal& zv, char*& res) override {
*(res++) = '/';
strcpy(res, text);
res += n;
@ -72,7 +72,7 @@ public:
}
protected:
size_t ComputeMaxSize(ZVal* zframe, int slot) override;
size_t ComputeMaxSize(const ZVal& zv) override;
const char* text = nullptr;
size_t n = 0;
@ -82,7 +82,7 @@ class DescCatArg : public CatArg {
public:
DescCatArg(TypePtr _t) : CatArg(), t(std::move(_t)) { d.SetStyle(RAW_STYLE); }
void RenderInto(ZVal* zframe, int slot, char*& res) override {
void RenderInto(const ZVal& zv, char*& res) override {
auto n = d.Len();
memcpy(res, d.Bytes(), n);
res += n;
@ -90,8 +90,8 @@ public:
}
protected:
size_t ComputeMaxSize(ZVal* zframe, int slot) override {
zframe[slot].ToVal(t)->Describe(&d);
size_t ComputeMaxSize(const ZVal& zv) override {
zv.ToVal(t)->Describe(&d);
return d.Len();
}

View file

@ -2455,16 +2455,15 @@ eval auto formatted_val = ZVal(ZAM_val_cat($1.ToVal(z.t)));
internal-op CatN
type V
eval auto aux = z.aux;
auto& ca = aux->cat_args;
eval CatNPre()
int n = aux->n;
size_t max_size = 0;
for ( int i = 0; i < n; ++i )
max_size += ca[i]->MaxSize(frame, aux->elems[i].Slot());
max_size += ca[i]->MaxSize(aux->elems[i].ToDirectZVal(frame));
auto res = new char[max_size + /* slop */ n + 1];
auto res_p = res;
for ( int i = 0; i < n; ++i )
ca[i]->RenderInto(frame, aux->elems[i].Slot(), res_p);
ca[i]->RenderInto(aux->elems[i].ToDirectZVal(frame), res_p);
*res_p = '\0';
auto s = new String(true, reinterpret_cast<byte_vec>(res), res_p - res);
Cat1Op($$, ZVal(new StringVal(s)))
@ -2485,113 +2484,113 @@ macro CatNPost(lhs)
internal-op Cat2
type V
eval CatNPre()
size_t max_size = ca[0]->MaxSize(frame, aux->elems[0].Slot());
max_size += ca[1]->MaxSize(frame, aux->elems[1].Slot());
size_t max_size = ca[0]->MaxSize(aux->elems[0].ToDirectZVal(frame));
max_size += ca[1]->MaxSize(aux->elems[1].ToDirectZVal(frame));
CatNMid()
ca[0]->RenderInto(frame, aux->elems[0].Slot(), res_p);
ca[1]->RenderInto(frame, aux->elems[1].Slot(), res_p);
ca[0]->RenderInto(aux->elems[0].ToDirectZVal(frame), res_p);
ca[1]->RenderInto(aux->elems[1].ToDirectZVal(frame), res_p);
CatNPost($$)
internal-op Cat3
type V
eval CatNPre()
size_t max_size = ca[0]->MaxSize(frame, aux->elems[0].Slot());
max_size += ca[1]->MaxSize(frame, aux->elems[1].Slot());
max_size += ca[2]->MaxSize(frame, aux->elems[2].Slot());
size_t max_size = ca[0]->MaxSize(aux->elems[0].ToDirectZVal(frame));
max_size += ca[1]->MaxSize(aux->elems[1].ToDirectZVal(frame));
max_size += ca[2]->MaxSize(aux->elems[2].ToDirectZVal(frame));
CatNMid()
ca[0]->RenderInto(frame, aux->elems[0].Slot(), res_p);
ca[1]->RenderInto(frame, aux->elems[1].Slot(), res_p);
ca[2]->RenderInto(frame, aux->elems[2].Slot(), res_p);
ca[0]->RenderInto(aux->elems[0].ToDirectZVal(frame), res_p);
ca[1]->RenderInto(aux->elems[1].ToDirectZVal(frame), res_p);
ca[2]->RenderInto(aux->elems[2].ToDirectZVal(frame), res_p);
CatNPost($$)
internal-op Cat4
type V
eval CatNPre()
size_t max_size = ca[0]->MaxSize(frame, aux->elems[0].Slot());
max_size += ca[1]->MaxSize(frame, aux->elems[1].Slot());
max_size += ca[2]->MaxSize(frame, aux->elems[2].Slot());
max_size += ca[3]->MaxSize(frame, aux->elems[3].Slot());
size_t max_size = ca[0]->MaxSize(aux->elems[0].ToDirectZVal(frame));
max_size += ca[1]->MaxSize(aux->elems[1].ToDirectZVal(frame));
max_size += ca[2]->MaxSize(aux->elems[2].ToDirectZVal(frame));
max_size += ca[3]->MaxSize(aux->elems[3].ToDirectZVal(frame));
CatNMid()
ca[0]->RenderInto(frame, aux->elems[0].Slot(), res_p);
ca[1]->RenderInto(frame, aux->elems[1].Slot(), res_p);
ca[2]->RenderInto(frame, aux->elems[2].Slot(), res_p);
ca[3]->RenderInto(frame, aux->elems[3].Slot(), res_p);
ca[0]->RenderInto(aux->elems[0].ToDirectZVal(frame), res_p);
ca[1]->RenderInto(aux->elems[1].ToDirectZVal(frame), res_p);
ca[2]->RenderInto(aux->elems[2].ToDirectZVal(frame), res_p);
ca[3]->RenderInto(aux->elems[3].ToDirectZVal(frame), res_p);
CatNPost($$)
internal-op Cat5
type V
eval CatNPre()
size_t max_size = ca[0]->MaxSize(frame, aux->elems[0].Slot());
max_size += ca[1]->MaxSize(frame, aux->elems[1].Slot());
max_size += ca[2]->MaxSize(frame, aux->elems[2].Slot());
max_size += ca[3]->MaxSize(frame, aux->elems[3].Slot());
max_size += ca[4]->MaxSize(frame, aux->elems[4].Slot());
size_t max_size = ca[0]->MaxSize(aux->elems[0].ToDirectZVal(frame));
max_size += ca[1]->MaxSize(aux->elems[1].ToDirectZVal(frame));
max_size += ca[2]->MaxSize(aux->elems[2].ToDirectZVal(frame));
max_size += ca[3]->MaxSize(aux->elems[3].ToDirectZVal(frame));
max_size += ca[4]->MaxSize(aux->elems[4].ToDirectZVal(frame));
CatNMid()
ca[0]->RenderInto(frame, aux->elems[0].Slot(), res_p);
ca[1]->RenderInto(frame, aux->elems[1].Slot(), res_p);
ca[2]->RenderInto(frame, aux->elems[2].Slot(), res_p);
ca[3]->RenderInto(frame, aux->elems[3].Slot(), res_p);
ca[4]->RenderInto(frame, aux->elems[4].Slot(), res_p);
ca[0]->RenderInto(aux->elems[0].ToDirectZVal(frame), res_p);
ca[1]->RenderInto(aux->elems[1].ToDirectZVal(frame), res_p);
ca[2]->RenderInto(aux->elems[2].ToDirectZVal(frame), res_p);
ca[3]->RenderInto(aux->elems[3].ToDirectZVal(frame), res_p);
ca[4]->RenderInto(aux->elems[4].ToDirectZVal(frame), res_p);
CatNPost($$)
internal-op Cat6
type V
eval CatNPre()
size_t max_size = ca[0]->MaxSize(frame, aux->elems[0].Slot());
max_size += ca[1]->MaxSize(frame, aux->elems[1].Slot());
max_size += ca[2]->MaxSize(frame, aux->elems[2].Slot());
max_size += ca[3]->MaxSize(frame, aux->elems[3].Slot());
max_size += ca[4]->MaxSize(frame, aux->elems[4].Slot());
max_size += ca[5]->MaxSize(frame, aux->elems[5].Slot());
size_t max_size = ca[0]->MaxSize(aux->elems[0].ToDirectZVal(frame));
max_size += ca[1]->MaxSize(aux->elems[1].ToDirectZVal(frame));
max_size += ca[2]->MaxSize(aux->elems[2].ToDirectZVal(frame));
max_size += ca[3]->MaxSize(aux->elems[3].ToDirectZVal(frame));
max_size += ca[4]->MaxSize(aux->elems[4].ToDirectZVal(frame));
max_size += ca[5]->MaxSize(aux->elems[5].ToDirectZVal(frame));
CatNMid()
ca[0]->RenderInto(frame, aux->elems[0].Slot(), res_p);
ca[1]->RenderInto(frame, aux->elems[1].Slot(), res_p);
ca[2]->RenderInto(frame, aux->elems[2].Slot(), res_p);
ca[3]->RenderInto(frame, aux->elems[3].Slot(), res_p);
ca[4]->RenderInto(frame, aux->elems[4].Slot(), res_p);
ca[5]->RenderInto(frame, aux->elems[5].Slot(), res_p);
ca[0]->RenderInto(aux->elems[0].ToDirectZVal(frame), res_p);
ca[1]->RenderInto(aux->elems[1].ToDirectZVal(frame), res_p);
ca[2]->RenderInto(aux->elems[2].ToDirectZVal(frame), res_p);
ca[3]->RenderInto(aux->elems[3].ToDirectZVal(frame), res_p);
ca[4]->RenderInto(aux->elems[4].ToDirectZVal(frame), res_p);
ca[5]->RenderInto(aux->elems[5].ToDirectZVal(frame), res_p);
CatNPost($$)
internal-op Cat7
type V
eval CatNPre()
size_t max_size = ca[0]->MaxSize(frame, aux->elems[0].Slot());
max_size += ca[1]->MaxSize(frame, aux->elems[1].Slot());
max_size += ca[2]->MaxSize(frame, aux->elems[2].Slot());
max_size += ca[3]->MaxSize(frame, aux->elems[3].Slot());
max_size += ca[4]->MaxSize(frame, aux->elems[4].Slot());
max_size += ca[5]->MaxSize(frame, aux->elems[5].Slot());
max_size += ca[6]->MaxSize(frame, aux->elems[6].Slot());
size_t max_size = ca[0]->MaxSize(aux->elems[0].ToDirectZVal(frame));
max_size += ca[1]->MaxSize(aux->elems[1].ToDirectZVal(frame));
max_size += ca[2]->MaxSize(aux->elems[2].ToDirectZVal(frame));
max_size += ca[3]->MaxSize(aux->elems[3].ToDirectZVal(frame));
max_size += ca[4]->MaxSize(aux->elems[4].ToDirectZVal(frame));
max_size += ca[5]->MaxSize(aux->elems[5].ToDirectZVal(frame));
max_size += ca[6]->MaxSize(aux->elems[6].ToDirectZVal(frame));
CatNMid()
ca[0]->RenderInto(frame, aux->elems[0].Slot(), res_p);
ca[1]->RenderInto(frame, aux->elems[1].Slot(), res_p);
ca[2]->RenderInto(frame, aux->elems[2].Slot(), res_p);
ca[3]->RenderInto(frame, aux->elems[3].Slot(), res_p);
ca[4]->RenderInto(frame, aux->elems[4].Slot(), res_p);
ca[5]->RenderInto(frame, aux->elems[5].Slot(), res_p);
ca[6]->RenderInto(frame, aux->elems[6].Slot(), res_p);
ca[0]->RenderInto(aux->elems[0].ToDirectZVal(frame), res_p);
ca[1]->RenderInto(aux->elems[1].ToDirectZVal(frame), res_p);
ca[2]->RenderInto(aux->elems[2].ToDirectZVal(frame), res_p);
ca[3]->RenderInto(aux->elems[3].ToDirectZVal(frame), res_p);
ca[4]->RenderInto(aux->elems[4].ToDirectZVal(frame), res_p);
ca[5]->RenderInto(aux->elems[5].ToDirectZVal(frame), res_p);
ca[6]->RenderInto(aux->elems[6].ToDirectZVal(frame), res_p);
CatNPost($$)
internal-op Cat8
type V
eval CatNPre()
size_t max_size = ca[0]->MaxSize(frame, aux->elems[0].Slot());
max_size += ca[1]->MaxSize(frame, aux->elems[1].Slot());
max_size += ca[2]->MaxSize(frame, aux->elems[2].Slot());
max_size += ca[3]->MaxSize(frame, aux->elems[3].Slot());
max_size += ca[4]->MaxSize(frame, aux->elems[4].Slot());
max_size += ca[5]->MaxSize(frame, aux->elems[5].Slot());
max_size += ca[6]->MaxSize(frame, aux->elems[6].Slot());
max_size += ca[7]->MaxSize(frame, aux->elems[7].Slot());
size_t max_size = ca[0]->MaxSize(aux->elems[0].ToDirectZVal(frame));
max_size += ca[1]->MaxSize(aux->elems[1].ToDirectZVal(frame));
max_size += ca[2]->MaxSize(aux->elems[2].ToDirectZVal(frame));
max_size += ca[3]->MaxSize(aux->elems[3].ToDirectZVal(frame));
max_size += ca[4]->MaxSize(aux->elems[4].ToDirectZVal(frame));
max_size += ca[5]->MaxSize(aux->elems[5].ToDirectZVal(frame));
max_size += ca[6]->MaxSize(aux->elems[6].ToDirectZVal(frame));
max_size += ca[7]->MaxSize(aux->elems[7].ToDirectZVal(frame));
CatNMid()
ca[0]->RenderInto(frame, aux->elems[0].Slot(), res_p);
ca[1]->RenderInto(frame, aux->elems[1].Slot(), res_p);
ca[2]->RenderInto(frame, aux->elems[2].Slot(), res_p);
ca[3]->RenderInto(frame, aux->elems[3].Slot(), res_p);
ca[4]->RenderInto(frame, aux->elems[4].Slot(), res_p);
ca[5]->RenderInto(frame, aux->elems[5].Slot(), res_p);
ca[6]->RenderInto(frame, aux->elems[6].Slot(), res_p);
ca[7]->RenderInto(frame, aux->elems[7].Slot(), res_p);
ca[0]->RenderInto(aux->elems[0].ToDirectZVal(frame), res_p);
ca[1]->RenderInto(aux->elems[1].ToDirectZVal(frame), res_p);
ca[2]->RenderInto(aux->elems[2].ToDirectZVal(frame), res_p);
ca[3]->RenderInto(aux->elems[3].ToDirectZVal(frame), res_p);
ca[4]->RenderInto(aux->elems[4].ToDirectZVal(frame), res_p);
ca[5]->RenderInto(aux->elems[5].ToDirectZVal(frame), res_p);
ca[6]->RenderInto(aux->elems[6].ToDirectZVal(frame), res_p);
ca[7]->RenderInto(aux->elems[7].ToDirectZVal(frame), res_p);
CatNPost($$)
internal-op Analyzer-Name

View file

@ -337,6 +337,21 @@ public:
return zv;
}
// The same, but for read-only access for which memory-management is
// not required.
const ZVal& ToDirectZVal(const ZVal* frame) const {
if ( c )
return zc;
if ( i >= 0 )
return frame[i];
// Currently the way we use AuxElem's we shouldn't get here, but
// just in case we do, return something sound rather than mis-indexing
// the frame.
static ZVal null_zval;
return null_zval;
}
int Slot() const { return i; }
int IntVal() const { return i; }
const ValPtr& Constant() const { return c; }