slang_rs_reflection.cpp revision a6d60672695f1438a63acdbf85eae7f97ce2b50d
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::DataTypeUnsigned32: { 125 BaseElement = VectorTypeJavaNameMap[3]; 126 break; 127 } 128 case RSExportPrimitiveType::DataTypeFloat32: { 129 BaseElement = VectorTypeJavaNameMap[4]; 130 break; 131 } 132 default: { 133 assert(false && "RSReflection::genElementTypeName : Unsupported vector " 134 "element data type"); 135 break; 136 } 137 } 138 139 assert((EVT->getNumElement() > 1) && 140 (EVT->getNumElement() <= 4) && 141 "Number of element in vector type is invalid"); 142 143 return BaseElement[EVT->getNumElement() - 2]; 144} 145 146static const char *GetMatrixTypeName(const RSExportMatrixType *EMT) { 147 static const char *MatrixTypeJavaNameMap[] = { 148 /* 2x2 */ "Matrix2f", 149 /* 3x3 */ "Matrix3f", 150 /* 4x4 */ "Matrix4f", 151 }; 152 unsigned Dim = EMT->getDim(); 153 154 if ((Dim - 2) < (sizeof(MatrixTypeJavaNameMap) / sizeof(const char*))) 155 return MatrixTypeJavaNameMap[ EMT->getDim() - 2 ]; 156 157 assert(false && "GetMatrixTypeName : Unsupported matrix dimension"); 158 return NULL; 159} 160 161static const char *GetVectorAccessor(int Index) { 162 static const char *VectorAccessorMap[] = { 163 /* 0 */ "x", 164 /* 1 */ "y", 165 /* 2 */ "z", 166 /* 3 */ "w", 167 }; 168 169 assert((Index >= 0) && 170 (Index < (sizeof(VectorAccessorMap) / sizeof(const char*))) && 171 "Out-of-bound index to access vector member"); 172 173 return VectorAccessorMap[Index]; 174} 175 176static const char *GetPackerAPIName(const RSExportPrimitiveType *EPT) { 177 static const char *PrimitiveTypePackerAPINameMap[] = { 178 "", // RSExportPrimitiveType::DataTypeFloat16 179 "addF32", // RSExportPrimitiveType::DataTypeFloat32 180 "addF64", // RSExportPrimitiveType::DataTypeFloat64 181 "addI8", // RSExportPrimitiveType::DataTypeSigned8 182 "addI16", // RSExportPrimitiveType::DataTypeSigned16 183 "addI32", // RSExportPrimitiveType::DataTypeSigned32 184 "addI64", // RSExportPrimitiveType::DataTypeSigned64 185 "addU8", // RSExportPrimitiveType::DataTypeUnsigned8 186 "addU16", // RSExportPrimitiveType::DataTypeUnsigned16 187 "addU32", // RSExportPrimitiveType::DataTypeUnsigned32 188 "addU64", // RSExportPrimitiveType::DataTypeUnsigned64 189 "addBoolean", // RSExportPrimitiveType::DataTypeBoolean 190 191 "addU16", // RSExportPrimitiveType::DataTypeUnsigned565 192 "addU16", // RSExportPrimitiveType::DataTypeUnsigned5551 193 "addU16", // RSExportPrimitiveType::DataTypeUnsigned4444 194 195 "addObj", // RSExportPrimitiveType::DataTypeRSMatrix2x2 196 "addObj", // RSExportPrimitiveType::DataTypeRSMatrix3x3 197 "addObj", // RSExportPrimitiveType::DataTypeRSMatrix4x4 198 199 "addObj", // RSExportPrimitiveType::DataTypeRSElement 200 "addObj", // RSExportPrimitiveType::DataTypeRSType 201 "addObj", // RSExportPrimitiveType::DataTypeRSAllocation 202 "addObj", // RSExportPrimitiveType::DataTypeRSSampler 203 "addObj", // RSExportPrimitiveType::DataTypeRSScript 204 "addObj", // RSExportPrimitiveType::DataTypeRSMesh 205 "addObj", // RSExportPrimitiveType::DataTypeRSProgramFragment 206 "addObj", // RSExportPrimitiveType::DataTypeRSProgramVertex 207 "addObj", // RSExportPrimitiveType::DataTypeRSProgramRaster 208 "addObj", // RSExportPrimitiveType::DataTypeRSProgramStore 209 "addObj", // RSExportPrimitiveType::DataTypeRSFont 210 }; 211 unsigned TypeId = EPT->getType(); 212 213 if (TypeId < (sizeof(PrimitiveTypePackerAPINameMap) / sizeof(const char*))) 214 return PrimitiveTypePackerAPINameMap[ EPT->getType() ]; 215 216 assert(false && "GetPackerAPIName : Unknown primitive data type"); 217 return NULL; 218} 219 220static std::string GetTypeName(const RSExportType *ET) { 221 switch (ET->getClass()) { 222 case RSExportType::ExportClassPrimitive: { 223 return GetPrimitiveTypeName( 224 static_cast<const RSExportPrimitiveType*>(ET)); 225 } 226 case RSExportType::ExportClassPointer: { 227 const RSExportType *PointeeType = 228 static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 229 230 if (PointeeType->getClass() != RSExportType::ExportClassRecord) 231 return "Allocation"; 232 else 233 return RS_TYPE_CLASS_NAME_PREFIX + PointeeType->getName(); 234 } 235 case RSExportType::ExportClassVector: { 236 return GetVectorTypeName(static_cast<const RSExportVectorType*>(ET)); 237 } 238 case RSExportType::ExportClassMatrix: { 239 return GetMatrixTypeName(static_cast<const RSExportMatrixType*>(ET)); 240 } 241 case RSExportType::ExportClassConstantArray: { 242 const RSExportConstantArrayType* CAT = 243 static_cast<const RSExportConstantArrayType*>(ET); 244 std::string ElementTypeName = GetTypeName(CAT->getElementType()); 245 ElementTypeName.append("[]"); 246 return ElementTypeName; 247 } 248 case RSExportType::ExportClassRecord: { 249 return RS_TYPE_CLASS_NAME_PREFIX + ET->getName() + 250 "."RS_TYPE_ITEM_CLASS_NAME; 251 } 252 default: { 253 assert(false && "Unknown class of type"); 254 } 255 } 256 257 return ""; 258} 259 260static const char *GetTypeNullValue(const RSExportType *ET) { 261 switch (ET->getClass()) { 262 case RSExportType::ExportClassPrimitive: { 263 const RSExportPrimitiveType *EPT = 264 static_cast<const RSExportPrimitiveType*>(ET); 265 if (EPT->isRSObjectType()) 266 return "null"; 267 else if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) 268 return "false"; 269 else 270 return "0"; 271 break; 272 } 273 case RSExportType::ExportClassPointer: 274 case RSExportType::ExportClassVector: 275 case RSExportType::ExportClassMatrix: 276 case RSExportType::ExportClassConstantArray: 277 case RSExportType::ExportClassRecord: { 278 return "null"; 279 break; 280 } 281 default: { 282 assert(false && "Unknown class of type"); 283 } 284 } 285 return ""; 286} 287 288static const char *GetBuiltinElementConstruct(const RSExportType *ET) { 289 if (ET->getClass() == RSExportType::ExportClassPrimitive) { 290 const RSExportPrimitiveType *EPT = 291 static_cast<const RSExportPrimitiveType*>(ET); 292 if (EPT->getKind() == RSExportPrimitiveType::DataKindUser) { 293 static const char *PrimitiveBuiltinElementConstructMap[] = { 294 NULL, // RSExportPrimitiveType::DataTypeFloat16 295 "F32", // RSExportPrimitiveType::DataTypeFloat32 296 "F64", // RSExportPrimitiveType::DataTypeFloat64 297 "I8", // RSExportPrimitiveType::DataTypeSigned8 298 NULL, // RSExportPrimitiveType::DataTypeSigned16 299 "I32", // RSExportPrimitiveType::DataTypeSigned32 300 "I64", // RSExportPrimitiveType::DataTypeSigned64 301 "U8", // RSExportPrimitiveType::DataTypeUnsigned8 302 NULL, // RSExportPrimitiveType::DataTypeUnsigned16 303 "U32", // RSExportPrimitiveType::DataTypeUnsigned32 304 NULL, // RSExportPrimitiveType::DataTypeUnsigned64 305 "BOOLEAN", // RSExportPrimitiveType::DataTypeBoolean 306 307 NULL, // RSExportPrimitiveType::DataTypeUnsigned565 308 NULL, // RSExportPrimitiveType::DataTypeUnsigned5551 309 NULL, // RSExportPrimitiveType::DataTypeUnsigned4444 310 311 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2 312 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3 313 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4 314 315 "ELEMENT", // RSExportPrimitiveType::DataTypeRSElement 316 "TYPE", // RSExportPrimitiveType::DataTypeRSType 317 "ALLOCATION", // RSExportPrimitiveType::DataTypeRSAllocation 318 "SAMPLER", // RSExportPrimitiveType::DataTypeRSSampler 319 "SCRIPT", // RSExportPrimitiveType::DataTypeRSScript 320 "MESH", // RSExportPrimitiveType::DataTypeRSMesh 321 "PROGRAM_FRAGMENT", // RSExportPrimitiveType::DataTypeRSProgramFragment 322 "PROGRAM_VERTEX", // RSExportPrimitiveType::DataTypeRSProgramVertex 323 "PROGRAM_RASTER", // RSExportPrimitiveType::DataTypeRSProgramRaster 324 "PROGRAM_STORE", // RSExportPrimitiveType::DataTypeRSProgramStore 325 "FONT", // RSExportPrimitiveType::DataTypeRSFont 326 }; 327 unsigned TypeId = EPT->getType(); 328 329 if (TypeId < 330 (sizeof(PrimitiveBuiltinElementConstructMap) / sizeof(const char*))) 331 return PrimitiveBuiltinElementConstructMap[ EPT->getType() ]; 332 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelA) { 333 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 334 return "A_8"; 335 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGB) { 336 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned565) 337 return "RGB_565"; 338 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 339 return "RGB_888"; 340 } else if (EPT->getKind() == RSExportPrimitiveType::DataKindPixelRGBA) { 341 if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned5551) 342 return "RGBA_5551"; 343 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned4444) 344 return "RGBA_4444"; 345 else if (EPT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) 346 return "RGBA_8888"; 347 } 348 } else if (ET->getClass() == RSExportType::ExportClassVector) { 349 const RSExportVectorType *EVT = static_cast<const RSExportVectorType*>(ET); 350 if (EVT->getKind() == RSExportPrimitiveType::DataKindUser) { 351 if (EVT->getType() == RSExportPrimitiveType::DataTypeFloat32) { 352 if (EVT->getNumElement() == 2) 353 return "F32_2"; 354 else if (EVT->getNumElement() == 3) 355 return "F32_3"; 356 else if (EVT->getNumElement() == 4) 357 return "F32_4"; 358 } else if (EVT->getType() == RSExportPrimitiveType::DataTypeUnsigned8) { 359 if (EVT->getNumElement() == 4) 360 return "U8_4"; 361 } 362 } 363 } else if (ET->getClass() == RSExportType::ExportClassMatrix) { 364 const RSExportMatrixType *EMT = static_cast<const RSExportMatrixType *>(ET); 365 switch (EMT->getDim()) { 366 case 2: { 367 return "MATRIX_2X2"; 368 break; 369 } 370 case 3: { 371 return "MATRIX_3X3"; 372 break; 373 } 374 case 4: { 375 return "MATRIX_4X4"; 376 break; 377 } 378 default: { 379 assert(false && "Unsupported dimension of matrix"); 380 } 381 } 382 } else if (ET->getClass() == RSExportType::ExportClassPointer) { 383 // Treat pointer type variable as unsigned int 384 // TODO(zonr): this is target dependent 385 return "USER_I32"; 386 } 387 388 return NULL; 389} 390 391static const char *GetElementDataKindName(RSExportPrimitiveType::DataKind DK) { 392 static const char *ElementDataKindNameMap[] = { 393 "Element.DataKind.USER", // RSExportPrimitiveType::DataKindUser 394 "Element.DataKind.PIXEL_L", // RSExportPrimitiveType::DataKindPixelL 395 "Element.DataKind.PIXEL_A", // RSExportPrimitiveType::DataKindPixelA 396 "Element.DataKind.PIXEL_LA", // RSExportPrimitiveType::DataKindPixelLA 397 "Element.DataKind.PIXEL_RGB", // RSExportPrimitiveType::DataKindPixelRGB 398 "Element.DataKind.PIXEL_RGBA", // RSExportPrimitiveType::DataKindPixelRGBA 399 }; 400 401 if (static_cast<unsigned>(DK) < 402 (sizeof(ElementDataKindNameMap) / sizeof(const char*))) 403 return ElementDataKindNameMap[ DK ]; 404 else 405 return NULL; 406} 407 408static const char *GetElementDataTypeName(RSExportPrimitiveType::DataType DT) { 409 static const char *ElementDataTypeNameMap[] = { 410 NULL, // RSExportPrimitiveType::DataTypeFloat16 411 "Element.DataType.FLOAT_32", // RSExportPrimitiveType::DataTypeFloat32 412 "Element.DataType.FLOAT_64", // RSExportPrimitiveType::DataTypeFloat64 413 "Element.DataType.SIGNED_8", // RSExportPrimitiveType::DataTypeSigned8 414 "Element.DataType.SIGNED_16", // RSExportPrimitiveType::DataTypeSigned16 415 "Element.DataType.SIGNED_32", // RSExportPrimitiveType::DataTypeSigned32 416 "Element.DataType.SIGNED_64", // RSExportPrimitiveType::DataTypeSigned64 417 "Element.DataType.UNSIGNED_8", // RSExportPrimitiveType::DataTypeUnsigned8 418 "Element.DataType.UNSIGNED_16", // RSExportPrimitiveType::DataTypeUnsigned16 419 "Element.DataType.UNSIGNED_32", // RSExportPrimitiveType::DataTypeUnsigned32 420 NULL, // RSExportPrimitiveType::DataTypeUnsigned64 421 "Element.DataType.BOOLEAN", // RSExportPrimitiveType::DataTypeBoolean 422 423 // RSExportPrimitiveType::DataTypeUnsigned565 424 "Element.DataType.UNSIGNED_5_6_5", 425 // RSExportPrimitiveType::DataTypeUnsigned5551 426 "Element.DataType.UNSIGNED_5_5_5_1", 427 // RSExportPrimitiveType::DataTypeUnsigned4444 428 "Element.DataType.UNSIGNED_4_4_4_4", 429 430 // DataTypeRSMatrix* must have been resolved in GetBuiltinElementConstruct() 431 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix2x2 432 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix3x3 433 NULL, // (Dummy) RSExportPrimitiveType::DataTypeRSMatrix4x4 434 435 "Element.DataType.RS_ELEMENT", // RSExportPrimitiveType::DataTypeRSElement 436 "Element.DataType.RS_TYPE", // RSExportPrimitiveType::DataTypeRSType 437 // RSExportPrimitiveType::DataTypeRSAllocation 438 "Element.DataType.RS_ALLOCATION", 439 // RSExportPrimitiveType::DataTypeRSSampler 440 "Element.DataType.RS_SAMPLER", 441 // RSExportPrimitiveType::DataTypeRSScript 442 "Element.DataType.RS_SCRIPT", 443 // RSExportPrimitiveType::DataTypeRSMesh 444 "Element.DataType.RS_MESH", 445 // RSExportPrimitiveType::DataTypeRSProgramFragment 446 "Element.DataType.RS_PROGRAM_FRAGMENT", 447 // RSExportPrimitiveType::DataTypeRSProgramVertex 448 "Element.DataType.RS_PROGRAM_VERTEX", 449 // RSExportPrimitiveType::DataTypeRSProgramRaster 450 "Element.DataType.RS_PROGRAM_RASTER", 451 // RSExportPrimitiveType::DataTypeRSProgramStore 452 "Element.DataType.RS_PROGRAM_STORE", 453 // RSExportPrimitiveType::DataTypeRSFont 454 "Element.DataType.RS_FONT", 455 }; 456 457 if (static_cast<unsigned>(DT) < 458 (sizeof(ElementDataTypeNameMap) / sizeof(const char*))) 459 return ElementDataTypeNameMap[ DT ]; 460 else 461 return NULL; 462} 463 464/********************** Methods to generate script class **********************/ 465bool RSReflection::genScriptClass(Context &C, 466 const std::string &ClassName, 467 std::string &ErrorMsg) { 468 if (!C.startClass(Context::AM_Public, 469 false, 470 ClassName, 471 RS_SCRIPT_CLASS_SUPER_CLASS_NAME, 472 ErrorMsg)) 473 return false; 474 475 genScriptClassConstructor(C); 476 477 // Reflect export variable 478 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(), 479 E = mRSContext->export_vars_end(); 480 I != E; 481 I++) 482 genExportVariable(C, *I); 483 484 // Reflect export function 485 for (RSContext::const_export_func_iterator 486 I = mRSContext->export_funcs_begin(), 487 E = mRSContext->export_funcs_end(); 488 I != E; I++) 489 genExportFunction(C, *I); 490 491 C.endClass(); 492 493 return true; 494} 495 496void RSReflection::genScriptClassConstructor(Context &C) { 497 C.indent() << "// Constructor" << std::endl; 498 C.startFunction(Context::AM_Public, 499 false, 500 NULL, 501 C.getClassName(), 502 4, 503 "RenderScript", 504 "rs", 505 "Resources", 506 "resources", 507 "int", 508 "id", 509 "boolean", 510 "isRoot"); 511 // Call constructor of super class 512 C.indent() << "super(rs, resources, id, isRoot);" << std::endl; 513 514 // If an exported variable has initial value, reflect it 515 516 for (RSContext::const_export_var_iterator I = mRSContext->export_vars_begin(), 517 E = mRSContext->export_vars_end(); 518 I != E; 519 I++) { 520 const RSExportVar *EV = *I; 521 if (!EV->getInit().isUninit()) 522 genInitExportVariable(C, EV->getType(), EV->getName(), EV->getInit()); 523 } 524 525 C.endFunction(); 526 return; 527} 528 529void RSReflection::genInitBoolExportVariable(Context &C, 530 const std::string &VarName, 531 const clang::APValue &Val) { 532 assert(!Val.isUninit() && "Not a valid initializer"); 533 534 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "; 535 assert((Val.getKind() == clang::APValue::Int) && 536 "Bool type has wrong initial APValue"); 537 538 C.out() << ((Val.getInt().getSExtValue() == 0) ? "false" : "true") 539 << ";" << std::endl; 540 541 return; 542} 543 544void RSReflection::genInitPrimitiveExportVariable(Context &C, 545 const std::string &VarName, 546 const clang::APValue &Val) { 547 assert(!Val.isUninit() && "Not a valid initializer"); 548 549 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = "; 550 switch (Val.getKind()) { 551 case clang::APValue::Int: { 552 llvm::APInt api = Val.getInt(); 553 C.out() << api.getSExtValue(); 554 if (api.getBitWidth() > 32) { 555 C.out() << "L"; 556 } 557 break; 558 } 559 case clang::APValue::Float: { 560 llvm::APFloat apf = Val.getFloat(); 561 if (&apf.getSemantics() == &llvm::APFloat::IEEEsingle) { 562 C.out() << apf.convertToFloat() << "f"; 563 } else { 564 C.out() << apf.convertToDouble(); 565 } 566 break; 567 } 568 569 case clang::APValue::ComplexInt: 570 case clang::APValue::ComplexFloat: 571 case clang::APValue::LValue: 572 case clang::APValue::Vector: { 573 assert(false && "Primitive type cannot have such kind of initializer"); 574 break; 575 } 576 default: { 577 assert(false && "Unknown kind of initializer"); 578 } 579 } 580 C.out() << ";" << std::endl; 581 582 return; 583} 584 585void RSReflection::genInitExportVariable(Context &C, 586 const RSExportType *ET, 587 const std::string &VarName, 588 const clang::APValue &Val) { 589 assert(!Val.isUninit() && "Not a valid initializer"); 590 591 switch (ET->getClass()) { 592 case RSExportType::ExportClassPrimitive: { 593 const RSExportPrimitiveType *EPT = 594 static_cast<const RSExportPrimitiveType*>(ET); 595 if (EPT->getType() == RSExportPrimitiveType::DataTypeBoolean) { 596 genInitBoolExportVariable(C, VarName, Val); 597 } else { 598 genInitPrimitiveExportVariable(C, VarName, Val); 599 } 600 break; 601 } 602 case RSExportType::ExportClassPointer: { 603 if (!Val.isInt() || Val.getInt().getSExtValue() != 0) 604 std::cout << "Initializer which is non-NULL to pointer type variable " 605 "will be ignored" << std::endl; 606 break; 607 } 608 case RSExportType::ExportClassVector: { 609 const RSExportVectorType *EVT = 610 static_cast<const RSExportVectorType*>(ET); 611 switch (Val.getKind()) { 612 case clang::APValue::Int: 613 case clang::APValue::Float: { 614 for (unsigned i = 0; i < EVT->getNumElement(); i++) { 615 std::string Name = VarName + "." + GetVectorAccessor(i); 616 genInitPrimitiveExportVariable(C, Name, Val); 617 } 618 break; 619 } 620 case clang::APValue::Vector: { 621 C.indent() << RS_EXPORT_VAR_PREFIX << VarName << " = new " 622 << GetVectorTypeName(EVT) << "();" << std::endl; 623 624 unsigned NumElements = 625 std::min(static_cast<unsigned>(EVT->getNumElement()), 626 Val.getVectorLength()); 627 for (unsigned i = 0; i < NumElements; i++) { 628 const clang::APValue &ElementVal = Val.getVectorElt(i); 629 std::string Name = VarName + "." + GetVectorAccessor(i); 630 genInitPrimitiveExportVariable(C, Name, ElementVal); 631 } 632 break; 633 } 634 case clang::APValue::Uninitialized: 635 case clang::APValue::ComplexInt: 636 case clang::APValue::ComplexFloat: 637 case clang::APValue::LValue: { 638 assert(false && "Unexpected type of value of initializer."); 639 } 640 } 641 break; 642 } 643 // TODO(zonr): Resolving initializer of a record (and matrix) type variable 644 // is complex. It cannot obtain by just simply evaluating the initializer 645 // expression. 646 case RSExportType::ExportClassMatrix: 647 case RSExportType::ExportClassConstantArray: 648 case RSExportType::ExportClassRecord: { 649#if 0 650 unsigned InitIndex = 0; 651 const RSExportRecordType *ERT = 652 static_cast<const RSExportRecordType*>(ET); 653 654 assert((Val.getKind() == clang::APValue::Vector) && "Unexpected type of " 655 "initializer for record type variable"); 656 657 C.indent() << RS_EXPORT_VAR_PREFIX << VarName 658 << " = new "RS_TYPE_CLASS_NAME_PREFIX << ERT->getName() 659 << "."RS_TYPE_ITEM_CLASS_NAME"();" << std::endl; 660 661 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(), 662 E = ERT->fields_end(); 663 I != E; 664 I++) { 665 const RSExportRecordType::Field *F = *I; 666 std::string FieldName = VarName + "." + F->getName(); 667 668 if (InitIndex > Val.getVectorLength()) 669 break; 670 671 genInitPrimitiveExportVariable(C, 672 FieldName, 673 Val.getVectorElt(InitIndex++)); 674 } 675#endif 676 assert(false && "Unsupported initializer for record/matrix/constant " 677 "array type variable currently"); 678 break; 679 } 680 default: { 681 assert(false && "Unknown class of type"); 682 } 683 } 684 return; 685} 686 687void RSReflection::genExportVariable(Context &C, const RSExportVar *EV) { 688 const RSExportType *ET = EV->getType(); 689 690 C.indent() << "private final static int "RS_EXPORT_VAR_INDEX_PREFIX 691 << EV->getName() << " = " << C.getNextExportVarSlot() << ";" 692 << std::endl; 693 694 switch (ET->getClass()) { 695 case RSExportType::ExportClassPrimitive: { 696 genPrimitiveTypeExportVariable(C, EV); 697 break; 698 } 699 case RSExportType::ExportClassPointer: { 700 genPointerTypeExportVariable(C, EV); 701 break; 702 } 703 case RSExportType::ExportClassVector: { 704 genVectorTypeExportVariable(C, EV); 705 break; 706 } 707 case RSExportType::ExportClassMatrix: { 708 genMatrixTypeExportVariable(C, EV); 709 break; 710 } 711 case RSExportType::ExportClassConstantArray: { 712 genConstantArrayTypeExportVariable(C, EV); 713 break; 714 } 715 case RSExportType::ExportClassRecord: { 716 genRecordTypeExportVariable(C, EV); 717 break; 718 } 719 default: { 720 assert(false && "Unknown class of type"); 721 } 722 } 723 724 return; 725} 726 727void RSReflection::genExportFunction(Context &C, const RSExportFunc *EF) { 728 C.indent() << "private final static int "RS_EXPORT_FUNC_INDEX_PREFIX 729 << EF->getName() << " = " << C.getNextExportFuncSlot() << ";" 730 << std::endl; 731 732 // invoke_*() 733 Context::ArgTy Args; 734 735 if (EF->hasParam()) { 736 for (RSExportFunc::const_param_iterator I = EF->params_begin(), 737 E = EF->params_end(); 738 I != E; 739 I++) { 740 Args.push_back(std::make_pair(GetTypeName((*I)->getType()), 741 (*I)->getName())); 742 } 743 } 744 745 C.startFunction(Context::AM_Public, 746 false, 747 "void", 748 "invoke_" + EF->getName(), 749 Args); 750 751 if (!EF->hasParam()) { 752 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ");" 753 << std::endl; 754 } else { 755 const RSExportRecordType *ERT = EF->getParamPacketType(); 756 std::string FieldPackerName = EF->getName() + "_fp"; 757 758 if (genCreateFieldPacker(C, ERT, FieldPackerName.c_str())) 759 genPackVarOfType(C, ERT, NULL, FieldPackerName.c_str()); 760 761 C.indent() << "invoke("RS_EXPORT_FUNC_INDEX_PREFIX << EF->getName() << ", " 762 << FieldPackerName << ");" << std::endl; 763 } 764 765 C.endFunction(); 766 return; 767} 768 769void RSReflection::genPrimitiveTypeExportVariable(Context &C, 770 const RSExportVar *EV) { 771 assert((EV->getType()->getClass() == RSExportType::ExportClassPrimitive) && 772 "Variable should be type of primitive here"); 773 774 const RSExportPrimitiveType *EPT = 775 static_cast<const RSExportPrimitiveType*>(EV->getType()); 776 const char *TypeName = GetPrimitiveTypeName(EPT); 777 778 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 779 << EV->getName() << ";" << std::endl; 780 781 // set_*() 782 if (!EV->isConst()) { 783 C.startFunction(Context::AM_Public, 784 false, 785 "void", 786 "set_" + EV->getName(), 787 1, 788 TypeName, 789 "v"); 790 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 791 792 if (EPT->isRSObjectType()) 793 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() 794 << ", (v == null) ? 0 : v.getID());" << std::endl; 795 else 796 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() 797 << ", v);" << std::endl; 798 799 C.endFunction(); 800 } 801 802 genGetExportVariable(C, TypeName, EV->getName()); 803 804 return; 805} 806 807void RSReflection::genPointerTypeExportVariable(Context &C, 808 const RSExportVar *EV) { 809 const RSExportType *ET = EV->getType(); 810 const RSExportType *PointeeType; 811 std::string TypeName; 812 813 assert((ET->getClass() == RSExportType::ExportClassPointer) && 814 "Variable should be type of pointer here"); 815 816 PointeeType = static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 817 TypeName = GetTypeName(ET); 818 819 // bind_*() 820 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 821 << EV->getName() << ";" << std::endl; 822 823 C.startFunction(Context::AM_Public, 824 false, 825 "void", 826 "bind_" + EV->getName(), 827 1, 828 TypeName.c_str(), 829 "v"); 830 831 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 832 C.indent() << "if (v == null) bindAllocation(null, "RS_EXPORT_VAR_INDEX_PREFIX 833 << EV->getName() << ");" << std::endl; 834 835 if (PointeeType->getClass() == RSExportType::ExportClassRecord) 836 C.indent() << "else bindAllocation(v.getAllocation(), " 837 RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ");" 838 << std::endl; 839 else 840 C.indent() << "else bindAllocation(v, "RS_EXPORT_VAR_INDEX_PREFIX 841 << EV->getName() << ");" << std::endl; 842 843 C.endFunction(); 844 845 genGetExportVariable(C, TypeName, EV->getName()); 846 847 return; 848} 849 850void RSReflection::genVectorTypeExportVariable(Context &C, 851 const RSExportVar *EV) { 852 assert((EV->getType()->getClass() == RSExportType::ExportClassVector) && 853 "Variable should be type of vector here"); 854 855 const RSExportVectorType *EVT = 856 static_cast<const RSExportVectorType*>(EV->getType()); 857 const char *TypeName = GetVectorTypeName(EVT); 858 const char *FieldPackerName = "fp"; 859 860 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 861 << EV->getName() << ";" << std::endl; 862 863 // set_*() 864 if (!EV->isConst()) { 865 C.startFunction(Context::AM_Public, 866 false, 867 "void", 868 "set_" + EV->getName(), 869 1, 870 TypeName, 871 "v"); 872 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 873 874 if (genCreateFieldPacker(C, EVT, FieldPackerName)) 875 genPackVarOfType(C, EVT, "v", FieldPackerName); 876 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " 877 << FieldPackerName << ");" << std::endl; 878 879 C.endFunction(); 880 } 881 882 genGetExportVariable(C, TypeName, EV->getName()); 883 return; 884} 885 886void RSReflection::genMatrixTypeExportVariable(Context &C, 887 const RSExportVar *EV) { 888 assert((EV->getType()->getClass() == RSExportType::ExportClassMatrix) && 889 "Variable should be type of matrix here"); 890 891 const RSExportMatrixType *EMT = 892 static_cast<const RSExportMatrixType*>(EV->getType()); 893 const char *TypeName = GetMatrixTypeName(EMT); 894 const char *FieldPackerName = "fp"; 895 896 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 897 << EV->getName() << ";" << std::endl; 898 899 // set_*() 900 if (!EV->isConst()) { 901 C.startFunction(Context::AM_Public, 902 false, 903 "void", 904 "set_" + EV->getName(), 905 1, 906 TypeName, "v"); 907 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 908 909 if (genCreateFieldPacker(C, EMT, FieldPackerName)) 910 genPackVarOfType(C, EMT, "v", FieldPackerName); 911 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " 912 << FieldPackerName << ");" << std::endl; 913 914 C.endFunction(); 915 } 916 917 genGetExportVariable(C, TypeName, EV->getName()); 918 return; 919} 920 921void RSReflection::genConstantArrayTypeExportVariable(Context &C, 922 const RSExportVar *EV) { 923 assert((EV->getType()->getClass() == RSExportType::ExportClassConstantArray)&& 924 "Variable should be type of constant array here"); 925 926 const RSExportConstantArrayType *ECAT = 927 static_cast<const RSExportConstantArrayType*>(EV->getType()); 928 std::string TypeName = GetTypeName(ECAT); 929 const char *FieldPackerName = "fp"; 930 931 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 932 << EV->getName() << ";" << std::endl; 933 934 // set_*() 935 if (!EV->isConst()) { 936 C.startFunction(Context::AM_Public, 937 false, 938 "void", 939 "set_" + EV->getName(), 940 1, 941 TypeName.c_str(), "v"); 942 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 943 944 if (genCreateFieldPacker(C, ECAT, FieldPackerName)) 945 genPackVarOfType(C, ECAT, "v", FieldPackerName); 946 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() << ", " 947 << FieldPackerName << ");" << std::endl; 948 949 C.endFunction(); 950 } 951 952 genGetExportVariable(C, TypeName, EV->getName()); 953 return; 954} 955 956void RSReflection::genRecordTypeExportVariable(Context &C, 957 const RSExportVar *EV) { 958 assert((EV->getType()->getClass() == RSExportType::ExportClassRecord) && 959 "Variable should be type of struct here"); 960 961 const RSExportRecordType *ERT = 962 static_cast<const RSExportRecordType*>(EV->getType()); 963 std::string TypeName = 964 RS_TYPE_CLASS_NAME_PREFIX + ERT->getName() + "."RS_TYPE_ITEM_CLASS_NAME; 965 const char *FieldPackerName = "fp"; 966 967 C.indent() << "private " << TypeName << " "RS_EXPORT_VAR_PREFIX 968 << EV->getName() << ";" << std::endl; 969 970 // set_*() 971 if (!EV->isConst()) { 972 C.startFunction(Context::AM_Public, 973 false, 974 "void", 975 "set_" + EV->getName(), 976 1, 977 TypeName.c_str(), 978 "v"); 979 C.indent() << RS_EXPORT_VAR_PREFIX << EV->getName() << " = v;" << std::endl; 980 981 if (genCreateFieldPacker(C, ERT, FieldPackerName)) 982 genPackVarOfType(C, ERT, "v", FieldPackerName); 983 C.indent() << "setVar("RS_EXPORT_VAR_INDEX_PREFIX << EV->getName() 984 << ", " << FieldPackerName << ");" << std::endl; 985 986 C.endFunction(); 987 } 988 989 genGetExportVariable(C, TypeName.c_str(), EV->getName()); 990 return; 991} 992 993void RSReflection::genGetExportVariable(Context &C, 994 const std::string &TypeName, 995 const std::string &VarName) { 996 C.startFunction(Context::AM_Public, 997 false, 998 TypeName.c_str(), 999 "get_" + VarName, 1000 0); 1001 1002 C.indent() << "return "RS_EXPORT_VAR_PREFIX << VarName << ";" << std::endl; 1003 1004 C.endFunction(); 1005 return; 1006} 1007 1008/******************* Methods to generate script class /end *******************/ 1009 1010bool RSReflection::genCreateFieldPacker(Context &C, 1011 const RSExportType *ET, 1012 const char *FieldPackerName) { 1013 size_t AllocSize = RSExportType::GetTypeAllocSize(ET); 1014 if (AllocSize > 0) 1015 C.indent() << "FieldPacker " << FieldPackerName << " = new FieldPacker(" 1016 << AllocSize << ");" << std::endl; 1017 else 1018 return false; 1019 return true; 1020} 1021 1022void RSReflection::genPackVarOfType(Context &C, 1023 const RSExportType *ET, 1024 const char *VarName, 1025 const char *FieldPackerName) { 1026 switch (ET->getClass()) { 1027 case RSExportType::ExportClassPrimitive: 1028 case RSExportType::ExportClassVector: { 1029 C.indent() << FieldPackerName << "." 1030 << GetPackerAPIName( 1031 static_cast<const RSExportPrimitiveType*>(ET)) 1032 << "(" << VarName << ");" << std::endl; 1033 break; 1034 } 1035 case RSExportType::ExportClassPointer: { 1036 // Must reflect as type Allocation in Java 1037 const RSExportType *PointeeType = 1038 static_cast<const RSExportPointerType*>(ET)->getPointeeType(); 1039 1040 if (PointeeType->getClass() != RSExportType::ExportClassRecord) 1041 C.indent() << FieldPackerName << ".addI32(" << VarName 1042 << ".getPtr());" << std::endl; 1043 else 1044 C.indent() << FieldPackerName << ".addI32(" << VarName 1045 << ".getAllocation().getPtr());" << std::endl; 1046 break; 1047 } 1048 case RSExportType::ExportClassMatrix: { 1049 C.indent() << FieldPackerName << ".addObj(" << VarName << ");" 1050 << std::endl; 1051 break; 1052 } 1053 case RSExportType::ExportClassConstantArray: { 1054 const RSExportConstantArrayType *ECAT = 1055 static_cast<const RSExportConstantArrayType *>(ET); 1056 C.indent() << "for (int ct = 0; ct < " << ECAT->getSize() << "; ct++)"; 1057 C.startBlock(); 1058 1059 std::string ElementVarName(VarName); 1060 ElementVarName.append("[ct]"); 1061 genPackVarOfType(C, ECAT->getElementType(), ElementVarName.c_str(), 1062 FieldPackerName); 1063 1064 C.endBlock(); 1065 break; 1066 } 1067 case RSExportType::ExportClassRecord: { 1068 const RSExportRecordType *ERT = 1069 static_cast<const RSExportRecordType*>(ET); 1070 // Relative pos from now on in field packer 1071 unsigned Pos = 0; 1072 1073 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(), 1074 E = ERT->fields_end(); 1075 I != E; 1076 I++) { 1077 const RSExportRecordType::Field *F = *I; 1078 std::string FieldName; 1079 size_t FieldOffset = F->getOffsetInParent(); 1080 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1081 size_t FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 1082 1083 if (VarName != NULL) 1084 FieldName = VarName + ("." + F->getName()); 1085 else 1086 FieldName = F->getName(); 1087 1088 if (FieldOffset > Pos) 1089 C.indent() << FieldPackerName << ".skip(" 1090 << (FieldOffset - Pos) << ");" << std::endl; 1091 1092 genPackVarOfType(C, F->getType(), FieldName.c_str(), FieldPackerName); 1093 1094 // There is padding in the field type 1095 if (FieldAllocSize > FieldStoreSize) 1096 C.indent() << FieldPackerName << ".skip(" 1097 << (FieldAllocSize - FieldStoreSize) 1098 << ");" << std::endl; 1099 1100 Pos = FieldOffset + FieldAllocSize; 1101 } 1102 1103 // There maybe some padding after the struct 1104 size_t Padding = RSExportType::GetTypeAllocSize(ERT) - Pos; 1105 if (Padding > 0) 1106 C.indent() << FieldPackerName << ".skip(" << Padding << ");" 1107 << std::endl; 1108 break; 1109 } 1110 default: { 1111 assert(false && "Unknown class of type"); 1112 } 1113 } 1114 1115 return; 1116} 1117 1118void RSReflection::genAllocateVarOfType(Context &C, 1119 const RSExportType *T, 1120 const std::string &VarName) { 1121 switch (T->getClass()) { 1122 case RSExportType::ExportClassPrimitive: { 1123 // Primitive type like int in Java has its own storage once it's declared. 1124 // 1125 // FIXME: Should we allocate storage for RS object? 1126 // if (static_cast<const RSExportPrimitiveType *>(T)->isRSObjectType()) 1127 // C.indent() << VarName << " = new " << GetTypeName(T) << "();" 1128 // << std::endl; 1129 break; 1130 } 1131 case RSExportType::ExportClassPointer: { 1132 // Pointer type is an instance of Allocation or a TypeClass whose value is 1133 // expected to be assigned by programmer later in Java program. Therefore 1134 // we don't reflect things like [VarName] = new Allocation(); 1135 C.indent() << VarName << " = null;" << std::endl; 1136 break; 1137 } 1138 case RSExportType::ExportClassConstantArray: { 1139 const RSExportConstantArrayType *ECAT = 1140 static_cast<const RSExportConstantArrayType *>(T); 1141 const RSExportType *ElementType = ECAT->getElementType(); 1142 1143 // Primitive type element doesn't need allocation code. 1144 if (ElementType->getClass() != RSExportType::ExportClassPrimitive) { 1145 C.indent() << VarName << " = new " << GetTypeName(ElementType) 1146 << "[" << ECAT->getSize() << "];" << std::endl; 1147 1148 C.indent() << "for (int $ct = 0; $ct < " << ECAT->getSize() << "; " 1149 "$ct++)"; 1150 C.startBlock(); 1151 1152 std::string ElementVarName(VarName); 1153 ElementVarName.append("[$ct]"); 1154 genAllocateVarOfType(C, ElementType, ElementVarName); 1155 1156 C.endBlock(); 1157 } 1158 break; 1159 } 1160 case RSExportType::ExportClassVector: 1161 case RSExportType::ExportClassMatrix: 1162 case RSExportType::ExportClassRecord: { 1163 C.indent() << VarName << " = new " << GetTypeName(T) << "();" 1164 << std::endl; 1165 break; 1166 } 1167 } 1168 return; 1169} 1170 1171void RSReflection::genNewItemBufferIfNull(Context &C, const char *Index) { 1172 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) " 1173 RS_TYPE_ITEM_BUFFER_NAME" = " 1174 "new "RS_TYPE_ITEM_CLASS_NAME"[mType.getX() /* count */];" 1175 << std::endl; 1176 if (Index != NULL) 1177 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] == null) " 1178 RS_TYPE_ITEM_BUFFER_NAME"[" << Index << "] = " 1179 "new "RS_TYPE_ITEM_CLASS_NAME"();" << std::endl; 1180 return; 1181} 1182 1183void RSReflection::genNewItemBufferPackerIfNull(Context &C) { 1184 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_PACKER_NAME" == null) " 1185 RS_TYPE_ITEM_BUFFER_PACKER_NAME" = " 1186 "new FieldPacker(" 1187 RS_TYPE_ITEM_CLASS_NAME".sizeof * mType.getX()/* count */" 1188 ");" << std::endl; 1189 return; 1190} 1191 1192/********************** Methods to generate type class **********************/ 1193bool RSReflection::genTypeClass(Context &C, 1194 const RSExportRecordType *ERT, 1195 std::string &ErrorMsg) { 1196 std::string ClassName = RS_TYPE_CLASS_NAME_PREFIX + ERT->getName(); 1197 1198 if (!C.startClass(Context::AM_Public, 1199 false, 1200 ClassName, 1201 RS_TYPE_CLASS_SUPER_CLASS_NAME, 1202 ErrorMsg)) 1203 return false; 1204 1205 genTypeItemClass(C, ERT); 1206 1207 // Declare item buffer and item buffer packer 1208 C.indent() << "private "RS_TYPE_ITEM_CLASS_NAME" "RS_TYPE_ITEM_BUFFER_NAME"[]" 1209 ";" << std::endl; 1210 C.indent() << "private FieldPacker "RS_TYPE_ITEM_BUFFER_PACKER_NAME";" 1211 << std::endl; 1212 1213 genTypeClassConstructor(C, ERT); 1214 genTypeClassCopyToArray(C, ERT); 1215 genTypeClassItemSetter(C, ERT); 1216 genTypeClassItemGetter(C, ERT); 1217 genTypeClassComponentSetter(C, ERT); 1218 genTypeClassComponentGetter(C, ERT); 1219 genTypeClassCopyAll(C, ERT); 1220 1221 C.endClass(); 1222 1223 C.resetFieldIndex(); 1224 C.clearFieldIndexMap(); 1225 1226 return true; 1227} 1228 1229void RSReflection::genTypeItemClass(Context &C, const RSExportRecordType *ERT) { 1230 C.indent() << "static public class "RS_TYPE_ITEM_CLASS_NAME; 1231 C.startBlock(); 1232 1233 C.indent() << "public static final int sizeof = " 1234 << RSExportType::GetTypeAllocSize(ERT) << ";" << std::endl; 1235 1236 // Member elements 1237 C.out() << std::endl; 1238 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 1239 FE = ERT->fields_end(); 1240 FI != FE; 1241 FI++) { 1242 C.indent() << GetTypeName((*FI)->getType()) << " " << (*FI)->getName() 1243 << ";" << std::endl; 1244 } 1245 1246 // Constructor 1247 C.out() << std::endl; 1248 C.indent() << RS_TYPE_ITEM_CLASS_NAME"()"; 1249 C.startBlock(); 1250 1251 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 1252 FE = ERT->fields_end(); 1253 FI != FE; 1254 FI++) { 1255 const RSExportRecordType::Field *F = *FI; 1256 genAllocateVarOfType(C, F->getType(), F->getName()); 1257 } 1258 1259 // end Constructor 1260 C.endBlock(); 1261 1262 // end Item class 1263 C.endBlock(); 1264 1265 return; 1266} 1267 1268void RSReflection::genTypeClassConstructor(Context &C, 1269 const RSExportRecordType *ERT) { 1270 const char *RenderScriptVar = "rs"; 1271 1272 C.startFunction(Context::AM_Public, 1273 true, 1274 "Element", 1275 "createElement", 1276 1, 1277 "RenderScript", 1278 RenderScriptVar); 1279 genBuildElement(C, ERT, RenderScriptVar); 1280 C.endFunction(); 1281 1282 C.startFunction(Context::AM_Public, 1283 false, 1284 NULL, 1285 C.getClassName(), 1286 2, 1287 "RenderScript", 1288 RenderScriptVar, 1289 "int", 1290 "count"); 1291 1292 C.indent() << RS_TYPE_ITEM_BUFFER_NAME" = null;" << std::endl; 1293 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME" = null;" << std::endl; 1294 C.indent() << "mElement = createElement(" << RenderScriptVar << ");" 1295 << std::endl; 1296 // Call init() in super class 1297 C.indent() << "init(" << RenderScriptVar << ", count);" << std::endl; 1298 C.endFunction(); 1299 1300 return; 1301} 1302 1303void RSReflection::genTypeClassCopyToArray(Context &C, 1304 const RSExportRecordType *ERT) { 1305 C.startFunction(Context::AM_Private, 1306 false, 1307 "void", 1308 "copyToArray", 1309 2, 1310 RS_TYPE_ITEM_CLASS_NAME, 1311 "i", 1312 "int", 1313 "index"); 1314 1315 genNewItemBufferPackerIfNull(C); 1316 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME 1317 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" 1318 << std::endl; 1319 1320 genPackVarOfType(C, ERT, "i", RS_TYPE_ITEM_BUFFER_PACKER_NAME); 1321 1322 C.endFunction(); 1323 return; 1324} 1325 1326void RSReflection::genTypeClassItemSetter(Context &C, 1327 const RSExportRecordType *ERT) { 1328 C.startFunction(Context::AM_Public, 1329 false, 1330 "void", 1331 "set", 1332 3, 1333 RS_TYPE_ITEM_CLASS_NAME, 1334 "i", 1335 "int", 1336 "index", 1337 "boolean", 1338 "copyNow"); 1339 genNewItemBufferIfNull(C, NULL); 1340 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index] = i;" << std::endl; 1341 1342 C.indent() << "if (copyNow) "; 1343 C.startBlock(); 1344 1345 C.indent() << "copyToArray(i, index);" << std::endl; 1346 C.indent() << "mAllocation.subData1D(index, 1, " 1347 RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" << std::endl; 1348 1349 // End of if (copyNow) 1350 C.endBlock(); 1351 1352 C.endFunction(); 1353 return; 1354} 1355 1356void RSReflection::genTypeClassItemGetter(Context &C, 1357 const RSExportRecordType *ERT) { 1358 C.startFunction(Context::AM_Public, 1359 false, 1360 RS_TYPE_ITEM_CLASS_NAME, 1361 "get", 1362 1, 1363 "int", 1364 "index"); 1365 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return null;" 1366 << std::endl; 1367 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index];" << std::endl; 1368 C.endFunction(); 1369 return; 1370} 1371 1372void RSReflection::genTypeClassComponentSetter(Context &C, 1373 const RSExportRecordType *ERT) { 1374 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 1375 FE = ERT->fields_end(); 1376 FI != FE; 1377 FI++) { 1378 const RSExportRecordType::Field *F = *FI; 1379 size_t FieldOffset = F->getOffsetInParent(); 1380 size_t FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1381 unsigned FieldIndex = C.getFieldIndex(F); 1382 1383 C.startFunction(Context::AM_Public, 1384 false, 1385 "void", 1386 "set_" + F->getName(), 3, 1387 "int", 1388 "index", 1389 GetTypeName(F->getType()).c_str(), 1390 "v", 1391 "boolean", 1392 "copyNow"); 1393 genNewItemBufferPackerIfNull(C); 1394 genNewItemBufferIfNull(C, "index"); 1395 C.indent() << RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName() 1396 << " = v;" << std::endl; 1397 1398 C.indent() << "if (copyNow) "; 1399 C.startBlock(); 1400 1401 if (FieldOffset > 0) 1402 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME 1403 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof + " 1404 << FieldOffset << ");" << std::endl; 1405 else 1406 C.indent() << RS_TYPE_ITEM_BUFFER_PACKER_NAME 1407 ".reset(index * "RS_TYPE_ITEM_CLASS_NAME".sizeof);" 1408 << std::endl; 1409 genPackVarOfType(C, F->getType(), "v", RS_TYPE_ITEM_BUFFER_PACKER_NAME); 1410 1411 C.indent() << "FieldPacker fp = new FieldPacker(" << FieldStoreSize << ");" 1412 << std::endl; 1413 genPackVarOfType(C, F->getType(), "v", "fp"); 1414 C.indent() << "mAllocation.subElementData(index, " << FieldIndex << ", fp);" 1415 << std::endl; 1416 1417 // End of if (copyNow) 1418 C.endBlock(); 1419 1420 C.endFunction(); 1421 } 1422 return; 1423} 1424 1425void RSReflection::genTypeClassComponentGetter(Context &C, 1426 const RSExportRecordType *ERT) { 1427 for (RSExportRecordType::const_field_iterator FI = ERT->fields_begin(), 1428 FE = ERT->fields_end(); 1429 FI != FE; 1430 FI++) { 1431 const RSExportRecordType::Field *F = *FI; 1432 C.startFunction(Context::AM_Public, 1433 false, 1434 GetTypeName(F->getType()).c_str(), 1435 "get_" + F->getName(), 1436 1, 1437 "int", 1438 "index"); 1439 C.indent() << "if ("RS_TYPE_ITEM_BUFFER_NAME" == null) return " 1440 << GetTypeNullValue(F->getType()) << ";" << std::endl; 1441 C.indent() << "return "RS_TYPE_ITEM_BUFFER_NAME"[index]." << F->getName() 1442 << ";" << std::endl; 1443 C.endFunction(); 1444 } 1445 return; 1446} 1447 1448void RSReflection::genTypeClassCopyAll(Context &C, 1449 const RSExportRecordType *ERT) { 1450 C.startFunction(Context::AM_Public, false, "void", "copyAll", 0); 1451 1452 C.indent() << "for (int ct = 0; ct < "RS_TYPE_ITEM_BUFFER_NAME".length; ct++)" 1453 " copyToArray("RS_TYPE_ITEM_BUFFER_NAME"[ct], ct);" 1454 << std::endl; 1455 C.indent() << "mAllocation.data("RS_TYPE_ITEM_BUFFER_PACKER_NAME".getData());" 1456 << std::endl; 1457 1458 C.endFunction(); 1459 return; 1460} 1461 1462/******************** Methods to generate type class /end ********************/ 1463 1464/********** Methods to create Element in Java of given record type ***********/ 1465void RSReflection::genBuildElement(Context &C, const RSExportRecordType *ERT, 1466 const char *RenderScriptVar) { 1467 const char *ElementBuilderName = "eb"; 1468 1469 // Create element builder 1470 // C.startBlock(true); 1471 1472 C.indent() << "Element.Builder " << ElementBuilderName << " = " 1473 "new Element.Builder(" << RenderScriptVar << ");" << std::endl; 1474 1475 // eb.add(...) 1476 genAddElementToElementBuilder(C, 1477 ERT, 1478 "", 1479 ElementBuilderName, 1480 RenderScriptVar); 1481 1482 C.indent() << "return " << ElementBuilderName << ".create();" << std::endl; 1483 1484 // C.endBlock(); 1485 return; 1486} 1487 1488#define EB_ADD(x) \ 1489 C.indent() << ElementBuilderName \ 1490 << ".add(Element." << x << ", \"" << VarName << "\");" \ 1491 << std::endl; \ 1492 C.incFieldIndex() 1493 1494void RSReflection::genAddElementToElementBuilder(Context &C, 1495 const RSExportType *ET, 1496 const std::string &VarName, 1497 const char *ElementBuilderName, 1498 const char *RenderScriptVar) { 1499 const char *ElementConstruct = GetBuiltinElementConstruct(ET); 1500 1501 if (ElementConstruct != NULL) { 1502 EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")"); 1503 } else { 1504 if ((ET->getClass() == RSExportType::ExportClassPrimitive) || 1505 (ET->getClass() == RSExportType::ExportClassVector)) { 1506 const RSExportPrimitiveType *EPT = 1507 static_cast<const RSExportPrimitiveType*>(ET); 1508 const char *DataKindName = GetElementDataKindName(EPT->getKind()); 1509 const char *DataTypeName = GetElementDataTypeName(EPT->getType()); 1510 int Size = (ET->getClass() == RSExportType::ExportClassVector) ? 1511 static_cast<const RSExportVectorType*>(ET)->getNumElement() : 1512 1; 1513 1514 switch (EPT->getKind()) { 1515 case RSExportPrimitiveType::DataKindPixelL: 1516 case RSExportPrimitiveType::DataKindPixelA: 1517 case RSExportPrimitiveType::DataKindPixelLA: 1518 case RSExportPrimitiveType::DataKindPixelRGB: 1519 case RSExportPrimitiveType::DataKindPixelRGBA: { 1520 // Element.createPixel() 1521 EB_ADD("createPixel(" << RenderScriptVar << ", " 1522 << DataTypeName << ", " 1523 << DataKindName << ")"); 1524 break; 1525 } 1526 case RSExportPrimitiveType::DataKindUser: 1527 default: { 1528 if (EPT->getClass() == RSExportType::ExportClassPrimitive) { 1529 // Element.createUser() 1530 EB_ADD("createUser(" << RenderScriptVar << ", " 1531 << DataTypeName << ")"); 1532 } else { 1533 assert((ET->getClass() == RSExportType::ExportClassVector) && 1534 "Unexpected type."); 1535 EB_ADD("createVector(" << RenderScriptVar << ", " 1536 << DataTypeName << ", " 1537 << Size << ")"); 1538 } 1539 break; 1540 } 1541 } 1542#ifndef NDEBUG 1543 } else if (ET->getClass() == RSExportType::ExportClassPointer) { 1544 // Pointer type variable should be resolved in 1545 // GetBuiltinElementConstruct() 1546 assert(false && "??"); 1547 } else if (ET->getClass() == RSExportType::ExportClassMatrix) { 1548 // Matrix type variable should be resolved 1549 // in GetBuiltinElementConstruct() 1550 assert(false && "??"); 1551#endif 1552 } else if (ET->getClass() == RSExportType::ExportClassConstantArray) { 1553 const RSExportConstantArrayType *ECAT = 1554 static_cast<const RSExportConstantArrayType *>(ET); 1555 C.indent() << "for (int ct = 0; ct < " << ECAT->getSize() << "; ct++)"; 1556 C.startBlock(); 1557 1558 std::string ElementVarName(VarName); 1559 ElementVarName.append("[\" + ct + \"]"); 1560 genAddElementToElementBuilder(C, 1561 ECAT->getElementType(), 1562 ElementVarName, 1563 ElementBuilderName, 1564 RenderScriptVar); 1565 1566 C.endBlock(); 1567 } else if (ET->getClass() == RSExportType::ExportClassRecord) { 1568 // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType. 1569 // 1570 // TODO(zonr): Generalize these two function such that there's no 1571 // duplicated codes. 1572 const RSExportRecordType *ERT = 1573 static_cast<const RSExportRecordType*>(ET); 1574 int Pos = 0; // relative pos from now on 1575 1576 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(), 1577 E = ERT->fields_end(); 1578 I != E; 1579 I++) { 1580 const RSExportRecordType::Field *F = *I; 1581 std::string FieldName; 1582 int FieldOffset = F->getOffsetInParent(); 1583 int FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1584 int FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 1585 1586 if (!VarName.empty()) 1587 FieldName = VarName + "." + F->getName(); 1588 else 1589 FieldName = F->getName(); 1590 1591 // Alignment 1592 genAddPaddingToElementBuiler(C, 1593 (FieldOffset - Pos), 1594 ElementBuilderName, 1595 RenderScriptVar); 1596 1597 // eb.add(...) 1598 C.addFieldIndexMapping(F); 1599 genAddElementToElementBuilder(C, 1600 F->getType(), 1601 FieldName, 1602 ElementBuilderName, 1603 RenderScriptVar); 1604 1605 // There is padding within the field type 1606 genAddPaddingToElementBuiler(C, 1607 (FieldAllocSize - FieldStoreSize), 1608 ElementBuilderName, 1609 RenderScriptVar); 1610 1611 Pos = FieldOffset + FieldAllocSize; 1612 } 1613 1614 // There maybe some padding after the struct 1615 //unsigned char align = RSExportType::GetTypeAlignment(ERT); 1616 //size_t siz = RSExportType::GetTypeAllocSize(ERT); 1617 size_t siz1 = RSExportType::GetTypeStoreSize(ERT); 1618 1619 genAddPaddingToElementBuiler(C, 1620 siz1 - Pos, 1621 ElementBuilderName, 1622 RenderScriptVar); 1623 } else { 1624 assert(false && "Unknown class of type"); 1625 } 1626 } 1627} 1628 1629void RSReflection::genAddPaddingToElementBuiler(Context &C, 1630 int PaddingSize, 1631 const char *ElementBuilderName, 1632 const char *RenderScriptVar) { 1633 while (PaddingSize > 0) { 1634 const std::string &VarName = C.createPaddingField(); 1635 if (PaddingSize >= 4) { 1636 EB_ADD("U32(" << RenderScriptVar << ")"); 1637 PaddingSize -= 4; 1638 } else if (PaddingSize >= 2) { 1639 EB_ADD("U16(" << RenderScriptVar << ")"); 1640 PaddingSize -= 2; 1641 } else if (PaddingSize >= 1) { 1642 EB_ADD("U8(" << RenderScriptVar << ")"); 1643 PaddingSize -= 1; 1644 } 1645 } 1646 return; 1647} 1648 1649#undef EB_ADD 1650/******** Methods to create Element in Java of given record type /end ********/ 1651 1652bool RSReflection::reflect(const char *OutputPackageName, 1653 const std::string &InputFileName, 1654 const std::string &OutputBCFileName) { 1655 Context *C = NULL; 1656 std::string ResourceId = ""; 1657 1658 if (!GetClassNameFromFileName(OutputBCFileName, ResourceId)) 1659 return false; 1660 1661 if (ResourceId.empty()) 1662 ResourceId = "<Resource ID>"; 1663 1664 if ((OutputPackageName == NULL) || 1665 (*OutputPackageName == '\0') || 1666 strcmp(OutputPackageName, "-") == 0) 1667 C = new Context(mRSContext->getReflectJavaPathName(), InputFileName, 1668 "<Package Name>", ResourceId, true); 1669 else 1670 C = new Context(mRSContext->getReflectJavaPathName(), InputFileName, 1671 OutputPackageName, 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(mOutputPath.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