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 #include "slang_rs_reflection_state.h" 33 34 namespace slang { 35 36 class RSContext; 37 class RSExportVar; 38 class RSExportFunc; 39 class RSExportForEach; 40 41 class RSReflectionJava { 42 private: 43 const RSContext *mRSContext; 44 45 ReflectionState *mState; 46 47 // If we're in the "collecting" state (according to mState), we 48 // don't actually generate code, but we do want to keep track of 49 // some information about what we WOULD generate. 50 const bool mCollecting; 51 52 // The name of the Java package name we're creating this file for, 53 // e.g. com.example.android.rs.flashlight 54 std::string mPackageName; 55 // The name of the Java Renderscript package we'll be using, 56 // e.g. android.renderscript 57 // e.g. android.support.v8.renderscript 58 std::string mRSPackageName; 59 60 // The directory under which we'll create the Java files, in appropriate subdirectories, 61 // e.g. /tmp/myout 62 std::string mOutputBaseDirectory; 63 // The output directory for the specfied package (mPackageName), 64 // e.g. /tmp/myout/com/example/android/rs/flashlight/ 65 // TODO This includes the terminating separator. Needed? 66 std::string mOutputDirectory; 67 68 // The full path of the .rs file that we are reflecting. 69 std::string mRSSourceFileName; 70 // The full path where the generated bit code can be read. 71 std::string mBitCodeFileName; 72 73 // The name of the resource we pass to the RenderScript constructor 74 // e.g. flashlight 75 std::string mResourceId; 76 // The name of the Java class we are generating for this script. 77 // e.g. ScriptC_flashlight 78 std::string mScriptClassName; 79 80 // This is set by startClass() and will change for the multiple classes generated. 81 std::string mClassName; 82 83 // This is the token used for determining the size of a given ScriptField.Item. 84 std::string mItemSizeof; 85 86 bool mEmbedBitcodeInJava; 87 88 int mNextExportVarSlot; 89 int mNextExportFuncSlot; 90 int mNextExportForEachSlot; 91 int mNextExportReduceSlot; 92 93 GeneratedFile mOut; 94 95 std::string mLastError; 96 std::vector<std::string> *mGeneratedFileNames; 97 98 // A mapping from a field in a record type to its index in the rsType 99 // instance. Only used when generates TypeClass (ScriptField_*). 100 // 101 // .first = field index 102 // .second = when compiling for both 32-bit and 64-bit (RSCCOptions::mEmit3264), 103 // and we are reflecting 64-bit code, this is field index for 32-bit; 104 // otherwise, it is undefined 105 typedef std::map<const RSExportRecordType::Field *, std::pair<unsigned,unsigned> > FieldIndexMapTy; 106 FieldIndexMapTy mFieldIndexMap; 107 // Field index of current processing TypeClass. 108 unsigned mFieldIndex; // corresponds to FieldIndexMapTy::mapped_type.first 109 unsigned mField32Index; // corresponds to FieldIndexMapTy::mapped_type.second 110 setError(const std::string & Error)111 inline void setError(const std::string &Error) { mLastError = Error; } 112 clear()113 inline void clear() { 114 mClassName = ""; 115 mNextExportVarSlot = 0; 116 mNextExportFuncSlot = 0; 117 mNextExportForEachSlot = 0; 118 mNextExportReduceSlot = 0; 119 } 120 121 public: 122 typedef enum { 123 AM_Public, 124 AM_Protected, 125 AM_Private, 126 AM_PublicSynchronized 127 } AccessModifier; 128 129 // Generated RS Elements for type-checking code. 130 std::set<std::string> mTypesToCheck; 131 132 // Generated FieldPackers for unsigned setters/validation. 133 std::set<std::string> mFieldPackerTypes; 134 135 bool addTypeNameForElement(const std::string &TypeName); 136 bool addTypeNameForFieldPacker(const std::string &TypeName); 137 138 static const char *AccessModifierStr(AccessModifier AM); 139 getEmbedBitcodeInJava()140 inline bool getEmbedBitcodeInJava() const { return mEmbedBitcodeInJava; } 141 getNextExportVarSlot()142 inline int getNextExportVarSlot() { return mNextExportVarSlot++; } getNextExportFuncSlot()143 inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; } getNextExportForEachSlot()144 inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; } getNextExportReduceSlot()145 inline int getNextExportReduceSlot() { return mNextExportReduceSlot++; } 146 147 bool startClass(AccessModifier AM, bool IsStatic, 148 const std::string &ClassName, const char *SuperClassName, 149 std::string &ErrorMsg); 150 void endClass(); 151 152 void startFunction(AccessModifier AM, bool IsStatic, const char *ReturnType, 153 const std::string &FunctionName, int Argc, ...); 154 155 typedef std::vector<std::pair<std::string, std::string>> ArgTy; 156 void startFunction(AccessModifier AM, bool IsStatic, const char *ReturnType, 157 const std::string &FunctionName, const ArgTy &Args); 158 void endFunction(); 159 getPackageName()160 inline const std::string &getPackageName() const { return mPackageName; } getRSPackageName()161 inline const std::string &getRSPackageName() const { return mRSPackageName; } getClassName()162 inline const std::string &getClassName() const { return mClassName; } getResourceId()163 inline const std::string &getResourceId() const { return mResourceId; } 164 165 void startTypeClass(const std::string &ClassName); 166 void endTypeClass(); 167 168 enum { FieldIndex = 0x1, Field32Index = 0x2 }; // bitmask incFieldIndex(unsigned Which)169 inline void incFieldIndex(unsigned Which) { 170 slangAssert(!(Which & ~(FieldIndex | Field32Index))); 171 if (Which & FieldIndex ) mFieldIndex++; 172 if (Which & Field32Index) mField32Index++; 173 } 174 resetFieldIndex()175 inline void resetFieldIndex() { mFieldIndex = mField32Index = 0; } 176 addFieldIndexMapping(const RSExportRecordType::Field * F)177 inline void addFieldIndexMapping(const RSExportRecordType::Field *F) { 178 slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) && 179 "Nested structure never occurs in C language."); 180 mFieldIndexMap.insert(std::make_pair(F, std::make_pair(mFieldIndex, mField32Index))); 181 } 182 getFieldIndex(const RSExportRecordType::Field * F)183 inline std::pair<unsigned, unsigned> getFieldIndex(const RSExportRecordType::Field *F) const { 184 FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F); 185 slangAssert((I != mFieldIndexMap.end()) && 186 "Requesting field is out of scope."); 187 return I->second; 188 } 189 clearFieldIndexMap()190 inline void clearFieldIndexMap() { mFieldIndexMap.clear(); } 191 192 enum { 193 TypeNameWithConstantArrayBrackets = 0x01, 194 TypeNameWithRecordElementName = 0x02, 195 196 // Three major flavors of types: 197 // - Java 198 // - C 199 // - PseudoC -- Identical to C for all types supported by C; 200 // for other types, uses a simplified C-like syntax 201 TypeNameC = 0x04, 202 TypeNamePseudoC = 0x08, 203 204 TypeNameDefault = TypeNameWithConstantArrayBrackets|TypeNameWithRecordElementName 205 }; 206 static std::string GetTypeName(const RSExportType *ET, unsigned Style = TypeNameDefault); 207 208 private: 209 static bool exportableReduce(const RSExportType *ResultType); 210 211 bool genScriptClass(const std::string &ClassName, std::string &ErrorMsg); 212 void genScriptClassConstructor(); 213 214 void genInitBoolExportVariable(const std::string &VarName, 215 const clang::APValue &Val); 216 void genInitPrimitiveExportVariable(const std::string &VarName, 217 const clang::APValue &Val); 218 void genInitExportVariable(const RSExportType *ET, const std::string &VarName, 219 const clang::APValue &Val); 220 void genInitValue(const clang::APValue &Val, bool asBool); 221 void genExportVariable(const RSExportVar *EV); 222 void genPrimitiveTypeExportVariable(const RSExportVar *EV); 223 void genPointerTypeExportVariable(const RSExportVar *EV); 224 void genVectorTypeExportVariable(const RSExportVar *EV); 225 void genMatrixTypeExportVariable(const RSExportVar *EV); 226 void genConstantArrayTypeExportVariable(const RSExportVar *EV, ReflectionState::Val32 AllocSize32); 227 void genRecordTypeExportVariable(const RSExportVar *EV, ReflectionState::Val32 AllocSize32); 228 void genPrivateExportVariable(const std::string &TypeName, 229 const std::string &VarName); 230 void genSetExportVariable(const std::string &TypeName, const RSExportVar *EV, unsigned Dimension, 231 ReflectionState::Val32 AllocSize32 = ReflectionState::NoVal32()); 232 void genGetExportVariable(const std::string &TypeName, 233 const std::string &VarName); 234 void genGetFieldID(const std::string &VarName); 235 236 void genExportFunction(const RSExportFunc *EF); 237 238 void genExportForEach(const RSExportForEach *EF); 239 240 void genExportReduce(const RSExportReduce *ER); 241 void genExportReduceAllocationVariant(const RSExportReduce *ER); 242 void genExportReduceArrayVariant(const RSExportReduce *ER); 243 void genExportReduceResultType(const RSExportType *ResultType); 244 245 void genTypeCheck(const RSExportType *ET, const char *VarName); 246 247 void genTypeInstanceFromPointer(const RSExportType *ET); 248 249 void genTypeInstance(const RSExportType *ET); 250 251 void genFieldPackerInstance(const RSExportType *ET); 252 253 bool genTypeClass(const RSExportRecordType *ERT, std::string &ErrorMsg); 254 void genTypeItemClass(const RSExportRecordType *ERT); 255 void genTypeClassConstructor(const RSExportRecordType *ERT); 256 void genTypeClassCopyToArray(const RSExportRecordType *ERT); 257 void genTypeClassCopyToArrayLocal(const RSExportRecordType *ERT); 258 void genTypeClassItemSetter(const RSExportRecordType *ERT); 259 void genTypeClassItemGetter(const RSExportRecordType *ERT); 260 void genTypeClassComponentSetter(const RSExportRecordType *ERT); 261 void genTypeClassComponentGetter(const RSExportRecordType *ERT); 262 void genTypeClassCopyAll(const RSExportRecordType *ERT); 263 void genTypeClassResize(); 264 265 // emits an expression that evaluates to true on a 64-bit target and 266 // false on a 32-bit target 267 void genCheck64Bit(bool Parens); 268 269 // emits a fragment of the class definition needed to set up for 270 // genCheck64Bit() 271 void genCompute64Bit(); 272 273 void genBuildElement(const char *ElementBuilderName, 274 const RSExportRecordType *ERT, 275 const char *RenderScriptVar, bool IsInline); 276 void genAddElementToElementBuilder(const RSExportType *ERT, 277 const std::string &VarName, 278 const char *ElementBuilderName, 279 const char *RenderScriptVar, 280 unsigned ArraySize); 281 282 bool genCreateFieldPacker(const RSExportType *T, const char *FieldPackerName, 283 ReflectionState::Val32 AllocSize32); 284 void genPackVarOfType(const RSExportType *T, const char *VarName, 285 const char *FieldPackerName); 286 void genAllocateVarOfType(const RSExportType *T, const std::string &VarName); 287 void genNewItemBufferIfNull(const char *Index); 288 void genNewItemBufferPackerIfNull(); 289 290 void genPairwiseDimCheck(const std::string &name0, const std::string &name1); 291 void genVectorLengthCompatibilityCheck(const std::string &ArrayName, unsigned VecSize); 292 void genNullArrayCheck(const std::string &ArrayName); 293 294 // NOTE 295 // 296 // If there's a nonempty Prefix, then: 297 // - If there's a nonzero value to emit, then emit the prefix followed by the value. 298 // - Otherwise, emit nothing. 299 // 300 // If there's an empty Prefix, then 301 // - Always emit a value, even if zero. 302 // 303 void genConditionalVal(const std::string &Prefix, bool Parens, 304 size_t Val, ReflectionState::Val32 Val32); 305 306 public: 307 RSReflectionJava(const RSContext *Context, 308 std::vector<std::string> *GeneratedFileNames, 309 const std::string &OutputBaseDirectory, 310 const std::string &RSSourceFilename, 311 const std::string &BitCodeFileName, 312 bool EmbedBitcodeInJava, 313 ReflectionState *RState); 314 315 bool reflect(); 316 getLastError()317 inline const char *getLastError() const { 318 if (mLastError.empty()) 319 return nullptr; 320 else 321 return mLastError.c_str(); 322 } 323 }; // class RSReflectionJava 324 325 } // namespace slang 326 327 #endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_ NOLINT 328