1 /************************************************************************
2  ************************************************************************
3     FAUST compiler
4     Copyright (C) 2003-2018 GRAME, Centre National de Creation Musicale
5     ---------------------------------------------------------------------
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  ************************************************************************
20  ************************************************************************/
21 
22 #ifndef __FAUST_GLOBAL__
23 #define __FAUST_GLOBAL__
24 
25 #include <stdio.h>
26 #include <string.h>
27 #include <list>
28 #include <map>
29 #include <set>
30 #include <stack>
31 #include <vector>
32 
33 #ifndef _WIN32
34 #include <unistd.h>
35 #endif
36 
37 #include "exception.hh"
38 #include "instructions_type.hh"
39 #include "loopDetector.hh"
40 #include "occurrences.hh"
41 #include "property.hh"
42 #include "sigtype.hh"
43 #include "sourcereader.hh"
44 
45 class CTree;
46 typedef CTree* Tree;
47 
48 class Symbol;
49 typedef Symbol* Sym;
50 
51 class xtended;
52 class AudioType;
53 
54 class Garbageable;
55 
56 struct DispatchVisitor;
57 class WASTInstVisitor;
58 class WASMInstVisitor;
59 class JuliaInstVisitor;
60 struct TableSizeVisitor;
61 struct DeclareStructTypeInst;
62 
63 struct Typed;
64 struct BasicTyped;
65 
66 struct dsp_factory_base;
67 
68 typedef long double quad;
69 
70 struct comp_str {
operator ()comp_str71     bool operator()(Tree s1, Tree s2) const { return (strcmp(tree2str(s1), tree2str(s2)) < 0); }
72 };
73 
74 typedef map<Tree, set<Tree>, comp_str> MetaDataSet;
75 
76 typedef map<Tree, set<Tree>> FunMDSet;  // foo -> {(file/foo/key,value)...}
77 
78 // Global singleton like compiler state
79 struct global {
80     Tree gResult;
81     Tree gResult2;
82 
83     SourceReader gReader;
84 
85     MetaDataSet gMetaDataSet;
86     FunMDSet    gFunMDSet;
87     string      gDocLang;
88     tvec        gWaveForm;
89 
90     //-- globals
91     string         gFaustSuperSuperDirectory;
92     string         gFaustSuperDirectory;
93     string         gFaustDirectory;
94     string         gFaustExeDir;
95     string         gFaustRootDir;  // abs path to faust root directory
96     string         gMasterDocument;
97     string         gMasterDirectory;
98     string         gMasterName;
99     string         gDocName;
100     vector<string> gImportDirList;        // dir list enrobage.cpp/fopensearch() searches for imports, etc.
101     vector<string> gArchitectureDirList;  // dir list enrobage.cpp/fopensearch() searches for architecture files
102     vector<string> gLibraryList;
103     string         gOutputDir;
104     string         gImportFilename;
105     Tree           gExpandedDefList;
106 
107     //-- command line arguments
108     bool   gDetailsSwitch;
109     bool   gDrawSignals;
110     bool   gDrawRouteFrame;
111     bool   gShadowBlur;      // note: svg2pdf doesn't like the blur filter
112     bool   gScaledSVG;       // to draw scaled SVG files
113     bool   gStripDocSwitch;  // Strip <mdoc> content from doc listings.
114     int    gFoldThreshold;   // global complexity threshold before activating folding
115     int    gFoldComplexity;  // individual complexity threshold before folding
116     int    gMaxNameSize;
117     bool   gSimpleNames;
118     bool   gSimplifyDiagrams;
119     int    gMaxCopyDelay;
120     string gOutputFile;
121 
122     bool gVectorSwitch;
123     bool gDeepFirstSwitch;
124     int  gVecSize;
125     int  gVectorLoopVariant;
126 
127     bool gOpenMPSwitch;
128     bool gOpenMPLoop;
129     bool gSchedulerSwitch;
130     bool gOpenCLSwitch;
131     bool gCUDASwitch;
132     bool gGroupTaskSwitch;
133     bool gFunTaskSwitch;
134 
135     bool gUIMacroSwitch;
136     bool gDumpNorm;
137     int  gFTZMode;
138     bool gRangeUI;  // whether to generate code to limit vslider/hslider/nentry values in [min..max] range
139 
140     int gFloatSize;
141 
142     bool gPrintFileListSwitch;
143     bool gInlineArchSwitch;
144 
145     bool gDSPStruct;
146     bool gLightMode;  // do not generate the entire DSP API (to be used with Emscripten to generate a light DSP module
147                       // for JavaScript)
148     bool   gClang;    // when compiled with clang/clang++, adds specific #pragma for auto-vectorization
149     string gCheckTable;  // whether to check RDTable and RWTable index range
150 
151     bool   gMathExceptions;  // whether to check math functions domains
152 
153     string gClassName;       // name of the generated dsp class, by default 'mydsp'
154     string gSuperClassName;  // name of the root class the generated dsp class inherits from, by default 'dsp'
155     string gProcessName;     // name of the entry point of the Faust program, by default 'process'
156 
157     // Backend configuration
158     string gOutputLang;            // Chosen backend
159     bool   gAllowForeignFunction;  // Can use foreign functions
160     bool   gAllowForeignConstant;  // Can use foreign constant
161     bool   gAllowForeignVar;       // Can use foreign variable
162     bool   gComputeIOTA;           // Cache some computation done with IOTA variable
163     bool   gFAUSTFLOAT2Internal;   // FAUSTFLOAT type (= kFloatMacro) forced to internal real
164     bool   gInPlace;               // Add cache to input for correct in-place computations
165     bool   gHasExp10;              // If the 'exp10' math function is available
166     bool   gLoopVarInBytes;        // If the 'i' variable used in the scalar loop moves by bytes instead of frames
167     bool   gWaveformInDSP;         // If waveform are allocated in the DSP and not as global data
168     bool   gUseDefaultSound;       // If default global variable is used in 'soundfile' primitive generation
169     bool   gHasTeeLocal;           // For wast/wasm backends
170     bool   gFastMath;              // Faster version of some mathematical functions (pow/exp/log)
171     bool   gMathApprox;            // Simpler/faster versions of 'floor/fmod/remainder' functions
172     bool   gNeedManualPow;         // If manual pow(x, y) generation when y is an integer is needed
173     bool   gRemoveVarAddress;      // If used of variable addresses (like &foo or &foo[n]) have to be removed
174     int    gOneSample;              // Generate one sample computation:  (0 = separated control) (1 = separated control and DSP struct)
175     bool   gOneSampleControl;      // Generate one sample computation control structure in DSP module
176     bool   gComputeMix;            // Mix in outputs buffers
177     string gFastMathLib;           // The fastmath code mapping file
178     string gNameSpace;             // Wrapping namespace used with the C++ backend
179 
180     int gWideningLimit;     // Max number of iterations before interval widening
181     int gNarrowingLimit;    // Max number of iterations to compute interval widener
182 
183     map<string, string> gFastMathLibTable;      // Mapping table for fastmath functions
184     map<string, bool>   gMathForeignFunctions;  // Map of math foreign functions
185 
186     dsp_factory_base* gDSPFactory;
187 
188     const char* gInputString;
189 
190     bool gLstDependenciesSwitch;  ///< mdoc listing management
191     bool gLstMdocTagsSwitch;      ///< mdoc listing management
192     bool gLstDistributedSwitch;   ///< mdoc listing management
193 
194     map<string, string> gDocMetadatasStringMap;
195     set<string>         gDocMetadatasKeySet;
196 
197     map<string, string> gDocAutodocStringMap;
198     set<string>         gDocAutodocKeySet;
199 
200     map<string, bool> gDocNoticeFlagMap;
201 
202     map<string, string> gDocMathStringMap;
203 
204     vector<Tree> gDocVector;  ///< Contains <mdoc> parsed trees: DOCTXT, DOCEQN, DOCDGM
205 
206     map<string, string> gDocNoticeStringMap;
207     set<string>         gDocNoticeKeySet;
208 
209     set<string> gDocMathKeySet;
210 
211     bool gLatexDocSwitch;  // Only LaTeX outformat is handled for the moment
212 
213     int gErrorCount;
214 
215     string gErrorMsg;
216 
217     Tabber TABBER;
218 
219     list<string> gInputFiles;
220 
221     int gFileNum;
222 
223     int gCountInferences;
224     int gCountMaximal;
225     int gDummyInput;
226 
227     int gBoxSlotNumber;  ///< counter for unique slot number
228 
229     bool gMemoryManager;
230 
231     bool gLocalCausalityCheck;  ///< when true trigs local causality errors (negative delay)
232 
233     bool gCausality;  ///< (FIXME: global used as a parameter of typeAnnotation) when true trigs causality errors
234                       ///< (negative delay)
235 
236     Tree BOXTYPEPROP;
237     Tree NUMERICPROPERTY;
238     Tree DEFLINEPROP;
239     Tree USELINEPROP;
240     Tree SIMPLIFIED;
241     Tree DOCTABLES;
242     Tree NULLENV;
243     Tree COLORPROPERTY;
244     Tree ORDERPROP;
245     Tree RECURSIVNESS;
246     Tree NULLTYPEENV;
247     Tree RECDEF;
248     Tree DEBRUIJN2SYM;
249     Tree DEFNAMEPROPERTY;
250     Tree NICKNAMEPROPERTY;
251     Tree BCOMPLEXITY;  // Node used for memoization purposes
252     Tree LETRECBODY;
253 
254     Node PROPAGATEPROPERTY;
255 
256     xtended* gAbsPrim;
257     xtended* gAcosPrim;
258     xtended* gTanPrim;
259     xtended* gSqrtPrim;
260     xtended* gSinPrim;
261     xtended* gRintPrim;
262     xtended* gRemainderPrim;
263     xtended* gPowPrim;
264     xtended* gMinPrim;
265     xtended* gMaxPrim;
266     xtended* gLogPrim;
267     xtended* gLog10Prim;
268     xtended* gFmodPrim;
269     xtended* gFloorPrim;
270     xtended* gExpPrim;
271     xtended* gExp10Prim;
272     xtended* gCosPrim;
273     xtended* gCeilPrim;
274     xtended* gAtanPrim;
275     xtended* gAtan2Prim;
276     xtended* gAsinPrim;
277     xtended* gFtzPrim;
278 
279     Sym BOXIDENT;
280     Sym BOXCUT;
281     Sym BOXWAVEFORM;
282     Sym BOXROUTE;
283     Sym BOXWIRE;
284     Sym BOXSLOT;
285     Sym BOXSYMBOLIC;
286     Sym BOXSEQ;
287     Sym BOXPAR;
288     Sym BOXREC;
289     Sym BOXSPLIT;
290     Sym BOXMERGE;
291     Sym BOXIPAR;
292     Sym BOXISEQ;
293     Sym BOXISUM;
294     Sym BOXIPROD;
295     Sym BOXABSTR;
296     Sym BOXAPPL;
297     Sym CLOSURE;
298     Sym BOXERROR;
299     Sym BOXACCESS;
300     Sym BOXWITHLOCALDEF;
301     Sym BOXMODIFLOCALDEF;
302     Sym BOXENVIRONMENT;
303     Sym BOXCOMPONENT;
304     Sym BOXLIBRARY;
305     Sym IMPORTFILE;
306     Sym BOXPRIM0;
307     Sym BOXPRIM1;
308     Sym BOXPRIM2;
309     Sym BOXPRIM3;
310     Sym BOXPRIM4;
311     Sym BOXPRIM5;
312     Sym BOXFFUN;
313     Sym BOXFCONST;
314     Sym BOXFVAR;
315     Sym BOXBUTTON;
316     Sym BOXCHECKBOX;
317     Sym BOXHSLIDER;
318     Sym BOXVSLIDER;
319     Sym BOXNUMENTRY;
320     Sym BOXHGROUP;
321     Sym BOXVGROUP;
322     Sym BOXTGROUP;
323     Sym BOXHBARGRAPH;
324     Sym BOXVBARGRAPH;
325     Sym BOXCASE;
326     Sym BOXPATMATCHER;
327     Sym BOXPATVAR;
328     Sym BOXINPUTS;
329     Sym BOXOUTPUTS;
330     Sym BOXSOUNDFILE;
331     Sym BOXMETADATA;
332     Sym DOCEQN;
333     Sym DOCDGM;
334     Sym DOCNTC;
335     Sym DOCLST;
336     Sym DOCMTD;
337     Sym DOCTXT;
338     Sym BARRIER;
339 
340     property<bool>* gPureRoutingProperty;
341     property<Tree>* gSymbolicBoxProperty;
342 
343     Node EVALPROPERTY;
344     Node PMPROPERTYNODE;
345 
346     property<Tree>* gSimplifiedBoxProperty;
347 
348     Sym UIFOLDER;
349     Sym UIWIDGET;
350 
351     Sym PATHROOT;
352     Sym PATHPARENT;
353     Sym PATHCURRENT;
354 
355     Sym FFUN;
356 
357     // the property used to memoize the results
358     property<Tree>* gSymListProp;
359 
360     Sym SIGINPUT;
361     int gMaxInputs;  // Max input allocated with sigInput API
362     Sym SIGOUTPUT;
363     Sym SIGDELAY1;
364     Sym SIGDELAY;
365     Sym SIGPREFIX;
366     Sym SIGIOTA;
367     Sym SIGRDTBL;
368     Sym SIGWRTBL;
369     Sym SIGTABLE;
370     Sym SIGGEN;
371     Sym SIGDOCONSTANTTBL;
372     Sym SIGDOCWRITETBL;
373     Sym SIGDOCACCESSTBL;
374     Sym SIGSELECT2;
375     Sym SIGASSERTBOUNDS;
376     Sym SIGHIGHEST;
377     Sym SIGLOWEST;
378     Sym SIGBINOP;
379     Sym SIGFFUN;
380     Sym SIGFCONST;
381     Sym SIGFVAR;
382     Sym SIGPROJ;
383     Sym SIGINTCAST;
384     Sym SIGFLOATCAST;
385     Sym SIGBUTTON;
386     Sym SIGCHECKBOX;
387     Sym SIGWAVEFORM;
388     Sym SIGHSLIDER;
389     Sym SIGVSLIDER;
390     Sym SIGNUMENTRY;
391     Sym SIGHBARGRAPH;
392     Sym SIGVBARGRAPH;
393     Sym SIGATTACH;
394     Sym SIGENABLE;
395     Sym SIGCONTROL;
396     Sym SIGSOUNDFILE;
397     Sym SIGSOUNDFILELENGTH;
398     Sym SIGSOUNDFILERATE;
399     Sym SIGSOUNDFILEBUFFER;
400     Sym SIGTUPLE;
401     Sym SIGTUPLEACCESS;
402 
403     Sym SIMPLETYPE;
404     Sym TABLETYPE;
405     Sym TUPLETTYPE;
406 
407     // Memoized type contruction
408     property<AudioType*>* gMemoizedTypes;
409 
410     // The map of types and associated Structured types
411     map<Typed::VarType, DeclareStructTypeInst*> gExternalStructTypes;
412 
413     // Essential predefined types
414     Type TINT;
415     Type TREAL;
416 
417     Type TKONST;
418     Type TBLOCK;
419     Type TSAMP;
420 
421     Type TCOMP;
422     Type TINIT;
423     Type TEXEC;
424 
425     // More predefined types
426     Type TINPUT;
427     Type TGUI;
428     Type TGUI01;
429     Type INT_TGUI;
430 
431     // Trying to accelerate type convergence
432     Type TREC;  // kVect ou kScal ?
433     Type TRECMAX;
434 
435     res RES;
436 
437     Sym  CONS;
438     Sym  NIL;
439     Tree nil;
440 
441     Sym PROCESS;
442 
443     Sym DEBRUIJN;
444     Sym DEBRUIJNREF;
445     Sym SUBSTITUTE;
446 
447     Sym SYMREC;
448     Sym SYMRECREF;
449     Sym SYMLIFTN;
450 
451     loopDetector          gLoopDetector;
452     stackOverflowDetector gStackOverflowDetector;
453 
454     string gDrawPath;
455 
456     int gMachineFloatSize;
457     int gMachineInt32Size;
458     int gMachineInt64Size;
459     int gMachineDoubleSize;
460     int gMachineBoolSize;
461     int gMachinePtrSize;
462 
463     int gMachineMaxStackSize;
464 
465     const char* gDocDevSuffix;  ///< ".tex" (or .??? - used to choose output device)
466     string      gCurrentDir;    ///< Room to save current directory name
467     string      gLatexheaderfilename;
468 
469     struct tm gCompilationDate;
470 
471     map<string, int> gIDCounters;
472 
473     string gDocTextsDefaultFile;
474 
475     // internal state during drawing
476     Occurrences*      gOccurrences;
477     bool              gFoldingFlag;     // true with complex block-diagrams
478     stack<Tree>       gPendingExp;      // Expressions that need to be drawn
479     set<Tree>         gDrawnExp;        // Expressions drawn or scheduled so far
480     const char*       gDevSuffix;       // .svg or .ps used to choose output device
481     string            gSchemaFileName;  // name of schema file beeing generated
482     map<Tree, string> gBackLink;        // link to enclosing file for sub schema
483 
484     // FIR
485     map<Typed::VarType, BasicTyped*> gTypeTable;     // To share a unique BasicTyped* object for a given type
486     map<string, Typed*>              gVarTypeTable;  // Types of variables or functions
487     map<Typed::VarType, int>         gTypeSizeMap;   // Size of types in bytes
488 
489     // colorize
490     map<Tree, int> gColorMap;
491     int            gNextFreeColor;
492 
493     // to keep track of already injected files
494     set<string> gAlreadyIncluded;
495 
496     char* gCurrentLocal;
497 
498     int gAllocationCount;  // Internal signal types counter
499 
500     int gMaskDelayLineThreshold;  // Power-of-two and mask delay-lines treshold
501 
502     bool gEnableFlag;
503 
504 #ifdef WASM_BUILD
505     // One single global visitor for WebAssembly, so that sub-containers and the global container use the same heap
506     WASMInstVisitor* gWASMVisitor;
507     WASTInstVisitor* gWASTVisitor;
508 #endif
509 
510 #ifdef INTERP_BUILD
511     // One single global visitor Interpreter backend, so that sub-containers and the global container use the same heap
512     DispatchVisitor* gInterpreterVisitor;
513 #endif
514 
515 #ifdef JULIA_BUILD
516     // One single global visitor Julia backend, so that sub-containers and the global container use the same heap
517     JuliaInstVisitor* gJuliaVisitor;
518 #endif
519 
520 #ifdef SOUL_BUILD
521     TableSizeVisitor* gTableSizeVisitor;
522 #endif
523 
524     bool gHelpSwitch;
525     bool gVersionSwitch;
526     bool gLibDirSwitch;
527     bool gIncludeDirSwitch;
528     bool gArchDirSwitch;
529     bool gDspDirSwitch;
530     bool gPathListSwitch;
531 
532     bool   gGraphSwitch;
533     bool   gDrawPSSwitch;
534     bool   gDrawSVGSwitch;
535     bool   gVHDLSwitch;
536     bool   gVHDLTrace;
537     bool   gElementarySwitch;
538     bool   gPrintXMLSwitch;
539     bool   gPrintJSONSwitch;
540     bool   gPrintDocSwitch;
541     string gArchFile;
542     bool   gExportDSP;
543 
544     // Source file injection
545     bool   gInjectFlag;
546     string gInjectFile;
547 
548     int gTimeout;  // Time out to abort compiler (in seconds)
549 
550     // Globals to transfer results in thread based evaluation
551     Tree   gProcessTree;
552     Tree   gLsignalsTree;
553     int    gNumInputs;
554     int    gNumOutputs;
555     string gErrorMessage;
556 
557     // GC
558     static list<Garbageable*> gObjectTable;
559     static bool               gHeapCleanup;
560 
561     global();
562     ~global();
563 
564     void init();
565 
566     static void allocate();
567     static void destroy();
568 
569     string getFreshID(const string& prefix);
570 
571     string makeDrawPath();
572     string makeDrawPathNoExt();
573 
getMathFunctionglobal574     string getMathFunction(const string& name)
575     {
576         if (gFastMath && (gFastMathLibTable.find(name) != gFastMathLibTable.end())) {
577             return gFastMathLibTable[name];
578         } else {
579             return name;
580         }
581     }
582 
hasVarTypeglobal583     bool hasVarType(const string& name) { return gVarTypeTable.find(name) != gVarTypeTable.end(); }
584 
585     BasicTyped* genBasicTyped(Typed::VarType type);
586 
587     Typed::VarType getVarType(const string& name);
588 
589     void setVarType(const string& name, Typed::VarType type);
590 
startWithglobal591     inline bool startWith(const string& str, const string& prefix) { return (str.substr(0, prefix.size()) == prefix); }
592 
593     // Some backends have an internal implementation of foreign functions like acos, asinh...
hasMathForeignFunctionglobal594     bool hasMathForeignFunction(const string& name)
595     {
596         bool has_internal_math_ff = ((gOutputLang == "llvm")
597                                      || startWith(gOutputLang, "wast")
598                                      || startWith(gOutputLang, "wasm")
599                                      || (gOutputLang == "interp")
600                                      || startWith(gOutputLang, "soul")
601                                      || (gOutputLang == "dlang")
602                                      || (gOutputLang == "csharp")
603                                      || (gOutputLang == "rust")
604                                      || (gOutputLang == "julia"));
605         return has_internal_math_ff && (gMathForeignFunctions.find(name) != gMathForeignFunctions.end());
606     }
607 
608     void printCompilationOptions(stringstream& dst, bool backend = true);
609 
610     void initTypeSizeMap();
611 
612     int audioSampleSize();
613 };
614 
615 // Unique shared global pointer
616 extern global* gGlobal;
617 
618 #define FAUST_LIB_PATH "FAUST_LIB_PATH"
619 #define MAX_MACHINE_STACK_SIZE 65536
620 #define MAX_SOUNDFILE_PARTS 256
621 
622 #endif
623