summaryrefslogtreecommitdiffstats
path: root/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp')
-rw-r--r--Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp97
1 files changed, 89 insertions, 8 deletions
diff --git a/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp b/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp
index 649b457..f27cb75 100644
--- a/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp
+++ b/Source/ThirdParty/ANGLE/src/compiler/Compiler.cpp
@@ -1,10 +1,14 @@
//
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
+#include "compiler/BuiltInFunctionEmulator.h"
+#include "compiler/DetectRecursion.h"
+#include "compiler/ForLoopUnroll.h"
#include "compiler/Initialize.h"
+#include "compiler/MapLongVariableNames.h"
#include "compiler/ParseHelper.h"
#include "compiler/ShHandle.h"
#include "compiler/ValidateLimitations.h"
@@ -17,7 +21,10 @@ bool InitializeSymbolTable(
{
TIntermediate intermediate(infoSink);
TExtensionBehavior extBehavior;
- TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, infoSink);
+ InitExtensionBehavior(resources, extBehavior);
+ // The builtins deliberately don't specify precisions for the function
+ // arguments and return types. For that reason we don't try to check them.
+ TParseContext parseContext(symbolTable, extBehavior, intermediate, type, spec, 0, false, NULL, infoSink);
GlobalParseContext = &parseContext;
@@ -81,12 +88,16 @@ TShHandleBase::~TShHandleBase() {
TCompiler::TCompiler(ShShaderType type, ShShaderSpec spec)
: shaderType(type),
- shaderSpec(spec)
+ shaderSpec(spec),
+ builtInFunctionEmulator(type)
{
+ longNameMap = LongNameMap::GetInstance();
}
TCompiler::~TCompiler()
{
+ ASSERT(longNameMap);
+ longNameMap->Release();
}
bool TCompiler::Init(const ShBuiltInResources& resources)
@@ -115,9 +126,19 @@ bool TCompiler::compile(const char* const shaderStrings[],
if (shaderSpec == SH_WEBGL_SPEC)
compileOptions |= SH_VALIDATE_LOOP_INDEXING;
+ // First string is path of source file if flag is set. The actual source follows.
+ const char* sourcePath = NULL;
+ int firstSource = 0;
+ if (compileOptions & SH_SOURCE_PATH)
+ {
+ sourcePath = shaderStrings[0];
+ ++firstSource;
+ }
+
TIntermediate intermediate(infoSink);
TParseContext parseContext(symbolTable, extensionBehavior, intermediate,
- shaderType, shaderSpec, infoSink);
+ shaderType, shaderSpec, compileOptions, true,
+ sourcePath, infoSink);
GlobalParseContext = &parseContext;
// We preserve symbols at the built-in level from compile-to-compile.
@@ -128,23 +149,40 @@ bool TCompiler::compile(const char* const shaderStrings[],
// Parse shader.
bool success =
- (PaParseStrings(numStrings, shaderStrings, NULL, &parseContext) == 0) &&
+ (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
(parseContext.treeRoot != NULL);
if (success) {
TIntermNode* root = parseContext.treeRoot;
success = intermediate.postProcess(root);
+ if (success)
+ success = detectRecursion(root);
+
if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
success = validateLimitations(root);
+ // Unroll for-loop markup needs to happen after validateLimitations pass.
+ if (success && (compileOptions & SH_UNROLL_FOR_LOOP_WITH_INTEGER_INDEX))
+ ForLoopUnroll::MarkForLoopsWithIntegerIndicesForUnrolling(root);
+
+ // Built-in function emulation needs to happen after validateLimitations pass.
+ if (success && (compileOptions & SH_EMULATE_BUILT_IN_FUNCTIONS))
+ builtInFunctionEmulator.MarkBuiltInFunctionsForEmulation(root);
+
+ // Call mapLongVariableNames() before collectAttribsUniforms() so in
+ // collectAttribsUniforms() we already have the mapped symbol names and
+ // we could composite mapped and original variable names.
+ if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES))
+ mapLongVariableNames(root);
+
+ if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
+ collectAttribsUniforms(root);
+
if (success && (compileOptions & SH_INTERMEDIATE_TREE))
intermediate.outputTree(root);
if (success && (compileOptions & SH_OBJECT_CODE))
translate(root);
-
- if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
- collectAttribsUniforms(root);
}
// Cleanup memory.
@@ -174,6 +212,27 @@ void TCompiler::clearResults()
attribs.clear();
uniforms.clear();
+
+ builtInFunctionEmulator.Cleanup();
+}
+
+bool TCompiler::detectRecursion(TIntermNode* root)
+{
+ DetectRecursion detect;
+ root->traverse(&detect);
+ switch (detect.detectRecursion()) {
+ case DetectRecursion::kErrorNone:
+ return true;
+ case DetectRecursion::kErrorMissingMain:
+ infoSink.info.message(EPrefixError, "Missing main()");
+ return false;
+ case DetectRecursion::kErrorRecursion:
+ infoSink.info.message(EPrefixError, "Function recursion detected");
+ return false;
+ default:
+ UNREACHABLE();
+ return false;
+ }
}
bool TCompiler::validateLimitations(TIntermNode* root) {
@@ -187,3 +246,25 @@ void TCompiler::collectAttribsUniforms(TIntermNode* root)
CollectAttribsUniforms collect(attribs, uniforms);
root->traverse(&collect);
}
+
+void TCompiler::mapLongVariableNames(TIntermNode* root)
+{
+ ASSERT(longNameMap);
+ MapLongVariableNames map(longNameMap);
+ root->traverse(&map);
+}
+
+int TCompiler::getMappedNameMaxLength() const
+{
+ return MAX_SHORTENED_IDENTIFIER_SIZE + 1;
+}
+
+const TExtensionBehavior& TCompiler::getExtensionBehavior() const
+{
+ return extensionBehavior;
+}
+
+const BuiltInFunctionEmulator& TCompiler::getBuiltInFunctionEmulator() const
+{
+ return builtInFunctionEmulator;
+}