diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-08-07 14:54:55 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-08-07 15:16:54 -0700 |
| commit | 7b54f43fb1b123f451460edb0add218a0428fe95 (patch) | |
| tree | e492a82b13334955c1c56f6e3f9d25e8165de82c /source/slang/parser.cpp | |
| parent | ca8eea98c89c632dd7b5a6a8b84d379d1e9e59cf (diff) | |
Remove uses of global variables
There were two main places where global variables were used in the Slang implementation:
1. The "standard library" code was generated as a string at run-time, and stored in a global variable so that it could be amortized across compiles.
2. The representation of types uses some globals (well, class `static` members) to store common types (e.g., `void`) and to deal with memory lifetime for things like canonicalized types.
In each case the "simple" fix is to move the relevant state into the `Session` type that controlled their lifetime already (the `Session` destructor was already cleaning up these globals to avoid leaks).
For the standard library stuff this really was easy, but for the types it required threading through the `Session` a bit carefully.
One more case that I found: there was a function-`static` variable used to generate a unique ID for files output when dumping of intermediates is enabled (this is almost strictly a debugging option).
Rather than make this counter per-session (which would lead to different sessions on different threads clobbering the same few files), I went ahead and used an atomic in this case.
Note that the remaining case I had been worried about was any function-`static` counter that might be used in generating unique names.
It turns out that right now the parser doesn't use such a counter (even in cases where it probably should), and the lowering pass already uses a counter local to the pass (again, whether or not this is a good idea).
This change should be a major step toward allowing an application to use Slang in multiple threads, so long as each thread uses a distinct `SlangSession`. The case of using a single session across multiple threads is harder to support, and will require more careful implementation work.
Diffstat (limited to 'source/slang/parser.cpp')
| -rw-r--r-- | source/slang/parser.cpp | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp index 801628e30..c36b2f477 100644 --- a/source/slang/parser.cpp +++ b/source/slang/parser.cpp @@ -80,6 +80,12 @@ namespace Slang , fileName(_fileName) , outerScope(outerScope) {} + + Session* getSession() + { + return translationUnit->compileRequest->mSession; + } + RefPtr<ProgramSyntaxNode> Parse(); Token ReadToken(); @@ -820,6 +826,7 @@ namespace Slang if( parser->LookAheadToken(TokenType::Identifier) ) { LookupResult lookupResult = LookUp( + parser->getSession(), nullptr, // No semantics visitor available yet! parser->tokenReader.PeekToken().Content, parser->currentScope); @@ -2070,12 +2077,14 @@ namespace Slang auto paramConstraint = new GenericTypeConstraintDecl(); parser->FillPosition(paramConstraint); - auto paramType = DeclRefType::Create(DeclRef<Decl>(paramDecl, nullptr)); + auto paramType = DeclRefType::Create( + parser->getSession(), + DeclRef<Decl>(paramDecl, nullptr)); auto paramTypeExpr = new SharedTypeExpr(); paramTypeExpr->Position = paramDecl->Position; paramTypeExpr->base.type = paramType; - paramTypeExpr->Type = new TypeType(paramType); + paramTypeExpr->Type = QualType(getTypeType(paramType)); paramConstraint->sub = TypeExp(paramTypeExpr); paramConstraint->sup = parser->ParseTypeExp(); @@ -2518,6 +2527,7 @@ namespace Slang static bool isGenericName(Parser* parser, String const& name) { auto lookupResult = LookUp( + parser->getSession(), nullptr, // no semantics visitor available yet name, parser->currentScope); @@ -2539,6 +2549,7 @@ namespace Slang static bool isTypeName(Parser* parser, String const& name) { auto lookupResult = LookUp( + parser->getSession(), nullptr, // no semantics visitor available yet name, parser->currentScope); @@ -3389,24 +3400,24 @@ namespace Slang if(unknownCount) { parser->sink->diagnose(token, Diagnostics::invalidIntegerLiteralSuffix, suffix); - suffixType = ExpressionType::GetError(); + suffixType = parser->getSession()->getErrorType(); } // `u` or `ul` suffix -> `uint` else if(uCount == 1 && (lCount <= 1)) { - suffixType = ExpressionType::GetUInt(); + suffixType = parser->getSession()->getUIntType(); } // `l` suffix on integer -> `int` (== `long`) else if(lCount == 1 && !uCount) { - suffixType = ExpressionType::GetInt(); + suffixType = parser->getSession()->getIntType(); } // TODO: probably need `ll` and `ull` // TODO: are there other suffixes we need to handle? else { parser->sink->diagnose(token, Diagnostics::invalidIntegerLiteralSuffix, suffix); - suffixType = ExpressionType::GetError(); + suffixType = parser->getSession()->getErrorType(); } } @@ -3459,23 +3470,23 @@ namespace Slang if(unknownCount) { parser->sink->diagnose(token, Diagnostics::invalidFloatingPOintLiteralSuffix, suffix); - suffixType = ExpressionType::GetError(); + suffixType = parser->getSession()->getErrorType(); } // `f` suffix -> `float` if(fCount == 1 && !lCount) { - suffixType = ExpressionType::GetFloat(); + suffixType = parser->getSession()->getFloatType(); } // `l` or `lf` suffix on float -> `double` else if(lCount == 1 && (fCount <= 1)) { - suffixType = ExpressionType::getDoubleType(); + suffixType = parser->getSession()->getDoubleType(); } // TODO: are there other suffixes we need to handle? else { parser->sink->diagnose(token, Diagnostics::invalidFloatingPOintLiteralSuffix, suffix); - suffixType = ExpressionType::GetError(); + suffixType = parser->getSession()->getErrorType(); } } |
