slang_rs_reflection.cpp revision 89273bd59a182fc0401d68f14ad206bf4dc800c7
1/* 2 * Copyright 2010, 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 "slang_rs_reflection.h" 18 19#include <utility> 20#include <cstdarg> 21#include <cctype> 22#include <sys/stat.h> 23 24#include "llvm/ADT/APFloat.h" 25#include "llvm/ADT/StringExtras.h" 26 27#include "slang_utils.h" 28#include "slang_rs_context.h" 29#include "slang_rs_export_var.h" 30#include "slang_rs_export_func.h" 31#include "slang_rs_reflect_utils.h" 32 33#define RS_SCRIPT_CLASS_NAME_PREFIX "ScriptC_" 34#define RS_SCRIPT_CLASS_SUPER_CLASS_NAME "ScriptC" 35 36#define RS_TYPE_CLASS_NAME_PREFIX "ScriptField_" 37#define RS_TYPE_CLASS_SUPER_CLASS_NAME "android.renderscript.Script.FieldBase" 38 39#define RS_TYPE_ITEM_CLASS_NAME "Item" 40 41#define RS_TYPE_ITEM_BUFFER_NAME "mItemArray" 42#define RS_TYPE_ITEM_BUFFER_PACKER_NAME "mIOBuffer" 43 44#define RS_EXPORT_VAR_INDEX_PREFIX "mExportVarIdx_" 45#define RS_EXPORT_VAR_PREFIX "mExportVar_" 46 47#define RS_EXPORT_FUNC_INDEX_PREFIX "mExportFuncIdx_" 48 49#define RS_EXPORT_VAR_ALLOCATION_PREFIX "mAlloction_" 50#define RS_EXPORT_VAR_DATA_STORAGE_PREFIX "mData_" 51 52using namespace slang; 53 54// Some utility function using internal in RSReflection 55static bool GetClassNameFromFileName(const std::string &FileName, 56 std::string &ClassName) { 57 ClassName.clear(); 58 59 if (FileName.empty() || (FileName == "-")) 60 return true; 61 62 ClassName = 63 RSSlangReflectUtils::JavaClassNameFromRSFileName(FileName.c_str()); 64 65 return true; 66} 67 68static const char *GetPrimitiveTypeName(const RSExportPrimitiveType *EPT) { 69 static const char *PrimitiveTypeJavaNameMap[] = { 70 "", // RSExportPrimitiveType::DataTypeFloat16 71 "float", // RSExportPrimitiveType::DataTypeFloat32 72 "double", // RSExportPrimitiveType::DataTypeFloat64 73 "byte", // RSExportPrimitiveType::DataTypeSigned8 74 "short", // RSExportPrimitiveType::DataTypeSigned16 75 "int", // RSExportPrimitiveType::DataTypeSigned32 76 "long", // RSExportPrimitiveType::DataTypeSigned64 77 "short", // RSExportPrimitiveType::DataTypeUnsigned8 78 "int", // RSExportPrimitiveType::DataTypeUnsigned16 79 "long", // RSExportPrimitiveType::DataTypeUnsigned32 80 "long", // RSExportPrimitiveType::DataTypeUnsigned64 81 "boolean", // RSExportPrimitiveType::DataTypeBoolean 82 83 "int", // RSExportPrimitiveType::DataTypeUnsigned565 84 "int", // RSExportPrimitiveType::DataTypeUnsigned5551 85 "int", // RSExportPrimitiveType::DataTypeUnsigned4444 86 87 "", // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2 88 "", // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3 89 "", // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4 90 91 "Element", // RSExportPrimitiveType::DataTypeRSElement 92 "Type", // RSExportPrimitiveType::DataTypeRSType 93 "Allocation", // RSExportPrimitiveType::DataTypeRSAllocation 94 "Sampler", // RSExportPrimitiveType::DataTypeRSSampler 95 "Script", // RSExportPrimitiveType::DataTypeRSScript 96 "Mesh", // RSExportPrimitiveType::DataTypeRSMesh 97 "ProgramFragment", // RSExportPrimitiveType::DataTypeRSProgramFragment 98 "ProgramVertex", // RSExportPrimitiveType::DataTypeRSProgramVertex 99 "ProgramRaster", // RSExportPrimitiveType::DataTypeRSProgramRaster 100 "ProgramStore", // RSExportPrimitiveType::DataTypeRSProgramStore 101 "Font", // RSExportPrimitiveType::DataTypeRSFont 102 }; 103 unsigned TypeId = EPT->getType(); 104 105 if (TypeId < (sizeof(PrimitiveTypeJavaNameMap) / sizeof(const char*))) { 106 return PrimitiveTypeJavaNameMap[ EPT->getType() ]; 107 } 108 109 assert(false && "GetPrimitiveTypeName : Unknown primitive data type"); 110 return NULL; 111} 112 113static const char *GetVectorTypeName(const RSExportVectorType *EVT) { 114 static const char *VectorTypeJavaNameMap[][3] = { 115 /* 0 */ { "Byte2", "Byte3", "Byte4" }, 116 /* 1 */ { "Short2", "Short3", "Short4" }, 117 /* 2 */ { "Int2", "Int3", "Int4" }, 118 /* 3 */ { "Long2", "Long3", "Long4" }, 119 /* 4 */ { "Float2", "Float3", "Float4" }, 120 }; 121 122 const char **BaseElement = NULL; 123 124 switch (EVT->getType()) { 125 case RSExportPrimitiveType::DataTypeSigned8: 126 case RSExportPrimitiveType::DataTypeBoolean: { 127 BaseElement = VectorTypeJavaNameMap[0]; 128 break; 129 } 130 case RSExportPrimitiveType::DataTypeSigned16: 131 case RSExportPrimitiveType::DataTypeUnsigned8: { 132 BaseElement = VectorTypeJavaNameMap[1]; 133 break; 134 } 135 case RSExportPrimitiveType::DataTypeSigned32: 136 case RSExportPrimitiveType::DataTypeUnsigned16: { 137 BaseElement = VectorTypeJavaNameMap[2]; 138 break; 139 } 140 case RSExportPrimitiveType::DataTypeSigned64: 141 case RSExportPrimitiveType::DataTypeUnsigned64: 142 case RSExportPrimitiveType::DataTypeUnsigned32: { 143 BaseElement = VectorTypeJavaNameMap[3]; 144 break; 145 } 146 case RSExportPrimitiveType::DataTypeFloat32: { 147 BaseElement = VectorTypeJavaNameMap[4]; 148 break; 149 } 150 default: { 151 assert(false && "RSReflection::genElementTypeName : Unsupported vector " 152 "element data type"); 153 break; 154 } 155 } 156 157 assert((EVT->getNumElement() > 1) && 158 (EVT->getNumElement() <= 4) && 159 "Number of element in vector type is invalid"); 160 161 return BaseElement[EVT->getNumElement() - 2]; 162} 163 164static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) { 165 static const char *MatrixTypeJavaNameMap[] = { 166 /* 2x2 */ "Matrix2f", 167 /* 3x3 */ "Matrix3f", 168 /* 4x4 */ "Matrix4f", 169 }; 170 unsigned Dim = EMT->getDim(); 171 172 if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char*))) 173 return MatrixTypeJavaNameMap[ EMT->getDim() - 2 ]; 174 175 assert(false && "GetMatrixTypeName : Unsupported matrix dimension"); 176 return NULL; 177} 178 179static const char *GetVectorAccessor(int Index) { 180 static const char *VectorAccessorMap[] = { 181 /* 0 */ "x", 182 /* 1 */ "y", 183 /* 2 */ "z", 184 /* 3 */ "w", 185 }; 186 187 assert((Index >= 0) && 188 (Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) && 189 "Out-of-bound index to access vector member"); 190 191 return VectorAccessorMap[Index]; 192} 193 194static const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) { 195 static const char *PrimitiveTypePackerAPINameMap[] = { 196 "", // RSExportPrimitiveType::DataTypeFloat16 197 "addF32", // RSExportPrimitiveType::DataTypeFloat32 198 "addF64", // RSExportPrimitiveType::DataTypeFloat64 199 "addI8", // RSExportPrimitiveType::DataTypeSigned8 200 "addI16", // RSExportPrimitiveType::DataTypeSigned16 201 "addI32", // RSExportPrimitiveType::DataTypeSigned32 202 "addI64", // RSExportPrimitiveType::DataTypeSigned64 203 "addU8", // RSExportPrimitiveType::DataTypeUnsigned8 204 "addU16", // RSExportPrimitiveType::DataTypeUnsigned16 205 "addU32", // RSExportPrimitiveType::DataTypeUnsigned32 206 "addU64", // RSExportPrimitiveType::DataTypeUnsigned64 207 "addBoolean", // RSExportPrimitiveType::DataTypeBoolean 208 209 "addU16", // RSExportPrimitiveType::DataTypeUnsigned565 210 "addU16", // RSExportPrimitiveType::DataTypeUnsigned5551 211 "addU16", // RSExportPrimitiveType::DataTypeUnsigned4444 212 213 "addObj", // RSExportPrimitiveType::DataTypeRSMatrix2x2 214 "addObj", // RSExportPrimitiveType::DataTypeRSMatrix3x3 215 "addObj", // RSExportPrimitiveType::DataTypeRSMatrix4x4 216 217 "addObj", // RSExportPrimitiveType::DataTypeRSElement 218 "addObj", // RSExportPrimitiveType::DataTypeRSType 219 "addObj", // RSExportPrimitiveType::DataTypeRSAllocation 220 "addObj", // RSExportPrimitiveType::DataTypeRSSampler 221 "addObj", // RSExportPrimitiveType::DataTypeRSScript 222 "addObj", // RSExportPrimitiveType::DataTypeRSMesh 223 "addObj", // RSExportPrimitiveType::DataTypeRSProgramFragment 224 "addObj", // RSExportPrimitiveType::DataTypeRSProgramVertex 225 "addObj", // RSExportPrimitiveType::DataTypeRSProgramRaster 226 "addObj", // RSExportPrimitiveType::DataTypeRSProgramStore 227 "addObj", // RSExportPrimitiveType::DataTypeRSFont 228 }; 229 unsigned TypeId = EPT->getType(); 230 231 if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*))) 232 return PrimitiveTypePackerAPINameMap[ EPT->getType() ]; 233 234 assert(false && "GetPackerAPIName : Unknown primitive data type"); 235 return NULL; 236} 237 238static std::string GetTypeName(const RSExportType *ET) { 239 switch (ET->getClass()) { 240 case RSExportType::ExportClassPrimitive: { 241 return GetPrimitiveTypeName( 242 static_cast<const RSExportPrimitiveType*>(ET)); 243 } 244 case RSExportType::ExportClassPointer: { 245 const RSExportType *PointeeType = 246 static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 247 248 if (PointeeType->getClass() != RSExportType::ExportClassRecord) 249 return "Allocation"; 250 else 251 return RS_TYPE_CLASS_NAME_PREFIX + PointeeType->getName(); 252 } 253 case RSExportType::ExportClassVector: { 254 return GetVectorTypeName(static_cast<const RSExportVectorType*>(ET)); 255 } 256 case RSExportType::ExportClassMatrix: { 257 return GetMatrixTypeName(static_cast<const RSExportMatrixType*>(ET)); 258 } 259 case RSExportType::ExportClassConstantArray: { 260 const RSExportConstantArrayType* CAT = 261 static_cast<const RSExportConstantArrayType*>(ET); 262 std::string ElementTypeName = GetTypeName(CAT->getElementType()); 263 ElementTypeName.append("[]"); 264 return ElementTypeName; 265 } 266 case RSExportType::ExportClassRecord: { 267 return RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + 268 "."RS_TYPE_ITEM_CLASS_NAME; 269 } 270 default: { 271 assert(false && "Unknown class of type"); 272 } 273 } 274 275 return ""; 276} 277 278static const char *GetTypeNullValue(const RSExportType *ET) { 279 switch (ET->getClass()) { 280 case RSExportType::ExportClassPrimitive: { 281 const RSExportPrimitiveType *EPT = 282 static_cast<const RSExportPrimitiveType*>(ET); 283 if (EPT->isRSObjectType()) 284 return "null"; 285 else if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) 286 return "false"; 287 else 288 return "0"; 289 break; 290 } 291 case RSExportType::ExportClassPointer: 292 case RSExportType::ExportClassVector: 293 case RSExportType::ExportClassMatrix: 294 case RSExportType::ExportClassConstantArray: 295 case RSExportType::ExportClassRecord: { 296 return "null"; 297 break; 298 } 299 default: { 300 assert(false && "Unknown class of type"); 301 } 302 } 303 return ""; 304} 305 306static const char *GetBuiltinElementConstruct(const RSExportType *ET) { 307 if (ET->getClass() == RSExportType::ExportClassPrimitive) { 308 const RSExportPrimitiveType *EPT = 309 static_cast<const RSExportPrimitiveType*>(ET); 310 if (EPT->getKind() == RSExportPrimitiveType::DataKindUser) { 311 static const char *PrimitiveBuiltinElementConstructMap[] = { 312 NULL, // RSExportPrimitiveType::DataTypeFloat16 313 "Element.F32", // RSExportPrimitiveType::DataTypeFloat32 314 "Element.F64", // RSExportPrimitiveType::DataTypeFloat64 315 "Element.I8", // RSExportPrimitiveType::DataTypeSigned8 316 NULL, // RSExportPrimitiveType::DataTypeSigned16 317 "Element.I32", // RSExportPrimitiveType::DataTypeSigned32 318 "Element.I64", // RSExportPrimitiveType::DataTypeSigned64 319 "Element.U8", // RSExportPrimitiveType::DataTypeUnsigned8 320 NULL, // RSExportPrimitiveType::DataTypeUnsigned16 321 "Element.U32", // RSExportPrimitiveType::DataTypeUnsigned32 322 "Element.U64", // RSExportPrimitiveType::DataTypeUnsigned64 323 "Element.BOOLEAN", // RSExportPrimitiveType::DataTypeBoolean 324 325 NULL, // RSExportPrimitiveType::DataTypeUnsigned565 326 NULL, // RSExportPrimitiveType::DataTypeUnsigned5551 327 NULL, // RSExportPrimitiveType::DataTypeUnsigned4444 328 329 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2 330 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3 331 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4 332 333 "Element.ELEMENT", // RSExportPrimitiveType::DataTypeRSElement 334 "Element.TYPE", // RSExportPrimitiveType::DataTypeRSType 335 "Element.ALLOCATION", // RSExportPrimitiveType::DataTypeRSAllocation 336 "Element.SAMPLER", // RSExportPrimitiveType::DataTypeRSSampler 337 "Element.SCRIPT", // RSExportPrimitiveType::DataTypeRSScript 338 "Element.MESH", // RSExportPrimitiveType::DataTypeRSMesh 339 "Element.PROGRAM_FRAGMENT", // RSExportPrimitiveType::DataTypeRSProgramFragment 340 "Element.PROGRAM_VERTEX", // RSExportPrimitiveType::DataTypeRSProgramVertex 341 "Element.PROGRAM_RASTER", // RSExportPrimitiveType::DataTypeRSProgramRaster 342 "Element.PROGRAM_STORE", // RSExportPrimitiveType::DataTypeRSProgramStore 343 "Element.FONT", // RSExportPrimitiveType::DataTypeRSFont 344 }; 345 unsigned TypeId = EPT->getType(); 346 347 if (TypeId < 348 (sizeof(PrimitiveBuiltinElementConstructMap) / sizeof(const char*))) 349 return PrimitiveBuiltinElementConstructMap[ EPT->getType() ]; 350 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) { 351 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 352 return "Element.A_8"; 353 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) { 354 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565) 355 return "Element.RGB_565"; 356 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 357 return "Element.RGB_888"; 358 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) { 359 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551) 360 return "Element.RGBA_5551"; 361 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444) 362 return "Element.RGBA_4444"; 363 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 364 return "Element.RGBA_8888"; 365 } 366 } else if (ET->getClass() == RSExportType::ExportClassVector) { 367 const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(ET); 368 if (EVT->getKind() == RSExportPrimitiveType::DataKindUser) { 369 if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 370 if (EVT->getNumElement() == 2) 371 return "Element.F32_2"; 372 else if (EVT->getNumElement() == 3) 373 return "Element.F32_3"; 374 else if (EVT->getNumElement() == 4) 375 return "Element.F32_4"; 376 } else if (EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) { 377 if (EVT->getNumElement() == 4) 378 return "Element.U8_4"; 379 } 380 } 381 } else if (ET->getClass() == RSExportType::ExportClassMatrix) { 382 const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET); 383 switch (EMT->getDim()) { 384 case 2: return "Element.MATRIX_2X2"; 385 case 3: return "Element.MATRIX_3X3"; 386 case 4: return "Element.MATRIX_4X4"; 387 default: assert(false && "Unsupported dimension of matrix"); 388 } 389 } else if (ET->getClass() == RSExportType::ExportClassPointer) { 390 // Treat pointer type variable as unsigned int 391 // TODO(zonr): this is target dependent 392 return "Element.USER_I32"; 393 } 394 395 return NULL; 396} 397 398static const char *GetElementDataKindName(RSExportPrimitiveType::DataKind DK) { 399 static const char *ElementDataKindNameMap[] = { 400 "Element.DataKind.USER", // RSExportPrimitiveType::DataKindUser 401 "Element.DataKind.PIXEL_L", // RSExportPrimitiveType::DataKindPixelL 402 "Element.DataKind.PIXEL_A", // RSExportPrimitiveType::DataKindPixelA 403 "Element.DataKind.PIXEL_LA", // RSExportPrimitiveType::DataKindPixelLA 404 "Element.DataKind.PIXEL_RGB", // RSExportPrimitiveType::DataKindPixelRGB 405 "Element.DataKind.PIXEL_RGBA", // RSExportPrimitiveType::DataKindPixelRGBA 406 }; 407 408 if (static_cast<unsigned>(DK) < 409 (sizeof(ElementDataKindNameMap) / sizeof(const char*))) 410 return ElementDataKindNameMap[ DK ]; 411 else 412 return NULL; 413} 414 415static const char *GetElementDataTypeName(RSExportPrimitiveType::DataType DT) { 416 static const char *ElementDataTypeNameMap[] = { 417 NULL, // RSExportPrimitiveType::DataTypeFloat16 418 "Element.DataType.FLOAT_32", // RSExportPrimitiveType::DataTypeFloat32 419 "Element.DataType.FLOAT_64", // RSExportPrimitiveType::DataTypeFloat64 420 "Element.DataType.SIGNED_8", // RSExportPrimitiveType::DataTypeSigned8 421 "Element.DataType.SIGNED_16", // RSExportPrimitiveType::DataTypeSigned16 422 "Element.DataType.SIGNED_32", // RSExportPrimitiveType::DataTypeSigned32 423 "Element.DataType.SIGNED_64", // RSExportPrimitiveType::DataTypeSigned64 424 "Element.DataType.UNSIGNED_8", // RSExportPrimitiveType::DataTypeUnsigned8 425 "Element.DataType.UNSIGNED_16", // RSExportPrimitiveType::DataTypeUnsigned16 426 "Element.DataType.UNSIGNED_32", // RSExportPrimitiveType::DataTypeUnsigned32 427 "Element.DataType.UNSIGNED_64", // RSExportPrimitiveType::DataTypeUnsigned64 428 "Element.DataType.BOOLEAN", // RSExportPrimitiveType::DataTypeBoolean 429 430 // RSExportPrimitiveType::DataTypeUnsigned565 431 "Element.DataType.UNSIGNED_5_6_5", 432 // RSExportPrimitiveType::DataTypeUnsigned5551 433 "Element.DataType.UNSIGNED_5_5_5_1", 434 // RSExportPrimitiveType::DataTypeUnsigned4444 435 "Element.DataType.UNSIGNED_4_4_4_4", 436 437 // DataTypeRSMatrix* must have been resolved in GetBuiltinElementConstruct() 438 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2 439 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3 440 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4 441 442 "Element.DataType.RS_ELEMENT", // RSExportPrimitiveType::DataTypeRSElement 443 "Element.DataType.RS_TYPE", // RSExportPrimitiveType::DataTypeRSType 444 // RSExportPrimitiveType::DataTypeRSAllocation 445 "Element.DataType.RS_ALLOCATION", 446 // RSExportPrimitiveType::DataTypeRSSampler 447 "Element.DataType.RS_SAMPLER", 448 // RSExportPrimitiveType::DataTypeRSScript 449 "Element.DataType.RS_SCRIPT", 450 // RSExportPrimitiveType::DataTypeRSMesh 451 "Element.DataType.RS_MESH", 452 // RSExportPrimitiveType::DataTypeRSProgramFragment 453 "Element.DataType.RS_PROGRAM_FRAGMENT", 454 // RSExportPrimitiveType::DataTypeRSProgramVertex 455 "Element.DataType.RS_PROGRAM_VERTEX", 456 // RSExportPrimitiveType::DataTypeRSProgramRaster 457 "Element.DataType.RS_PROGRAM_RASTER", 458 // RSExportPrimitiveType::DataTypeRSProgramStore 459 "Element.DataType.RS_PROGRAM_STORE", 460 // RSExportPrimitiveType::DataTypeRSFont 461 "Element.DataType.RS_FONT", 462 }; 463 464 if (static_cast<unsigned>(DT) < 465 (sizeof(ElementDataTypeNameMap) / sizeof(const char*))) 466 return ElementDataTypeNameMap[ DT ]; 467 else 468 return NULL; 469} 470 471/********************** Methods to generate script class **********************/ 472bool RSReflection::genScriptClass(Context &C, 473 const std::string &ClassName, 474 std::string &ErrorMsg) { 475 if (!C.startClass(Context::AM_Public, 476 false, 477 ClassName, 478 RS_SCRIPT_CLASS_SUPER_CLASS_NAME, 479 ErrorMsg)) 480 return false; 481 482 genScriptClassConstructor(C); 483 484 // Reflect export variable 485 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(), 486 E = mRSContext->export_vars_end(); 487 I != E; 488 I++) 489 genExportVariable(C, *I); 490 491 // Reflect export function 492 for (RSContext::const_export_func_iterator 493 I = mRSContext->export_funcs_begin(), 494 E = mRSContext->export_funcs_end(); 495 I != E; I++) 496 genExportFunction(C, *I); 497 498 C.endClass(); 499 500 return true; 501} 502 503void RSReflection::genScriptClassConstructor(Context &C) { 504 C.indent() << "// Constructor" << std::endl; 505 C.startFunction(Context::AM_Public, 506 false, 507 NULL, 508 C.getClassName(), 509 4, 510 "RenderScript", 511 "rs", 512 "Resources", 513 "resources", 514 "int", 515 "id", 516 "boolean", 517 "isRoot"); 518 // Call constructor of super class 519 C.indent() << "super(rs, resources, id, isRoot);" << std::endl; 520 521 // If an exported variable has initial value, reflect it 522 523 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(), 524 E = mRSContext->export_vars_end(); 525 I != E; 526 I++) { 527 const RSExportVar *EV = *I; 528 if (!EV->getInit().isUninit()) 529 genInitExportVariable(C, EV->getType(), EV->getName(), EV->getInit()); 530 } 531 532 C.endFunction(); 533 return; 534} 535 536void RSReflection::genInitBoolExportVariable(Context &C, 537 const std::string &VarName, 538 const clang::APValue &Val) { 539 assert(!Val.isUninit() && "Not a valid initializer"); 540 541 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "; 542 assert((Val.getKind() == clang::APValue::Int) && 543 "Bool type has wrong initial APValue"); 544 545 C.out() << ((Val.getInt().getSExtValue() == 0) ? "false" : "true") 546 << ";" << std::endl; 547 548 return; 549} 550 551void RSReflection::genInitPrimitiveExportVariable(Context &C, 552 const std::string &VarName, 553 const clang::APValue &Val) { 554 assert(!Val.isUninit() && "Not a valid initializer"); 555 556 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "; 557 switch (Val.getKind()) { 558 case clang::APValue::Int: { 559 llvm::APInt api = Val.getInt(); 560 C.out() << api.getSExtValue(); 561 if (api.getBitWidth() > 32) { 562 C.out() << "L"; 563 } 564 break; 565 } 566 case clang::APValue::Float: { 567 llvm::APFloat apf = Val.getFloat(); 568 if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) { 569 C.out() << apf.convertToFloat() << "f"; 570 } else { 571 C.out() << apf.convertToDouble(); 572 } 573 break; 574 } 575 576 case clang::APValue::ComplexInt: 577 case clang::APValue::ComplexFloat: 578 case clang::APValue::LValue: 579 case clang::APValue::Vector: { 580 assert(false && "Primitive type cannot have such kind of initializer"); 581 break; 582 } 583 default: { 584 assert(false && "Unknown kind of initializer"); 585 } 586 } 587 C.out() << ";" << std::endl; 588 589 return; 590} 591 592void RSReflection::genInitExportVariable(Context &C, 593 const RSExportType *ET, 594 const std::string &VarName, 595 const clang::APValue &Val) { 596 assert(!Val.isUninit() && "Not a valid initializer"); 597 598 switch (ET->getClass()) { 599 case RSExportType::ExportClassPrimitive: { 600 const RSExportPrimitiveType *EPT = 601 static_cast<const RSExportPrimitiveType*>(ET); 602 if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) { 603 genInitBoolExportVariable(C, VarName, Val); 604 } else { 605 genInitPrimitiveExportVariable(C, VarName, Val); 606 } 607 break; 608 } 609 case RSExportType::ExportClassPointer: { 610 if (!Val.isInt() || Val.getInt().getSExtValue() != 0) 611 std::cout << "Initializer which is non-NULL to pointer type variable " 612 "will be ignored" << std::endl; 613 break; 614 } 615 case RSExportType::ExportClassVector: { 616 const RSExportVectorType *EVT = 617 static_cast<const RSExportVectorType*>(ET); 618 switch (Val.getKind()) { 619 case clang::APValue::Int: 620 case clang::APValue::Float: { 621 for (unsigned i = 0; i < EVT->getNumElement(); i++) { 622 std::string Name = VarName + "." + GetVectorAccessor(i); 623 genInitPrimitiveExportVariable(C, Name, Val); 624 } 625 break; 626 } 627 case clang::APValue::Vector: { 628 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new " 629 << GetVectorTypeName(EVT) << "();" << std::endl; 630 631 unsigned NumElements = 632 std::min(static_cast<unsigned>(EVT->getNumElement()), 633 Val.getVectorLength()); 634 for (unsigned i = 0; i < NumElements; i++) { 635 const clang::APValue &ElementVal = Val.getVectorElt(i); 636 std::string Name = VarName + "." + GetVectorAccessor(i); 637 genInitPrimitiveExportVariable(C, Name, ElementVal); 638 } 639 break; 640 } 641 case clang::APValue::Uninitialized: 642 case clang::APValue::ComplexInt: 643 case clang::APValue::ComplexFloat: 644 case clang::APValue::LValue: { 645 assert(false && "Unexpected type of value of initializer."); 646 } 647 } 648 break; 649 } 650 // TODO(zonr): Resolving initializer of a record (and matrix) type variable 651 // is complex. It cannot obtain by just simply evaluating the initializer 652 // expression. 653 case RSExportType::ExportClassMatrix: 654 case RSExportType::ExportClassConstantArray: 655 case RSExportType::ExportClassRecord: { 656#if 0 657 unsigned InitIndex = 0; 658 const RSExportRecordType *ERT = 659 static_cast<const RSExportRecordType*>(ET); 660 661 assert((Val.getKind() == clang::APValue::Vector) && "Unexpected type of " 662 "initializer for record type variable"); 663 664 C.indent() << RS_EXPORT_VAR_PREFIX << VarName 665 << " = new "RS_TYPE_CLASS_NAME_PREFIX << ERT->getName() 666 << "."RS_TYPE_ITEM_CLASS_NAME"();" << std::endl; 667 668 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(), 669 E = ERT->fields_end(); 670 I != E; 671 I++) { 672 const RSExportRecordType::Field *F = *I; 673 std::string FieldName = VarName + "." + F->getName(); 674 675 if (InitIndex > Val.getVectorLength()) 676 break; 677 678 genInitPrimitiveExportVariable(C, 679 FieldName, 680 Val.getVectorElt(InitIndex++)); 681 } 682#endif 683 assert(false && "Unsupported initializer for record/matrix/constant " 684 "array type variable currently"); 685 break; 686 } 687 default: { 688 assert(false && "Unknown class of type"); 689 } 690 } 691 return; 692} 693 694void RSReflection::genExportVariable(Context &C, const RSExportVar *EV) { 695 const RSExportType *ET = EV->getType(); 696 697 C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX 698 << EV->getName() << " = " << C.getNextExportVarSlot() << ";" 699 << std::endl; 700 701 switch (ET->getClass()) { 702 case RSExportType::ExportClassPrimitive: { 703 genPrimitiveTypeExportVariable(C, EV); 704 break; 705 } 706 case RSExportType::ExportClassPointer: { 707 genPointerTypeExportVariable(C, EV); 708 break; 709 } 710 case RSExportType::ExportClassVector: { 711 genVectorTypeExportVariable(C, EV); 712 break; 713 } 714 case RSExportType::ExportClassMatrix: { 715 genMatrixTypeExportVariable(C, EV); 716 break; 717 } 718 case RSExportType::ExportClassConstantArray: { 719 genConstantArrayTypeExportVariable(C, EV); 720 break; 721 } 722 case RSExportType::ExportClassRecord: { 723 genRecordTypeExportVariable(C, EV); 724 break; 725 } 726 default: { 727 assert(false && "Unknown class of type"); 728 } 729 } 730 731 return; 732} 733 734void RSReflection::genExportFunction(Context &C, const RSExportFunc *EF) { 735 C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX 736 << EF->getName() << " = " << C.getNextExportFuncSlot() << ";" 737 << std::endl; 738 739 // invoke_*() 740 Context::ArgTy Args; 741 742 if (EF->hasParam()) { 743 for (RSExportFunc::const_param_iterator I = EF->params_begin(), 744 E = EF->params_end(); 745 I != E; 746 I++) { 747 Args.push_back(std::make_pair(GetTypeName((*I)->getType()), 748 (*I)->getName())); 749 } 750 } 751 752 C.startFunction(Context::AM_Public, 753 false, 754 "void", 755 "invoke_" + EF->getName(), 756 Args); 757 758 if (!EF->hasParam()) { 759 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");" 760 << std::endl; 761 } else { 762 const RSExportRecordType *ERT = EF->getParamPacketType(); 763 std::string FieldPackerName = EF->getName() + "_fp"; 764 765 if (genCreateFieldPacker(C, ERT, FieldPackerName.c_str())) 766 genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str()); 767 768 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", " 769 << FieldPackerName << ");" << std::endl; 770 } 771 772 C.endFunction(); 773 return; 774} 775 776void RSReflection::genPrimitiveTypeExportVariable(Context &C, 777 const RSExportVar *EV) { 778 assert((EV->getType()->getClass() == RSExportType::ExportClassPrimitive) && 779 "Variable should be type of primitive here"); 780 781 const RSExportPrimitiveType *EPT = 782 static_cast<const RSExportPrimitiveType*>(EV->getType()); 783 const char *TypeName = GetPrimitiveTypeName(EPT); 784 785 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 786 << EV->getName() << ";" << std::endl; 787 788 // set_*() 789 if (!EV->isConst()) { 790 C.startFunction(Context::AM_Public, 791 false, 792 "void", 793 "set_" + EV->getName(), 794 1, 795 TypeName, 796 "v"); 797 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 798 799 if (EPT->isRSObjectType()) 800 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() 801 << ", (v == null) ? 0 : v.getID());" << std::endl; 802 else 803 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() 804 << ", v);" << std::endl; 805 806 C.endFunction(); 807 } 808 809 genGetExportVariable(C, TypeName, EV->getName()); 810 811 return; 812} 813 814void RSReflection::genPointerTypeExportVariable(Context &C, 815 const RSExportVar *EV) { 816 const RSExportType *ET = EV->getType(); 817 const RSExportType *PointeeType; 818 std::string TypeName; 819 820 assert((ET->getClass() == RSExportType::ExportClassPointer) && 821 "Variable should be type of pointer here"); 822 823 PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 824 TypeName = GetTypeName(ET); 825 826 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 827 << EV->getName() << ";" << std::endl; 828 829 // bind_*() 830 C.startFunction(Context::AM_Public, 831 false, 832 "void", 833 "bind_" + EV->getName(), 834 1, 835 TypeName.c_str(), 836 "v"); 837 838 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 839 C.indent() << "if (v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX 840 << EV->getName() << ");" << std::endl; 841 842 if (PointeeType->getClass() == RSExportType::ExportClassRecord) 843 C.indent() << "else bindAllocation(v.getAllocation(), " 844 RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" 845 << std::endl; 846 else 847 C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX 848 << EV->getName() << ");" << std::endl; 849 850 C.endFunction(); 851 852 genGetExportVariable(C, TypeName, EV->getName()); 853 854 return; 855} 856 857void RSReflection::genVectorTypeExportVariable(Context &C, 858 const RSExportVar *EV) { 859 assert((EV->getType()->getClass() == RSExportType::ExportClassVector) && 860 "Variable should be type of vector here"); 861 862 const RSExportVectorType *EVT = 863 static_cast<const RSExportVectorType*>(EV->getType()); 864 const char *TypeName = GetVectorTypeName(EVT); 865 const char *FieldPackerName = "fp"; 866 867 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 868 << EV->getName() << ";" << std::endl; 869 870 // set_*() 871 if (!EV->isConst()) { 872 C.startFunction(Context::AM_Public, 873 false, 874 "void", 875 "set_" + EV->getName(), 876 1, 877 TypeName, 878 "v"); 879 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 880 881 if (genCreateFieldPacker(C, EVT, FieldPackerName)) 882 genPackVarOfType(C, EVT, "v", FieldPackerName); 883 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " 884 << FieldPackerName << ");" << std::endl; 885 886 C.endFunction(); 887 } 888 889 genGetExportVariable(C, TypeName, EV->getName()); 890 return; 891} 892 893void RSReflection::genMatrixTypeExportVariable(Context &C, 894 const RSExportVar *EV) { 895 assert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) && 896 "Variable should be type of matrix here"); 897 898 const RSExportMatrixType *EMT = 899 static_cast<const RSExportMatrixType*>(EV->getType()); 900 const char *TypeName = GetMatrixTypeName(EMT); 901 const char *FieldPackerName = "fp"; 902 903 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 904 << EV->getName() << ";" << std::endl; 905 906 // set_*() 907 if (!EV->isConst()) { 908 C.startFunction(Context::AM_Public, 909 false, 910 "void", 911 "set_" + EV->getName(), 912 1, 913 TypeName, "v"); 914 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 915 916 if (genCreateFieldPacker(C, EMT, FieldPackerName)) 917 genPackVarOfType(C, EMT, "v", FieldPackerName); 918 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " 919 << FieldPackerName << ");" << std::endl; 920 921 C.endFunction(); 922 } 923 924 genGetExportVariable(C, TypeName, EV->getName()); 925 return; 926} 927 928void RSReflection::genConstantArrayTypeExportVariable(Context &C, 929 const RSExportVar *EV) { 930 assert((EV->getType()->getClass() == RSExportType::ExportClassConstantArray)&& 931 "Variable should be type of constant array here"); 932 933 const RSExportConstantArrayType *ECAT = 934 static_cast<const RSExportConstantArrayType*>(EV->getType()); 935 std::string TypeName = GetTypeName(ECAT); 936 const char *FieldPackerName = "fp"; 937 938 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 939 << EV->getName() << ";" << std::endl; 940 941 // set_*() 942 if (!EV->isConst()) { 943 C.startFunction(Context::AM_Public, 944 false, 945 "void", 946 "set_" + EV->getName(), 947 1, 948 TypeName.c_str(), "v"); 949 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 950 951 if (genCreateFieldPacker(C, ECAT, FieldPackerName)) 952 genPackVarOfType(C, ECAT, "v", FieldPackerName); 953 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " 954 << FieldPackerName << ");" << std::endl; 955 956 C.endFunction(); 957 } 958 959 genGetExportVariable(C, TypeName, EV->getName()); 960 return; 961} 962 963void RSReflection::genRecordTypeExportVariable(Context &C, 964 const RSExportVar *EV) { 965 assert((EV->getType()->getClass() == RSExportType::ExportClassRecord) && 966 "Variable should be type of struct here"); 967 968 const RSExportRecordType *ERT = 969 static_cast<const RSExportRecordType*>(EV->getType()); 970 std::string TypeName = 971 RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME; 972 const char *FieldPackerName = "fp"; 973 974 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 975 << EV->getName() << ";" << std::endl; 976 977 // set_*() 978 if (!EV->isConst()) { 979 C.startFunction(Context::AM_Public, 980 false, 981 "void", 982 "set_" + EV->getName(), 983 1, 984 TypeName.c_str(), 985 "v"); 986 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 987 988 if (genCreateFieldPacker(C, ERT, FieldPackerName)) 989 genPackVarOfType(C, ERT, "v", FieldPackerName); 990 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() 991 << ", " << FieldPackerName << ");" << std::endl; 992 993 C.endFunction(); 994 } 995 996 genGetExportVariable(C, TypeName.c_str(), EV->getName()); 997 return; 998} 999 1000void RSReflection::genGetExportVariable(Context &C, 1001 const std::string &TypeName, 1002 const std::string &VarName) { 1003 C.startFunction(Context::AM_Public, 1004 false, 1005 TypeName.c_str(), 1006 "get_" + VarName, 1007 0); 1008 1009 C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << std::endl; 1010 1011 C.endFunction(); 1012 return; 1013} 1014 1015/******************* Methods to generate script class /end *******************/ 1016 1017bool RSReflection::genCreateFieldPacker(Context &C, 1018 const RSExportType *ET, 1019 const char *FieldPackerName) { 1020 size_t AllocSize = RSExportType::GetTypeAllocSize(ET); 1021 if (AllocSize > 0) 1022 C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker(" 1023 << AllocSize << ");" << std::endl; 1024 else 1025 return false; 1026 return true; 1027} 1028 1029void RSReflection::genPackVarOfType(Context &C, 1030 const RSExportType *ET, 1031 const char *VarName, 1032 const char *FieldPackerName) { 1033 switch (ET->getClass()) { 1034 case RSExportType::ExportClassPrimitive: 1035 case RSExportType::ExportClassVector: { 1036 C.indent() << FieldPackerName << "." 1037 << GetPackerAPIName( 1038 static_cast<const RSExportPrimitiveType*>(ET)) 1039 << "(" << VarName << ");" << std::endl; 1040 break; 1041 } 1042 case RSExportType::ExportClassPointer: { 1043 // Must reflect as type Allocation in Java 1044 const RSExportType *PointeeType = 1045 static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 1046 1047 if (PointeeType->getClass() != RSExportType::ExportClassRecord) 1048 C.indent() << FieldPackerName << ".addI32(" << VarName 1049 << ".getPtr());" << std::endl; 1050 else 1051 C.indent() << FieldPackerName << ".addI32(" << VarName 1052 << ".getAllocation().getPtr());" << std::endl; 1053 break; 1054 } 1055 case RSExportType::ExportClassMatrix: { 1056 C.indent() << FieldPackerName << ".addObj(" << VarName << ");" 1057 << std::endl; 1058 break; 1059 } 1060 case RSExportType::ExportClassConstantArray: { 1061 const RSExportConstantArrayType *ECAT = 1062 static_cast<const RSExportConstantArrayType *>(ET); 1063 1064 // TODO(zonr): more elegant way. Currently, we obtain the unique index 1065 // variable (this method involves recursive call which means 1066 // we may have more than one level loop, therefore we can't 1067 // always use the same index variable name here) name given 1068 // in the for-loop from counting the '.' in @VarName. 1069 unsigned Level = 0; 1070 size_t LastDotPos = 0; 1071 std::string ElementVarName(VarName); 1072 1073 while (LastDotPos != std::string::npos) { 1074 LastDotPos = ElementVarName.find_first_of('.', LastDotPos + 1); 1075 Level++; 1076 } 1077 std::string IndexVarName("ct"); 1078 IndexVarName.append(llvm::utostr_32(Level)); 1079 1080 C.indent() << "for (int " << IndexVarName << " = 0; " << 1081 IndexVarName << " < " << ECAT->getSize() << "; " << 1082 IndexVarName << "++)"; 1083 C.startBlock(); 1084 1085 ElementVarName.append("[" + IndexVarName + "]"); 1086 genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(), 1087 FieldPackerName); 1088 1089 C.endBlock(); 1090 break; 1091 } 1092 case RSExportType::ExportClassRecord: { 1093 const RSExportRecordType *ERT = 1094 static_cast<const RSExportRecordType*>(ET); 1095 // Relative pos from now on in field packer 1096 unsigned Pos = 0; 1097 1098 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(), 1099 E = ERT->fields_end(); 1100 I != E; 1101 I++) { 1102 const RSExportRecordType::Field *F = *I; 1103 std::string FieldName; 1104 size_t FieldOffset = F->getOffsetInParent(); 1105 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1106 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 1107 1108 if (VarName != NULL) 1109 FieldName = VarName + ("." + F->getName()); 1110 else 1111 FieldName = F->getName(); 1112 1113 if (FieldOffset > Pos) 1114 C.indent() << FieldPackerName << ".skip(" 1115 << (FieldOffset - Pos) << ");" << std::endl; 1116 1117 genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName); 1118 1119 // There is padding in the field type 1120 if (FieldAllocSize > FieldStoreSize) 1121 C.indent() << FieldPackerName << ".skip(" 1122 << (FieldAllocSize - FieldStoreSize) 1123 << ");" << std::endl; 1124 1125 Pos = FieldOffset + FieldAllocSize; 1126 } 1127 1128 // There maybe some padding after the struct 1129 size_t Padding = RSExportType::GetTypeAllocSize(ERT) - Pos; 1130 if (Padding > 0) 1131 C.indent() << FieldPackerName << ".skip(" << Padding << ");" 1132 << std::endl; 1133 break; 1134 } 1135 default: { 1136 assert(false && "Unknown class of type"); 1137 } 1138 } 1139 1140 return; 1141} 1142 1143void RSReflection::genAllocateVarOfType(Context &C, 1144 const RSExportType *T, 1145 const std::string &VarName) { 1146 switch (T->getClass()) { 1147 case RSExportType::ExportClassPrimitive: { 1148 // Primitive type like int in Java has its own storage once it's declared. 1149 // 1150 // FIXME: Should we allocate storage for RS object? 1151 // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType()) 1152 // C.indent() << VarName << " = new " << GetTypeName(T) << "();" 1153 // << std::endl; 1154 break; 1155 } 1156 case RSExportType::ExportClassPointer: { 1157 // Pointer type is an instance of Allocation or a TypeClass whose value is 1158 // expected to be assigned by programmer later in Java program. Therefore 1159 // we don't reflect things like [VarName] = new Allocation(); 1160 C.indent() << VarName << " = null;" << std::endl; 1161 break; 1162 } 1163 case RSExportType::ExportClassConstantArray: { 1164 const RSExportConstantArrayType *ECAT = 1165 static_cast<const RSExportConstantArrayType *>(T); 1166 const RSExportType *ElementType = ECAT->getElementType(); 1167 1168 C.indent() << VarName << " = new " << GetTypeName(ElementType) 1169 << "[" << ECAT->getSize() << "];" << std::endl; 1170 1171 // Primitive type element doesn't need allocation code. 1172 if (ElementType->getClass() != RSExportType::ExportClassPrimitive) { 1173 C.indent() << "for (int $ct = 0; $ct < " << ECAT->getSize() << "; " 1174 "$ct++)"; 1175 C.startBlock(); 1176 1177 std::string ElementVarName(VarName); 1178 ElementVarName.append("[$ct]"); 1179 genAllocateVarOfType(C, ElementType, ElementVarName); 1180 1181 C.endBlock(); 1182 } 1183 break; 1184 } 1185 case RSExportType::ExportClassVector: 1186 case RSExportType::ExportClassMatrix: 1187 case RSExportType::ExportClassRecord: { 1188 C.indent() << VarName << " = new " << GetTypeName(T) << "();" 1189 << std::endl; 1190 break; 1191 } 1192 } 1193 return; 1194} 1195 1196void RSReflection::genNewItemBufferIfNull(Context &C, const char *Index) { 1197 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) " 1198 RS_TYPE_ITEM_BUFFER_NAME" = " 1199 "new "RS_TYPE_ITEM_CLASS_NAME"[mType.getX() /* count */];" 1200 << std::endl; 1201 if (Index != NULL) 1202 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] == null) " 1203 RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] = " 1204 "new "RS_TYPE_ITEM_CLASS_NAME"();" << std::endl; 1205 return; 1206} 1207 1208void RSReflection::genNewItemBufferPackerIfNull(Context &C) { 1209 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_PACKER_NAME" == null) " 1210 RS_TYPE_ITEM_BUFFER_PACKER_NAME" = " 1211 "new FieldPacker(" 1212 RS_TYPE_ITEM_CLASS_NAME".sizeof * mType.getX()/* count */" 1213 ");" << std::endl; 1214 return; 1215} 1216 1217/********************** Methods to generate type class **********************/ 1218bool RSReflection::genTypeClass(Context &C, 1219 const RSExportRecordType *ERT, 1220 std::string &ErrorMsg) { 1221 std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName(); 1222 1223 if (!C.startClass(Context::AM_Public, 1224 false, 1225 ClassName, 1226 RS_TYPE_CLASS_SUPER_CLASS_NAME, 1227 ErrorMsg)) 1228 return false; 1229 1230 genTypeItemClass(C, ERT); 1231 1232 // Declare item buffer and item buffer packer 1233 C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[]" 1234 ";" << std::endl; 1235 C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";" 1236 << std::endl; 1237 1238 genTypeClassConstructor(C, ERT); 1239 genTypeClassCopyToArray(C, ERT); 1240 genTypeClassItemSetter(C, ERT); 1241 genTypeClassItemGetter(C, ERT); 1242 genTypeClassComponentSetter(C, ERT); 1243 genTypeClassComponentGetter(C, ERT); 1244 genTypeClassCopyAll(C, ERT); 1245 1246 C.endClass(); 1247 1248 C.resetFieldIndex(); 1249 C.clearFieldIndexMap(); 1250 1251 return true; 1252} 1253 1254void RSReflection::genTypeItemClass(Context &C, const RSExportRecordType *ERT) { 1255 C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME; 1256 C.startBlock(); 1257 1258 C.indent() << "public static final int sizeof = " 1259 << RSExportType::GetTypeAllocSize(ERT) << ";" << std::endl; 1260 1261 // Member elements 1262 C.out() << std::endl; 1263 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 1264 FE = ERT->fields_end(); 1265 FI != FE; 1266 FI++) { 1267 C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName() 1268 << ";" << std::endl; 1269 } 1270 1271 // Constructor 1272 C.out() << std::endl; 1273 C.indent() << RS_TYPE_ITEM_CLASS_NAME"()"; 1274 C.startBlock(); 1275 1276 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 1277 FE = ERT->fields_end(); 1278 FI != FE; 1279 FI++) { 1280 const RSExportRecordType::Field *F = *FI; 1281 genAllocateVarOfType(C, F->getType(), F->getName()); 1282 } 1283 1284 // end Constructor 1285 C.endBlock(); 1286 1287 // end Item class 1288 C.endBlock(); 1289 1290 return; 1291} 1292 1293void RSReflection::genTypeClassConstructor(Context &C, 1294 const RSExportRecordType *ERT) { 1295 const char *RenderScriptVar = "rs"; 1296 1297 C.startFunction(Context::AM_Public, 1298 true, 1299 "Element", 1300 "createElement", 1301 1, 1302 "RenderScript", 1303 RenderScriptVar); 1304 genBuildElement(C, "eb", ERT, RenderScriptVar, /* IsInline = */false); 1305 C.endFunction(); 1306 1307 C.startFunction(Context::AM_Public, 1308 false, 1309 NULL, 1310 C.getClassName(), 1311 2, 1312 "RenderScript", 1313 RenderScriptVar, 1314 "int", 1315 "count"); 1316 1317 C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl; 1318 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl; 1319 C.indent() << "mElement = createElement(" << RenderScriptVar << ");" 1320 << std::endl; 1321 // Call init() in super class 1322 C.indent() << "init(" << RenderScriptVar << ", count);" << std::endl; 1323 C.endFunction(); 1324 1325 return; 1326} 1327 1328void RSReflection::genTypeClassCopyToArray(Context &C, 1329 const RSExportRecordType *ERT) { 1330 C.startFunction(Context::AM_Private, 1331 false, 1332 "void", 1333 "copyToArray", 1334 2, 1335 RS_TYPE_ITEM_CLASS_NAME, 1336 "i", 1337 "int", 1338 "index"); 1339 1340 genNewItemBufferPackerIfNull(C); 1341 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME 1342 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" 1343 << std::endl; 1344 1345 genPackVarOfType(C, ERT, "i", RS_TYPE_ITEM_BUFFER_PACKER_NAME); 1346 1347 C.endFunction(); 1348 return; 1349} 1350 1351void RSReflection::genTypeClassItemSetter(Context &C, 1352 const RSExportRecordType *ERT) { 1353 C.startFunction(Context::AM_Public, 1354 false, 1355 "void", 1356 "set", 1357 3, 1358 RS_TYPE_ITEM_CLASS_NAME, 1359 "i", 1360 "int", 1361 "index", 1362 "boolean", 1363 "copyNow"); 1364 genNewItemBufferIfNull(C, NULL); 1365 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << std::endl; 1366 1367 C.indent() << "if (copyNow) "; 1368 C.startBlock(); 1369 1370 C.indent() << "copyToArray(i, index);" << std::endl; 1371 C.indent() << "mAllocation.subData1D(index, 1, " 1372 RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << std::endl; 1373 1374 // End of if (copyNow) 1375 C.endBlock(); 1376 1377 C.endFunction(); 1378 return; 1379} 1380 1381void RSReflection::genTypeClassItemGetter(Context &C, 1382 const RSExportRecordType *ERT) { 1383 C.startFunction(Context::AM_Public, 1384 false, 1385 RS_TYPE_ITEM_CLASS_NAME, 1386 "get", 1387 1, 1388 "int", 1389 "index"); 1390 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return null;" 1391 << std::endl; 1392 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index];" << std::endl; 1393 C.endFunction(); 1394 return; 1395} 1396 1397void RSReflection::genTypeClassComponentSetter(Context &C, 1398 const RSExportRecordType *ERT) { 1399 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 1400 FE = ERT->fields_end(); 1401 FI != FE; 1402 FI++) { 1403 const RSExportRecordType::Field *F = *FI; 1404 size_t FieldOffset = F->getOffsetInParent(); 1405 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1406 unsigned FieldIndex = C.getFieldIndex(F); 1407 1408 C.startFunction(Context::AM_Public, 1409 false, 1410 "void", 1411 "set_" + F->getName(), 3, 1412 "int", 1413 "index", 1414 GetTypeName(F->getType()).c_str(), 1415 "v", 1416 "boolean", 1417 "copyNow"); 1418 genNewItemBufferPackerIfNull(C); 1419 genNewItemBufferIfNull(C, "index"); 1420 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName() 1421 << " = v;" << std::endl; 1422 1423 C.indent() << "if (copyNow) "; 1424 C.startBlock(); 1425 1426 if (FieldOffset > 0) 1427 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME 1428 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof + " 1429 << FieldOffset << ");" << std::endl; 1430 else 1431 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME 1432 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" 1433 << std::endl; 1434 genPackVarOfType(C, F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME); 1435 1436 C.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize << ");" 1437 << std::endl; 1438 genPackVarOfType(C, F->getType(), "v", "fp"); 1439 C.indent() << "mAllocation.subElementData(index, " << FieldIndex << ", fp);" 1440 << std::endl; 1441 1442 // End of if (copyNow) 1443 C.endBlock(); 1444 1445 C.endFunction(); 1446 } 1447 return; 1448} 1449 1450void RSReflection::genTypeClassComponentGetter(Context &C, 1451 const RSExportRecordType *ERT) { 1452 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 1453 FE = ERT->fields_end(); 1454 FI != FE; 1455 FI++) { 1456 const RSExportRecordType::Field *F = *FI; 1457 C.startFunction(Context::AM_Public, 1458 false, 1459 GetTypeName(F->getType()).c_str(), 1460 "get_" + F->getName(), 1461 1, 1462 "int", 1463 "index"); 1464 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return " 1465 << GetTypeNullValue(F->getType()) << ";" << std::endl; 1466 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName() 1467 << ";" << std::endl; 1468 C.endFunction(); 1469 } 1470 return; 1471} 1472 1473void RSReflection::genTypeClassCopyAll(Context &C, 1474 const RSExportRecordType *ERT) { 1475 C.startFunction(Context::AM_Public, false, "void", "copyAll", 0); 1476 1477 C.indent() << "for (int ct = 0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++)" 1478 " copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);" 1479 << std::endl; 1480 C.indent() << "mAllocation.data("RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" 1481 << std::endl; 1482 1483 C.endFunction(); 1484 return; 1485} 1486 1487/******************** Methods to generate type class /end ********************/ 1488 1489/********** Methods to create Element in Java of given record type ***********/ 1490void RSReflection::genBuildElement(Context &C, 1491 const char *ElementBuilderName, 1492 const RSExportRecordType *ERT, 1493 const char *RenderScriptVar, 1494 bool IsInline) { 1495 C.indent() << "Element.Builder " << ElementBuilderName << " = " 1496 "new Element.Builder(" << RenderScriptVar << ");" << std::endl; 1497 1498 // eb.add(...) 1499 genAddElementToElementBuilder(C, 1500 ERT, 1501 "", 1502 ElementBuilderName, 1503 RenderScriptVar, 1504 /* ArraySize = */0); 1505 1506 if (!IsInline) 1507 C.indent() << "return " << ElementBuilderName << ".create();" << std::endl; 1508 return; 1509} 1510 1511#define EB_ADD(x) do { \ 1512 C.indent() << ElementBuilderName \ 1513 << ".add(" << x << ", \"" << VarName << "\""; \ 1514 if (ArraySize > 0) \ 1515 C.out() << ", " << ArraySize; \ 1516 C.out() << ");" << std::endl; \ 1517 C.incFieldIndex(); \ 1518} while (false) 1519 1520void RSReflection::genAddElementToElementBuilder(Context &C, 1521 const RSExportType *ET, 1522 const std::string &VarName, 1523 const char *ElementBuilderName, 1524 const char *RenderScriptVar, 1525 unsigned ArraySize) { 1526 const char *ElementConstruct = GetBuiltinElementConstruct(ET); 1527 1528 if (ElementConstruct != NULL) { 1529 EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")"); 1530 } else { 1531 if ((ET->getClass() == RSExportType::ExportClassPrimitive) || 1532 (ET->getClass() == RSExportType::ExportClassVector)) { 1533 const RSExportPrimitiveType *EPT = 1534 static_cast<const RSExportPrimitiveType*>(ET); 1535 const char *DataKindName = GetElementDataKindName(EPT->getKind()); 1536 const char *DataTypeName = GetElementDataTypeName(EPT->getType()); 1537 int Size = (ET->getClass() == RSExportType::ExportClassVector) ? 1538 static_cast<const RSExportVectorType*>(ET)->getNumElement() : 1539 1; 1540 1541 switch (EPT->getKind()) { 1542 case RSExportPrimitiveType::DataKindPixelL: 1543 case RSExportPrimitiveType::DataKindPixelA: 1544 case RSExportPrimitiveType::DataKindPixelLA: 1545 case RSExportPrimitiveType::DataKindPixelRGB: 1546 case RSExportPrimitiveType::DataKindPixelRGBA: { 1547 // Element.createPixel() 1548 EB_ADD("Element.createPixel(" << RenderScriptVar << ", " 1549 << DataTypeName << ", " 1550 << DataKindName << ")"); 1551 break; 1552 } 1553 case RSExportPrimitiveType::DataKindUser: 1554 default: { 1555 if (EPT->getClass() == RSExportType::ExportClassPrimitive) { 1556 // Element.createUser() 1557 EB_ADD("Element.createUser(" << RenderScriptVar << ", " 1558 << DataTypeName << ")"); 1559 } else { 1560 assert((ET->getClass() == RSExportType::ExportClassVector) && 1561 "Unexpected type."); 1562 EB_ADD("Element.createVector(" << RenderScriptVar << ", " 1563 << DataTypeName << ", " 1564 << Size << ")"); 1565 } 1566 break; 1567 } 1568 } 1569#ifndef NDEBUG 1570 } else if (ET->getClass() == RSExportType::ExportClassPointer) { 1571 // Pointer type variable should be resolved in 1572 // GetBuiltinElementConstruct() 1573 assert(false && "??"); 1574 } else if (ET->getClass() == RSExportType::ExportClassMatrix) { 1575 // Matrix type variable should be resolved 1576 // in GetBuiltinElementConstruct() 1577 assert(false && "??"); 1578#endif 1579 } else if (ET->getClass() == RSExportType::ExportClassConstantArray) { 1580 const RSExportConstantArrayType *ECAT = 1581 static_cast<const RSExportConstantArrayType *>(ET); 1582 1583 const RSExportType *ElementType = ECAT->getElementType(); 1584 if (ElementType->getClass() != RSExportType::ExportClassRecord) { 1585 genAddElementToElementBuilder(C, 1586 ECAT->getElementType(), 1587 VarName, 1588 ElementBuilderName, 1589 RenderScriptVar, 1590 ECAT->getSize()); 1591 } else { 1592 std::string NewElementBuilderName(ElementBuilderName); 1593 NewElementBuilderName.append(1, '_'); 1594 1595 genBuildElement(C, 1596 NewElementBuilderName.c_str(), 1597 static_cast<const RSExportRecordType*>(ElementType), 1598 RenderScriptVar, 1599 /* IsInline = */true); 1600 ArraySize = ECAT->getSize(); 1601 EB_ADD(NewElementBuilderName << ".create()"); 1602 } 1603 } else if (ET->getClass() == RSExportType::ExportClassRecord) { 1604 // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType. 1605 // 1606 // TODO(zonr): Generalize these two function such that there's no 1607 // duplicated codes. 1608 const RSExportRecordType *ERT = 1609 static_cast<const RSExportRecordType*>(ET); 1610 int Pos = 0; // relative pos from now on 1611 1612 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(), 1613 E = ERT->fields_end(); 1614 I != E; 1615 I++) { 1616 const RSExportRecordType::Field *F = *I; 1617 std::string FieldName; 1618 int FieldOffset = F->getOffsetInParent(); 1619 int FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1620 int FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 1621 1622 if (!VarName.empty()) 1623 FieldName = VarName + "." + F->getName(); 1624 else 1625 FieldName = F->getName(); 1626 1627 // Alignment 1628 genAddPaddingToElementBuiler(C, 1629 (FieldOffset - Pos), 1630 ElementBuilderName, 1631 RenderScriptVar); 1632 1633 // eb.add(...) 1634 C.addFieldIndexMapping(F); 1635 if (F->getType()->getClass() != RSExportType::ExportClassRecord) { 1636 genAddElementToElementBuilder(C, 1637 F->getType(), 1638 FieldName, 1639 ElementBuilderName, 1640 RenderScriptVar, 1641 0); 1642 } else { 1643 std::string NewElementBuilderName(ElementBuilderName); 1644 NewElementBuilderName.append(1, '_'); 1645 1646 genBuildElement(C, 1647 NewElementBuilderName.c_str(), 1648 static_cast<const RSExportRecordType*>(F->getType()), 1649 RenderScriptVar, 1650 /* IsInline = */true); 1651 1652 const std::string &VarName = FieldName; // Hack for EB_ADD macro 1653 EB_ADD(NewElementBuilderName << ".create()"); 1654 } 1655 1656 // There is padding within the field type 1657 genAddPaddingToElementBuiler(C, 1658 (FieldAllocSize - FieldStoreSize), 1659 ElementBuilderName, 1660 RenderScriptVar); 1661 1662 Pos = FieldOffset + FieldAllocSize; 1663 } 1664 1665 // There maybe some padding after the struct 1666 size_t RecordStoreSize = RSExportType::GetTypeStoreSize(ERT); 1667 1668 genAddPaddingToElementBuiler(C, 1669 RecordStoreSize - Pos, 1670 ElementBuilderName, 1671 RenderScriptVar); 1672 } else { 1673 assert(false && "Unknown class of type"); 1674 } 1675 } 1676} 1677 1678void RSReflection::genAddPaddingToElementBuiler(Context &C, 1679 int PaddingSize, 1680 const char *ElementBuilderName, 1681 const char *RenderScriptVar) { 1682 unsigned ArraySize = 0; // Hack the EB_ADD macro 1683 while (PaddingSize > 0) { 1684 const std::string &VarName = C.createPaddingField(); 1685 if (PaddingSize >= 4) { 1686 EB_ADD("Element.U32(" << RenderScriptVar << ")"); 1687 PaddingSize -= 4; 1688 } else if (PaddingSize >= 2) { 1689 EB_ADD("Element.U16(" << RenderScriptVar << ")"); 1690 PaddingSize -= 2; 1691 } else if (PaddingSize >= 1) { 1692 EB_ADD("Element.U8(" << RenderScriptVar << ")"); 1693 PaddingSize -= 1; 1694 } 1695 } 1696 return; 1697} 1698 1699#undef EB_ADD 1700/******** Methods to create Element in Java of given record type /end ********/ 1701 1702bool RSReflection::reflect(const std::string &OutputPathBase, 1703 const std::string &OutputPackageName, 1704 const std::string &InputFileName, 1705 const std::string &OutputBCFileName) { 1706 Context *C = NULL; 1707 std::string ResourceId = ""; 1708 1709 if (!GetClassNameFromFileName(OutputBCFileName, ResourceId)) 1710 return false; 1711 1712 if (ResourceId.empty()) 1713 ResourceId = "<Resource ID>"; 1714 1715 if (OutputPackageName.empty() || OutputPackageName == "-") 1716 C = new Context(OutputPathBase, InputFileName, "<Package Name>", 1717 ResourceId, true); 1718 else 1719 C = new Context(OutputPathBase, InputFileName, OutputPackageName, 1720 ResourceId, false); 1721 1722 if (C != NULL) { 1723 std::string ErrorMsg, ScriptClassName; 1724 // class ScriptC_<ScriptName> 1725 if (!GetClassNameFromFileName(InputFileName, ScriptClassName)) 1726 return false; 1727 1728 if (ScriptClassName.empty()) 1729 ScriptClassName = "<Input Script Name>"; 1730 1731 ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX); 1732 1733 if (mRSContext->getLicenseNote() != NULL) { 1734 C->setLicenseNote(*(mRSContext->getLicenseNote())); 1735 } 1736 1737 if (!genScriptClass(*C, ScriptClassName, ErrorMsg)) { 1738 std::cerr << "Failed to generate class " << ScriptClassName << " (" 1739 << ErrorMsg << ")" << std::endl; 1740 return false; 1741 } 1742 1743 // class ScriptField_<TypeName> 1744 for (RSContext::const_export_type_iterator TI = 1745 mRSContext->export_types_begin(), 1746 TE = mRSContext->export_types_end(); 1747 TI != TE; 1748 TI++) { 1749 const RSExportType *ET = TI->getValue(); 1750 1751 if (ET->getClass() == RSExportType::ExportClassRecord) { 1752 const RSExportRecordType *ERT = 1753 static_cast<const RSExportRecordType*>(ET); 1754 1755 if (!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) { 1756 std::cerr << "Failed to generate type class for struct '" 1757 << ERT->getName() << "' (" << ErrorMsg << ")" << std::endl; 1758 return false; 1759 } 1760 } 1761 } 1762 } 1763 1764 return true; 1765} 1766 1767/************************** RSReflection::Context **************************/ 1768const char *const RSReflection::Context::ApacheLicenseNote = 1769 "/*\n" 1770 " * Copyright (C) 2010 The Android Open Source Project\n" 1771 " *\n" 1772 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" 1773 " * you may not use this file except in compliance with the License.\n" 1774 " * You may obtain a copy of the License at\n" 1775 " *\n" 1776 " * http://www.apache.org/licenses/LICENSE-2.0\n" 1777 " *\n" 1778 " * Unless required by applicable law or agreed to in writing, software\n" 1779 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" 1780 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or " 1781 "implied.\n" 1782 " * See the License for the specific language governing permissions and\n" 1783 " * limitations under the License.\n" 1784 " */\n" 1785 "\n"; 1786 1787const char *const RSReflection::Context::Import[] = { 1788 // RenderScript java class 1789 "android.renderscript.*", 1790 // Import R 1791 "android.content.res.Resources", 1792 // Import for debugging 1793 "android.util.Log", 1794}; 1795 1796bool RSReflection::Context::openClassFile(const std::string &ClassName, 1797 std::string &ErrorMsg) { 1798 if (!mUseStdout) { 1799 mOF.clear(); 1800 std::string Path = 1801 RSSlangReflectUtils::ComputePackagedPath(mOutputPathBase.c_str(), 1802 mPackageName.c_str()); 1803 1804 if (!SlangUtils::CreateDirectoryWithParents(Path, &ErrorMsg)) 1805 return false; 1806 1807 std::string ClassFile = Path + "/" + ClassName + ".java"; 1808 1809 mOF.open(ClassFile.c_str()); 1810 if (!mOF.good()) { 1811 ErrorMsg = "failed to open file '" + ClassFile + "' for write"; 1812 return false; 1813 } 1814 } 1815 return true; 1816} 1817 1818const char *RSReflection::Context::AccessModifierStr(AccessModifier AM) { 1819 switch (AM) { 1820 case AM_Public: return "public"; break; 1821 case AM_Protected: return "protected"; break; 1822 case AM_Private: return "private"; break; 1823 default: return ""; break; 1824 } 1825} 1826 1827bool RSReflection::Context::startClass(AccessModifier AM, 1828 bool IsStatic, 1829 const std::string &ClassName, 1830 const char *SuperClassName, 1831 std::string &ErrorMsg) { 1832 if (mVerbose) 1833 std::cout << "Generating " << ClassName << ".java ..." << std::endl; 1834 1835 // Open file for class 1836 if (!openClassFile(ClassName, ErrorMsg)) 1837 return false; 1838 1839 // License 1840 out() << mLicenseNote; 1841 1842 // Notice of generated file 1843 out() << "/*" << std::endl; 1844 out() << " * This file is auto-generated. DO NOT MODIFY!" << std::endl; 1845 out() << " * The source RenderScript file: " << mInputRSFile << std::endl; 1846 out() << " */" << std::endl; 1847 1848 // Package 1849 if (!mPackageName.empty()) 1850 out() << "package " << mPackageName << ";" << std::endl; 1851 out() << std::endl; 1852 1853 // Imports 1854 for (unsigned i = 0;i < (sizeof(Import) / sizeof(const char*)); i++) 1855 out() << "import " << Import[i] << ";" << std::endl; 1856 out() << std::endl; 1857 1858 // All reflected classes should be annotated as hidden, so that they won't 1859 // be exposed in SDK. 1860 out() << "/**" << std::endl; 1861 out() << " * @hide" << std::endl; 1862 out() << " */" << std::endl; 1863 1864 out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class " 1865 << ClassName; 1866 if (SuperClassName != NULL) 1867 out() << " extends " << SuperClassName; 1868 1869 startBlock(); 1870 1871 mClassName = ClassName; 1872 1873 return true; 1874} 1875 1876void RSReflection::Context::endClass() { 1877 endBlock(); 1878 if (!mUseStdout) 1879 mOF.close(); 1880 clear(); 1881 return; 1882} 1883 1884void RSReflection::Context::startBlock(bool ShouldIndent) { 1885 if (ShouldIndent) 1886 indent() << "{" << std::endl; 1887 else 1888 out() << " {" << std::endl; 1889 incIndentLevel(); 1890 return; 1891} 1892 1893void RSReflection::Context::endBlock() { 1894 decIndentLevel(); 1895 indent() << "}" << std::endl << std::endl; 1896 return; 1897} 1898 1899void RSReflection::Context::startTypeClass(const std::string &ClassName) { 1900 indent() << "public static class " << ClassName; 1901 startBlock(); 1902 return; 1903} 1904 1905void RSReflection::Context::endTypeClass() { 1906 endBlock(); 1907 return; 1908} 1909 1910void RSReflection::Context::startFunction(AccessModifier AM, 1911 bool IsStatic, 1912 const char *ReturnType, 1913 const std::string &FunctionName, 1914 int Argc, ...) { 1915 ArgTy Args; 1916 va_list vl; 1917 va_start(vl, Argc); 1918 1919 for (int i = 0; i < Argc; i++) { 1920 const char *ArgType = va_arg(vl, const char*); 1921 const char *ArgName = va_arg(vl, const char*); 1922 1923 Args.push_back(std::make_pair(ArgType, ArgName)); 1924 } 1925 va_end(vl); 1926 1927 startFunction(AM, IsStatic, ReturnType, FunctionName, Args); 1928 1929 return; 1930} 1931 1932void RSReflection::Context::startFunction(AccessModifier AM, 1933 bool IsStatic, 1934 const char *ReturnType, 1935 const std::string &FunctionName, 1936 const ArgTy &Args) { 1937 indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ") 1938 << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "("; 1939 1940 bool FirstArg = true; 1941 for (ArgTy::const_iterator I = Args.begin(), E = Args.end(); 1942 I != E; 1943 I++) { 1944 if (!FirstArg) 1945 out() << ", "; 1946 else 1947 FirstArg = false; 1948 1949 out() << I->first << " " << I->second; 1950 } 1951 1952 out() << ")"; 1953 startBlock(); 1954 1955 return; 1956} 1957 1958void RSReflection::Context::endFunction() { 1959 endBlock(); 1960 return; 1961} 1962