LCOV - code coverage report
Current view: directory - gfx/angle/src/compiler - Compiler.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 134 0 0.0 %
Date: 2012-06-02 Functions: 20 0 0.0 %

       1                 : //
       2                 : // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
       3                 : // Use of this source code is governed by a BSD-style license that can be
       4                 : // found in the LICENSE file.
       5                 : //
       6                 : 
       7                 : #include "compiler/BuiltInFunctionEmulator.h"
       8                 : #include "compiler/DetectRecursion.h"
       9                 : #include "compiler/ForLoopUnroll.h"
      10                 : #include "compiler/Initialize.h"
      11                 : #include "compiler/MapLongVariableNames.h"
      12                 : #include "compiler/ParseHelper.h"
      13                 : #include "compiler/ShHandle.h"
      14                 : #include "compiler/ValidateLimitations.h"
      15                 : 
      16                 : namespace {
      17               0 : bool InitializeSymbolTable(
      18                 :     const TBuiltInStrings& builtInStrings,
      19                 :     ShShaderType type, ShShaderSpec spec, const ShBuiltInResources& resources,
      20                 :     TInfoSink& infoSink, TSymbolTable& symbolTable)
      21                 : {
      22               0 :     TIntermediate intermediate(infoSink);
      23               0 :     TExtensionBehavior extBehavior;
      24               0 :     InitExtensionBehavior(resources, extBehavior);
      25                 :     // The builtins deliberately don't specify precisions for the function
      26                 :     // arguments and return types. For that reason we don't try to check them.
      27               0 :     TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, false, NULL, infoSink);
      28                 : 
      29               0 :     GlobalParseContext = &parseContext;
      30                 : 
      31               0 :     assert(symbolTable.isEmpty());       
      32                 :     //
      33                 :     // Parse the built-ins.  This should only happen once per
      34                 :     // language symbol table.
      35                 :     //
      36                 :     // Push the symbol table to give it an initial scope.  This
      37                 :     // push should not have a corresponding pop, so that built-ins
      38                 :     // are preserved, and the test for an empty table fails.
      39                 :     //
      40               0 :     symbolTable.push();
      41                 : 
      42               0 :     for (TBuiltInStrings::const_iterator i = builtInStrings.begin(); i != builtInStrings.end(); ++i)
      43                 :     {
      44               0 :         const char* builtInShaders = i->c_str();
      45               0 :         int builtInLengths = static_cast<int>(i->size());
      46               0 :         if (builtInLengths <= 0)
      47               0 :           continue;
      48                 : 
      49               0 :         if (PaParseStrings(1, &builtInShaders, &builtInLengths, &parseContext) != 0)
      50                 :         {
      51               0 :             infoSink.info.message(EPrefixInternalError, "Unable to parse built-ins");
      52               0 :             return false;
      53                 :         }
      54                 :     }
      55                 : 
      56               0 :     IdentifyBuiltIns(type, spec, resources, symbolTable);
      57                 : 
      58               0 :     return true;
      59                 : }
      60                 : 
      61                 : class TScopedPoolAllocator {
      62                 : public:
      63               0 :     TScopedPoolAllocator(TPoolAllocator* allocator, bool pushPop)
      64               0 :         : mAllocator(allocator), mPushPopAllocator(pushPop) {
      65               0 :         if (mPushPopAllocator) mAllocator->push();
      66               0 :         SetGlobalPoolAllocator(mAllocator);
      67               0 :     }
      68               0 :     ~TScopedPoolAllocator() {
      69               0 :         SetGlobalPoolAllocator(NULL);
      70               0 :         if (mPushPopAllocator) mAllocator->pop();
      71               0 :     }
      72                 : 
      73                 : private:
      74                 :     TPoolAllocator* mAllocator;
      75                 :     bool mPushPopAllocator;
      76                 : };
      77                 : }  // namespace
      78                 : 
      79               0 : TShHandleBase::TShHandleBase() {
      80               0 :     allocator.push();
      81               0 :     SetGlobalPoolAllocator(&allocator);
      82               0 : }
      83                 : 
      84               0 : TShHandleBase::~TShHandleBase() {
      85               0 :     SetGlobalPoolAllocator(NULL);
      86               0 :     allocator.popAll();
      87               0 : }
      88                 : 
      89               0 : TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
      90                 :     : shaderType(type),
      91                 :       shaderSpec(spec),
      92               0 :       builtInFunctionEmulator(type)
      93                 : {
      94               0 :     longNameMap = LongNameMap::GetInstance();
      95               0 : }
      96                 : 
      97               0 : TCompiler::~TCompiler()
      98                 : {
      99               0 :     ASSERT(longNameMap);
     100               0 :     longNameMap->Release();
     101               0 : }
     102                 : 
     103               0 : bool TCompiler::Init(const ShBuiltInResources& resources)
     104                 : {
     105               0 :     TScopedPoolAllocator scopedAlloc(&allocator, false);
     106                 : 
     107                 :     // Generate built-in symbol table.
     108               0 :     if (!InitBuiltInSymbolTable(resources))
     109               0 :         return false;
     110               0 :     InitExtensionBehavior(resources, extensionBehavior);
     111                 : 
     112               0 :     return true;
     113                 : }
     114                 : 
     115               0 : bool TCompiler::compile(const char* const shaderStrings[],
     116                 :                         const int numStrings,
     117                 :                         int compileOptions)
     118                 : {
     119               0 :     TScopedPoolAllocator scopedAlloc(&allocator, true);
     120               0 :     clearResults();
     121                 : 
     122               0 :     if (numStrings == 0)
     123               0 :         return true;
     124                 : 
     125                 :     // If compiling for WebGL, validate loop and indexing as well.
     126               0 :     if (shaderSpec == SH_WEBGL_SPEC)
     127               0 :         compileOptions |= SH_VALIDATE_LOOP_INDEXING;
     128                 : 
     129                 :     // First string is path of source file if flag is set. The actual source follows.
     130               0 :     const char* sourcePath = NULL;
     131               0 :     int firstSource = 0;
     132               0 :     if (compileOptions & SH_SOURCE_PATH)
     133                 :     {
     134               0 :         sourcePath = shaderStrings[0];
     135               0 :         ++firstSource;
     136                 :     }
     137                 : 
     138               0 :     TIntermediate intermediate(infoSink);
     139                 :     TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
     140                 :                                shaderType, shaderSpec, compileOptions, true,
     141               0 :                                sourcePath, infoSink);
     142               0 :     GlobalParseContext = &parseContext;
     143                 : 
     144                 :     // We preserve symbols at the built-in level from compile-to-compile.
     145                 :     // Start pushing the user-defined symbols at global level.
     146               0 :     symbolTable.push();
     147               0 :     if (!symbolTable.atGlobalLevel())
     148               0 :         infoSink.info.message(EPrefixInternalError, "Wrong symbol table level");
     149                 : 
     150                 :     // Parse shader.
     151                 :     bool success =
     152               0 :         (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
     153               0 :         (parseContext.treeRoot != NULL);
     154               0 :     if (success) {
     155               0 :         TIntermNode* root = parseContext.treeRoot;
     156               0 :         success = intermediate.postProcess(root);
     157                 : 
     158               0 :         if (success)
     159               0 :             success = detectRecursion(root);
     160                 : 
     161               0 :         if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
     162               0 :             success = validateLimitations(root);
     163                 : 
     164                 :         // Unroll for-loop markup needs to happen after validateLimitations pass.
     165               0 :         if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
     166               0 :             ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root);
     167                 : 
     168                 :         // Built-in function emulation needs to happen after validateLimitations pass.
     169               0 :         if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
     170               0 :             builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
     171                 : 
     172                 :         // Call mapLongVariableNames() before collectAttribsUniforms() so in
     173                 :         // collectAttribsUniforms() we already have the mapped symbol names and
     174                 :         // we could composite mapped and original variable names.
     175               0 :         if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES))
     176               0 :             mapLongVariableNames(root);
     177                 : 
     178               0 :         if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
     179               0 :             collectAttribsUniforms(root);
     180                 : 
     181               0 :         if (success && (compileOptions & SH_INTERMEDIATE_TREE))
     182               0 :             intermediate.outputTree(root);
     183                 : 
     184               0 :         if (success && (compileOptions & SH_OBJECT_CODE))
     185               0 :             translate(root);
     186                 :     }
     187                 : 
     188                 :     // Cleanup memory.
     189               0 :     intermediate.remove(parseContext.treeRoot);
     190                 :     // Ensure symbol table is returned to the built-in level,
     191                 :     // throwing away all but the built-ins.
     192               0 :     while (!symbolTable.atBuiltInLevel())
     193               0 :         symbolTable.pop();
     194                 : 
     195               0 :     return success;
     196                 : }
     197                 : 
     198               0 : bool TCompiler::InitBuiltInSymbolTable(const ShBuiltInResources& resources)
     199                 : {
     200               0 :     TBuiltIns builtIns;
     201                 : 
     202               0 :     builtIns.initialize(shaderType, shaderSpec, resources);
     203               0 :     return InitializeSymbolTable(builtIns.getBuiltInStrings(),
     204               0 :         shaderType, shaderSpec, resources, infoSink, symbolTable);
     205                 : }
     206                 : 
     207               0 : void TCompiler::clearResults()
     208                 : {
     209               0 :     infoSink.info.erase();
     210               0 :     infoSink.obj.erase();
     211               0 :     infoSink.debug.erase();
     212                 : 
     213               0 :     attribs.clear();
     214               0 :     uniforms.clear();
     215                 : 
     216               0 :     builtInFunctionEmulator.Cleanup();
     217               0 : }
     218                 : 
     219               0 : bool TCompiler::detectRecursion(TIntermNode* root)
     220                 : {
     221               0 :     DetectRecursion detect;
     222               0 :     root->traverse(&detect);
     223               0 :     switch (detect.detectRecursion()) {
     224                 :         case DetectRecursion::kErrorNone:
     225               0 :             return true;
     226                 :         case DetectRecursion::kErrorMissingMain:
     227               0 :             infoSink.info.message(EPrefixError, "Missing main()");
     228               0 :             return false;
     229                 :         case DetectRecursion::kErrorRecursion:
     230               0 :             infoSink.info.message(EPrefixError, "Function recursion detected");
     231               0 :             return false;
     232                 :         default:
     233               0 :             UNREACHABLE();
     234                 :             return false;
     235                 :     }
     236                 : }
     237                 : 
     238               0 : bool TCompiler::validateLimitations(TIntermNode* root) {
     239               0 :     ValidateLimitations validate(shaderType, infoSink.info);
     240               0 :     root->traverse(&validate);
     241               0 :     return validate.numErrors() == 0;
     242                 : }
     243                 : 
     244               0 : void TCompiler::collectAttribsUniforms(TIntermNode* root)
     245                 : {
     246               0 :     CollectAttribsUniforms collect(attribs, uniforms);
     247               0 :     root->traverse(&collect);
     248               0 : }
     249                 : 
     250               0 : void TCompiler::mapLongVariableNames(TIntermNode* root)
     251                 : {
     252               0 :     ASSERT(longNameMap);
     253               0 :     MapLongVariableNames map(longNameMap);
     254               0 :     root->traverse(&map);
     255               0 : }
     256                 : 
     257               0 : int TCompiler::getMappedNameMaxLength() const
     258                 : {
     259               0 :     return MAX_SHORTENED_IDENTIFIER_SIZE + 1;
     260                 : }
     261                 : 
     262               0 : const TExtensionBehavior& TCompiler::getExtensionBehavior() const
     263                 : {
     264               0 :     return extensionBehavior;
     265                 : }
     266                 : 
     267               0 : const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
     268                 : {
     269               0 :     return builtInFunctionEmulator;
     270                 : }

Generated by: LCOV version 1.7