turn primop names into strings

we don't *need* symbols here. the only advantage they have over strings is
making call-counting slightly faster, but that's a diagnostic feature and thus
needn't be optimized.

this also fixes a move bug that previously didn't show up: PrimOp structs were
accessed after being moved from, which technically invalidates them. previously
the names remained valid because Symbol copies on move, but strings are
invalidated. we now copy the entire primop struct instead of moving since primop
registration happen once and are not performance-sensitive.
This commit is contained in:
pennae 2022-03-05 19:26:36 +01:00
parent 3b9d31b88c
commit 90b5c0a1a6
3 changed files with 11 additions and 11 deletions

View file

@ -645,14 +645,14 @@ Value * EvalState::addPrimOp(const std::string & name,
the primop to a dummy value. */
if (arity == 0) {
auto vPrimOp = allocValue();
vPrimOp->mkPrimOp(new PrimOp { .fun = primOp, .arity = 1, .name = sym });
vPrimOp->mkPrimOp(new PrimOp { .fun = primOp, .arity = 1, .name = name2 });
Value v;
v.mkApp(vPrimOp, vPrimOp);
return addConstant(name, v);
}
Value * v = allocValue();
v->mkPrimOp(new PrimOp { .fun = primOp, .arity = arity, .name = sym });
v->mkPrimOp(new PrimOp { .fun = primOp, .arity = arity, .name = name2 });
staticBaseEnv.vars.emplace_back(symbols.create(name), baseEnvDispl);
baseEnv.values[baseEnvDispl++] = v;
baseEnv.values[0]->attrs->push_back(Attr(sym, v));
@ -667,21 +667,21 @@ Value * EvalState::addPrimOp(PrimOp && primOp)
if (primOp.arity == 0) {
primOp.arity = 1;
auto vPrimOp = allocValue();
vPrimOp->mkPrimOp(new PrimOp(std::move(primOp)));
vPrimOp->mkPrimOp(new PrimOp(primOp));
Value v;
v.mkApp(vPrimOp, vPrimOp);
return addConstant(primOp.name, v);
}
Symbol envName = primOp.name;
Symbol envName = symbols.create(primOp.name);
if (hasPrefix(primOp.name, "__"))
primOp.name = symbols.create(std::string(primOp.name, 2));
primOp.name = primOp.name.substr(2);
Value * v = allocValue();
v->mkPrimOp(new PrimOp(std::move(primOp)));
v->mkPrimOp(new PrimOp(primOp));
staticBaseEnv.vars.emplace_back(envName, baseEnvDispl);
baseEnv.values[baseEnvDispl++] = v;
baseEnv.values[0]->attrs->push_back(Attr(primOp.name, v));
baseEnv.values[0]->attrs->push_back(Attr(symbols.create(primOp.name), v));
return v;
}

View file

@ -30,7 +30,7 @@ struct PrimOp
{
PrimOpFun fun;
size_t arity;
Symbol name;
std::string name;
std::vector<std::string> args;
const char * doc = nullptr;
};
@ -305,7 +305,7 @@ public:
struct Doc
{
Pos pos;
std::optional<Symbol> name;
std::optional<std::string> name;
size_t arity;
std::vector<std::string> args;
const char * doc;
@ -391,7 +391,7 @@ private:
bool countCalls;
typedef std::map<Symbol, size_t> PrimOpCalls;
typedef std::map<std::string, size_t> PrimOpCalls;
PrimOpCalls primOpCalls;
typedef std::map<ExprLambda *, size_t> FunctionCalls;

View file

@ -3906,7 +3906,7 @@ void EvalState::createBaseEnv()
addPrimOp({
.fun = primOp.fun,
.arity = std::max(primOp.args.size(), primOp.arity),
.name = symbols.create(primOp.name),
.name = primOp.name,
.args = primOp.args,
.doc = primOp.doc,
});