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