Skip to content

Commit 3b7edbc

Browse files
committed
[Heavy] Simplify environments in Clang
1 parent 1575310 commit 3b7edbc

File tree

10 files changed

+16
-75
lines changed

10 files changed

+16
-75
lines changed

clang/lib/Parse/ParseDeclHeavy.cpp

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,6 @@ clang::SourceLocation getSourceLocation(heavy::FullSourceLocation Loc) {
4545
.getLocWithOffset(Loc.getOffset());
4646
}
4747

48-
heavy::Environment* LoadEnv(heavy::HeavyScheme& HS, void* Handle) {
49-
DeclContext* DC = reinterpret_cast<DeclContext*>(Handle);
50-
// Here, nullptr represents the default, root environment.
51-
void* ParentHandle = !DC->isTranslationUnit() ? DC->getParent()
52-
: nullptr;
53-
54-
return HS.LoadEmbeddedEnv(ParentHandle, LoadEnv);
55-
}
56-
5748
// It is complicated to keep the TokenBuffer alive
5849
// for the Preprocessor, so we use an array to give
5950
// ownership via the EnterTokenStream overload.
@@ -365,13 +356,9 @@ bool Parser::ParseHeavyScheme() {
365356
C.Cont();
366357
}));
367358

368-
// Get the nested environment for the current DeclContext.
369-
DeclContext* DC = getActions().CurContext;
370-
heavy::Environment* Env = HeavyScheme->LoadEmbeddedEnv(DC, LoadEnv);
371-
372359
heavy::TokenKind Terminator = heavy::tok::r_brace;
373360
HeavyScheme->ProcessTopLevelCommands(SchemeLexer, heavy::base::eval,
374-
ErrorHandler, Env, Terminator);
361+
ErrorHandler, Terminator);
375362

376363
// Return control to C++ Lexer
377364
PP.FinishEmbeddedLexer(SchemeLexer.GetByteOffset());

heavy/include/heavy/Context.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,11 @@ class Context : public ContinuationStack<Context>,
8989
static constexpr size_t MiB = 1024 * 1024;
9090

9191
llvm::StringMap<std::unique_ptr<Module>> Modules;
92-
llvm::DenseMap<void*, std::unique_ptr<Environment>> EmbeddedEnvs;
9392
llvm::DenseMap<String*, Value> KnownAddresses;
9493

94+
// DefaultEnv participates in garbage collection.
95+
std::unique_ptr<heavy::Environment> DefaultEnv;
96+
9597
// MaxMemHint
9698
// - The threshold used to determine if a garbage
9799
// collection run is needed. This value is not a

