slang_rs_reflection_cpp.cpp revision 003ac666e57669d4312b5792068c3db302ee7b84
1d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam/* 2d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * Copyright 2013, The Android Open Source Project 3d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * 4d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * Licensed under the Apache License, Version 2.0 (the "License"); 5d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * you may not use this file except in compliance with the License. 6d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * You may obtain a copy of the License at 7d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * 8d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * http://www.apache.org/licenses/LICENSE-2.0 9d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * 10d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * Unless required by applicable law or agreed to in writing, software 11d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * distributed under the License is distributed on an "AS IS" BASIS, 12d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * See the License for the specific language governing permissions and 14d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam * limitations under the License. 15d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam */ 16d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 17d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include <sys/stat.h> 18d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include <stdio.h> 19d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include <stdlib.h> 20d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 217c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam#include <cstdarg> 22d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include <cctype> 23d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 24d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include <algorithm> 25d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include <sstream> 26d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include <string> 27059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam#include <utility> 28059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam 297c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam#include "os_sep.h" 30d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include "slang_rs_context.h" 31d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include "slang_rs_export_var.h" 32d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include "slang_rs_export_foreach.h" 33d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include "slang_rs_export_func.h" 34d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include "slang_rs_reflect_utils.h" 35d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include "slang_version.h" 36d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include "slang_utils.h" 37d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 38d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#include "slang_rs_reflection_cpp.h" 39d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 40d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamusing namespace std; 41d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 427c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lamnamespace slang { 437c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 44d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#define RS_TYPE_ITEM_CLASS_NAME "Item" 45d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 46d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam#define RS_ELEM_PREFIX "__rs_elem_" 47059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam 48059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lamstatic const char *GetMatrixTypeName(const RSExportMatrixType *EMT) { 49d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam static const char *MatrixTypeCNameMap[] = { 50d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam "rs_matrix2x2", 517c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam "rs_matrix3x3", 52059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam "rs_matrix4x4", 53d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam }; 54d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam unsigned Dim = EMT->getDim(); 55d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 56d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam if ((Dim - 2) < (sizeof(MatrixTypeCNameMap) / sizeof(const char*))) 57d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return MatrixTypeCNameMap[ EMT->getDim() - 2 ]; 587c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 59059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam slangAssert(false && "GetMatrixTypeName : Unsupported matrix dimension"); 60d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return NULL; 61d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam} 62d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 63d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 64d832154e333a3a45b5faecd518b664ddd297183cMaurice Lamstatic std::string GetTypeName(const RSExportType *ET, bool Brackets = true) { 65d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam switch (ET->getClass()) { 667c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam case RSExportType::ExportClassPrimitive: { 67d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return RSExportPrimitiveType::getRSReflectionType( 68d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam static_cast<const RSExportPrimitiveType*>(ET))->c_name; 69d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 70d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam case RSExportType::ExportClassPointer: { 71d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam const RSExportType *PointeeType = 72d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 73d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 74d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam if (PointeeType->getClass() != RSExportType::ExportClassRecord) 75d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return "android::RSC::sp<android::RSC::Allocation>"; 767c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam else 77d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return PointeeType->getElementName(); 78d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 79d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam case RSExportType::ExportClassVector: { 80d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam const RSExportVectorType *EVT = 81d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam static_cast<const RSExportVectorType*>(ET); 82d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam std::stringstream VecName; 83d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam VecName << EVT->getRSReflectionType(EVT)->rs_c_vector_prefix 84d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam << EVT->getNumElement(); 85d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return VecName.str(); 86d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 87d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam case RSExportType::ExportClassMatrix: { 88d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return GetMatrixTypeName(static_cast<const RSExportMatrixType*>(ET)); 897c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 90d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam case RSExportType::ExportClassConstantArray: { 91d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam // TODO: Fix this for C arrays! 92d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam const RSExportConstantArrayType* CAT = 93d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam static_cast<const RSExportConstantArrayType*>(ET); 94d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam std::string ElementTypeName = GetTypeName(CAT->getElementType()); 95d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam if (Brackets) { 96d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam ElementTypeName.append("[]"); 97d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 98d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return ElementTypeName; 99d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 100d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam case RSExportType::ExportClassRecord: { 1017c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam // TODO: Fix for C structs! 102d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return ET->getElementName() + "." RS_TYPE_ITEM_CLASS_NAME; 103d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 104d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam default: { 105d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam slangAssert(false && "Unknown class of type"); 106d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 107d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 108d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 109d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return ""; 110d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam} 111059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam 112059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam 113d832154e333a3a45b5faecd518b664ddd297183cMaurice LamRSReflectionCpp::RSReflectionCpp(const RSContext *con) 114d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam : RSReflectionBase(con) { 115d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam clear(); 116d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam} 117cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam 118cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice LamRSReflectionCpp::~RSReflectionCpp() { 1197c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam} 120cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam 121cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lambool RSReflectionCpp::reflect(const string &OutputPathBase, 122cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam const string &InputFileName, 123cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam const string &OutputBCFileName) { 124cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam mInputFileName = InputFileName; 125cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam mOutputPath = OutputPathBase; 126cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam mOutputBCFileName = OutputBCFileName; 127cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam mClassName = string("ScriptC_") + stripRS(InputFileName); 128cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam 129cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam makeHeader("android::RSC::ScriptC"); 130cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam std::vector< std::string > header(mText); 131cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam mText.clear(); 132cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam 133cf90658b5c16018c9f3db7fd1d872025cff5d1dcMaurice Lam makeImpl("android::RSC::ScriptC"); 13404eecdd42f0bc9751825f9f21131a59852256278Maurice Lam std::vector< std::string > cpp(mText); 13504eecdd42f0bc9751825f9f21131a59852256278Maurice Lam mText.clear(); 13604eecdd42f0bc9751825f9f21131a59852256278Maurice Lam 1377c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1387c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam writeFile(mClassName + ".h", header); 13904eecdd42f0bc9751825f9f21131a59852256278Maurice Lam writeFile(mClassName + ".cpp", cpp); 14004eecdd42f0bc9751825f9f21131a59852256278Maurice Lam 14104eecdd42f0bc9751825f9f21131a59852256278Maurice Lam 14204eecdd42f0bc9751825f9f21131a59852256278Maurice Lam return true; 14304eecdd42f0bc9751825f9f21131a59852256278Maurice Lam} 14404eecdd42f0bc9751825f9f21131a59852256278Maurice Lam 14504eecdd42f0bc9751825f9f21131a59852256278Maurice Lam 14604eecdd42f0bc9751825f9f21131a59852256278Maurice Lam#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_" 1477c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1487c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1497c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1507c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lambool RSReflectionCpp::makeHeader(const std::string &baseClass) { 1517c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam startFile(mClassName + ".h"); 1527c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1537c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write(""); 1547c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write("#include \"RenderScript.h\""); 1557c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write("using namespace android::RSC;"); 1567c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write(""); 1577c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1587c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam // Imports 1597c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++) 1607c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam //out() << "import " << Import[i] << ";" << std::endl; 1617c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam //out() << std::endl; 1627c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1637c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam if (!baseClass.empty()) { 1647c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write("class " + mClassName + " : public " + baseClass + " {"); 1657c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } else { 1667c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write("class " + mClassName + " {"); 1677c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 1687c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 1697c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write("private:"); 1707c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam uint32_t slot = 0; 1717c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam incIndent(); 1727c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(), 1737c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam E = mRSContext->export_vars_end(); I != E; I++, slot++) { 1747c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam const RSExportVar *ev = *I; 1757c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam if (!ev->isConst()) { 1767c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write(GetTypeName(ev->getType()) + " __" + ev->getName() + ";"); 1777c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 1787c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 1797c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam for (RSContext::const_export_foreach_iterator 1807c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam I = mRSContext->export_foreach_begin(), 1817c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam E = mRSContext->export_foreach_end(); I != E; I++) { 1827c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam const RSExportForEach *EF = *I; 1837c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam const RSExportType *IET = EF->getInType(); 1847c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam const RSExportType *OET = EF->getOutType(); 1857c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam if (IET) { 1867c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam genTypeInstanceFromPointer(IET); 1877c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 1887c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam if (OET) { 1897c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam genTypeInstanceFromPointer(OET); 1907c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 1917c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 1927c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 19304eecdd42f0bc9751825f9f21131a59852256278Maurice Lam for (std::set<std::string>::iterator I = mTypesToCheck.begin(), 19404eecdd42f0bc9751825f9f21131a59852256278Maurice Lam E = mTypesToCheck.end(); 19504eecdd42f0bc9751825f9f21131a59852256278Maurice Lam I != E; 19604eecdd42f0bc9751825f9f21131a59852256278Maurice Lam I++) { 1977c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write("android::RSC::sp<const android::RSC::Element> " RS_ELEM_PREFIX 1987c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam + *I + ";"); 1997c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 2007c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2017c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam decIndent(); 2027c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2037c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write("public:"); 2047c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam incIndent(); 2057c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write(mClassName + "(android::RSC::sp<android::RSC::RS> rs);"); 2067c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write("virtual ~" + mClassName + "();"); 2077c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write(""); 2087c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2097c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2107c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam // Reflect export variable 2117c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam slot = 0; 2127c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(), 2137c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam E = mRSContext->export_vars_end(); I != E; I++, slot++) { 2147c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam genExportVariable(*I); 2157c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 2167c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2177c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam // Reflect export for each functions 2187c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam for (RSContext::const_export_foreach_iterator 2197c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam I = mRSContext->export_foreach_begin(), 2207c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam E = mRSContext->export_foreach_end(); I != E; I++) { 2217c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam const RSExportForEach *ef = *I; 2227c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam if (ef->isDummyRoot()) { 2237c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam write("// No forEach_root(...)"); 2247c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam continue; 2257c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 2267c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2277c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam ArgTy Args; 2287c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam stringstream ss; 2297c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam ss << "void forEach_" << ef->getName() << "("; 2307c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2317c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam if (ef->hasIn()) { 2327c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam Args.push_back(std::make_pair( 2337c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam "android::RSC::sp<const android::RSC::Allocation>", "ain")); 2347c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 2357c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2367c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam if (ef->hasOut() || ef->hasReturn()) { 2377c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam Args.push_back(std::make_pair( 2387c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam "android::RSC::sp<const android::RSC::Allocation>", "aout")); 2397c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam } 2407c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam 2417c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam const RSExportRecordType *ERT = ef->getParamPacketType(); 2427c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam if (ERT) { 2437c7aa7d0d3cd465b1f4c0aa812fc4006cd7a14adMaurice Lam for (RSExportForEach::const_param_iterator i = ef->params_begin(), 244059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam e = ef->params_end(); i != e; i++) { 245059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam RSReflectionTypeData rtd; 246059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam (*i)->getType()->convertToRTD(&rtd); 247059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam Args.push_back(std::make_pair(rtd.type->c_name, (*i)->getName())); 248059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam } 249059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam } 250059321ff28f79a2cbe630b4d814a96ff9254643aMaurice Lam makeArgs(ss, Args); 251d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam ss << ");"; 252d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam write(ss); 253d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 254d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 255d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 256d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam // Reflect export function 257d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam for (RSContext::const_export_func_iterator 258d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam I = mRSContext->export_funcs_begin(), 259d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam E = mRSContext->export_funcs_end(); I != E; I++) { 260d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam const RSExportFunc *ef = *I; 261d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 262d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam stringstream ss; 263d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam makeFunctionSignature(ss, false, ef); 264d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam write(ss); 265d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 266d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 267d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam decIndent(); 268d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam write("};"); 269d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return true; 270d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam} 271d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 272d832154e333a3a45b5faecd518b664ddd297183cMaurice Lambool RSReflectionCpp::writeBC() { 273d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam FILE *pfin = fopen(mOutputBCFileName.c_str(), "rb"); 274d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam if (pfin == NULL) { 275d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam fprintf(stderr, "Error: could not read file %s\n", 276d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam mOutputBCFileName.c_str()); 277d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam return false; 278d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam } 279d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam 280d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam unsigned char buf[16]; 281d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam int read_length; 282d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam write("static const unsigned char __txt[] = {"); 283d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam incIndent(); 284d832154e333a3a45b5faecd518b664ddd297183cMaurice Lam while ((read_length = fread(buf, 1, sizeof(buf), pfin)) > 0) { 285 string s; 286 for (int i = 0; i < read_length; i++) { 287 char buf2[16]; 288 snprintf(buf2, sizeof(buf2), "0x%02x,", buf[i]); 289 s += buf2; 290 } 291 write(s); 292 } 293 decIndent(); 294 write("};"); 295 write(""); 296 return true; 297} 298 299bool RSReflectionCpp::makeImpl(const std::string &baseClass) { 300 startFile(mClassName + ".cpp"); 301 302 write(""); 303 write("#include \"" + mClassName + ".h\""); 304 write(""); 305 306 writeBC(); 307 308 // Imports 309 //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++) 310 //out() << "import " << Import[i] << ";" << std::endl; 311 //out() << std::endl; 312 313 write("\n"); 314 stringstream ss; 315 const std::string &packageName = mRSContext->getReflectJavaPackageName(); 316 ss << mClassName << "::" << mClassName 317 << "(android::RSC::sp<android::RSC::RS> rs):\n" 318 " ScriptC(rs, __txt, sizeof(__txt), \"" 319 << stripRS(mInputFileName) << "\", " << stripRS(mInputFileName).length() 320 << ", \"/data/data/" << packageName << "/app\", sizeof(\"" << packageName << "\")) {"; 321 write(ss); 322 incIndent(); 323 for (std::set<std::string>::iterator I = mTypesToCheck.begin(), 324 E = mTypesToCheck.end(); 325 I != E; 326 I++) { 327 write(RS_ELEM_PREFIX + *I + " = android::RSC::Element::" + *I + "(mRS);"); 328 } 329 decIndent(); 330 write("}"); 331 write(""); 332 333 write(mClassName + "::~" + mClassName + "() {"); 334 write("}"); 335 write(""); 336 337 // Reflect export for each functions 338 uint32_t slot = 0; 339 for (RSContext::const_export_foreach_iterator 340 I = mRSContext->export_foreach_begin(), 341 E = mRSContext->export_foreach_end(); I != E; I++, slot++) { 342 const RSExportForEach *ef = *I; 343 if (ef->isDummyRoot()) { 344 write("// No forEach_root(...)"); 345 continue; 346 } 347 348 stringstream tmp; 349 ArgTy Args; 350 tmp << "void " << mClassName << "::forEach_" << ef->getName() << "("; 351 352 if (ef->hasIn()) { 353 Args.push_back(std::make_pair( 354 "android::RSC::sp<const android::RSC::Allocation>", "ain")); 355 } 356 357 if (ef->hasOut() || ef->hasReturn()) { 358 Args.push_back(std::make_pair( 359 "android::RSC::sp<const android::RSC::Allocation>", "aout")); 360 } 361 362 const RSExportRecordType *ERT = ef->getParamPacketType(); 363 if (ERT) { 364 for (RSExportForEach::const_param_iterator i = ef->params_begin(), 365 e = ef->params_end(); i != e; i++) { 366 RSReflectionTypeData rtd; 367 (*i)->getType()->convertToRTD(&rtd); 368 Args.push_back(std::make_pair(rtd.type->c_name, (*i)->getName())); 369 } 370 } 371 makeArgs(tmp, Args); 372 373 tmp << ") {"; 374 write(tmp); 375 tmp.str(""); 376 377 const RSExportType *IET = ef->getInType(); 378 const RSExportType *OET = ef->getOutType(); 379 380 incIndent(); 381 if (IET) { 382 genTypeCheck(IET, "ain"); 383 } 384 385 if (OET) { 386 genTypeCheck(OET, "aout"); 387 } 388 decIndent(); 389 390 std::string FieldPackerName = ef->getName() + "_fp"; 391 if (ERT) { 392 if (genCreateFieldPacker(ERT, FieldPackerName.c_str())) { 393 genPackVarOfType(ERT, NULL, FieldPackerName.c_str()); 394 } 395 } 396 tmp << " forEach(" << slot << ", "; 397 398 if (ef->hasIn()) { 399 tmp << "ain, "; 400 } else { 401 tmp << "NULL, "; 402 } 403 404 if (ef->hasOut() || ef->hasReturn()) { 405 tmp << "aout, "; 406 } else { 407 tmp << "NULL, "; 408 } 409 410 // FIXME (no support for usrData with C++ kernels) 411 tmp << "NULL, 0);"; 412 write(tmp); 413 414 write("}"); 415 write(""); 416 } 417 418 slot = 0; 419 // Reflect export function 420 for (RSContext::const_export_func_iterator 421 I = mRSContext->export_funcs_begin(), 422 E = mRSContext->export_funcs_end(); I != E; I++) { 423 const RSExportFunc *ef = *I; 424 425 stringstream ss; 426 makeFunctionSignature(ss, true, ef); 427 write(ss); 428 ss.str(""); 429 const RSExportRecordType *params = ef->getParamPacketType(); 430 size_t param_len = 0; 431 if (params) { 432 param_len = RSExportType::GetTypeAllocSize(params); 433 if (genCreateFieldPacker(params, "__fp")) { 434 genPackVarOfType(params, NULL, "__fp"); 435 } 436 } 437 438 ss.str(""); 439 ss << " invoke(" << slot; 440 if (params) { 441 ss << ", __fp.getData(), " << param_len << ");"; 442 } else { 443 ss << ", NULL, 0);"; 444 } 445 write(ss); 446 447 write("}"); 448 write(""); 449 450 slot++; 451 } 452 453 decIndent(); 454 return true; 455} 456 457void RSReflectionCpp::genExportVariable(const RSExportVar *EV) { 458 const RSExportType *ET = EV->getType(); 459 460 switch (ET->getClass()) { 461 case RSExportType::ExportClassPrimitive: { 462 genPrimitiveTypeExportVariable(EV); 463 break; 464 } 465 case RSExportType::ExportClassPointer: { 466 genPointerTypeExportVariable(EV); 467 break; 468 } 469 case RSExportType::ExportClassVector: { 470 genVectorTypeExportVariable(EV); 471 break; 472 } 473 case RSExportType::ExportClassMatrix: { 474 genMatrixTypeExportVariable(EV); 475 break; 476 } 477 case RSExportType::ExportClassConstantArray: { 478 genConstantArrayTypeExportVariable(EV); 479 break; 480 } 481 case RSExportType::ExportClassRecord: { 482 genRecordTypeExportVariable(EV); 483 break; 484 } 485 default: { 486 slangAssert(false && "Unknown class of type"); 487 } 488 } 489} 490 491 492void RSReflectionCpp::genPrimitiveTypeExportVariable(const RSExportVar *EV) { 493 RSReflectionTypeData rtd; 494 EV->getType()->convertToRTD(&rtd); 495 496 if (!EV->isConst()) { 497 write(string("void set_") + EV->getName() + "(" + rtd.type->c_name + 498 " v) {"); 499 stringstream tmp; 500 tmp << getNextExportVarSlot(); 501 write(string(" setVar(") + tmp.str() + ", &v, sizeof(v));"); 502 write(string(" __") + EV->getName() + " = v;"); 503 write("}"); 504 } 505 write(string(rtd.type->c_name) + " get_" + EV->getName() + "() const {"); 506 if (EV->isConst()) { 507 const clang::APValue &val = EV->getInit(); 508 bool isBool = !strcmp(rtd.type->c_name, "bool"); 509 write(string(" return ") + genInitValue(val, isBool) + ";"); 510 } else { 511 write(string(" return __") + EV->getName() + ";"); 512 } 513 write("}"); 514 write(""); 515} 516 517void RSReflectionCpp::genPointerTypeExportVariable(const RSExportVar *EV) { 518 const RSExportType *ET = EV->getType(); 519 520 slangAssert((ET->getClass() == RSExportType::ExportClassPointer) && 521 "Variable should be type of pointer here"); 522 523 std::string TypeName = GetTypeName(ET); 524 std::string VarName = EV->getName(); 525 526 RSReflectionTypeData rtd; 527 EV->getType()->convertToRTD(&rtd); 528 uint32_t slot = getNextExportVarSlot(); 529 530 if (!EV->isConst()) { 531 write(string("void bind_") + VarName + "(" + TypeName + 532 " v) {"); 533 stringstream tmp; 534 tmp << slot; 535 write(string(" bindAllocation(v, ") + tmp.str() + ");"); 536 write(string(" __") + VarName + " = v;"); 537 write("}"); 538 } 539 write(TypeName + " get_" + VarName + "() const {"); 540 if (EV->isConst()) { 541 const clang::APValue &val = EV->getInit(); 542 bool isBool = !strcmp(TypeName.c_str(), "bool"); 543 write(string(" return ") + genInitValue(val, isBool) + ";"); 544 } else { 545 write(string(" return __") + VarName + ";"); 546 } 547 write("}"); 548 write(""); 549 550} 551 552void RSReflectionCpp::genVectorTypeExportVariable(const RSExportVar *EV) { 553 slangAssert(false); 554} 555 556void RSReflectionCpp::genMatrixTypeExportVariable(const RSExportVar *EV) { 557 slangAssert(false); 558} 559 560void RSReflectionCpp::genConstantArrayTypeExportVariable( 561 const RSExportVar *EV) { 562 slangAssert(false); 563} 564 565void RSReflectionCpp::genRecordTypeExportVariable(const RSExportVar *EV) { 566 slangAssert(false); 567} 568 569 570void RSReflectionCpp::makeFunctionSignature( 571 std::stringstream &ss, 572 bool isDefinition, 573 const RSExportFunc *ef) { 574 ss << "void "; 575 if (isDefinition) { 576 ss << mClassName << "::"; 577 } 578 ss << "invoke_" << ef->getName() << "("; 579 580 if (ef->getParamPacketType()) { 581 bool FirstArg = true; 582 for (RSExportFunc::const_param_iterator i = ef->params_begin(), 583 e = ef->params_end(); i != e; i++) { 584 RSReflectionTypeData rtd; 585 (*i)->getType()->convertToRTD(&rtd); 586 if (!FirstArg) { 587 ss << ", "; 588 } else { 589 FirstArg = false; 590 } 591 ss << rtd.type->c_name << " " << (*i)->getName(); 592 } 593 } 594 595 if (isDefinition) { 596 ss << ") {"; 597 } else { 598 ss << ");"; 599 } 600} 601 602void RSReflectionCpp::makeArgs(std::stringstream &ss, const ArgTy& Args) { 603 bool FirstArg = true; 604 605 for (ArgTy::const_iterator I = Args.begin(), E = Args.end(); I != E; I++) { 606 if (!FirstArg) { 607 ss << ", "; 608 } else { 609 FirstArg = false; 610 } 611 612 ss << I->first << " " << I->second; 613 } 614} 615 616bool RSReflectionCpp::genCreateFieldPacker(const RSExportType *ET, 617 const char *FieldPackerName) { 618 size_t AllocSize = RSExportType::GetTypeAllocSize(ET); 619 620 if (AllocSize > 0) { 621 std::stringstream ss; 622 ss << " FieldPacker " << FieldPackerName << "(" 623 << AllocSize << ");"; 624 write(ss); 625 return true; 626 } 627 628 return false; 629} 630 631void RSReflectionCpp::genPackVarOfType(const RSExportType *ET, 632 const char *VarName, 633 const char *FieldPackerName) { 634 std::stringstream ss; 635 switch (ET->getClass()) { 636 case RSExportType::ExportClassPrimitive: 637 case RSExportType::ExportClassVector: 638 case RSExportType::ExportClassPointer: 639 case RSExportType::ExportClassMatrix: { 640 ss << " " << FieldPackerName << ".add(" << VarName << ");"; 641 write(ss); 642 break; 643 } 644 case RSExportType::ExportClassConstantArray: { 645 /*const RSExportConstantArrayType *ECAT = 646 static_cast<const RSExportConstantArrayType *>(ET); 647 648 // TODO(zonr): more elegant way. Currently, we obtain the unique index 649 // variable (this method involves recursive call which means 650 // we may have more than one level loop, therefore we can't 651 // always use the same index variable name here) name given 652 // in the for-loop from counting the '.' in @VarName. 653 unsigned Level = 0; 654 size_t LastDotPos = 0; 655 std::string ElementVarName(VarName); 656 657 while (LastDotPos != std::string::npos) { 658 LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1); 659 Level++; 660 } 661 std::string IndexVarName("ct"); 662 IndexVarName.append(llvm::utostr_32(Level)); 663 664 C.indent() << "for (int " << IndexVarName << " = 0; " << 665 IndexVarName << " < " << ECAT->getSize() << "; " << 666 IndexVarName << "++)"; 667 C.startBlock(); 668 669 ElementVarName.append("[" + IndexVarName + "]"); 670 genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(), 671 FieldPackerName); 672 673 C.endBlock();*/ 674 break; 675 } 676 case RSExportType::ExportClassRecord: { 677 const RSExportRecordType *ERT = 678 static_cast<const RSExportRecordType*>(ET); 679 // Relative pos from now on in field packer 680 unsigned Pos = 0; 681 682 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(), 683 E = ERT->fields_end(); 684 I != E; 685 I++) { 686 const RSExportRecordType::Field *F = *I; 687 std::string FieldName; 688 size_t FieldOffset = F->getOffsetInParent(); 689 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 690 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 691 692 if (VarName != NULL) 693 FieldName = VarName + ("." + F->getName()); 694 else 695 FieldName = F->getName(); 696 697 if (FieldOffset > Pos) { 698 ss.str(""); 699 ss << " " << FieldPackerName << ".skip(" 700 << (FieldOffset - Pos) << ");"; 701 write(ss); 702 } 703 704 genPackVarOfType(F->getType(), FieldName.c_str(), FieldPackerName); 705 706 // There is padding in the field type 707 if (FieldAllocSize > FieldStoreSize) { 708 ss.str(""); 709 ss << " " << FieldPackerName << ".skip(" 710 << (FieldAllocSize - FieldStoreSize) << ");"; 711 write(ss); 712 } 713 714 Pos = FieldOffset + FieldAllocSize; 715 } 716 717 // There maybe some padding after the struct 718 if (RSExportType::GetTypeAllocSize(ERT) > Pos) { 719 ss.str(""); 720 ss << " " << FieldPackerName << ".skip(" 721 << RSExportType::GetTypeAllocSize(ERT) - Pos << ");"; 722 write(ss); 723 } 724 break; 725 } 726 default: { 727 slangAssert(false && "Unknown class of type"); 728 } 729 } 730} 731 732 733void RSReflectionCpp::genTypeCheck(const RSExportType *ET, 734 const char *VarName) { 735 stringstream tmp; 736 tmp << "// Type check for " << VarName; 737 write(tmp); 738 tmp.str(""); 739 740 if (ET->getClass() == RSExportType::ExportClassPointer) { 741 const RSExportPointerType *EPT = 742 static_cast<const RSExportPointerType*>(ET); 743 ET = EPT->getPointeeType(); 744 } 745 746 std::string TypeName; 747 switch (ET->getClass()) { 748 case RSExportType::ExportClassPrimitive: 749 case RSExportType::ExportClassVector: 750 case RSExportType::ExportClassRecord: { 751 TypeName = ET->getElementName(); 752 break; 753 } 754 755 default: 756 break; 757 } 758 759 if (!TypeName.empty()) { 760 //tmp << "// TypeName: " << TypeName; 761 tmp << "if (!" << VarName 762 << "->getType()->getElement()->isCompatible(" 763 << RS_ELEM_PREFIX 764 << TypeName << ")) {"; 765 write(tmp); 766 767 incIndent(); 768 write("mRS->throwError(RS_ERROR_RUNTIME_ERROR, " 769 "\"Incompatible type\");"); 770 write("return;"); 771 decIndent(); 772 773 write("}"); 774 } 775} 776 777void RSReflectionCpp::genTypeInstanceFromPointer(const RSExportType *ET) { 778 if (ET->getClass() == RSExportType::ExportClassPointer) { 779 // For pointer parameters to original forEach kernels. 780 const RSExportPointerType *EPT = 781 static_cast<const RSExportPointerType*>(ET); 782 genTypeInstance(EPT->getPointeeType()); 783 } else { 784 // For handling pass-by-value kernel parameters. 785 genTypeInstance(ET); 786 } 787} 788 789void RSReflectionCpp::genTypeInstance(const RSExportType *ET) { 790 switch (ET->getClass()) { 791 case RSExportType::ExportClassPrimitive: 792 case RSExportType::ExportClassVector: 793 case RSExportType::ExportClassConstantArray: 794 case RSExportType::ExportClassRecord: { 795 std::string TypeName = ET->getElementName(); 796 addTypeNameForElement(TypeName); 797 break; 798 } 799 800 default: 801 break; 802 } 803} 804 805 806 807} // namespace slang 808