switched skslc from std::string to SkString
authorEthan Nicholas <ethannicholas@google.com>
Thu, 17 Nov 2016 21:13:37 +0000 (16:13 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 18 Nov 2016 14:34:08 +0000 (14:34 +0000)
BUG=skia:

GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4977

Change-Id: I15e24963b09b719a2c07da67745114f5ac66cee8
Reviewed-on: https://skia-review.googlesource.com/4977
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>

100 files changed:
bench/GLBench.cpp
fuzz/fuzz.cpp
src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
src/gpu/vk/GrVkUtil.cpp
src/sksl/SkSLCodeGenerator.h
src/sksl/SkSLCompiler.cpp
src/sksl/SkSLCompiler.h
src/sksl/SkSLContext.h
src/sksl/SkSLErrorReporter.h
src/sksl/SkSLGLSLCodeGenerator.cpp
src/sksl/SkSLGLSLCodeGenerator.h
src/sksl/SkSLIRGenerator.cpp
src/sksl/SkSLIRGenerator.h
src/sksl/SkSLMain.cpp
src/sksl/SkSLParser.cpp
src/sksl/SkSLParser.h
src/sksl/SkSLPosition.h
src/sksl/SkSLSPIRVCodeGenerator.cpp
src/sksl/SkSLSPIRVCodeGenerator.h
src/sksl/SkSLToken.h
src/sksl/SkSLUtil.cpp
src/sksl/SkSLUtil.h
src/sksl/ast/SkSLASTBinaryExpression.h
src/sksl/ast/SkSLASTBlock.h
src/sksl/ast/SkSLASTBoolLiteral.h
src/sksl/ast/SkSLASTBreakStatement.h
src/sksl/ast/SkSLASTCallSuffix.h
src/sksl/ast/SkSLASTContinueStatement.h
src/sksl/ast/SkSLASTDiscardStatement.h
src/sksl/ast/SkSLASTDoStatement.h
src/sksl/ast/SkSLASTExpressionStatement.h
src/sksl/ast/SkSLASTExtension.h
src/sksl/ast/SkSLASTFieldSuffix.h
src/sksl/ast/SkSLASTFloatLiteral.h
src/sksl/ast/SkSLASTForStatement.h
src/sksl/ast/SkSLASTFunction.h
src/sksl/ast/SkSLASTIdentifier.h
src/sksl/ast/SkSLASTIfStatement.h
src/sksl/ast/SkSLASTIndexSuffix.h
src/sksl/ast/SkSLASTIntLiteral.h
src/sksl/ast/SkSLASTInterfaceBlock.h
src/sksl/ast/SkSLASTLayout.h
src/sksl/ast/SkSLASTModifiers.h
src/sksl/ast/SkSLASTModifiersDeclaration.h
src/sksl/ast/SkSLASTNode.h
src/sksl/ast/SkSLASTParameter.h
src/sksl/ast/SkSLASTPrecision.h
src/sksl/ast/SkSLASTPrefixExpression.h
src/sksl/ast/SkSLASTReturnStatement.h
src/sksl/ast/SkSLASTSuffix.h
src/sksl/ast/SkSLASTSuffixExpression.h
src/sksl/ast/SkSLASTTernaryExpression.h
src/sksl/ast/SkSLASTType.h
src/sksl/ast/SkSLASTVarDeclaration.h
src/sksl/ast/SkSLASTVarDeclarationStatement.h
src/sksl/ast/SkSLASTWhileStatement.h
src/sksl/ir/SkSLBinaryExpression.h
src/sksl/ir/SkSLBlock.h
src/sksl/ir/SkSLBoolLiteral.h
src/sksl/ir/SkSLBreakStatement.h
src/sksl/ir/SkSLConstructor.h
src/sksl/ir/SkSLContinueStatement.h
src/sksl/ir/SkSLDiscardStatement.h
src/sksl/ir/SkSLDoStatement.h
src/sksl/ir/SkSLExpressionStatement.h
src/sksl/ir/SkSLExtension.h
src/sksl/ir/SkSLField.h
src/sksl/ir/SkSLFieldAccess.h
src/sksl/ir/SkSLFloatLiteral.h
src/sksl/ir/SkSLForStatement.h
src/sksl/ir/SkSLFunctionCall.h
src/sksl/ir/SkSLFunctionDeclaration.h
src/sksl/ir/SkSLFunctionDefinition.h
src/sksl/ir/SkSLFunctionReference.h
src/sksl/ir/SkSLIRNode.h
src/sksl/ir/SkSLIfStatement.h
src/sksl/ir/SkSLIndexExpression.h
src/sksl/ir/SkSLIntLiteral.h
src/sksl/ir/SkSLInterfaceBlock.h
src/sksl/ir/SkSLLayout.h
src/sksl/ir/SkSLModifiers.h
src/sksl/ir/SkSLModifiersDeclaration.h
src/sksl/ir/SkSLPostfixExpression.h
src/sksl/ir/SkSLPrefixExpression.h
src/sksl/ir/SkSLReturnStatement.h
src/sksl/ir/SkSLSwizzle.h
src/sksl/ir/SkSLSymbol.h
src/sksl/ir/SkSLSymbolTable.cpp
src/sksl/ir/SkSLSymbolTable.h
src/sksl/ir/SkSLTernaryExpression.h
src/sksl/ir/SkSLType.h
src/sksl/ir/SkSLTypeReference.h
src/sksl/ir/SkSLUnresolvedFunction.h
src/sksl/ir/SkSLVarDeclarations.h
src/sksl/ir/SkSLVarDeclarationsStatement.h
src/sksl/ir/SkSLVariable.h
src/sksl/ir/SkSLVariableReference.h
src/sksl/ir/SkSLWhileStatement.h
tests/SkSLErrorTest.cpp
tests/SkSLGLSLTest.cpp

index df9ee9b..a39edee 100644 (file)
@@ -14,7 +14,6 @@
 #include "gl/builders/GrGLShaderStringBuilder.h"
 #include "SkSLCompiler.h"
 #include <stdio.h>
-#include <string>
 
 const GrGLContext* GLBench::getGLContext(SkCanvas* canvas) {
     // This bench exclusively tests GL calls directly
@@ -66,11 +65,11 @@ void GLBench::onDraw(int loops, SkCanvas* canvas) {
 
 GrGLuint GLBench::CompileShader(const GrGLContext* context, const char* sksl, GrGLenum type) {
     const GrGLInterface* gl = context->interface();
-    std::string glsl;
+    SkString glsl;
     bool result = context->compiler()->toGLSL(type == GR_GL_VERTEX_SHADER 
                                                                     ? SkSL::Program::kVertex_Kind
                                                                     : SkSL::Program::kFragment_Kind,
-                                              std::string(sksl),
+                                              SkString(sksl),
                                               *context->caps()->glslCaps(),
                                               &glsl);
     if (!result) {
index d146a2f..377e53f 100644 (file)
@@ -402,9 +402,9 @@ int fuzz_color_deserialize(sk_sp<SkData> bytes) {
 #if SK_SUPPORT_GPU
 int fuzz_sksl2glsl(sk_sp<SkData> bytes) {
     SkSL::Compiler compiler;
-    std::string output;
+    SkString output;
     bool result = compiler.toGLSL(SkSL::Program::kFragment_Kind,
-        (const char*)bytes->data(), *SkSL::GLSLCapsFactory::Default(), &output);
+        SkString((const char*)bytes->data()), *SkSL::GLSLCapsFactory::Default(), &output);
 
     if (!result) {
         SkDebugf("[terminated] Couldn't compile input.\n");
index 1e42259..86df089 100644 (file)
@@ -21,18 +21,19 @@ static const bool c_PrintShaders{false};
 
 static void print_shader_source(const char** strings, int* lengths, int count);
 
-static void dump_string(std::string s) {
+static void dump_string(SkString s) {
     // on Android, SkDebugf only displays the first 1K characters of output, which results in
     // incomplete shader source code. Print each line individually to avoid this problem.
-    size_t index = 0;
+    const char* chars = s.c_str();
     for (;;) {
-        size_t next = s.find("\n", index);
-        if (next == std::string::npos) {
-            SkDebugf("%s", s.substr(index).c_str());
-            break;
+        const char* next = strchr(chars, '\n');
+        if (next) {
+            next++;
+            SkDebugf("%s", SkString(chars, next - chars).c_str());
+            chars = next;
         } else {
-            SkDebugf("%s", s.substr(index, next - index + 1).c_str());
-            index = next + 1;
+            SkDebugf("%s", chars);
+            break;
         }
     }
 }
@@ -52,23 +53,22 @@ GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
         return 0;
     }
 
-    std::string sksl;
+    SkString sksl;
 #ifdef SK_DEBUG
-    SkString prettySource = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, count, false);
-    sksl = std::string(prettySource.c_str());
+    sksl = GrGLSLPrettyPrint::PrettyPrintGLSL(strings, lengths, count, false);
 #else
     for (int i = 0; i < count; i++) {
         sksl.append(strings[i], lengths[i]);
     }
 #endif
 
-    std::string glsl;
+    SkString glsl;
     SkSL::Compiler& compiler = *glCtx.compiler();
     SkASSERT(type == GR_GL_VERTEX_SHADER || type == GR_GL_FRAGMENT_SHADER);
     SkDEBUGCODE(bool result = )compiler.toGLSL(type == GR_GL_VERTEX_SHADER 
                                                                     ? SkSL::Program::kVertex_Kind
                                                                     : SkSL::Program::kFragment_Kind,
-                                               std::string(sksl.c_str()),
+                                               sksl,
                                                *glCtx.caps()->glslCaps(),
                                                &glsl);
 #ifdef SK_DEBUG
@@ -82,7 +82,7 @@ GrGLuint GrGLCompileAndAttachShader(const GrGLContext& glCtx,
 #endif
 
     const char* glslChars = glsl.c_str();
-    GrGLint glslLength = (GrGLint) glsl.length();
+    GrGLint glslLength = (GrGLint) glsl.size();
     GR_GL_CALL(gli, ShaderSource(shaderId, 1, &glslChars, &glslLength));
 
     // If tracing is enabled in chrome then we pretty print
index 1d93e8d..4446dfe 100644 (file)
@@ -292,7 +292,7 @@ bool GrCompileVkShaderModule(const GrVkGpu* gpu,
     moduleCreateInfo.flags = 0;
 
 #if USE_SKSL
-    std::string code;
+    SkString code;
 #else
     shaderc_compilation_result_t result = nullptr;
 #endif
@@ -304,7 +304,7 @@ bool GrCompileVkShaderModule(const GrVkGpu* gpu,
 
 #if USE_SKSL
         bool result = gpu->shaderCompiler()->toSPIRV(vk_shader_stage_to_skiasl_kind(stage),
-                                                     std::string(shaderString),
+                                                     SkString(shaderString),
                                                      &code);
         if (!result) {
             SkDebugf("%s\n", gpu->shaderCompiler()->errorText().c_str());
index 7bf857d..211cf0a 100644 (file)
@@ -9,8 +9,6 @@
 #define SKSL_CODEGENERATOR
 
 #include "ir/SkSLProgram.h"
-#include <vector>
-#include <ostream>
 
 namespace SkSL {
 
@@ -22,7 +20,7 @@ class CodeGenerator {
 public:
     virtual ~CodeGenerator() {}
     
-    virtual void generateCode(const Program& program, std::ostream& out) = 0;
+    virtual void generateCode(const Program& program, SkWStream& out) = 0;
 };
 
 } // namespace
index 510d610..905eff4 100644 (file)
@@ -7,9 +7,6 @@
 
 #include "SkSLCompiler.h"
 
-#include <fstream>
-#include <streambuf>
-
 #include "ast/SkSLASTPrecision.h"
 #include "SkSLCFGGenerator.h"
 #include "SkSLIRGenerator.h"
@@ -71,17 +68,17 @@ Compiler::Compiler()
     ADD_TYPE(BVec3);
     ADD_TYPE(BVec4);
     ADD_TYPE(Mat2x2);
-    types->addWithoutOwnership("mat2x2", fContext.fMat2x2_Type.get());
+    types->addWithoutOwnership(SkString("mat2x2"), fContext.fMat2x2_Type.get());
     ADD_TYPE(Mat2x3);
     ADD_TYPE(Mat2x4);
     ADD_TYPE(Mat3x2);
     ADD_TYPE(Mat3x3);
-    types->addWithoutOwnership("mat3x3", fContext.fMat3x3_Type.get());
+    types->addWithoutOwnership(SkString("mat3x3"), fContext.fMat3x3_Type.get());
     ADD_TYPE(Mat3x4);
     ADD_TYPE(Mat4x2);
     ADD_TYPE(Mat4x3);
     ADD_TYPE(Mat4x4);
-    types->addWithoutOwnership("mat4x4", fContext.fMat4x4_Type.get());
+    types->addWithoutOwnership(SkString("mat4x4"), fContext.fMat4x4_Type.get());
     ADD_TYPE(GenType);
     ADD_TYPE(GenDType);
     ADD_TYPE(GenIType);
@@ -140,7 +137,7 @@ Compiler::Compiler()
 
     Modifiers::Flag ignored1;
     std::vector<std::unique_ptr<ProgramElement>> ignored2;
-    this->internalConvertProgram(SKSL_INCLUDE, &ignored1, &ignored2);
+    this->internalConvertProgram(SkString(SKSL_INCLUDE), &ignored1, &ignored2);
     fIRGenerator->fSymbolTable->markAllFunctionsBuiltin();
     ASSERT(!fErrorCount);
 }
@@ -289,7 +286,7 @@ void Compiler::scanCFG(const FunctionDefinition& f) {
     for (size_t i = 0; i < cfg.fBlocks.size(); i++) {
         if (i != cfg.fStart && !cfg.fBlocks[i].fEntrances.size() &&
             cfg.fBlocks[i].fNodes.size()) {
-            this->error(cfg.fBlocks[i].fNodes[0].fNode->fPosition, "unreachable");
+            this->error(cfg.fBlocks[i].fNodes[0].fNode->fPosition, SkString("unreachable"));
         }
     }
     if (fErrorCount) {
@@ -318,12 +315,12 @@ void Compiler::scanCFG(const FunctionDefinition& f) {
     // check for missing return
     if (f.fDeclaration.fReturnType != *fContext.fVoid_Type) {
         if (cfg.fBlocks[cfg.fExit].fEntrances.size()) {
-            this->error(f.fPosition, "function can exit without returning a value");
+            this->error(f.fPosition, SkString("function can exit without returning a value"));
         }
     }
 }
 
-void Compiler::internalConvertProgram(std::string text,
+void Compiler::internalConvertProgram(SkString text,
                                       Modifiers::Flag* defaultPrecision,
                                       std::vector<std::unique_ptr<ProgramElement>>* result) {
     Parser parser(text, *fTypes, *this);
@@ -386,7 +383,7 @@ void Compiler::internalConvertProgram(std::string text,
     }
 }
 
-std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, std::string text) {
+std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, SkString text) {
     fErrorText = "";
     fErrorCount = 0;
     fIRGenerator->pushSymbolTable();
@@ -394,10 +391,10 @@ std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, std::strin
     Modifiers::Flag ignored;
     switch (kind) {
         case Program::kVertex_Kind:
-            this->internalConvertProgram(SKSL_VERT_INCLUDE, &ignored, &elements);
+            this->internalConvertProgram(SkString(SKSL_VERT_INCLUDE), &ignored, &elements);
             break;
         case Program::kFragment_Kind:
-            this->internalConvertProgram(SKSL_FRAG_INCLUDE, &ignored, &elements);
+            this->internalConvertProgram(SkString(SKSL_FRAG_INCLUDE), &ignored, &elements);
             break;
     }
     fIRGenerator->fSymbolTable->markAllFunctionsBuiltin();
@@ -410,13 +407,13 @@ std::unique_ptr<Program> Compiler::convertProgram(Program::Kind kind, std::strin
     return result;
 }
 
-void Compiler::error(Position position, std::string msg) {
+void Compiler::error(Position position, SkString msg) {
     fErrorCount++;
     fErrorText += "error: " + position.description() + ": " + msg.c_str() + "\n";
 }
 
-std::string Compiler::errorText() {
-    std::string result = fErrorText;
+SkString Compiler::errorText() {
+    SkString result = fErrorText;
     return result;
 }
 
@@ -430,42 +427,42 @@ void Compiler::writeErrorCount() {
     }
 }
 
-bool Compiler::toSPIRV(Program::Kind kind, const std::string& text, std::ostream& out) {
+bool Compiler::toSPIRV(Program::Kind kind, const SkString& text, SkWStream& out) {
     auto program = this->convertProgram(kind, text);
     if (fErrorCount == 0) {
         SkSL::SPIRVCodeGenerator cg(&fContext);
         cg.generateCode(*program.get(), out);
-        ASSERT(!out.rdstate());
     }
     return fErrorCount == 0;
 }
 
-bool Compiler::toSPIRV(Program::Kind kind, const std::string& text, std::string* out) {
-    std::stringstream buffer;
+bool Compiler::toSPIRV(Program::Kind kind, const SkString& text, SkString* out) {
+    SkDynamicMemoryWStream buffer;
     bool result = this->toSPIRV(kind, text, buffer);
     if (result) {
-        *out = buffer.str();
+        sk_sp<SkData> data(buffer.detachAsData());
+        *out = SkString((const char*) data->data(), data->size());
     }
     return result;
 }
 
-bool Compiler::toGLSL(Program::Kind kind, const std::string& text, const GrGLSLCaps& caps,
-                      std::ostream& out) {
+bool Compiler::toGLSL(Program::Kind kind, const SkString& text, const GrGLSLCaps& caps,
+                      SkWStream& out) {
     auto program = this->convertProgram(kind, text);
     if (fErrorCount == 0) {
         SkSL::GLSLCodeGenerator cg(&fContext, &caps);
         cg.generateCode(*program.get(), out);
-        ASSERT(!out.rdstate());
     }
     return fErrorCount == 0;
 }
 
-bool Compiler::toGLSL(Program::Kind kind, const std::string& text, const GrGLSLCaps& caps,
-                      std::string* out) {
-    std::stringstream buffer;
+bool Compiler::toGLSL(Program::Kind kind, const SkString& text, const GrGLSLCaps& caps,
+                      SkString* out) {
+    SkDynamicMemoryWStream buffer;
     bool result = this->toGLSL(kind, text, caps, buffer);
     if (result) {
-        *out = buffer.str();
+        sk_sp<SkData> data(buffer.detachAsData());
+        *out = SkString((const char*) data->data(), data->size());
     }
     return result;
 }
index e69db59..e1bc052 100644 (file)
@@ -37,21 +37,21 @@ public:
 
     ~Compiler();
 
-    std::unique_ptr<Program> convertProgram(Program::Kind kind, std::string text);
+    std::unique_ptr<Program> convertProgram(Program::Kind kind, SkString text);
 
-    bool toSPIRV(Program::Kind kind, const std::string& text, std::ostream& out);
+    bool toSPIRV(Program::Kind kind, const SkString& text, SkWStream& out);
     
-    bool toSPIRV(Program::Kind kind, const std::string& text, std::string* out);
+    bool toSPIRV(Program::Kind kind, const SkString& text, SkString* out);
 
-    bool toGLSL(Program::Kind kind, const std::string& text, const GrGLSLCaps& caps,
-                std::ostream& out);
+    bool toGLSL(Program::Kind kind, const SkString& text, const GrGLSLCaps& caps,
+                SkWStream& out);
     
-    bool toGLSL(Program::Kind kind, const std::string& text, const GrGLSLCaps& caps,
-                std::string* out);
+    bool toGLSL(Program::Kind kind, const SkString& text, const GrGLSLCaps& caps,
+                SkString* out);
 
-    void error(Position position, std::string msg) override;
+    void error(Position position, SkString msg) override;
 
-    std::string errorText();
+    SkString errorText();
 
     void writeErrorCount();
 
@@ -66,17 +66,17 @@ private:
 
     void scanCFG(const FunctionDefinition& f);
 
-    void internalConvertProgram(std::string text,
+    void internalConvertProgram(SkString text,
                                 Modifiers::Flag* defaultPrecision,
                                 std::vector<std::unique_ptr<ProgramElement>>* result);
 
     std::shared_ptr<SymbolTable> fTypes;
     IRGenerator* fIRGenerator;
-    std::string fSkiaVertText; // FIXME store parsed version instead
+    SkString fSkiaVertText; // FIXME store parsed version instead
 
     Context fContext;
     int fErrorCount;
-    std::string fErrorText;
+    SkString fErrorText;
 };
 
 } // namespace
index a42a4cc..05e08f2 100644 (file)
@@ -19,114 +19,120 @@ namespace SkSL {
 class Context {
 public:
     Context()
-    : fInvalid_Type(new Type("<INVALID>"))
-    , fVoid_Type(new Type("void"))
-    , fDouble_Type(new Type("double", true))
-    , fDVec2_Type(new Type("dvec2", *fDouble_Type, 2))
-    , fDVec3_Type(new Type("dvec3", *fDouble_Type, 3))
-    , fDVec4_Type(new Type("dvec4", *fDouble_Type, 4))
-    , fFloat_Type(new Type("float", true, { fDouble_Type.get() }))
-    , fVec2_Type(new Type("vec2", *fFloat_Type, 2))
-    , fVec3_Type(new Type("vec3", *fFloat_Type, 3))
-    , fVec4_Type(new Type("vec4", *fFloat_Type, 4))
-    , fUInt_Type(new Type("uint", true, { fFloat_Type.get(), fDouble_Type.get() }))
-    , fUVec2_Type(new Type("uvec2", *fUInt_Type, 2))
-    , fUVec3_Type(new Type("uvec3", *fUInt_Type, 3))
-    , fUVec4_Type(new Type("uvec4", *fUInt_Type, 4))
-    , fInt_Type(new Type("int", true, { fUInt_Type.get(), fFloat_Type.get(), fDouble_Type.get() }))
-    , fIVec2_Type(new Type("ivec2", *fInt_Type, 2))
-    , fIVec3_Type(new Type("ivec3", *fInt_Type, 3))
-    , fIVec4_Type(new Type("ivec4", *fInt_Type, 4))
-    , fBool_Type(new Type("bool", false))
-    , fBVec2_Type(new Type("bvec2", *fBool_Type, 2))
-    , fBVec3_Type(new Type("bvec3", *fBool_Type, 3))
-    , fBVec4_Type(new Type("bvec4", *fBool_Type, 4))
-    , fMat2x2_Type(new Type("mat2",   *fFloat_Type, 2, 2))
-    , fMat2x3_Type(new Type("mat2x3", *fFloat_Type, 2, 3))
-    , fMat2x4_Type(new Type("mat2x4", *fFloat_Type, 2, 4))
-    , fMat3x2_Type(new Type("mat3x2", *fFloat_Type, 3, 2))
-    , fMat3x3_Type(new Type("mat3",   *fFloat_Type, 3, 3))
-    , fMat3x4_Type(new Type("mat3x4", *fFloat_Type, 3, 4))
-    , fMat4x2_Type(new Type("mat4x2", *fFloat_Type, 4, 2))
-    , fMat4x3_Type(new Type("mat4x3", *fFloat_Type, 4, 3))
-    , fMat4x4_Type(new Type("mat4",   *fFloat_Type, 4, 4))
-    , fDMat2x2_Type(new Type("dmat2",   *fFloat_Type, 2, 2))
-    , fDMat2x3_Type(new Type("dmat2x3", *fFloat_Type, 2, 3))
-    , fDMat2x4_Type(new Type("dmat2x4", *fFloat_Type, 2, 4))
-    , fDMat3x2_Type(new Type("dmat3x2", *fFloat_Type, 3, 2))
-    , fDMat3x3_Type(new Type("dmat3",   *fFloat_Type, 3, 3))
-    , fDMat3x4_Type(new Type("dmat3x4", *fFloat_Type, 3, 4))
-    , fDMat4x2_Type(new Type("dmat4x2", *fFloat_Type, 4, 2))
-    , fDMat4x3_Type(new Type("dmat4x3", *fFloat_Type, 4, 3))
-    , fDMat4x4_Type(new Type("dmat4",   *fFloat_Type, 4, 4))
-    , fSampler1D_Type(new Type("sampler1D", SpvDim1D, false, false, false, true))
-    , fSampler2D_Type(new Type("sampler2D", SpvDim2D, false, false, false, true))
-    , fSampler3D_Type(new Type("sampler3D", SpvDim3D, false, false, false, true))
-    , fSamplerExternalOES_Type(new Type("samplerExternalOES", SpvDim2D, false, false, false, true))
-    , fSamplerCube_Type(new Type("samplerCube"))
-    , fSampler2DRect_Type(new Type("sampler2DRect"))
-    , fSampler1DArray_Type(new Type("sampler1DArray"))
-    , fSampler2DArray_Type(new Type("sampler2DArray"))
-    , fSamplerCubeArray_Type(new Type("samplerCubeArray"))
-    , fSamplerBuffer_Type(new Type("samplerBuffer"))
-    , fSampler2DMS_Type(new Type("sampler2DMS"))
-    , fSampler2DMSArray_Type(new Type("sampler2DMSArray"))
-    , fSampler1DShadow_Type(new Type("sampler1DShadow"))
-    , fSampler2DShadow_Type(new Type("sampler2DShadow"))
-    , fSamplerCubeShadow_Type(new Type("samplerCubeShadow"))
-    , fSampler2DRectShadow_Type(new Type("sampler2DRectShadow"))
-    , fSampler1DArrayShadow_Type(new Type("sampler1DArrayShadow"))
-    , fSampler2DArrayShadow_Type(new Type("sampler2DArrayShadow"))
-    , fSamplerCubeArrayShadow_Type(new Type("samplerCubeArrayShadow"))
+    : fInvalid_Type(new Type(SkString("<INVALID>")))
+    , fVoid_Type(new Type(SkString("void")))
+    , fDouble_Type(new Type(SkString("double"), true))
+    , fDVec2_Type(new Type(SkString("dvec2"), *fDouble_Type, 2))
+    , fDVec3_Type(new Type(SkString("dvec3"), *fDouble_Type, 3))
+    , fDVec4_Type(new Type(SkString("dvec4"), *fDouble_Type, 4))
+    , fFloat_Type(new Type(SkString("float"), true, { fDouble_Type.get() }))
+    , fVec2_Type(new Type(SkString("vec2"), *fFloat_Type, 2))
+    , fVec3_Type(new Type(SkString("vec3"), *fFloat_Type, 3))
+    , fVec4_Type(new Type(SkString("vec4"), *fFloat_Type, 4))
+    , fUInt_Type(new Type(SkString("uint"), true, { fFloat_Type.get(), fDouble_Type.get() }))
+    , fUVec2_Type(new Type(SkString("uvec2"), *fUInt_Type, 2))
+    , fUVec3_Type(new Type(SkString("uvec3"), *fUInt_Type, 3))
+    , fUVec4_Type(new Type(SkString("uvec4"), *fUInt_Type, 4))
+    , fInt_Type(new Type(SkString("int"), true, { fUInt_Type.get(), fFloat_Type.get(),
+                                                  fDouble_Type.get() }))
+    , fIVec2_Type(new Type(SkString("ivec2"), *fInt_Type, 2))
+    , fIVec3_Type(new Type(SkString("ivec3"), *fInt_Type, 3))
+    , fIVec4_Type(new Type(SkString("ivec4"), *fInt_Type, 4))
+    , fBool_Type(new Type(SkString("bool"), false))
+    , fBVec2_Type(new Type(SkString("bvec2"), *fBool_Type, 2))
+    , fBVec3_Type(new Type(SkString("bvec3"), *fBool_Type, 3))
+    , fBVec4_Type(new Type(SkString("bvec4"), *fBool_Type, 4))
+    , fMat2x2_Type(new Type(SkString("mat2"),   *fFloat_Type, 2, 2))
+    , fMat2x3_Type(new Type(SkString("mat2x3"), *fFloat_Type, 2, 3))
+    , fMat2x4_Type(new Type(SkString("mat2x4"), *fFloat_Type, 2, 4))
+    , fMat3x2_Type(new Type(SkString("mat3x2"), *fFloat_Type, 3, 2))
+    , fMat3x3_Type(new Type(SkString("mat3"),   *fFloat_Type, 3, 3))
+    , fMat3x4_Type(new Type(SkString("mat3x4"), *fFloat_Type, 3, 4))
+    , fMat4x2_Type(new Type(SkString("mat4x2"), *fFloat_Type, 4, 2))
+    , fMat4x3_Type(new Type(SkString("mat4x3"), *fFloat_Type, 4, 3))
+    , fMat4x4_Type(new Type(SkString("mat4"),   *fFloat_Type, 4, 4))
+    , fDMat2x2_Type(new Type(SkString("dmat2"),   *fFloat_Type, 2, 2))
+    , fDMat2x3_Type(new Type(SkString("dmat2x3"), *fFloat_Type, 2, 3))
+    , fDMat2x4_Type(new Type(SkString("dmat2x4"), *fFloat_Type, 2, 4))
+    , fDMat3x2_Type(new Type(SkString("dmat3x2"), *fFloat_Type, 3, 2))
+    , fDMat3x3_Type(new Type(SkString("dmat3"),   *fFloat_Type, 3, 3))
+    , fDMat3x4_Type(new Type(SkString("dmat3x4"), *fFloat_Type, 3, 4))
+    , fDMat4x2_Type(new Type(SkString("dmat4x2"), *fFloat_Type, 4, 2))
+    , fDMat4x3_Type(new Type(SkString("dmat4x3"), *fFloat_Type, 4, 3))
+    , fDMat4x4_Type(new Type(SkString("dmat4"),   *fFloat_Type, 4, 4))
+    , fSampler1D_Type(new Type(SkString("sampler1D"), SpvDim1D, false, false, false, true))
+    , fSampler2D_Type(new Type(SkString("sampler2D"), SpvDim2D, false, false, false, true))
+    , fSampler3D_Type(new Type(SkString("sampler3D"), SpvDim3D, false, false, false, true))
+    , fSamplerExternalOES_Type(new Type(SkString("samplerExternalOES"), SpvDim2D, false, false,
+                                        false, true))
+    , fSamplerCube_Type(new Type(SkString("samplerCube")))
+    , fSampler2DRect_Type(new Type(SkString("sampler2DRect")))
+    , fSampler1DArray_Type(new Type(SkString("sampler1DArray")))
+    , fSampler2DArray_Type(new Type(SkString("sampler2DArray")))
+    , fSamplerCubeArray_Type(new Type(SkString("samplerCubeArray")))
+    , fSamplerBuffer_Type(new Type(SkString("samplerBuffer")))
+    , fSampler2DMS_Type(new Type(SkString("sampler2DMS")))
+    , fSampler2DMSArray_Type(new Type(SkString("sampler2DMSArray")))
+    , fSampler1DShadow_Type(new Type(SkString("sampler1DShadow")))
+    , fSampler2DShadow_Type(new Type(SkString("sampler2DShadow")))
+    , fSamplerCubeShadow_Type(new Type(SkString("samplerCubeShadow")))
+    , fSampler2DRectShadow_Type(new Type(SkString("sampler2DRectShadow")))
+    , fSampler1DArrayShadow_Type(new Type(SkString("sampler1DArrayShadow")))
+    , fSampler2DArrayShadow_Type(new Type(SkString("sampler2DArrayShadow")))
+    , fSamplerCubeArrayShadow_Type(new Type(SkString("samplerCubeArrayShadow")))
 
     // Related to below FIXME, gsampler*s don't currently expand to cover integer case.
-    , fISampler2D_Type(new Type("isampler2D", SpvDim2D, false, false, false, true))
+    , fISampler2D_Type(new Type(SkString("isampler2D"), SpvDim2D, false, false, false, true))
 
     // FIXME express these as "gimage2D" that expand to image2D, iimage2D, and uimage2D.
-    , fImage2D_Type(new Type("image2D", SpvDim2D, false, false, false, true))
-    , fIImage2D_Type(new Type("iimage2D", SpvDim2D, false, false, false, true))
+    , fImage2D_Type(new Type(SkString("image2D"), SpvDim2D, false, false, false, true))
+    , fIImage2D_Type(new Type(SkString("iimage2D"), SpvDim2D, false, false, false, true))
 
     // FIXME figure out what we're supposed to do with the gsampler et al. types)
-    , fGSampler1D_Type(new Type("$gsampler1D", static_type(*fSampler1D_Type)))
-    , fGSampler2D_Type(new Type("$gsampler2D", static_type(*fSampler2D_Type)))
-    , fGSampler3D_Type(new Type("$gsampler3D", static_type(*fSampler3D_Type)))
-    , fGSamplerCube_Type(new Type("$gsamplerCube", static_type(*fSamplerCube_Type)))
-    , fGSampler2DRect_Type(new Type("$gsampler2DRect", static_type(*fSampler2DRect_Type)))
-    , fGSampler1DArray_Type(new Type("$gsampler1DArray", static_type(*fSampler1DArray_Type)))
-    , fGSampler2DArray_Type(new Type("$gsampler2DArray", static_type(*fSampler2DArray_Type)))
-    , fGSamplerCubeArray_Type(new Type("$gsamplerCubeArray", static_type(*fSamplerCubeArray_Type)))
-    , fGSamplerBuffer_Type(new Type("$gsamplerBuffer", static_type(*fSamplerBuffer_Type)))
-    , fGSampler2DMS_Type(new Type("$gsampler2DMS", static_type(*fSampler2DMS_Type)))
-    , fGSampler2DMSArray_Type(new Type("$gsampler2DMSArray", static_type(*fSampler2DMSArray_Type)))
-    , fGSampler2DArrayShadow_Type(new Type("$gsampler2DArrayShadow", 
+    , fGSampler1D_Type(new Type(SkString("$gsampler1D"), static_type(*fSampler1D_Type)))
+    , fGSampler2D_Type(new Type(SkString("$gsampler2D"), static_type(*fSampler2D_Type)))
+    , fGSampler3D_Type(new Type(SkString("$gsampler3D"), static_type(*fSampler3D_Type)))
+    , fGSamplerCube_Type(new Type(SkString("$gsamplerCube"), static_type(*fSamplerCube_Type)))
+    , fGSampler2DRect_Type(new Type(SkString("$gsampler2DRect"), static_type(*fSampler2DRect_Type)))
+    , fGSampler1DArray_Type(new Type(SkString("$gsampler1DArray"),
+                                     static_type(*fSampler1DArray_Type)))
+    , fGSampler2DArray_Type(new Type(SkString("$gsampler2DArray"),
+                                     static_type(*fSampler2DArray_Type)))
+    , fGSamplerCubeArray_Type(new Type(SkString("$gsamplerCubeArray"),
+                                       static_type(*fSamplerCubeArray_Type)))
+    , fGSamplerBuffer_Type(new Type(SkString("$gsamplerBuffer"), static_type(*fSamplerBuffer_Type)))
+    , fGSampler2DMS_Type(new Type(SkString("$gsampler2DMS"), static_type(*fSampler2DMS_Type)))
+    , fGSampler2DMSArray_Type(new Type(SkString("$gsampler2DMSArray"),
+                                       static_type(*fSampler2DMSArray_Type)))
+    , fGSampler2DArrayShadow_Type(new Type(SkString("$gsampler2DArrayShadow"),
                                            static_type(*fSampler2DArrayShadow_Type)))
-    , fGSamplerCubeArrayShadow_Type(new Type("$gsamplerCubeArrayShadow",
+    , fGSamplerCubeArrayShadow_Type(new Type(SkString("$gsamplerCubeArrayShadow"),
                                              static_type(*fSamplerCubeArrayShadow_Type)))
-    , fGenType_Type(new Type("$genType", { fFloat_Type.get(), fVec2_Type.get(), fVec3_Type.get(), 
-                                           fVec4_Type.get() }))
-    , fGenDType_Type(new Type("$genDType", { fDouble_Type.get(), fDVec2_Type.get(), 
-                                             fDVec3_Type.get(), fDVec4_Type.get() }))
-    , fGenIType_Type(new Type("$genIType", { fInt_Type.get(), fIVec2_Type.get(), fIVec3_Type.get(), 
-                                             fIVec4_Type.get() }))
-    , fGenUType_Type(new Type("$genUType", { fUInt_Type.get(), fUVec2_Type.get(), fUVec3_Type.get(), 
-                                             fUVec4_Type.get() }))
-    , fGenBType_Type(new Type("$genBType", { fBool_Type.get(), fBVec2_Type.get(), fBVec3_Type.get(), 
-                                             fBVec4_Type.get() }))
-    , fMat_Type(new Type("$mat"))
-    , fVec_Type(new Type("$vec", { fInvalid_Type.get(), fVec2_Type.get(), fVec3_Type.get(),
-                                   fVec4_Type.get() }))
-    , fGVec_Type(new Type("$gvec"))
-    , fGVec2_Type(new Type("$gvec2"))
-    , fGVec3_Type(new Type("$gvec3"))
-    , fGVec4_Type(new Type("$gvec4", static_type(*fVec4_Type)))
-    , fDVec_Type(new Type("$dvec", { fInvalid_Type.get(), fDVec2_Type.get(), fDVec3_Type.get(),
-                                     fDVec4_Type.get() }))
-    , fIVec_Type(new Type("$ivec", { fInvalid_Type.get(), fIVec2_Type.get(), fIVec3_Type.get(),
-                                     fIVec4_Type.get() }))
-    , fUVec_Type(new Type("$uvec", { fInvalid_Type.get(), fUVec2_Type.get(), fUVec3_Type.get(),
-                                     fUVec4_Type.get() }))
-    , fBVec_Type(new Type("$bvec", { fInvalid_Type.get(), fBVec2_Type.get(), fBVec3_Type.get(), 
-                                     fBVec4_Type.get() }))
+    , fGenType_Type(new Type(SkString("$genType"), { fFloat_Type.get(), fVec2_Type.get(),
+                                                     fVec3_Type.get(), fVec4_Type.get() }))
+    , fGenDType_Type(new Type(SkString("$genDType"), { fDouble_Type.get(), fDVec2_Type.get(),
+                                                       fDVec3_Type.get(), fDVec4_Type.get() }))
+    , fGenIType_Type(new Type(SkString("$genIType"), { fInt_Type.get(), fIVec2_Type.get(),
+                                                       fIVec3_Type.get(), fIVec4_Type.get() }))
+    , fGenUType_Type(new Type(SkString("$genUType"), { fUInt_Type.get(), fUVec2_Type.get(),
+                                                       fUVec3_Type.get(), fUVec4_Type.get() }))
+    , fGenBType_Type(new Type(SkString("$genBType"), { fBool_Type.get(), fBVec2_Type.get(),
+                                                       fBVec3_Type.get(), fBVec4_Type.get() }))
+    , fMat_Type(new Type(SkString("$mat")))
+    , fVec_Type(new Type(SkString("$vec"), { fInvalid_Type.get(), fVec2_Type.get(),
+                                             fVec3_Type.get(), fVec4_Type.get() }))
+    , fGVec_Type(new Type(SkString("$gvec")))
+    , fGVec2_Type(new Type(SkString("$gvec2")))
+    , fGVec3_Type(new Type(SkString("$gvec3")))
+    , fGVec4_Type(new Type(SkString("$gvec4"), static_type(*fVec4_Type)))
+    , fDVec_Type(new Type(SkString("$dvec"), { fInvalid_Type.get(), fDVec2_Type.get(),
+                                              fDVec3_Type.get(), fDVec4_Type.get() }))
+    , fIVec_Type(new Type(SkString("$ivec"), { fInvalid_Type.get(), fIVec2_Type.get(),
+                                               fIVec3_Type.get(), fIVec4_Type.get() }))
+    , fUVec_Type(new Type(SkString("$uvec"), { fInvalid_Type.get(), fUVec2_Type.get(),
+                                               fUVec3_Type.get(), fUVec4_Type.get() }))
+    , fBVec_Type(new Type(SkString("$bvec"), { fInvalid_Type.get(), fBVec2_Type.get(),
+                                               fBVec3_Type.get(), fBVec4_Type.get() }))
     , fDefined_Expression(new Defined(*fInvalid_Type)) {}
 
     static std::vector<const Type*> static_type(const Type& t) {
@@ -252,8 +258,8 @@ private:
         Defined(const Type& type)
         : INHERITED(Position(), kDefined_Kind, type) {}
 
-        virtual std::string description() const override {
-            return "<defined>";
+        virtual SkString description() const override {
+            return SkString("<defined>");
         }
 
         typedef Expression INHERITED;
index 26b4471..585a97c 100644 (file)
@@ -19,7 +19,11 @@ class ErrorReporter {
 public:
     virtual ~ErrorReporter() {}
 
-    virtual void error(Position position, std::string msg) = 0;
+    void error(Position position, const char* msg) {
+        this->error(position, SkString(msg));
+    }
+
+    virtual void error(Position position, SkString msg) = 0;
 };
 
 } // namespace
index 1252f86..5536261 100644 (file)
@@ -27,24 +27,24 @@ void GLSLCodeGenerator::write(const char* s) {
     }
     if (fAtLineStart) {
         for (int i = 0; i < fIndentation; i++) {
-            *fOut << "    ";
+            fOut->writeText("    ");
         }
     }
-    *fOut << s;
+    fOut->writeText(s);
     fAtLineStart = false;
 }
 
 void GLSLCodeGenerator::writeLine(const char* s) {
     this->write(s);
-    *fOut << "\n";
+    fOut->writeText("\n");
     fAtLineStart = true;
 }
 
-void GLSLCodeGenerator::write(const std::string& s) {
+void GLSLCodeGenerator::write(const SkString& s) {
     this->write(s.c_str());
 }
 
-void GLSLCodeGenerator::writeLine(const std::string& s) {
+void GLSLCodeGenerator::writeLine(const SkString& s) {
     this->writeLine(s.c_str());
 }
 
@@ -138,8 +138,8 @@ static bool is_abs(Expression& expr) {
 // Tegra3 compiler bug.
 void GLSLCodeGenerator::writeMinAbsHack(Expression& absExpr, Expression& otherExpr) {
     ASSERT(!fCaps.canUseMinAndAbsTogether());
-    std::string tmpVar1 = "minAbsHackVar" + to_string(fVarCount++);
-    std::string tmpVar2 = "minAbsHackVar" + to_string(fVarCount++);
+    SkString tmpVar1 = "minAbsHackVar" + to_string(fVarCount++);
+    SkString tmpVar2 = "minAbsHackVar" + to_string(fVarCount++);
     this->fFunctionHeader += "    " + absExpr.fType.name() + " " + tmpVar1 + ";\n";
     this->fFunctionHeader += "    " + otherExpr.fType.name() + " " + tmpVar2 + ";\n";
     this->write("((" + tmpVar1 + " = ");
@@ -179,7 +179,9 @@ void GLSLCodeGenerator::writeFunctionCall(const FunctionCall& c) {
     if (!fFoundDerivatives && (c.fFunction.fName == "dFdx" || c.fFunction.fName == "dFdy") && 
         c.fFunction.fBuiltin && fCaps.shaderDerivativeExtensionString()) {
         ASSERT(fCaps.shaderDerivativeSupport());
-        fHeader << "#extension " << fCaps.shaderDerivativeExtensionString() << " : require\n";
+        fHeader.writeText("#extension ");
+        fHeader.writeText(fCaps.shaderDerivativeExtensionString());
+        fHeader.writeText(" : require\n");
         fFoundDerivatives = true;
     }
     this->write(c.fFunction.fName + "(");
@@ -373,8 +375,8 @@ void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
     this->writeLine(") {");
 
     fFunctionHeader = "";
-    std::ostream* oldOut = fOut;
-    std::stringstream buffer;
+    SkWStream* oldOut = fOut;
+    SkDynamicMemoryWStream buffer;
     fOut = &buffer;
     fIndentation++;
     for (const auto& s : f.fBody->fStatements) {
@@ -386,7 +388,8 @@ void GLSLCodeGenerator::writeFunction(const FunctionDefinition& f) {
 
     fOut = oldOut;
     this->write(fFunctionHeader);
-    this->write(buffer.str());
+    sk_sp<SkData> data(buffer.detachAsData());
+    this->write(SkString((const char*) data->data(), data->size()));
 }
 
 void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers, 
@@ -397,8 +400,8 @@ void GLSLCodeGenerator::writeModifiers(const Modifiers& modifiers,
     if (modifiers.fFlags & Modifiers::kFlat_Flag) {
         this->write("flat ");
     }
-    std::string layout = modifiers.fLayout.description();
-    if (layout.length()) {
+    SkString layout = modifiers.fLayout.description();
+    if (layout.size()) {
         this->write(layout + " ");
     }
     if ((modifiers.fFlags & Modifiers::kIn_Flag) && 
@@ -457,11 +460,11 @@ void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool g
     ASSERT(decl.fVars.size() > 0);
     this->writeModifiers(decl.fVars[0].fVar->fModifiers, global);
     this->writeType(decl.fBaseType);
-    std::string separator = " ";
+    SkString separator(" ");
     for (const auto& var : decl.fVars) {
         ASSERT(var.fVar->fModifiers == decl.fVars[0].fVar->fModifiers);
         this->write(separator);
-        separator = ", ";
+        separator = SkString(", ");
         this->write(var.fVar->fName);
         for (const auto& size : var.fSizes) {
             this->write("[");
@@ -476,7 +479,9 @@ void GLSLCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, bool g
         }
         if (!fFoundImageDecl && var.fVar->fType == *fContext.fImage2D_Type) {
             if (fCaps.imageLoadStoreExtensionString()) {
-                fHeader << "#extension " << fCaps.imageLoadStoreExtensionString() << " : require\n";
+                fHeader.writeText("#extension ");
+                fHeader.writeText(fCaps.imageLoadStoreExtensionString());
+                fHeader.writeText(" : require\n");
             }
             fFoundImageDecl = true;
         }
@@ -589,7 +594,7 @@ void GLSLCodeGenerator::writeReturnStatement(const ReturnStatement& r) {
     this->write(";");
 }
 
-void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out) {
+void GLSLCodeGenerator::generateCode(const Program& program, SkWStream& out) {
     ASSERT(fOut == nullptr);
     fOut = &fHeader;
     fProgramKind = program.fKind;
@@ -600,7 +605,7 @@ void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out)
             this->writeExtension((Extension&) *e);
         }
     }
-    std::stringstream body;
+    SkDynamicMemoryWStream body;
     fOut = &body;
     if (fCaps.usesPrecisionModifiers()) {
         this->write("precision ");
@@ -660,8 +665,8 @@ void GLSLCodeGenerator::generateCode(const Program& program, std::ostream& out)
     }
     fOut = nullptr;
 
-    out << fHeader.str();
-    out << body.str();
+    write_data(*fHeader.detachAsData(), out);
+    write_data(*body.detachAsData(), out);
 }
 
 }
index 16d6192..b8cb34e 100644 (file)
@@ -12,6 +12,7 @@
 #include <tuple>
 #include <unordered_map>
 
+#include "SkStream.h"
 #include "glsl/GrGLSLCaps.h"
 #include "SkSLCodeGenerator.h"
 #include "ir/SkSLBinaryExpression.h"
@@ -75,7 +76,7 @@ public:
     : fContext(*context)
     , fCaps(*caps) {}
 
-    void generateCode(const Program& program, std::ostream& out) override;
+    void generateCode(const Program& program, SkWStream& out) override;
 
 private:
     void write(const char* s);
@@ -84,9 +85,9 @@ private:
 
     void writeLine(const char* s);
 
-    void write(const std::string& s);
+    void write(const SkString& s);
 
-    void writeLine(const std::string& s);
+    void writeLine(const SkString& s);
 
     void writeType(const Type& type);
 
@@ -156,9 +157,9 @@ private:
 
     const Context& fContext;
     const GrGLSLCaps& fCaps;
-    std::ostream* fOut = nullptr;
-    std::stringstream fHeader;
-    std::string fFunctionHeader;
+    SkWStream* fOut = nullptr;
+    SkDynamicMemoryWStream fHeader;
+    SkString fFunctionHeader;
     Program::Kind fProgramKind;
     int fVarCount = 0;
     int fIndentation = 0;
index 1a4c775..245c72f 100644 (file)
@@ -173,7 +173,7 @@ std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTVa
                 if (!size) {
                     return nullptr;
                 }
-                std::string name = type->fName;
+                SkString name = type->fName;
                 uint64_t count;
                 if (size->fKind == Expression::kIntLiteral_Kind) {
                     count = ((IntLiteral&) *size).fValue;
@@ -204,7 +204,7 @@ std::unique_ptr<VarDeclarations> IRGenerator::convertVarDeclarations(const ASTVa
             }
             value = this->coerce(std::move(value), *type);
         }
-        if (storage == Variable::kGlobal_Storage && "sk_FragColor" == varDecl.fName && 
+        if (storage == Variable::kGlobal_Storage && varDecl.fName == SkString("sk_FragColor") && 
             (*fSymbolTable)[varDecl.fName]) {
             // already defined, ignore
         } else if (storage == Variable::kGlobal_Storage && (*fSymbolTable)[varDecl.fName] &&
@@ -397,12 +397,12 @@ std::unique_ptr<FunctionDefinition> IRGenerator::convertFunction(const ASTFuncti
         }
         for (int j = (int) param->fSizes.size() - 1; j >= 0; j--) {
             int size = param->fSizes[j];
-            std::string name = type->name() + "[" + to_string(size) + "]";
+            SkString name = type->name() + "[" + to_string(size) + "]";
             Type* newType = new Type(std::move(name), Type::kArray_Kind, *type, size);
             fSymbolTable->takeOwnership(newType);
             type = newType;
         }
-        std::string name = param->fName;
+        SkString name = param->fName;
         Modifiers modifiers = this->convertModifiers(param->fModifiers);
         Position pos = param->fPosition;
         Variable* var = new Variable(pos, modifiers, std::move(name), *type,
@@ -523,10 +523,10 @@ std::unique_ptr<InterfaceBlock> IRGenerator::convertInterfaceBlock(const ASTInte
     }
     Type* type = new Type(intf.fInterfaceName, fields);
     fSymbolTable->takeOwnership(type);
-    std::string name = intf.fValueName.length() > 0 ? intf.fValueName : intf.fInterfaceName;
+    SkString name = intf.fValueName.size() > 0 ? intf.fValueName : intf.fInterfaceName;
     Variable* var = new Variable(intf.fPosition, mods, name, *type, Variable::kGlobal_Storage);
     fSymbolTable->takeOwnership(var);
-    if (intf.fValueName.length()) {
+    if (intf.fValueName.size()) {
         old->addWithoutOwnership(intf.fValueName, var);
     } else {
         for (size_t i = 0; i < fields.size(); i++) {
@@ -966,7 +966,7 @@ std::unique_ptr<Expression> IRGenerator::call(Position position,
                                               const FunctionDeclaration& function, 
                                               std::vector<std::unique_ptr<Expression>> arguments) {
     if (function.fParameters.size() != arguments.size()) {
-        std::string msg = "call to '" + function.fName + "' expected " + 
+        SkString msg = "call to '" + function.fName + "' expected " + 
                                  to_string((uint64_t) function.fParameters.size()) + 
                                  " argument";
         if (function.fParameters.size() != 1) {
@@ -979,8 +979,8 @@ std::unique_ptr<Expression> IRGenerator::call(Position position,
     std::vector<const Type*> types;
     const Type* returnType;
     if (!function.determineFinalTypes(arguments, &types, &returnType)) {
-        std::string msg = "no match for " + function.fName + "(";
-        std::string separator = "";
+        SkString msg = "no match for " + function.fName + "(";
+        SkString separator;
         for (size_t i = 0; i < arguments.size(); i++) {
             msg += separator;
             separator = ", ";
@@ -1058,8 +1058,8 @@ std::unique_ptr<Expression> IRGenerator::call(Position position,
         if (best) {
             return this->call(position, *best, std::move(arguments));
         }
-        std::string msg = "no match for " + ref->fFunctions[0]->fName + "(";
-        std::string separator = "";
+        SkString msg = "no match for " + ref->fFunctions[0]->fName + "(";
+        SkString separator;
         for (size_t i = 0; i < arguments.size(); i++) {
             msg += separator;
             separator = ", ";
@@ -1267,7 +1267,7 @@ std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression
 }
 
 std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression> base,
-                                                      const std::string& field) {
+                                                      const SkString& field) {
     auto fields = base->fType.fields();
     for (size_t i = 0; i < fields.size(); i++) {
         if (fields[i].fName == field) {
@@ -1280,14 +1280,14 @@ std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression
 }
 
 std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expression> base,
-                                                        const std::string& fields) {
+                                                        const SkString& fields) {
     if (base->fType.kind() != Type::kVector_Kind) {
         fErrors.error(base->fPosition, "cannot swizzle type '" + base->fType.description() + "'");
         return nullptr;
     }
     std::vector<int> swizzleComponents;
-    for (char c : fields) {
-        switch (c) {
+    for (size_t i = 0; i < fields.size(); i++) {
+        switch (fields[i]) {
             case 'x': // fall through
             case 'r': // fall through
             case 's': 
@@ -1318,8 +1318,8 @@ std::unique_ptr<Expression> IRGenerator::convertSwizzle(std::unique_ptr<Expressi
                 }
                 // fall through
             default:
-                fErrors.error(base->fPosition, "invalid swizzle component '" + std::string(1, c) +
-                                               "'");
+                fErrors.error(base->fPosition, SkStringPrintf("invalid swizzle component '%c'",
+                                                              fields[i]));
                 return nullptr;
         }
     }
index 036f242..d7bd59a 100644 (file)
@@ -107,9 +107,9 @@ private:
     std::unique_ptr<Statement> convertReturn(const ASTReturnStatement& r);
     std::unique_ptr<Expression> convertSuffixExpression(const ASTSuffixExpression& expression);
     std::unique_ptr<Expression> convertField(std::unique_ptr<Expression> base, 
-                                             const std::string& field);
+                                             const SkString& field);
     std::unique_ptr<Expression> convertSwizzle(std::unique_ptr<Expression> base,
-                                               const std::string& fields);
+                                               const SkString& fields);
     std::unique_ptr<Expression> convertTernaryExpression(const ASTTernaryExpression& expression);
     std::unique_ptr<Statement> convertVarDeclarationStatement(const ASTVarDeclarationStatement& s);
     std::unique_ptr<Statement> convertWhile(const ASTWhileStatement& w);
index 3658992..d9fc814 100644 (file)
 #include "SkSLCompiler.h"
 #include "GrContextOptions.h"
 
-bool endsWith(const std::string& s, const std::string& ending) {
-    if (s.length() >= ending.length()) {
-        return (0 == s.compare(s.length() - ending.length(), ending.length(), ending));
-    }
-    return false;
-}
-
 /**
  * Very simple standalone executable to facilitate testing.
  */
@@ -37,35 +30,36 @@ int main(int argc, const char** argv) {
     }
 
     std::ifstream in(argv[1]);
-    std::string text((std::istreambuf_iterator<char>(in)),
-                     std::istreambuf_iterator<char>());
+    std::string stdText((std::istreambuf_iterator<char>(in)),
+                        std::istreambuf_iterator<char>());
+    SkString text(stdText.c_str());
     if (in.rdstate()) {
         printf("error reading '%s'\n", argv[1]);
         exit(2);
     }
-    std::string name(argv[2]);
-    if (endsWith(name, ".spirv")) {
-        std::ofstream out(argv[2], std::ofstream::binary);
+    SkString name(argv[2]);
+    if (name.endsWith(".spirv")) {
+        SkFILEWStream out(argv[2]);
         SkSL::Compiler compiler;
+        if (!out.isValid()) {
+            printf("error writing '%s'\n", argv[2]);
+            exit(4);
+        }
         if (!compiler.toSPIRV(kind, text, out)) {
             printf("%s", compiler.errorText().c_str());
             exit(3);
         }
-        if (out.rdstate()) {
+    } else if (name.endsWith(".glsl")) {
+        SkFILEWStream out(argv[2]);
+        SkSL::Compiler compiler;
+        if (!out.isValid()) {
             printf("error writing '%s'\n", argv[2]);
             exit(4);
         }
-    } else if (endsWith(name, ".glsl")) {
-        std::ofstream out(argv[2], std::ofstream::binary);
-        SkSL::Compiler compiler;
         if (!compiler.toGLSL(kind, text, *SkSL::GLSLCapsFactory::Default(), out)) {
             printf("%s", compiler.errorText().c_str());
             exit(3);
         }
-        if (out.rdstate()) {
-            printf("error writing '%s'\n", argv[2]);
-            exit(4);
-        }
     } else {
         printf("expected output filename to end with '.spirv' or '.glsl'");
     }
index 2be664d..03d0d33 100644 (file)
@@ -88,7 +88,7 @@ public:
 
     bool checkValid() {
         if (fParser->fDepth > MAX_PARSE_DEPTH) {
-            fParser->error(fParser->peek().fPosition, "exceeded max parse depth");
+            fParser->error(fParser->peek().fPosition, SkString("exceeded max parse depth"));
             return false;
         }
         return true;
@@ -98,8 +98,8 @@ private:
     Parser* fParser;
 };
 
-Parser::Parser(std::string text, SymbolTable& types, ErrorReporter& errors) 
-: fPushback(Position(-1, -1), Token::INVALID_TOKEN, "")
+Parser::Parser(SkString text, SymbolTable& types, ErrorReporter& errors) 
+: fPushback(Position(-1, -1), Token::INVALID_TOKEN, SkString())
 , fTypes(types)
 , fErrors(errors) {
     sksllex_init(&fScanner);
@@ -157,13 +157,13 @@ Token Parser::nextToken() {
         return result;
     }
     int token = sksllex(fScanner);
-    std::string text;
+    SkString text;
     switch ((Token::Kind) token) {
         case Token::IDENTIFIER:    // fall through
         case Token::INT_LITERAL:   // fall through
         case Token::FLOAT_LITERAL: // fall through
         case Token::DIRECTIVE:
-            text = std::string(skslget_text(fScanner));
+            text = SkString(skslget_text(fScanner));
             break;
         default:
             break;
@@ -181,7 +181,12 @@ Token Parser::peek() {
     return fPushback;
 }
 
-bool Parser::expect(Token::Kind kind, std::string expected, Token* result) {
+
+bool Parser::expect(Token::Kind kind, const char* expected, Token* result) {
+    return this->expect(kind, SkString(expected), result);
+}
+
+bool Parser::expect(Token::Kind kind, SkString expected, Token* result) {
     Token next = this->nextToken();
     if (next.fKind == kind) {
         if (result) {
@@ -194,11 +199,15 @@ bool Parser::expect(Token::Kind kind, std::string expected, Token* result) {
     }
 }
 
-void Parser::error(Position p, std::string msg) {
+void Parser::error(Position p, const char* msg) {
+    this->error(p, SkString(msg));
+}
+
+void Parser::error(Position p, SkString msg) {
     fErrors.error(p, msg);
 }
 
-bool Parser::isType(std::string name) {
+bool Parser::isType(SkString name) {
     return nullptr != fTypes[name];
 }
 
@@ -370,7 +379,7 @@ std::unique_ptr<ASTType> Parser::structDeclaration() {
                     return nullptr;
                 }
                 uint64_t columns = ((ASTIntLiteral&) *var.fSizes[i]).fValue;
-                std::string name = type->name() + "[" + to_string(columns) + "]";
+                SkString name = type->name() + "[" + to_string(columns) + "]";
                 type = new Type(name, Type::kArray_Kind, *type, (int) columns);
                 fTypes.takeOwnership((Type*) type);
             }
@@ -417,7 +426,7 @@ std::unique_ptr<ASTVarDeclarations> Parser::structVarDeclaration(ASTModifiers mo
    (LBRACKET expression? RBRACKET)* (EQ expression)?)* SEMICOLON */
 std::unique_ptr<ASTVarDeclarations> Parser::varDeclarationEnd(ASTModifiers mods,
                                                               std::unique_ptr<ASTType> type,
-                                                              std::string name) {
+                                                              SkString name) {
     std::vector<ASTVarDeclaration> vars;
     std::vector<std::unique_ptr<ASTExpression>> currentVarSizes;
     while (this->peek().fKind == Token::LBRACKET) {
@@ -731,7 +740,7 @@ std::unique_ptr<ASTDeclaration> Parser::interfaceBlock(ASTModifiers mods) {
         decls.push_back(std::move(decl));
     }
     this->nextToken();
-    std::string valueName;
+    SkString valueName;
     if (this->peek().fKind == Token::IDENTIFIER) {
         valueName = this->nextToken().fText;
     }
@@ -1361,7 +1370,7 @@ std::unique_ptr<ASTSuffix> Parser::suffix() {
         }
         case Token::DOT: {
             Position pos = this->peek().fPosition;
-            std::string text;
+            SkString text;
             if (this->identifier(&text)) {
                 return std::unique_ptr<ASTSuffix>(new ASTFieldSuffix(pos, std::move(text)));
             }
@@ -1406,7 +1415,7 @@ std::unique_ptr<ASTExpression> Parser::term() {
     Token t = this->peek();
     switch (t.fKind) {
         case Token::IDENTIFIER: {
-            std::string text;
+            SkString text;
             if (this->identifier(&text)) {
                 result.reset(new ASTIdentifier(t.fPosition, std::move(text)));
             }
@@ -1487,7 +1496,7 @@ bool Parser::boolLiteral(bool* dest) {
 }
 
 /* IDENTIFIER */
-bool Parser::identifier(std::string* dest) {
+bool Parser::identifier(SkString* dest) {
     Token t;
     if (this->expect(Token::IDENTIFIER, "identifier", &t)) {
         *dest = t.fText; 
index f9dcde2..f2b6fb8 100644 (file)
@@ -8,7 +8,6 @@
 #ifndef SKSL_PARSER
 #define SKSL_PARSER
 
-#include <string>
 #include <vector>
 #include <memory>
 #include <unordered_set>
@@ -49,7 +48,7 @@ class SymbolTable;
  */
 class Parser {
 public:
-    Parser(std::string text, SymbolTable& types, ErrorReporter& errors);
+    Parser(SkString text, SymbolTable& types, ErrorReporter& errors);
 
     ~Parser();
 
@@ -87,15 +86,17 @@ private:
      * If 'result' is non-null, it is set to point to the token that was read.
      * Returns true if the read token was as expected, false otherwise.
      */
-    bool expect(Token::Kind kind, std::string expected, Token* result = nullptr);
+    bool expect(Token::Kind kind, const char* expected, Token* result = nullptr);
+    bool expect(Token::Kind kind, SkString expected, Token* result = nullptr);
 
-    void error(Position p, std::string msg);
+    void error(Position p, const char* msg);
+    void error(Position p, SkString msg);
     
     /**
      * Returns true if the 'name' identifier refers to a type name. For instance, isType("int") will
      * always return true.
      */
-    bool isType(std::string name);
+    bool isType(SkString name);
 
     // these functions parse individual grammar rules from the current parse position; you probably
     // don't need to call any of these outside of the parser. The function declarations in the .cpp
@@ -115,7 +116,7 @@ private:
 
     std::unique_ptr<ASTVarDeclarations> varDeclarationEnd(ASTModifiers modifiers,
                                                           std::unique_ptr<ASTType> type, 
-                                                          std::string name);
+                                                          SkString name);
 
     std::unique_ptr<ASTParameter> parameter();
 
@@ -195,7 +196,7 @@ private:
 
     bool boolLiteral(bool* dest);
 
-    bool identifier(std::string* dest);
+    bool identifier(SkString* dest);
 
     void* fScanner;
     YY_BUFFER_STATE fBuffer;
index 979f630..b1841c5 100644 (file)
@@ -25,7 +25,7 @@ struct Position {
     : fLine(line)
     , fColumn(column) {}
 
-    std::string description() const {
+    SkString description() const {
         return to_string(fLine);
     }
 
index a491968..b5cd54a 100644 (file)
@@ -34,107 +34,112 @@ void SPIRVCodeGenerator::setupIntrinsics() {
 #define SPECIAL(x) std::make_tuple(kSpecial_IntrinsicKind, k ## x ## _SpecialIntrinsic, \
                                    k ## x ## _SpecialIntrinsic, k ## x ## _SpecialIntrinsic, \
                                    k ## x ## _SpecialIntrinsic)
-    fIntrinsicMap["round"]         = ALL_GLSL(Round);
-    fIntrinsicMap["roundEven"]     = ALL_GLSL(RoundEven);
-    fIntrinsicMap["trunc"]         = ALL_GLSL(Trunc);
-    fIntrinsicMap["abs"]           = BY_TYPE_GLSL(FAbs, SAbs, SAbs);
-    fIntrinsicMap["sign"]          = BY_TYPE_GLSL(FSign, SSign, SSign);
-    fIntrinsicMap["floor"]         = ALL_GLSL(Floor);
-    fIntrinsicMap["ceil"]          = ALL_GLSL(Ceil);
-    fIntrinsicMap["fract"]         = ALL_GLSL(Fract);
-    fIntrinsicMap["radians"]       = ALL_GLSL(Radians);
-    fIntrinsicMap["degrees"]       = ALL_GLSL(Degrees);
-    fIntrinsicMap["sin"]           = ALL_GLSL(Sin);
-    fIntrinsicMap["cos"]           = ALL_GLSL(Cos);
-    fIntrinsicMap["tan"]           = ALL_GLSL(Tan);
-    fIntrinsicMap["asin"]          = ALL_GLSL(Asin);
-    fIntrinsicMap["acos"]          = ALL_GLSL(Acos);
-    fIntrinsicMap["atan"]          = SPECIAL(Atan);
-    fIntrinsicMap["sinh"]          = ALL_GLSL(Sinh);
-    fIntrinsicMap["cosh"]          = ALL_GLSL(Cosh);
-    fIntrinsicMap["tanh"]          = ALL_GLSL(Tanh);
-    fIntrinsicMap["asinh"]         = ALL_GLSL(Asinh);
-    fIntrinsicMap["acosh"]         = ALL_GLSL(Acosh);
-    fIntrinsicMap["atanh"]         = ALL_GLSL(Atanh);
-    fIntrinsicMap["pow"]           = ALL_GLSL(Pow);
-    fIntrinsicMap["exp"]           = ALL_GLSL(Exp);
-    fIntrinsicMap["log"]           = ALL_GLSL(Log);
-    fIntrinsicMap["exp2"]          = ALL_GLSL(Exp2);
-    fIntrinsicMap["log2"]          = ALL_GLSL(Log2);
-    fIntrinsicMap["sqrt"]          = ALL_GLSL(Sqrt);
-    fIntrinsicMap["inversesqrt"]   = ALL_GLSL(InverseSqrt);
-    fIntrinsicMap["determinant"]   = ALL_GLSL(Determinant);
-    fIntrinsicMap["matrixInverse"] = ALL_GLSL(MatrixInverse);
-    fIntrinsicMap["mod"]           = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpFMod, SpvOpSMod, 
-                                                     SpvOpUMod, SpvOpUndef);
-    fIntrinsicMap["min"]           = BY_TYPE_GLSL(FMin, SMin, UMin);
-    fIntrinsicMap["max"]           = BY_TYPE_GLSL(FMax, SMax, UMax);
-    fIntrinsicMap["clamp"]         = BY_TYPE_GLSL(FClamp, SClamp, UClamp);
-    fIntrinsicMap["dot"]           = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDot, SpvOpUndef,
-                                                     SpvOpUndef, SpvOpUndef);
-    fIntrinsicMap["mix"]           = ALL_GLSL(FMix);
-    fIntrinsicMap["step"]          = ALL_GLSL(Step);
-    fIntrinsicMap["smoothstep"]    = ALL_GLSL(SmoothStep);
-    fIntrinsicMap["fma"]           = ALL_GLSL(Fma);
-    fIntrinsicMap["frexp"]         = ALL_GLSL(Frexp);
-    fIntrinsicMap["ldexp"]         = ALL_GLSL(Ldexp);
-
-#define PACK(type) fIntrinsicMap["pack" #type] = ALL_GLSL(Pack ## type); \
-                   fIntrinsicMap["unpack" #type] = ALL_GLSL(Unpack ## type)
+    fIntrinsicMap[SkString("round")]         = ALL_GLSL(Round);
+    fIntrinsicMap[SkString("roundEven")]     = ALL_GLSL(RoundEven);
+    fIntrinsicMap[SkString("trunc")]         = ALL_GLSL(Trunc);
+    fIntrinsicMap[SkString("abs")]           = BY_TYPE_GLSL(FAbs, SAbs, SAbs);
+    fIntrinsicMap[SkString("sign")]          = BY_TYPE_GLSL(FSign, SSign, SSign);
+    fIntrinsicMap[SkString("floor")]         = ALL_GLSL(Floor);
+    fIntrinsicMap[SkString("ceil")]          = ALL_GLSL(Ceil);
+    fIntrinsicMap[SkString("fract")]         = ALL_GLSL(Fract);
+    fIntrinsicMap[SkString("radians")]       = ALL_GLSL(Radians);
+    fIntrinsicMap[SkString("degrees")]       = ALL_GLSL(Degrees);
+    fIntrinsicMap[SkString("sin")]           = ALL_GLSL(Sin);
+    fIntrinsicMap[SkString("cos")]           = ALL_GLSL(Cos);
+    fIntrinsicMap[SkString("tan")]           = ALL_GLSL(Tan);
+    fIntrinsicMap[SkString("asin")]          = ALL_GLSL(Asin);
+    fIntrinsicMap[SkString("acos")]          = ALL_GLSL(Acos);
+    fIntrinsicMap[SkString("atan")]          = SPECIAL(Atan);
+    fIntrinsicMap[SkString("sinh")]          = ALL_GLSL(Sinh);
+    fIntrinsicMap[SkString("cosh")]          = ALL_GLSL(Cosh);
+    fIntrinsicMap[SkString("tanh")]          = ALL_GLSL(Tanh);
+    fIntrinsicMap[SkString("asinh")]         = ALL_GLSL(Asinh);
+    fIntrinsicMap[SkString("acosh")]         = ALL_GLSL(Acosh);
+    fIntrinsicMap[SkString("atanh")]         = ALL_GLSL(Atanh);
+    fIntrinsicMap[SkString("pow")]           = ALL_GLSL(Pow);
+    fIntrinsicMap[SkString("exp")]           = ALL_GLSL(Exp);
+    fIntrinsicMap[SkString("log")]           = ALL_GLSL(Log);
+    fIntrinsicMap[SkString("exp2")]          = ALL_GLSL(Exp2);
+    fIntrinsicMap[SkString("log2")]          = ALL_GLSL(Log2);
+    fIntrinsicMap[SkString("sqrt")]          = ALL_GLSL(Sqrt);
+    fIntrinsicMap[SkString("inversesqrt")]   = ALL_GLSL(InverseSqrt);
+    fIntrinsicMap[SkString("determinant")]   = ALL_GLSL(Determinant);
+    fIntrinsicMap[SkString("matrixInverse")] = ALL_GLSL(MatrixInverse);
+    fIntrinsicMap[SkString("mod")]           = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpFMod,
+                                                               SpvOpSMod, SpvOpUMod, SpvOpUndef);
+    fIntrinsicMap[SkString("min")]           = BY_TYPE_GLSL(FMin, SMin, UMin);
+    fIntrinsicMap[SkString("max")]           = BY_TYPE_GLSL(FMax, SMax, UMax);
+    fIntrinsicMap[SkString("clamp")]         = BY_TYPE_GLSL(FClamp, SClamp, UClamp);
+    fIntrinsicMap[SkString("dot")]           = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDot,
+                                                               SpvOpUndef, SpvOpUndef, SpvOpUndef);
+    fIntrinsicMap[SkString("mix")]           = ALL_GLSL(FMix);
+    fIntrinsicMap[SkString("step")]          = ALL_GLSL(Step);
+    fIntrinsicMap[SkString("smoothstep")]    = ALL_GLSL(SmoothStep);
+    fIntrinsicMap[SkString("fma")]           = ALL_GLSL(Fma);
+    fIntrinsicMap[SkString("frexp")]         = ALL_GLSL(Frexp);
+    fIntrinsicMap[SkString("ldexp")]         = ALL_GLSL(Ldexp);
+
+#define PACK(type) fIntrinsicMap[SkString("pack" #type)] = ALL_GLSL(Pack ## type); \
+                   fIntrinsicMap[SkString("unpack" #type)] = ALL_GLSL(Unpack ## type)
     PACK(Snorm4x8);
     PACK(Unorm4x8);
     PACK(Snorm2x16);
     PACK(Unorm2x16);
     PACK(Half2x16);
     PACK(Double2x32);
-    fIntrinsicMap["length"]      = ALL_GLSL(Length);
-    fIntrinsicMap["distance"]    = ALL_GLSL(Distance);
-    fIntrinsicMap["cross"]       = ALL_GLSL(Cross);
-    fIntrinsicMap["normalize"]   = ALL_GLSL(Normalize);
-    fIntrinsicMap["faceForward"] = ALL_GLSL(FaceForward);
-    fIntrinsicMap["reflect"]     = ALL_GLSL(Reflect);
-    fIntrinsicMap["refract"]     = ALL_GLSL(Refract);
-    fIntrinsicMap["findLSB"]     = ALL_GLSL(FindILsb);
-    fIntrinsicMap["findMSB"]     = BY_TYPE_GLSL(FindSMsb, FindSMsb, FindUMsb);
-    fIntrinsicMap["dFdx"]        = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDPdx, SpvOpUndef,
-                                                   SpvOpUndef, SpvOpUndef);
-    fIntrinsicMap["dFdy"]        = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDPdy, SpvOpUndef,
-                                                   SpvOpUndef, SpvOpUndef);
-    fIntrinsicMap["dFdy"]        = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDPdy, SpvOpUndef,
-                                                   SpvOpUndef, SpvOpUndef);
-    fIntrinsicMap["texture"]     = SPECIAL(Texture);
-    fIntrinsicMap["texture2D"]   = SPECIAL(Texture2D);
-    fIntrinsicMap["textureProj"] = SPECIAL(TextureProj);
-
-    fIntrinsicMap["any"]              = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpUndef, 
-                                                        SpvOpUndef, SpvOpUndef, SpvOpAny);
-    fIntrinsicMap["all"]              = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpUndef, 
-                                                        SpvOpUndef, SpvOpUndef, SpvOpAll);
-    fIntrinsicMap["equal"]            = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpFOrdEqual, 
-                                                        SpvOpIEqual, SpvOpIEqual, 
-                                                        SpvOpLogicalEqual);
-    fIntrinsicMap["notEqual"]         = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpFOrdNotEqual, 
-                                                        SpvOpINotEqual, SpvOpINotEqual, 
-                                                        SpvOpLogicalNotEqual);
-    fIntrinsicMap["lessThan"]         = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpSLessThan, 
-                                                        SpvOpULessThan, SpvOpFOrdLessThan, 
-                                                        SpvOpUndef);
-    fIntrinsicMap["lessThanEqual"]    = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpSLessThanEqual, 
-                                                        SpvOpULessThanEqual, SpvOpFOrdLessThanEqual,
-                                                        SpvOpUndef);
-    fIntrinsicMap["greaterThan"]      = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpSGreaterThan, 
-                                                        SpvOpUGreaterThan, SpvOpFOrdGreaterThan, 
-                                                        SpvOpUndef);
-    fIntrinsicMap["greaterThanEqual"] = std::make_tuple(kSPIRV_IntrinsicKind, 
-                                                        SpvOpSGreaterThanEqual, 
-                                                        SpvOpUGreaterThanEqual, 
-                                                        SpvOpFOrdGreaterThanEqual,
-                                                        SpvOpUndef);
+    fIntrinsicMap[SkString("length")]      = ALL_GLSL(Length);
+    fIntrinsicMap[SkString("distance")]    = ALL_GLSL(Distance);
+    fIntrinsicMap[SkString("cross")]       = ALL_GLSL(Cross);
+    fIntrinsicMap[SkString("normalize")]   = ALL_GLSL(Normalize);
+    fIntrinsicMap[SkString("faceForward")] = ALL_GLSL(FaceForward);
+    fIntrinsicMap[SkString("reflect")]     = ALL_GLSL(Reflect);
+    fIntrinsicMap[SkString("refract")]     = ALL_GLSL(Refract);
+    fIntrinsicMap[SkString("findLSB")]     = ALL_GLSL(FindILsb);
+    fIntrinsicMap[SkString("findMSB")]     = BY_TYPE_GLSL(FindSMsb, FindSMsb, FindUMsb);
+    fIntrinsicMap[SkString("dFdx")]        = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDPdx,
+                                                             SpvOpUndef, SpvOpUndef, SpvOpUndef);
+    fIntrinsicMap[SkString("dFdy")]        = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDPdy,
+                                                             SpvOpUndef, SpvOpUndef, SpvOpUndef);
+    fIntrinsicMap[SkString("dFdy")]        = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpDPdy,
+                                                             SpvOpUndef, SpvOpUndef, SpvOpUndef);
+    fIntrinsicMap[SkString("texture")]     = SPECIAL(Texture);
+    fIntrinsicMap[SkString("texture2D")]   = SPECIAL(Texture2D);
+    fIntrinsicMap[SkString("textureProj")] = SPECIAL(TextureProj);
+
+    fIntrinsicMap[SkString("any")]              = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpUndef, 
+                                                                  SpvOpUndef, SpvOpUndef, SpvOpAny);
+    fIntrinsicMap[SkString("all")]              = std::make_tuple(kSPIRV_IntrinsicKind, SpvOpUndef, 
+                                                                  SpvOpUndef, SpvOpUndef, SpvOpAll);
+    fIntrinsicMap[SkString("equal")]            = std::make_tuple(kSPIRV_IntrinsicKind,
+                                                                  SpvOpFOrdEqual, SpvOpIEqual,
+                                                                  SpvOpIEqual, SpvOpLogicalEqual);
+    fIntrinsicMap[SkString("notEqual")]         = std::make_tuple(kSPIRV_IntrinsicKind,
+                                                                  SpvOpFOrdNotEqual, SpvOpINotEqual,
+                                                                  SpvOpINotEqual,
+                                                                  SpvOpLogicalNotEqual);
+    fIntrinsicMap[SkString("lessThan")]         = std::make_tuple(kSPIRV_IntrinsicKind,
+                                                                  SpvOpSLessThan, SpvOpULessThan,
+                                                                  SpvOpFOrdLessThan, SpvOpUndef);
+    fIntrinsicMap[SkString("lessThanEqual")]    = std::make_tuple(kSPIRV_IntrinsicKind,
+                                                                  SpvOpSLessThanEqual, 
+                                                                  SpvOpULessThanEqual,
+                                                                  SpvOpFOrdLessThanEqual,
+                                                                  SpvOpUndef);
+    fIntrinsicMap[SkString("greaterThan")]      = std::make_tuple(kSPIRV_IntrinsicKind,
+                                                                  SpvOpSGreaterThan, 
+                                                                  SpvOpUGreaterThan,
+                                                                  SpvOpFOrdGreaterThan, 
+                                                                  SpvOpUndef);
+    fIntrinsicMap[SkString("greaterThanEqual")] = std::make_tuple(kSPIRV_IntrinsicKind, 
+                                                                  SpvOpSGreaterThanEqual, 
+                                                                  SpvOpUGreaterThanEqual, 
+                                                                  SpvOpFOrdGreaterThanEqual,
+                                                                  SpvOpUndef);
 
 // interpolateAt* not yet supported...
 }
 
-void SPIRVCodeGenerator::writeWord(int32_t word, std::ostream& out) {
+void SPIRVCodeGenerator::writeWord(int32_t word, SkWStream& out) {
 #if SPIRV_DEBUG
     out << "(" << word << ") ";
 #else
@@ -175,603 +180,603 @@ static bool is_out(const Variable& var) {
 }
 
 #if SPIRV_DEBUG
-static std::string opcode_text(SpvOp_ opCode) {
+static SkString opcode_text(SpvOp_ opCode) {
     switch (opCode) {
         case SpvOpNop:
-            return "Nop";
+            return SkString("Nop");
         case SpvOpUndef:
-            return "Undef";
+            return SkString("Undef");
         case SpvOpSourceContinued:
-            return "SourceContinued";
+            return SkString("SourceContinued");
         case SpvOpSource:
-            return "Source";
+            return SkString("Source");
         case SpvOpSourceExtension:
-            return "SourceExtension";
+            return SkString("SourceExtension");
         case SpvOpName:
-            return "Name";
+            return SkString("Name");
         case SpvOpMemberName:
-            return "MemberName";
+            return SkString("MemberName");
         case SpvOpString:
-            return "String";
+            return SkString("String");
         case SpvOpLine:
-            return "Line";
+            return SkString("Line");
         case SpvOpExtension:
-            return "Extension";
+            return SkString("Extension");
         case SpvOpExtInstImport:
-            return "ExtInstImport";
+            return SkString("ExtInstImport");
         case SpvOpExtInst:
-            return "ExtInst";
+            return SkString("ExtInst");
         case SpvOpMemoryModel:
-            return "MemoryModel";
+            return SkString("MemoryModel");
         case SpvOpEntryPoint:
-            return "EntryPoint";
+            return SkString("EntryPoint");
         case SpvOpExecutionMode:
-            return "ExecutionMode";
+            return SkString("ExecutionMode");
         case SpvOpCapability:
-            return "Capability";
+            return SkString("Capability");
         case SpvOpTypeVoid:
-            return "TypeVoid";
+            return SkString("TypeVoid");
         case SpvOpTypeBool:
-            return "TypeBool";
+            return SkString("TypeBool");
         case SpvOpTypeInt:
-            return "TypeInt";
+            return SkString("TypeInt");
         case SpvOpTypeFloat:
-            return "TypeFloat";
+            return SkString("TypeFloat");
         case SpvOpTypeVector:
-            return "TypeVector";
+            return SkString("TypeVector");
         case SpvOpTypeMatrix:
-            return "TypeMatrix";
+            return SkString("TypeMatrix");
         case SpvOpTypeImage:
-            return "TypeImage";
+            return SkString("TypeImage");
         case SpvOpTypeSampler:
-            return "TypeSampler";
+            return SkString("TypeSampler");
         case SpvOpTypeSampledImage:
-            return "TypeSampledImage";
+            return SkString("TypeSampledImage");
         case SpvOpTypeArray:
-            return "TypeArray";
+            return SkString("TypeArray");
         case SpvOpTypeRuntimeArray:
-            return "TypeRuntimeArray";
+            return SkString("TypeRuntimeArray");
         case SpvOpTypeStruct:
-            return "TypeStruct";
+            return SkString("TypeStruct");
         case SpvOpTypeOpaque:
-            return "TypeOpaque";
+            return SkString("TypeOpaque");
         case SpvOpTypePointer:
-            return "TypePointer";
+            return SkString("TypePointer");
         case SpvOpTypeFunction:
-            return "TypeFunction";
+            return SkString("TypeFunction");
         case SpvOpTypeEvent:
-            return "TypeEvent";
+            return SkString("TypeEvent");
         case SpvOpTypeDeviceEvent:
-            return "TypeDeviceEvent";
+            return SkString("TypeDeviceEvent");
         case SpvOpTypeReserveId:
-            return "TypeReserveId";
+            return SkString("TypeReserveId");
         case SpvOpTypeQueue:
-            return "TypeQueue";
+            return SkString("TypeQueue");
         case SpvOpTypePipe:
-            return "TypePipe";
+            return SkString("TypePipe");
         case SpvOpTypeForwardPointer:
-            return "TypeForwardPointer";
+            return SkString("TypeForwardPointer");
         case SpvOpConstantTrue:
-            return "ConstantTrue";
+            return SkString("ConstantTrue");
         case SpvOpConstantFalse:
-            return "ConstantFalse";
+            return SkString("ConstantFalse");
         case SpvOpConstant:
-            return "Constant";
+            return SkString("Constant");
         case SpvOpConstantComposite:
-            return "ConstantComposite";
+            return SkString("ConstantComposite");
         case SpvOpConstantSampler:
-            return "ConstantSampler";
+            return SkString("ConstantSampler");
         case SpvOpConstantNull:
-            return "ConstantNull";
+            return SkString("ConstantNull");
         case SpvOpSpecConstantTrue:
-            return "SpecConstantTrue";
+            return SkString("SpecConstantTrue");
         case SpvOpSpecConstantFalse:
-            return "SpecConstantFalse";
+            return SkString("SpecConstantFalse");
         case SpvOpSpecConstant:
-            return "SpecConstant";
+            return SkString("SpecConstant");
         case SpvOpSpecConstantComposite:
-            return "SpecConstantComposite";
+            return SkString("SpecConstantComposite");
         case SpvOpSpecConstantOp:
-            return "SpecConstantOp";
+            return SkString("SpecConstantOp");
         case SpvOpFunction:
-            return "Function";
+            return SkString("Function");
         case SpvOpFunctionParameter:
-            return "FunctionParameter";
+            return SkString("FunctionParameter");
         case SpvOpFunctionEnd:
-            return "FunctionEnd";
+            return SkString("FunctionEnd");
         case SpvOpFunctionCall:
-            return "FunctionCall";
+            return SkString("FunctionCall");
         case SpvOpVariable:
-            return "Variable";
+            return SkString("Variable");
         case SpvOpImageTexelPointer:
-            return "ImageTexelPointer";
+            return SkString("ImageTexelPointer");
         case SpvOpLoad:
-            return "Load";
+            return SkString("Load");
         case SpvOpStore:
-            return "Store";
+            return SkString("Store");
         case SpvOpCopyMemory:
-            return "CopyMemory";
+            return SkString("CopyMemory");
         case SpvOpCopyMemorySized:
-            return "CopyMemorySized";
+            return SkString("CopyMemorySized");
         case SpvOpAccessChain:
-            return "AccessChain";
+            return SkString("AccessChain");
         case SpvOpInBoundsAccessChain:
-            return "InBoundsAccessChain";
+            return SkString("InBoundsAccessChain");
         case SpvOpPtrAccessChain:
-            return "PtrAccessChain";
+            return SkString("PtrAccessChain");
         case SpvOpArrayLength:
-            return "ArrayLength";
+            return SkString("ArrayLength");
         case SpvOpGenericPtrMemSemantics:
-            return "GenericPtrMemSemantics";
+            return SkString("GenericPtrMemSemantics");
         case SpvOpInBoundsPtrAccessChain:
-            return "InBoundsPtrAccessChain";
+            return SkString("InBoundsPtrAccessChain");
         case SpvOpDecorate:
-            return "Decorate";
+            return SkString("Decorate");
         case SpvOpMemberDecorate:
-            return "MemberDecorate";
+            return SkString("MemberDecorate");
         case SpvOpDecorationGroup:
-            return "DecorationGroup";
+            return SkString("DecorationGroup");
         case SpvOpGroupDecorate:
-            return "GroupDecorate";
+            return SkString("GroupDecorate");
         case SpvOpGroupMemberDecorate:
-            return "GroupMemberDecorate";
+            return SkString("GroupMemberDecorate");
         case SpvOpVectorExtractDynamic:
-            return "VectorExtractDynamic";
+            return SkString("VectorExtractDynamic");
         case SpvOpVectorInsertDynamic:
-            return "VectorInsertDynamic";
+            return SkString("VectorInsertDynamic");
         case SpvOpVectorShuffle:
-            return "VectorShuffle";
+            return SkString("VectorShuffle");
         case SpvOpCompositeConstruct:
-            return "CompositeConstruct";
+            return SkString("CompositeConstruct");
         case SpvOpCompositeExtract:
-            return "CompositeExtract";
+            return SkString("CompositeExtract");
         case SpvOpCompositeInsert:
-            return "CompositeInsert";
+            return SkString("CompositeInsert");
         case SpvOpCopyObject:
-            return "CopyObject";
+            return SkString("CopyObject");
         case SpvOpTranspose:
-            return "Transpose";
+            return SkString("Transpose");
         case SpvOpSampledImage:
-            return "SampledImage";
+            return SkString("SampledImage");
         case SpvOpImageSampleImplicitLod:
-            return "ImageSampleImplicitLod";
+            return SkString("ImageSampleImplicitLod");
         case SpvOpImageSampleExplicitLod:
-            return "ImageSampleExplicitLod";
+            return SkString("ImageSampleExplicitLod");
         case SpvOpImageSampleDrefImplicitLod:
-            return "ImageSampleDrefImplicitLod";
+            return SkString("ImageSampleDrefImplicitLod");
         case SpvOpImageSampleDrefExplicitLod:
-            return "ImageSampleDrefExplicitLod";
+            return SkString("ImageSampleDrefExplicitLod");
         case SpvOpImageSampleProjImplicitLod:
-            return "ImageSampleProjImplicitLod";
+            return SkString("ImageSampleProjImplicitLod");
         case SpvOpImageSampleProjExplicitLod:
-            return "ImageSampleProjExplicitLod";
+            return SkString("ImageSampleProjExplicitLod");
         case SpvOpImageSampleProjDrefImplicitLod:
-            return "ImageSampleProjDrefImplicitLod";
+            return SkString("ImageSampleProjDrefImplicitLod");
         case SpvOpImageSampleProjDrefExplicitLod:
-            return "ImageSampleProjDrefExplicitLod";
+            return SkString("ImageSampleProjDrefExplicitLod");
         case SpvOpImageFetch:
-            return "ImageFetch";
+            return SkString("ImageFetch");
         case SpvOpImageGather:
-            return "ImageGather";
+            return SkString("ImageGather");
         case SpvOpImageDrefGather:
-            return "ImageDrefGather";
+            return SkString("ImageDrefGather");
         case SpvOpImageRead:
-            return "ImageRead";
+            return SkString("ImageRead");
         case SpvOpImageWrite:
-            return "ImageWrite";
+            return SkString("ImageWrite");
         case SpvOpImage:
-            return "Image";
+            return SkString("Image");
         case SpvOpImageQueryFormat:
-            return "ImageQueryFormat";
+            return SkString("ImageQueryFormat");
         case SpvOpImageQueryOrder:
-            return "ImageQueryOrder";
+            return SkString("ImageQueryOrder");
         case SpvOpImageQuerySizeLod:
-            return "ImageQuerySizeLod";
+            return SkString("ImageQuerySizeLod");
         case SpvOpImageQuerySize:
-            return "ImageQuerySize";
+            return SkString("ImageQuerySize");
         case SpvOpImageQueryLod:
-            return "ImageQueryLod";
+            return SkString("ImageQueryLod");
         case SpvOpImageQueryLevels:
-            return "ImageQueryLevels";
+            return SkString("ImageQueryLevels");
         case SpvOpImageQuerySamples:
-            return "ImageQuerySamples";
+            return SkString("ImageQuerySamples");
         case SpvOpConvertFToU:
-            return "ConvertFToU";
+            return SkString("ConvertFToU");
         case SpvOpConvertFToS:
-            return "ConvertFToS";
+            return SkString("ConvertFToS");
         case SpvOpConvertSToF:
-            return "ConvertSToF";
+            return SkString("ConvertSToF");
         case SpvOpConvertUToF:
-            return "ConvertUToF";
+            return SkString("ConvertUToF");
         case SpvOpUConvert:
-            return "UConvert";
+            return SkString("UConvert");
         case SpvOpSConvert:
-            return "SConvert";
+            return SkString("SConvert");
         case SpvOpFConvert:
-            return "FConvert";
+            return SkString("FConvert");
         case SpvOpQuantizeToF16:
-            return "QuantizeToF16";
+            return SkString("QuantizeToF16");
         case SpvOpConvertPtrToU:
-            return "ConvertPtrToU";
+            return SkString("ConvertPtrToU");
         case SpvOpSatConvertSToU:
-            return "SatConvertSToU";
+            return SkString("SatConvertSToU");
         case SpvOpSatConvertUToS:
-            return "SatConvertUToS";
+            return SkString("SatConvertUToS");
         case SpvOpConvertUToPtr:
-            return "ConvertUToPtr";
+            return SkString("ConvertUToPtr");
         case SpvOpPtrCastToGeneric:
-            return "PtrCastToGeneric";
+            return SkString("PtrCastToGeneric");
         case SpvOpGenericCastToPtr:
-            return "GenericCastToPtr";
+            return SkString("GenericCastToPtr");
         case SpvOpGenericCastToPtrExplicit:
-            return "GenericCastToPtrExplicit";
+            return SkString("GenericCastToPtrExplicit");
         case SpvOpBitcast:
-            return "Bitcast";
+            return SkString("Bitcast");
         case SpvOpSNegate:
-            return "SNegate";
+            return SkString("SNegate");
         case SpvOpFNegate:
-            return "FNegate";
+            return SkString("FNegate");
         case SpvOpIAdd:
-            return "IAdd";
+            return SkString("IAdd");
         case SpvOpFAdd:
-            return "FAdd";
+            return SkString("FAdd");
         case SpvOpISub:
-            return "ISub";
+            return SkString("ISub");
         case SpvOpFSub:
-            return "FSub";
+            return SkString("FSub");
         case SpvOpIMul:
-            return "IMul";
+            return SkString("IMul");
         case SpvOpFMul:
-            return "FMul";
+            return SkString("FMul");
         case SpvOpUDiv:
-            return "UDiv";
+            return SkString("UDiv");
         case SpvOpSDiv:
-            return "SDiv";
+            return SkString("SDiv");
         case SpvOpFDiv:
-            return "FDiv";
+            return SkString("FDiv");
         case SpvOpUMod:
-            return "UMod";
+            return SkString("UMod");
         case SpvOpSRem:
-            return "SRem";
+            return SkString("SRem");
         case SpvOpSMod:
-            return "SMod";
+            return SkString("SMod");
         case SpvOpFRem:
-            return "FRem";
+            return SkString("FRem");
         case SpvOpFMod:
-            return "FMod";
+            return SkString("FMod");
         case SpvOpVectorTimesScalar:
-            return "VectorTimesScalar";
+            return SkString("VectorTimesScalar");
         case SpvOpMatrixTimesScalar:
-            return "MatrixTimesScalar";
+            return SkString("MatrixTimesScalar");
         case SpvOpVectorTimesMatrix:
-            return "VectorTimesMatrix";
+            return SkString("VectorTimesMatrix");
         case SpvOpMatrixTimesVector:
-            return "MatrixTimesVector";
+            return SkString("MatrixTimesVector");
         case SpvOpMatrixTimesMatrix:
-            return "MatrixTimesMatrix";
+            return SkString("MatrixTimesMatrix");
         case SpvOpOuterProduct:
-            return "OuterProduct";
+            return SkString("OuterProduct");
         case SpvOpDot:
-            return "Dot";
+            return SkString("Dot");
         case SpvOpIAddCarry:
-            return "IAddCarry";
+            return SkString("IAddCarry");
         case SpvOpISubBorrow:
-            return "ISubBorrow";
+            return SkString("ISubBorrow");
         case SpvOpUMulExtended:
-            return "UMulExtended";
+            return SkString("UMulExtended");
         case SpvOpSMulExtended:
-            return "SMulExtended";
+            return SkString("SMulExtended");
         case SpvOpAny:
-            return "Any";
+            return SkString("Any");
         case SpvOpAll:
-            return "All";
+            return SkString("All");
         case SpvOpIsNan:
-            return "IsNan";
+            return SkString("IsNan");
         case SpvOpIsInf:
-            return "IsInf";
+            return SkString("IsInf");
         case SpvOpIsFinite:
-            return "IsFinite";
+            return SkString("IsFinite");
         case SpvOpIsNormal:
-            return "IsNormal";
+            return SkString("IsNormal");
         case SpvOpSignBitSet:
-            return "SignBitSet";
+            return SkString("SignBitSet");
         case SpvOpLessOrGreater:
-            return "LessOrGreater";
+            return SkString("LessOrGreater");
         case SpvOpOrdered:
-            return "Ordered";
+            return SkString("Ordered");
         case SpvOpUnordered:
-            return "Unordered";
+            return SkString("Unordered");
         case SpvOpLogicalEqual:
-            return "LogicalEqual";
+            return SkString("LogicalEqual");
         case SpvOpLogicalNotEqual:
-            return "LogicalNotEqual";
+            return SkString("LogicalNotEqual");
         case SpvOpLogicalOr:
-            return "LogicalOr";
+            return SkString("LogicalOr");
         case SpvOpLogicalAnd:
-            return "LogicalAnd";
+            return SkString("LogicalAnd");
         case SpvOpLogicalNot:
-            return "LogicalNot";
+            return SkString("LogicalNot");
         case SpvOpSelect:
-            return "Select";
+            return SkString("Select");
         case SpvOpIEqual:
-            return "IEqual";
+            return SkString("IEqual");
         case SpvOpINotEqual:
-            return "INotEqual";
+            return SkString("INotEqual");
         case SpvOpUGreaterThan:
-            return "UGreaterThan";
+            return SkString("UGreaterThan");
         case SpvOpSGreaterThan:
-            return "SGreaterThan";
+            return SkString("SGreaterThan");
         case SpvOpUGreaterThanEqual:
-            return "UGreaterThanEqual";
+            return SkString("UGreaterThanEqual");
         case SpvOpSGreaterThanEqual:
-            return "SGreaterThanEqual";
+            return SkString("SGreaterThanEqual");
         case SpvOpULessThan:
-            return "ULessThan";
+            return SkString("ULessThan");
         case SpvOpSLessThan:
-            return "SLessThan";
+            return SkString("SLessThan");
         case SpvOpULessThanEqual:
-            return "ULessThanEqual";
+            return SkString("ULessThanEqual");
         case SpvOpSLessThanEqual:
-            return "SLessThanEqual";
+            return SkString("SLessThanEqual");
         case SpvOpFOrdEqual:
-            return "FOrdEqual";
+            return SkString("FOrdEqual");
         case SpvOpFUnordEqual:
-            return "FUnordEqual";
+            return SkString("FUnordEqual");
         case SpvOpFOrdNotEqual:
-            return "FOrdNotEqual";
+            return SkString("FOrdNotEqual");
         case SpvOpFUnordNotEqual:
-            return "FUnordNotEqual";
+            return SkString("FUnordNotEqual");
         case SpvOpFOrdLessThan:
-            return "FOrdLessThan";
+            return SkString("FOrdLessThan");
         case SpvOpFUnordLessThan:
-            return "FUnordLessThan";
+            return SkString("FUnordLessThan");
         case SpvOpFOrdGreaterThan:
-            return "FOrdGreaterThan";
+            return SkString("FOrdGreaterThan");
         case SpvOpFUnordGreaterThan:
-            return "FUnordGreaterThan";
+            return SkString("FUnordGreaterThan");
         case SpvOpFOrdLessThanEqual:
-            return "FOrdLessThanEqual";
+            return SkString("FOrdLessThanEqual");
         case SpvOpFUnordLessThanEqual:
-            return "FUnordLessThanEqual";
+            return SkString("FUnordLessThanEqual");
         case SpvOpFOrdGreaterThanEqual:
-            return "FOrdGreaterThanEqual";
+            return SkString("FOrdGreaterThanEqual");
         case SpvOpFUnordGreaterThanEqual:
-            return "FUnordGreaterThanEqual";
+            return SkString("FUnordGreaterThanEqual");
         case SpvOpShiftRightLogical:
-            return "ShiftRightLogical";
+            return SkString("ShiftRightLogical");
         case SpvOpShiftRightArithmetic:
-            return "ShiftRightArithmetic";
+            return SkString("ShiftRightArithmetic");
         case SpvOpShiftLeftLogical:
-            return "ShiftLeftLogical";
+            return SkString("ShiftLeftLogical");
         case SpvOpBitwiseOr:
-            return "BitwiseOr";
+            return SkString("BitwiseOr");
         case SpvOpBitwiseXor:
-            return "BitwiseXor";
+            return SkString("BitwiseXor");
         case SpvOpBitwiseAnd:
-            return "BitwiseAnd";
+            return SkString("BitwiseAnd");
         case SpvOpNot:
-            return "Not";
+            return SkString("Not");
         case SpvOpBitFieldInsert:
-            return "BitFieldInsert";
+            return SkString("BitFieldInsert");
         case SpvOpBitFieldSExtract:
-            return "BitFieldSExtract";
+            return SkString("BitFieldSExtract");
         case SpvOpBitFieldUExtract:
-            return "BitFieldUExtract";
+            return SkString("BitFieldUExtract");
         case SpvOpBitReverse:
-            return "BitReverse";
+            return SkString("BitReverse");
         case SpvOpBitCount:
-            return "BitCount";
+            return SkString("BitCount");
         case SpvOpDPdx:
-            return "DPdx";
+            return SkString("DPdx");
         case SpvOpDPdy:
-            return "DPdy";
+            return SkString("DPdy");
         case SpvOpFwidth:
-            return "Fwidth";
+            return SkString("Fwidth");
         case SpvOpDPdxFine:
-            return "DPdxFine";
+            return SkString("DPdxFine");
         case SpvOpDPdyFine:
-            return "DPdyFine";
+            return SkString("DPdyFine");
         case SpvOpFwidthFine:
-            return "FwidthFine";
+            return SkString("FwidthFine");
         case SpvOpDPdxCoarse:
-            return "DPdxCoarse";
+            return SkString("DPdxCoarse");
         case SpvOpDPdyCoarse:
-            return "DPdyCoarse";
+            return SkString("DPdyCoarse");
         case SpvOpFwidthCoarse:
-            return "FwidthCoarse";
+            return SkString("FwidthCoarse");
         case SpvOpEmitVertex:
-            return "EmitVertex";
+            return SkString("EmitVertex");
         case SpvOpEndPrimitive:
-            return "EndPrimitive";
+            return SkString("EndPrimitive");
         case SpvOpEmitStreamVertex:
-            return "EmitStreamVertex";
+            return SkString("EmitStreamVertex");
         case SpvOpEndStreamPrimitive:
-            return "EndStreamPrimitive";
+            return SkString("EndStreamPrimitive");
         case SpvOpControlBarrier:
-            return "ControlBarrier";
+            return SkString("ControlBarrier");
         case SpvOpMemoryBarrier:
-            return "MemoryBarrier";
+            return SkString("MemoryBarrier");
         case SpvOpAtomicLoad:
-            return "AtomicLoad";
+            return SkString("AtomicLoad");
         case SpvOpAtomicStore:
-            return "AtomicStore";
+            return SkString("AtomicStore");
         case SpvOpAtomicExchange:
-            return "AtomicExchange";
+            return SkString("AtomicExchange");
         case SpvOpAtomicCompareExchange:
-            return "AtomicCompareExchange";
+            return SkString("AtomicCompareExchange");
         case SpvOpAtomicCompareExchangeWeak:
-            return "AtomicCompareExchangeWeak";
+            return SkString("AtomicCompareExchangeWeak");
         case SpvOpAtomicIIncrement:
-            return "AtomicIIncrement";
+            return SkString("AtomicIIncrement");
         case SpvOpAtomicIDecrement:
-            return "AtomicIDecrement";
+            return SkString("AtomicIDecrement");
         case SpvOpAtomicIAdd:
-            return "AtomicIAdd";
+            return SkString("AtomicIAdd");
         case SpvOpAtomicISub:
-            return "AtomicISub";
+            return SkString("AtomicISub");
         case SpvOpAtomicSMin:
-            return "AtomicSMin";
+            return SkString("AtomicSMin");
         case SpvOpAtomicUMin:
-            return "AtomicUMin";
+            return SkString("AtomicUMin");
         case SpvOpAtomicSMax:
-            return "AtomicSMax";
+            return SkString("AtomicSMax");
         case SpvOpAtomicUMax:
-            return "AtomicUMax";
+            return SkString("AtomicUMax");
         case SpvOpAtomicAnd:
-            return "AtomicAnd";
+            return SkString("AtomicAnd");
         case SpvOpAtomicOr:
-            return "AtomicOr";
+            return SkString("AtomicOr");
         case SpvOpAtomicXor:
-            return "AtomicXor";
+            return SkString("AtomicXor");
         case SpvOpPhi:
-            return "Phi";
+            return SkString("Phi");
         case SpvOpLoopMerge:
-            return "LoopMerge";
+            return SkString("LoopMerge");
         case SpvOpSelectionMerge:
-            return "SelectionMerge";
+            return SkString("SelectionMerge");
         case SpvOpLabel:
-            return "Label";
+            return SkString("Label");
         case SpvOpBranch:
-            return "Branch";
+            return SkString("Branch");
         case SpvOpBranchConditional:
-            return "BranchConditional";
+            return SkString("BranchConditional");
         case SpvOpSwitch:
-            return "Switch";
+            return SkString("Switch");
         case SpvOpKill:
-            return "Kill";
+            return SkString("Kill");
         case SpvOpReturn:
-            return "Return";
+            return SkString("Return");
         case SpvOpReturnValue:
-            return "ReturnValue";
+            return SkString("ReturnValue");
         case SpvOpUnreachable:
-            return "Unreachable";
+            return SkString("Unreachable");
         case SpvOpLifetimeStart:
-            return "LifetimeStart";
+            return SkString("LifetimeStart");
         case SpvOpLifetimeStop:
-            return "LifetimeStop";
+            return SkString("LifetimeStop");
         case SpvOpGroupAsyncCopy:
-            return "GroupAsyncCopy";
+            return SkString("GroupAsyncCopy");
         case SpvOpGroupWaitEvents:
-            return "GroupWaitEvents";
+            return SkString("GroupWaitEvents");
         case SpvOpGroupAll:
-            return "GroupAll";
+            return SkString("GroupAll");
         case SpvOpGroupAny:
-            return "GroupAny";
+            return SkString("GroupAny");
         case SpvOpGroupBroadcast:
-            return "GroupBroadcast";
+            return SkString("GroupBroadcast");
         case SpvOpGroupIAdd:
-            return "GroupIAdd";
+            return SkString("GroupIAdd");
         case SpvOpGroupFAdd:
-            return "GroupFAdd";
+            return SkString("GroupFAdd");
         case SpvOpGroupFMin:
-            return "GroupFMin";
+            return SkString("GroupFMin");
         case SpvOpGroupUMin:
-            return "GroupUMin";
+            return SkString("GroupUMin");
         case SpvOpGroupSMin:
-            return "GroupSMin";
+            return SkString("GroupSMin");
         case SpvOpGroupFMax:
-            return "GroupFMax";
+            return SkString("GroupFMax");
         case SpvOpGroupUMax:
-            return "GroupUMax";
+            return SkString("GroupUMax");
         case SpvOpGroupSMax:
-            return "GroupSMax";
+            return SkString("GroupSMax");
         case SpvOpReadPipe:
-            return "ReadPipe";
+            return SkString("ReadPipe");
         case SpvOpWritePipe:
-            return "WritePipe";
+            return SkString("WritePipe");
         case SpvOpReservedReadPipe:
-            return "ReservedReadPipe";
+            return SkString("ReservedReadPipe");
         case SpvOpReservedWritePipe:
-            return "ReservedWritePipe";
+            return SkString("ReservedWritePipe");
         case SpvOpReserveReadPipePackets:
-            return "ReserveReadPipePackets";
+            return SkString("ReserveReadPipePackets");
         case SpvOpReserveWritePipePackets:
-            return "ReserveWritePipePackets";
+            return SkString("ReserveWritePipePackets");
         case SpvOpCommitReadPipe:
-            return "CommitReadPipe";
+            return SkString("CommitReadPipe");
         case SpvOpCommitWritePipe:
-            return "CommitWritePipe";
+            return SkString("CommitWritePipe");
         case SpvOpIsValidReserveId:
-            return "IsValidReserveId";
+            return SkString("IsValidReserveId");
         case SpvOpGetNumPipePackets:
-            return "GetNumPipePackets";
+            return SkString("GetNumPipePackets");
         case SpvOpGetMaxPipePackets:
-            return "GetMaxPipePackets";
+            return SkString("GetMaxPipePackets");
         case SpvOpGroupReserveReadPipePackets:
-            return "GroupReserveReadPipePackets";
+            return SkString("GroupReserveReadPipePackets");
         case SpvOpGroupReserveWritePipePackets:
-            return "GroupReserveWritePipePackets";
+            return SkString("GroupReserveWritePipePackets");
         case SpvOpGroupCommitReadPipe:
-            return "GroupCommitReadPipe";
+            return SkString("GroupCommitReadPipe");
         case SpvOpGroupCommitWritePipe:
-            return "GroupCommitWritePipe";
+            return SkString("GroupCommitWritePipe");
         case SpvOpEnqueueMarker:
-            return "EnqueueMarker";
+            return SkString("EnqueueMarker");
         case SpvOpEnqueueKernel:
-            return "EnqueueKernel";
+            return SkString("EnqueueKernel");
         case SpvOpGetKernelNDrangeSubGroupCount:
-            return "GetKernelNDrangeSubGroupCount";
+            return SkString("GetKernelNDrangeSubGroupCount");
         case SpvOpGetKernelNDrangeMaxSubGroupSize:
-            return "GetKernelNDrangeMaxSubGroupSize";
+            return SkString("GetKernelNDrangeMaxSubGroupSize");
         case SpvOpGetKernelWorkGroupSize:
-            return "GetKernelWorkGroupSize";
+            return SkString("GetKernelWorkGroupSize");
         case SpvOpGetKernelPreferredWorkGroupSizeMultiple:
-            return "GetKernelPreferredWorkGroupSizeMultiple";
+            return SkString("GetKernelPreferredWorkGroupSizeMultiple");
         case SpvOpRetainEvent:
-            return "RetainEvent";
+            return SkString("RetainEvent");
         case SpvOpReleaseEvent:
-            return "ReleaseEvent";
+            return SkString("ReleaseEvent");
         case SpvOpCreateUserEvent:
-            return "CreateUserEvent";
+            return SkString("CreateUserEvent");
         case SpvOpIsValidEvent:
-            return "IsValidEvent";
+            return SkString("IsValidEvent");
         case SpvOpSetUserEventStatus:
-            return "SetUserEventStatus";
+            return SkString("SetUserEventStatus");
         case SpvOpCaptureEventProfilingInfo:
-            return "CaptureEventProfilingInfo";
+            return SkString("CaptureEventProfilingInfo");
         case SpvOpGetDefaultQueue:
-            return "GetDefaultQueue";
+            return SkString("GetDefaultQueue");
         case SpvOpBuildNDRange:
-            return "BuildNDRange";
+            return SkString("BuildNDRange");
         case SpvOpImageSparseSampleImplicitLod:
-            return "ImageSparseSampleImplicitLod";
+            return SkString("ImageSparseSampleImplicitLod");
         case SpvOpImageSparseSampleExplicitLod:
-            return "ImageSparseSampleExplicitLod";
+            return SkString("ImageSparseSampleExplicitLod");
         case SpvOpImageSparseSampleDrefImplicitLod:
-            return "ImageSparseSampleDrefImplicitLod";
+            return SkString("ImageSparseSampleDrefImplicitLod");
         case SpvOpImageSparseSampleDrefExplicitLod:
-            return "ImageSparseSampleDrefExplicitLod";
+            return SkString("ImageSparseSampleDrefExplicitLod");
         case SpvOpImageSparseSampleProjImplicitLod:
-            return "ImageSparseSampleProjImplicitLod";
+            return SkString("ImageSparseSampleProjImplicitLod");
         case SpvOpImageSparseSampleProjExplicitLod:
-            return "ImageSparseSampleProjExplicitLod";
+            return SkString("ImageSparseSampleProjExplicitLod");
         case SpvOpImageSparseSampleProjDrefImplicitLod:
-            return "ImageSparseSampleProjDrefImplicitLod";
+            return SkString("ImageSparseSampleProjDrefImplicitLod");
         case SpvOpImageSparseSampleProjDrefExplicitLod:
-            return "ImageSparseSampleProjDrefExplicitLod";
+            return SkString("ImageSparseSampleProjDrefExplicitLod");
         case SpvOpImageSparseFetch:
-            return "ImageSparseFetch";
+            return SkString("ImageSparseFetch");
         case SpvOpImageSparseGather:
-            return "ImageSparseGather";
+            return SkString("ImageSparseGather");
         case SpvOpImageSparseDrefGather:
-            return "ImageSparseDrefGather";
+            return SkString("ImageSparseDrefGather");
         case SpvOpImageSparseTexelsResident:
-            return "ImageSparseTexelsResident";
+            return SkString("ImageSparseTexelsResident");
         case SpvOpNoLine:
-            return "NoLine";
+            return SkString("NoLine");
         case SpvOpAtomicFlagTestAndSet:
-            return "AtomicFlagTestAndSet";
+            return SkString("AtomicFlagTestAndSet");
         case SpvOpAtomicFlagClear:
-            return "AtomicFlagClear";
+            return SkString("AtomicFlagClear");
         case SpvOpImageSparseRead:
-            return "ImageSparseRead";
+            return SkString("ImageSparseRead");
         default:
             ABORT("unsupported SPIR-V op");    
     }
 }
 #endif
 
-void SPIRVCodeGenerator::writeOpCode(SpvOp_ opCode, int length, std::ostream& out) {
+void SPIRVCodeGenerator::writeOpCode(SpvOp_ opCode, int length, SkWStream& out) {
     ASSERT(opCode != SpvOpUndef);
     switch (opCode) {
         case SpvOpReturn:      // fall through
@@ -825,39 +830,39 @@ void SPIRVCodeGenerator::writeOpCode(SpvOp_ opCode, int length, std::ostream& ou
 #endif
 }
 
-void SPIRVCodeGenerator::writeLabel(SpvId label, std::ostream& out) {
+void SPIRVCodeGenerator::writeLabel(SpvId label, SkWStream& out) {
     fCurrentBlock = label;
     this->writeInstruction(SpvOpLabel, label, out);
 }
 
-void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, std::ostream& out) {
+void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, SkWStream& out) {
     this->writeOpCode(opCode, 1, out);
 }
 
-void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, std::ostream& out) {
+void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, SkWStream& out) {
     this->writeOpCode(opCode, 2, out);
     this->writeWord(word1, out);
 }
 
-void SPIRVCodeGenerator::writeString(const char* string, std::ostream& out) {
+void SPIRVCodeGenerator::writeString(const char* string, SkWStream& out) {
     size_t length = strlen(string);
-    out << string;
+    out.writeText(string);
     switch (length % 4) {
         case 1:
-            out << (char) 0;
+            out.write8(0);
             // fall through
         case 2:
-            out << (char) 0;
+            out.write8(0);
             // fall through
         case 3:
-            out << (char) 0;
+            out.write8(0);
             break;
         default:
             this->writeWord(0, out);
     }
 }
 
-void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, const char* string, std::ostream& out) {
+void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, const char* string, SkWStream& out) {
     int32_t length = (int32_t) strlen(string);
     this->writeOpCode(opCode, 1 + (length + 4) / 4, out);
     this->writeString(string, out);
@@ -865,7 +870,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, const char* string, std
 
 
 void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, const char* string, 
-                                          std::ostream& out) {
+                                          SkWStream& out) {
     int32_t length = (int32_t) strlen(string);
     this->writeOpCode(opCode, 2 + (length + 4) / 4, out);
     this->writeWord(word1, out);
@@ -873,7 +878,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, const ch
 }
 
 void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, 
-                                          const char* string, std::ostream& out) {
+                                          const char* string, SkWStream& out) {
     int32_t length = (int32_t) strlen(string);
     this->writeOpCode(opCode, 3 + (length + 4) / 4, out);
     this->writeWord(word1, out);
@@ -882,14 +887,14 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t
 }
 
 void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, 
-                                          std::ostream& out) {
+                                          SkWStream& out) {
     this->writeOpCode(opCode, 3, out);
     this->writeWord(word1, out);
     this->writeWord(word2, out);
 }
 
 void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, 
-                                          int32_t word3, std::ostream& out) {
+                                          int32_t word3, SkWStream& out) {
     this->writeOpCode(opCode, 4, out);
     this->writeWord(word1, out);
     this->writeWord(word2, out);
@@ -897,7 +902,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t
 }
 
 void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, 
-                                          int32_t word3, int32_t word4, std::ostream& out) {
+                                          int32_t word3, int32_t word4, SkWStream& out) {
     this->writeOpCode(opCode, 5, out);
     this->writeWord(word1, out);
     this->writeWord(word2, out);
@@ -907,7 +912,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t
 
 void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, 
                                           int32_t word3, int32_t word4, int32_t word5, 
-                                          std::ostream& out) {
+                                          SkWStream& out) {
     this->writeOpCode(opCode, 6, out);
     this->writeWord(word1, out);
     this->writeWord(word2, out);
@@ -918,7 +923,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t
 
 void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, 
                                           int32_t word3, int32_t word4, int32_t word5,
-                                          int32_t word6, std::ostream& out) {
+                                          int32_t word6, SkWStream& out) {
     this->writeOpCode(opCode, 7, out);
     this->writeWord(word1, out);
     this->writeWord(word2, out);
@@ -930,7 +935,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t
 
 void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, 
                                           int32_t word3, int32_t word4, int32_t word5,
-                                          int32_t word6, int32_t word7, std::ostream& out) {
+                                          int32_t word6, int32_t word7, SkWStream& out) {
     this->writeOpCode(opCode, 8, out);
     this->writeWord(word1, out);
     this->writeWord(word2, out);
@@ -944,7 +949,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t
 void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, 
                                           int32_t word3, int32_t word4, int32_t word5,
                                           int32_t word6, int32_t word7, int32_t word8,
-                                          std::ostream& out) {
+                                          SkWStream& out) {
     this->writeOpCode(opCode, 9, out);
     this->writeWord(word1, out);
     this->writeWord(word2, out);
@@ -956,7 +961,7 @@ void SPIRVCodeGenerator::writeInstruction(SpvOp_ opCode, int32_t word1, int32_t
     this->writeWord(word8, out);
 }
 
-void SPIRVCodeGenerator::writeCapabilities(std::ostream& out) {
+void SPIRVCodeGenerator::writeCapabilities(SkWStream& out) {
     for (uint64_t i = 0, bit = 1; i <= kLast_Capability; i++, bit <<= 1) {
         if (fCapabilities & bit) {
             this->writeInstruction(SpvOpCapability, (SpvId) i, out);
@@ -1007,7 +1012,6 @@ void SPIRVCodeGenerator::writeStruct(const Type& type, SpvId resultId) {
         if ((kind == Type::kArray_Kind || kind == Type::kStruct_Kind) && offset % alignment != 0) {
             offset += alignment - offset % alignment;
         }
-        ASSERT(offset % alignment == 0);
     }
 }
 
@@ -1082,8 +1086,8 @@ SpvId SPIRVCodeGenerator::getType(const Type& type) {
 }
 
 SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) {
-    std::string key = function.fReturnType.description() + "(";
-    std::string separator = "";
+    SkString key = function.fReturnType.description() + "(";
+    SkString separator;
     for (size_t i = 0; i < function.fParameters.size(); i++) {
         key += separator;
         separator = ", ";
@@ -1140,7 +1144,7 @@ SpvId SPIRVCodeGenerator::getFunctionType(const FunctionDeclaration& function) {
 
 SpvId SPIRVCodeGenerator::getPointerType(const Type& type, 
                                          SpvStorageClass_ storageClass) {
-    std::string key = type.description() + "*" + to_string(storageClass);
+    SkString key = type.description() + "*" + to_string(storageClass);
     auto entry = fTypeMap.find(key);
     if (entry == fTypeMap.end()) {
         SpvId result = this->nextId();
@@ -1152,7 +1156,7 @@ SpvId SPIRVCodeGenerator::getPointerType(const Type& type,
     return entry->second;
 }
 
-SpvId SPIRVCodeGenerator::writeExpression(const Expression& expr, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeExpression(const Expression& expr, SkWStream& out) {
     switch (expr.fKind) {
         case Expression::kBinary_Kind:
             return this->writeBinaryExpression((BinaryExpression&) expr, out);
@@ -1186,7 +1190,7 @@ SpvId SPIRVCodeGenerator::writeExpression(const Expression& expr, std::ostream&
     return -1;
 }
 
-SpvId SPIRVCodeGenerator::writeIntrinsicCall(const FunctionCall& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeIntrinsicCall(const FunctionCall& c, SkWStream& out) {
     auto intrinsic = fIntrinsicMap.find(c.fFunction.fName);
     ASSERT(intrinsic != fIntrinsicMap.end());
     const Type& type = c.fArguments[0]->fType;
@@ -1242,7 +1246,7 @@ SpvId SPIRVCodeGenerator::writeIntrinsicCall(const FunctionCall& c, std::ostream
 }
 
 SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind, 
-                                                std::ostream& out) {
+                                                SkWStream& out) {
     SpvId result = this->nextId();
     switch (kind) {
         case kAtan_SpecialIntrinsic: {
@@ -1306,7 +1310,7 @@ SpvId SPIRVCodeGenerator::writeSpecialIntrinsic(const FunctionCall& c, SpecialIn
     return result;
 }
 
-SpvId SPIRVCodeGenerator::writeFunctionCall(const FunctionCall& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeFunctionCall(const FunctionCall& c, SkWStream& out) {
     const auto& entry = fFunctionMap.find(&c.fFunction);
     if (entry == fFunctionMap.end()) {
         return this->writeIntrinsicCall(c, out);
@@ -1395,7 +1399,7 @@ SpvId SPIRVCodeGenerator::writeConstantVector(const Constructor& c) {
     return result;
 }
 
-SpvId SPIRVCodeGenerator::writeFloatConstructor(const Constructor& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeFloatConstructor(const Constructor& c, SkWStream& out) {
     ASSERT(c.fType == *fContext.fFloat_Type);
     ASSERT(c.fArguments.size() == 1);
     ASSERT(c.fArguments[0]->fType.isNumber());
@@ -1413,7 +1417,7 @@ SpvId SPIRVCodeGenerator::writeFloatConstructor(const Constructor& c, std::ostre
     return result;
 }
 
-SpvId SPIRVCodeGenerator::writeIntConstructor(const Constructor& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeIntConstructor(const Constructor& c, SkWStream& out) {
     ASSERT(c.fType == *fContext.fInt_Type);
     ASSERT(c.fArguments.size() == 1);
     ASSERT(c.fArguments[0]->fType.isNumber());
@@ -1431,7 +1435,7 @@ SpvId SPIRVCodeGenerator::writeIntConstructor(const Constructor& c, std::ostream
     return result;
 }
 
-SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, SkWStream& out) {
     ASSERT(c.fType.kind() == Type::kMatrix_Kind);
     // go ahead and write the arguments so we don't try to write new instructions in the middle of
     // an instruction
@@ -1503,7 +1507,7 @@ SpvId SPIRVCodeGenerator::writeMatrixConstructor(const Constructor& c, std::ostr
     return result;
 }
 
-SpvId SPIRVCodeGenerator::writeVectorConstructor(const Constructor& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeVectorConstructor(const Constructor& c, SkWStream& out) {
     ASSERT(c.fType.kind() == Type::kVector_Kind);
     if (c.isConstant()) {
         return this->writeConstantVector(c);
@@ -1533,7 +1537,7 @@ SpvId SPIRVCodeGenerator::writeVectorConstructor(const Constructor& c, std::ostr
     return result;
 }
 
-SpvId SPIRVCodeGenerator::writeConstructor(const Constructor& c, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeConstructor(const Constructor& c, SkWStream& out) {
     if (c.fType == *fContext.fFloat_Type) {
         return this->writeFloatConstructor(c, out);
     } else if (c.fType == *fContext.fInt_Type) {
@@ -1574,7 +1578,7 @@ SpvStorageClass_ get_storage_class(const Expression& expr) {
     }
 }
 
-std::vector<SpvId> SPIRVCodeGenerator::getAccessChain(const Expression& expr, std::ostream& out) {
+std::vector<SpvId> SPIRVCodeGenerator::getAccessChain(const Expression& expr, SkWStream& out) {
     std::vector<SpvId> chain;
     switch (expr.fKind) {
         case Expression::kIndex_Kind: {
@@ -1607,13 +1611,13 @@ public:
         return fPointer;
     }
 
-    virtual SpvId load(std::ostream& out) override {
+    virtual SpvId load(SkWStream& out) override {
         SpvId result = fGen.nextId();
         fGen.writeInstruction(SpvOpLoad, fType, result, fPointer, out);
         return result;
     }
 
-    virtual void store(SpvId value, std::ostream& out) override {
+    virtual void store(SpvId value, SkWStream& out) override {
         fGen.writeInstruction(SpvOpStore, fPointer, value, out);
     }
 
@@ -1637,7 +1641,7 @@ public:
         return 0;
     }
 
-    virtual SpvId load(std::ostream& out) override {
+    virtual SpvId load(SkWStream& out) override {
         SpvId base = fGen.nextId();
         fGen.writeInstruction(SpvOpLoad, fGen.getType(fBaseType), base, fVecPointer, out);
         SpvId result = fGen.nextId();
@@ -1652,7 +1656,7 @@ public:
         return result;
     }
 
-    virtual void store(SpvId value, std::ostream& out) override {
+    virtual void store(SpvId value, SkWStream& out) override {
         // use OpVectorShuffle to mix and match the vector components. We effectively create
         // a virtual vector out of the concatenation of the left and right vectors, and then
         // select components from this virtual vector to make the result vector. For 
@@ -1699,7 +1703,7 @@ private:
 };
 
 std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const Expression& expr, 
-                                                                          std::ostream& out) {
+                                                                          SkWStream& out) {
     switch (expr.fKind) {
         case Expression::kVariableReference_Kind: {
             const Variable& var = ((VariableReference&) expr).fVariable;
@@ -1772,7 +1776,7 @@ std::unique_ptr<SPIRVCodeGenerator::LValue> SPIRVCodeGenerator::getLValue(const
     }
 }
 
-SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, SkWStream& out) {
     auto entry = fVariableMap.find(&ref.fVariable);
     ASSERT(entry != fVariableMap.end());
     SpvId var = entry->second;
@@ -1781,15 +1785,15 @@ SpvId SPIRVCodeGenerator::writeVariableReference(const VariableReference& ref, s
     return result;
 }
 
-SpvId SPIRVCodeGenerator::writeIndexExpression(const IndexExpression& expr, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeIndexExpression(const IndexExpression& expr, SkWStream& out) {
     return getLValue(expr, out)->load(out);
 }
 
-SpvId SPIRVCodeGenerator::writeFieldAccess(const FieldAccess& f, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeFieldAccess(const FieldAccess& f, SkWStream& out) {
     return getLValue(f, out)->load(out);
 }
 
-SpvId SPIRVCodeGenerator::writeSwizzle(const Swizzle& swizzle, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeSwizzle(const Swizzle& swizzle, SkWStream& out) {
     SpvId base = this->writeExpression(*swizzle.fBase, out);
     SpvId result = this->nextId();
     size_t count = swizzle.fComponents.size();
@@ -1812,7 +1816,7 @@ SpvId SPIRVCodeGenerator::writeSwizzle(const Swizzle& swizzle, std::ostream& out
 SpvId SPIRVCodeGenerator::writeBinaryOperation(const Type& resultType, 
                                                const Type& operandType, SpvId lhs, 
                                                SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt, 
-                                               SpvOp_ ifUInt, SpvOp_ ifBool, std::ostream& out) {
+                                               SpvOp_ ifUInt, SpvOp_ ifBool, SkWStream& out) {
     SpvId result = this->nextId();
     if (is_float(fContext, operandType)) {
         this->writeInstruction(ifFloat, this->getType(resultType), result, lhs, rhs, out);
@@ -1850,7 +1854,7 @@ bool is_assignment(Token::Kind op) {
     }
 }
 
-SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, SkWStream& out) {
     // handle cases where we don't necessarily evaluate both LHS and RHS
     switch (b.fOperator) {
         case Token::EQ: {
@@ -2042,7 +2046,7 @@ SpvId SPIRVCodeGenerator::writeBinaryExpression(const BinaryExpression& b, std::
     }
 }
 
-SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, SkWStream& out) {
     ASSERT(a.fOperator == Token::LOGICALAND);
     BoolLiteral falseLiteral(fContext, Position(), false);
     SpvId falseConstant = this->writeBoolLiteral(falseLiteral);
@@ -2063,7 +2067,7 @@ SpvId SPIRVCodeGenerator::writeLogicalAnd(const BinaryExpression& a, std::ostrea
     return result;
 }
 
-SpvId SPIRVCodeGenerator::writeLogicalOr(const BinaryExpression& o, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeLogicalOr(const BinaryExpression& o, SkWStream& out) {
     ASSERT(o.fOperator == Token::LOGICALOR);
     BoolLiteral trueLiteral(fContext, Position(), true);
     SpvId trueConstant = this->writeBoolLiteral(trueLiteral);
@@ -2084,7 +2088,7 @@ SpvId SPIRVCodeGenerator::writeLogicalOr(const BinaryExpression& o, std::ostream
     return result;
 }
 
-SpvId SPIRVCodeGenerator::writeTernaryExpression(const TernaryExpression& t, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeTernaryExpression(const TernaryExpression& t, SkWStream& out) {
     SpvId test = this->writeExpression(*t.fTest, out);
     if (t.fIfTrue->isConstant() && t.fIfFalse->isConstant()) {
         // both true and false are constants, can just use OpSelect
@@ -2128,7 +2132,7 @@ std::unique_ptr<Expression> create_literal_1(const Context& context, const Type&
     }
 }
 
-SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, SkWStream& out) {
     if (p.fOperator == Token::MINUS) {
         SpvId result = this->nextId();
         SpvId typeId = this->getType(p.fType);
@@ -2181,7 +2185,7 @@ SpvId SPIRVCodeGenerator::writePrefixExpression(const PrefixExpression& p, std::
     }
 }
 
-SpvId SPIRVCodeGenerator::writePostfixExpression(const PostfixExpression& p, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writePostfixExpression(const PostfixExpression& p, SkWStream& out) {
     std::unique_ptr<LValue> lv = this->getLValue(*p.fOperand, out);
     SpvId result = lv->load(out);
     SpvId one = this->writeExpression(*create_literal_1(fContext, p.fType), out);
@@ -2278,7 +2282,7 @@ SpvId SPIRVCodeGenerator::writeFloatLiteral(const FloatLiteral& f) {
     }
 }
 
-SpvId SPIRVCodeGenerator::writeFunctionStart(const FunctionDeclaration& f, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeFunctionStart(const FunctionDeclaration& f, SkWStream& out) {
     SpvId result = fFunctionMap[&f];
     this->writeInstruction(SpvOpFunction, this->getType(f.fReturnType), result, 
                            SpvFunctionControlMaskNone, this->getFunctionType(f), out);
@@ -2293,17 +2297,16 @@ SpvId SPIRVCodeGenerator::writeFunctionStart(const FunctionDeclaration& f, std::
     return result;
 }
 
-SpvId SPIRVCodeGenerator::writeFunction(const FunctionDefinition& f, std::ostream& out) {
+SpvId SPIRVCodeGenerator::writeFunction(const FunctionDefinition& f, SkWStream& out) {
     SpvId result = this->writeFunctionStart(f.fDeclaration, out);
     this->writeLabel(this->nextId(), out);
     if (f.fDeclaration.fName == "main") {
-        out << fGlobalInitializersBuffer.str();
+        write_data(*fGlobalInitializersBuffer.detachAsData(), out);
     }
-    std::stringstream bodyBuffer;
+    SkDynamicMemoryWStream bodyBuffer;
     this->writeBlock(*f.fBody, bodyBuffer);
-    out << fVariableBuffer.str();
-    fVariableBuffer.str("");
-    out << bodyBuffer.str();
+    write_data(*fVariableBuffer.detachAsData(), out);
+    write_data(*bodyBuffer.detachAsData(), out);
     if (fCurrentBlock) {
         this->writeInstruction(SpvOpReturn, out);
     }
@@ -2372,7 +2375,7 @@ SpvId SPIRVCodeGenerator::writeInterfaceBlock(const InterfaceBlock& intf) {
 
 #define BUILTIN_IGNORE 9999
 void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclarations& decl, 
-                                         std::ostream& out) {
+                                         SkWStream& out) {
     for (size_t i = 0; i < decl.fVars.size(); i++) {
         const VarDeclaration& varDecl = decl.fVars[i];
         const Variable* var = varDecl.fVar;
@@ -2427,7 +2430,7 @@ void SPIRVCodeGenerator::writeGlobalVars(Program::Kind kind, const VarDeclaratio
     }
 }
 
-void SPIRVCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, std::ostream& out) {
+void SPIRVCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, SkWStream& out) {
     for (const auto& varDecl : decl.fVars) {
         const Variable* var = varDecl.fVar;
         SpvId id = this->nextId();
@@ -2442,7 +2445,7 @@ void SPIRVCodeGenerator::writeVarDeclarations(const VarDeclarations& decl, std::
     }
 }
 
-void SPIRVCodeGenerator::writeStatement(const Statement& s, std::ostream& out) {
+void SPIRVCodeGenerator::writeStatement(const Statement& s, SkWStream& out) {
     switch (s.fKind) {
         case Statement::kBlock_Kind:
             this->writeBlock((Block&) s, out);
@@ -2476,13 +2479,13 @@ void SPIRVCodeGenerator::writeStatement(const Statement& s, std::ostream& out) {
     }
 }
 
-void SPIRVCodeGenerator::writeBlock(const Block& b, std::ostream& out) {
+void SPIRVCodeGenerator::writeBlock(const Block& b, SkWStream& out) {
     for (size_t i = 0; i < b.fStatements.size(); i++) {
         this->writeStatement(*b.fStatements[i], out);
     }
 }
 
-void SPIRVCodeGenerator::writeIfStatement(const IfStatement& stmt, std::ostream& out) {
+void SPIRVCodeGenerator::writeIfStatement(const IfStatement& stmt, SkWStream& out) {
     SpvId test = this->writeExpression(*stmt.fTest, out);
     SpvId ifTrue = this->nextId();
     SpvId ifFalse = this->nextId();
@@ -2513,7 +2516,7 @@ void SPIRVCodeGenerator::writeIfStatement(const IfStatement& stmt, std::ostream&
     }
 }
 
-void SPIRVCodeGenerator::writeForStatement(const ForStatement& f, std::ostream& out) {
+void SPIRVCodeGenerator::writeForStatement(const ForStatement& f, SkWStream& out) {
     if (f.fInitializer) {
         this->writeStatement(*f.fInitializer, out);
     }
@@ -2548,7 +2551,7 @@ void SPIRVCodeGenerator::writeForStatement(const ForStatement& f, std::ostream&
     fContinueTarget.pop();
 }
 
-void SPIRVCodeGenerator::writeReturnStatement(const ReturnStatement& r, std::ostream& out) {
+void SPIRVCodeGenerator::writeReturnStatement(const ReturnStatement& r, SkWStream& out) {
     if (r.fExpression) {
         this->writeInstruction(SpvOpReturnValue, this->writeExpression(*r.fExpression, out), 
                                out);
@@ -2557,9 +2560,9 @@ void SPIRVCodeGenerator::writeReturnStatement(const ReturnStatement& r, std::ost
     }
 }
 
-void SPIRVCodeGenerator::writeInstructions(const Program& program, std::ostream& out) {
+void SPIRVCodeGenerator::writeInstructions(const Program& program, SkWStream& out) {
     fGLSLExtendedInstructions = this->nextId();
-    std::stringstream body;
+    SkDynamicMemoryWStream body;
     std::vector<SpvId> interfaceVars;
     // assign IDs to functions
     for (size_t i = 0; i < program.fElements.size(); i++) {
@@ -2636,22 +2639,22 @@ void SPIRVCodeGenerator::writeInstructions(const Program& program, std::ostream&
         }
     }
     
-    out << fNameBuffer.str();
-    out << fDecorationBuffer.str();
-    out << fConstantBuffer.str();
-    out << fExternalFunctionsBuffer.str();
-    out << body.str();
+    write_data(*fNameBuffer.detachAsData(), out);
+    write_data(*fDecorationBuffer.detachAsData(), out);
+    write_data(*fConstantBuffer.detachAsData(), out);
+    write_data(*fExternalFunctionsBuffer.detachAsData(), out);
+    write_data(*body.detachAsData(), out);
 }
 
-void SPIRVCodeGenerator::generateCode(const Program& program, std::ostream& out) {
+void SPIRVCodeGenerator::generateCode(const Program& program, SkWStream& out) {
     this->writeWord(SpvMagicNumber, out);
     this->writeWord(SpvVersion, out);
     this->writeWord(SKSL_MAGIC, out);
-    std::stringstream buffer;
+    SkDynamicMemoryWStream buffer;
     this->writeInstructions(program, buffer);
     this->writeWord(fIdCount, out);
     this->writeWord(0, out); // reserved, always zero
-    out << buffer.str();
+    write_data(*buffer.detachAsData(), out);
 }
 
 }
index e6fc28e..84c582e 100644 (file)
@@ -8,11 +8,11 @@
 #ifndef SKSL_SPIRVCODEGENERATOR
 #define SKSL_SPIRVCODEGENERATOR
 
-#include <sstream>
 #include <stack>
 #include <tuple>
 #include <unordered_map>
 
+#include "SkStream.h"
 #include "SkSLCodeGenerator.h"
 #include "ir/SkSLBinaryExpression.h"
 #include "ir/SkSLBoolLiteral.h"
@@ -56,9 +56,9 @@ public:
         // by a pointer (e.g. vector swizzles), returns 0.
         virtual SpvId getPointer() = 0;
 
-        virtual SpvId load(std::ostream& out) = 0;
+        virtual SpvId load(SkWStream& out) = 0;
 
-        virtual void store(SpvId value, std::ostream& out) = 0;
+        virtual void store(SpvId value, SkWStream& out) = 0;
     };
 
     SPIRVCodeGenerator(const Context* context)
@@ -71,7 +71,7 @@ public:
         this->setupIntrinsics();
     }
 
-    void generateCode(const Program& program, std::ostream& out) override;
+    void generateCode(const Program& program, SkWStream& out) override;
 
 private:
     enum IntrinsicKind {
@@ -97,7 +97,7 @@ private:
 
     SpvId getPointerType(const Type& type, SpvStorageClass_ storageClass);
 
-    std::vector<SpvId> getAccessChain(const Expression& expr, std::ostream& out);
+    std::vector<SpvId> getAccessChain(const Expression& expr, SkWStream& out);
 
     void writeLayout(const Layout& layout, SpvId target);
 
@@ -105,68 +105,68 @@ private:
 
     void writeStruct(const Type& type, SpvId resultId);
 
-    void writeProgramElement(const ProgramElement& pe, std::ostream& out);
+    void writeProgramElement(const ProgramElement& pe, SkWStream& out);
 
     SpvId writeInterfaceBlock(const InterfaceBlock& intf);
 
-    SpvId writeFunctionStart(const FunctionDeclaration& f, std::ostream& out);
+    SpvId writeFunctionStart(const FunctionDeclaration& f, SkWStream& out);
     
-    SpvId writeFunctionDeclaration(const FunctionDeclaration& f, std::ostream& out);
+    SpvId writeFunctionDeclaration(const FunctionDeclaration& f, SkWStream& out);
 
-    SpvId writeFunction(const FunctionDefinition& f, std::ostream& out);
+    SpvId writeFunction(const FunctionDefinition& f, SkWStream& out);
 
-    void writeGlobalVars(Program::Kind kind, const VarDeclarations& v, std::ostream& out);
+    void writeGlobalVars(Program::Kind kind, const VarDeclarations& v, SkWStream& out);
 
-    void writeVarDeclarations(const VarDeclarations& decl, std::ostream& out);
+    void writeVarDeclarations(const VarDeclarations& decl, SkWStream& out);
 
-    SpvId writeVariableReference(const VariableReference& ref, std::ostream& out);
+    SpvId writeVariableReference(const VariableReference& ref, SkWStream& out);
 
-    std::unique_ptr<LValue> getLValue(const Expression& value, std::ostream& out);
+    std::unique_ptr<LValue> getLValue(const Expression& value, SkWStream& out);
 
-    SpvId writeExpression(const Expression& expr, std::ostream& out);
+    SpvId writeExpression(const Expression& expr, SkWStream& out);
     
-    SpvId writeIntrinsicCall(const FunctionCall& c, std::ostream& out);
+    SpvId writeIntrinsicCall(const FunctionCall& c, SkWStream& out);
 
-    SpvId writeFunctionCall(const FunctionCall& c, std::ostream& out);
+    SpvId writeFunctionCall(const FunctionCall& c, SkWStream& out);
 
-    SpvId writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind, std::ostream& out);
+    SpvId writeSpecialIntrinsic(const FunctionCall& c, SpecialIntrinsic kind, SkWStream& out);
 
     SpvId writeConstantVector(const Constructor& c);
 
-    SpvId writeFloatConstructor(const Constructor& c, std::ostream& out);
+    SpvId writeFloatConstructor(const Constructor& c, SkWStream& out);
 
-    SpvId writeIntConstructor(const Constructor& c, std::ostream& out);
+    SpvId writeIntConstructor(const Constructor& c, SkWStream& out);
     
-    SpvId writeMatrixConstructor(const Constructor& c, std::ostream& out);
+    SpvId writeMatrixConstructor(const Constructor& c, SkWStream& out);
 
-    SpvId writeVectorConstructor(const Constructor& c, std::ostream& out);
+    SpvId writeVectorConstructor(const Constructor& c, SkWStream& out);
 
-    SpvId writeConstructor(const Constructor& c, std::ostream& out);
+    SpvId writeConstructor(const Constructor& c, SkWStream& out);
 
-    SpvId writeFieldAccess(const FieldAccess& f, std::ostream& out);
+    SpvId writeFieldAccess(const FieldAccess& f, SkWStream& out);
 
-    SpvId writeSwizzle(const Swizzle& swizzle, std::ostream& out);
+    SpvId writeSwizzle(const Swizzle& swizzle, SkWStream& out);
 
     SpvId writeBinaryOperation(const Type& resultType, const Type& operandType, SpvId lhs, 
                                SpvId rhs, SpvOp_ ifFloat, SpvOp_ ifInt, SpvOp_ ifUInt, 
-                               SpvOp_ ifBool, std::ostream& out);
+                               SpvOp_ ifBool, SkWStream& out);
 
     SpvId writeBinaryOperation(const BinaryExpression& expr, SpvOp_ ifFloat, SpvOp_ ifInt, 
-                               SpvOp_ ifUInt, std::ostream& out);
+                               SpvOp_ ifUInt, SkWStream& out);
 
-    SpvId writeBinaryExpression(const BinaryExpression& b, std::ostream& out);
+    SpvId writeBinaryExpression(const BinaryExpression& b, SkWStream& out);
 
-    SpvId writeTernaryExpression(const TernaryExpression& t, std::ostream& out);
+    SpvId writeTernaryExpression(const TernaryExpression& t, SkWStream& out);
 
-    SpvId writeIndexExpression(const IndexExpression& expr, std::ostream& out);
+    SpvId writeIndexExpression(const IndexExpression& expr, SkWStream& out);
 
-    SpvId writeLogicalAnd(const BinaryExpression& b, std::ostream& out);
+    SpvId writeLogicalAnd(const BinaryExpression& b, SkWStream& out);
 
-    SpvId writeLogicalOr(const BinaryExpression& o, std::ostream& out);
+    SpvId writeLogicalOr(const BinaryExpression& o, SkWStream& out);
 
-    SpvId writePrefixExpression(const PrefixExpression& p, std::ostream& out);
+    SpvId writePrefixExpression(const PrefixExpression& p, SkWStream& out);
 
-    SpvId writePostfixExpression(const PostfixExpression& p, std::ostream& out);
+    SpvId writePostfixExpression(const PostfixExpression& p, SkWStream& out);
 
     SpvId writeBoolLiteral(const BoolLiteral& b);
 
@@ -174,59 +174,59 @@ private:
 
     SpvId writeFloatLiteral(const FloatLiteral& f);
 
-    void writeStatement(const Statement& s, std::ostream& out);
+    void writeStatement(const Statement& s, SkWStream& out);
 
-    void writeBlock(const Block& b, std::ostream& out);
+    void writeBlock(const Block& b, SkWStream& out);
 
-    void writeIfStatement(const IfStatement& stmt, std::ostream& out);
+    void writeIfStatement(const IfStatement& stmt, SkWStream& out);
 
-    void writeForStatement(const ForStatement& f, std::ostream& out);
+    void writeForStatement(const ForStatement& f, SkWStream& out);
 
-    void writeReturnStatement(const ReturnStatement& r, std::ostream& out);
+    void writeReturnStatement(const ReturnStatement& r, SkWStream& out);
 
-    void writeCapabilities(std::ostream& out);
+    void writeCapabilities(SkWStream& out);
 
-    void writeInstructions(const Program& program, std::ostream& out);
+    void writeInstructions(const Program& program, SkWStream& out);
 
-    void writeOpCode(SpvOp_ opCode, int length, std::ostream& out);
+    void writeOpCode(SpvOp_ opCode, int length, SkWStream& out);
 
-    void writeWord(int32_t word, std::ostream& out);
+    void writeWord(int32_t word, SkWStream& out);
 
-    void writeString(const char* string, std::ostream& out);
+    void writeString(const char* string, SkWStream& out);
 
-    void writeLabel(SpvId id, std::ostream& out);
+    void writeLabel(SpvId id, SkWStream& out);
 
-    void writeInstruction(SpvOp_ opCode, std::ostream& out);
+    void writeInstruction(SpvOp_ opCode, SkWStream& out);
 
-    void writeInstruction(SpvOp_ opCode, const char* string, std::ostream& out);
+    void writeInstruction(SpvOp_ opCode, const char* string, SkWStream& out);
 
-    void writeInstruction(SpvOp_ opCode, int32_t word1, std::ostream& out);
+    void writeInstruction(SpvOp_ opCode, int32_t word1, SkWStream& out);
 
-    void writeInstruction(SpvOp_ opCode, int32_t word1, const char* string, std::ostream& out);
+    void writeInstruction(SpvOp_ opCode, int32_t word1, const char* string, SkWStream& out);
 
     void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, const char* string,
-                          std::ostream& out);
+                          SkWStream& out);
 
-    void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, std::ostream& out);
+    void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, SkWStream& out);
 
     void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, 
-                          std::ostream& out);
+                          SkWStream& out);
 
     void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
-                          std::ostream& out);
+                          SkWStream& out);
 
     void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
-                          int32_t word5, std::ostream& out);
+                          int32_t word5, SkWStream& out);
 
     void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
-                          int32_t word5, int32_t word6, std::ostream& out);
+                          int32_t word5, int32_t word6, SkWStream& out);
 
     void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
-                          int32_t word5, int32_t word6, int32_t word7, std::ostream& out);
+                          int32_t word5, int32_t word6, int32_t word7, SkWStream& out);
 
     void writeInstruction(SpvOp_ opCode, int32_t word1, int32_t word2, int32_t word3, int32_t word4,
                           int32_t word5, int32_t word6, int32_t word7, int32_t word8, 
-                          std::ostream& out);
+                          SkWStream& out);
 
     const Context& fContext;
 
@@ -234,18 +234,18 @@ private:
     SpvId fIdCount;
     SpvId fGLSLExtendedInstructions;
     typedef std::tuple<IntrinsicKind, int32_t, int32_t, int32_t, int32_t> Intrinsic;
-    std::unordered_map<std::string, Intrinsic> fIntrinsicMap;
+    std::unordered_map<SkString, Intrinsic> fIntrinsicMap;
     std::unordered_map<const FunctionDeclaration*, SpvId> fFunctionMap;
     std::unordered_map<const Variable*, SpvId> fVariableMap;
     std::unordered_map<const Variable*, int32_t> fInterfaceBlockMap;
-    std::unordered_map<std::string, SpvId> fTypeMap;
-    std::stringstream fCapabilitiesBuffer;
-    std::stringstream fGlobalInitializersBuffer;
-    std::stringstream fConstantBuffer;
-    std::stringstream fExternalFunctionsBuffer;
-    std::stringstream fVariableBuffer;
-    std::stringstream fNameBuffer;
-    std::stringstream fDecorationBuffer;
+    std::unordered_map<SkString, SpvId> fTypeMap;
+    SkDynamicMemoryWStream fCapabilitiesBuffer;
+    SkDynamicMemoryWStream fGlobalInitializersBuffer;
+    SkDynamicMemoryWStream fConstantBuffer;
+    SkDynamicMemoryWStream fExternalFunctionsBuffer;
+    SkDynamicMemoryWStream fVariableBuffer;
+    SkDynamicMemoryWStream fNameBuffer;
+    SkDynamicMemoryWStream fDecorationBuffer;
 
     SpvId fBoolTrue;
     SpvId fBoolFalse;
index 76a1df7..6fe130f 100644 (file)
@@ -103,45 +103,45 @@ struct Token {
         INVALID_TOKEN
     };
 
-    static std::string OperatorName(Kind kind) {
+    static SkString OperatorName(Kind kind) {
         switch (kind) {
-            case Token::PLUS:         return "+";
-            case Token::MINUS:        return "-";
-            case Token::STAR:         return "*";
-            case Token::SLASH:        return "/";
-            case Token::PERCENT:      return "%";
-            case Token::SHL:          return "<<";
-            case Token::SHR:          return ">>";
-            case Token::LOGICALNOT:   return "!";
-            case Token::LOGICALAND:   return "&&";
-            case Token::LOGICALOR:    return "||";
-            case Token::LOGICALXOR:   return "^^";
-            case Token::BITWISENOT:   return "~";
-            case Token::BITWISEAND:   return "&";
-            case Token::BITWISEOR:    return "|";
-            case Token::BITWISEXOR:   return "^";
-            case Token::EQ:           return "=";
-            case Token::EQEQ:         return "==";
-            case Token::NEQ:          return "!=";
-            case Token::LT:           return "<";
-            case Token::GT:           return ">";
-            case Token::LTEQ:         return "<=";
-            case Token::GTEQ:         return ">=";
-            case Token::PLUSEQ:       return "+=";
-            case Token::MINUSEQ:      return "-=";
-            case Token::STAREQ:       return "*=";
-            case Token::SLASHEQ:      return "/=";
-            case Token::PERCENTEQ:    return "%=";
-            case Token::SHLEQ:        return "<<=";
-            case Token::SHREQ:        return ">>=";
-            case Token::LOGICALANDEQ: return "&&=";
-            case Token::LOGICALOREQ:  return "||=";
-            case Token::LOGICALXOREQ: return "^^=";
-            case Token::BITWISEANDEQ: return "&=";
-            case Token::BITWISEOREQ:  return "|=";
-            case Token::BITWISEXOREQ: return "^=";
-            case Token::PLUSPLUS:     return "++";
-            case Token::MINUSMINUS:   return "--";
+            case Token::PLUS:         return SkString("+");
+            case Token::MINUS:        return SkString("-");
+            case Token::STAR:         return SkString("*");
+            case Token::SLASH:        return SkString("/");
+            case Token::PERCENT:      return SkString("%");
+            case Token::SHL:          return SkString("<<");
+            case Token::SHR:          return SkString(">>");
+            case Token::LOGICALNOT:   return SkString("!");
+            case Token::LOGICALAND:   return SkString("&&");
+            case Token::LOGICALOR:    return SkString("||");
+            case Token::LOGICALXOR:   return SkString("^^");
+            case Token::BITWISENOT:   return SkString("~");
+            case Token::BITWISEAND:   return SkString("&");
+            case Token::BITWISEOR:    return SkString("|");
+            case Token::BITWISEXOR:   return SkString("^");
+            case Token::EQ:           return SkString("=");
+            case Token::EQEQ:         return SkString("==");
+            case Token::NEQ:          return SkString("!=");
+            case Token::LT:           return SkString("<");
+            case Token::GT:           return SkString(">");
+            case Token::LTEQ:         return SkString("<=");
+            case Token::GTEQ:         return SkString(">=");
+            case Token::PLUSEQ:       return SkString("+=");
+            case Token::MINUSEQ:      return SkString("-=");
+            case Token::STAREQ:       return SkString("*=");
+            case Token::SLASHEQ:      return SkString("/=");
+            case Token::PERCENTEQ:    return SkString("%=");
+            case Token::SHLEQ:        return SkString("<<=");
+            case Token::SHREQ:        return SkString(">>=");
+            case Token::LOGICALANDEQ: return SkString("&&=");
+            case Token::LOGICALOREQ:  return SkString("||=");
+            case Token::LOGICALXOREQ: return SkString("^^=");
+            case Token::BITWISEANDEQ: return SkString("&=");
+            case Token::BITWISEOREQ:  return SkString("|=");
+            case Token::BITWISEXOREQ: return SkString("^=");
+            case Token::PLUSPLUS:     return SkString("++");
+            case Token::MINUSMINUS:   return SkString("--");
             default:
                 ABORT("unsupported operator: %d\n", kind); 
         }        
@@ -150,7 +150,7 @@ struct Token {
     Token() {
     }
 
-    Token(Position position, Kind kind, std::string text)
+    Token(Position position, Kind kind, SkString text)
     : fPosition(position)
     , fKind(kind)
     , fText(std::move(text)) {}
@@ -159,7 +159,7 @@ struct Token {
     Kind fKind;
     // will be the empty string unless the token has variable text content (identifiers, numeric
     // literals, and directives)
-    std::string fText;
+    SkString fText;
 };
 
 } // namespace
index 51ad9fe..97b5179 100644 (file)
@@ -7,61 +7,63 @@
 
 #include "SkSLUtil.h"
 
+#include <cinttypes>
+
 namespace SkSL {
 
-std::string to_string(double value) {
-    std::stringstream buffer;
-    buffer << std::setprecision(std::numeric_limits<double>::digits10) << value;
-    std::string result = buffer.str();
-    if (result.find_last_of(".") == std::string::npos && 
-        result.find_last_of("e") == std::string::npos) {
+SkString to_string(double value) {
+#ifdef SK_BUILD_FOR_WIN
+    #define SNPRINTF    _snprintf
+#else
+    #define SNPRINTF    snprintf
+#endif
+#define MAX_DOUBLE_CHARS 25
+    char buffer[MAX_DOUBLE_CHARS];
+    SkDEBUGCODE(int len = )SNPRINTF(buffer, sizeof(buffer), "%.17g", value);
+    ASSERT(len < MAX_DOUBLE_CHARS);
+    SkString result(buffer);
+    if (!strchr(buffer, '.') && !strchr(buffer, 'e')) {
         result += ".0";
     }
     return result;
+#undef SNPRINTF
+#undef MAX_DOUBLE_CHARS
 }
 
-std::string to_string(int32_t value) {
-    std::stringstream buffer;
-    buffer << value;
-    return buffer.str();
+SkString to_string(int32_t value) {
+    return SkStringPrintf("%d", value);
 }
 
-std::string to_string(uint32_t value) {
-    std::stringstream buffer;
-    buffer << value;
-    return buffer.str();
+SkString to_string(uint32_t value) {
+    return SkStringPrintf("%u", value);
 }
 
-std::string to_string(int64_t value) {
-    std::stringstream buffer;
-    buffer << value;
-    return buffer.str();
+SkString to_string(int64_t value) {
+    return SkStringPrintf("%" PRId64, value);
 }
 
-std::string to_string(uint64_t value) {
-    std::stringstream buffer;
-    buffer << value;
-    return buffer.str();
+SkString to_string(uint64_t value) {
+    return SkStringPrintf("%" PRIu64, value);
 }
 
-int stoi(std::string s) {
+int stoi(SkString s) {
     if (s.size() > 2 && s[0] == '0' && s[1] == 'x') {
         char* p;
-        int result = strtoul(s.substr(2).c_str(), &p, 16);
+        int result = strtoul(s.c_str() + 2, &p, 16);
         ASSERT(*p == 0);
         return result;
     }
     return atoi(s.c_str());
 }
 
-double stod(std::string s) {
+double stod(SkString s) {
     return atof(s.c_str());
 }
 
-long stol(std::string s) {
+long stol(SkString s) {
     if (s.size() > 2 && s[0] == '0' && s[1] == 'x') {
         char* p;
-        long result = strtoul(s.substr(2).c_str(), &p, 16);
+        long result = strtoul(s.c_str() + 2, &p, 16);
         ASSERT(*p == 0);
         return result;
     }
@@ -77,4 +79,37 @@ void sksl_abort() {
 #endif
 }
 
+void write_data(const SkData& data, SkWStream& out) {
+    out.write(data.data(), data.size());
+}
+
+SkString operator+(const SkString& s, const char* c) {
+    SkString result(s);
+    result += c;
+    return result;
+}
+
+SkString operator+(const char* c, const SkString& s) {
+    SkString result(c);
+    result += s;
+    return result;
+}
+
+SkString operator+(const SkString& s1, const SkString& s2) {
+    SkString result(s1);
+    result += s2;
+    return result;
+}
+
+bool operator==(const SkString& s1, const char* s2) {
+    return !strcmp(s1.c_str(), s2);
+}
+
+bool operator!=(const SkString& s1, const char* s2) {
+    return strcmp(s1.c_str(), s2);
+}
+
+bool operator!=(const char* s1, const SkString& s2) {
+    return strcmp(s1, s2.c_str());
+}
 } // namespace
index ede2183..ad8287e 100644 (file)
@@ -8,12 +8,12 @@
 #ifndef SKSL_UTIL
 #define SKSL_UTIL
 
-#include <iomanip>
-#include <string>
-#include <sstream>
 #include "stdlib.h"
 #include "assert.h"
+#include "SkOpts.h"
 #include "SkRefCnt.h"
+#include "SkStream.h"
+#include "SkString.h"
 #include "SkTypes.h"
 #include "glsl/GrGLSLCaps.h"
 #include "GrContextOptions.h"
@@ -73,40 +73,47 @@ public:
     }
 };
 
-// our own definitions of certain std:: functions, because they are not always present on Android
+void write_data(const SkData& d, SkWStream& out);
 
-std::string to_string(double value);
+SkString operator+(const SkString& s, const char* c);
 
-std::string to_string(int32_t value);
+SkString operator+(const char* c, const SkString& s);
 
-std::string to_string(uint32_t value);
+SkString operator+(const SkString& s1, const SkString& s2);
 
-std::string to_string(int64_t value);
+bool operator==(const SkString& s1, const char* s2);
 
-std::string to_string(uint64_t value);
+bool operator!=(const SkString& s1, const char* s2);
+
+bool operator!=(const char* s1, const SkString& s2);
+
+SkString to_string(double value);
+
+SkString to_string(int32_t value);
+
+SkString to_string(uint32_t value);
+
+SkString to_string(int64_t value);
+
+SkString to_string(uint64_t value);
 
 #if _MSC_VER
 #define NORETURN __declspec(noreturn)
 #else
 #define NORETURN __attribute__((__noreturn__))
 #endif
-int stoi(std::string s);
+int stoi(SkString s);
 
-double stod(std::string s);
+double stod(SkString s);
 
-long stol(std::string s);
+long stol(SkString s);
 
 NORETURN void sksl_abort();
 
 } // namespace
 
-#ifdef DEBUG
-#define ASSERT(x) assert(x)
-#define ASSERT_RESULT(x) ASSERT(x);
-#else
-#define ASSERT(x)
-#define ASSERT_RESULT(x) x
-#endif
+#define ASSERT(x) SkASSERT(x)
+#define ASSERT_RESULT(x) SkAssertResult(x);
 
 #ifdef SKIA
 #define ABORT(...) { SkDebugf(__VA_ARGS__); sksl_abort(); }
@@ -114,4 +121,11 @@ NORETURN void sksl_abort();
 #define ABORT(...) { sksl_abort(); }
 #endif
 
+namespace std {
+    template<> struct hash<SkString> {
+        size_t operator()(const SkString& s) const {
+            return SkOpts::hash_fn(s.c_str(), s.size(), 0);
+        }
+    };
+}
 #endif
index 88feba6..c4b6e3a 100644 (file)
@@ -10,7 +10,6 @@
 
 #include "SkSLASTExpression.h"
 #include "../SkSLToken.h"
-#include <sstream>
 
 namespace SkSL {
 
@@ -25,7 +24,7 @@ struct ASTBinaryExpression : public ASTExpression {
     , fOperator(op.fKind)
     , fRight(std::move(right)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return "(" + fLeft->description() + " " + Token::OperatorName(fOperator) + " " +
                fRight->description() + ")";
     }
index 09450a3..6b1e9c5 100644 (file)
@@ -20,8 +20,8 @@ struct ASTBlock : public ASTStatement {
     : INHERITED(position, kBlock_Kind)
     , fStatements(std::move(statements)) {}
 
-    std::string description() const override {
-        std::string result("{");
+    SkString description() const override {
+        SkString result("{");
         for (size_t i = 0; i < fStatements.size(); i++) {
             result += "\n";
             result += fStatements[i]->description();
index ff58822..02f4bac 100644 (file)
@@ -20,8 +20,8 @@ struct ASTBoolLiteral : public ASTExpression {
     : INHERITED(position, kBool_Kind)
     , fValue(value) {}
 
-    std::string description() const override {
-        return fValue ? "true" : "false";
+    SkString description() const override {
+        return SkString(fValue ? "true" : "false");
     }
 
     const bool fValue;
index ede548c..dad2a85 100644 (file)
@@ -19,8 +19,8 @@ struct ASTBreakStatement : public ASTStatement {
     ASTBreakStatement(Position position)
     : INHERITED(position, kBreak_Kind) {}
 
-    std::string description() const override {
-        return "break;";
+    SkString description() const override {
+        return SkString("break;");
     }
 
     typedef ASTStatement INHERITED;
index 5cff6f6..356ac85 100644 (file)
@@ -8,7 +8,6 @@
 #ifndef SKSL_ASTCALLSUFFIX
 #define SKSL_ASTCALLSUFFIX
 
-#include <sstream>
 #include <vector>
 #include "SkSLASTSuffix.h"
 
@@ -22,9 +21,9 @@ struct ASTCallSuffix : public ASTSuffix {
     : INHERITED(position, ASTSuffix::kCall_Kind)
     , fArguments(std::move(arguments)) {}
 
-    std::string description() const override {
-        std::string result("(");
-        std::string separator = "";
+    SkString description() const override {
+        SkString result("(");
+        SkString separator;
         for (size_t i = 0; i < fArguments.size(); ++i) {
             result += separator;
             separator = ", ";
index d5ab7a5..4cded3b 100644 (file)
@@ -19,8 +19,8 @@ struct ASTContinueStatement : public ASTStatement {
     ASTContinueStatement(Position position)
     : INHERITED(position, kContinue_Kind) {}
 
-    std::string description() const override {
-        return "continue;";
+    SkString description() const override {
+        return SkString("continue;");
     }
 
     typedef ASTStatement INHERITED;
index 4eaeec9..754bf95 100644 (file)
@@ -19,8 +19,8 @@ struct ASTDiscardStatement : public ASTStatement {
     ASTDiscardStatement(Position position)
     : INHERITED(position, kDiscard_Kind) {}
 
-    std::string description() const override {
-        return "discard;";
+    SkString description() const override {
+        return SkString("discard;");
     }
 
     typedef ASTStatement INHERITED;
index a952d62..9a0cace 100644 (file)
@@ -22,7 +22,7 @@ struct ASTDoStatement : public ASTStatement {
     , fStatement(std::move(statement))
     , fTest(std::move(test)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return "do " + fStatement->description() + " while (" + fTest->description() + ");";
     }
 
index 450cca2..2dbd209 100644 (file)
@@ -20,7 +20,7 @@ struct ASTExpressionStatement : public ASTStatement {
     : INHERITED(expression->fPosition, kExpression_Kind)
     , fExpression(std::move(expression)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return fExpression->description() + ";";
     }
 
index 896ac46..b9df3c5 100644 (file)
@@ -16,15 +16,15 @@ namespace SkSL {
  * An extension declaration. 
  */
 struct ASTExtension : public ASTDeclaration {
-    ASTExtension(Position position, std::string name)
+    ASTExtension(Position position, SkString name)
     : INHERITED(position, kExtension_Kind)
     , fName(std::move(name)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return "#extension " + fName + " : enable";
     }
 
-    const std::string fName;
+    const SkString fName;
 
     typedef ASTDeclaration INHERITED;
 };
index cf141d8..9ee8531 100644 (file)
@@ -17,15 +17,15 @@ namespace SkSL {
  * actually vector swizzle (which looks the same to the parser).
  */
 struct ASTFieldSuffix : public ASTSuffix {
-    ASTFieldSuffix(Position position, std::string field) 
+    ASTFieldSuffix(Position position, SkString field) 
     : INHERITED(position, ASTSuffix::kField_Kind)
     , fField(std::move(field)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return "." + fField;
     }
 
-    std::string fField;
+    SkString fField;
 
     typedef ASTSuffix INHERITED;
 };
index 89d43cc..ea0f595 100644 (file)
@@ -20,7 +20,7 @@ struct ASTFloatLiteral : public ASTExpression {
     : INHERITED(position, kFloat_Kind)
     , fValue(value) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return to_string(fValue);
     }
 
index f4f68c8..2706a39 100644 (file)
@@ -25,8 +25,8 @@ struct ASTForStatement : public ASTStatement {
     , fNext(std::move(next))
     , fStatement(std::move(statement)) {}
 
-    std::string description() const override {
-        std::string result = "for (";
+    SkString description() const override {
+        SkString result("for (");
         if (fInitializer) {
             result.append(fInitializer->description());
         }
index c5c3b9a..32f4da7 100644 (file)
@@ -19,7 +19,7 @@ namespace SkSL {
  * A function declaration or definition. The fBody field will be null for declarations. 
  */
 struct ASTFunction : public ASTDeclaration {
-    ASTFunction(Position position, std::unique_ptr<ASTType> returnType, std::string name,
+    ASTFunction(Position position, std::unique_ptr<ASTType> returnType, SkString name,
                 std::vector<std::unique_ptr<ASTParameter>> parameters, 
                 std::unique_ptr<ASTBlock> body)
     : INHERITED(position, kFunction_Kind)
@@ -28,8 +28,8 @@ struct ASTFunction : public ASTDeclaration {
     , fParameters(std::move(parameters))
     , fBody(std::move(body)) {}
 
-    std::string description() const override {
-        std::string result = fReturnType->description() + " " + fName + "(";
+    SkString description() const override {
+        SkString result = fReturnType->description() + " " + fName + "(";
         for (size_t i = 0; i < fParameters.size(); i++) {
             if (i > 0) {
                 result += ", ";
@@ -45,7 +45,7 @@ struct ASTFunction : public ASTDeclaration {
     }
 
     const std::unique_ptr<ASTType> fReturnType;
-    const std::string fName;
+    const SkString fName;
     const std::vector<std::unique_ptr<ASTParameter>> fParameters;
     const std::unique_ptr<ASTBlock> fBody;
 
index d67f64d..aa0179a 100644 (file)
@@ -16,15 +16,15 @@ namespace SkSL {
  * An identifier in an expression context. 
  */
 struct ASTIdentifier : public ASTExpression {
-    ASTIdentifier(Position position, std::string text)
+    ASTIdentifier(Position position, SkString text)
     : INHERITED(position, kIdentifier_Kind)
     , fText(std::move(text)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return fText;
     }
 
-    const std::string fText;
+    const SkString fText;
 
     typedef ASTExpression INHERITED;
 };
index 06f663d..d169702 100644 (file)
@@ -23,8 +23,8 @@ struct ASTIfStatement : public ASTStatement {
     , fIfTrue(std::move(ifTrue))
     , fIfFalse(std::move(ifFalse)) {}
 
-    std::string description() const override {
-        std::string result("if (");
+    SkString description() const override {
+        SkString result("if (");
         result += fTest->description();
         result += ") ";
         result += fIfTrue->description();
index 755029b..2b7cd48 100644 (file)
@@ -26,11 +26,11 @@ struct ASTIndexSuffix : public ASTSuffix {
     : INHERITED(expression ? expression->fPosition : Position(), ASTSuffix::kIndex_Kind)
     , fExpression(std::move(expression)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         if (fExpression) {
             return "[" + fExpression->description() + "]";
         } else {
-            return "[]";
+            return SkString("[]");
         }
     }
 
index 2598847..f524bc0 100644 (file)
@@ -21,7 +21,7 @@ struct ASTIntLiteral : public ASTExpression {
     : INHERITED(position, kInt_Kind)
     , fValue(value) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return to_string(fValue);
     }
 
index c271362..8d86c7c 100644 (file)
@@ -24,8 +24,8 @@ struct ASTInterfaceBlock : public ASTDeclaration {
     // valueName is empty when it was not present in the source
     ASTInterfaceBlock(Position position,
                       ASTModifiers modifiers, 
-                      std::string interfaceName, 
-                      std::string valueName, 
+                      SkString interfaceName, 
+                      SkString valueName, 
                       std::vector<std::unique_ptr<ASTVarDeclarations>> declarations)
     : INHERITED(position, kInterfaceBlock_Kind)
     , fModifiers(modifiers)
@@ -33,21 +33,21 @@ struct ASTInterfaceBlock : public ASTDeclaration {
     , fValueName(std::move(valueName))
     , fDeclarations(std::move(declarations)) {}
 
-    std::string description() const override {
-        std::string result = fModifiers.description() + fInterfaceName + " {\n";
+    SkString description() const override {
+        SkString result = fModifiers.description() + fInterfaceName + " {\n";
         for (size_t i = 0; i < fDeclarations.size(); i++) {
             result += fDeclarations[i]->description() + "\n";
         }
         result += "}";
-        if (fValueName.length()) {
+        if (fValueName.size()) {
             result += " " + fValueName;
         }
         return result + ";";
     }
 
     const ASTModifiers fModifiers;
-    const std::string fInterfaceName;
-    const std::string fValueName;
+    const SkString fInterfaceName;
+    const SkString fValueName;
     const std::vector<std::unique_ptr<ASTVarDeclarations>> fDeclarations;
 
     typedef ASTDeclaration INHERITED;
index ae3c3b6..cb7f3c1 100644 (file)
@@ -48,7 +48,7 @@ struct ASTLayout : public ASTNode {
         return "";
     }
 
-    static bool ReadFormat(std::string str, Format* format) {
+    static bool ReadFormat(SkString str, Format* format) {
         if (str == "rgba32f") {
             *format = Format::kRGBA32F;
             return true;
@@ -90,9 +90,9 @@ struct ASTLayout : public ASTNode {
     , fBlendSupportAllEquations(blendSupportAllEquations)
     , fFormat(format) {}
 
-    std::string description() const {
-        std::string result;
-        std::string separator;
+    SkString description() const {
+        SkString result;
+        SkString separator;
         if (fLocation >= 0) {
             result += separator + "location = " + to_string(fLocation);
             separator = ", ";
@@ -129,7 +129,7 @@ struct ASTLayout : public ASTNode {
             result += separator + FormatToStr(fFormat);
             separator = ", ";
         }
-        if (result.length() > 0) {
+        if (result.size() > 0) {
             result = "layout (" + result + ")";
         }
         return result;
index 61d2e9f..7341692 100644 (file)
@@ -34,8 +34,8 @@ struct ASTModifiers : public ASTNode {
     : fLayout(layout)
     , fFlags(flags) {}
 
-    std::string description() const override {
-        std::string result = fLayout.description();
+    SkString description() const override {
+        SkString result = fLayout.description();
         if (fFlags & kUniform_Flag) {
             result += "uniform ";
         }
index f5cc620..07efdf6 100644 (file)
@@ -23,7 +23,7 @@ struct ASTModifiersDeclaration : public ASTDeclaration {
     : INHERITED(Position(), kModifiers_Kind)
     , fModifiers(modifiers) {}
 
-    std::string description() const {
+    SkString description() const {
         return fModifiers.description() + ";";
     }
 
index 4305011..af06595 100644 (file)
@@ -8,8 +8,7 @@
 #ifndef SKSL_ASTNODE
 #define SKSL_ASTNODE
 
-#include <memory>
-#include <string>
+#include "SkString.h"
 
 namespace SkSL {
 
@@ -20,7 +19,7 @@ namespace SkSL {
 struct ASTNode {
     virtual ~ASTNode() {}
      
-    virtual std::string description() const = 0;
+    virtual SkString description() const = 0;
 };
 
 } // namespace
index 8f1b453..b1fd658 100644 (file)
@@ -20,15 +20,15 @@ struct ASTParameter : public ASTPositionNode {
     // 'sizes' is a list of the array sizes appearing on a parameter, in source order. 
     // e.g. int x[3][1] would have sizes [3, 1].
     ASTParameter(Position position, ASTModifiers modifiers, std::unique_ptr<ASTType> type, 
-                 std::string name, std::vector<int> sizes)
+                 SkString name, std::vector<int> sizes)
     : INHERITED(position)
     , fModifiers(modifiers)
     , fType(std::move(type))
     , fName(std::move(name))
     , fSizes(std::move(sizes)) {}
 
-    std::string description() const override {
-        std::string result = fModifiers.description() + fType->description() + " " + fName;
+    SkString description() const override {
+        SkString result = fModifiers.description() + fType->description() + " " + fName;
         for (int size : fSizes) {
             result += "[" + to_string(size) + "]";
         }
@@ -37,7 +37,7 @@ struct ASTParameter : public ASTPositionNode {
 
     const ASTModifiers fModifiers;
     const std::unique_ptr<ASTType> fType;
-    const std::string fName;
+    const SkString fName;
     const std::vector<int> fSizes;
 
     typedef ASTPositionNode INHERITED;
index a7df579..a2f427c 100644 (file)
@@ -22,17 +22,17 @@ struct ASTPrecision : public ASTDeclaration {
     : INHERITED(position, kPrecision_Kind)
     , fPrecision(precision) {}
 
-    std::string description() const {
+    SkString description() const {
         switch (fPrecision) {
-            case Modifiers::kLowp_Flag: return "precision lowp float;";
-            case Modifiers::kMediump_Flag: return "precision mediump float;";
-            case Modifiers::kHighp_Flag: return "precision highp float;";
+            case Modifiers::kLowp_Flag: return SkString("precision lowp float;");
+            case Modifiers::kMediump_Flag: return SkString("precision mediump float;");
+            case Modifiers::kHighp_Flag: return SkString("precision highp float;");
             default: 
                 ASSERT(false); 
-                return "<error>";
+                return SkString("<error>");
         }
         ASSERT(false);
-        return "<error>";
+        return SkString("<error>");
     }
 
     const Modifiers::Flag fPrecision;
index 0d326e2..e06ec41 100644 (file)
@@ -22,7 +22,7 @@ struct ASTPrefixExpression : public ASTExpression {
     , fOperator(op.fKind)
     , fOperand(std::move(operand)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return Token::OperatorName(fOperator) + fOperand->description();
     }
 
index 3aac783..ed24d4a 100644 (file)
@@ -21,8 +21,8 @@ struct ASTReturnStatement : public ASTStatement {
     : INHERITED(position, kReturn_Kind)
     , fExpression(std::move(expression)) {}
 
-    std::string description() const override {
-        std::string result("return");
+    SkString description() const override {
+        SkString result("return");
         if (fExpression) {
             result += " " + fExpression->description();
         }
index 18f79f0..64178c7 100644 (file)
@@ -30,12 +30,12 @@ struct ASTSuffix : public ASTPositionNode {
     : INHERITED(position)
     , fKind(kind) {}
 
-    std::string description() const override {
+    SkString description() const override {
         switch (fKind) {
             case kPostIncrement_Kind:
-                return "++";
+                return SkString("++");
             case kPostDecrement_Kind:
-                return "--";
+                return SkString("--");
             default:
                 ABORT("unsupported suffix operator");
         }        
index c0fda29..7ee200f 100644 (file)
@@ -22,7 +22,7 @@ struct ASTSuffixExpression : public ASTExpression {
     , fBase(std::move(base))
     , fSuffix(std::move(suffix)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return fBase->description() + fSuffix->description();
     }
 
index 20b827a..ddf8e3d 100644 (file)
@@ -24,7 +24,7 @@ struct ASTTernaryExpression : public ASTExpression {
     , fIfTrue(std::move(ifTrue))
     , fIfFalse(std::move(ifFalse)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return "(" + fTest->description() + " ? " + fIfTrue->description() + " : " +
                fIfFalse->description() + ")";        
     }
index b8fdedb..8159400 100644 (file)
@@ -19,16 +19,16 @@ struct ASTType : public ASTPositionNode {
         kStruct_Kind
     };
 
-    ASTType(Position position, std::string name, Kind kind)
+    ASTType(Position position, SkString name, Kind kind)
     : INHERITED(position)
     , fName(std::move(name))
     , fKind(kind) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return fName;
     }
 
-    const std::string fName;
+    const SkString fName;
 
     const Kind fKind;
 
index 066922f..9de4cf5 100644 (file)
@@ -22,15 +22,15 @@ namespace SkSL {
  * instances.
  */
 struct ASTVarDeclaration {
-    ASTVarDeclaration(const std::string name,
+    ASTVarDeclaration(const SkString name,
                       std::vector<std::unique_ptr<ASTExpression>> sizes,
                       std::unique_ptr<ASTExpression> value)
     : fName(name)
     , fSizes(std::move(sizes))
     , fValue(std::move(value)) {}
 
-    std::string description() const {
-        std::string result = fName;
+    SkString description() const {
+        SkString result = fName;
         for (const auto& size : fSizes) {
             if (size) {
                 result += "[" + size->description() + "]";
@@ -44,7 +44,7 @@ struct ASTVarDeclaration {
         return result;        
     }
 
-    std::string fName;
+    SkString fName;
 
     // array sizes, if any. e.g. 'foo[3][]' has sizes [3, null]
     std::vector<std::unique_ptr<ASTExpression>> fSizes;
@@ -65,9 +65,9 @@ struct ASTVarDeclarations : public ASTDeclaration {
     , fType(std::move(type))
     , fVars(std::move(vars)) {}
 
-    std::string description() const override {
-        std::string result = fModifiers.description() + fType->description() + " ";
-        std::string separator = "";
+    SkString description() const override {
+        SkString result = fModifiers.description() + fType->description() + " ";
+        SkString separator;
         for (const auto& var : fVars) {
             result += separator;
             separator = ", ";
index 8bae389..d71639d 100644 (file)
@@ -21,7 +21,7 @@ struct ASTVarDeclarationStatement : public ASTStatement {
     : INHERITED(decl->fPosition, kVarDeclaration_Kind)
     , fDeclarations(std::move(decl)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return fDeclarations->description() + ";";
     }
 
index e29aa23..853ac80 100644 (file)
@@ -22,7 +22,7 @@ struct ASTWhileStatement : public ASTStatement {
     , fTest(std::move(test))
     , fStatement(std::move(statement)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return "while (" + fTest->description() + ") " + fStatement->description();
     }
 
index 9ecdbc7..132513e 100644 (file)
@@ -24,7 +24,7 @@ struct BinaryExpression : public Expression {
     , fOperator(op)
     , fRight(std::move(right)) {}
 
-    virtual std::string description() const override {
+    virtual SkString description() const override {
         return "(" + fLeft->description() + " " + Token::OperatorName(fOperator) + " " +
                fRight->description() + ")";
     }
index a53d13d..f975d16 100644 (file)
@@ -4,7 +4,7 @@
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
+
 #ifndef SKSL_BLOCK
 #define SKSL_BLOCK
 
@@ -23,14 +23,14 @@ struct Block : public Statement {
     , fStatements(std::move(statements))
     , fSymbols(std::move(symbols)) {}
 
-    std::string description() const override {
-        std::string result = "{";
+    SkString description() const override {
+        SkString result("{");
         for (size_t i = 0; i < fStatements.size(); i++) {
             result += "\n";
             result += fStatements[i]->description();
         }
         result += "\n}\n";
-        return result;        
+        return result;
     }
 
     const std::vector<std::unique_ptr<Statement>> fStatements;
index ba054e4..b372f2f 100644 (file)
@@ -21,8 +21,8 @@ struct BoolLiteral : public Expression {
     : INHERITED(position, kBoolLiteral_Kind, *context.fBool_Type)
     , fValue(value) {}
 
-    std::string description() const override {
-        return fValue ? "true" : "false";
+    SkString description() const override {
+        return SkString(fValue ? "true" : "false");
     }
 
     bool isConstant() const override {
index 8aa17b0..cd633c7 100644 (file)
@@ -20,8 +20,8 @@ struct BreakStatement : public Statement {
     BreakStatement(Position position)
     : INHERITED(position, kBreak_Kind) {}
 
-    std::string description() const override {
-        return "break;";
+    SkString description() const override {
+        return SkString("break;");
     }
 
     typedef Statement INHERITED;
index 0501b65..92f7580 100644 (file)
@@ -21,9 +21,9 @@ struct Constructor : public Expression {
     : INHERITED(position, kConstructor_Kind, type)
     , fArguments(std::move(arguments)) {}
 
-    std::string description() const override {
-        std::string result = fType.description() + "(";
-        std::string separator = "";
+    SkString description() const override {
+        SkString result = fType.description() + "(";
+        SkString separator;
         for (size_t i = 0; i < fArguments.size(); i++) {
             result += separator;
             result += fArguments[i]->description();
index 1951bd9..b444694 100644 (file)
@@ -20,8 +20,8 @@ struct ContinueStatement : public Statement {
     ContinueStatement(Position position)
     : INHERITED(position, kContinue_Kind) {}
 
-    std::string description() const override {
-        return "continue;";
+    SkString description() const override {
+        return SkString("continue;");
     }
 
     typedef Statement INHERITED;
index b39712e..3ab6b27 100644 (file)
@@ -20,8 +20,8 @@ struct DiscardStatement : public Statement {
     DiscardStatement(Position position)
     : INHERITED(position, kDiscard_Kind) {}
 
-    std::string description() const override {
-        return "discard;";
+    SkString description() const override {
+        return SkString("discard;");
     }
 
     typedef Statement INHERITED;
index 6012453..78c0a1b 100644 (file)
@@ -23,7 +23,7 @@ struct DoStatement : public Statement {
     , fStatement(std::move(statement))
     , fTest(std::move(test)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return "do " + fStatement->description() + " while (" + fTest->description() + ");";
     }
 
index e975ccf..677c647 100644 (file)
@@ -21,7 +21,7 @@ struct ExpressionStatement : public Statement {
     : INHERITED(expression->fPosition, kExpression_Kind)
     , fExpression(std::move(expression)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return fExpression->description() + ";";
     }
 
index d7f83fa..ea5e044 100644 (file)
@@ -16,15 +16,15 @@ namespace SkSL {
  * An extension declaration. 
  */
 struct Extension : public ProgramElement {
-    Extension(Position position, std::string name)
+    Extension(Position position, SkString name)
     : INHERITED(position, kExtension_Kind) 
     , fName(std::move(name)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return "#extension " + fName + " : enable";
     }
 
-    const std::string fName;
+    const SkString fName;
 
     typedef ProgramElement INHERITED;
 };
index a01df29..f73b602 100644 (file)
@@ -26,7 +26,7 @@ struct Field : public Symbol {
     , fOwner(owner)
     , fFieldIndex(fieldIndex) {}
 
-    virtual std::string description() const override {
+    virtual SkString description() const override {
         return fOwner.description() + "." + fOwner.fType.fields()[fFieldIndex].fName;
     }
 
index 4be4e9e..fb727e0 100644 (file)
@@ -31,7 +31,7 @@ struct FieldAccess : public Expression {
     , fFieldIndex(fieldIndex)
     , fOwnerKind(ownerKind) {}
 
-    virtual std::string description() const override {
+    virtual SkString description() const override {
         return fBase->description() + "." + fBase->fType.fields()[fFieldIndex].fName;
     }
 
index a8fcfcf..8a1a5ad 100644 (file)
@@ -21,7 +21,7 @@ struct FloatLiteral : public Expression {
     : INHERITED(position, kFloatLiteral_Kind, *context.fFloat_Type)
     , fValue(value) {}
 
-    virtual std::string description() const override {
+    virtual SkString description() const override {
         return to_string(fValue);
     }
 
index 642d151..ff03d0d 100644 (file)
@@ -28,8 +28,8 @@ struct ForStatement : public Statement {
     , fStatement(std::move(statement))
     , fSymbols(symbols) {}
 
-    std::string description() const override {
-        std::string result = "for (";
+    SkString description() const override {
+        SkString result("for (");
         if (fInitializer) {
             result += fInitializer->description();
         } 
index 5c67a28..971af36 100644 (file)
@@ -23,9 +23,9 @@ struct FunctionCall : public Expression {
     , fFunction(std::move(function))
     , fArguments(std::move(arguments)) {}
 
-    std::string description() const override {
-        std::string result = fFunction.fName + "(";
-        std::string separator = "";
+    SkString description() const override {
+        SkString result = fFunction.fName + "(";
+        SkString separator;
         for (size_t i = 0; i < fArguments.size(); i++) {
             result += separator;
             result += fArguments[i]->description();
index 52a579a..c15d2b9 100644 (file)
@@ -21,7 +21,7 @@ namespace SkSL {
  * A function declaration (not a definition -- does not contain a body).
  */
 struct FunctionDeclaration : public Symbol {
-    FunctionDeclaration(Position position, std::string name, 
+    FunctionDeclaration(Position position, SkString name, 
                         std::vector<const Variable*> parameters, const Type& returnType)
     : INHERITED(position, kFunctionDeclaration_Kind, std::move(name))
     , fDefined(false)
@@ -29,9 +29,9 @@ struct FunctionDeclaration : public Symbol {
     , fParameters(std::move(parameters))
     , fReturnType(returnType) {}
 
-    std::string description() const override {
-        std::string result = fReturnType.description() + " " + fName + "(";
-        std::string separator = "";
+    SkString description() const override {
+        SkString result = fReturnType.description() + " " + fName + "(";
+        SkString separator;
         for (auto p : fParameters) {
             result += separator;
             separator = ", ";
index ace27a3..bae8825 100644 (file)
@@ -24,7 +24,7 @@ struct FunctionDefinition : public ProgramElement {
     , fDeclaration(declaration)
     , fBody(std::move(body)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return fDeclaration.description() + " " + fBody->description();
     }
 
index f3f8fb7..ec1fc38 100644 (file)
@@ -23,9 +23,9 @@ struct FunctionReference : public Expression {
     : INHERITED(position, kFunctionReference_Kind, *context.fInvalid_Type)
     , fFunctions(function) {}
 
-    virtual std::string description() const override {
+    virtual SkString description() const override {
         ASSERT(false);
-        return "<function>";
+        return SkString("<function>");
     }
 
     const std::vector<const FunctionDeclaration*> fFunctions;
index 8c433cf..9a04cdd 100644 (file)
@@ -22,7 +22,7 @@ struct IRNode {
 
     virtual ~IRNode() {}
 
-    virtual std::string description() const = 0;
+    virtual SkString description() const = 0;
 
     const Position fPosition;
 };
index 8ab5c00..f8beded 100644 (file)
@@ -24,8 +24,8 @@ struct IfStatement : public Statement {
     , fIfTrue(std::move(ifTrue))
     , fIfFalse(std::move(ifFalse)) {}
 
-    std::string description() const override {
-        std::string result = "if (" + fTest->description() + ") " + fIfTrue->description();
+    SkString description() const override {
+        SkString result = "if (" + fTest->description() + ") " + fIfTrue->description();
         if (fIfFalse) {
             result += " else " + fIfFalse->description();
         }
index abd8a03..079dde5 100644 (file)
@@ -51,7 +51,7 @@ struct IndexExpression : public Expression {
         ASSERT(fIndex->fType == *context.fInt_Type || fIndex->fType == *context.fUInt_Type);
     }
 
-    std::string description() const override {
+    SkString description() const override {
         return fBase->description() + "[" + fIndex->description() + "]";
     }
 
index 8921c28..23325e6 100644 (file)
@@ -22,7 +22,7 @@ struct IntLiteral : public Expression {
     : INHERITED(position, kIntLiteral_Kind, type ? *type : *context.fInt_Type)
     , fValue(value) {}
 
-    virtual std::string description() const override {
+    virtual SkString description() const override {
         return to_string(fValue);
     }
 
index debde20..bc84396 100644 (file)
@@ -31,8 +31,8 @@ struct InterfaceBlock : public ProgramElement {
         ASSERT(fVariable.fType.kind() == Type::kStruct_Kind);
     }
 
-    std::string description() const override {
-        std::string result = fVariable.fModifiers.description() + fVariable.fName + " {\n";
+    SkString description() const override {
+        SkString result = fVariable.fModifiers.description() + fVariable.fName + " {\n";
         for (size_t i = 0; i < fVariable.fType.fields().size(); i++) {
             result += fVariable.fType.fields()[i].description() + "\n";
         }
index 4cfd1a2..7359262 100644 (file)
@@ -50,9 +50,9 @@ struct Layout {
     , fBlendSupportAllEquations(false)
     , fFormat(ASTLayout::Format::kUnspecified) {}
 
-    std::string description() const {
-        std::string result;
-        std::string separator;
+    SkString description() const {
+        SkString result;
+        SkString separator;
         if (fLocation >= 0) {
             result += separator + "location = " + to_string(fLocation);
             separator = ", ";
@@ -89,7 +89,7 @@ struct Layout {
             result += separator + ASTLayout::FormatToStr(fFormat);
             separator = ", ";
         }
-        if (result.length() > 0) {
+        if (result.size() > 0) {
             result = "layout (" + result + ")";
         }
         return result;
index f39e929..2c9b3b3 100644 (file)
@@ -38,8 +38,8 @@ struct Modifiers {
     : fLayout(layout)
     , fFlags(flags) {}
 
-    std::string description() const {
-        std::string result = fLayout.description();
+    SkString description() const {
+        SkString result = fLayout.description();
         if (fFlags & kUniform_Flag) {
             result += "uniform ";
         }
index 0066fab..625954d 100644 (file)
@@ -23,7 +23,7 @@ struct ModifiersDeclaration : public ProgramElement {
     : INHERITED(Position(), kModifiers_Kind)
     , fModifiers(modifiers) {}
 
-    std::string description() const {
+    SkString description() const {
         return fModifiers.description() + ";";
     }
 
index de146ac..01671b5 100644 (file)
@@ -21,7 +21,7 @@ struct PostfixExpression : public Expression {
     , fOperand(std::move(operand))
     , fOperator(op) {}
 
-    virtual std::string description() const override {
+    virtual SkString description() const override {
         return fOperand->description() + Token::OperatorName(fOperator);
     }
 
index 53c3849..790c5ab 100644 (file)
@@ -21,7 +21,7 @@ struct PrefixExpression : public Expression {
     , fOperand(std::move(operand))
     , fOperator(op) {}
 
-    virtual std::string description() const override {
+    virtual SkString description() const override {
         return Token::OperatorName(fOperator) + fOperand->description();
     }
 
index ec2226c..c83b450 100644 (file)
@@ -24,11 +24,11 @@ struct ReturnStatement : public Statement {
     : INHERITED(expression->fPosition, kReturn_Kind) 
     , fExpression(std::move(expression)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         if (fExpression) {
             return "return " + fExpression->description() + ";";
         } else {
-            return "return;";
+            return SkString("return;");
         }
     }
 
index 0eb4a00..c9397ae 100644 (file)
@@ -68,8 +68,8 @@ struct Swizzle : public Expression {
         ASSERT(fComponents.size() >= 1 && fComponents.size() <= 4);
     }
 
-    std::string description() const override {
-        std::string result = fBase->description() + ".";
+    SkString description() const override {
+        SkString result = fBase->description() + ".";
         for (int x : fComponents) {
             result += "xyzw"[x];
         }
index d736516..10dcaf9 100644 (file)
@@ -24,13 +24,13 @@ struct Symbol : public IRNode {
         kField_Kind
     };
 
-    Symbol(Position position, Kind kind, std::string name)
+    Symbol(Position position, Kind kind, SkString name)
     : INHERITED(position)
     , fKind(kind)
     , fName(std::move(name)) {}
 
     const Kind fKind;
-    const std::string fName;
+    const SkString fName;
 
     typedef IRNode INHERITED;
 };
index 6d8e9a7..3ceeab9 100644 (file)
@@ -21,7 +21,7 @@ std::vector<const FunctionDeclaration*> SymbolTable::GetFunctions(const Symbol&
     }
 }
 
-const Symbol* SymbolTable::operator[](const std::string& name) {
+const Symbol* SymbolTable::operator[](const SkString& name) {
     const auto& entry = fSymbols.find(name);
     if (entry == fSymbols.end()) {
         if (fParent) {
@@ -64,12 +64,12 @@ Symbol* SymbolTable::takeOwnership(Symbol* s) {
     return s;
 }
 
-void SymbolTable::add(const std::string& name, std::unique_ptr<Symbol> symbol) {
+void SymbolTable::add(const SkString& name, std::unique_ptr<Symbol> symbol) {
     this->addWithoutOwnership(name, symbol.get());
     fOwnedPointers.push_back(std::move(symbol));
 }
 
-void SymbolTable::addWithoutOwnership(const std::string& name, const Symbol* symbol) {
+void SymbolTable::addWithoutOwnership(const SkString& name, const Symbol* symbol) {
     const auto& existing = fSymbols.find(name);
     if (existing == fSymbols.end()) {
         fSymbols[name] = symbol;
index be2b49c..df8dc71 100644 (file)
@@ -31,11 +31,11 @@ public:
     : fParent(parent)
     , fErrorReporter(errorReporter) {}
 
-    const Symbol* operator[](const std::string& name);
+    const Symbol* operator[](const SkString& name);
 
-    void add(const std::string& name, std::unique_ptr<Symbol> symbol);
+    void add(const SkString& name, std::unique_ptr<Symbol> symbol);
 
-    void addWithoutOwnership(const std::string& name, const Symbol* symbol);
+    void addWithoutOwnership(const SkString& name, const Symbol* symbol);
 
     Symbol* takeOwnership(Symbol* s);
 
@@ -48,7 +48,7 @@ private:
 
     std::vector<std::unique_ptr<Symbol>> fOwnedPointers;
 
-    std::unordered_map<std::string, const Symbol*> fSymbols;
+    std::unordered_map<SkString, const Symbol*> fSymbols;
 
     ErrorReporter& fErrorReporter;
 };
index bfaf304..4a35253 100644 (file)
@@ -26,7 +26,7 @@ struct TernaryExpression : public Expression {
         ASSERT(fIfTrue->fType == fIfFalse->fType);
     }
 
-    std::string description() const override {
+    SkString description() const override {
         return "(" + fTest->description() + " ? " + fIfTrue->description() + " : " + 
                fIfFalse->description() + ")";
     }
index afd00d8..4174c72 100644 (file)
@@ -26,17 +26,17 @@ class Context;
 class Type : public Symbol {
 public:
     struct Field {
-        Field(Modifiers modifiers, std::string name, const Type* type)
+        Field(Modifiers modifiers, SkString name, const Type* type)
         : fModifiers(modifiers)
         , fName(std::move(name))
         , fType(std::move(type)) {}
 
-        const std::string description() const {
+        const SkString description() const {
             return fType->description() + " " + fName + ";";
         }
 
         Modifiers fModifiers;
-        std::string fName;
+        SkString fName;
         const Type* fType;
     };
 
@@ -53,14 +53,14 @@ public:
 
     // Create an "other" (special) type with the given name. These types cannot be directly 
     // referenced from user code.
-    Type(std::string name)
+    Type(SkString name)
     : INHERITED(Position(), kType_Kind, std::move(name))
     , fTypeKind(kOther_Kind) {}
 
     // Create a generic type which maps to the listed types. As currently implemented, there are 
     // always exactly four coercion targets, mapping to the scalar, vec2, vec3, and vec4 versions of 
     // a type.
-    Type(std::string name, std::vector<const Type*> types)
+    Type(SkString name, std::vector<const Type*> types)
     : INHERITED(Position(), kType_Kind, std::move(name))
     , fTypeKind(kGeneric_Kind)
     , fCoercibleTypes(std::move(types)) {
@@ -68,13 +68,13 @@ public:
     }
 
     // Create a struct type with the given fields.
-    Type(std::string name, std::vector<Field> fields)
+    Type(SkString name, std::vector<Field> fields)
     : INHERITED(Position(), kType_Kind, std::move(name))
     , fTypeKind(kStruct_Kind)
     , fFields(std::move(fields)) {}
 
     // Create a scalar type.
-    Type(std::string name, bool isNumber)
+    Type(SkString name, bool isNumber)
     : INHERITED(Position(), kType_Kind, std::move(name))
     , fTypeKind(kScalar_Kind)
     , fIsNumber(isNumber)
@@ -82,7 +82,7 @@ public:
     , fRows(1) {}
 
     // Create a scalar type which can be coerced to the listed types.
-    Type(std::string name, bool isNumber, std::vector<const Type*> coercibleTypes)
+    Type(SkString name, bool isNumber, std::vector<const Type*> coercibleTypes)
     : INHERITED(Position(), kType_Kind, std::move(name))
     , fTypeKind(kScalar_Kind)
     , fIsNumber(isNumber)
@@ -91,11 +91,11 @@ public:
     , fRows(1) {}
 
     // Create a vector type.
-    Type(std::string name, const Type& componentType, int columns)
+    Type(SkString name, const Type& componentType, int columns)
     : Type(name, kVector_Kind, componentType, columns) {}
 
     // Create a vector or array type.
-    Type(std::string name, Kind kind, const Type& componentType, int columns)
+    Type(SkString name, Kind kind, const Type& componentType, int columns)
     : INHERITED(Position(), kType_Kind, std::move(name))
     , fTypeKind(kind)
     , fComponentType(&componentType)
@@ -104,7 +104,7 @@ public:
     , fDimensions(SpvDim1D) {}
 
     // Create a matrix type.
-    Type(std::string name, const Type& componentType, int columns, int rows)
+    Type(SkString name, const Type& componentType, int columns, int rows)
     : INHERITED(Position(), kType_Kind, std::move(name))
     , fTypeKind(kMatrix_Kind)
     , fComponentType(&componentType)
@@ -113,7 +113,7 @@ public:
     , fDimensions(SpvDim1D) {}
 
     // Create a sampler type.
-    Type(std::string name, SpvDim_ dimensions, bool isDepth, bool isArrayed, bool isMultisampled, 
+    Type(SkString name, SpvDim_ dimensions, bool isDepth, bool isArrayed, bool isMultisampled, 
          bool isSampled) 
     : INHERITED(Position(), kType_Kind, std::move(name))
     , fTypeKind(kSampler_Kind)
@@ -123,11 +123,11 @@ public:
     , fIsMultisampled(isMultisampled)
     , fIsSampled(isSampled) {}
 
-    std::string name() const {
+    SkString name() const {
         return fName;
     }
 
-    std::string description() const override {
+    SkString description() const override {
         return fName;
     }
 
index 67e0466..1c6f16c 100644 (file)
@@ -22,7 +22,7 @@ struct TypeReference : public Expression {
     : INHERITED(position, kTypeReference_Kind, *context.fInvalid_Type)
     , fValue(type) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return fValue.name();
     }
 
index 7e8a360..76741cf 100644 (file)
@@ -26,7 +26,7 @@ struct UnresolvedFunction : public Symbol {
 #endif
     }
 
-    virtual std::string description() const override {
+    virtual SkString description() const override {
         return fName;
     }
 
index e64a874..295c0b6 100644 (file)
@@ -27,8 +27,8 @@ struct VarDeclaration {
     , fSizes(std::move(sizes))
     , fValue(std::move(value)) {}
 
-    std::string description() const {
-        std::string result = fVar->fName;
+    SkString description() const {
+        SkString result = fVar->fName;
         for (const auto& size : fSizes) {
             if (size) {
                 result += "[" + size->description() + "]";
@@ -57,13 +57,12 @@ struct VarDeclarations : public ProgramElement {
     , fBaseType(*baseType)
     , fVars(std::move(vars)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         if (!fVars.size()) {
-            return "";
+            return SkString();
         }
-        std::string result = fVars[0].fVar->fModifiers.description() + fBaseType.description() + 
-                             " ";
-        std::string separator = "";
+        SkString result = fVars[0].fVar->fModifiers.description() + fBaseType.description() + " ";
+        SkString separator;
         for (const auto& var : fVars) {
             result += separator;
             separator = ", ";
index 0b62edb..7a29656 100644 (file)
@@ -21,7 +21,7 @@ struct VarDeclarationsStatement : public Statement {
     : INHERITED(decl->fPosition, kVarDeclarations_Kind) 
     , fDeclaration(std::move(decl)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return fDeclaration->description();
     }
 
index 217b100..39b8482 100644 (file)
@@ -27,7 +27,7 @@ struct Variable : public Symbol {
         kParameter_Storage
     };
 
-    Variable(Position position, Modifiers modifiers, std::string name, const Type& type,
+    Variable(Position position, Modifiers modifiers, SkString name, const Type& type,
              Storage storage)
     : INHERITED(position, kVariable_Kind, std::move(name))
     , fModifiers(modifiers)
@@ -36,7 +36,7 @@ struct Variable : public Symbol {
     , fIsReadFrom(false)
     , fIsWrittenTo(false) {}
 
-    virtual std::string description() const override {
+    virtual SkString description() const override {
         return fModifiers.description() + fType.fName + " " + fName;
     }
 
index b443da1..c6a2ea0 100644 (file)
@@ -24,7 +24,7 @@ struct VariableReference : public Expression {
     : INHERITED(position, kVariableReference_Kind, variable.fType)
     , fVariable(variable) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return fVariable.fName;
     }
 
index 1acb572..7c6a290 100644 (file)
@@ -23,7 +23,7 @@ struct WhileStatement : public Statement {
     , fTest(std::move(test))
     , fStatement(std::move(statement)) {}
 
-    std::string description() const override {
+    SkString description() const override {
         return "while (" + fTest->description() + ") " + fStatement->description();
     }
 
index e9e05c1..c9e342c 100644 (file)
@@ -9,24 +9,25 @@
 
 #include "Test.h"
 
-#if SKIA_SUPPORT_GPU
+#if SK_SUPPORT_GPU
 
 static void test_failure(skiatest::Reporter* r, const char* src, const char* error) {
     SkSL::Compiler compiler;
-    std::stringstream out;
-    bool result = compiler.toSPIRV(SkSL::Program::kFragment_Kind, src, out);
-    if (compiler.errorText() != error) {
+    SkDynamicMemoryWStream out;
+    bool result = compiler.toSPIRV(SkSL::Program::kFragment_Kind, SkString(src), out);
+    SkString skError(error);
+    if (compiler.errorText() != skError) {
         SkDebugf("SKSL ERROR:\n    source: %s\n    expected: %s    received: %s", src, error,
                  compiler.errorText().c_str());
     }
     REPORTER_ASSERT(r, !result);
-    REPORTER_ASSERT(r, compiler.errorText() == error);
+    REPORTER_ASSERT(r, compiler.errorText() == skError);
 }
 
 static void test_success(skiatest::Reporter* r, const char* src) {
     SkSL::Compiler compiler;
-    std::stringstream out;
-    bool result = compiler.toSPIRV(SkSL::Program::kFragment_Kind, src, out);
+    SkDynamicMemoryWStream out;
+    bool result = compiler.toSPIRV(SkSL::Program::kFragment_Kind, SkString(src), out);
     REPORTER_ASSERT(r, result);
 }
 
index b01aad8..7af32be 100644 (file)
@@ -9,23 +9,24 @@
 
 #include "Test.h"
 
-#if SKIA_SUPPORT_GPU
+#if SK_SUPPORT_GPU
 
 static void test(skiatest::Reporter* r, const char* src, const GrGLSLCaps& caps, 
                  const char* expected) {
     SkSL::Compiler compiler;
-    std::string output;
-    bool result = compiler.toGLSL(SkSL::Program::kFragment_Kind, src, caps, &output);
+    SkString output;
+    bool result = compiler.toGLSL(SkSL::Program::kFragment_Kind, SkString(src), caps, &output);
     if (!result) {
         SkDebugf("Unexpected error compiling %s\n%s", src, compiler.errorText().c_str());
     }
     REPORTER_ASSERT(r, result);
     if (result) {
-        if (output != expected) {
+        SkString skExpected(expected);
+        if (output != skExpected) {
             SkDebugf("GLSL MISMATCH:\nsource:\n%s\n\nexpected:\n'%s'\n\nreceived:\n'%s'", src, 
                      expected, output.c_str());
         }
-        REPORTER_ASSERT(r, output == expected);
+        REPORTER_ASSERT(r, output == skExpected);
     }
 }
 
@@ -46,7 +47,7 @@ DEF_TEST(SkSLControl, r) {
          "if (sqrt(2) > 5) { sk_FragColor = vec4(0.75); } else { discard; }"
          "int i = 0;"
          "while (i < 10) sk_FragColor *= 0.5;"
-         "do { sk_FragColor += 0.01; } while (sk_FragColor.x < 0.7);"
+         "do { sk_FragColor += 0.01; } while (sk_FragColor.x < 0.75);"
          "for (int i = 0; i < 10; i++) {"
          "if (i % 0 == 1) break; else continue;"
          "}"
@@ -65,7 +66,7 @@ DEF_TEST(SkSLControl, r) {
          "    while (i < 10) sk_FragColor *= 0.5;\n"
          "    do {\n"
          "        sk_FragColor += 0.01;\n"
-         "    } while (sk_FragColor.x < 0.7);\n"
+         "    } while (sk_FragColor.x < 0.75);\n"
          "    for (int i = 0;i < 10; i++) {\n"
          "        if (i % 0 == 1) break; else continue;\n"
          "    }\n"