slang_rs_reflection.cpp revision d42a429f42fd6f272188af64f412cd604f02b365
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"[mType.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 * mType.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() << "int oldSize = mItemArray.length;" << std::endl; 1476 C.indent() << "int copySize = Math.min(oldSize, newSize);" << std::endl; 1477 C.indent() << "if (copySize == oldSize) return;" << std::endl; 1478 C.indent() << "Item ni[] = new Item[newSize];" << std::endl; 1479 C.indent() << "System.arraycopy(mItemArray, 0, ni, 0, copySize);" 1480 << std::endl; 1481 C.indent() << "mItemArray = ni;" << std::endl; 1482 C.indent() << "mAllocation.resize(newSize);" << std::endl; 1483 1484 C.endFunction(); 1485 return; 1486} 1487 1488/******************** Methods to generate type class /end ********************/ 1489 1490/********** Methods to create Element in Java of given record type ***********/ 1491void RSReflection::genBuildElement(Context &C, 1492 const char *ElementBuilderName, 1493 const RSExportRecordType *ERT, 1494 const char *RenderScriptVar, 1495 bool IsInline) { 1496 C.indent() << "Element.Builder " << ElementBuilderName << " = " 1497 "new Element.Builder(" << RenderScriptVar << ");" << std::endl; 1498 1499 // eb.add(...) 1500 genAddElementToElementBuilder(C, 1501 ERT, 1502 "", 1503 ElementBuilderName, 1504 RenderScriptVar, 1505 /* ArraySize = */0); 1506 1507 if (!IsInline) 1508 C.indent() << "return " << ElementBuilderName << ".create();" << std::endl; 1509 return; 1510} 1511 1512#define EB_ADD(x) do { \ 1513 C.indent() << ElementBuilderName \ 1514 << ".add(" << x << ", \"" << VarName << "\""; \ 1515 if (ArraySize > 0) \ 1516 C.out() << ", " << ArraySize; \ 1517 C.out() << ");" << std::endl; \ 1518 C.incFieldIndex(); \ 1519} while (false) 1520 1521void RSReflection::genAddElementToElementBuilder(Context &C, 1522 const RSExportType *ET, 1523 const std::string &VarName, 1524 const char *ElementBuilderName, 1525 const char *RenderScriptVar, 1526 unsigned ArraySize) { 1527 const char *ElementConstruct = GetBuiltinElementConstruct(ET); 1528 1529 if (ElementConstruct != NULL) { 1530 EB_ADD(ElementConstruct << "(" << RenderScriptVar << ")"); 1531 } else { 1532 if ((ET->getClass() == RSExportType::ExportClassPrimitive) || 1533 (ET->getClass() == RSExportType::ExportClassVector)) { 1534 const RSExportPrimitiveType *EPT = 1535 static_cast<const RSExportPrimitiveType*>(ET); 1536 const char *DataKindName = GetElementDataKindName(EPT->getKind()); 1537 const char *DataTypeName = GetElementDataTypeName(EPT->getType()); 1538 int Size = (ET->getClass() == RSExportType::ExportClassVector) ? 1539 static_cast<const RSExportVectorType*>(ET)->getNumElement() : 1540 1; 1541 1542 switch (EPT->getKind()) { 1543 case RSExportPrimitiveType::DataKindPixelL: 1544 case RSExportPrimitiveType::DataKindPixelA: 1545 case RSExportPrimitiveType::DataKindPixelLA: 1546 case RSExportPrimitiveType::DataKindPixelRGB: 1547 case RSExportPrimitiveType::DataKindPixelRGBA: { 1548 // Element.createPixel() 1549 EB_ADD("Element.createPixel(" << RenderScriptVar << ", " 1550 << DataTypeName << ", " 1551 << DataKindName << ")"); 1552 break; 1553 } 1554 case RSExportPrimitiveType::DataKindUser: 1555 default: { 1556 if (EPT->getClass() == RSExportType::ExportClassPrimitive) { 1557 // Element.createUser() 1558 EB_ADD("Element.createUser(" << RenderScriptVar << ", " 1559 << DataTypeName << ")"); 1560 } else { 1561 assert((ET->getClass() == RSExportType::ExportClassVector) && 1562 "Unexpected type."); 1563 EB_ADD("Element.createVector(" << RenderScriptVar << ", " 1564 << DataTypeName << ", " 1565 << Size << ")"); 1566 } 1567 break; 1568 } 1569 } 1570#ifndef NDEBUG 1571 } else if (ET->getClass() == RSExportType::ExportClassPointer) { 1572 // Pointer type variable should be resolved in 1573 // GetBuiltinElementConstruct() 1574 assert(false && "??"); 1575 } else if (ET->getClass() == RSExportType::ExportClassMatrix) { 1576 // Matrix type variable should be resolved 1577 // in GetBuiltinElementConstruct() 1578 assert(false && "??"); 1579#endif 1580 } else if (ET->getClass() == RSExportType::ExportClassConstantArray) { 1581 const RSExportConstantArrayType *ECAT = 1582 static_cast<const RSExportConstantArrayType *>(ET); 1583 1584 const RSExportType *ElementType = ECAT->getElementType(); 1585 if (ElementType->getClass() != RSExportType::ExportClassRecord) { 1586 genAddElementToElementBuilder(C, 1587 ECAT->getElementType(), 1588 VarName, 1589 ElementBuilderName, 1590 RenderScriptVar, 1591 ECAT->getSize()); 1592 } else { 1593 std::string NewElementBuilderName(ElementBuilderName); 1594 NewElementBuilderName.append(1, '_'); 1595 1596 genBuildElement(C, 1597 NewElementBuilderName.c_str(), 1598 static_cast<const RSExportRecordType*>(ElementType), 1599 RenderScriptVar, 1600 /* IsInline = */true); 1601 ArraySize = ECAT->getSize(); 1602 EB_ADD(NewElementBuilderName << ".create()"); 1603 } 1604 } else if (ET->getClass() == RSExportType::ExportClassRecord) { 1605 // Simalar to case of RSExportType::ExportClassRecord in genPackVarOfType. 1606 // 1607 // TODO(zonr): Generalize these two function such that there's no 1608 // duplicated codes. 1609 const RSExportRecordType *ERT = 1610 static_cast<const RSExportRecordType*>(ET); 1611 int Pos = 0; // relative pos from now on 1612 1613 for (RSExportRecordType::const_field_iterator I = ERT->fields_begin(), 1614 E = ERT->fields_end(); 1615 I != E; 1616 I++) { 1617 const RSExportRecordType::Field *F = *I; 1618 std::string FieldName; 1619 int FieldOffset = F->getOffsetInParent(); 1620 int FieldStoreSize = RSExportType::GetTypeStoreSize(F->getType()); 1621 int FieldAllocSize = RSExportType::GetTypeAllocSize(F->getType()); 1622 1623 if (!VarName.empty()) 1624 FieldName = VarName + "." + F->getName(); 1625 else 1626 FieldName = F->getName(); 1627 1628 // Alignment 1629 genAddPaddingToElementBuiler(C, 1630 (FieldOffset - Pos), 1631 ElementBuilderName, 1632 RenderScriptVar); 1633 1634 // eb.add(...) 1635 C.addFieldIndexMapping(F); 1636 if (F->getType()->getClass() != RSExportType::ExportClassRecord) { 1637 genAddElementToElementBuilder(C, 1638 F->getType(), 1639 FieldName, 1640 ElementBuilderName, 1641 RenderScriptVar, 1642 0); 1643 } else { 1644 std::string NewElementBuilderName(ElementBuilderName); 1645 NewElementBuilderName.append(1, '_'); 1646 1647 genBuildElement(C, 1648 NewElementBuilderName.c_str(), 1649 static_cast<const RSExportRecordType*>(F->getType()), 1650 RenderScriptVar, 1651 /* IsInline = */true); 1652 1653 const std::string &VarName = FieldName; // Hack for EB_ADD macro 1654 EB_ADD(NewElementBuilderName << ".create()"); 1655 } 1656 1657 // There is padding within the field type 1658 genAddPaddingToElementBuiler(C, 1659 (FieldAllocSize - FieldStoreSize), 1660 ElementBuilderName, 1661 RenderScriptVar); 1662 1663 Pos = FieldOffset + FieldAllocSize; 1664 } 1665 1666 // There maybe some padding after the struct 1667 size_t RecordStoreSize = RSExportType::GetTypeStoreSize(ERT); 1668 1669 genAddPaddingToElementBuiler(C, 1670 RecordStoreSize - Pos, 1671 ElementBuilderName, 1672 RenderScriptVar); 1673 } else { 1674 assert(false && "Unknown class of type"); 1675 } 1676 } 1677} 1678 1679void RSReflection::genAddPaddingToElementBuiler(Context &C, 1680 int PaddingSize, 1681 const char *ElementBuilderName, 1682 const char *RenderScriptVar) { 1683 unsigned ArraySize = 0; // Hack the EB_ADD macro 1684 while (PaddingSize > 0) { 1685 const std::string &VarName = C.createPaddingField(); 1686 if (PaddingSize >= 4) { 1687 EB_ADD("Element.U32(" << RenderScriptVar << ")"); 1688 PaddingSize -= 4; 1689 } else if (PaddingSize >= 2) { 1690 EB_ADD("Element.U16(" << RenderScriptVar << ")"); 1691 PaddingSize -= 2; 1692 } else if (PaddingSize >= 1) { 1693 EB_ADD("Element.U8(" << RenderScriptVar << ")"); 1694 PaddingSize -= 1; 1695 } 1696 } 1697 return; 1698} 1699 1700#undef EB_ADD 1701/******** Methods to create Element in Java of given record type /end ********/ 1702 1703bool RSReflection::reflect(const std::string &OutputPathBase, 1704 const std::string &OutputPackageName, 1705 const std::string &InputFileName, 1706 const std::string &OutputBCFileName) { 1707 Context *C = NULL; 1708 std::string ResourceId = ""; 1709 1710 if (!GetClassNameFromFileName(OutputBCFileName, ResourceId)) 1711 return false; 1712 1713 if (ResourceId.empty()) 1714 ResourceId = "<Resource ID>"; 1715 1716 if (OutputPackageName.empty() || OutputPackageName == "-") 1717 C = new Context(OutputPathBase, InputFileName, "<Package Name>", 1718 ResourceId, true); 1719 else 1720 C = new Context(OutputPathBase, InputFileName, OutputPackageName, 1721 ResourceId, false); 1722 1723 if (C != NULL) { 1724 std::string ErrorMsg, ScriptClassName; 1725 // class ScriptC_<ScriptName> 1726 if (!GetClassNameFromFileName(InputFileName, ScriptClassName)) 1727 return false; 1728 1729 if (ScriptClassName.empty()) 1730 ScriptClassName = "<Input Script Name>"; 1731 1732 ScriptClassName.insert(0, RS_SCRIPT_CLASS_NAME_PREFIX); 1733 1734 if (mRSContext->getLicenseNote() != NULL) { 1735 C->setLicenseNote(*(mRSContext->getLicenseNote())); 1736 } 1737 1738 if (!genScriptClass(*C, ScriptClassName, ErrorMsg)) { 1739 std::cerr << "Failed to generate class " << ScriptClassName << " (" 1740 << ErrorMsg << ")" << std::endl; 1741 return false; 1742 } 1743 1744 // class ScriptField_<TypeName> 1745 for (RSContext::const_export_type_iterator TI = 1746 mRSContext->export_types_begin(), 1747 TE = mRSContext->export_types_end(); 1748 TI != TE; 1749 TI++) { 1750 const RSExportType *ET = TI->getValue(); 1751 1752 if (ET->getClass() == RSExportType::ExportClassRecord) { 1753 const RSExportRecordType *ERT = 1754 static_cast<const RSExportRecordType*>(ET); 1755 1756 if (!ERT->isArtificial() && !genTypeClass(*C, ERT, ErrorMsg)) { 1757 std::cerr << "Failed to generate type class for struct '" 1758 << ERT->getName() << "' (" << ErrorMsg << ")" << std::endl; 1759 return false; 1760 } 1761 } 1762 } 1763 } 1764 1765 return true; 1766} 1767 1768/************************** RSReflection::Context **************************/ 1769const char *const RSReflection::Context::ApacheLicenseNote = 1770 "/*\n" 1771 " * Copyright (C) 2010 The Android Open Source Project\n" 1772 " *\n" 1773 " * Licensed under the Apache License, Version 2.0 (the \"License\");\n" 1774 " * you may not use this file except in compliance with the License.\n" 1775 " * You may obtain a copy of the License at\n" 1776 " *\n" 1777 " * http://www.apache.org/licenses/LICENSE-2.0\n" 1778 " *\n" 1779 " * Unless required by applicable law or agreed to in writing, software\n" 1780 " * distributed under the License is distributed on an \"AS IS\" BASIS,\n" 1781 " * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or " 1782 "implied.\n" 1783 " * See the License for the specific language governing permissions and\n" 1784 " * limitations under the License.\n" 1785 " */\n" 1786 "\n"; 1787 1788const char *const RSReflection::Context::Import[] = { 1789 // RenderScript java class 1790 "android.renderscript.*", 1791 // Import R 1792 "android.content.res.Resources", 1793 // Import for debugging 1794 "android.util.Log", 1795}; 1796 1797bool RSReflection::Context::openClassFile(const std::string &ClassName, 1798 std::string &ErrorMsg) { 1799 if (!mUseStdout) { 1800 mOF.clear(); 1801 std::string Path = 1802 RSSlangReflectUtils::ComputePackagedPath(mOutputPathBase.c_str(), 1803 mPackageName.c_str()); 1804 1805 if (!SlangUtils::CreateDirectoryWithParents(Path, &ErrorMsg)) 1806 return false; 1807 1808 std::string ClassFile = Path + "/" + ClassName + ".java"; 1809 1810 mOF.open(ClassFile.c_str()); 1811 if (!mOF.good()) { 1812 ErrorMsg = "failed to open file '" + ClassFile + "' for write"; 1813 return false; 1814 } 1815 } 1816 return true; 1817} 1818 1819const char *RSReflection::Context::AccessModifierStr(AccessModifier AM) { 1820 switch (AM) { 1821 case AM_Public: return "public"; break; 1822 case AM_Protected: return "protected"; break; 1823 case AM_Private: return "private"; break; 1824 default: return ""; break; 1825 } 1826} 1827 1828bool RSReflection::Context::startClass(AccessModifier AM, 1829 bool IsStatic, 1830 const std::string &ClassName, 1831 const char *SuperClassName, 1832 std::string &ErrorMsg) { 1833 if (mVerbose) 1834 std::cout << "Generating " << ClassName << ".java ..." << std::endl; 1835 1836 // Open file for class 1837 if (!openClassFile(ClassName, ErrorMsg)) 1838 return false; 1839 1840 // License 1841 out() << mLicenseNote; 1842 1843 // Notice of generated file 1844 out() << "/*" << std::endl; 1845 out() << " * This file is auto-generated. DO NOT MODIFY!" << std::endl; 1846 out() << " * The source RenderScript file: " << mInputRSFile << std::endl; 1847 out() << " */" << std::endl; 1848 1849 // Package 1850 if (!mPackageName.empty()) 1851 out() << "package " << mPackageName << ";" << std::endl; 1852 out() << std::endl; 1853 1854 // Imports 1855 for (unsigned i = 0;i < (sizeof(Import) / sizeof(const char*)); i++) 1856 out() << "import " << Import[i] << ";" << std::endl; 1857 out() << std::endl; 1858 1859 // All reflected classes should be annotated as hidden, so that they won't 1860 // be exposed in SDK. 1861 out() << "/**" << std::endl; 1862 out() << " * @hide" << std::endl; 1863 out() << " */" << std::endl; 1864 1865 out() << AccessModifierStr(AM) << ((IsStatic) ? " static" : "") << " class " 1866 << ClassName; 1867 if (SuperClassName != NULL) 1868 out() << " extends " << SuperClassName; 1869 1870 startBlock(); 1871 1872 mClassName = ClassName; 1873 1874 return true; 1875} 1876 1877void RSReflection::Context::endClass() { 1878 endBlock(); 1879 if (!mUseStdout) 1880 mOF.close(); 1881 clear(); 1882 return; 1883} 1884 1885void RSReflection::Context::startBlock(bool ShouldIndent) { 1886 if (ShouldIndent) 1887 indent() << "{" << std::endl; 1888 else 1889 out() << " {" << std::endl; 1890 incIndentLevel(); 1891 return; 1892} 1893 1894void RSReflection::Context::endBlock() { 1895 decIndentLevel(); 1896 indent() << "}" << std::endl << std::endl; 1897 return; 1898} 1899 1900void RSReflection::Context::startTypeClass(const std::string &ClassName) { 1901 indent() << "public static class " << ClassName; 1902 startBlock(); 1903 return; 1904} 1905 1906void RSReflection::Context::endTypeClass() { 1907 endBlock(); 1908 return; 1909} 1910 1911void RSReflection::Context::startFunction(AccessModifier AM, 1912 bool IsStatic, 1913 const char *ReturnType, 1914 const std::string &FunctionName, 1915 int Argc, ...) { 1916 ArgTy Args; 1917 va_list vl; 1918 va_start(vl, Argc); 1919 1920 for (int i = 0; i < Argc; i++) { 1921 const char *ArgType = va_arg(vl, const char*); 1922 const char *ArgName = va_arg(vl, const char*); 1923 1924 Args.push_back(std::make_pair(ArgType, ArgName)); 1925 } 1926 va_end(vl); 1927 1928 startFunction(AM, IsStatic, ReturnType, FunctionName, Args); 1929 1930 return; 1931} 1932 1933void RSReflection::Context::startFunction(AccessModifier AM, 1934 bool IsStatic, 1935 const char *ReturnType, 1936 const std::string &FunctionName, 1937 const ArgTy &Args) { 1938 indent() << AccessModifierStr(AM) << ((IsStatic) ? " static " : " ") 1939 << ((ReturnType) ? ReturnType : "") << " " << FunctionName << "("; 1940 1941 bool FirstArg = true; 1942 for (ArgTy::const_iterator I = Args.begin(), E = Args.end(); 1943 I != E; 1944 I++) { 1945 if (!FirstArg) 1946 out() << ", "; 1947 else 1948 FirstArg = false; 1949 1950 out() << I->first << " " << I->second; 1951 } 1952 1953 out() << ")"; 1954 startBlock(); 1955 1956 return; 1957} 1958 1959void RSReflection::Context::endFunction() { 1960 endBlock(); 1961 return; 1962} 1963