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