mirror of
https://github.com/NixOS/nix.git
synced 2025-11-09 12:06:01 +01:00
Merge pull request #14443 from NixOS/inline-unreused-lambda
Inline only-used-once closures in `ExprConcatStrings::eval`
This commit is contained in:
commit
e4e4063f16
1 changed files with 23 additions and 31 deletions
|
|
@ -2021,7 +2021,7 @@ void EvalState::concatLists(
|
||||||
void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
std::vector<BackedStringView> s;
|
std::vector<BackedStringView> strings;
|
||||||
size_t sSize = 0;
|
size_t sSize = 0;
|
||||||
NixInt n{0};
|
NixInt n{0};
|
||||||
NixFloat nf = 0;
|
NixFloat nf = 0;
|
||||||
|
|
@ -2029,27 +2029,6 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
bool first = !forceString;
|
bool first = !forceString;
|
||||||
ValueType firstType = nString;
|
ValueType firstType = nString;
|
||||||
|
|
||||||
const auto str = [&] {
|
|
||||||
std::string result;
|
|
||||||
result.reserve(sSize);
|
|
||||||
for (const auto & part : s)
|
|
||||||
result += *part;
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
/* c_str() is not str().c_str() because we want to create a string
|
|
||||||
Value. allocating a GC'd string directly and moving it into a
|
|
||||||
Value lets us avoid an allocation and copy. */
|
|
||||||
const auto c_str = [&] {
|
|
||||||
char * result = allocString(sSize + 1);
|
|
||||||
char * tmp = result;
|
|
||||||
for (const auto & part : s) {
|
|
||||||
memcpy(tmp, part->data(), part->size());
|
|
||||||
tmp += part->size();
|
|
||||||
}
|
|
||||||
*tmp = 0;
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
|
|
||||||
// List of returned strings. References to these Values must NOT be persisted.
|
// List of returned strings. References to these Values must NOT be persisted.
|
||||||
SmallTemporaryValueVector<conservativeStackReservation> values(es.size());
|
SmallTemporaryValueVector<conservativeStackReservation> values(es.size());
|
||||||
Value * vTmpP = values.data();
|
Value * vTmpP = values.data();
|
||||||
|
|
@ -2097,33 +2076,46 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
.withFrame(env, *this)
|
.withFrame(env, *this)
|
||||||
.debugThrow();
|
.debugThrow();
|
||||||
} else {
|
} else {
|
||||||
if (s.empty())
|
if (strings.empty())
|
||||||
s.reserve(es.size());
|
strings.reserve(es.size());
|
||||||
/* skip canonization of first path, which would only be not
|
/* skip canonization of first path, which would only be not
|
||||||
canonized in the first place if it's coming from a ./${foo} type
|
canonized in the first place if it's coming from a ./${foo} type
|
||||||
path */
|
path */
|
||||||
auto part = state.coerceToString(
|
auto part = state.coerceToString(
|
||||||
i_pos, vTmp, context, "while evaluating a path segment", false, firstType == nString, !first);
|
i_pos, vTmp, context, "while evaluating a path segment", false, firstType == nString, !first);
|
||||||
sSize += part->size();
|
sSize += part->size();
|
||||||
s.emplace_back(std::move(part));
|
strings.emplace_back(std::move(part));
|
||||||
}
|
}
|
||||||
|
|
||||||
first = false;
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstType == nInt)
|
if (firstType == nInt) {
|
||||||
v.mkInt(n);
|
v.mkInt(n);
|
||||||
else if (firstType == nFloat)
|
} else if (firstType == nFloat) {
|
||||||
v.mkFloat(nf);
|
v.mkFloat(nf);
|
||||||
else if (firstType == nPath) {
|
} else if (firstType == nPath) {
|
||||||
if (!context.empty())
|
if (!context.empty())
|
||||||
state.error<EvalError>("a string that refers to a store path cannot be appended to a path")
|
state.error<EvalError>("a string that refers to a store path cannot be appended to a path")
|
||||||
.atPos(pos)
|
.atPos(pos)
|
||||||
.withFrame(env, *this)
|
.withFrame(env, *this)
|
||||||
.debugThrow();
|
.debugThrow();
|
||||||
v.mkPath(state.rootPath(CanonPath(str())));
|
std::string result_str;
|
||||||
} else
|
result_str.reserve(sSize);
|
||||||
v.mkStringMove(c_str(), context);
|
for (const auto & part : strings) {
|
||||||
|
result_str += *part;
|
||||||
|
}
|
||||||
|
v.mkPath(state.rootPath(CanonPath(result_str)));
|
||||||
|
} else {
|
||||||
|
char * result_str = allocString(sSize + 1);
|
||||||
|
char * tmp = result_str;
|
||||||
|
for (const auto & part : strings) {
|
||||||
|
memcpy(tmp, part->data(), part->size());
|
||||||
|
tmp += part->size();
|
||||||
|
}
|
||||||
|
*tmp = 0;
|
||||||
|
v.mkStringMove(result_str, context);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprPos::eval(EvalState & state, Env & env, Value & v)
|
void ExprPos::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue