Home | History | Annotate | Download | only in slang
      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 
     33 namespace slang {
     34 
     35 class RSContext;
     36 class RSExportVar;
     37 class RSExportFunc;
     38 class RSExportForEach;
     39 
     40 class RSReflectionJava {
     41 private:
     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 
     86   GeneratedFile mOut;
     87 
     88   std::string mLastError;
     89   std::vector<std::string> *mGeneratedFileNames;
     90 
     91   // A mapping from a field in a record type to its index in the rsType
     92   // instance. Only used when generates TypeClass (ScriptField_*).
     93   typedef std::map<const RSExportRecordType::Field *, unsigned> FieldIndexMapTy;
     94   FieldIndexMapTy mFieldIndexMap;
     95   // Field index of current processing TypeClass.
     96   unsigned mFieldIndex;
     97 
     98   inline void setError(const std::string &Error) { mLastError = Error; }
     99 
    100   inline void clear() {
    101     mClassName = "";
    102     mNextExportVarSlot = 0;
    103     mNextExportFuncSlot = 0;
    104     mNextExportForEachSlot = 0;
    105     mNextExportReduceSlot = 0;
    106   }
    107 
    108 public:
    109   typedef enum {
    110     AM_Public,
    111     AM_Protected,
    112     AM_Private,
    113     AM_PublicSynchronized
    114   } AccessModifier;
    115 
    116   // Generated RS Elements for type-checking code.
    117   std::set<std::string> mTypesToCheck;
    118 
    119   // Generated FieldPackers for unsigned setters/validation.
    120   std::set<std::string> mFieldPackerTypes;
    121 
    122   bool addTypeNameForElement(const std::string &TypeName);
    123   bool addTypeNameForFieldPacker(const std::string &TypeName);
    124 
    125   static const char *AccessModifierStr(AccessModifier AM);
    126 
    127   inline bool getEmbedBitcodeInJava() const { return mEmbedBitcodeInJava; }
    128 
    129   inline int getNextExportVarSlot() { return mNextExportVarSlot++; }
    130   inline int getNextExportFuncSlot() { return mNextExportFuncSlot++; }
    131   inline int getNextExportForEachSlot() { return mNextExportForEachSlot++; }
    132   inline int getNextExportReduceSlot() { return mNextExportReduceSlot++; }
    133 
    134   bool startClass(AccessModifier AM, bool IsStatic,
    135                   const std::string &ClassName, const char *SuperClassName,
    136                   std::string &ErrorMsg);
    137   void endClass();
    138 
    139   void startFunction(AccessModifier AM, bool IsStatic, const char *ReturnType,
    140                      const std::string &FunctionName, int Argc, ...);
    141 
    142   typedef std::vector<std::pair<std::string, std::string>> ArgTy;
    143   void startFunction(AccessModifier AM, bool IsStatic, const char *ReturnType,
    144                      const std::string &FunctionName, const ArgTy &Args);
    145   void endFunction();
    146 
    147   inline const std::string &getPackageName() const { return mPackageName; }
    148   inline const std::string &getRSPackageName() const { return mRSPackageName; }
    149   inline const std::string &getClassName() const { return mClassName; }
    150   inline const std::string &getResourceId() const { return mResourceId; }
    151 
    152   void startTypeClass(const std::string &ClassName);
    153   void endTypeClass();
    154 
    155   inline void incFieldIndex() { mFieldIndex++; }
    156 
    157   inline void resetFieldIndex() { mFieldIndex = 0; }
    158 
    159   inline void addFieldIndexMapping(const RSExportRecordType::Field *F) {
    160     slangAssert((mFieldIndexMap.find(F) == mFieldIndexMap.end()) &&
    161                 "Nested structure never occurs in C language.");
    162     mFieldIndexMap.insert(std::make_pair(F, mFieldIndex));
    163   }
    164 
    165   inline unsigned getFieldIndex(const RSExportRecordType::Field *F) const {
    166     FieldIndexMapTy::const_iterator I = mFieldIndexMap.find(F);
    167     slangAssert((I != mFieldIndexMap.end()) &&
    168                 "Requesting field is out of scope.");
    169     return I->second;
    170   }
    171 
    172   inline void clearFieldIndexMap() { mFieldIndexMap.clear(); }
    173 
    174 private:
    175   static bool exportableReduce(const RSExportType *ResultType);
    176 
    177   bool genScriptClass(const std::string &ClassName, std::string &ErrorMsg);
    178   void genScriptClassConstructor();
    179 
    180   void genInitBoolExportVariable(const std::string &VarName,
    181                                  const clang::APValue &Val);
    182   void genInitPrimitiveExportVariable(const std::string &VarName,
    183                                       const clang::APValue &Val);
    184   void genInitExportVariable(const RSExportType *ET, const std::string &VarName,
    185                              const clang::APValue &Val);
    186   void genInitValue(const clang::APValue &Val, bool asBool);
    187   void genExportVariable(const RSExportVar *EV);
    188   void genPrimitiveTypeExportVariable(const RSExportVar *EV);
    189   void genPointerTypeExportVariable(const RSExportVar *EV);
    190   void genVectorTypeExportVariable(const RSExportVar *EV);
    191   void genMatrixTypeExportVariable(const RSExportVar *EV);
    192   void genConstantArrayTypeExportVariable(const RSExportVar *EV);
    193   void genRecordTypeExportVariable(const RSExportVar *EV);
    194   void genPrivateExportVariable(const std::string &TypeName,
    195                                 const std::string &VarName);
    196   void genSetExportVariable(const std::string &TypeName, const RSExportVar *EV, unsigned Dimension);
    197   void genGetExportVariable(const std::string &TypeName,
    198                             const std::string &VarName);
    199   void genGetFieldID(const std::string &VarName);
    200 
    201   void genExportFunction(const RSExportFunc *EF);
    202 
    203   void genExportForEach(const RSExportForEach *EF);
    204 
    205   void genExportReduce(const RSExportReduce *ER);
    206   void genExportReduceAllocationVariant(const RSExportReduce *ER);
    207   void genExportReduceArrayVariant(const RSExportReduce *ER);
    208   void genExportReduceResultType(const RSExportType *ResultType);
    209 
    210   void genTypeCheck(const RSExportType *ET, const char *VarName);
    211 
    212   void genTypeInstanceFromPointer(const RSExportType *ET);
    213 
    214   void genTypeInstance(const RSExportType *ET);
    215 
    216   void genFieldPackerInstance(const RSExportType *ET);
    217 
    218   bool genTypeClass(const RSExportRecordType *ERT, std::string &ErrorMsg);
    219   void genTypeItemClass(const RSExportRecordType *ERT);
    220   void genTypeClassConstructor(const RSExportRecordType *ERT);
    221   void genTypeClassCopyToArray(const RSExportRecordType *ERT);
    222   void genTypeClassCopyToArrayLocal(const RSExportRecordType *ERT);
    223   void genTypeClassItemSetter(const RSExportRecordType *ERT);
    224   void genTypeClassItemGetter(const RSExportRecordType *ERT);
    225   void genTypeClassComponentSetter(const RSExportRecordType *ERT);
    226   void genTypeClassComponentGetter(const RSExportRecordType *ERT);
    227   void genTypeClassCopyAll(const RSExportRecordType *ERT);
    228   void genTypeClassResize();
    229 
    230   void genBuildElement(const char *ElementBuilderName,
    231                        const RSExportRecordType *ERT,
    232                        const char *RenderScriptVar, bool IsInline);
    233   void genAddElementToElementBuilder(const RSExportType *ERT,
    234                                      const std::string &VarName,
    235                                      const char *ElementBuilderName,
    236                                      const char *RenderScriptVar,
    237                                      unsigned ArraySize);
    238 
    239   bool genCreateFieldPacker(const RSExportType *T, const char *FieldPackerName);
    240   void genPackVarOfType(const RSExportType *T, const char *VarName,
    241                         const char *FieldPackerName);
    242   void genAllocateVarOfType(const RSExportType *T, const std::string &VarName);
    243   void genNewItemBufferIfNull(const char *Index);
    244   void genNewItemBufferPackerIfNull();
    245 
    246   void genPairwiseDimCheck(std::string name0, std::string name1);
    247   void genVectorLengthCompatibilityCheck(const std::string &ArrayName, unsigned VecSize);
    248   void genNullArrayCheck(const std::string &ArrayName);
    249 
    250 public:
    251   RSReflectionJava(const RSContext *Context,
    252                    std::vector<std::string> *GeneratedFileNames,
    253                    const std::string &OutputBaseDirectory,
    254                    const std::string &RSSourceFilename,
    255                    const std::string &BitCodeFileName,
    256                    bool EmbedBitcodeInJava);
    257 
    258   bool reflect();
    259 
    260   inline const char *getLastError() const {
    261     if (mLastError.empty())
    262       return nullptr;
    263     else
    264       return mLastError.c_str();
    265   }
    266 }; // class RSReflectionJava
    267 
    268 } // namespace slang
    269 
    270 #endif // _FRAMEWORKS_COMPILE_SLANG_SLANG_RS_REFLECTION_H_  NOLINT
    271