libexpr: move floats to auxiliary storage
floats are used very rarely, and our float support is bad enough to strongly discourage using them on reproducibility grounds alone. we can thus move them to more expensive storage without hurting folks. Change-Id: I1086f612f85e294dd3fae4a2d334e09f52bbe4a8
This commit is contained in:
@@ -107,6 +107,8 @@ std::string showType(const Value & v)
|
||||
switch (v.auxiliary()->type) {
|
||||
case Value::Acb::tExternal:
|
||||
return v.external()->showType();
|
||||
case Value::Acb::tFloat:
|
||||
return std::string(showType(v.type()));
|
||||
}
|
||||
#pragma GCC diagnostic pop
|
||||
case tThunk: return v.isBlackhole() ? "a black hole" : "a thunk";
|
||||
|
||||
+15
-2
@@ -177,14 +177,27 @@ protected:
|
||||
public:
|
||||
|
||||
ExprLiteral(const PosIdx pos, NewValueAs::integer_t, NixInt n) : Expr(pos) { v.mkInt(n); };
|
||||
ExprLiteral(const PosIdx pos, NewValueAs::integer_t, NixInt::Inner n) : Expr(pos) { v.mkInt(n); };
|
||||
ExprLiteral(const PosIdx pos, NewValueAs::floating_t, NixFloat nf) : Expr(pos) { v.mkFloat(nf); };
|
||||
ExprLiteral(const PosIdx pos, NewValueAs::integer_t, NixInt::Inner n) : Expr(pos)
|
||||
{
|
||||
v.mkInt(n);
|
||||
}
|
||||
Value * maybeThunk(EvalState & state, Env & env) override;
|
||||
JSON toJSON(const SymbolTable & symbols) const override;
|
||||
void eval(EvalState & state, Env & env, Value & v) override;
|
||||
void accept(ExprVisitor & ev, std::unique_ptr<Expr> & ptr) override { ev.visit(*this, ptr); }
|
||||
};
|
||||
|
||||
struct ExprFloat : ExprLiteral
|
||||
{
|
||||
Value::Float f;
|
||||
ExprFloat(const PosIdx pos, NewValueAs::floating_t, double f)
|
||||
: ExprLiteral(pos)
|
||||
, f{{Value::Acb::tFloat}, f}
|
||||
{
|
||||
v = Value(this->f);
|
||||
}
|
||||
};
|
||||
|
||||
struct ExprString : ExprLiteral
|
||||
{
|
||||
std::string s;
|
||||
|
||||
@@ -542,7 +542,7 @@ template<> struct BuildAST<grammar::v1::expr::float_> {
|
||||
});
|
||||
}
|
||||
}();
|
||||
s.emplaceExpr<ExprLiteral>(ps.at(in), NewValueAs::floating, v);
|
||||
s.emplaceExpr<ExprFloat>(ps.at(in), NewValueAs::floating, v);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+17
-15
@@ -34,7 +34,6 @@ typedef enum {
|
||||
tLambda,
|
||||
tPrimOp,
|
||||
tAuxiliary,
|
||||
tFloat
|
||||
} InternalType;
|
||||
|
||||
/**
|
||||
@@ -259,11 +258,13 @@ public:
|
||||
|
||||
/// Constructs a nix language value of type "float", with the floating
|
||||
/// point value of @ref f.
|
||||
Value(floating_t, NixFloat f)
|
||||
: internalType(tFloat)
|
||||
, _fpoint(f)
|
||||
, _float_pad(0)
|
||||
{ }
|
||||
Value(floating_t, NixFloat f) : internalType(tAuxiliary), _aux_pad(0)
|
||||
{
|
||||
auto fp = gcAllocType<Float>();
|
||||
fp->type = Acb::tFloat;
|
||||
fp->value = f;
|
||||
_auxiliary = fp;
|
||||
}
|
||||
|
||||
/// Constructs a nix language value of type "bool", with the boolean
|
||||
/// value of @ref b.
|
||||
@@ -638,12 +639,17 @@ public:
|
||||
{
|
||||
enum {
|
||||
tExternal,
|
||||
tFloat,
|
||||
} type;
|
||||
};
|
||||
struct External : Acb
|
||||
{
|
||||
ExternalValueBase * external;
|
||||
};
|
||||
struct Float : Acb
|
||||
{
|
||||
NixFloat value;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
@@ -688,10 +694,6 @@ public:
|
||||
const Acb * _auxiliary;
|
||||
uintptr_t _aux_pad;
|
||||
};
|
||||
struct {
|
||||
NixFloat _fpoint;
|
||||
uintptr_t _float_pad;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -719,8 +721,9 @@ public:
|
||||
switch (_auxiliary->type) {
|
||||
case Acb::tExternal:
|
||||
return nExternal;
|
||||
case Acb::tFloat:
|
||||
return nFloat;
|
||||
}
|
||||
case tFloat: return nFloat;
|
||||
case tThunk:
|
||||
return nThunk;
|
||||
case tApp:
|
||||
@@ -834,9 +837,7 @@ public:
|
||||
|
||||
inline void mkFloat(NixFloat n)
|
||||
{
|
||||
clearValue();
|
||||
internalType = tFloat;
|
||||
_fpoint = n;
|
||||
*this = {NewValueAs::floating, n};
|
||||
}
|
||||
|
||||
bool isList() const
|
||||
@@ -954,7 +955,8 @@ public:
|
||||
|
||||
NixFloat fpoint() const
|
||||
{
|
||||
return _fpoint;
|
||||
assert(internalType == tAuxiliary && _auxiliary->type == Acb::tFloat);
|
||||
return static_cast<const Float *>(_auxiliary)->value;
|
||||
}
|
||||
|
||||
const Acb * auxiliary() const
|
||||
|
||||
Reference in New Issue
Block a user