fix(3p/nix): inherit Expr from gc, make parser state traceable
The parser contained vectors, and the primary parser state, that were not participating in GC tracing. Change-Id: Ie198592cd7acffd390e3e2ae9595138b56416838 Reviewed-on: https://cl.tvl.fyi/c/depot/+/1706 Tested-by: BuildkiteCI Reviewed-by: tazjin <mail@tazj.in> Reviewed-by: glittershark <grfn@gws.fyi>
This commit is contained in:
parent
42bdaacca6
commit
906f5c1d2d
4 changed files with 56 additions and 40 deletions
34
third_party/nix/src/libexpr/nixexpr.hh
vendored
34
third_party/nix/src/libexpr/nixexpr.hh
vendored
|
@ -74,13 +74,18 @@ struct StaticEnv;
|
||||||
/* An attribute path is a sequence of attribute names. */
|
/* An attribute path is a sequence of attribute names. */
|
||||||
using AttrName = std::variant<Symbol, Expr*>;
|
using AttrName = std::variant<Symbol, Expr*>;
|
||||||
|
|
||||||
typedef std::vector<AttrName> AttrPath;
|
typedef std::vector<AttrName, traceable_allocator<AttrName>> AttrPath;
|
||||||
|
|
||||||
|
using AttrNameVector =
|
||||||
|
std::vector<nix::AttrName, traceable_allocator<nix::AttrName>>;
|
||||||
|
|
||||||
|
using VectorExprs = std::vector<nix::Expr*, traceable_allocator<nix::Expr*>>;
|
||||||
|
|
||||||
std::string showAttrPath(const AttrPath& attrPath);
|
std::string showAttrPath(const AttrPath& attrPath);
|
||||||
|
|
||||||
/* Abstract syntax of Nix expressions. */
|
/* Abstract syntax of Nix expressions. */
|
||||||
|
|
||||||
struct Expr {
|
struct Expr : public gc {
|
||||||
virtual ~Expr(){};
|
virtual ~Expr(){};
|
||||||
virtual void show(std::ostream& str) const;
|
virtual void show(std::ostream& str) const;
|
||||||
virtual void bindVars(const StaticEnv& env);
|
virtual void bindVars(const StaticEnv& env);
|
||||||
|
@ -186,7 +191,7 @@ struct ExprOpHasAttr : Expr {
|
||||||
struct ExprAttrs : Expr {
|
struct ExprAttrs : Expr {
|
||||||
bool recursive;
|
bool recursive;
|
||||||
|
|
||||||
struct AttrDef {
|
struct AttrDef : public gc {
|
||||||
bool inherited;
|
bool inherited;
|
||||||
Expr* e;
|
Expr* e;
|
||||||
Pos pos;
|
Pos pos;
|
||||||
|
@ -196,17 +201,22 @@ struct ExprAttrs : Expr {
|
||||||
AttrDef(){};
|
AttrDef(){};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef absl::flat_hash_map<Symbol, AttrDef> AttrDefs;
|
typedef absl::flat_hash_map<
|
||||||
|
Symbol, AttrDef, absl::container_internal::hash_default_hash<Symbol>,
|
||||||
|
absl::container_internal::hash_default_eq<Symbol>,
|
||||||
|
traceable_allocator<std::pair<const Symbol, AttrDef>>>
|
||||||
|
AttrDefs;
|
||||||
AttrDefs attrs;
|
AttrDefs attrs;
|
||||||
|
|
||||||
struct DynamicAttrDef {
|
struct DynamicAttrDef : public gc {
|
||||||
Expr *nameExpr, *valueExpr;
|
Expr *nameExpr, *valueExpr;
|
||||||
Pos pos;
|
Pos pos;
|
||||||
DynamicAttrDef(Expr* nameExpr, Expr* valueExpr, const Pos& pos)
|
DynamicAttrDef(Expr* nameExpr, Expr* valueExpr, const Pos& pos)
|
||||||
: nameExpr(nameExpr), valueExpr(valueExpr), pos(pos){};
|
: nameExpr(nameExpr), valueExpr(valueExpr), pos(pos){};
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::vector<DynamicAttrDef> DynamicAttrDefs;
|
typedef std::vector<DynamicAttrDef, traceable_allocator<DynamicAttrDef>>
|
||||||
|
DynamicAttrDefs;
|
||||||
DynamicAttrDefs dynamicAttrs;
|
DynamicAttrDefs dynamicAttrs;
|
||||||
|
|
||||||
ExprAttrs() : recursive(false){};
|
ExprAttrs() : recursive(false){};
|
||||||
|
@ -214,20 +224,20 @@ struct ExprAttrs : Expr {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ExprList : Expr {
|
struct ExprList : Expr {
|
||||||
std::vector<Expr*> elems;
|
VectorExprs elems;
|
||||||
ExprList(){};
|
ExprList(){};
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Formal {
|
struct Formal : public gc {
|
||||||
Symbol name;
|
Symbol name;
|
||||||
Expr* def; // def = default, not definition
|
Expr* def; // def = default, not definition
|
||||||
Formal(const Symbol& name, Expr* def) : name(name), def(def){};
|
Formal(const Symbol& name, Expr* def) : name(name), def(def){};
|
||||||
};
|
};
|
||||||
|
|
||||||
// Describes structured function arguments (e.g. `{ a }: ...`)
|
// Describes structured function arguments (e.g. `{ a }: ...`)
|
||||||
struct Formals {
|
struct Formals : public gc {
|
||||||
typedef std::list<Formal> Formals_;
|
typedef std::list<Formal, traceable_allocator<Formal>> Formals_;
|
||||||
Formals_ formals;
|
Formals_ formals;
|
||||||
std::set<Symbol> argNames; // used during parsing
|
std::set<Symbol> argNames; // used during parsing
|
||||||
bool ellipsis;
|
bool ellipsis;
|
||||||
|
@ -325,8 +335,8 @@ MakeBinOp(ExprOpConcatLists, "++");
|
||||||
struct ExprConcatStrings : Expr {
|
struct ExprConcatStrings : Expr {
|
||||||
Pos pos;
|
Pos pos;
|
||||||
bool forceString;
|
bool forceString;
|
||||||
std::vector<Expr*>* es;
|
nix::VectorExprs* es;
|
||||||
ExprConcatStrings(const Pos& pos, bool forceString, std::vector<Expr*>* es)
|
ExprConcatStrings(const Pos& pos, bool forceString, nix::VectorExprs* es)
|
||||||
: pos(pos), forceString(forceString), es(es){};
|
: pos(pos), forceString(forceString), es(es){};
|
||||||
COMMON_METHODS
|
COMMON_METHODS
|
||||||
};
|
};
|
||||||
|
|
7
third_party/nix/src/libexpr/parser.cc
vendored
7
third_party/nix/src/libexpr/parser.cc
vendored
|
@ -92,8 +92,7 @@ void addFormal(const Pos& pos, Formals* formals, const Formal& formal) {
|
||||||
formals->argNames.insert(formal.name);
|
formals->argNames.insert(formal.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expr* stripIndentation(const Pos& pos, SymbolTable& symbols,
|
Expr* stripIndentation(const Pos& pos, SymbolTable& symbols, VectorExprs& es) {
|
||||||
std::vector<Expr*>& es) {
|
|
||||||
if (es.empty()) {
|
if (es.empty()) {
|
||||||
return new ExprString(symbols.Create(""));
|
return new ExprString(symbols.Create(""));
|
||||||
}
|
}
|
||||||
|
@ -138,11 +137,11 @@ Expr* stripIndentation(const Pos& pos, SymbolTable& symbols,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Strip spaces from each line. */
|
/* Strip spaces from each line. */
|
||||||
std::vector<Expr*>* es2 = new std::vector<Expr*>;
|
VectorExprs* es2 = new VectorExprs;
|
||||||
atStartOfLine = true;
|
atStartOfLine = true;
|
||||||
size_t curDropped = 0;
|
size_t curDropped = 0;
|
||||||
size_t n = es.size();
|
size_t n = es.size();
|
||||||
for (std::vector<Expr*>::iterator i = es.begin(); i != es.end(); ++i, --n) {
|
for (VectorExprs::iterator i = es.begin(); i != es.end(); ++i, --n) {
|
||||||
ExprIndStr* e = dynamic_cast<ExprIndStr*>(*i);
|
ExprIndStr* e = dynamic_cast<ExprIndStr*>(*i);
|
||||||
if (!e) {
|
if (!e) {
|
||||||
atStartOfLine = false;
|
atStartOfLine = false;
|
||||||
|
|
4
third_party/nix/src/libexpr/parser.hh
vendored
4
third_party/nix/src/libexpr/parser.hh
vendored
|
@ -5,6 +5,7 @@
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
#include <gc/gc.h>
|
||||||
#include <glog/logging.h>
|
#include <glog/logging.h>
|
||||||
|
|
||||||
#include "libexpr/eval.hh"
|
#include "libexpr/eval.hh"
|
||||||
|
@ -59,8 +60,7 @@ void addAttr(ExprAttrs* attrs, AttrPath& attrPath, Expr* e, const Pos& pos);
|
||||||
|
|
||||||
void addFormal(const Pos& pos, Formals* formals, const Formal& formal);
|
void addFormal(const Pos& pos, Formals* formals, const Formal& formal);
|
||||||
|
|
||||||
Expr* stripIndentation(const Pos& pos, SymbolTable& symbols,
|
Expr* stripIndentation(const Pos& pos, SymbolTable& symbols, VectorExprs& es);
|
||||||
std::vector<Expr*>& es);
|
|
||||||
|
|
||||||
Path resolveExprPath(Path path);
|
Path resolveExprPath(Path path);
|
||||||
|
|
||||||
|
|
51
third_party/nix/src/libexpr/parser.y
vendored
51
third_party/nix/src/libexpr/parser.y
vendored
|
@ -14,6 +14,29 @@
|
||||||
%code requires {
|
%code requires {
|
||||||
#define YY_NO_INPUT 1 // disable unused yyinput features
|
#define YY_NO_INPUT 1 // disable unused yyinput features
|
||||||
#include "libexpr/parser.hh"
|
#include "libexpr/parser.hh"
|
||||||
|
|
||||||
|
// Allow GC tracing of YY-allocated structures
|
||||||
|
#define YYMALLOC GC_MALLOC_UNCOLLECTABLE
|
||||||
|
#define YYFREE GC_FREE
|
||||||
|
#define YYREALLOC GC_REALLOC
|
||||||
|
|
||||||
|
struct YYSTYPE : public gc {
|
||||||
|
union {
|
||||||
|
nix::Expr * e;
|
||||||
|
nix::ExprList * list;
|
||||||
|
nix::ExprAttrs * attrs;
|
||||||
|
nix::Formals * formals;
|
||||||
|
nix::Formal * formal;
|
||||||
|
nix::NixInt n;
|
||||||
|
nix::NixFloat nf;
|
||||||
|
const char * id; // !!! -> Symbol
|
||||||
|
char * path;
|
||||||
|
char * uri;
|
||||||
|
nix::AttrNameVector * attrNames;
|
||||||
|
nix::VectorExprs * string_parts;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
%{
|
%{
|
||||||
|
@ -40,22 +63,6 @@ void yyerror(YYLTYPE* loc, yyscan_t scanner, ParseData* data,
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union {
|
|
||||||
// !!! We're probably leaking stuff here.
|
|
||||||
nix::Expr * e;
|
|
||||||
nix::ExprList * list;
|
|
||||||
nix::ExprAttrs * attrs;
|
|
||||||
nix::Formals * formals;
|
|
||||||
nix::Formal * formal;
|
|
||||||
nix::NixInt n;
|
|
||||||
nix::NixFloat nf;
|
|
||||||
const char * id; // !!! -> Symbol
|
|
||||||
char * path;
|
|
||||||
char * uri;
|
|
||||||
std::vector<nix::AttrName> * attrNames;
|
|
||||||
std::vector<nix::Expr *> * string_parts;
|
|
||||||
}
|
|
||||||
|
|
||||||
%type <e> start expr expr_function expr_if expr_op
|
%type <e> start expr expr_function expr_if expr_op
|
||||||
%type <e> expr_app expr_select expr_simple
|
%type <e> expr_app expr_select expr_simple
|
||||||
%type <list> expr_list
|
%type <list> expr_list
|
||||||
|
@ -138,7 +145,7 @@ expr_op
|
||||||
| expr_op UPDATE expr_op { $$ = new ExprOpUpdate(CUR_POS, $1, $3); }
|
| expr_op UPDATE expr_op { $$ = new ExprOpUpdate(CUR_POS, $1, $3); }
|
||||||
| expr_op '?' attrpath { $$ = new ExprOpHasAttr($1, *$3); }
|
| expr_op '?' attrpath { $$ = new ExprOpHasAttr($1, *$3); }
|
||||||
| expr_op '+' expr_op
|
| expr_op '+' expr_op
|
||||||
{ $$ = new ExprConcatStrings(CUR_POS, false, new std::vector<Expr *>({$1, $3})); }
|
{ $$ = new ExprConcatStrings(CUR_POS, false, new nix::VectorExprs({$1, $3})); }
|
||||||
| expr_op '-' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprVar(data->symbols.Create("__sub")), $1), $3); }
|
| expr_op '-' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprVar(data->symbols.Create("__sub")), $1), $3); }
|
||||||
| expr_op '*' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprVar(data->symbols.Create("__mul")), $1), $3); }
|
| expr_op '*' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprVar(data->symbols.Create("__mul")), $1), $3); }
|
||||||
| expr_op '/' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprVar(data->symbols.Create("__div")), $1), $3); }
|
| expr_op '/' expr_op { $$ = new ExprApp(CUR_POS, new ExprApp(new ExprVar(data->symbols.Create("__div")), $1), $3); }
|
||||||
|
@ -208,9 +215,9 @@ string_parts
|
||||||
string_parts_interpolated
|
string_parts_interpolated
|
||||||
: string_parts_interpolated STR { $$ = $1; $1->push_back($2); }
|
: string_parts_interpolated STR { $$ = $1; $1->push_back($2); }
|
||||||
| string_parts_interpolated DOLLAR_CURLY expr '}' { $$ = $1; $1->push_back($3); }
|
| string_parts_interpolated DOLLAR_CURLY expr '}' { $$ = $1; $1->push_back($3); }
|
||||||
| DOLLAR_CURLY expr '}' { $$ = new std::vector<Expr *>; $$->push_back($2); }
|
| DOLLAR_CURLY expr '}' { $$ = new nix::VectorExprs; $$->push_back($2); }
|
||||||
| STR DOLLAR_CURLY expr '}' {
|
| STR DOLLAR_CURLY expr '}' {
|
||||||
$$ = new std::vector<Expr *>;
|
$$ = new nix::VectorExprs;
|
||||||
$$->push_back($1);
|
$$->push_back($1);
|
||||||
$$->push_back($3);
|
$$->push_back($3);
|
||||||
}
|
}
|
||||||
|
@ -219,7 +226,7 @@ string_parts_interpolated
|
||||||
ind_string_parts
|
ind_string_parts
|
||||||
: ind_string_parts IND_STR { $$ = $1; $1->push_back($2); }
|
: ind_string_parts IND_STR { $$ = $1; $1->push_back($2); }
|
||||||
| ind_string_parts DOLLAR_CURLY expr '}' { $$ = $1; $1->push_back($3); }
|
| ind_string_parts DOLLAR_CURLY expr '}' { $$ = $1; $1->push_back($3); }
|
||||||
| { $$ = new std::vector<Expr *>; }
|
| { $$ = new nix::VectorExprs; }
|
||||||
;
|
;
|
||||||
|
|
||||||
binds
|
binds
|
||||||
|
@ -276,9 +283,9 @@ attrpath
|
||||||
$$->push_back(AttrName($3));
|
$$->push_back(AttrName($3));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| attr { $$ = new std::vector<AttrName>; $$->push_back(AttrName(data->symbols.Create($1))); }
|
| attr { $$ = new nix::AttrNameVector; $$->push_back(AttrName(data->symbols.Create($1))); }
|
||||||
| string_attr
|
| string_attr
|
||||||
{ $$ = new std::vector<AttrName>;
|
{ $$ = new nix::AttrNameVector;
|
||||||
ExprString *str = dynamic_cast<ExprString *>($1);
|
ExprString *str = dynamic_cast<ExprString *>($1);
|
||||||
if (str) {
|
if (str) {
|
||||||
$$->push_back(AttrName(str->s));
|
$$->push_back(AttrName(str->s));
|
||||||
|
|
Loading…
Reference in a new issue