// See the file "COPYING" in the main distribution directory for copyright. #include "zeek/File.h" #include "zeek/RE.h" #include "zeek/script_opt/CPP/Compile.h" using namespace std; namespace zeek::detail { shared_ptr CPPCompile::RegisterConstant(const ValPtr& vp, int& consts_offset) { // Make sure the value pointer, which might be transient // in construction, sticks around so we can track its // value. cv_indices.push_back(vp); auto v = vp.get(); auto cv = const_vals.find(v); if ( cv != const_vals.end() ) { // Already did this one. consts_offset = const_offsets[v]; return cv->second; } // Formulate a key that's unique per distinct constant. const auto& t = v->GetType(); string c_desc; if ( t->Tag() == TYPE_STRING ) { // We can't rely on these to render with consistent // escaping, sigh. Just use the raw string. auto s = v->AsString(); auto b = (const char*)(s->Bytes()); c_desc = string(b, s->Len()) + "string"; } else { ODesc d; v->Describe(&d); // Don't confuse constants of different types that happen to // render the same. t->Describe(&d); // Likewise, tables that have attributes. if ( t->Tag() == TYPE_TABLE ) { const auto& attrs = v->AsTableVal()->GetAttrs(); if ( attrs ) attrs->Describe(&d); else d.Add(""); } c_desc = d.Description(); } auto c = constants.find(c_desc); if ( c != constants.end() ) { const_vals[v] = c->second; consts_offset = const_offsets[v] = constants_offsets[c_desc]; return c->second; } auto tag = t->Tag(); auto const_name = const_info[tag]->NextName(); shared_ptr gi; switch ( tag ) { case TYPE_BOOL: gi = make_shared(vp->AsBool() ? "true" : "false"); break; case TYPE_INT: gi = make_shared(to_string(vp->AsInt())); break; case TYPE_COUNT: gi = make_shared(to_string(vp->AsCount()) + "ULL"); break; case TYPE_DOUBLE: gi = make_shared(to_string(vp->AsDouble())); break; case TYPE_TIME: gi = make_shared(to_string(vp->AsDouble())); break; case TYPE_INTERVAL: gi = make_shared(to_string(vp->AsDouble())); break; case TYPE_ADDR: gi = make_shared(this, vp); break; case TYPE_SUBNET: gi = make_shared(this, vp); break; case TYPE_ENUM: gi = make_shared(this, vp); break; case TYPE_STRING: gi = make_shared(this, vp); break; case TYPE_PATTERN: gi = make_shared(this, vp); break; case TYPE_PORT: gi = make_shared(vp); break; case TYPE_LIST: gi = make_shared(this, vp); break; case TYPE_VECTOR: gi = make_shared(this, vp); break; case TYPE_RECORD: gi = make_shared(this, vp); break; case TYPE_TABLE: gi = make_shared(this, vp); break; case TYPE_FILE: gi = make_shared(this, vp); break; case TYPE_FUNC: gi = make_shared(this, vp); break; default: reporter->InternalError("bad constant type in CPPCompile::AddConstant"); break; } const_info[tag]->AddInstance(gi); const_vals[v] = constants[c_desc] = gi; consts_offset = const_offsets[v] = constants_offsets[c_desc] = consts.size(); consts.emplace_back(tag, gi->Offset()); return gi; } } // namespace zeek::detail