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