7070
7171namespace SkSL {
7272
73+ class AutoSource {
74+ public:
75+ AutoSource (Compiler* compiler, const String* source)
76+ : fCompiler (compiler), fOldSource (fCompiler ->fSource ) {
77+ fCompiler ->fSource = source;
78+ }
79+
80+ ~AutoSource () { fCompiler ->fSource = fOldSource ; }
81+
82+ Compiler* fCompiler ;
83+ const String* fOldSource ;
84+ };
85+
7386Compiler::Compiler (Flags flags)
7487: fFlags (flags)
7588, fContext (std::make_shared<Context>())
7689, fErrorCount (0 ) {
7790 fRootSymbolTable = std::make_shared<SymbolTable>(this );
78- fIRGenerator =
79- std::make_unique<IRGenerator>(fContext .get (), &fInliner , fRootSymbolTable , *this );
80- #define ADD_TYPE (t ) fRootSymbolTable ->addWithoutOwnership (fContext ->f ## t ## _Type.get())
91+ fIRGenerator = std::make_unique<IRGenerator>(fContext .get (), &fInliner , *this );
92+ #define ADD_TYPE (t ) fRootSymbolTable ->addWithoutOwnership (fContext ->f##t##_Type.get())
8193 ADD_TYPE(Void);
8294 ADD_TYPE (Float);
8395 ADD_TYPE (Float2);
@@ -221,37 +233,52 @@ Compiler::Compiler(Flags flags)
221233
222234Compiler::~Compiler () {}
223235
224- void Compiler::loadGeometryIntrinsics () {
236+ const ParsedModule& Compiler::loadGeometryModule () {
225237 if (!fGeometryModule .fSymbols ) {
226238 fGeometryModule = this ->parseModule (Program::kGeometry_Kind , MODULE_DATA (geom), fGPUModule );
227239 }
240+ return fGeometryModule ;
228241}
229242
230- void Compiler::loadFPIntrinsics () {
243+ const ParsedModule& Compiler::loadFPModule () {
231244 if (!fFPModule .fSymbols ) {
232245 fFPModule =
233246 this ->parseModule (Program::kFragmentProcessor_Kind , MODULE_DATA (fp), fGPUModule );
234247 }
248+ return fFPModule ;
235249}
236250
237- void Compiler::loadPipelineIntrinsics () {
251+ const ParsedModule& Compiler::loadPipelineModule () {
238252 if (!fPipelineModule .fSymbols ) {
239253 fPipelineModule =
240254 this ->parseModule (Program::kPipelineStage_Kind , MODULE_DATA (pipeline), fGPUModule );
241255 }
256+ return fPipelineModule ;
242257}
243258
244- void Compiler::loadInterpreterIntrinsics () {
259+ const ParsedModule& Compiler::loadInterpreterModule () {
245260 if (!fInterpreterModule .fSymbols ) {
246261 fInterpreterModule =
247262 this ->parseModule (Program::kGeneric_Kind , MODULE_DATA (interp), fRootModule );
248263 }
264+ return fInterpreterModule ;
265+ }
266+
267+ const ParsedModule& Compiler::moduleForProgramKind (Program::Kind kind) {
268+ switch (kind) {
269+ case Program::kVertex_Kind : return fVertexModule ; break ;
270+ case Program::kFragment_Kind : return fFragmentModule ; break ;
271+ case Program::kGeometry_Kind : return this ->loadGeometryModule (); break ;
272+ case Program::kFragmentProcessor_Kind : return this ->loadFPModule (); break ;
273+ case Program::kPipelineStage_Kind : return this ->loadPipelineModule (); break ;
274+ case Program::kGeneric_Kind : return this ->loadInterpreterModule (); break ;
275+ }
276+ SkUNREACHABLE;
249277}
250278
251279LoadedModule Compiler::loadModule (Program::Kind kind,
252280 ModuleData data,
253281 std::shared_ptr<SymbolTable> base) {
254- LoadedModule module ;
255282 if (!base) {
256283 base = fRootSymbolTable ;
257284 }
@@ -266,26 +293,26 @@ LoadedModule Compiler::loadModule(Program::Kind kind,
266293 abort ();
267294 }
268295 const String* source = fRootSymbolTable ->takeOwnershipOfString (std::move (text));
269- fSource = source;
296+ AutoSource as ( this , source) ;
270297 Program::Settings settings;
271298 SkASSERT (fIRGenerator ->fCanInline );
272299 fIRGenerator ->fCanInline = false ;
273- fIRGenerator ->start (&settings, {base, /* fIntrinsics=*/ nullptr }, /* builtin=*/ true );
274- fIRGenerator ->convertProgram (kind, source->c_str (), source->length (), &module .fElements );
300+ ParsedModule baseModule = {base, /* fIntrinsics=*/ nullptr };
301+ IRGenerator::IRBundle ir = fIRGenerator ->convertProgram (
302+ kind, &settings, baseModule, /* isBuiltinCode=*/ true , source->c_str (), source->length (),
303+ /* externalValues=*/ nullptr );
304+ LoadedModule module = { std::move (ir.fSymbolTable ), std::move (ir.fElements ) };
275305 fIRGenerator ->fCanInline = true ;
276306 if (this ->fErrorCount ) {
277307 printf (" Unexpected errors: %s\n " , this ->fErrorText .c_str ());
278308 SkDEBUGFAILF (" %s %s\n " , data.fPath , this ->fErrorText .c_str ());
279309 }
280- module .fSymbols = fIRGenerator ->fSymbolTable ;
281- fSource = nullptr ;
282- fModifiers .push_back (fIRGenerator ->releaseModifiers ());
283- fIRGenerator ->finish ();
310+ fModifiers .push_back (std::move (ir.fModifiers ));
284311#else
285312 SkASSERT (data.fData && (data.fSize != 0 ));
286313 Rehydrator rehydrator (fContext .get (), fIRGenerator ->fModifiers .get (), base, this ,
287314 data.fData , data.fSize );
288- module = { rehydrator.symbolTable (), rehydrator.elements () };
315+ LoadedModule module = { rehydrator.symbolTable (), rehydrator.elements () };
289316 fModifiers .push_back (fIRGenerator ->releaseModifiers ());
290317#endif
291318
@@ -1499,50 +1526,24 @@ std::unique_ptr<Program> Compiler::convertProgram(
14991526 fErrorText = " " ;
15001527 fErrorCount = 0 ;
15011528 fInliner .reset (fContext .get (), fIRGenerator ->fModifiers .get (), &settings);
1502- std::vector<std::unique_ptr<ProgramElement>> elements;
1503- switch (kind) {
1504- case Program::kVertex_Kind :
1505- fIRGenerator ->start (&settings, fVertexModule );
1506- break ;
1507- case Program::kFragment_Kind :
1508- fIRGenerator ->start (&settings, fFragmentModule );
1509- break ;
1510- case Program::kGeometry_Kind :
1511- this ->loadGeometryIntrinsics ();
1512- fIRGenerator ->start (&settings, fGeometryModule );
1513- break ;
1514- case Program::kFragmentProcessor_Kind :
1515- this ->loadFPIntrinsics ();
1516- fIRGenerator ->start (&settings, fFPModule );
1517- break ;
1518- case Program::kPipelineStage_Kind :
1519- this ->loadPipelineIntrinsics ();
1520- fIRGenerator ->start (&settings, fPipelineModule );
1521- break ;
1522- case Program::kGeneric_Kind :
1523- this ->loadInterpreterIntrinsics ();
1524- fIRGenerator ->start (&settings, fInterpreterModule );
1525- break ;
1526- }
1527- if (externalValues) {
1528- // Add any external values to the symbol table. IRGenerator::start() has pushed a table, so
1529- // we're only making these visible to the current Program.
1530- for (const auto & ev : *externalValues) {
1531- fIRGenerator ->fSymbolTable ->addWithoutOwnership (ev.get ());
1532- }
1533- }
1529+
1530+ // Not using AutoSource, because caller is likely to call errorText() if we fail to compile
15341531 std::unique_ptr<String> textPtr (new String (std::move (text)));
15351532 fSource = textPtr.get ();
1536- fIRGenerator ->convertProgram (kind, textPtr->c_str (), textPtr->size (), &elements);
1533+
1534+ const ParsedModule& baseModule = this ->moduleForProgramKind (kind);
1535+
1536+ IRGenerator::IRBundle ir =
1537+ fIRGenerator ->convertProgram (kind, &settings, baseModule, /* isBuiltinCode=*/ false ,
1538+ textPtr->c_str (), textPtr->size (), externalValues);
15371539 auto result = std::make_unique<Program>(kind,
15381540 std::move (textPtr),
15391541 settings,
15401542 fContext ,
1541- std::move (elements),
1542- fIRGenerator ->releaseModifiers (),
1543- fIRGenerator ->fSymbolTable ,
1544- fIRGenerator ->fInputs );
1545- fIRGenerator ->finish ();
1543+ std::move (ir.fElements ),
1544+ std::move (ir.fModifiers ),
1545+ std::move (ir.fSymbolTable ),
1546+ ir.fInputs );
15461547 if (fErrorCount ) {
15471548 return nullptr ;
15481549 }
@@ -1617,10 +1618,9 @@ bool Compiler::optimize(Program& program) {
16171618bool Compiler::toSPIRV (Program& program, OutputStream& out) {
16181619#ifdef SK_ENABLE_SPIRV_VALIDATION
16191620 StringStream buffer;
1620- fSource = program.fSource .get ();
1621+ AutoSource as ( this , program.fSource .get () );
16211622 SPIRVCodeGenerator cg (fContext .get (), &program, this , &buffer);
16221623 bool result = cg.generateCode ();
1623- fSource = nullptr ;
16241624 if (result) {
16251625 spvtools::SpirvTools tools (SPV_ENV_VULKAN_1_0);
16261626 const String& data = buffer.str ();
@@ -1635,10 +1635,9 @@ bool Compiler::toSPIRV(Program& program, OutputStream& out) {
16351635 out.write (data.c_str (), data.size ());
16361636 }
16371637#else
1638- fSource = program.fSource .get ();
1638+ AutoSource as ( this , program.fSource .get () );
16391639 SPIRVCodeGenerator cg (fContext .get (), &program, this , &out);
16401640 bool result = cg.generateCode ();
1641- fSource = nullptr ;
16421641#endif
16431642 return result;
16441643}
@@ -1653,10 +1652,9 @@ bool Compiler::toSPIRV(Program& program, String* out) {
16531652}
16541653
16551654bool Compiler::toGLSL (Program& program, OutputStream& out) {
1656- fSource = program.fSource .get ();
1655+ AutoSource as ( this , program.fSource .get () );
16571656 GLSLCodeGenerator cg (fContext .get (), &program, this , &out);
16581657 bool result = cg.generateCode ();
1659- fSource = nullptr ;
16601658 return result;
16611659}
16621660
@@ -1695,18 +1693,16 @@ bool Compiler::toMetal(Program& program, String* out) {
16951693
16961694#if defined(SKSL_STANDALONE) || GR_TEST_UTILS
16971695bool Compiler::toCPP (Program& program, String name, OutputStream& out) {
1698- fSource = program.fSource .get ();
1696+ AutoSource as ( this , program.fSource .get () );
16991697 CPPCodeGenerator cg (fContext .get (), &program, this , name, &out);
17001698 bool result = cg.generateCode ();
1701- fSource = nullptr ;
17021699 return result;
17031700}
17041701
17051702bool Compiler::toH (Program& program, String name, OutputStream& out) {
1706- fSource = program.fSource .get ();
1703+ AutoSource as ( this , program.fSource .get () );
17071704 HCodeGenerator cg (fContext .get (), &program, this , name, &out);
17081705 bool result = cg.generateCode ();
1709- fSource = nullptr ;
17101706 return result;
17111707}
17121708#endif // defined(SKSL_STANDALONE) || GR_TEST_UTILS
@@ -1715,11 +1711,10 @@ bool Compiler::toH(Program& program, String name, OutputStream& out) {
17151711
17161712#if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
17171713bool Compiler::toPipelineStage (Program& program, PipelineStageArgs* outArgs) {
1718- fSource = program.fSource .get ();
1714+ AutoSource as ( this , program.fSource .get () );
17191715 StringStream buffer;
17201716 PipelineStageCodeGenerator cg (fContext .get (), &program, this , &buffer, outArgs);
17211717 bool result = cg.generateCode ();
1722- fSource = nullptr ;
17231718 if (result) {
17241719 outArgs->fCode = buffer.str ();
17251720 }
@@ -1729,11 +1724,10 @@ bool Compiler::toPipelineStage(Program& program, PipelineStageArgs* outArgs) {
17291724
17301725std::unique_ptr<ByteCode> Compiler::toByteCode (Program& program) {
17311726#if defined(SK_ENABLE_SKSL_INTERPRETER)
1732- fSource = program.fSource .get ();
1727+ AutoSource as ( this , program.fSource .get () );
17331728 std::unique_ptr<ByteCode> result (new ByteCode ());
17341729 ByteCodeGenerator cg (fContext .get (), &program, this , result.get ());
17351730 bool success = cg.generateCode ();
1736- fSource = nullptr ;
17371731 if (success) {
17381732 return result;
17391733 }
0 commit comments