Fix encoding/decoding of string literals for big-endian systems
[platform/upstream/glslang.git] / SPIRV / disassemble.cpp
index 73c988c..74dd605 100644 (file)
@@ -43,6 +43,7 @@
 #include <stack>
 #include <sstream>
 #include <cstring>
+#include <utility>
 
 #include "disassemble.h"
 #include "doc.h"
@@ -100,6 +101,7 @@ protected:
     void outputMask(OperandClass operandClass, unsigned mask);
     void disassembleImmediates(int numOperands);
     void disassembleIds(int numOperands);
+    std::pair<int, std::string> decodeString();
     int disassembleString();
     void disassembleInstruction(Id resultId, Id typeId, Op opCode, int numOperands);
 
@@ -290,31 +292,44 @@ void SpirvStream::disassembleIds(int numOperands)
     }
 }
 
-// return the number of operands consumed by the string
-int SpirvStream::disassembleString()
+// decode string from words at current position (non-consuming)
+std::pair<int, std::string> SpirvStream::decodeString()
 {
-    int startWord = word;
-
-    out << " \"";
-
-    const char* wordString;
+    std::string res;
+    int wordPos = word;
+    char c;
     bool done = false;
+
     do {
-        unsigned int content = stream[word];
-        wordString = (const char*)&content;
+        unsigned int content = stream[wordPos];
         for (int charCount = 0; charCount < 4; ++charCount) {
-            if (*wordString == 0) {
+            c = content & 0xff;
+            content >>= 8;
+            if (c == '\0') {
                 done = true;
                 break;
             }
-            out << *(wordString++);
+            res += c;
         }
-        ++word;
-    } while (! done);
+        ++wordPos;
+    } while(! done);
+
+    return std::make_pair(wordPos - word, res);
+}
+
+// return the number of operands consumed by the string
+int SpirvStream::disassembleString()
+{
+    out << " \"";
 
+    std::pair<int, std::string> decoderes = decodeString();
+
+    out << decoderes.second;
     out << "\"";
 
-    return word - startWord;
+    word += decoderes.first;
+
+    return decoderes.first;
 }
 
 void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode, int numOperands)
@@ -331,7 +346,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
             nextNestedControl = 0;
         }
     } else if (opCode == OpExtInstImport) {
-        idDescriptor[resultId] = (const char*)(&stream[word]);
+        idDescriptor[resultId] = decodeString().second;
     }
     else {
         if (resultId != 0 && idDescriptor[resultId].size() == 0) {
@@ -428,7 +443,7 @@ void SpirvStream::disassembleInstruction(Id resultId, Id /*typeId*/, Op opCode,
             --numOperands;
             // Get names for printing "(XXX)" for readability, *after* this id
             if (opCode == OpName)
-                idDescriptor[stream[word - 1]] = (const char*)(&stream[word]);
+                idDescriptor[stream[word - 1]] = decodeString().second;
             break;
         case OperandVariableIds:
             disassembleIds(numOperands);