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