1 /*
2  * Copyright 2006-2008 The FLWOR Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #pragma once
17 #ifndef ZORBA_COMPILER_API_COMPILERCB
18 #define ZORBA_COMPILER_API_COMPILERCB
19 
20 #include <vector>
21 #include <map>
22 
23 #include <zorba/config.h>
24 
25 #include "common/shared_types.h"
26 
27 #ifdef MSVC
28 // The visual studio compiler is not able to compile the type rchandle<static_context>
29 // without having the definition of static_context availble.
30 # include "context/static_context.h"
31 #endif
32 #include "compiler/expression/pragma.h"
33 
34 #include "zorbaserialization/class_serializer.h"
35 
36 #include "compiler/expression/mem_manager.h"
37 #include "compiler/expression/expr_manager.h"
38 
39 namespace zorba {
40 
41 #ifdef ZORBA_WITH_DEBUGGER
42 class DebuggerCommons;
43 #endif
44 class static_context;
45 
46 /*******************************************************************************
47   There is one CompilerCB per query plus one CompilerCB per invocation of an
48   eval or xqdoc expression that appears in the query. The query-level ccb is
49   created by the constructor of the XQueryImpl obj and remains alive for the
50   whole duration of the query (including runtime). Each eval/xqdoc-level ccb is
51   created as a copy of the query-level ccb during the execution of the eval/xqdoc
52   expr.
53 
54   theXQueryDiagnostics :
55   ----------------------
56   Pointer to the query's XQueryDiagnostics obj. (see src/api/xqueryimpl.h). The eval
57   CompilerCBs share the query's XQueryDiagnostics.
58 
59   theSctxMap :
60   ------------
61   A query-level (or eval-level) map that stores the sctx objs that need to be
62   kept around for the whole duration of a query (including runtime). In non-
63   DEBUGGER mode, the map stores only for root sctx of each module. In DEBUGGER
64   mode, it stores all the sctxs created by each module. Each sctx stored in
65   this map has an associated numeric id, and theSctxMap actually maps these
66   numeric ids to their associated sctx objs. The map is modified by the methods
67   TranslatorImpl::end_visit(ModuleImport) and TranslatorImpl::push_scope().
68 
69   theRootSctx :
70   -------------
71   The root static ctx for the query or for one of the query's eval exprs. For
72   an eval expr, its root sctx is a child of the query's root sctx. For the query,
73   its root sctx may be (a) a child of a user-provided sctx, or (b) if the query
74   is a load-prolog query, the user-provided sctx, or (c) if the user did not
75   provide any sctx, a child of zorba's root sctx.
76 
77   theDebuggerCommons :
78   --------------------
79 
80   theHasEval :
81   ------------
82   True if there is an eval expr within the compilation unit covered by this CCB.
83 
84   theIsEval :
85   -----------
86   True if this is the CCB for an eval query. This flag is needed to determine
87   if a PUL returned by the main program must be applied or not.
88 
89   theIsLoadProlog :
90   -----------------
91   Whether this is a load-prolog query or not (load-prolog queries are created
92   internally by the StaticContextImpl::loadProlog() method).
93 
94   theIsUpdating :
95   ---------------
96   Set to true if the root expr of the query or eval expr is an updating expr.
97 
98   theTimeout :
99   ------------
100 
101   theTempIndexCounter :
102   ---------------------
103   A counter used to create unique names for temporary (query-specific) indexes
104   created to perform hashjoins (see rewriter/rules/index_join_rule.cpp).
105 
106   thePragmas:
107   -------------
108   A multimap from expr* to pragma such that not every expression needs
109   to keep it's own list of pragmas. Since the expr* pointer is only valid
110   until codegen finished, the pragmas can only be used in the compiler.
111 
112 
113   theConfig.lib_module :
114   ----------------------
115   If true, then if the query string that is given by the user is a library
116   module, zorba will wrap it in a dummy main module and compile/execute that
117   dummy module (see  XQueryCompiler::createMainModule() method). This flag is
118   a copy of the lib_module flag in Zorba_CompilerHints_t.
119 
120   theConfig.for_serialization_only :
121   ----------------------------------
122   This flag is a copy of the for_serialization_only flag in Zorba_CompilerHints_t.
123 
124   theConfig.parse_cb :
125   Pointer to the function to call to print the AST that results from parsing
126   the query.
127 
128   theConfig.translate_cb :
129   ------------------------
130   Pointer to the function to call to print the expr tree that results from
131   translating the query AST.
132 ********************************************************************************/
133 class ZORBA_DLL_PUBLIC CompilerCB : public zorba::serialization::SerializeBaseClass
134 {
135 public:
136   struct config : public zorba::serialization::SerializeBaseClass
137   {
138     typedef enum
139     {
140       O0,
141       O1,
142       O2
143     } opt_level_t;
144 
145     typedef void (* expr_callback) (const expr *, const std::string& name);
146 
147     typedef void (* ast_callback) (const parsenode *, const std::string& name);
148 
149     bool           force_gflwor;
150     opt_level_t    opt_level;
151     bool           lib_module;
152     bool           for_serialization_only;
153     ast_callback   parse_cb;
154     expr_callback  translate_cb;
155     expr_callback  optimize_cb;
156     bool           print_item_flow;  // TODO: move to RuntimeCB
157 
158    public:
159     SERIALIZABLE_CLASS(config);
160     config(::zorba::serialization::Archiver& ar);
161 
162     config();
163 
~configconfig164     ~config() {}
165 
166     void serialize(::zorba::serialization::Archiver& ar);
167   };
168 
169   typedef std::map<csize, static_context_t> SctxMap;
170 
171 public:
172   XQueryDiagnostics       * theXQueryDiagnostics;
173 
174   SctxMap                   theSctxMap;
175 
176   static_context          * theRootSctx;
177 
178 #ifdef ZORBA_WITH_DEBUGGER
179   DebuggerCommons         * theDebuggerCommons;
180 #endif
181 
182   bool                      theHasEval;
183 
184   bool                      theIsEval;
185 
186   bool                      theIsLoadProlog;
187 
188   bool                      theIsUpdating;
189 
190   bool                      theIsSequential;
191 
192   bool                      theHaveTimeout;
193 
194   uint32_t                  theTimeout;
195 
196   uint32_t                  theTempIndexCounter;
197 
198   config                    theConfig;
199 
200   ExprManager       * const theEM;
201 
202   typedef std::multimap<const expr*, pragma*>  PragmaMap;
203   typedef PragmaMap::const_iterator            PragmaMapIter;
204   PragmaMap                                    thePragmas;
205 
206 public:
207   SERIALIZABLE_CLASS(CompilerCB);
208   CompilerCB(::zorba::serialization::Archiver& ar);
209   void serialize(::zorba::serialization::Archiver& ar);
210 
211 public:
212   CompilerCB(XQueryDiagnostics*, long timeout = -1);
213 
214   CompilerCB(const CompilerCB& ccb);
215 
216   ~CompilerCB();
217 
isLoadPrologQuery()218   bool isLoadPrologQuery() const { return theIsLoadProlog; }
219 
setLoadPrologQuery()220   void setLoadPrologQuery() { theIsLoadProlog = true; }
221 
setIsUpdating(bool aIsUpdating)222   void setIsUpdating(bool aIsUpdating) { theIsUpdating = aIsUpdating; }
223 
isUpdating()224   bool isUpdating() const { return theIsUpdating; }
225 
setIsSequential(bool aIsSequential)226   void setIsSequential(bool aIsSequential) {theIsSequential = aIsSequential;}
227 
isSequential()228   bool isSequential() const { return theIsSequential;}
229 
230   static_context* getStaticContext(int id);
231 
getExprManager()232   ExprManager* getExprManager() const { return theEM; }
233 
getMemoryManager()234   MemoryManager& getMemoryManager() const { return theEM->getMemory(); }
235 
236   //
237   // Pragmas
238   //
239   void add_pragma(const expr* e, pragma* p);
240 
241   void
242   lookup_pragmas(const expr* e, std::vector<pragma*>& pragmas) const;
243 
244   bool
245   lookup_pragma(const expr* e, const zstring& localname, pragma*&) const;
246 
247 };
248 
249 
250 }
251 
252 #endif
253 
254 /*
255  * Local variables:
256  * mode: c++
257  * End:
258  */
259 /* vim:set et sw=2 ts=2: */
260