WIP: pic/tracy-profiler #1
0
.gitmodules
vendored
Normal file
0
.gitmodules
vendored
Normal file
|
@ -14,6 +14,7 @@ ENABLE_FUNCTIONAL_TESTS = @ENABLE_FUNCTIONAL_TESTS@
|
||||||
ENABLE_INTERNAL_API_DOCS = @ENABLE_INTERNAL_API_DOCS@
|
ENABLE_INTERNAL_API_DOCS = @ENABLE_INTERNAL_API_DOCS@
|
||||||
ENABLE_S3 = @ENABLE_S3@
|
ENABLE_S3 = @ENABLE_S3@
|
||||||
ENABLE_UNIT_TESTS = @ENABLE_UNIT_TESTS@
|
ENABLE_UNIT_TESTS = @ENABLE_UNIT_TESTS@
|
||||||
|
ENABLE_TRACY = @ENABLE_TRACY@
|
||||||
GTEST_LIBS = @GTEST_LIBS@
|
GTEST_LIBS = @GTEST_LIBS@
|
||||||
HAVE_LIBCPUID = @HAVE_LIBCPUID@
|
HAVE_LIBCPUID = @HAVE_LIBCPUID@
|
||||||
HAVE_SECCOMP = @HAVE_SECCOMP@
|
HAVE_SECCOMP = @HAVE_SECCOMP@
|
||||||
|
|
|
@ -348,6 +348,15 @@ if test "$gc" = yes; then
|
||||||
AC_DEFINE(HAVE_BOEHMGC, 1, [Whether to use the Boehm garbage collector.])
|
AC_DEFINE(HAVE_BOEHMGC, 1, [Whether to use the Boehm garbage collector.])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(tracy-profiler, AS_HELP_STRING([--enable-tracy-profiler],[Profile the Nix evaluation using the Tracy profiler (default no)]),
|
||||||
|
TRACY_PROFILER=$enableval, TRACY_PROFILER=no)
|
||||||
|
if test "$TRACY_PROFILER" != no; then
|
||||||
|
# We don't have any pkg-config file for tracy, we have to inject the
|
||||||
|
# headers manually…
|
||||||
|
CXXFLAGS="-I $TRACY_PROFILER/include/Tracy $CXXFLAGS"
|
||||||
|
fi
|
||||||
|
AC_SUBST(TRACY_PROFILER)
|
||||||
|
|
||||||
AS_IF([test "$ENABLE_UNIT_TESTS" == "yes"],[
|
AS_IF([test "$ENABLE_UNIT_TESTS" == "yes"],[
|
||||||
|
|
||||||
# Look for gtest.
|
# Look for gtest.
|
||||||
|
|
19
flake.lock
19
flake.lock
|
@ -64,12 +64,29 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs-tracy": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1707205788,
|
||||||
|
"narHash": "sha256-dFPctGYh7cNPAuJQY9i4+1/M+LdrRDpk0RRwpClEQ4w=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "e311f423a6e56505afae9d4b621759826e7270c0",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-23.11-small",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
"libgit2": "libgit2",
|
"libgit2": "libgit2",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"nixpkgs-regression": "nixpkgs-regression"
|
"nixpkgs-regression": "nixpkgs-regression",
|
||||||
|
"nixpkgs-tracy": "nixpkgs-tracy"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
24
flake.nix
24
flake.nix
|
@ -2,11 +2,14 @@
|
||||||
description = "The purely functional package manager";
|
description = "The purely functional package manager";
|
||||||
|
|
||||||
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05-small";
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-23.05-small";
|
||||||
|
# Tracy is in a half-broken situation on 23.05. We need the changes
|
||||||
|
# introduced by https://github.com/NixOS/nixpkgs/pull/261589.
|
||||||
|
inputs.nixpkgs-tracy.url = "github:NixOS/nixpkgs/nixos-23.11-small";
|
||||||
inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
|
inputs.nixpkgs-regression.url = "github:NixOS/nixpkgs/215d4d0fd80ca5163643b03a33fde804a29cc1e2";
|
||||||
inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
|
inputs.flake-compat = { url = "github:edolstra/flake-compat"; flake = false; };
|
||||||
inputs.libgit2 = { url = "github:libgit2/libgit2"; flake = false; };
|
inputs.libgit2 = { url = "github:libgit2/libgit2"; flake = false; };
|
||||||
|
|
||||||
outputs = { self, nixpkgs, nixpkgs-regression, libgit2, ... }:
|
outputs = { self, nixpkgs, nixpkgs-regression, libgit2, nixpkgs-tracy, ... }:
|
||||||
|
|
||||||
let
|
let
|
||||||
inherit (nixpkgs) lib;
|
inherit (nixpkgs) lib;
|
||||||
|
@ -186,6 +189,19 @@
|
||||||
stdenv
|
stdenv
|
||||||
versionSuffix
|
versionSuffix
|
||||||
;
|
;
|
||||||
|
# We have to use the nixos-23.11 tracy version. However,
|
||||||
|
# we can't link the 23.11 lib on our 23.05 nix without
|
||||||
|
# hitting some Glibc ABI incompatibilities.
|
||||||
|
#
|
||||||
|
# To go around that issue, we build the 23.11 tracy
|
||||||
|
# derivation with the 23.05 toolchain/libs.
|
||||||
|
tracy = final.callPackage (nixpkgs-tracy.legacyPackages.${final.hostPlatform.system}.path + "/pkgs/development/tools/tracy") {};
|
||||||
|
# Temporarily enabling the tracy profiler and disabling
|
||||||
|
# install check for convenience.
|
||||||
|
# TODO: remove this before undrafting the PR.
|
||||||
|
enableTracy = true;
|
||||||
|
doCheck = false;
|
||||||
|
doInstallCheck = false;
|
||||||
officialRelease = false;
|
officialRelease = false;
|
||||||
boehmgc = final.boehmgc-nix;
|
boehmgc = final.boehmgc-nix;
|
||||||
libgit2 = final.libgit2-nix;
|
libgit2 = final.libgit2-nix;
|
||||||
|
@ -223,6 +239,10 @@
|
||||||
self.packages.${system}.nix.override { enableGC = false; }
|
self.packages.${system}.nix.override { enableGC = false; }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
buildWithTracy = forAllSystems (system:
|
||||||
|
self.packages.${system}.nix.override { enableTracy = true; }
|
||||||
|
);
|
||||||
|
|
||||||
buildNoTests = forAllSystems (system:
|
buildNoTests = forAllSystems (system:
|
||||||
self.packages.${system}.nix.override {
|
self.packages.${system}.nix.override {
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
|
@ -394,7 +414,7 @@
|
||||||
stdenvs)));
|
stdenvs)));
|
||||||
|
|
||||||
devShells = let
|
devShells = let
|
||||||
makeShell = pkgs: stdenv: (pkgs.nix.override { inherit stdenv; forDevShell = true; }).overrideAttrs (attrs: {
|
makeShell = pkgs: stdenv: (pkgs.nix.override { inherit stdenv; forDevShell = true; enableTracy = true; }).overrideAttrs (attrs: {
|
||||||
installFlags = "sysconfdir=$(out)/etc";
|
installFlags = "sysconfdir=$(out)/etc";
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
PATH=$prefix/bin:$PATH
|
PATH=$prefix/bin:$PATH
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
, rapidcheck
|
, rapidcheck
|
||||||
, sqlite
|
, sqlite
|
||||||
, util-linux
|
, util-linux
|
||||||
|
, tracy
|
||||||
, xz
|
, xz
|
||||||
|
|
||||||
, busybox-sandbox-shell ? null
|
, busybox-sandbox-shell ? null
|
||||||
|
@ -76,6 +77,9 @@
|
||||||
# only leaked *within* the process.)
|
# only leaked *within* the process.)
|
||||||
, enableGC ? true
|
, enableGC ? true
|
||||||
|
|
||||||
|
# TODO
|
||||||
|
, enableTracy ? false
|
||||||
|
|
||||||
# Whether to enable Markdown rendering in the Nix binary.
|
# Whether to enable Markdown rendering in the Nix binary.
|
||||||
, enableMarkdown ? !stdenv.hostPlatform.isWindows
|
, enableMarkdown ? !stdenv.hostPlatform.isWindows
|
||||||
|
|
||||||
|
@ -234,6 +238,7 @@ in {
|
||||||
rapidcheck
|
rapidcheck
|
||||||
] ++ lib.optional stdenv.isLinux libseccomp
|
] ++ lib.optional stdenv.isLinux libseccomp
|
||||||
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid
|
++ lib.optional stdenv.hostPlatform.isx86_64 libcpuid
|
||||||
|
++ lib.optional enableTracy tracy
|
||||||
# There have been issues building these dependencies
|
# There have been issues building these dependencies
|
||||||
++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin))
|
++ lib.optional (stdenv.hostPlatform == stdenv.buildPlatform && (stdenv.isLinux || stdenv.isDarwin))
|
||||||
(aws-sdk-cpp.override {
|
(aws-sdk-cpp.override {
|
||||||
|
@ -287,6 +292,8 @@ in {
|
||||||
(lib.enableFeature enableMarkdown "markdown")
|
(lib.enableFeature enableMarkdown "markdown")
|
||||||
(lib.enableFeature installUnitTests "install-unit-tests")
|
(lib.enableFeature installUnitTests "install-unit-tests")
|
||||||
(lib.withFeatureAs true "readline-flavor" readlineFlavor)
|
(lib.withFeatureAs true "readline-flavor" readlineFlavor)
|
||||||
|
] ++ lib.optionals (enableTracy) [
|
||||||
|
"--enable-tracy-profiler=${tracy}"
|
||||||
] ++ lib.optionals (!forDevShell) [
|
] ++ lib.optionals (!forDevShell) [
|
||||||
"--sysconfdir=/etc"
|
"--sysconfdir=/etc"
|
||||||
] ++ lib.optionals installUnitTests [
|
] ++ lib.optionals installUnitTests [
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "flake/flakeref.hh"
|
#include "flake/flakeref.hh"
|
||||||
#include "parser-tab.hh"
|
#include "parser-tab.hh"
|
||||||
|
|
||||||
|
#include <tracy/Tracy.hpp>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -54,6 +55,16 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define TRACY_TRACE(evalstate, expr) \
|
||||||
|
std::ostringstream tracyss; \
|
||||||
|
tracyss << (evalstate).positions[(expr)->getPos()] << " " << (expr)->showExprType(); \
|
||||||
|
ZoneTransientN(nix, tracyss.str().c_str(), true);
|
||||||
|
|
||||||
|
#define TRACY_TRACE_TYPE_STR(evalstate, expr, typestr) \
|
||||||
|
std::ostringstream tracyss; \
|
||||||
|
tracyss << (evalstate).positions[(expr)->getPos()] << " " << typestr; \
|
||||||
|
ZoneTransientN(nix, tracyss.str().c_str(), true);
|
||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
@ -70,7 +81,6 @@ static char * allocString(size_t size)
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static char * dupString(const char * s)
|
static char * dupString(const char * s)
|
||||||
{
|
{
|
||||||
char * t;
|
char * t;
|
||||||
|
@ -1163,6 +1173,7 @@ void EvalState::eval(Expr * e, Value & v)
|
||||||
|
|
||||||
inline bool EvalState::evalBool(Env & env, Expr * e, const PosIdx pos, std::string_view errorCtx)
|
inline bool EvalState::evalBool(Env & env, Expr * e, const PosIdx pos, std::string_view errorCtx)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_TYPE_STR(*this, e, "bool")
|
||||||
try {
|
try {
|
||||||
Value v;
|
Value v;
|
||||||
e->eval(*this, env, v);
|
e->eval(*this, env, v);
|
||||||
|
@ -1181,6 +1192,7 @@ inline bool EvalState::evalBool(Env & env, Expr * e, const PosIdx pos, std::stri
|
||||||
|
|
||||||
inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v, const PosIdx pos, std::string_view errorCtx)
|
inline void EvalState::evalAttrs(Env & env, Expr * e, Value & v, const PosIdx pos, std::string_view errorCtx)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_TYPE_STR(*this, e, "attrs")
|
||||||
try {
|
try {
|
||||||
e->eval(*this, env, v);
|
e->eval(*this, env, v);
|
||||||
if (v.type() != nAttrs)
|
if (v.type() != nAttrs)
|
||||||
|
@ -1203,29 +1215,34 @@ void Expr::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprInt::eval(EvalState & state, Env & env, Value & v)
|
void ExprInt::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
v = this->v;
|
v = this->v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExprFloat::eval(EvalState & state, Env & env, Value & v)
|
void ExprFloat::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
v = this->v;
|
v = this->v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExprString::eval(EvalState & state, Env & env, Value & v)
|
void ExprString::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
v = this->v;
|
v = this->v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExprPath::eval(EvalState & state, Env & env, Value & v)
|
void ExprPath::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
v = this->v;
|
v = this->v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
v.mkAttrs(state.buildBindings(attrs.size() + dynamicAttrs.size()).finish());
|
v.mkAttrs(state.buildBindings(attrs.size() + dynamicAttrs.size()).finish());
|
||||||
auto dynamicEnv = &env;
|
auto dynamicEnv = &env;
|
||||||
|
|
||||||
|
@ -1310,6 +1327,7 @@ void ExprAttrs::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
/* Create a new environment that contains the attributes in this
|
/* Create a new environment that contains the attributes in this
|
||||||
`let'. */
|
`let'. */
|
||||||
Env & env2(state.allocEnv(attrs->attrs.size()));
|
Env & env2(state.allocEnv(attrs->attrs.size()));
|
||||||
|
@ -1328,6 +1346,7 @@ void ExprLet::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprList::eval(EvalState & state, Env & env, Value & v)
|
void ExprList::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
state.mkList(v, elems.size());
|
state.mkList(v, elems.size());
|
||||||
for (auto [n, v2] : enumerate(v.listItems()))
|
for (auto [n, v2] : enumerate(v.listItems()))
|
||||||
const_cast<Value * &>(v2) = elems[n]->maybeThunk(state, env);
|
const_cast<Value * &>(v2) = elems[n]->maybeThunk(state, env);
|
||||||
|
@ -1336,6 +1355,7 @@ void ExprList::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
Value * ExprList::maybeThunk(EvalState & state, Env & env)
|
Value * ExprList::maybeThunk(EvalState & state, Env & env)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
if (elems.empty()) {
|
if (elems.empty()) {
|
||||||
return &state.vEmptyList;
|
return &state.vEmptyList;
|
||||||
}
|
}
|
||||||
|
@ -1345,6 +1365,7 @@ Value * ExprList::maybeThunk(EvalState & state, Env & env)
|
||||||
|
|
||||||
void ExprVar::eval(EvalState & state, Env & env, Value & v)
|
void ExprVar::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
Value * v2 = state.lookupVar(&env, *this, false);
|
Value * v2 = state.lookupVar(&env, *this, false);
|
||||||
state.forceValue(*v2, pos);
|
state.forceValue(*v2, pos);
|
||||||
v = *v2;
|
v = *v2;
|
||||||
|
@ -1372,6 +1393,7 @@ static std::string showAttrPath(EvalState & state, Env & env, const AttrPath & a
|
||||||
|
|
||||||
void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this)
|
||||||
Value vTmp;
|
Value vTmp;
|
||||||
PosIdx pos2;
|
PosIdx pos2;
|
||||||
Value * vAttrs = &vTmp;
|
Value * vAttrs = &vTmp;
|
||||||
|
@ -1436,6 +1458,7 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this)
|
||||||
Value vTmp;
|
Value vTmp;
|
||||||
Value * vAttrs = &vTmp;
|
Value * vAttrs = &vTmp;
|
||||||
|
|
||||||
|
@ -1461,6 +1484,7 @@ void ExprOpHasAttr::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprLambda::eval(EvalState & state, Env & env, Value & v)
|
void ExprLambda::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this)
|
||||||
v.mkLambda(&env, this);
|
v.mkLambda(&env, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1718,6 +1742,7 @@ void EvalState::callFunction(Value & fun, size_t nrArgs, Value * * args, Value &
|
||||||
|
|
||||||
void ExprCall::eval(EvalState & state, Env & env, Value & v)
|
void ExprCall::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
Value vFun;
|
Value vFun;
|
||||||
fun->eval(state, env, vFun);
|
fun->eval(state, env, vFun);
|
||||||
|
|
||||||
|
@ -1795,6 +1820,7 @@ https://nixos.org/manual/nix/stable/language/constructs.html#functions.)", symbo
|
||||||
|
|
||||||
void ExprWith::eval(EvalState & state, Env & env, Value & v)
|
void ExprWith::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
Env & env2(state.allocEnv(1));
|
Env & env2(state.allocEnv(1));
|
||||||
env2.up = &env;
|
env2.up = &env;
|
||||||
env2.values[0] = attrs->maybeThunk(state, env);
|
env2.values[0] = attrs->maybeThunk(state, env);
|
||||||
|
@ -1805,6 +1831,7 @@ void ExprWith::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprIf::eval(EvalState & state, Env & env, Value & v)
|
void ExprIf::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
// We cheat in the parser, and pass the position of the condition as the position of the if itself.
|
// We cheat in the parser, and pass the position of the condition as the position of the if itself.
|
||||||
(state.evalBool(env, cond, pos, "while evaluating a branch condition") ? then : else_)->eval(state, env, v);
|
(state.evalBool(env, cond, pos, "while evaluating a branch condition") ? then : else_)->eval(state, env, v);
|
||||||
}
|
}
|
||||||
|
@ -1812,6 +1839,7 @@ void ExprIf::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprAssert::eval(EvalState & state, Env & env, Value & v)
|
void ExprAssert::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
if (!state.evalBool(env, cond, pos, "in the condition of the assert statement")) {
|
if (!state.evalBool(env, cond, pos, "in the condition of the assert statement")) {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
cond->show(state.symbols, out);
|
cond->show(state.symbols, out);
|
||||||
|
@ -1823,12 +1851,14 @@ void ExprAssert::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprOpNot::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpNot::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
v.mkBool(!state.evalBool(env, e, getPos(), "in the argument of the not operator")); // XXX: FIXME: !
|
v.mkBool(!state.evalBool(env, e, getPos(), "in the argument of the not operator")); // XXX: FIXME: !
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExprOpEq::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpEq::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
Value v1; e1->eval(state, env, v1);
|
Value v1; e1->eval(state, env, v1);
|
||||||
Value v2; e2->eval(state, env, v2);
|
Value v2; e2->eval(state, env, v2);
|
||||||
v.mkBool(state.eqValues(v1, v2, pos, "while testing two values for equality"));
|
v.mkBool(state.eqValues(v1, v2, pos, "while testing two values for equality"));
|
||||||
|
@ -1837,6 +1867,7 @@ void ExprOpEq::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprOpNEq::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpNEq::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
Value v1; e1->eval(state, env, v1);
|
Value v1; e1->eval(state, env, v1);
|
||||||
Value v2; e2->eval(state, env, v2);
|
Value v2; e2->eval(state, env, v2);
|
||||||
v.mkBool(!state.eqValues(v1, v2, pos, "while testing two values for inequality"));
|
v.mkBool(!state.eqValues(v1, v2, pos, "while testing two values for inequality"));
|
||||||
|
@ -1845,6 +1876,7 @@ void ExprOpNEq::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprOpAnd::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpAnd::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
v.mkBool(state.evalBool(env, e1, pos, "in the left operand of the AND (&&) operator") && state.evalBool(env, e2, pos, "in the right operand of the AND (&&) operator"));
|
v.mkBool(state.evalBool(env, e1, pos, "in the left operand of the AND (&&) operator") && state.evalBool(env, e2, pos, "in the right operand of the AND (&&) operator"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1857,12 +1889,14 @@ void ExprOpOr::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprOpImpl::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpImpl::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
v.mkBool(!state.evalBool(env, e1, pos, "in the left operand of the IMPL (->) operator") || state.evalBool(env, e2, pos, "in the right operand of the IMPL (->) operator"));
|
v.mkBool(!state.evalBool(env, e1, pos, "in the left operand of the IMPL (->) operator") || state.evalBool(env, e2, pos, "in the right operand of the IMPL (->) operator"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
Value v1, v2;
|
Value v1, v2;
|
||||||
state.evalAttrs(env, e1, v1, pos, "in the left operand of the update (//) operator");
|
state.evalAttrs(env, e1, v1, pos, "in the left operand of the update (//) operator");
|
||||||
state.evalAttrs(env, e2, v2, pos, "in the right operand of the update (//) operator");
|
state.evalAttrs(env, e2, v2, pos, "in the right operand of the update (//) operator");
|
||||||
|
@ -1901,6 +1935,7 @@ void ExprOpUpdate::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprOpConcatLists::eval(EvalState & state, Env & env, Value & v)
|
void ExprOpConcatLists::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
Value v1; e1->eval(state, env, v1);
|
Value v1; e1->eval(state, env, v1);
|
||||||
Value v2; e2->eval(state, env, v2);
|
Value v2; e2->eval(state, env, v2);
|
||||||
Value * lists[2] = { &v1, &v2 };
|
Value * lists[2] = { &v1, &v2 };
|
||||||
|
@ -1939,6 +1974,7 @@ void EvalState::concatLists(Value & v, size_t nrLists, Value * * lists, const Po
|
||||||
|
|
||||||
void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
std::vector<BackedStringView> s;
|
std::vector<BackedStringView> s;
|
||||||
size_t sSize = 0;
|
size_t sSize = 0;
|
||||||
|
@ -2031,12 +2067,14 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
|
||||||
|
|
||||||
void ExprPos::eval(EvalState & state, Env & env, Value & v)
|
void ExprPos::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
state.mkPos(v, pos);
|
state.mkPos(v, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ExprBlackHole::eval(EvalState & state, Env & env, Value & v)
|
void ExprBlackHole::eval(EvalState & state, Env & env, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE(state, this);
|
||||||
state.error("infinite recursion encountered")
|
state.error("infinite recursion encountered")
|
||||||
.debugThrow<InfiniteRecursionError>();
|
.debugThrow<InfiniteRecursionError>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,12 @@ libexpr_LDFLAGS += -lboost_context $(THREAD_LDFLAGS)
|
||||||
ifdef HOST_LINUX
|
ifdef HOST_LINUX
|
||||||
libexpr_LDFLAGS += -ldl
|
libexpr_LDFLAGS += -ldl
|
||||||
endif
|
endif
|
||||||
|
ifneq ($(TRACY_PROFILER), no)
|
||||||
|
libexpr_LDFLAGS += -ltracy
|
||||||
|
# We have to set TRACY_ENABLE to have tracy actually send the trace
|
||||||
|
# events, it's no-op without them.
|
||||||
|
libexpr_CXXFLAGS += -DTRACY_ENABLE=1
|
||||||
|
endif
|
||||||
|
|
||||||
# The dependency on libgc must be propagated (i.e. meaning that
|
# The dependency on libgc must be propagated (i.e. meaning that
|
||||||
# programs/libraries that use libexpr must explicitly pass -lgc),
|
# programs/libraries that use libexpr must explicitly pass -lgc),
|
||||||
|
@ -48,3 +54,4 @@ $(d)/primops.cc: $(d)/imported-drv-to-derivation.nix.gen.hh
|
||||||
$(d)/eval.cc: $(d)/primops/derivation.nix.gen.hh $(d)/fetchurl.nix.gen.hh $(d)/flake/call-flake.nix.gen.hh
|
$(d)/eval.cc: $(d)/primops/derivation.nix.gen.hh $(d)/fetchurl.nix.gen.hh $(d)/flake/call-flake.nix.gen.hh
|
||||||
|
|
||||||
$(buildprefix)src/libexpr/primops/fromTOML.o: ERROR_SWITCH_ENUM =
|
$(buildprefix)src/libexpr/primops/fromTOML.o: ERROR_SWITCH_ENUM =
|
||||||
|
$(buildprefix)src/libexpr/tracy/public/TracyClient.o: ERROR_SWITCH_ENUM =
|
||||||
|
|
|
@ -156,6 +156,7 @@ struct Expr
|
||||||
virtual Value * maybeThunk(EvalState & state, Env & env);
|
virtual Value * maybeThunk(EvalState & state, Env & env);
|
||||||
virtual void setName(Symbol name);
|
virtual void setName(Symbol name);
|
||||||
virtual PosIdx getPos() const { return noPos; }
|
virtual PosIdx getPos() const { return noPos; }
|
||||||
|
virtual const char* showExprType() const { return "undefined"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define COMMON_METHODS \
|
#define COMMON_METHODS \
|
||||||
|
@ -168,6 +169,7 @@ struct ExprInt : Expr
|
||||||
Value v;
|
Value v;
|
||||||
ExprInt(NixInt n) { v.mkInt(n); };
|
ExprInt(NixInt n) { v.mkInt(n); };
|
||||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||||
|
const char* showExprType() const { return "int"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -176,6 +178,7 @@ struct ExprFloat : Expr
|
||||||
Value v;
|
Value v;
|
||||||
ExprFloat(NixFloat nf) { v.mkFloat(nf); };
|
ExprFloat(NixFloat nf) { v.mkFloat(nf); };
|
||||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||||
|
const char* showExprType() const { return "float"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -185,6 +188,7 @@ struct ExprString : Expr
|
||||||
Value v;
|
Value v;
|
||||||
ExprString(std::string &&s) : s(std::move(s)) { v.mkString(this->s.data()); };
|
ExprString(std::string &&s) : s(std::move(s)) { v.mkString(this->s.data()); };
|
||||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||||
|
const char* showExprType() const { return "string"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -198,6 +202,7 @@ struct ExprPath : Expr
|
||||||
v.mkPath(&*accessor, this->s.c_str());
|
v.mkPath(&*accessor, this->s.c_str());
|
||||||
}
|
}
|
||||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||||
|
const char* showExprType() const { return "path"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -229,6 +234,7 @@ struct ExprVar : Expr
|
||||||
ExprVar(const PosIdx & pos, Symbol name) : pos(pos), name(name) { };
|
ExprVar(const PosIdx & pos, Symbol name) : pos(pos), name(name) { };
|
||||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||||
PosIdx getPos() const override { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
|
const char* showExprType() const { return "var"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -240,6 +246,7 @@ struct ExprSelect : Expr
|
||||||
ExprSelect(const PosIdx & pos, Expr * e, AttrPath attrPath, Expr * def) : pos(pos), e(e), def(def), attrPath(std::move(attrPath)) { };
|
ExprSelect(const PosIdx & pos, Expr * e, AttrPath attrPath, Expr * def) : pos(pos), e(e), def(def), attrPath(std::move(attrPath)) { };
|
||||||
ExprSelect(const PosIdx & pos, Expr * e, Symbol name) : pos(pos), e(e), def(0) { attrPath.push_back(AttrName(name)); };
|
ExprSelect(const PosIdx & pos, Expr * e, Symbol name) : pos(pos), e(e), def(0) { attrPath.push_back(AttrName(name)); };
|
||||||
PosIdx getPos() const override { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
|
const char* showExprType() const { return "select"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -249,6 +256,7 @@ struct ExprOpHasAttr : Expr
|
||||||
AttrPath attrPath;
|
AttrPath attrPath;
|
||||||
ExprOpHasAttr(Expr * e, AttrPath attrPath) : e(e), attrPath(std::move(attrPath)) { };
|
ExprOpHasAttr(Expr * e, AttrPath attrPath) : e(e), attrPath(std::move(attrPath)) { };
|
||||||
PosIdx getPos() const override { return e->getPos(); }
|
PosIdx getPos() const override { return e->getPos(); }
|
||||||
|
const char* showExprType() const { return "op_has_attr"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -278,6 +286,7 @@ struct ExprAttrs : Expr
|
||||||
ExprAttrs(const PosIdx &pos) : recursive(false), pos(pos) { };
|
ExprAttrs(const PosIdx &pos) : recursive(false), pos(pos) { };
|
||||||
ExprAttrs() : recursive(false) { };
|
ExprAttrs() : recursive(false) { };
|
||||||
PosIdx getPos() const override { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
|
const char* showExprType() const { return "attrs"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -285,6 +294,7 @@ struct ExprList : Expr
|
||||||
{
|
{
|
||||||
std::vector<Expr *> elems;
|
std::vector<Expr *> elems;
|
||||||
ExprList() { };
|
ExprList() { };
|
||||||
|
const char* showExprType() const { return "list"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||||
|
|
||||||
|
@ -345,6 +355,7 @@ struct ExprLambda : Expr
|
||||||
std::string showNamePos(const EvalState & state) const;
|
std::string showNamePos(const EvalState & state) const;
|
||||||
inline bool hasFormals() const { return formals != nullptr; }
|
inline bool hasFormals() const { return formals != nullptr; }
|
||||||
PosIdx getPos() const override { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
|
const char* showExprType() const { return "lambda"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -357,6 +368,7 @@ struct ExprCall : Expr
|
||||||
: fun(fun), args(args), pos(pos)
|
: fun(fun), args(args), pos(pos)
|
||||||
{ }
|
{ }
|
||||||
PosIdx getPos() const override { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
|
const char* showExprType() const { return "call"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -365,6 +377,7 @@ struct ExprLet : Expr
|
||||||
ExprAttrs * attrs;
|
ExprAttrs * attrs;
|
||||||
Expr * body;
|
Expr * body;
|
||||||
ExprLet(ExprAttrs * attrs, Expr * body) : attrs(attrs), body(body) { };
|
ExprLet(ExprAttrs * attrs, Expr * body) : attrs(attrs), body(body) { };
|
||||||
|
const char* showExprType() const { return "let"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -376,6 +389,7 @@ struct ExprWith : Expr
|
||||||
ExprWith * parentWith;
|
ExprWith * parentWith;
|
||||||
ExprWith(const PosIdx & pos, Expr * attrs, Expr * body) : pos(pos), attrs(attrs), body(body) { };
|
ExprWith(const PosIdx & pos, Expr * attrs, Expr * body) : pos(pos), attrs(attrs), body(body) { };
|
||||||
PosIdx getPos() const override { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
|
const char* showExprType() const { return "with"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -385,6 +399,7 @@ struct ExprIf : Expr
|
||||||
Expr * cond, * then, * else_;
|
Expr * cond, * then, * else_;
|
||||||
ExprIf(const PosIdx & pos, Expr * cond, Expr * then, Expr * else_) : pos(pos), cond(cond), then(then), else_(else_) { };
|
ExprIf(const PosIdx & pos, Expr * cond, Expr * then, Expr * else_) : pos(pos), cond(cond), then(then), else_(else_) { };
|
||||||
PosIdx getPos() const override { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
|
const char* showExprType() const { return "if"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -394,6 +409,7 @@ struct ExprAssert : Expr
|
||||||
Expr * cond, * body;
|
Expr * cond, * body;
|
||||||
ExprAssert(const PosIdx & pos, Expr * cond, Expr * body) : pos(pos), cond(cond), body(body) { };
|
ExprAssert(const PosIdx & pos, Expr * cond, Expr * body) : pos(pos), cond(cond), body(body) { };
|
||||||
PosIdx getPos() const override { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
|
const char* showExprType() const { return "assert"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -422,6 +438,7 @@ struct ExprOpNot : Expr
|
||||||
} \
|
} \
|
||||||
void eval(EvalState & state, Env & env, Value & v) override; \
|
void eval(EvalState & state, Env & env, Value & v) override; \
|
||||||
PosIdx getPos() const override { return pos; } \
|
PosIdx getPos() const override { return pos; } \
|
||||||
|
const char* showExprType() const { return #name; } \
|
||||||
};
|
};
|
||||||
|
|
||||||
MakeBinOp(ExprOpEq, "==")
|
MakeBinOp(ExprOpEq, "==")
|
||||||
|
@ -440,6 +457,7 @@ struct ExprConcatStrings : Expr
|
||||||
ExprConcatStrings(const PosIdx & pos, bool forceString, std::vector<std::pair<PosIdx, Expr *>> * es)
|
ExprConcatStrings(const PosIdx & pos, bool forceString, std::vector<std::pair<PosIdx, Expr *>> * es)
|
||||||
: pos(pos), forceString(forceString), es(es) { };
|
: pos(pos), forceString(forceString), es(es) { };
|
||||||
PosIdx getPos() const override { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
|
const char* showExprType() const { return "concat_strings"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -448,6 +466,7 @@ struct ExprPos : Expr
|
||||||
PosIdx pos;
|
PosIdx pos;
|
||||||
ExprPos(const PosIdx & pos) : pos(pos) { };
|
ExprPos(const PosIdx & pos) : pos(pos) { };
|
||||||
PosIdx getPos() const override { return pos; }
|
PosIdx getPos() const override { return pos; }
|
||||||
|
const char* showExprType() const { return "pos"; }
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -457,6 +476,7 @@ struct ExprBlackHole : Expr
|
||||||
void show(const SymbolTable & symbols, std::ostream & str) const override {}
|
void show(const SymbolTable & symbols, std::ostream & str) const override {}
|
||||||
void eval(EvalState & state, Env & env, Value & v) override;
|
void eval(EvalState & state, Env & env, Value & v) override;
|
||||||
void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env) override {}
|
void bindVars(EvalState & es, const std::shared_ptr<const StaticEnv> & env) override {}
|
||||||
|
const char* showExprType() const { return "blackhole"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
extern ExprBlackHole eBlackHole;
|
extern ExprBlackHole eBlackHole;
|
||||||
|
|
|
@ -32,6 +32,13 @@
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
#include <tracy/Tracy.hpp>
|
||||||
|
|
||||||
|
#define TRACY_TRACE_PRIMOP(es, posidx, typestr) \
|
||||||
|
std::ostringstream tracyss; \
|
||||||
|
tracyss << es.positions[posidx] << " " << typestr; \
|
||||||
|
ZoneTransientN(nix, tracyss.str().c_str(), true);
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
|
||||||
|
|
||||||
|
@ -120,6 +127,7 @@ StringMap EvalState::realiseContext(const NixStringContext & context)
|
||||||
|
|
||||||
static SourcePath realisePath(EvalState & state, const PosIdx pos, Value & v, bool resolveSymlinks = true)
|
static SourcePath realisePath(EvalState & state, const PosIdx pos, Value & v, bool resolveSymlinks = true)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "realizePath");
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
|
|
||||||
auto path = state.coerceToPath(noPos, v, context, "while realising the context of a path");
|
auto path = state.coerceToPath(noPos, v, context, "while realising the context of a path");
|
||||||
|
@ -170,6 +178,7 @@ static void mkOutputString(
|
||||||
argument. */
|
argument. */
|
||||||
static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * vScope, Value & v)
|
static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * vScope, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.import");
|
||||||
auto path = realisePath(state, pos, vPath, false);
|
auto path = realisePath(state, pos, vPath, false);
|
||||||
auto path2 = path.path.abs();
|
auto path2 = path.path.abs();
|
||||||
|
|
||||||
|
@ -334,6 +343,7 @@ extern "C" typedef void (*ValueInitializer)(EvalState & state, Value & v);
|
||||||
/* Load a ValueInitializer from a DSO and return whatever it initializes */
|
/* Load a ValueInitializer from a DSO and return whatever it initializes */
|
||||||
void prim_importNative(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
void prim_importNative(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.importNative");
|
||||||
auto path = realisePath(state, pos, *args[0]);
|
auto path = realisePath(state, pos, *args[0]);
|
||||||
|
|
||||||
std::string sym(state.forceStringNoCtx(*args[1], pos, "while evaluating the second argument passed to builtins.importNative"));
|
std::string sym(state.forceStringNoCtx(*args[1], pos, "while evaluating the second argument passed to builtins.importNative"));
|
||||||
|
@ -361,6 +371,7 @@ void prim_importNative(EvalState & state, const PosIdx pos, Value * * args, Valu
|
||||||
/* Execute a program and parse its output */
|
/* Execute a program and parse its output */
|
||||||
void prim_exec(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
void prim_exec(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.exec");
|
||||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.exec");
|
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.exec");
|
||||||
auto elems = args[0]->listElems();
|
auto elems = args[0]->listElems();
|
||||||
auto count = args[0]->listSize();
|
auto count = args[0]->listSize();
|
||||||
|
@ -402,6 +413,7 @@ void prim_exec(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
/* Return a string representing the type of the expression. */
|
/* Return a string representing the type of the expression. */
|
||||||
static void prim_typeOf(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_typeOf(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.typeOf");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
std::string t;
|
std::string t;
|
||||||
switch (args[0]->type()) {
|
switch (args[0]->type()) {
|
||||||
|
@ -436,6 +448,7 @@ static RegisterPrimOp primop_typeOf({
|
||||||
/* Determine whether the argument is the null value. */
|
/* Determine whether the argument is the null value. */
|
||||||
static void prim_isNull(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_isNull(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.isNull");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
v.mkBool(args[0]->type() == nNull);
|
v.mkBool(args[0]->type() == nNull);
|
||||||
}
|
}
|
||||||
|
@ -454,6 +467,7 @@ static RegisterPrimOp primop_isNull({
|
||||||
/* Determine whether the argument is a function. */
|
/* Determine whether the argument is a function. */
|
||||||
static void prim_isFunction(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_isFunction(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.isFunction");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
v.mkBool(args[0]->type() == nFunction);
|
v.mkBool(args[0]->type() == nFunction);
|
||||||
}
|
}
|
||||||
|
@ -470,6 +484,7 @@ static RegisterPrimOp primop_isFunction({
|
||||||
/* Determine whether the argument is an integer. */
|
/* Determine whether the argument is an integer. */
|
||||||
static void prim_isInt(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_isInt(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.isInt");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
v.mkBool(args[0]->type() == nInt);
|
v.mkBool(args[0]->type() == nInt);
|
||||||
}
|
}
|
||||||
|
@ -486,6 +501,7 @@ static RegisterPrimOp primop_isInt({
|
||||||
/* Determine whether the argument is a float. */
|
/* Determine whether the argument is a float. */
|
||||||
static void prim_isFloat(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_isFloat(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.isFloat");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
v.mkBool(args[0]->type() == nFloat);
|
v.mkBool(args[0]->type() == nFloat);
|
||||||
}
|
}
|
||||||
|
@ -502,6 +518,7 @@ static RegisterPrimOp primop_isFloat({
|
||||||
/* Determine whether the argument is a string. */
|
/* Determine whether the argument is a string. */
|
||||||
static void prim_isString(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_isString(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.isString");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
v.mkBool(args[0]->type() == nString);
|
v.mkBool(args[0]->type() == nString);
|
||||||
}
|
}
|
||||||
|
@ -518,6 +535,7 @@ static RegisterPrimOp primop_isString({
|
||||||
/* Determine whether the argument is a Boolean. */
|
/* Determine whether the argument is a Boolean. */
|
||||||
static void prim_isBool(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_isBool(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.isBool");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
v.mkBool(args[0]->type() == nBool);
|
v.mkBool(args[0]->type() == nBool);
|
||||||
}
|
}
|
||||||
|
@ -534,6 +552,7 @@ static RegisterPrimOp primop_isBool({
|
||||||
/* Determine whether the argument is a path. */
|
/* Determine whether the argument is a path. */
|
||||||
static void prim_isPath(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_isPath(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.isPath");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
v.mkBool(args[0]->type() == nPath);
|
v.mkBool(args[0]->type() == nPath);
|
||||||
}
|
}
|
||||||
|
@ -644,6 +663,7 @@ static Bindings::iterator getAttr(
|
||||||
|
|
||||||
static void prim_genericClosure(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_genericClosure(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.genericClosure");
|
||||||
state.forceAttrs(*args[0], noPos, "while evaluating the first argument passed to builtins.genericClosure");
|
state.forceAttrs(*args[0], noPos, "while evaluating the first argument passed to builtins.genericClosure");
|
||||||
|
|
||||||
/* Get the start set. */
|
/* Get the start set. */
|
||||||
|
@ -754,6 +774,7 @@ static RegisterPrimOp primop_break({
|
||||||
)",
|
)",
|
||||||
.fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
.fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.break");
|
||||||
if (state.debugRepl && !state.debugTraces.empty()) {
|
if (state.debugRepl && !state.debugTraces.empty()) {
|
||||||
auto error = Error(ErrorInfo {
|
auto error = Error(ErrorInfo {
|
||||||
.level = lvlInfo,
|
.level = lvlInfo,
|
||||||
|
@ -787,6 +808,7 @@ static RegisterPrimOp primop_abort({
|
||||||
)",
|
)",
|
||||||
.fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
.fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.abort");
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
auto s = state.coerceToString(pos, *args[0], context,
|
auto s = state.coerceToString(pos, *args[0], context,
|
||||||
"while evaluating the error message passed to builtins.abort").toOwned();
|
"while evaluating the error message passed to builtins.abort").toOwned();
|
||||||
|
@ -806,6 +828,7 @@ static RegisterPrimOp primop_throw({
|
||||||
)",
|
)",
|
||||||
.fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
.fun = [](EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.throw");
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
auto s = state.coerceToString(pos, *args[0], context,
|
auto s = state.coerceToString(pos, *args[0], context,
|
||||||
"while evaluating the error message passed to builtin.throw").toOwned();
|
"while evaluating the error message passed to builtin.throw").toOwned();
|
||||||
|
@ -815,6 +838,7 @@ static RegisterPrimOp primop_throw({
|
||||||
|
|
||||||
static void prim_addErrorContext(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_addErrorContext(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.addErrorContext");
|
||||||
try {
|
try {
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
v = *args[1];
|
v = *args[1];
|
||||||
|
@ -836,6 +860,7 @@ static RegisterPrimOp primop_addErrorContext(PrimOp {
|
||||||
|
|
||||||
static void prim_ceil(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_ceil(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.ceil");
|
||||||
auto value = state.forceFloat(*args[0], args[0]->determinePos(pos),
|
auto value = state.forceFloat(*args[0], args[0]->determinePos(pos),
|
||||||
"while evaluating the first argument passed to builtins.ceil");
|
"while evaluating the first argument passed to builtins.ceil");
|
||||||
v.mkInt(ceil(value));
|
v.mkInt(ceil(value));
|
||||||
|
@ -856,6 +881,7 @@ static RegisterPrimOp primop_ceil({
|
||||||
|
|
||||||
static void prim_floor(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_floor(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.floor");
|
||||||
auto value = state.forceFloat(*args[0], args[0]->determinePos(pos), "while evaluating the first argument passed to builtins.floor");
|
auto value = state.forceFloat(*args[0], args[0]->determinePos(pos), "while evaluating the first argument passed to builtins.floor");
|
||||||
v.mkInt(floor(value));
|
v.mkInt(floor(value));
|
||||||
}
|
}
|
||||||
|
@ -877,6 +903,7 @@ static RegisterPrimOp primop_floor({
|
||||||
* else => {success=false; value=false;} */
|
* else => {success=false; value=false;} */
|
||||||
static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_tryEval(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.tryEval");
|
||||||
auto attrs = state.buildBindings(2);
|
auto attrs = state.buildBindings(2);
|
||||||
|
|
||||||
/* increment state.trylevel, and decrement it when this function returns. */
|
/* increment state.trylevel, and decrement it when this function returns. */
|
||||||
|
@ -930,6 +957,7 @@ static RegisterPrimOp primop_tryEval({
|
||||||
/* Return an environment variable. Use with care. */
|
/* Return an environment variable. Use with care. */
|
||||||
static void prim_getEnv(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_getEnv(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.getEnv");
|
||||||
std::string name(state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.getEnv"));
|
std::string name(state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.getEnv"));
|
||||||
v.mkString(evalSettings.restrictEval || evalSettings.pureEval ? "" : getEnv(name).value_or(""));
|
v.mkString(evalSettings.restrictEval || evalSettings.pureEval ? "" : getEnv(name).value_or(""));
|
||||||
}
|
}
|
||||||
|
@ -954,6 +982,7 @@ static RegisterPrimOp primop_getEnv({
|
||||||
/* Evaluate the first argument, then return the second argument. */
|
/* Evaluate the first argument, then return the second argument. */
|
||||||
static void prim_seq(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_seq(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.seq");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
v = *args[1];
|
v = *args[1];
|
||||||
|
@ -973,6 +1002,7 @@ static RegisterPrimOp primop_seq({
|
||||||
attrsets), then return the second argument. */
|
attrsets), then return the second argument. */
|
||||||
static void prim_deepSeq(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_deepSeq(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.deepSeq");
|
||||||
state.forceValueDeep(*args[0]);
|
state.forceValueDeep(*args[0]);
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
v = *args[1];
|
v = *args[1];
|
||||||
|
@ -993,6 +1023,7 @@ static RegisterPrimOp primop_deepSeq({
|
||||||
return the second expression. Useful for debugging. */
|
return the second expression. Useful for debugging. */
|
||||||
static void prim_trace(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_trace(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.trace");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
if (args[0]->type() == nString)
|
if (args[0]->type() == nString)
|
||||||
printError("trace: %1%", args[0]->string_view());
|
printError("trace: %1%", args[0]->string_view());
|
||||||
|
@ -1019,6 +1050,7 @@ static RegisterPrimOp primop_trace({
|
||||||
*/
|
*/
|
||||||
static void prim_second(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_second(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.second");
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
v = *args[1];
|
v = *args[1];
|
||||||
}
|
}
|
||||||
|
@ -1038,6 +1070,7 @@ static void derivationStrictInternal(EvalState & state, const std::string & name
|
||||||
derivation. */
|
derivation. */
|
||||||
static void prim_derivationStrict(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_derivationStrict(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.derivationStrict");
|
||||||
state.forceAttrs(*args[0], pos, "while evaluating the argument passed to builtins.derivationStrict");
|
state.forceAttrs(*args[0], pos, "while evaluating the argument passed to builtins.derivationStrict");
|
||||||
|
|
||||||
Bindings * attrs = args[0]->attrs;
|
Bindings * attrs = args[0]->attrs;
|
||||||
|
@ -1436,6 +1469,7 @@ static RegisterPrimOp primop_derivationStrict(PrimOp {
|
||||||
‘out’. */
|
‘out’. */
|
||||||
static void prim_placeholder(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_placeholder(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.placeholder");
|
||||||
v.mkString(hashPlaceholder(state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.placeholder")));
|
v.mkString(hashPlaceholder(state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.placeholder")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1459,6 +1493,7 @@ static RegisterPrimOp primop_placeholder({
|
||||||
/* Convert the argument to a path. !!! obsolete? */
|
/* Convert the argument to a path. !!! obsolete? */
|
||||||
static void prim_toPath(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_toPath(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.toPath");
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
auto path = state.coerceToPath(pos, *args[0], context, "while evaluating the first argument passed to builtins.toPath");
|
auto path = state.coerceToPath(pos, *args[0], context, "while evaluating the first argument passed to builtins.toPath");
|
||||||
v.mkString(path.path.abs(), context);
|
v.mkString(path.path.abs(), context);
|
||||||
|
@ -1484,6 +1519,7 @@ static RegisterPrimOp primop_toPath({
|
||||||
corner cases. */
|
corner cases. */
|
||||||
static void prim_storePath(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_storePath(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.storePath");
|
||||||
if (evalSettings.pureEval)
|
if (evalSettings.pureEval)
|
||||||
state.debugThrowLastTrace(EvalError({
|
state.debugThrowLastTrace(EvalError({
|
||||||
.msg = hintfmt("'%s' is not allowed in pure evaluation mode", "builtins.storePath"),
|
.msg = hintfmt("'%s' is not allowed in pure evaluation mode", "builtins.storePath"),
|
||||||
|
@ -1531,6 +1567,7 @@ static RegisterPrimOp primop_storePath({
|
||||||
|
|
||||||
static void prim_pathExists(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_pathExists(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.pathExists");
|
||||||
try {
|
try {
|
||||||
auto & arg = *args[0];
|
auto & arg = *args[0];
|
||||||
|
|
||||||
|
@ -1563,6 +1600,7 @@ static RegisterPrimOp primop_pathExists({
|
||||||
following the last slash. */
|
following the last slash. */
|
||||||
static void prim_baseNameOf(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_baseNameOf(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.baseNameOf");
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
v.mkString(baseNameOf(*state.coerceToString(pos, *args[0], context,
|
v.mkString(baseNameOf(*state.coerceToString(pos, *args[0], context,
|
||||||
"while evaluating the first argument passed to builtins.baseNameOf",
|
"while evaluating the first argument passed to builtins.baseNameOf",
|
||||||
|
@ -1585,6 +1623,7 @@ static RegisterPrimOp primop_baseNameOf({
|
||||||
of the argument. */
|
of the argument. */
|
||||||
static void prim_dirOf(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_dirOf(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.dirOf");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
if (args[0]->type() == nPath) {
|
if (args[0]->type() == nPath) {
|
||||||
auto path = args[0]->path();
|
auto path = args[0]->path();
|
||||||
|
@ -1613,6 +1652,7 @@ static RegisterPrimOp primop_dirOf({
|
||||||
/* Return the contents of a file as a string. */
|
/* Return the contents of a file as a string. */
|
||||||
static void prim_readFile(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_readFile(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.readFile");
|
||||||
auto path = realisePath(state, pos, *args[0]);
|
auto path = realisePath(state, pos, *args[0]);
|
||||||
auto s = path.readFile();
|
auto s = path.readFile();
|
||||||
if (s.find((char) 0) != std::string::npos)
|
if (s.find((char) 0) != std::string::npos)
|
||||||
|
@ -1650,6 +1690,7 @@ static RegisterPrimOp primop_readFile({
|
||||||
which are desugared to 'findFile __nixPath "x"'. */
|
which are desugared to 'findFile __nixPath "x"'. */
|
||||||
static void prim_findFile(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_findFile(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.findFile");
|
||||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.findFile");
|
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.findFile");
|
||||||
|
|
||||||
SearchPath searchPath;
|
SearchPath searchPath;
|
||||||
|
@ -1742,6 +1783,7 @@ static RegisterPrimOp primop_findFile(PrimOp {
|
||||||
/* Return the cryptographic hash of a file in base-16. */
|
/* Return the cryptographic hash of a file in base-16. */
|
||||||
static void prim_hashFile(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_hashFile(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.hashFile");
|
||||||
auto algo = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.hashFile");
|
auto algo = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.hashFile");
|
||||||
std::optional<HashAlgorithm> ha = parseHashAlgo(algo);
|
std::optional<HashAlgorithm> ha = parseHashAlgo(algo);
|
||||||
if (!ha)
|
if (!ha)
|
||||||
|
@ -1777,6 +1819,7 @@ static std::string_view fileTypeToString(InputAccessor::Type type)
|
||||||
|
|
||||||
static void prim_readFileType(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_readFileType(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.readFileType");
|
||||||
auto path = realisePath(state, pos, *args[0], false);
|
auto path = realisePath(state, pos, *args[0], false);
|
||||||
/* Retrieve the directory entry type and stringize it. */
|
/* Retrieve the directory entry type and stringize it. */
|
||||||
v.mkString(fileTypeToString(path.lstat().type));
|
v.mkString(fileTypeToString(path.lstat().type));
|
||||||
|
@ -1795,6 +1838,7 @@ static RegisterPrimOp primop_readFileType({
|
||||||
/* Read a directory (without . or ..) */
|
/* Read a directory (without . or ..) */
|
||||||
static void prim_readDir(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_readDir(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.readDir");
|
||||||
auto path = realisePath(state, pos, *args[0]);
|
auto path = realisePath(state, pos, *args[0]);
|
||||||
|
|
||||||
// Retrieve directory entries for all nodes in a directory.
|
// Retrieve directory entries for all nodes in a directory.
|
||||||
|
@ -1852,6 +1896,7 @@ static RegisterPrimOp primop_readDir({
|
||||||
/* Extend single element string context with another output. */
|
/* Extend single element string context with another output. */
|
||||||
static void prim_outputOf(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_outputOf(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.outputOf");
|
||||||
SingleDerivedPath drvPath = state.coerceToSingleDerivedPath(pos, *args[0], "while evaluating the first argument to builtins.outputOf");
|
SingleDerivedPath drvPath = state.coerceToSingleDerivedPath(pos, *args[0], "while evaluating the first argument to builtins.outputOf");
|
||||||
|
|
||||||
OutputNameView outputName = state.forceStringNoCtx(*args[1], pos, "while evaluating the second argument to builtins.outputOf");
|
OutputNameView outputName = state.forceStringNoCtx(*args[1], pos, "while evaluating the second argument to builtins.outputOf");
|
||||||
|
@ -1899,6 +1944,7 @@ static RegisterPrimOp primop_outputOf({
|
||||||
be sensibly or completely represented (e.g., functions). */
|
be sensibly or completely represented (e.g., functions). */
|
||||||
static void prim_toXML(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_toXML(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.toXML");
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
printValueAsXML(state, true, false, *args[0], out, context, pos);
|
printValueAsXML(state, true, false, *args[0], out, context, pos);
|
||||||
|
@ -2007,6 +2053,7 @@ static RegisterPrimOp primop_toXML({
|
||||||
represented (e.g., functions). */
|
represented (e.g., functions). */
|
||||||
static void prim_toJSON(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_toJSON(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.toJSON");
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
printValueAsJSON(state, true, *args[0], pos, out, context);
|
printValueAsJSON(state, true, *args[0], pos, out, context);
|
||||||
|
@ -2030,6 +2077,7 @@ static RegisterPrimOp primop_toJSON({
|
||||||
/* Parse a JSON string to a value. */
|
/* Parse a JSON string to a value. */
|
||||||
static void prim_fromJSON(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_fromJSON(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.fromJSON");
|
||||||
auto s = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.fromJSON");
|
auto s = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.fromJSON");
|
||||||
try {
|
try {
|
||||||
parseJSON(state, s, v);
|
parseJSON(state, s, v);
|
||||||
|
@ -2058,6 +2106,7 @@ static RegisterPrimOp primop_fromJSON({
|
||||||
as an input by derivations. */
|
as an input by derivations. */
|
||||||
static void prim_toFile(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_toFile(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.toFile");
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
std::string name(state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.toFile"));
|
std::string name(state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.toFile"));
|
||||||
std::string contents(state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.toFile"));
|
std::string contents(state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.toFile"));
|
||||||
|
@ -2207,6 +2256,7 @@ static void addPath(
|
||||||
Value & v,
|
Value & v,
|
||||||
const NixStringContext & context)
|
const NixStringContext & context)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.addPath");
|
||||||
try {
|
try {
|
||||||
StorePathSet refs;
|
StorePathSet refs;
|
||||||
|
|
||||||
|
@ -2256,6 +2306,7 @@ static void addPath(
|
||||||
|
|
||||||
static void prim_filterSource(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_filterSource(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.filterSource");
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
auto path = state.coerceToPath(pos, *args[1], context,
|
auto path = state.coerceToPath(pos, *args[1], context,
|
||||||
"while evaluating the second argument (the path to filter) passed to 'builtins.filterSource'");
|
"while evaluating the second argument (the path to filter) passed to 'builtins.filterSource'");
|
||||||
|
@ -2321,6 +2372,7 @@ static RegisterPrimOp primop_filterSource({
|
||||||
|
|
||||||
static void prim_path(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_path(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.path");
|
||||||
std::optional<SourcePath> path;
|
std::optional<SourcePath> path;
|
||||||
std::string name;
|
std::string name;
|
||||||
Value * filterFun = nullptr;
|
Value * filterFun = nullptr;
|
||||||
|
@ -2404,6 +2456,7 @@ static RegisterPrimOp primop_path({
|
||||||
strings. */
|
strings. */
|
||||||
static void prim_attrNames(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_attrNames(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.attrNames");
|
||||||
state.forceAttrs(*args[0], pos, "while evaluating the argument passed to builtins.attrNames");
|
state.forceAttrs(*args[0], pos, "while evaluating the argument passed to builtins.attrNames");
|
||||||
|
|
||||||
state.mkList(v, args[0]->attrs->size());
|
state.mkList(v, args[0]->attrs->size());
|
||||||
|
@ -2431,6 +2484,7 @@ static RegisterPrimOp primop_attrNames({
|
||||||
order as attrNames. */
|
order as attrNames. */
|
||||||
static void prim_attrValues(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_attrValues(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.attrValues");
|
||||||
state.forceAttrs(*args[0], pos, "while evaluating the argument passed to builtins.attrValues");
|
state.forceAttrs(*args[0], pos, "while evaluating the argument passed to builtins.attrValues");
|
||||||
|
|
||||||
state.mkList(v, args[0]->attrs->size());
|
state.mkList(v, args[0]->attrs->size());
|
||||||
|
@ -2463,6 +2517,7 @@ static RegisterPrimOp primop_attrValues({
|
||||||
/* Dynamic version of the `.' operator. */
|
/* Dynamic version of the `.' operator. */
|
||||||
void prim_getAttr(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
void prim_getAttr(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.getAttr");
|
||||||
auto attr = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.getAttr");
|
auto attr = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.getAttr");
|
||||||
state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.getAttr");
|
state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.getAttr");
|
||||||
Bindings::iterator i = getAttr(
|
Bindings::iterator i = getAttr(
|
||||||
|
@ -2492,6 +2547,7 @@ static RegisterPrimOp primop_getAttr({
|
||||||
/* Return position information of the specified attribute. */
|
/* Return position information of the specified attribute. */
|
||||||
static void prim_unsafeGetAttrPos(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_unsafeGetAttrPos(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.unsafeGetAttrPos");
|
||||||
auto attr = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.unsafeGetAttrPos");
|
auto attr = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.unsafeGetAttrPos");
|
||||||
state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.unsafeGetAttrPos");
|
state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.unsafeGetAttrPos");
|
||||||
Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
|
Bindings::iterator i = args[1]->attrs->find(state.symbols.create(attr));
|
||||||
|
@ -2510,6 +2566,7 @@ static RegisterPrimOp primop_unsafeGetAttrPos(PrimOp {
|
||||||
/* Dynamic version of the `?' operator. */
|
/* Dynamic version of the `?' operator. */
|
||||||
static void prim_hasAttr(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_hasAttr(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.hasAttr");
|
||||||
auto attr = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.hasAttr");
|
auto attr = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.hasAttr");
|
||||||
state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.hasAttr");
|
state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.hasAttr");
|
||||||
v.mkBool(args[1]->attrs->find(state.symbols.create(attr)) != args[1]->attrs->end());
|
v.mkBool(args[1]->attrs->find(state.symbols.create(attr)) != args[1]->attrs->end());
|
||||||
|
@ -2544,6 +2601,7 @@ static RegisterPrimOp primop_isAttrs({
|
||||||
|
|
||||||
static void prim_removeAttrs(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_removeAttrs(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.removeAttrs");
|
||||||
state.forceAttrs(*args[0], pos, "while evaluating the first argument passed to builtins.removeAttrs");
|
state.forceAttrs(*args[0], pos, "while evaluating the first argument passed to builtins.removeAttrs");
|
||||||
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.removeAttrs");
|
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.removeAttrs");
|
||||||
|
|
||||||
|
@ -2593,6 +2651,7 @@ static RegisterPrimOp primop_removeAttrs({
|
||||||
name, the first takes precedence. */
|
name, the first takes precedence. */
|
||||||
static void prim_listToAttrs(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_listToAttrs(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.listToAttrs");
|
||||||
state.forceList(*args[0], pos, "while evaluating the argument passed to builtins.listToAttrs");
|
state.forceList(*args[0], pos, "while evaluating the argument passed to builtins.listToAttrs");
|
||||||
|
|
||||||
auto attrs = state.buildBindings(args[0]->listSize());
|
auto attrs = state.buildBindings(args[0]->listSize());
|
||||||
|
@ -2649,6 +2708,7 @@ static RegisterPrimOp primop_listToAttrs({
|
||||||
|
|
||||||
static void prim_intersectAttrs(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_intersectAttrs(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.intersectAttrs");
|
||||||
state.forceAttrs(*args[0], pos, "while evaluating the first argument passed to builtins.intersectAttrs");
|
state.forceAttrs(*args[0], pos, "while evaluating the first argument passed to builtins.intersectAttrs");
|
||||||
state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.intersectAttrs");
|
state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.intersectAttrs");
|
||||||
|
|
||||||
|
@ -2727,6 +2787,7 @@ static RegisterPrimOp primop_intersectAttrs({
|
||||||
|
|
||||||
static void prim_catAttrs(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_catAttrs(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.catAttrs");
|
||||||
auto attrName = state.symbols.create(state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.catAttrs"));
|
auto attrName = state.symbols.create(state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.catAttrs"));
|
||||||
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.catAttrs");
|
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.catAttrs");
|
||||||
|
|
||||||
|
@ -2764,6 +2825,7 @@ static RegisterPrimOp primop_catAttrs({
|
||||||
|
|
||||||
static void prim_functionArgs(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_functionArgs(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.functionArgs");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
if (args[0]->isPrimOpApp() || args[0]->isPrimOp()) {
|
if (args[0]->isPrimOpApp() || args[0]->isPrimOp()) {
|
||||||
v.mkAttrs(&state.emptyBindings);
|
v.mkAttrs(&state.emptyBindings);
|
||||||
|
@ -2807,6 +2869,7 @@ static RegisterPrimOp primop_functionArgs({
|
||||||
/* */
|
/* */
|
||||||
static void prim_mapAttrs(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_mapAttrs(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.mapAttrs");
|
||||||
state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.mapAttrs");
|
state.forceAttrs(*args[1], pos, "while evaluating the second argument passed to builtins.mapAttrs");
|
||||||
|
|
||||||
auto attrs = state.buildBindings(args[1]->attrs->size());
|
auto attrs = state.buildBindings(args[1]->attrs->size());
|
||||||
|
@ -2839,6 +2902,7 @@ static RegisterPrimOp primop_mapAttrs({
|
||||||
|
|
||||||
static void prim_zipAttrsWith(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_zipAttrsWith(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.zipAttrsWith");
|
||||||
// we will first count how many values are present for each given key.
|
// we will first count how many values are present for each given key.
|
||||||
// we then allocate a single attrset and pre-populate it with lists of
|
// we then allocate a single attrset and pre-populate it with lists of
|
||||||
// appropriate sizes, stash the pointers to the list elements of each,
|
// appropriate sizes, stash the pointers to the list elements of each,
|
||||||
|
@ -2926,6 +2990,7 @@ static RegisterPrimOp primop_zipAttrsWith({
|
||||||
/* Determine whether the argument is a list. */
|
/* Determine whether the argument is a list. */
|
||||||
static void prim_isList(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_isList(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.isList");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
v.mkBool(args[0]->type() == nList);
|
v.mkBool(args[0]->type() == nList);
|
||||||
}
|
}
|
||||||
|
@ -2954,6 +3019,7 @@ static void elemAt(EvalState & state, const PosIdx pos, Value & list, int n, Val
|
||||||
/* Return the n-1'th element of a list. */
|
/* Return the n-1'th element of a list. */
|
||||||
static void prim_elemAt(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_elemAt(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.elemAt");
|
||||||
elemAt(state, pos, *args[0], state.forceInt(*args[1], pos, "while evaluating the second argument passed to builtins.elemAt"), v);
|
elemAt(state, pos, *args[0], state.forceInt(*args[1], pos, "while evaluating the second argument passed to builtins.elemAt"), v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2970,6 +3036,7 @@ static RegisterPrimOp primop_elemAt({
|
||||||
/* Return the first element of a list. */
|
/* Return the first element of a list. */
|
||||||
static void prim_head(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_head(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.head");
|
||||||
elemAt(state, pos, *args[0], 0, v);
|
elemAt(state, pos, *args[0], 0, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2989,6 +3056,7 @@ static RegisterPrimOp primop_head({
|
||||||
don't want to use it! */
|
don't want to use it! */
|
||||||
static void prim_tail(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_tail(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.tail");
|
||||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.tail");
|
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.tail");
|
||||||
if (args[0]->listSize() == 0)
|
if (args[0]->listSize() == 0)
|
||||||
state.debugThrowLastTrace(Error({
|
state.debugThrowLastTrace(Error({
|
||||||
|
@ -3020,6 +3088,7 @@ static RegisterPrimOp primop_tail({
|
||||||
/* Apply a function to every element of a list. */
|
/* Apply a function to every element of a list. */
|
||||||
static void prim_map(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_map(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.map");
|
||||||
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.map");
|
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.map");
|
||||||
|
|
||||||
if (args[1]->listSize() == 0) {
|
if (args[1]->listSize() == 0) {
|
||||||
|
@ -3056,6 +3125,7 @@ static RegisterPrimOp primop_map({
|
||||||
returns true. */
|
returns true. */
|
||||||
static void prim_filter(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_filter(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.filter");
|
||||||
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.filter");
|
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.filter");
|
||||||
|
|
||||||
if (args[1]->listSize() == 0) {
|
if (args[1]->listSize() == 0) {
|
||||||
|
@ -3099,6 +3169,7 @@ static RegisterPrimOp primop_filter({
|
||||||
/* Return true if a list contains a given element. */
|
/* Return true if a list contains a given element. */
|
||||||
static void prim_elem(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_elem(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.elem");
|
||||||
bool res = false;
|
bool res = false;
|
||||||
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.elem");
|
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.elem");
|
||||||
for (auto elem : args[1]->listItems())
|
for (auto elem : args[1]->listItems())
|
||||||
|
@ -3122,6 +3193,7 @@ static RegisterPrimOp primop_elem({
|
||||||
/* Concatenate a list of lists. */
|
/* Concatenate a list of lists. */
|
||||||
static void prim_concatLists(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_concatLists(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.concatLists");
|
||||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.concatLists");
|
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.concatLists");
|
||||||
state.concatLists(v, args[0]->listSize(), args[0]->listElems(), pos, "while evaluating a value of the list passed to builtins.concatLists");
|
state.concatLists(v, args[0]->listSize(), args[0]->listElems(), pos, "while evaluating a value of the list passed to builtins.concatLists");
|
||||||
}
|
}
|
||||||
|
@ -3138,6 +3210,7 @@ static RegisterPrimOp primop_concatLists({
|
||||||
/* Return the length of a list. This is an O(1) time operation. */
|
/* Return the length of a list. This is an O(1) time operation. */
|
||||||
static void prim_length(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_length(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.length");
|
||||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.length");
|
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.length");
|
||||||
v.mkInt(args[0]->listSize());
|
v.mkInt(args[0]->listSize());
|
||||||
}
|
}
|
||||||
|
@ -3155,6 +3228,7 @@ static RegisterPrimOp primop_length({
|
||||||
right. The operator is applied strictly. */
|
right. The operator is applied strictly. */
|
||||||
static void prim_foldlStrict(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_foldlStrict(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.foldStrict");
|
||||||
state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.foldlStrict");
|
state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.foldlStrict");
|
||||||
state.forceList(*args[2], pos, "while evaluating the third argument passed to builtins.foldlStrict");
|
state.forceList(*args[2], pos, "while evaluating the third argument passed to builtins.foldlStrict");
|
||||||
|
|
||||||
|
@ -3218,6 +3292,7 @@ static void anyOrAll(bool any, EvalState & state, const PosIdx pos, Value * * ar
|
||||||
|
|
||||||
static void prim_any(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_any(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.any");
|
||||||
anyOrAll(true, state, pos, args, v);
|
anyOrAll(true, state, pos, args, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3233,6 +3308,7 @@ static RegisterPrimOp primop_any({
|
||||||
|
|
||||||
static void prim_all(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_all(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.all");
|
||||||
anyOrAll(false, state, pos, args, v);
|
anyOrAll(false, state, pos, args, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3248,6 +3324,7 @@ static RegisterPrimOp primop_all({
|
||||||
|
|
||||||
static void prim_genList(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_genList(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.genList");
|
||||||
auto len = state.forceInt(*args[1], pos, "while evaluating the second argument passed to builtins.genList");
|
auto len = state.forceInt(*args[1], pos, "while evaluating the second argument passed to builtins.genList");
|
||||||
|
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
|
@ -3286,6 +3363,7 @@ static void prim_lessThan(EvalState & state, const PosIdx pos, Value * * args, V
|
||||||
|
|
||||||
static void prim_sort(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_sort(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.sort");
|
||||||
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.sort");
|
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.sort");
|
||||||
|
|
||||||
auto len = args[1]->listSize();
|
auto len = args[1]->listSize();
|
||||||
|
@ -3345,6 +3423,7 @@ static RegisterPrimOp primop_sort({
|
||||||
|
|
||||||
static void prim_partition(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_partition(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.partition");
|
||||||
state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.partition");
|
state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.partition");
|
||||||
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.partition");
|
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.partition");
|
||||||
|
|
||||||
|
@ -3405,6 +3484,7 @@ static RegisterPrimOp primop_partition({
|
||||||
|
|
||||||
static void prim_groupBy(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_groupBy(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.groupBy");
|
||||||
state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.groupBy");
|
state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.groupBy");
|
||||||
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.groupBy");
|
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.groupBy");
|
||||||
|
|
||||||
|
@ -3457,6 +3537,7 @@ static RegisterPrimOp primop_groupBy({
|
||||||
|
|
||||||
static void prim_concatMap(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_concatMap(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.concatMap");
|
||||||
state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.concatMap");
|
state.forceFunction(*args[0], pos, "while evaluating the first argument passed to builtins.concatMap");
|
||||||
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.concatMap");
|
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.concatMap");
|
||||||
auto nrLists = args[1]->listSize();
|
auto nrLists = args[1]->listSize();
|
||||||
|
@ -3500,6 +3581,7 @@ static RegisterPrimOp primop_concatMap({
|
||||||
|
|
||||||
static void prim_add(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_add(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.add");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
if (args[0]->type() == nFloat || args[1]->type() == nFloat)
|
if (args[0]->type() == nFloat || args[1]->type() == nFloat)
|
||||||
|
@ -3521,6 +3603,7 @@ static RegisterPrimOp primop_add({
|
||||||
|
|
||||||
static void prim_sub(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_sub(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.sub");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
if (args[0]->type() == nFloat || args[1]->type() == nFloat)
|
if (args[0]->type() == nFloat || args[1]->type() == nFloat)
|
||||||
|
@ -3542,6 +3625,7 @@ static RegisterPrimOp primop_sub({
|
||||||
|
|
||||||
static void prim_mul(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_mul(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.mul");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
if (args[0]->type() == nFloat || args[1]->type() == nFloat)
|
if (args[0]->type() == nFloat || args[1]->type() == nFloat)
|
||||||
|
@ -3563,6 +3647,7 @@ static RegisterPrimOp primop_mul({
|
||||||
|
|
||||||
static void prim_div(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_div(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.div");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
|
|
||||||
|
@ -3600,6 +3685,7 @@ static RegisterPrimOp primop_div({
|
||||||
|
|
||||||
static void prim_bitAnd(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_bitAnd(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.bitAnd");
|
||||||
v.mkInt(state.forceInt(*args[0], pos, "while evaluating the first argument passed to builtins.bitAnd")
|
v.mkInt(state.forceInt(*args[0], pos, "while evaluating the first argument passed to builtins.bitAnd")
|
||||||
& state.forceInt(*args[1], pos, "while evaluating the second argument passed to builtins.bitAnd"));
|
& state.forceInt(*args[1], pos, "while evaluating the second argument passed to builtins.bitAnd"));
|
||||||
}
|
}
|
||||||
|
@ -3645,6 +3731,7 @@ static RegisterPrimOp primop_bitXor({
|
||||||
|
|
||||||
static void prim_lessThan(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_lessThan(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.lessThan");
|
||||||
state.forceValue(*args[0], pos);
|
state.forceValue(*args[0], pos);
|
||||||
state.forceValue(*args[1], pos);
|
state.forceValue(*args[1], pos);
|
||||||
// pos is exact here, no need for a message.
|
// pos is exact here, no need for a message.
|
||||||
|
@ -3674,6 +3761,7 @@ static RegisterPrimOp primop_lessThan({
|
||||||
`"/nix/store/whatever..."'. */
|
`"/nix/store/whatever..."'. */
|
||||||
static void prim_toString(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_toString(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.toString");
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
auto s = state.coerceToString(pos, *args[0], context,
|
auto s = state.coerceToString(pos, *args[0], context,
|
||||||
"while evaluating the first argument passed to builtins.toString",
|
"while evaluating the first argument passed to builtins.toString",
|
||||||
|
@ -3711,6 +3799,7 @@ static RegisterPrimOp primop_toString({
|
||||||
non-negative. */
|
non-negative. */
|
||||||
static void prim_substring(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_substring(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.substring");
|
||||||
int start = state.forceInt(*args[0], pos, "while evaluating the first argument (the start offset) passed to builtins.substring");
|
int start = state.forceInt(*args[0], pos, "while evaluating the first argument (the start offset) passed to builtins.substring");
|
||||||
|
|
||||||
if (start < 0)
|
if (start < 0)
|
||||||
|
@ -3761,6 +3850,7 @@ static RegisterPrimOp primop_substring({
|
||||||
|
|
||||||
static void prim_stringLength(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_stringLength(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.stringLength");
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
auto s = state.coerceToString(pos, *args[0], context, "while evaluating the argument passed to builtins.stringLength");
|
auto s = state.coerceToString(pos, *args[0], context, "while evaluating the argument passed to builtins.stringLength");
|
||||||
v.mkInt(s->size());
|
v.mkInt(s->size());
|
||||||
|
@ -3779,6 +3869,7 @@ static RegisterPrimOp primop_stringLength({
|
||||||
/* Return the cryptographic hash of a string in base-16. */
|
/* Return the cryptographic hash of a string in base-16. */
|
||||||
static void prim_hashString(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_hashString(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.hashString");
|
||||||
auto algo = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.hashString");
|
auto algo = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.hashString");
|
||||||
std::optional<HashAlgorithm> ha = parseHashAlgo(algo);
|
std::optional<HashAlgorithm> ha = parseHashAlgo(algo);
|
||||||
if (!ha)
|
if (!ha)
|
||||||
|
@ -3806,6 +3897,7 @@ static RegisterPrimOp primop_hashString({
|
||||||
|
|
||||||
static void prim_convertHash(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_convertHash(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.convertHash");
|
||||||
state.forceAttrs(*args[0], pos, "while evaluating the first argument passed to builtins.convertHash");
|
state.forceAttrs(*args[0], pos, "while evaluating the first argument passed to builtins.convertHash");
|
||||||
auto &inputAttrs = args[0]->attrs;
|
auto &inputAttrs = args[0]->attrs;
|
||||||
|
|
||||||
|
@ -3923,6 +4015,7 @@ std::shared_ptr<RegexCache> makeRegexCache()
|
||||||
|
|
||||||
void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.match");
|
||||||
auto re = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.match");
|
auto re = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.match");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -4003,6 +4096,7 @@ static RegisterPrimOp primop_match({
|
||||||
non-matching parts interleaved by the lists of the matching groups. */
|
non-matching parts interleaved by the lists of the matching groups. */
|
||||||
void prim_split(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
void prim_split(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.split");
|
||||||
auto re = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.split");
|
auto re = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.split");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -4106,6 +4200,7 @@ static RegisterPrimOp primop_split({
|
||||||
|
|
||||||
static void prim_concatStringsSep(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_concatStringsSep(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.concatStringsSep");
|
||||||
NixStringContext context;
|
NixStringContext context;
|
||||||
|
|
||||||
auto sep = state.forceString(*args[0], context, pos, "while evaluating the first argument (the separator string) passed to builtins.concatStringsSep");
|
auto sep = state.forceString(*args[0], context, pos, "while evaluating the first argument (the separator string) passed to builtins.concatStringsSep");
|
||||||
|
@ -4136,6 +4231,7 @@ static RegisterPrimOp primop_concatStringsSep({
|
||||||
|
|
||||||
static void prim_replaceStrings(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_replaceStrings(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.replaceStrings");
|
||||||
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.replaceStrings");
|
state.forceList(*args[0], pos, "while evaluating the first argument passed to builtins.replaceStrings");
|
||||||
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.replaceStrings");
|
state.forceList(*args[1], pos, "while evaluating the second argument passed to builtins.replaceStrings");
|
||||||
if (args[0]->listSize() != args[1]->listSize())
|
if (args[0]->listSize() != args[1]->listSize())
|
||||||
|
@ -4218,6 +4314,7 @@ static RegisterPrimOp primop_replaceStrings({
|
||||||
|
|
||||||
static void prim_parseDrvName(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_parseDrvName(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.parseDrvName");
|
||||||
auto name = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.parseDrvName");
|
auto name = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.parseDrvName");
|
||||||
DrvName parsed(name);
|
DrvName parsed(name);
|
||||||
auto attrs = state.buildBindings(2);
|
auto attrs = state.buildBindings(2);
|
||||||
|
@ -4242,6 +4339,7 @@ static RegisterPrimOp primop_parseDrvName({
|
||||||
|
|
||||||
static void prim_compareVersions(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_compareVersions(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.compareVersions");
|
||||||
auto version1 = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.compareVersions");
|
auto version1 = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.compareVersions");
|
||||||
auto version2 = state.forceStringNoCtx(*args[1], pos, "while evaluating the second argument passed to builtins.compareVersions");
|
auto version2 = state.forceStringNoCtx(*args[1], pos, "while evaluating the second argument passed to builtins.compareVersions");
|
||||||
v.mkInt(compareVersions(version1, version2));
|
v.mkInt(compareVersions(version1, version2));
|
||||||
|
@ -4262,6 +4360,7 @@ static RegisterPrimOp primop_compareVersions({
|
||||||
|
|
||||||
static void prim_splitVersion(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
static void prim_splitVersion(EvalState & state, const PosIdx pos, Value * * args, Value & v)
|
||||||
{
|
{
|
||||||
|
TRACY_TRACE_PRIMOP(state, pos, "primop.splitVersion");
|
||||||
auto version = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.splitVersion");
|
auto version = state.forceStringNoCtx(*args[0], pos, "while evaluating the first argument passed to builtins.splitVersion");
|
||||||
auto iter = version.cbegin();
|
auto iter = version.cbegin();
|
||||||
Strings components;
|
Strings components;
|
||||||
|
|
Loading…
Reference in a new issue