1 /* 2 * Copyright 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 #include <sys/stat.h> 18 #include <stdio.h> 19 #include <stdlib.h> 20 21 #include <cstdarg> 22 #include <cctype> 23 24 #include <algorithm> 25 #include <sstream> 26 #include <string> 27 #include <utility> 28 29 #include "os_sep.h" 30 #include "slang_rs_context.h" 31 #include "slang_rs_export_var.h" 32 #include "slang_rs_export_foreach.h" 33 #include "slang_rs_export_func.h" 34 #include "slang_rs_reflect_utils.h" 35 #include "slang_version.h" 36 #include "slang_utils.h" 37 38 #include "slang_rs_reflection_cpp.h" 39 40 using namespace std; 41 42 namespace slang { 43 44 RSReflectionCpp::RSReflectionCpp(const RSContext *con) : 45 RSReflectionBase(con) { 46 47 } 48 49 RSReflectionCpp::~RSReflectionCpp() { 50 51 } 52 53 bool RSReflectionCpp::reflect(const string &OutputPathBase, 54 const string &InputFileName, 55 const string &OutputBCFileName) { 56 mInputFileName = InputFileName; 57 mOutputPath = OutputPathBase; 58 mOutputBCFileName = OutputBCFileName; 59 mClassName = string("ScriptC_") + stripRS(InputFileName); 60 61 makeHeader("android::renderscriptCpp::ScriptC"); 62 std::vector< std::string > header(mText); 63 mText.clear(); 64 65 makeImpl("android::renderscriptCpp::ScriptC"); 66 std::vector< std::string > cpp(mText); 67 mText.clear(); 68 69 70 RSReflectionBase::writeFile(mClassName + ".h", header); 71 RSReflectionBase::writeFile(mClassName + ".cpp", cpp); 72 73 74 return false; 75 } 76 77 typedef std::vector<std::pair<std::string, std::string> > ArgTy; 78 79 80 #define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_" 81 82 83 84 bool RSReflectionCpp::makeHeader(const std::string &baseClass) { 85 startFile(mClassName + ".h"); 86 87 write(""); 88 write("#include \"ScriptC.h\""); 89 write(""); 90 91 // Imports 92 //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++) 93 //out() << "import " << Import[i] << ";" << std::endl; 94 //out() << std::endl; 95 96 if(!baseClass.empty()) { 97 write("class " + mClassName + " : public " + baseClass + " {"); 98 } else { 99 write("class " + mClassName + " {"); 100 } 101 102 write("private:"); 103 uint32_t slot = 0; 104 incIndent(); 105 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(), 106 E = mRSContext->export_vars_end(); I != E; I++, slot++) { 107 108 const RSExportVar *ev = *I; 109 RSReflectionTypeData rtd; 110 ev->getType()->convertToRTD(&rtd); 111 if(!ev->isConst()) { 112 write(string(rtd.type->c_name) + " __" + ev->getName() + ";"); 113 } 114 } 115 decIndent(); 116 117 write("public:"); 118 incIndent(); 119 write(mClassName + "(android::renderscriptCpp::RenderScript *rs," + 120 " const char *cacheDir, size_t cacheDirLength);"); 121 write("virtual ~" + mClassName + "();"); 122 write(""); 123 124 125 // Reflect export variable 126 slot = 0; 127 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(), 128 E = mRSContext->export_vars_end(); I != E; I++, slot++) { 129 130 const RSExportVar *ev = *I; 131 RSReflectionTypeData rtd; 132 ev->getType()->convertToRTD(&rtd); 133 134 if(!ev->isConst()) { 135 write(string("void set_") + ev->getName() + "(" + rtd.type->c_name + " v) {"); 136 stringstream tmp; 137 tmp << slot; 138 write(string(" setVar(") + tmp.str() + ", v);"); 139 write(string(" __") + ev->getName() + " = v;"); 140 write("}"); 141 } 142 write(string(rtd.type->c_name) + " get_" + ev->getName() + "() const {"); 143 if(ev->isConst()) { 144 const clang::APValue &val = ev->getInit(); 145 bool isBool = !strcmp(rtd.type->c_name, "bool"); 146 write(string(" return ") + genInitValue(val, isBool) + ";"); 147 } else { 148 write(string(" return __") + ev->getName() + ";"); 149 } 150 write("}"); 151 write(""); 152 } 153 154 // Reflect export for each functions 155 for (RSContext::const_export_foreach_iterator I = mRSContext->export_foreach_begin(), 156 E = mRSContext->export_foreach_end(); I != E; I++) { 157 158 const RSExportForEach *ef = *I; 159 if (ef->isDummyRoot()) { 160 write("// No forEach_root(...)"); 161 continue; 162 } 163 164 stringstream tmp; 165 tmp << "void forEach_" << ef->getName() << "("; 166 if(ef->hasIn() && ef->hasOut()) { 167 tmp << "android::sp<const android::renderscriptCpp::Allocation> ain"; 168 tmp << ", android::sp<const android::renderscriptCpp::Allocation> aout"; 169 } else if(ef->hasIn()) { 170 tmp << "android::sp<const android::renderscriptCpp::Allocation> ain"; 171 } else { 172 tmp << "android::sp<const android::renderscriptCpp::Allocation> aout"; 173 } 174 175 if(ef->getParamPacketType()) { 176 for(RSExportForEach::const_param_iterator i = ef->params_begin(), 177 e = ef->params_end(); i != e; i++) { 178 179 RSReflectionTypeData rtd; 180 (*i)->getType()->convertToRTD(&rtd); 181 tmp << rtd.type->c_name << " " << (*i)->getName(); 182 } 183 } 184 tmp << ") const;"; 185 write(tmp); 186 } 187 188 189 // Reflect export function 190 for (RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(), 191 E = mRSContext->export_funcs_end(); I != E; I++) { 192 193 //genExportFunction(C, *I); 194 } 195 196 decIndent(); 197 write("};"); 198 return true; 199 } 200 201 bool RSReflectionCpp::writeBC() { 202 FILE *pfin = fopen(mOutputBCFileName.c_str(), "rb"); 203 if (pfin == NULL) { 204 fprintf(stderr, "Error: could not read file %s\n", mOutputBCFileName.c_str()); 205 return false; 206 } 207 208 unsigned char buf[16]; 209 int read_length; 210 write("static const unsigned char __txt[] = {"); 211 incIndent(); 212 while ((read_length = fread(buf, 1, sizeof(buf), pfin)) > 0) { 213 string s; 214 for(int i = 0; i < read_length; i++) { 215 char buf2[16]; 216 sprintf(buf2, "0x%02x,", buf[i]); 217 s += buf2; 218 } 219 write(s); 220 } 221 decIndent(); 222 write("};"); 223 write(""); 224 return true; 225 } 226 227 bool RSReflectionCpp::makeImpl(const std::string &baseClass) { 228 startFile(mClassName + ".h"); 229 230 write(""); 231 write("#include \"" + mClassName + ".h\""); 232 write(""); 233 234 writeBC(); 235 236 // Imports 237 //for(unsigned i = 0; i < (sizeof(Import) / sizeof(const char*)); i++) 238 //out() << "import " << Import[i] << ";" << std::endl; 239 //out() << std::endl; 240 241 write(mClassName + "::" + mClassName + 242 "(android::renderscriptCpp::RenderScript *rs, const char *cacheDir, size_t cacheDirLength) :"); 243 write(" ScriptC(rs, __txt, sizeof(__txt), \"" + mInputFileName + 244 "\", 4, cacheDir, cacheDirLength) {"); 245 incIndent(); 246 //... 247 decIndent(); 248 write("}"); 249 write(""); 250 251 write(mClassName + "::~" + mClassName + "() {"); 252 write("}"); 253 write(""); 254 255 // Reflect export for each functions 256 uint32_t slot = 0; 257 for (RSContext::const_export_foreach_iterator I = mRSContext->export_foreach_begin(), 258 E = mRSContext->export_foreach_end(); I != E; I++, slot++) { 259 260 const RSExportForEach *ef = *I; 261 if (ef->isDummyRoot()) { 262 write("// No forEach_root(...)"); 263 continue; 264 } 265 266 stringstream tmp; 267 tmp << "void " << mClassName << "::forEach_" << ef->getName() << "("; 268 if(ef->hasIn() && ef->hasOut()) { 269 tmp << "android::sp<const android::renderscriptCpp::Allocation> ain"; 270 tmp << ", android::sp<const android::renderscriptCpp::Allocation> aout"; 271 } else if(ef->hasIn()) { 272 tmp << "android::sp<const android::renderscriptCpp::Allocation> ain"; 273 } else { 274 tmp << "android::sp<const android::renderscriptCpp::Allocation> aout"; 275 } 276 tmp << ") const {"; 277 write(tmp); 278 tmp.str(""); 279 280 tmp << " forEach(" << slot << ", "; 281 if(ef->hasIn() && ef->hasOut()) { 282 tmp << "ain, aout, NULL, 0);"; 283 } else if(ef->hasIn()) { 284 tmp << "ain, NULL, 0);"; 285 } else { 286 tmp << "aout, NULL, 0);"; 287 } 288 write(tmp); 289 290 write("}"); 291 write(""); 292 } 293 294 295 // Reflect export function 296 slot = 0; 297 for (RSContext::const_export_func_iterator I = mRSContext->export_funcs_begin(), 298 E = mRSContext->export_funcs_end(); I != E; I++) { 299 300 //genExportFunction(C, *I); 301 } 302 303 decIndent(); 304 return true; 305 } 306 307 308 309 } 310