slang_rs_reflection.h revision 277fd5e6545c8ba1272027ee6e6bc55a96316dc0
1/*
2 * Copyright 2010-2012, The Android Open Source Project
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
17#ifndef _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ // NOLINT
18#define _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_
19
20#include <fstream>
21#include <iostream>
22#include <map>
23#include <set>
24#include <string>
25#include <vector>
26
27#include "llvm/ADT/StringExtras.h"
28
29#include "slang_assert.h"
30#include "slang_rs_export_type.h"
31#include "slang_rs_reflect_utils.h"
32
33namespace slang {
34
35class RSContext;
36class RSExportVar;
37class RSExportFunc;
38class RSExportForEach;
39
40class RSReflectionJava {
41private:
42  const RSContext *mRSContext;
43
44  // The name of the Java package name we're creating this file for,
45  // e.g. com.example.android.rs.flashlight
46  std::string mPackageName;
47  // The name of the Java Renderscript package we'll be using,
48  // e.g. android.renderscript
49  // e.g. android.support.v8.renderscript
50  std::string mRSPackageName;
51
52  // The directory under which we'll create the Java files, in appropriate subdirectories,
53  // e.g. /tmp/myout
54  std::string mOutputBaseDirectory;
55  // The output directory for the specfied package (mPackageName),
56  // e.g. /tmp/myout/com/example/android/rs/flashlight/
57  // TODO This includes the terminating separator.  Needed?
58  std::string mOutputDirectory;
59
60  // The full path of the .rs file that we are reflecting.
61  std::string mRSSourceFileName;
62  // The full path where the generated bit code can be read.
63  std::string mBitCodeFileName;
64
65  // The name of the resource we pass to the RenderScript constructor
66  // e.g. flashlight
67  std::string mResourceId;
68  // The name of the Java class we are generating for this script.
69  // e.g. ScriptC_flashlight
70  std::string mScriptClassName;
71
72
73  // This is set by startClass() and will change for the multiple classes generated.
74  std::string mClassName;
75
76  // This is the token used for determining the size of a given ScriptField.Item.
77  std::string mItemSizeof;
78
79  bool mEmbedBitcodeInJava;
80
81  int mNextExportVarSlot;
82  int mNextExportFuncSlot;
83  int mNextExportForEachSlot;
84  int mNextExportReduceSlot;
85  int mNextExportReduceNewSlot;
86
87  GeneratedFile mOut;
88
89  std::string mLastError;
90  std::vector<std::string> *mGeneratedFileNames;
91
92  // A mapping from a field in a record type to its index in the rsType
93  // instance. Only used when generates TypeClass (ScriptField_*).
94  typedef std::map<const RSExportRecordType::Field *, unsigned> FieldIndexMapTy;
95  FieldIndexMapTy mFieldIndexMap;
96  // Field index of current processing TypeClass.
97  unsigned mFieldIndex;
98
99  inline void setError(const std::string &Error) { mLastError = Error; }
100
101  inline void clear() {
102    mClassName = "";
103    mNextExportVarSlot = 0;
104    mNextExportFuncSlot = 0;
105    mNextExportForEachSlot = 0;
106    mNextExportReduceSlot = 0;
107    mNextExportReduceNewSlot = 0;
108  }
109
110public:
111  typedef enum {
112    AM_Public,
113    AM_Protected,
114    AM_Private,
115    AM_PublicSynchronized
116  } AccessModifier;
117
118  // Generated RS Elements for type-checking code.
119  std::set<std::string> mTypesToCheck;
120
121  // Generated FieldPackers for unsigned setters/validation.
122  std::set<std::string> mFieldPackerTypes;
123
124  bool addTypeNameForElement(const std::string &TypeName);
125  bool addTypeNameForFieldPacker(const std::string &TypeName);
126
127  static const char *AccessModifierStr(AccessModifier AM);
128
129  inline bool getEmbedBitcodeInJava() const { return mEmbedBitcodeInJava; }
130
131  inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
132  inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
133  inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; }
134  inline int getNextExportReduceSlot() { return mNextExportReduceSlot++; }
135  inline int getNextExportReduceNewSlot() { return mNextExportReduceNewSlot++; }
136
137  bool startClass(AccessModifier AM, bool IsStatic,
138                  const std::string &ClassName, const char *SuperClassName,
139                  std::string &ErrorMsg);
140  void endClass();
141
142  void startFunction(AccessModifier AM, bool IsStatic, const char *ReturnType,
143                     const std::string &FunctionName, int Argc, ...);
144
145  typedef std::vector<std::pair<std::string, std::string>> ArgTy;
146  void startFunction(AccessModifier AM, bool IsStatic, const char *ReturnType,
147                     const std::string &FunctionName, const ArgTy &Args);
148  void endFunction();
149
150  inline const std::string &getPackageName() const { return mPackageName; }
151  inline const std::string &getRSPackageName() const { return mRSPackageName; }
152  inline const std::string &getClassName() const { return mClassName; }
153  inline const std::string &getResourceId() const { return mResourceId; }
154
155  void startTypeClass(const std::string &ClassName);
156  void endTypeClass();
157
158  inline void incFieldIndex() { mFieldIndex++; }
159
160  inline void resetFieldIndex() { mFieldIndex = 0; }
161
162  inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
163    slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
164                "Nested structure never occurs in C language.");
165    mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
166  }
167
168  inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
169    FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
170    slangAssert((I != mFieldIndexMap.end()) &&
171                "Requesting field is out of scope.");
172    return I->second;
173  }
174
175  inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
176
177private:
178  static bool exportableReduceNew(const RSExportType *ResultType);
179
180  bool genScriptClass(const std::string &ClassName, std::string &ErrorMsg);
181  void genScriptClassConstructor();
182
183  void genInitBoolExportVariable(const std::string &VarName,
184                                 const clang::APValue &Val);
185  void genInitPrimitiveExportVariable(const std::string &VarName,
186                                      const clang::APValue &Val);
187  void genInitExportVariable(const RSExportType *ET, const std::string &VarName,
188                             const clang::APValue &Val);
189  void genInitValue(const clang::APValue &Val, bool asBool);
190  void genExportVariable(const RSExportVar *EV);
191  void genPrimitiveTypeExportVariable(const RSExportVar *EV);
192  void genPointerTypeExportVariable(const RSExportVar *EV);
193  void genVectorTypeExportVariable(const RSExportVar *EV);
194  void genMatrixTypeExportVariable(const RSExportVar *EV);
195  void genConstantArrayTypeExportVariable(const RSExportVar *EV);
196  void genRecordTypeExportVariable(const RSExportVar *EV);
197  void genPrivateExportVariable(const std::string &TypeName,
198                                const std::string &VarName);
199  void genSetExportVariable(const std::string &TypeName, const RSExportVar *EV, unsigned Dimension);
200  void genGetExportVariable(const std::string &TypeName,
201                            const std::string &VarName);
202  void genGetFieldID(const std::string &VarName);
203
204  void genExportFunction(const RSExportFunc *EF);
205
206  void genExportForEach(const RSExportForEach *EF);
207
208  void genExportReduce(const RSExportReduce *ER);
209  void genExportReduceAllocationVariant(const RSExportType *Type,
210                                        const std::string &KernelName);
211  void genExportReduceArrayVariant(const RSExportType *Type,
212                                   const std::string &KernelName);
213
214  void genExportReduceNew(const RSExportReduceNew *ER);
215  void genExportReduceNewAllocationVariant(const RSExportReduceNew *ER);
216  void genExportReduceNewArrayVariant(const RSExportReduceNew *ER);
217  void genExportReduceNewResultType(const RSExportType *ResultType);
218
219  void genTypeCheck(const RSExportType *ET, const char *VarName);
220
221  void genTypeInstanceFromPointer(const RSExportType *ET);
222
223  void genTypeInstance(const RSExportType *ET);
224
225  void genFieldPackerInstance(const RSExportType *ET);
226
227  bool genTypeClass(const RSExportRecordType *ERT, std::string &ErrorMsg);
228  void genTypeItemClass(const RSExportRecordType *ERT);
229  void genTypeClassConstructor(const RSExportRecordType *ERT);
230  void genTypeClassCopyToArray(const RSExportRecordType *ERT);
231  void genTypeClassCopyToArrayLocal(const RSExportRecordType *ERT);
232  void genTypeClassItemSetter(const RSExportRecordType *ERT);
233  void genTypeClassItemGetter(const RSExportRecordType *ERT);
234  void genTypeClassComponentSetter(const RSExportRecordType *ERT);
235  void genTypeClassComponentGetter(const RSExportRecordType *ERT);
236  void genTypeClassCopyAll(const RSExportRecordType *ERT);
237  void genTypeClassResize();
238
239  void genBuildElement(const char *ElementBuilderName,
240                       const RSExportRecordType *ERT,
241                       const char *RenderScriptVar, bool IsInline);
242  void genAddElementToElementBuilder(const RSExportType *ERT,
243                                     const std::string &VarName,
244                                     const char *ElementBuilderName,
245                                     const char *RenderScriptVar,
246                                     unsigned ArraySize);
247
248  bool genCreateFieldPacker(const RSExportType *T, const char *FieldPackerName);
249  void genPackVarOfType(const RSExportType *T, const char *VarName,
250                        const char *FieldPackerName);
251  void genAllocateVarOfType(const RSExportType *T, const std::string &VarName);
252  void genNewItemBufferIfNull(const char *Index);
253  void genNewItemBufferPackerIfNull();
254
255  void genPairwiseDimCheck(std::string name0, std::string name1);
256  void genVectorLengthCompatibilityCheck(const std::string &ArrayName, unsigned VecSize);
257  void genNullArrayCheck(const std::string &ArrayName);
258  void genNullOrEmptyArrayCheck(const std::string &ArrayName);
259  void gen1DCheck(const std::string &Name);
260
261public:
262  RSReflectionJava(const RSContext *Context,
263                   std::vector<std::string> *GeneratedFileNames,
264                   const std::string &OutputBaseDirectory,
265                   const std::string &RSSourceFilename,
266                   const std::string &BitCodeFileName,
267                   bool EmbedBitcodeInJava);
268
269  bool reflect();
270
271  inline const char *getLastError() const {
272    if (mLastError.empty())
273      return nullptr;
274    else
275      return mLastError.c_str();
276  }
277}; // class RSReflectionJava
278
279} // namespace slang
280
281#endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_  NOLINT
282