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