heavy/include/heavy/HeavyScheme.h

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ class HeavyScheme {
4242
friend class SourceFileStorage;
4343

4444
std::unique_ptr<heavy::Context> ContextPtr;
45-
std::unique_ptr<heavy::Environment> EnvPtr;
4645
std::unique_ptr<heavy::SourceManager> SourceManagerPtr;
4746
std::unique_ptr<heavy::SourceFileStorage,
4847
void(*)(SourceFileStorage*)> SourceFileStoragePtr;
@@ -88,18 +87,6 @@ class HeavyScheme {
8887
void InitSourceFileStorage();
8988
void SetModulePath(llvm::StringRef ModulePath);
9089

91-
// LoadEmbeddedEnv
92-
// - Associates an opaque pointer with a scheme environment
93-
// and loads it as the current environment in the Context.
94-
// Any environment previously loaded with this function is
95-
// cached. If a new environment must be created,
96-
// LoadParent is called, and then the new environment is
97-
// created to shadow whatever environment is loaded in
98-
// Context at that point.
99-
using LoadEnvFnTy = heavy::Environment*(HeavyScheme&, void*);
100-
heavy::Environment* LoadEmbeddedEnv(void* Handle,
101-
llvm::function_ref<LoadEnvFnTy> LoadParent);
102-
10390
using ErrorHandlerFn = void(llvm::StringRef,
10491
heavy::FullSourceLocation const&);
10592

@@ -114,7 +101,6 @@ class HeavyScheme {
114101
void ProcessTopLevelCommands(heavy::Lexer& Lexer,
115102
llvm::function_ref<ValueFnTy> ExprHandler,
116103
llvm::function_ref<ErrorHandlerFn> ErrorHandler,
117-
heavy::Environment* Env = nullptr,
118104
heavy::tok Terminator = heavy::tok::eof);
119105
// ProcessTopLevelCommands
120106
// - Filename overload requires calling InitSourceFileStorage.

heavy/include/heavy/Value.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1655,18 +1655,16 @@ class Environment : public ValueBase {
16551655
using MapTy = llvm::DenseMap<String*, String*>;
16561656

16571657
std::unique_ptr<heavy::OpGen> OpGen;
1658-
Environment* Parent = nullptr;
16591658
MapTy EnvMap;
16601659

16611660
public:
16621661
// Implemented in Context.cpp
1663-
Environment(Environment* Parent);
16641662
Environment(heavy::Context& C, heavy::Symbol* ModulePrefix = {});
16651663
~Environment();
16661664

1667-
heavy::OpGen* GetOpGen() {
1668-
if (OpGen) return OpGen.get();
1669-
return Parent->GetOpGen();
1665+
heavy::OpGen* getOpGen() {
1666+
assert(OpGen && "environment should have OpGen");
1667+
return OpGen.get();
16701668
}
16711669

16721670
// Returns nullptr if not found

heavy/lib/Builtins.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -686,7 +686,7 @@ void compile(Context& C, ValueRefs Args) {
686686
}
687687

688688
// Clear any errors in the compiler too keep the dream alive.
689-
if (heavy::OpGen* OpGen = Env->GetOpGen())
689+
if (heavy::OpGen* OpGen = Env->getOpGen())
690690
OpGen->ClearError();
691691

692692
// If there is a provided handler then we save the results in an

heavy/lib/Context.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,16 +92,9 @@ bool Context::CheckError() {
9292
return OpGen && OpGen->CheckError();
9393
}
9494

95-
Environment::Environment(Environment* Parent)
96-
: ValueBase(ValueKind::Environment),
97-
OpGen(nullptr),
98-
Parent(Parent),
99-
EnvMap(0)
100-
{ }
10195
Environment::Environment(Context& C, heavy::Symbol* ModulePrefix)
10296
: ValueBase(ValueKind::Environment),
10397
OpGen(std::make_unique<heavy::OpGen>(C, ModulePrefix)),
104-
Parent(nullptr),
10598
EnvMap(0)
10699
{ }
107100
Environment::~Environment() = default;
@@ -1319,7 +1312,7 @@ class LibraryEnv {
13191312
heavy::Environment* Env,
13201313
Value Thunk) {
13211314
auto Ptr = std::make_unique<LibraryEnv>(std::move(EnvPtr), Env);
1322-
heavy::OpGen* OpGen = Ptr->Env->GetOpGen();
1315+
heavy::OpGen* OpGen = Ptr->Env->getOpGen();
13231316

13241317
Value PrevEnv = Context.getEnvironment();
13251318
heavy::OpGen* PrevOpGen = Context.OpGen;

heavy/lib/Heap.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -307,8 +307,6 @@ class CopyCollector : private ValueVisitor<CopyCollector, heavy::Value> {
307307
}
308308

309309
VisitedSpecials.push_back(Env);
310-
if (Env->Parent)
311-
VisitEnvironment(Env->Parent);
312310
return Env;
313311
}
314312
};
@@ -327,11 +325,8 @@ void Context::CollectGarbage() {
327325

328326
GC.VisitRootNode(EnvStack);
329327

330-
// EmbeddedEnvs
331-
for (auto& DensePair : EmbeddedEnvs) {
332-
heavy::Environment* Env = DensePair.second.get();
333-
GC.VisitEnvironment(Env);
334-
}
328+
// DefaultEnv is referenced globally.
329+
GC.VisitEnvironment(DefaultEnv.get());
335330

336331
// KnownAddresses
337332
for (auto& DensePair : KnownAddresses) {

heavy/lib/HeavyScheme.cpp

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,7 @@ HeavyScheme::HeavyScheme(std::unique_ptr<heavy::Context> C)
3030
SourceFileStoragePtr(nullptr, [](SourceFileStorage*) { })
3131
{
3232
// Create and store the default environment.
33-
ContextPtr->EmbeddedEnvs[nullptr] =
34-
std::make_unique<heavy::Environment>(*ContextPtr);
33+
ContextPtr->DefaultEnv = std::make_unique<heavy::Environment>(*ContextPtr);
3534
}
3635

3736
HeavyScheme::HeavyScheme()
@@ -54,32 +53,16 @@ heavy::Lexer HeavyScheme::createEmbeddedLexer(uintptr_t ExternalRawLoc,
5453
return Lexer(File, BufferPos);
5554
}
5655

57-
heavy::Environment* HeavyScheme::LoadEmbeddedEnv(void* Handle,
58-
llvm::function_ref<heavy::Environment*(HeavyScheme&, void*)> LoadParent) {
59-
auto& EmbeddedEnvs = getContext().EmbeddedEnvs;
60-
auto itr = EmbeddedEnvs.find(Handle);
61-
if (itr != EmbeddedEnvs.end())
62-
return itr->second.get();
63-
64-
assert(Handle != nullptr && "HeavyScheme should have root environment");
65-
Environment* Parent = LoadParent(*this, Handle);
66-
auto& EnvPtr = EmbeddedEnvs[Handle] =
67-
std::make_unique<Environment>(Parent);
68-
return EnvPtr.get();
69-
}
70-
7156
void HeavyScheme::ProcessTopLevelCommands(
7257
heavy::Lexer& Lexer,
7358
llvm::function_ref<ValueFnTy> ExprHandler,
7459
llvm::function_ref<ErrorHandlerFn> ErrorHandler,
75-
heavy::Environment* Env,
7660
heavy::tok Terminator) {
7761
auto& Context = getContext();
7862
auto& SM = getSourceManager();
7963
auto ParserPtr = std::make_unique<Parser>(Lexer, Context);
8064
Parser& Parser = *ParserPtr;
81-
if (Env == nullptr)
82-
Env = Context.EmbeddedEnvs[nullptr].get();
65+
heavy::Environment* Env = Context.DefaultEnv.get();
8366

8467
auto HandleErrorFn = [&](heavy::Context& Context, ValueRefs Args) {
8568
heavy::FullSourceLocation FullLoc = SM.getFullSourceLocation(

heavy/lib/SourceFileStorage.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,7 @@ void HeavyScheme::ProcessTopLevelCommands(llvm::StringRef Filename,
5757
return;
5858
}
5959
heavy::Lexer Lexer(FileResult.get());
60-
ProcessTopLevelCommands(Lexer, ExprHandler, ErrorHandler,
61-
/*Environment=*/nullptr, tok::eof);
60+
ProcessTopLevelCommands(Lexer, ExprHandler, ErrorHandler, tok::eof);
6261
}
6362

6463
// This overload provides the default file system

heavy/test/Clang/import.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
#include <type_traits>
44

55
namespace foo {
6-
// expected-error@+6{{expected unqualified-id}}
6+
// expected-error@+7{{expected unqualified-id}}
77
heavy_scheme {
8+
;// The scheme environment is orthogonal to namespaces.
89
(import (my lib))
910
(import (heavy base))
1011

@@ -19,10 +20,7 @@ static_assert(std::is_empty_v<foo::woof>);
1920

2021
namespace bar {
2122
heavy_scheme {
22-
; // FIXME Should we have separate scopes in different namespaces?
23-
(import (heavy base))
2423
(write hello-foo)
25-
(import (my lib)) ; FIXME
2624
(if (is-empty 'foo::woof)
2725
(lol-trait 'bark)
2826
(raise-error "expecting empty woof"))

0 commit comments

Comments
 (0)