diff --git a/patches/common/config.json b/patches/common/config.json index 088dba42bcb12..e04c4bc0f0357 100644 --- a/patches/common/config.json +++ b/patches/common/config.json @@ -9,6 +9,8 @@ "src/electron/patches/common/skia": "src/third_party/skia", + "src/electron/patches/common/swiftshader": "src/third_party/swiftshader", + "src/electron/patches/common/webrtc": "src/third_party/webrtc", "src/electron/patches/common/v8": "src/v8" diff --git a/patches/common/swiftshader/.patches b/patches/common/swiftshader/.patches new file mode 100644 index 0000000000000..95e76e5e56ca1 --- /dev/null +++ b/patches/common/swiftshader/.patches @@ -0,0 +1,2 @@ +fix_undefined_behavior_in_offset.patch +fixed_all_oob_accesses_in_vertexprogram_and_pixelprogram.patch diff --git a/patches/common/swiftshader/fix_undefined_behavior_in_offset.patch b/patches/common/swiftshader/fix_undefined_behavior_in_offset.patch new file mode 100644 index 0000000000000..ce375d1ac0cde --- /dev/null +++ b/patches/common/swiftshader/fix_undefined_behavior_in_offset.patch @@ -0,0 +1,36 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Nicolas Capens +Date: Thu, 22 Nov 2018 10:32:35 -0500 +Subject: Fix undefined behavior in OFFSET(). +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Accessing members of a null pointer is undefined behavior, even when +only used to obtain the address again. So use a non-zero value as the +base pointer address instead. 32 was chosen to provide sufficient +alignment guarantees. + +Bug b/119823623 + +Change-Id: Ia6d24dd6c2740261948860c45eb35cc489a3a827 +Reviewed-on: https://swiftshader-review.googlesource.com/c/22788 +Tested-by: Nicolas Capens +Reviewed-by: Alexis Hétu + +diff --git a/src/Common/Types.hpp b/src/Common/Types.hpp +index cd08ed5704caa7f6454a619fd4ccbb9e2ddcee2c..837df461ab0676d94e6ee1276d75d289f06851ef 100644 +--- a/src/Common/Types.hpp ++++ b/src/Common/Types.hpp +@@ -151,7 +151,10 @@ namespace sw + return v; + } + +- #define OFFSET(s,m) (int)(size_t)&reinterpret_cast((((s*)0)->m)) ++ // The OFFSET macro is a generalization of the offsetof() macro defined in . ++ // It allows e.g. getting the offset of array elements, even when indexed dynamically. ++ // We cast the address '32' and subtract it again, because null-dereference is undefined behavior. ++ #define OFFSET(s,m) ((int)(size_t)&reinterpret_cast((((s*)32)->m)) - 32) + } + + #endif // sw_Types_hpp diff --git a/patches/common/swiftshader/fixed_all_oob_accesses_in_vertexprogram_and_pixelprogram.patch b/patches/common/swiftshader/fixed_all_oob_accesses_in_vertexprogram_and_pixelprogram.patch new file mode 100644 index 0000000000000..c841bccb02910 --- /dev/null +++ b/patches/common/swiftshader/fixed_all_oob_accesses_in_vertexprogram_and_pixelprogram.patch @@ -0,0 +1,508 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Alexis Hetu +Date: Thu, 10 Jan 2019 14:04:26 -0500 +Subject: Fixed all OOB accesses in VertexProgram and PixelProgram +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +A lot of arrays in VertexProgram and PixelProgram have fixed sizes, +so programs that have more nested loops or ifs or deeper call stacks +can cause OOB accesses, which causes security issues in Chromium. + +Index clamping was added to prevent any OOB memory accesses here. + +This could eventually be fixed properly by first verifying these sizes +and giving shader compile errors when these limits are exceeded. + +Bug chromium:915197 chromium:915206 chromium:915218 b/116373662 + +Change-Id: I2d0710ed0ce6585f139cba49d5b5d8c909ae6391 +Reviewed-on: https://swiftshader-review.googlesource.com/c/23568 +Tested-by: Alexis Hétu +Reviewed-by: Corentin Wallez + +diff --git a/src/Common/Types.hpp b/src/Common/Types.hpp +index 837df461ab0676d94e6ee1276d75d289f06851ef..fac6d362891cf0b2a19f8faee0a1dbbdddbc3a88 100644 +--- a/src/Common/Types.hpp ++++ b/src/Common/Types.hpp +@@ -15,6 +15,7 @@ + #ifndef sw_Types_hpp + #define sw_Types_hpp + ++#include + #include + #include + +@@ -151,6 +152,46 @@ namespace sw + return v; + } + ++ template class BoundedIndex ++ { ++ public: ++ BoundedIndex(int index) : index(index) {} ++ ++ inline int operator++(int) { return index++; } ++ inline int operator--(int) { return index--; } ++ inline void operator=(int i) { index = i; } ++ ++ inline bool operator==(int i) { return index == i; } ++ inline bool operator!=(int i) { return index != i; } ++ inline bool operator<(int i) { return index < i; } ++ inline bool operator>(int i) { return index > i; } ++ inline bool operator<=(int i) { return index <= i; } ++ inline bool operator>=(int i) { return index >= i; } ++ ++ inline operator int() ++ { ++ if(index < 0) ++ { ++#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) ++ assert(false); ++#endif ++ return 0; ++ } ++ else if(index >= limit) ++ { ++#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) ++ assert(false); ++#endif ++ return limit - 1; ++ } ++ ++ return index; ++ } ++ ++ private: ++ int index = 0; ++ }; ++ + // The OFFSET macro is a generalization of the offsetof() macro defined in . + // It allows e.g. getting the offset of array elements, even when indexed dynamically. + // We cast the address '32' and subtract it again, because null-dereference is undefined behavior. +diff --git a/src/Main/Config.hpp b/src/Main/Config.hpp +index 764bfed1e7a159715f5d269e88d0d9ab578b778f..f875085452d0255d78b60ad9313e035d4ab3691f 100644 +--- a/src/Main/Config.hpp ++++ b/src/Main/Config.hpp +@@ -97,6 +97,11 @@ namespace sw + MAX_TEXTURE_LOD = MIPMAP_LEVELS - 2, // Trilinear accesses lod+1 + RENDERTARGETS = 8, + NUM_TEMPORARY_REGISTERS = 4096, ++ MAX_SHADER_CALL_SITES = 2048, ++ MAX_SHADER_NESTED_LOOPS = 4, ++ MAX_SHADER_NESTED_IFS = 24 + 24, ++ MAX_SHADER_CALL_STACK_SIZE = 16, ++ MAX_SHADER_ENABLE_STACK_SIZE = 1 + 24, + }; + } + +diff --git a/src/Shader/PixelProgram.cpp b/src/Shader/PixelProgram.cpp +index 3cedbce8debcc7a1f8d22a7e687ea5673f33d01f..f8637209323b7dfe52b1736a9b15f0285f987331 100644 +--- a/src/Shader/PixelProgram.cpp ++++ b/src/Shader/PixelProgram.cpp +@@ -828,7 +828,7 @@ namespace sw + + Int4 PixelProgram::enableMask(const Shader::Instruction *instruction) + { +- Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF); ++ Int4 enable = instruction->analysisBranch ? Int4(enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]) : Int4(0xFFFFFFFF); + + if(!whileTest) + { +@@ -1343,7 +1343,7 @@ namespace sw + + void PixelProgram::BREAK() + { +- enableBreak = enableBreak & ~enableStack[enableIndex]; ++ enableBreak = enableBreak & ~enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + } + + void PixelProgram::BREAKC(Vector4f &src0, Vector4f &src1, Control control) +@@ -1379,14 +1379,14 @@ namespace sw + + void PixelProgram::BREAK(Int4 &condition) + { +- condition &= enableStack[enableIndex]; ++ condition &= enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + + enableBreak = enableBreak & ~condition; + } + + void PixelProgram::CONTINUE() + { +- enableContinue = enableContinue & ~enableStack[enableIndex]; ++ enableContinue = enableContinue & ~enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + } + + void PixelProgram::TEST() +@@ -1403,7 +1403,7 @@ namespace sw + + if(callRetBlock[labelIndex].size() > 1) + { +- callStack[stackIndex++] = UInt(callSiteIndex); ++ callStack[Min(stackIndex++, Int(MAX_SHADER_CALL_STACK_SIZE))] = UInt(callSiteIndex); + } + + Int4 restoreLeave = enableLeave; +@@ -1443,7 +1443,7 @@ namespace sw + + if(callRetBlock[labelIndex].size() > 1) + { +- callStack[stackIndex++] = UInt(callSiteIndex); ++ callStack[Min(stackIndex++, Int(MAX_SHADER_CALL_STACK_SIZE))] = UInt(callSiteIndex); + } + + Int4 restoreLeave = enableLeave; +@@ -1463,7 +1463,7 @@ namespace sw + condition = ~condition; + } + +- condition &= enableStack[enableIndex]; ++ condition &= enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + + if(!labelBlock[labelIndex]) + { +@@ -1472,11 +1472,11 @@ namespace sw + + if(callRetBlock[labelIndex].size() > 1) + { +- callStack[stackIndex++] = UInt(callSiteIndex); ++ callStack[Min(stackIndex++, Int(MAX_SHADER_CALL_STACK_SIZE))] = UInt(callSiteIndex); + } + + enableIndex++; +- enableStack[enableIndex] = condition; ++ enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))] = condition; + Int4 restoreLeave = enableLeave; + + Bool notAllFalse = SignMask(condition) != 0; +@@ -1496,12 +1496,12 @@ namespace sw + + if(isConditionalIf[ifDepth]) + { +- Int4 condition = ~enableStack[enableIndex] & enableStack[enableIndex - 1]; ++ Int4 condition = ~enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))] & enableStack[Min(enableIndex - 1, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + Bool notAllFalse = SignMask(condition) != 0; + + branch(notAllFalse, falseBlock, endBlock); + +- enableStack[enableIndex] = ~enableStack[enableIndex] & enableStack[enableIndex - 1]; ++ enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))] = ~enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))] & enableStack[Min(enableIndex - 1, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + } + else + { +@@ -1655,10 +1655,10 @@ namespace sw + + void PixelProgram::IF(Int4 &condition) + { +- condition &= enableStack[enableIndex]; ++ condition &= enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + + enableIndex++; +- enableStack[enableIndex] = condition; ++ enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))] = condition; + + BasicBlock *trueBlock = Nucleus::createBasicBlock(); + BasicBlock *falseBlock = Nucleus::createBasicBlock(); +@@ -1763,10 +1763,10 @@ namespace sw + + const Vector4f &src = fetchRegister(temporaryRegister); + Int4 condition = As(src.x); +- condition &= enableStack[enableIndex - 1]; ++ condition &= enableStack[Min(enableIndex - 1, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + if(shader->containsLeaveInstruction()) condition &= enableLeave; + if(shader->containsBreakInstruction()) condition &= enableBreak; +- enableStack[enableIndex] = condition; ++ enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))] = condition; + + Bool notAllFalse = SignMask(condition) != 0; + branch(notAllFalse, loopBlock, endBlock); +@@ -1838,7 +1838,7 @@ namespace sw + + void PixelProgram::LEAVE() + { +- enableLeave = enableLeave & ~enableStack[enableIndex]; ++ enableLeave = enableLeave & ~enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + + // FIXME: Return from function if all instances left + // FIXME: Use enableLeave in other control-flow constructs +diff --git a/src/Shader/PixelProgram.hpp b/src/Shader/PixelProgram.hpp +index 240938dd15820601ce2bf5e4ff6eb242ddd196e7..4ed3eef7545e27b56ceffa5a7cf33ebe9b7c287f 100644 +--- a/src/Shader/PixelProgram.hpp ++++ b/src/Shader/PixelProgram.hpp +@@ -27,7 +27,7 @@ namespace sw + PixelRoutine(state, shader), r(shader->indirectAddressableTemporaries), + loopDepth(-1), ifDepth(0), loopRepDepth(0), currentLabel(-1), whileTest(false) + { +- for(int i = 0; i < 2048; ++i) ++ for(int i = 0; i < MAX_SHADER_CALL_SITES; ++i) + { + labelBlock[i] = 0; + } +@@ -67,17 +67,17 @@ namespace sw + + // DX9 specific variables + Vector4f p0; +- Array aL; +- Array increment; +- Array iteration; ++ Array aL; ++ Array increment; ++ Array iteration; + + Int loopDepth; // FIXME: Add support for switch + Int stackIndex; // FIXME: Inc/decrement callStack +- Array callStack; ++ Array callStack; + + // Per pixel based on conditions reached + Int enableIndex; +- Array enableStack; ++ Array enableStack; + Int4 enableBreak; + Int4 enableContinue; + Int4 enableLeave; +@@ -152,18 +152,18 @@ namespace sw + void RET(); + void LEAVE(); + +- int ifDepth; +- int loopRepDepth; +- int currentLabel; ++ BoundedIndex ifDepth = 0; ++ BoundedIndex loopRepDepth = 0; ++ BoundedIndex currentLabel = -1; + bool whileTest; + +- BasicBlock *ifFalseBlock[24 + 24]; +- BasicBlock *loopRepTestBlock[4]; +- BasicBlock *loopRepEndBlock[4]; +- BasicBlock *labelBlock[2048]; +- std::vector callRetBlock[2048]; ++ BasicBlock *ifFalseBlock[MAX_SHADER_NESTED_IFS]; ++ BasicBlock *loopRepTestBlock[MAX_SHADER_NESTED_LOOPS]; ++ BasicBlock *loopRepEndBlock[MAX_SHADER_NESTED_LOOPS]; ++ BasicBlock *labelBlock[MAX_SHADER_CALL_SITES]; ++ std::vector callRetBlock[MAX_SHADER_CALL_SITES]; + BasicBlock *returnBlock; +- bool isConditionalIf[24 + 24]; ++ bool isConditionalIf[MAX_SHADER_NESTED_IFS]; + }; + } + +diff --git a/src/Shader/Shader.cpp b/src/Shader/Shader.cpp +index 36192c93c7473e7c4bc140843ad2c16ca11d3788..0e06703cae08a5e955684d7dc3f03069c3789f4f 100644 +--- a/src/Shader/Shader.cpp ++++ b/src/Shader/Shader.cpp +@@ -1877,13 +1877,13 @@ namespace sw + // This is used to know what basic block to return to. + void Shader::analyzeCallSites() + { +- int callSiteIndex[2048] = {0}; ++ int callSiteIndex[MAX_SHADER_CALL_SITES] = {0}; + + for(auto &inst : instruction) + { + if(inst->opcode == OPCODE_CALL || inst->opcode == OPCODE_CALLNZ) + { +- int label = inst->dst.label; ++ int label = sw::min(inst->dst.label, unsigned int(MAX_SHADER_CALL_SITES)); + + inst->dst.callSite = callSiteIndex[label]++; + } +diff --git a/src/Shader/VertexProgram.cpp b/src/Shader/VertexProgram.cpp +index ad4e37bd4e5c1e93bc6728d5eaba19caf7f95e92..694f05179d6df328ef6f64a882d428422d7e86d6 100644 +--- a/src/Shader/VertexProgram.cpp ++++ b/src/Shader/VertexProgram.cpp +@@ -31,7 +31,7 @@ namespace sw + currentLabel = -1; + whileTest = false; + +- for(int i = 0; i < 2048; i++) ++ for(int i = 0; i < MAX_SHADER_CALL_SITES; i++) + { + labelBlock[i] = 0; + } +@@ -978,7 +978,7 @@ namespace sw + + Int4 VertexProgram::enableMask(const Shader::Instruction *instruction) + { +- Int4 enable = instruction->analysisBranch ? Int4(enableStack[enableIndex]) : Int4(0xFFFFFFFF); ++ Int4 enable = instruction->analysisBranch ? Int4(enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]) : Int4(0xFFFFFFFF); + + if(!whileTest) + { +@@ -1060,7 +1060,7 @@ namespace sw + + void VertexProgram::BREAK() + { +- enableBreak = enableBreak & ~enableStack[enableIndex]; ++ enableBreak = enableBreak & ~enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + } + + void VertexProgram::BREAKC(Vector4f &src0, Vector4f &src1, Control control) +@@ -1096,14 +1096,14 @@ namespace sw + + void VertexProgram::BREAK(Int4 &condition) + { +- condition &= enableStack[enableIndex]; ++ condition &= enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + + enableBreak = enableBreak & ~condition; + } + + void VertexProgram::CONTINUE() + { +- enableContinue = enableContinue & ~enableStack[enableIndex]; ++ enableContinue = enableContinue & ~enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + } + + void VertexProgram::TEST() +@@ -1120,7 +1120,7 @@ namespace sw + + if(callRetBlock[labelIndex].size() > 1) + { +- callStack[stackIndex++] = UInt(callSiteIndex); ++ callStack[Min(stackIndex++, Int(MAX_SHADER_CALL_STACK_SIZE))] = UInt(callSiteIndex); + } + + Int4 restoreLeave = enableLeave; +@@ -1160,7 +1160,7 @@ namespace sw + + if(callRetBlock[labelIndex].size() > 1) + { +- callStack[stackIndex++] = UInt(callSiteIndex); ++ callStack[Min(stackIndex++, Int(MAX_SHADER_CALL_STACK_SIZE))] = UInt(callSiteIndex); + } + + Int4 restoreLeave = enableLeave; +@@ -1180,7 +1180,7 @@ namespace sw + condition = ~condition; + } + +- condition &= enableStack[enableIndex]; ++ condition &= enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + + if(!labelBlock[labelIndex]) + { +@@ -1189,11 +1189,11 @@ namespace sw + + if(callRetBlock[labelIndex].size() > 1) + { +- callStack[stackIndex++] = UInt(callSiteIndex); ++ callStack[Min(stackIndex++, Int(MAX_SHADER_CALL_STACK_SIZE))] = UInt(callSiteIndex); + } + + enableIndex++; +- enableStack[enableIndex] = condition; ++ enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))] = condition; + Int4 restoreLeave = enableLeave; + + Bool notAllFalse = SignMask(condition) != 0; +@@ -1213,12 +1213,12 @@ namespace sw + + if(isConditionalIf[ifDepth]) + { +- Int4 condition = ~enableStack[enableIndex] & enableStack[enableIndex - 1]; ++ Int4 condition = ~enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))] & enableStack[Min(enableIndex - 1, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + Bool notAllFalse = SignMask(condition) != 0; + + branch(notAllFalse, falseBlock, endBlock); + +- enableStack[enableIndex] = ~enableStack[enableIndex] & enableStack[enableIndex - 1]; ++ enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))] = ~enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))] & enableStack[Min(enableIndex - 1, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + } + else + { +@@ -1372,10 +1372,10 @@ namespace sw + + void VertexProgram::IF(Int4 &condition) + { +- condition &= enableStack[enableIndex]; ++ condition &= enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + + enableIndex++; +- enableStack[enableIndex] = condition; ++ enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))] = condition; + + BasicBlock *trueBlock = Nucleus::createBasicBlock(); + BasicBlock *falseBlock = Nucleus::createBasicBlock(); +@@ -1481,10 +1481,10 @@ namespace sw + + const Vector4f &src = fetchRegister(temporaryRegister); + Int4 condition = As(src.x); +- condition &= enableStack[enableIndex - 1]; ++ condition &= enableStack[Min(enableIndex - 1, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + if(shader->containsLeaveInstruction()) condition &= enableLeave; + if(shader->containsBreakInstruction()) condition &= enableBreak; +- enableStack[enableIndex] = condition; ++ enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))] = condition; + + Bool notAllFalse = SignMask(condition) != 0; + branch(notAllFalse, loopBlock, endBlock); +@@ -1556,7 +1556,7 @@ namespace sw + + void VertexProgram::LEAVE() + { +- enableLeave = enableLeave & ~enableStack[enableIndex]; ++ enableLeave = enableLeave & ~enableStack[Min(enableIndex, Int(MAX_SHADER_ENABLE_STACK_SIZE))]; + + // FIXME: Return from function if all instances left + // FIXME: Use enableLeave in other control-flow constructs +diff --git a/src/Shader/VertexProgram.hpp b/src/Shader/VertexProgram.hpp +index 3c4199c6611198997326d387f787bcd7467558a3..8421078acaa9f89e311015f62e17d4825a3a6e82 100644 +--- a/src/Shader/VertexProgram.hpp ++++ b/src/Shader/VertexProgram.hpp +@@ -39,18 +39,18 @@ namespace sw + + RegisterArray r; // Temporary registers + Vector4f a0; +- Array aL; ++ Array aL; + Vector4f p0; + +- Array increment; +- Array iteration; ++ Array increment; ++ Array iteration; + + Int loopDepth; + Int stackIndex; // FIXME: Inc/decrement callStack +- Array callStack; ++ Array callStack; + + Int enableIndex; +- Array enableStack; ++ Array enableStack; + Int4 enableBreak; + Int4 enableContinue; + Int4 enableLeave; +@@ -121,18 +121,18 @@ namespace sw + Vector4f sampleTexture(const Src &s, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function); + Vector4f sampleTexture(int sampler, Vector4f &uvwq, Float4 &lod, Vector4f &dsx, Vector4f &dsy, Vector4f &offset, SamplerFunction function); + +- int ifDepth; +- int loopRepDepth; +- int currentLabel; ++ BoundedIndex ifDepth = 0; ++ BoundedIndex loopRepDepth = 0; ++ BoundedIndex currentLabel = -1; + bool whileTest; + +- BasicBlock *ifFalseBlock[24 + 24]; +- BasicBlock *loopRepTestBlock[4]; +- BasicBlock *loopRepEndBlock[4]; +- BasicBlock *labelBlock[2048]; +- std::vector callRetBlock[2048]; ++ BasicBlock *ifFalseBlock[MAX_SHADER_NESTED_IFS]; ++ BasicBlock *loopRepTestBlock[MAX_SHADER_NESTED_LOOPS]; ++ BasicBlock *loopRepEndBlock[MAX_SHADER_NESTED_LOOPS]; ++ BasicBlock *labelBlock[MAX_SHADER_CALL_SITES]; ++ std::vector callRetBlock[MAX_SHADER_CALL_SITES]; + BasicBlock *returnBlock; +- bool isConditionalIf[24 + 24]; ++ bool isConditionalIf[MAX_SHADER_NESTED_IFS]; + }; + } +